Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete most of InteropExtensions #97685

Merged
merged 1 commit into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,26 @@ public static uint GetStructFieldOffset(RuntimeTypeHandle structureTypeHandle, s
throw new NotSupportedException(SR.Format(SR.StructMarshalling_MissingInteropData, structureType));
}

public static int GetStructUnsafeStructSize(RuntimeTypeHandle structureTypeHandle)
public static unsafe int GetStructUnsafeStructSize(RuntimeTypeHandle structureTypeHandle)
{
if (TryGetStructUnsafeStructSize(structureTypeHandle, out int size))
{
return size;
}

MethodTable* structureMT = structureTypeHandle.ToMethodTable();

// IsBlittable() checks whether the type contains GC references. It is approximate check with false positives.
// This fallback path will return incorrect answer for types that do not contain GC references, but that are
// not actually blittable; e.g. for types with bool fields.
if (structureTypeHandle.IsBlittable() && structureTypeHandle.IsValueType())
if (structureTypeHandle.IsBlittable() && structureMT->IsValueType)
{
return structureTypeHandle.GetValueTypeSize();
return (int)structureMT->ValueTypeSize;
}

// If the type is an interface or a generic type, the reason is likely that.
Type structureType = Type.GetTypeFromHandle(structureTypeHandle)!;
if (structureTypeHandle.IsInterface() || structureTypeHandle.IsGenericType())
if (structureMT->IsInterface || structureMT->IsGeneric)
{
throw new ArgumentException(SR.Format(SR.Arg_CannotMarshal, structureType));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,89 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;

using Internal.Runtime.Augments;
using Internal.Runtime.CompilerServices;

namespace System.Runtime.InteropServices
{
/// <summary>
/// Hooks for interop code to access internal functionality in System.Private.CoreLib.dll.
/// </summary>
internal static unsafe class InteropExtensions
{
internal static bool MightBeBlittable(this RuntimeTypeHandle handle)
public static bool IsBlittable(this RuntimeTypeHandle handle)
{
//
// This is used as the approximate implementation of MethodTable::IsBlittable(). It will err in the direction of declaring
// things blittable since it is used for argument validation only.
//
return !handle.ToMethodTable()->ContainsGCPointers;
}

public static bool IsBlittable(this RuntimeTypeHandle handle)
{
return handle.MightBeBlittable();
}

public static bool IsGenericType(this RuntimeTypeHandle handle)
{
return handle.ToMethodTable()->IsGeneric;
}

public static bool IsGenericTypeDefinition(this RuntimeTypeHandle handle)
{
return handle.ToMethodTable()->IsGenericTypeDefinition;
}

//
// Returns the raw function pointer for a open static delegate - if the function has a jump stub
// it returns the jump target. Therefore the function pointer returned
// by two delegates may NOT be unique
//
public static IntPtr GetRawFunctionPointerForOpenStaticDelegate(this Delegate del)
{
//If it is not open static then return IntPtr.Zero
if (!del.IsOpenStatic)
return IntPtr.Zero;

IntPtr funcPtr = del.GetFunctionPointer(out RuntimeTypeHandle _, out bool _, out bool _);
return funcPtr;
}

public static int GetValueTypeSize(this RuntimeTypeHandle handle)
{
return (int)handle.ToMethodTable()->ValueTypeSize;
}

public static bool IsValueType(this RuntimeTypeHandle handle)
{
return handle.ToMethodTable()->IsValueType;
}

public static bool IsEnum(this RuntimeTypeHandle handle)
{
return handle.ToMethodTable()->IsEnum;
}

public static bool IsInterface(this RuntimeTypeHandle handle)
{
return handle.ToMethodTable()->IsInterface;
}

public static bool AreTypesAssignable(RuntimeTypeHandle sourceType, RuntimeTypeHandle targetType)
{
return RuntimeImports.AreTypesAssignable(sourceType.ToMethodTable(), targetType.ToMethodTable());
}

public static RuntimeTypeHandle GetTypeHandle(this object target)
{
return new RuntimeTypeHandle(target.GetMethodTable());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Runtime.CompilerServices;
using System.Text;

using Internal.Runtime;
using Internal.Runtime.Augments;
using Internal.Runtime.CompilerHelpers;

Expand All @@ -29,7 +30,7 @@ internal static int SizeOfHelper(RuntimeType t, bool throwIfNotMarshalable)
}

[EditorBrowsable(EditorBrowsableState.Never)]
public static IntPtr OffsetOf(Type t, string fieldName)
public static unsafe IntPtr OffsetOf(Type t, string fieldName)
{
ArgumentNullException.ThrowIfNull(t);

Expand All @@ -43,7 +44,7 @@ public static IntPtr OffsetOf(Type t, string fieldName)
throw new ArgumentException(SR.Argument_MustBeRuntimeFieldInfo, nameof(fieldName));
}

if (t.TypeHandle.IsGenericTypeDefinition())
if (t.TypeHandle.ToMethodTable()->IsGenericTypeDefinition)
throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));

return new IntPtr(RuntimeInteropData.GetStructFieldOffset(t.TypeHandle, fieldName));
Expand All @@ -61,7 +62,8 @@ private static unsafe void PtrToStructureHelper(IntPtr ptr, object structure, bo

internal static unsafe void PtrToStructureImpl(IntPtr ptr, object structure)
{
RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;
MethodTable* structureMT = structure.GetMethodTable();
RuntimeTypeHandle structureTypeHandle = new RuntimeTypeHandle(structureMT);

IntPtr unmarshalStub;
if (structureTypeHandle.IsBlittable())
Expand All @@ -78,7 +80,7 @@ internal static unsafe void PtrToStructureImpl(IntPtr ptr, object structure)

if (unmarshalStub != IntPtr.Zero)
{
if (structureTypeHandle.IsValueType())
if (structureMT->IsValueType)
{
((delegate*<ref byte, ref byte, void>)unmarshalStub)(ref *(byte*)ptr, ref structure.GetRawData());
}
Expand All @@ -104,12 +106,12 @@ public static unsafe void DestroyStructure(IntPtr ptr, Type structuretype)

RuntimeTypeHandle structureTypeHandle = structuretype.TypeHandle;

if (structureTypeHandle.IsGenericType())
if (structureTypeHandle.ToMethodTable()->IsGeneric)
throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(structuretype));

if (structureTypeHandle.IsEnum() ||
structureTypeHandle.IsInterface() ||
InteropExtensions.AreTypesAssignable(typeof(Delegate).TypeHandle, structureTypeHandle))
if (structureTypeHandle.ToMethodTable()->IsEnum ||
structureTypeHandle.ToMethodTable()->IsInterface ||
RuntimeImports.AreTypesAssignable(MethodTable.Of<Delegate>(), structureTypeHandle.ToMethodTable()))
{
throw new ArgumentException(SR.Format(SR.Argument_MustHaveLayoutOrBeBlittable, structuretype));
}
Expand Down Expand Up @@ -137,9 +139,10 @@ public static unsafe void StructureToPtr(object structure, IntPtr ptr, bool fDel
ArgumentNullException.ThrowIfNull(structure);
ArgumentNullException.ThrowIfNull(ptr);

RuntimeTypeHandle structureTypeHandle = structure.GetType().TypeHandle;
MethodTable* structureMT = structure.GetMethodTable();
RuntimeTypeHandle structureTypeHandle = new RuntimeTypeHandle(structureMT);

if (structureTypeHandle.IsGenericType())
if (structureMT->IsGeneric)
{
throw new ArgumentException(SR.Argument_NeedNonGenericObject, nameof(structure));
}
Expand All @@ -164,7 +167,7 @@ public static unsafe void StructureToPtr(object structure, IntPtr ptr, bool fDel

if (marshalStub != IntPtr.Zero)
{
if (structureTypeHandle.IsValueType())
if (structureMT->IsValueType)
{
((delegate*<ref byte, ref byte, void>)marshalStub)(ref structure.GetRawData(), ref *(byte*)ptr);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ public PInvokeDelegateThunk(Delegate del)
thunkData->Handle = GCHandle.Alloc(del, GCHandleType.Weak);

// if it is an open static delegate get the function pointer
thunkData->FunctionPtr = del.GetRawFunctionPointerForOpenStaticDelegate();
if (del.IsOpenStatic)
thunkData->FunctionPtr = del.GetFunctionPointer(out RuntimeTypeHandle _, out bool _, out bool _);
else
thunkData->FunctionPtr = default;
}
}
}
Expand All @@ -163,7 +166,7 @@ public PInvokeDelegateThunk(Delegate del)
}
}

private static PInvokeDelegateThunk AllocateThunk(Delegate del)
private static unsafe PInvokeDelegateThunk AllocateThunk(Delegate del)
{
if (s_thunkPoolHeap == null)
{
Expand All @@ -181,9 +184,9 @@ private static PInvokeDelegateThunk AllocateThunk(Delegate del)
//
// For open static delegates set target to ReverseOpenStaticDelegateStub which calls the static function pointer directly
//
bool openStaticDelegate = del.GetRawFunctionPointerForOpenStaticDelegate() != IntPtr.Zero;
bool openStaticDelegate = del.IsOpenStatic;

IntPtr pTarget = RuntimeInteropData.GetDelegateMarshallingStub(del.GetTypeHandle(), openStaticDelegate);
IntPtr pTarget = RuntimeInteropData.GetDelegateMarshallingStub(new RuntimeTypeHandle(del.GetMethodTable()), openStaticDelegate);
Debug.Assert(pTarget != IntPtr.Zero);

RuntimeAugments.SetThunkData(s_thunkPoolHeap, delegateThunk.Thunk, delegateThunk.ContextData, pTarget);
Expand Down
Loading