This commit is contained in:
2022-12-22 19:54:30 +02:00
parent e03a819176
commit 3c79be2910
3 changed files with 128 additions and 124 deletions

View File

@@ -25,7 +25,7 @@ namespace FlaxEngine
#region Native structures #region Native structures
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct ManagedClass internal struct NativeClassDefinitions
{ {
internal IntPtr typeHandle; internal IntPtr typeHandle;
internal IntPtr name; internal IntPtr name;
@@ -35,7 +35,7 @@ namespace FlaxEngine
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct ClassMethod internal struct NativeMethodDefinitions
{ {
internal IntPtr name; internal IntPtr name;
internal int numParameters; internal int numParameters;
@@ -44,7 +44,7 @@ namespace FlaxEngine
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct ClassField internal struct NativeFieldDefinitions
{ {
internal IntPtr name; internal IntPtr name;
internal IntPtr fieldHandle; internal IntPtr fieldHandle;
@@ -53,7 +53,7 @@ namespace FlaxEngine
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct ClassProperty internal struct NativePropertyDefinitions
{ {
internal IntPtr name; internal IntPtr name;
internal IntPtr getterHandle; internal IntPtr getterHandle;
@@ -63,7 +63,7 @@ namespace FlaxEngine
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct ClassAttribute internal struct NativeAttributeDefinitions
{ {
internal IntPtr name; internal IntPtr name;
internal IntPtr attributeHandle; internal IntPtr attributeHandle;
@@ -132,43 +132,6 @@ namespace FlaxEngine
int AsData5; int AsData5;
} }
#if false
[StructLayout(LayoutKind.Sequential)]
internal struct GuidNative
{
internal int A;
internal short B;
internal short C;
internal byte D;
internal byte E;
internal byte F;
internal byte G;
internal byte H;
internal byte I;
internal byte J;
internal byte K;
internal GuidNative(Guid guid)
{
byte[] bytes = guid.ToByteArray();
A = MemoryMarshal.Cast<byte, int>(bytes.AsSpan())[0];
B = MemoryMarshal.Cast<byte, short>(bytes.AsSpan())[4];
C = MemoryMarshal.Cast<byte, short>(bytes.AsSpan())[6];
D = bytes[8];
E = bytes[9];
F = bytes[10];
G = bytes[11];
H = bytes[12];
I = bytes[13];
J = bytes[14];
K = bytes[15];
}
internal static implicit operator Guid(GuidNative guid) => new Guid(guid.A, guid.B, guid.C, guid.D, guid.E, guid.F, guid.G, guid.H, guid.I, guid.J, guid.K);
internal static explicit operator GuidNative(Guid guid) => new GuidNative(guid);
}
#endif
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct VersionNative internal struct VersionNative
{ {
@@ -1517,27 +1480,15 @@ namespace FlaxEngine
Unsafe.Write<IntPtr>(nativePtr.ToPointer(), managedPtr); Unsafe.Write<IntPtr>(nativePtr.ToPointer(), managedPtr);
} }
} }
internal class FieldBlob
{
internal FieldInfo field;
internal MarshalToNativeFieldDelegate toNativeMarshaller;
internal FieldBlob(FieldInfo field, Type type) internal class MethodHolder
{
this.field = field;
toNativeMarshaller = GetToNativeFieldMarshallerDelegate(type);
}
}
internal class MethodBlob
{ {
internal Type[] parameterTypes; internal Type[] parameterTypes;
internal MethodInfo method; internal MethodInfo method;
private Invoker.MarshalAndInvokeDelegate invokeDelegate; private Invoker.MarshalAndInvokeDelegate invokeDelegate;
private object delegInvoke; private object delegInvoke;
internal MethodBlob(MethodInfo method) internal MethodHolder(MethodInfo method)
{ {
this.method = method; this.method = method;
parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray(); parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray();
@@ -1580,10 +1531,10 @@ namespace FlaxEngine
internal static GCHandle GetMethodGCHandle(MethodInfo method) internal static GCHandle GetMethodGCHandle(MethodInfo method)
{ {
MethodBlob methodBlob = new MethodBlob(method); MethodHolder methodHolder = new MethodHolder(method);
GCHandle handle = GCHandle.Alloc(methodBlob); GCHandle handle = GCHandle.Alloc(methodHolder);
if (methodBlob.parameterTypes.Any(x => x.IsCollectible) || method.IsCollectible) if (methodHolder.parameterTypes.Any(x => x.IsCollectible) || method.IsCollectible)
methodHandlesCollectible.Add(handle); methodHandlesCollectible.Add(handle);
else else
methodHandles.Add(handle); methodHandles.Add(handle);
@@ -1601,24 +1552,24 @@ namespace FlaxEngine
} }
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
internal static unsafe void GetManagedClasses(IntPtr assemblyHandle, ManagedClass** managedClasses, int* managedClassCount) internal static unsafe void GetManagedClasses(IntPtr assemblyHandle, NativeClassDefinitions** managedClasses, int* managedClassCount)
{ {
Assembly assembly = Unsafe.As<Assembly>(GCHandle.FromIntPtr(assemblyHandle).Target); Assembly assembly = Unsafe.As<Assembly>(GCHandle.FromIntPtr(assemblyHandle).Target);
var assemblyTypes = GetAssemblyTypes(assembly); var assemblyTypes = GetAssemblyTypes(assembly);
ManagedClass* arr = (ManagedClass*)Marshal.AllocCoTaskMem(Unsafe.SizeOf<ManagedClass>() * assemblyTypes.Length).ToPointer(); NativeClassDefinitions* arr = (NativeClassDefinitions*)Marshal.AllocCoTaskMem(Unsafe.SizeOf<NativeClassDefinitions>() * assemblyTypes.Length).ToPointer();
for (int i = 0; i < assemblyTypes.Length; i++) for (int i = 0; i < assemblyTypes.Length; i++)
{ {
var type = assemblyTypes[i]; var type = assemblyTypes[i];
IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<ManagedClass>() * i); IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<NativeClassDefinitions>() * i);
bool isStatic = type.IsAbstract && type.IsSealed; bool isStatic = type.IsAbstract && type.IsSealed;
bool isInterface = type.IsInterface; bool isInterface = type.IsInterface;
bool isAbstract = type.IsAbstract; bool isAbstract = type.IsAbstract;
GCHandle typeHandle = GetOrAddTypeGCHandle(type); GCHandle typeHandle = GetOrAddTypeGCHandle(type);
ManagedClass managedClass = new ManagedClass() NativeClassDefinitions managedClass = new NativeClassDefinitions()
{ {
typeHandle = GCHandle.ToIntPtr(typeHandle), typeHandle = GCHandle.ToIntPtr(typeHandle),
name = Marshal.StringToCoTaskMemAnsi(type.Name), name = Marshal.StringToCoTaskMemAnsi(type.Name),
@@ -1634,12 +1585,12 @@ namespace FlaxEngine
} }
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
internal static unsafe void GetManagedClassFromType(IntPtr typeHandle, ManagedClass* managedClass, IntPtr* assemblyHandle) internal static unsafe void GetManagedClassFromType(IntPtr typeHandle, NativeClassDefinitions* managedClass, IntPtr* assemblyHandle)
{ {
Type type = Unsafe.As<Type>(GCHandle.FromIntPtr(typeHandle).Target); Type type = Unsafe.As<Type>(GCHandle.FromIntPtr(typeHandle).Target);
GCHandle classTypeHandle = GetOrAddTypeGCHandle(type); GCHandle classTypeHandle = GetOrAddTypeGCHandle(type);
*managedClass = new ManagedClass() *managedClass = new NativeClassDefinitions()
{ {
typeHandle = GCHandle.ToIntPtr(classTypeHandle), typeHandle = GCHandle.ToIntPtr(classTypeHandle),
name = Marshal.StringToCoTaskMemAnsi(type.Name), name = Marshal.StringToCoTaskMemAnsi(type.Name),
@@ -1651,7 +1602,7 @@ namespace FlaxEngine
} }
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
internal static void GetClassMethods(IntPtr typeHandle, ClassMethod** classMethods, int* classMethodsCount) internal static void GetClassMethods(IntPtr typeHandle, NativeMethodDefinitions** classMethods, int* classMethodsCount)
{ {
Type type = Unsafe.As<Type>(GCHandle.FromIntPtr(typeHandle).Target); Type type = Unsafe.As<Type>(GCHandle.FromIntPtr(typeHandle).Target);
@@ -1663,11 +1614,11 @@ namespace FlaxEngine
foreach (MethodInfo method in instanceMethods) foreach (MethodInfo method in instanceMethods)
methods.Add(method); methods.Add(method);
ClassMethod* arr = (ClassMethod*)Marshal.AllocCoTaskMem(Unsafe.SizeOf<ClassMethod>() * methods.Count).ToPointer(); NativeMethodDefinitions* arr = (NativeMethodDefinitions*)Marshal.AllocCoTaskMem(Unsafe.SizeOf<NativeMethodDefinitions>() * methods.Count).ToPointer();
for (int i = 0; i < methods.Count; i++) for (int i = 0; i < methods.Count; i++)
{ {
IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<ClassMethod>() * i); IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<NativeMethodDefinitions>() * i);
ClassMethod classMethod = new ClassMethod() NativeMethodDefinitions classMethod = new NativeMethodDefinitions()
{ {
name = Marshal.StringToCoTaskMemAnsi(methods[i].Name), name = Marshal.StringToCoTaskMemAnsi(methods[i].Name),
numParameters = methods[i].GetParameters().Length, numParameters = methods[i].GetParameters().Length,
@@ -1680,31 +1631,43 @@ namespace FlaxEngine
*classMethodsCount = methods.Count; *classMethodsCount = methods.Count;
} }
internal class FieldHolder
{
internal FieldInfo field;
internal MarshalToNativeFieldDelegate toNativeMarshaller;
internal FieldHolder(FieldInfo field, Type type)
{
this.field = field;
toNativeMarshaller = GetToNativeFieldMarshallerDelegate(type);
}
}
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
internal static void GetClassFields(IntPtr typeHandle, ClassField** classFields, int* classFieldsCount) internal static void GetClassFields(IntPtr typeHandle, NativeFieldDefinitions** classFields, int* classFieldsCount)
{ {
Type type = Unsafe.As<Type>(GCHandle.FromIntPtr(typeHandle).Target); Type type = Unsafe.As<Type>(GCHandle.FromIntPtr(typeHandle).Target);
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
ClassField* arr = (ClassField*)Marshal.AllocCoTaskMem(Unsafe.SizeOf<ClassField>() * fields.Length).ToPointer(); NativeFieldDefinitions* arr = (NativeFieldDefinitions*)Marshal.AllocCoTaskMem(Unsafe.SizeOf<NativeFieldDefinitions>() * fields.Length).ToPointer();
for (int i = 0; i < fields.Length; i++) for (int i = 0; i < fields.Length; i++)
{ {
IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<ClassField>() * i); IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<NativeFieldDefinitions>() * i);
FieldBlob fieldBlob = new FieldBlob(fields[i], type); FieldHolder fieldHolder = new FieldHolder(fields[i], type);
GCHandle fieldHandle = GCHandle.Alloc(fieldBlob); GCHandle fieldHandle = GCHandle.Alloc(fieldHolder);
if (type.IsCollectible) if (type.IsCollectible)
fieldHandleCacheCollectible.Add(fieldHandle); fieldHandleCacheCollectible.Add(fieldHandle);
else else
fieldHandleCache.Add(fieldHandle); fieldHandleCache.Add(fieldHandle);
ClassField classField = new ClassField() NativeFieldDefinitions classField = new NativeFieldDefinitions()
{ {
name = Marshal.StringToCoTaskMemAnsi(fieldBlob.field.Name), name = Marshal.StringToCoTaskMemAnsi(fieldHolder.field.Name),
fieldHandle = GCHandle.ToIntPtr(fieldHandle), fieldHandle = GCHandle.ToIntPtr(fieldHandle),
fieldTypeHandle = GCHandle.ToIntPtr(GetOrAddTypeGCHandle(fieldBlob.field.FieldType)), fieldTypeHandle = GCHandle.ToIntPtr(GetOrAddTypeGCHandle(fieldHolder.field.FieldType)),
fieldAttributes = (uint)fieldBlob.field.Attributes, fieldAttributes = (uint)fieldHolder.field.Attributes,
}; };
Unsafe.Write(ptr.ToPointer(), classField); Unsafe.Write(ptr.ToPointer(), classField);
} }
@@ -1713,20 +1676,20 @@ namespace FlaxEngine
} }
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
internal static void GetClassProperties(IntPtr typeHandle, ClassProperty** classProperties, int* classPropertiesCount) internal static void GetClassProperties(IntPtr typeHandle, NativePropertyDefinitions** classProperties, int* classPropertiesCount)
{ {
Type type = Unsafe.As<Type>(GCHandle.FromIntPtr(typeHandle).Target); Type type = Unsafe.As<Type>(GCHandle.FromIntPtr(typeHandle).Target);
var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
ClassProperty* arr = (ClassProperty*)Marshal.AllocCoTaskMem(Unsafe.SizeOf<ClassProperty>() * properties.Length).ToPointer(); NativePropertyDefinitions* arr = (NativePropertyDefinitions*)Marshal.AllocCoTaskMem(Unsafe.SizeOf<NativePropertyDefinitions>() * properties.Length).ToPointer();
for (int i = 0; i < properties.Length; i++) for (int i = 0; i < properties.Length; i++)
{ {
IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<ClassProperty>() * i); IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<NativePropertyDefinitions>() * i);
var getterMethod = properties[i].GetGetMethod(true); var getterMethod = properties[i].GetGetMethod(true);
var setterMethod = properties[i].GetSetMethod(true); var setterMethod = properties[i].GetSetMethod(true);
ClassProperty classProperty = new ClassProperty() NativePropertyDefinitions classProperty = new NativePropertyDefinitions()
{ {
name = Marshal.StringToCoTaskMemAnsi(properties[i].Name), name = Marshal.StringToCoTaskMemAnsi(properties[i].Name),
}; };
@@ -1747,16 +1710,16 @@ namespace FlaxEngine
} }
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
internal static void GetClassAttributes(IntPtr typeHandle, ClassAttribute** classAttributes, int* classAttributesCount) internal static void GetClassAttributes(IntPtr typeHandle, NativeAttributeDefinitions** classAttributes, int* classAttributesCount)
{ {
Type type = Unsafe.As<Type>(GCHandle.FromIntPtr(typeHandle).Target); Type type = Unsafe.As<Type>(GCHandle.FromIntPtr(typeHandle).Target);
object[] attributeValues = type.GetCustomAttributes(false); object[] attributeValues = type.GetCustomAttributes(false);
Type[] attributeTypes = type.GetCustomAttributes(false).Select(x => x.GetType()).ToArray(); Type[] attributeTypes = type.GetCustomAttributes(false).Select(x => x.GetType()).ToArray();
ClassAttribute* arr = (ClassAttribute*)Marshal.AllocCoTaskMem(Unsafe.SizeOf<ClassAttribute>() * attributeTypes.Length).ToPointer(); NativeAttributeDefinitions* arr = (NativeAttributeDefinitions*)Marshal.AllocCoTaskMem(Unsafe.SizeOf<NativeAttributeDefinitions>() * attributeTypes.Length).ToPointer();
for (int i = 0; i < attributeTypes.Length; i++) for (int i = 0; i < attributeTypes.Length; i++)
{ {
IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<ClassAttribute>() * i); IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<NativeAttributeDefinitions>() * i);
if (!classAttributesCacheCollectible.TryGetValue(attributeValues[i], out GCHandle attributeHandle)) if (!classAttributesCacheCollectible.TryGetValue(attributeValues[i], out GCHandle attributeHandle))
{ {
@@ -1765,7 +1728,7 @@ namespace FlaxEngine
} }
GCHandle attributeTypeHandle = GetOrAddTypeGCHandle(attributeTypes[i]); GCHandle attributeTypeHandle = GetOrAddTypeGCHandle(attributeTypes[i]);
ClassAttribute classAttribute = new ClassAttribute() NativeAttributeDefinitions classAttribute = new NativeAttributeDefinitions()
{ {
name = Marshal.StringToCoTaskMemAnsi(attributeTypes[i].Name), name = Marshal.StringToCoTaskMemAnsi(attributeTypes[i].Name),
attributeTypeHandle = GCHandle.ToIntPtr(attributeTypeHandle), attributeTypeHandle = GCHandle.ToIntPtr(attributeTypeHandle),
@@ -1814,8 +1777,8 @@ namespace FlaxEngine
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
internal static IntPtr GetMethodReturnType(IntPtr methodHandle) internal static IntPtr GetMethodReturnType(IntPtr methodHandle)
{ {
MethodBlob methodBlob = Unsafe.As<MethodBlob>(GCHandle.FromIntPtr(methodHandle).Target); MethodHolder methodHolder = Unsafe.As<MethodHolder>(GCHandle.FromIntPtr(methodHandle).Target);
Type returnType = methodBlob.method.ReturnType; Type returnType = methodHolder.method.ReturnType;
return GCHandle.ToIntPtr(GetTypeGCHandle(returnType)); return GCHandle.ToIntPtr(GetTypeGCHandle(returnType));
} }
@@ -1823,13 +1786,13 @@ namespace FlaxEngine
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
internal static void GetMethodParameterTypes(IntPtr methodHandle, IntPtr* typeHandles) internal static void GetMethodParameterTypes(IntPtr methodHandle, IntPtr* typeHandles)
{ {
MethodBlob methodBlob = Unsafe.As<MethodBlob>(GCHandle.FromIntPtr(methodHandle).Target); MethodHolder methodHolder = Unsafe.As<MethodHolder>(GCHandle.FromIntPtr(methodHandle).Target);
Type returnType = methodBlob.method.ReturnType; Type returnType = methodHolder.method.ReturnType;
IntPtr arr = Marshal.AllocCoTaskMem(IntPtr.Size * methodBlob.parameterTypes.Length); IntPtr arr = Marshal.AllocCoTaskMem(IntPtr.Size * methodHolder.parameterTypes.Length);
for (int i = 0; i < methodBlob.parameterTypes.Length; i++) for (int i = 0; i < methodHolder.parameterTypes.Length; i++)
{ {
GCHandle typeHandle = GetOrAddTypeGCHandle(methodBlob.parameterTypes[i]); GCHandle typeHandle = GetOrAddTypeGCHandle(methodHolder.parameterTypes[i]);
Marshal.WriteIntPtr(IntPtr.Add(new IntPtr(arr), IntPtr.Size * i), GCHandle.ToIntPtr(typeHandle)); Marshal.WriteIntPtr(IntPtr.Add(new IntPtr(arr), IntPtr.Size * i), GCHandle.ToIntPtr(typeHandle));
} }
*typeHandles = arr; *typeHandles = arr;
@@ -2050,10 +2013,10 @@ namespace FlaxEngine
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
internal static IntPtr InvokeMethod(IntPtr instancePtr, IntPtr methodHandle, IntPtr paramPtr, IntPtr exceptionPtr) internal static IntPtr InvokeMethod(IntPtr instancePtr, IntPtr methodHandle, IntPtr paramPtr, IntPtr exceptionPtr)
{ {
MethodBlob methodBlob = Unsafe.As<MethodBlob>(GCHandle.FromIntPtr(methodHandle).Target); MethodHolder methodHolder = Unsafe.As<MethodHolder>(GCHandle.FromIntPtr(methodHandle).Target);
if (methodBlob.TryGetDelegate(out var methodDelegate, out var methodDelegateContext)) if (methodHolder.TryGetDelegate(out var methodDelegate, out var methodDelegateContext))
{ {
// Fast path, invoke the method with minimal allocations // Fast path, invoke the method with minimal allocations
IntPtr returnValue; IntPtr returnValue;
@@ -2075,19 +2038,19 @@ namespace FlaxEngine
{ {
// Slow path, method parameters needs to be stored in heap // Slow path, method parameters needs to be stored in heap
object returnObject; object returnObject;
int numParams = methodBlob.parameterTypes.Length; int numParams = methodHolder.parameterTypes.Length;
IntPtr* nativePtrs = stackalloc IntPtr[numParams]; IntPtr* nativePtrs = stackalloc IntPtr[numParams];
object[] methodParameters = new object[numParams]; object[] methodParameters = new object[numParams];
for (int i = 0; i < numParams; i++) for (int i = 0; i < numParams; i++)
{ {
nativePtrs[i] = Marshal.ReadIntPtr(IntPtr.Add(paramPtr, sizeof(IntPtr) * i)); nativePtrs[i] = Marshal.ReadIntPtr(IntPtr.Add(paramPtr, sizeof(IntPtr) * i));
methodParameters[i] = MarshalToManaged(nativePtrs[i], methodBlob.parameterTypes[i]); methodParameters[i] = MarshalToManaged(nativePtrs[i], methodHolder.parameterTypes[i]);
} }
try try
{ {
returnObject = methodBlob.method.Invoke(instancePtr != IntPtr.Zero ? GCHandle.FromIntPtr(instancePtr).Target : null, methodParameters); returnObject = methodHolder.method.Invoke(instancePtr != IntPtr.Zero ? GCHandle.FromIntPtr(instancePtr).Target : null, methodParameters);
} }
catch (Exception exception) catch (Exception exception)
{ {
@@ -2109,22 +2072,22 @@ namespace FlaxEngine
// Marshal reference parameters back to original unmanaged references // Marshal reference parameters back to original unmanaged references
for (int i = 0; i < numParams; i++) for (int i = 0; i < numParams; i++)
{ {
Type parameterType = methodBlob.parameterTypes[i]; Type parameterType = methodHolder.parameterTypes[i];
if (parameterType.IsByRef) if (parameterType.IsByRef)
MarshalToNative(methodParameters[i], nativePtrs[i], parameterType.GetElementType()); MarshalToNative(methodParameters[i], nativePtrs[i], parameterType.GetElementType());
} }
if (returnObject is not null) if (returnObject is not null)
{ {
if (methodBlob.method.ReturnType == typeof(string)) if (methodHolder.method.ReturnType == typeof(string))
return ManagedString.ToNative(Unsafe.As<string>(returnObject)); return ManagedString.ToNative(Unsafe.As<string>(returnObject));
else if (methodBlob.method.ReturnType == typeof(IntPtr)) else if (methodHolder.method.ReturnType == typeof(IntPtr))
return (IntPtr)returnObject; return (IntPtr)returnObject;
else if (methodBlob.method.ReturnType == typeof(bool)) else if (methodHolder.method.ReturnType == typeof(bool))
return (bool)returnObject ? boolTruePtr : boolFalsePtr; return (bool)returnObject ? boolTruePtr : boolFalsePtr;
else if (methodBlob.method.ReturnType == typeof(Type)) else if (methodHolder.method.ReturnType == typeof(Type))
return GCHandle.ToIntPtr(GetOrAddTypeGCHandle(Unsafe.As<Type>(returnObject))); return GCHandle.ToIntPtr(GetOrAddTypeGCHandle(Unsafe.As<Type>(returnObject)));
else if (methodBlob.method.ReturnType == typeof(object[])) else if (methodHolder.method.ReturnType == typeof(object[]))
return GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As<object[]>(returnObject))), GCHandleType.Weak)); return GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As<object[]>(returnObject))), GCHandleType.Weak));
else else
return GCHandle.ToIntPtr(GCHandle.Alloc(returnObject, GCHandleType.Weak)); return GCHandle.ToIntPtr(GCHandle.Alloc(returnObject, GCHandleType.Weak));
@@ -2136,18 +2099,18 @@ namespace FlaxEngine
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
internal static IntPtr GetMethodUnmanagedFunctionPointer(IntPtr methodHandle) internal static IntPtr GetMethodUnmanagedFunctionPointer(IntPtr methodHandle)
{ {
MethodBlob methodBlob = Unsafe.As<MethodBlob>(GCHandle.FromIntPtr(methodHandle).Target); MethodHolder methodHolder = Unsafe.As<MethodHolder>(GCHandle.FromIntPtr(methodHandle).Target);
// Wrap the method call, this is needed to get the object instance from GCHandle and to pass the exception back to native side // Wrap the method call, this is needed to get the object instance from GCHandle and to pass the exception back to native side
MethodInfo invokeThunk = typeof(ThunkContext).GetMethod(nameof(ThunkContext.InvokeThunk)); MethodInfo invokeThunk = typeof(ThunkContext).GetMethod(nameof(ThunkContext.InvokeThunk));
Type delegateType = DelegateHelpers.MakeNewCustomDelegate(invokeThunk.GetParameters().Select(x => x.ParameterType).Append(invokeThunk.ReturnType).ToArray()); Type delegateType = DelegateHelpers.MakeNewCustomDelegate(invokeThunk.GetParameters().Select(x => x.ParameterType).Append(invokeThunk.ReturnType).ToArray());
ThunkContext context = new ThunkContext(methodBlob.method); ThunkContext context = new ThunkContext(methodHolder.method);
Delegate methodDelegate = invokeThunk.CreateDelegate(delegateType, context); Delegate methodDelegate = invokeThunk.CreateDelegate(delegateType, context);
IntPtr functionPtr = Marshal.GetFunctionPointerForDelegate(methodDelegate); IntPtr functionPtr = Marshal.GetFunctionPointerForDelegate(methodDelegate);
// Keep a reference to the delegate to prevent it from being garbage collected // Keep a reference to the delegate to prevent it from being garbage collected
if (methodBlob.method.IsCollectible) if (methodHolder.method.IsCollectible)
cachedDelegatesCollectible[functionPtr] = methodDelegate; cachedDelegatesCollectible[functionPtr] = methodDelegate;
else else
cachedDelegates[functionPtr] = methodDelegate; cachedDelegates[functionPtr] = methodDelegate;
@@ -2159,7 +2122,7 @@ namespace FlaxEngine
internal static void FieldSetValue(IntPtr fieldOwnerHandle, IntPtr fieldHandle, IntPtr valuePtr) internal static void FieldSetValue(IntPtr fieldOwnerHandle, IntPtr fieldHandle, IntPtr valuePtr)
{ {
object fieldOwner = GCHandle.FromIntPtr(fieldOwnerHandle).Target; object fieldOwner = GCHandle.FromIntPtr(fieldOwnerHandle).Target;
FieldBlob field = Unsafe.As<FieldBlob>(GCHandle.FromIntPtr(fieldHandle).Target); FieldHolder field = Unsafe.As<FieldHolder>(GCHandle.FromIntPtr(fieldHandle).Target);
field.field.SetValue(fieldOwner, Marshal.PtrToStructure(valuePtr, field.field.FieldType)); field.field.SetValue(fieldOwner, Marshal.PtrToStructure(valuePtr, field.field.FieldType));
} }
@@ -2167,7 +2130,7 @@ namespace FlaxEngine
internal static void FieldGetValue(IntPtr fieldOwnerHandle, IntPtr fieldHandle, IntPtr valuePtr) internal static void FieldGetValue(IntPtr fieldOwnerHandle, IntPtr fieldHandle, IntPtr valuePtr)
{ {
object fieldOwner = GCHandle.FromIntPtr(fieldOwnerHandle).Target; object fieldOwner = GCHandle.FromIntPtr(fieldOwnerHandle).Target;
FieldBlob field = Unsafe.As<FieldBlob>(GCHandle.FromIntPtr(fieldHandle).Target); FieldHolder field = Unsafe.As<FieldHolder>(GCHandle.FromIntPtr(fieldHandle).Target);
field.toNativeMarshaller(field.field, fieldOwner, valuePtr, out int fieldOffset); field.toNativeMarshaller(field.field, fieldOwner, valuePtr, out int fieldOffset);
} }
@@ -2364,8 +2327,8 @@ namespace FlaxEngine
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
internal static byte GetMethodParameterIsOut(IntPtr methodHandle, int parameterNum) internal static byte GetMethodParameterIsOut(IntPtr methodHandle, int parameterNum)
{ {
MethodBlob methodBlob = Unsafe.As<MethodBlob>(GCHandle.FromIntPtr(methodHandle).Target); MethodHolder methodHolder = Unsafe.As<MethodHolder>(GCHandle.FromIntPtr(methodHandle).Target);
ParameterInfo parameterInfo = methodBlob.method.GetParameters()[parameterNum]; ParameterInfo parameterInfo = methodHolder.method.GetParameters()[parameterNum];
return (byte)(parameterInfo.IsOut ? 1 : 0); return (byte)(parameterInfo.IsOut ? 1 : 0);
} }

View File

@@ -7,6 +7,7 @@ using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Diagnostics;
namespace FlaxEngine namespace FlaxEngine
{ {
@@ -80,6 +81,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -89,6 +91,7 @@ namespace FlaxEngine
return IntPtr.Zero; return IntPtr.Zero;
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -114,6 +117,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -132,6 +136,7 @@ namespace FlaxEngine
return IntPtr.Zero; return IntPtr.Zero;
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -159,6 +164,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -182,6 +188,7 @@ namespace FlaxEngine
return IntPtr.Zero; return IntPtr.Zero;
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -210,6 +217,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -238,6 +246,7 @@ namespace FlaxEngine
return IntPtr.Zero; return IntPtr.Zero;
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -267,6 +276,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -300,6 +310,7 @@ namespace FlaxEngine
return IntPtr.Zero; return IntPtr.Zero;
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -330,6 +341,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -339,6 +351,7 @@ namespace FlaxEngine
return IntPtr.Zero; return IntPtr.Zero;
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -364,6 +377,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -382,6 +396,7 @@ namespace FlaxEngine
return IntPtr.Zero; return IntPtr.Zero;
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -409,6 +424,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -432,6 +448,7 @@ namespace FlaxEngine
return IntPtr.Zero; return IntPtr.Zero;
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -460,6 +477,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -488,6 +506,7 @@ namespace FlaxEngine
return IntPtr.Zero; return IntPtr.Zero;
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -517,6 +536,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -550,6 +570,7 @@ namespace FlaxEngine
return IntPtr.Zero; return IntPtr.Zero;
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -580,6 +601,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -589,6 +611,7 @@ namespace FlaxEngine
return MarshalReturnValue(ref ret); return MarshalReturnValue(ref ret);
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -614,6 +637,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -632,6 +656,7 @@ namespace FlaxEngine
return MarshalReturnValue(ref ret); return MarshalReturnValue(ref ret);
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -659,6 +684,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -682,6 +708,7 @@ namespace FlaxEngine
return MarshalReturnValue(ref ret); return MarshalReturnValue(ref ret);
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -710,6 +737,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -738,6 +766,7 @@ namespace FlaxEngine
return MarshalReturnValue(ref ret); return MarshalReturnValue(ref ret);
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -767,6 +796,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -800,6 +830,7 @@ namespace FlaxEngine
return MarshalReturnValue(ref ret); return MarshalReturnValue(ref ret);
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -830,6 +861,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -839,6 +871,7 @@ namespace FlaxEngine
return MarshalReturnValue(ref ret); return MarshalReturnValue(ref ret);
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -864,6 +897,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -882,6 +916,7 @@ namespace FlaxEngine
return MarshalReturnValue(ref ret); return MarshalReturnValue(ref ret);
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -909,6 +944,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -932,6 +968,7 @@ namespace FlaxEngine
return MarshalReturnValue(ref ret); return MarshalReturnValue(ref ret);
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -960,6 +997,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -988,6 +1026,7 @@ namespace FlaxEngine
return MarshalReturnValue(ref ret); return MarshalReturnValue(ref ret);
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -1017,6 +1056,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false)); return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
} }
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr) internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
{ {
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext); (Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -1050,6 +1090,7 @@ namespace FlaxEngine
return MarshalReturnValue(ref ret); return MarshalReturnValue(ref ret);
} }
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs) internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{ {
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext); ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);

View File

@@ -26,7 +26,7 @@ struct CoreCLRProperty;
struct CoreCLRClass; struct CoreCLRClass;
// Structures used to pass information from runtime, must match with the structures in managed side // Structures used to pass information from runtime, must match with the structures in managed side
struct ManagedClass struct NativeClassDefinitions
{ {
void* typeHandle; void* typeHandle;
const char* name; const char* name;
@@ -35,7 +35,7 @@ struct ManagedClass
uint32 typeAttributes; uint32 typeAttributes;
}; };
struct ClassMethod struct NativeMethodDefinitions
{ {
const char* name; const char* name;
int numParameters; int numParameters;
@@ -43,7 +43,7 @@ struct ClassMethod
uint32 methodAttributes; uint32 methodAttributes;
}; };
struct ClassField struct NativeFieldDefinitions
{ {
const char* name; const char* name;
void* fieldHandle; void* fieldHandle;
@@ -51,7 +51,7 @@ struct ClassField
uint32 fieldAttributes; uint32 fieldAttributes;
}; };
struct ClassProperty struct NativePropertyDefinitions
{ {
const char* name; const char* name;
void* getterHandle; void* getterHandle;
@@ -88,9 +88,9 @@ public:
_name = name; _name = name;
_fullname = fullname; _fullname = fullname;
ManagedClass* managedClasses; NativeClassDefinitions* managedClasses;
int classCount; int classCount;
CoreCLR::CallStaticMethod<void, void*, ManagedClass**, int*>(GetManagedClassesPtr, _assemblyHandle, &managedClasses, &classCount); CoreCLR::CallStaticMethod<void, void*, NativeClassDefinitions**, int*>(GetManagedClassesPtr, _assemblyHandle, &managedClasses, &classCount);
for (int i = 0; i < classCount; i++) for (int i = 0; i < classCount; i++)
{ {
CoreCLRClass* mci = New<CoreCLRClass>(managedClasses[i].typeHandle, StringAnsi(managedClasses[i].name), StringAnsi(managedClasses[i].fullname), StringAnsi(managedClasses[i].namespace_), managedClasses[i].typeAttributes, this); CoreCLRClass* mci = New<CoreCLRClass>(managedClasses[i].typeHandle, StringAnsi(managedClasses[i].name), StringAnsi(managedClasses[i].fullname), StringAnsi(managedClasses[i].namespace_), managedClasses[i].typeAttributes, this);
@@ -233,9 +233,9 @@ public:
static void* GetClassMethodsPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassMethods")); static void* GetClassMethodsPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassMethods"));
ClassMethod* foundMethods; NativeMethodDefinitions* foundMethods;
int numMethods; int numMethods;
CoreCLR::CallStaticMethod<void, void*, ClassMethod**, int*>(GetClassMethodsPtr, _typeHandle, &foundMethods, &numMethods); CoreCLR::CallStaticMethod<void, void*, NativeMethodDefinitions**, int*>(GetClassMethodsPtr, _typeHandle, &foundMethods, &numMethods);
for (int i = 0; i < numMethods; i++) for (int i = 0; i < numMethods; i++)
{ {
CoreCLRMethod* method = New<CoreCLRMethod>(StringAnsi(foundMethods[i].name), foundMethods[i].numParameters, foundMethods[i].handle, foundMethods[i].methodAttributes, this); CoreCLRMethod* method = New<CoreCLRMethod>(StringAnsi(foundMethods[i].name), foundMethods[i].numParameters, foundMethods[i].handle, foundMethods[i].methodAttributes, this);
@@ -256,9 +256,9 @@ public:
static void* GetClassFieldsPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassFields")); static void* GetClassFieldsPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassFields"));
ClassField* foundFields; NativeFieldDefinitions* foundFields;
int numFields; int numFields;
CoreCLR::CallStaticMethod<void, void*, ClassField**, int*>(GetClassFieldsPtr, _typeHandle, &foundFields, &numFields); CoreCLR::CallStaticMethod<void, void*, NativeFieldDefinitions**, int*>(GetClassFieldsPtr, _typeHandle, &foundFields, &numFields);
for (int i = 0; i < numFields; i++) for (int i = 0; i < numFields; i++)
{ {
CoreCLRField* field = New<CoreCLRField>(StringAnsi(foundFields[i].name), foundFields[i].fieldHandle, foundFields[i].fieldType, foundFields[i].fieldAttributes, this); CoreCLRField* field = New<CoreCLRField>(StringAnsi(foundFields[i].name), foundFields[i].fieldHandle, foundFields[i].fieldType, foundFields[i].fieldAttributes, this);
@@ -279,9 +279,9 @@ public:
static void* GetClassPropertiesPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassProperties")); static void* GetClassPropertiesPtr = CoreCLR::GetStaticMethodPointer(TEXT("GetClassProperties"));
ClassProperty* foundProperties; NativePropertyDefinitions* foundProperties;
int numProperties; int numProperties;
CoreCLR::CallStaticMethod<void, void*, ClassProperty**, int*>(GetClassPropertiesPtr, _typeHandle, &foundProperties, &numProperties); CoreCLR::CallStaticMethod<void, void*, NativePropertyDefinitions**, int*>(GetClassPropertiesPtr, _typeHandle, &foundProperties, &numProperties);
for (int i = 0; i < numProperties; i++) for (int i = 0; i < numProperties; i++)
{ {
CoreCLRProperty* prop = New<CoreCLRProperty>(StringAnsi(foundProperties[i].name), foundProperties[i].getterHandle, foundProperties[i].setterHandle, foundProperties[i].getterFlags, foundProperties[i].setterFlags, this); CoreCLRProperty* prop = New<CoreCLRProperty>(StringAnsi(foundProperties[i].name), foundProperties[i].getterHandle, foundProperties[i].setterHandle, foundProperties[i].getterFlags, foundProperties[i].setterFlags, this);
@@ -543,7 +543,7 @@ CoreCLRClass* GetOrCreateClass(void* type)
{ {
static void* GetManagedClassFromTypePtr = CoreCLR::GetStaticMethodPointer(TEXT("GetManagedClassFromType")); static void* GetManagedClassFromTypePtr = CoreCLR::GetStaticMethodPointer(TEXT("GetManagedClassFromType"));
ManagedClass classInfo; NativeClassDefinitions classInfo;
void* assemblyHandle; void* assemblyHandle;
CoreCLR::CallStaticMethod<void, void*, void*>(GetManagedClassFromTypePtr, type, &classInfo, &assemblyHandle); CoreCLR::CallStaticMethod<void, void*, void*>(GetManagedClassFromTypePtr, type, &classInfo, &assemblyHandle);
CoreCLRAssembly* image = GetAssembly(assemblyHandle); CoreCLRAssembly* image = GetAssembly(assemblyHandle);