Optimize allocations in return values from invoked managed methods

This commit is contained in:
2022-12-21 22:09:57 +02:00
parent b449353d2f
commit e71e6835de
2 changed files with 139 additions and 118 deletions

View File

@@ -1964,13 +1964,14 @@ namespace FlaxEngine
{
MethodBlob methodBlob = Unsafe.As<MethodBlob>(GCHandle.FromIntPtr(methodHandle).Target);
object returnObject;
if (methodBlob.TryGetDelegate(out var methodDelegate, out var methodDelegateContext))
{
// Fast path, invoke the method with minimal allocations
IntPtr returnValue;
try
{
returnObject = methodDelegate(methodDelegateContext, instancePtr, paramPtr);
returnValue = methodDelegate(methodDelegateContext, instancePtr, paramPtr);
}
catch (Exception exception)
{
@@ -1980,10 +1981,12 @@ namespace FlaxEngine
Marshal.WriteIntPtr(exceptionPtr, GCHandle.ToIntPtr(GCHandle.Alloc(exception, GCHandleType.Weak)));
return IntPtr.Zero;
}
return returnValue;
}
else
{
// Slow path, method parameters needs to be stored in heap
object returnObject;
int numParams = methodBlob.parameterTypes.Length;
IntPtr* nativePtrs = stackalloc IntPtr[numParams];
object[] methodParameters = new object[numParams];
@@ -2022,24 +2025,24 @@ namespace FlaxEngine
if (parameterType.IsByRef)
MarshalToNative(methodParameters[i], nativePtrs[i], parameterType.GetElementType());
}
}
if (returnObject is not null)
{
if (methodBlob.method.ReturnType == typeof(string))
return ManagedString.ToNative(Unsafe.As<string>(returnObject));
else if (methodBlob.method.ReturnType == typeof(IntPtr))
return (IntPtr)returnObject;
else if (methodBlob.method.ReturnType == typeof(bool))
return (bool)returnObject ? boolTruePtr : boolFalsePtr;
else if (methodBlob.method.ReturnType == typeof(Type))
return GCHandle.ToIntPtr(GetOrAddTypeGCHandle(Unsafe.As<Type>(returnObject)));
else if (methodBlob.method.ReturnType == typeof(object[]))
return GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.Get(ManagedArrayToGCHandleArray(Unsafe.As<object[]>(returnObject))), GCHandleType.Weak));
else
return GCHandle.ToIntPtr(GCHandle.Alloc(returnObject, GCHandleType.Weak));
if (returnObject is not null)
{
if (methodBlob.method.ReturnType == typeof(string))
return ManagedString.ToNative(Unsafe.As<string>(returnObject));
else if (methodBlob.method.ReturnType == typeof(IntPtr))
return (IntPtr)returnObject;
else if (methodBlob.method.ReturnType == typeof(bool))
return (bool)returnObject ? boolTruePtr : boolFalsePtr;
else if (methodBlob.method.ReturnType == typeof(Type))
return GCHandle.ToIntPtr(GetOrAddTypeGCHandle(Unsafe.As<Type>(returnObject)));
else if (methodBlob.method.ReturnType == typeof(object[]))
return GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.Get(ManagedArrayToGCHandleArray(Unsafe.As<object[]>(returnObject))), GCHandleType.Weak));
else
return GCHandle.ToIntPtr(GCHandle.Alloc(returnObject, GCHandleType.Weak));
}
return IntPtr.Zero;
}
return IntPtr.Zero;
}
[UnmanagedCallersOnly]
@@ -2589,13 +2592,13 @@ namespace FlaxEngine
public IntPtr InvokeThunk(IntPtr instancePtr, IntPtr param1, IntPtr param2, IntPtr param3, IntPtr param4, IntPtr param5, IntPtr param6, IntPtr param7)
{
IntPtr* nativePtrs = stackalloc IntPtr[] { param1, param2, param3, param4, param5, param6, param7 };
object returnObject;
if (methodDelegate != null)
{
IntPtr returnValue;
try
{
returnObject = methodDelegate(methodDelegateContext, instancePtr, nativePtrs);
returnValue = methodDelegate(methodDelegateContext, instancePtr, nativePtrs);
}
catch (Exception exception)
{
@@ -2607,10 +2610,12 @@ namespace FlaxEngine
Marshal.WriteIntPtr(exceptionPtr, GCHandle.ToIntPtr(GCHandle.Alloc(exception, GCHandleType.Weak)));
return IntPtr.Zero;
}
return returnValue;
}
else
{
// The parameters are wrapped in GCHandles
object returnObject;
int numParams = parameterTypes.Length;
object[] methodParameters = new object[numParams];
for (int i = 0; i < numParams; i++)
@@ -2630,24 +2635,24 @@ namespace FlaxEngine
Marshal.WriteIntPtr(exceptionPtr, GCHandle.ToIntPtr(GCHandle.Alloc(exception, GCHandleType.Weak)));
return IntPtr.Zero;
}
}
if (returnObject is not null)
{
if (method.ReturnType == typeof(string))
return ManagedString.ToNative(Unsafe.As<string>(returnObject));
else if (method.ReturnType == typeof(IntPtr))
return (IntPtr)returnObject;
else if (method.ReturnType == typeof(bool))
return (bool)returnObject ? boolTruePtr : boolFalsePtr;
else if (method.ReturnType == typeof(Type))
return GCHandle.ToIntPtr(GetOrAddTypeGCHandle(Unsafe.As<Type>(returnObject)));
else if (method.ReturnType == typeof(object[]))
return GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.Get(ManagedArrayToGCHandleArray(Unsafe.As<object[]>(returnObject))), GCHandleType.Weak));
else
return GCHandle.ToIntPtr(GCHandle.Alloc(returnObject, GCHandleType.Weak));
if (returnObject is not null)
{
if (method.ReturnType == typeof(string))
return ManagedString.ToNative(Unsafe.As<string>(returnObject));
else if (method.ReturnType == typeof(IntPtr))
return (IntPtr)returnObject;
else if (method.ReturnType == typeof(bool))
return (bool)returnObject ? boolTruePtr : boolFalsePtr;
else if (method.ReturnType == typeof(Type))
return GCHandle.ToIntPtr(GetOrAddTypeGCHandle(Unsafe.As<Type>(returnObject)));
else if (method.ReturnType == typeof(object[]))
return GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.Get(ManagedArrayToGCHandleArray(Unsafe.As<object[]>(returnObject))), GCHandleType.Weak));
else
return GCHandle.ToIntPtr(GCHandle.Alloc(returnObject, GCHandleType.Weak));
}
return IntPtr.Zero;
}
return IntPtr.Zero;
}
}
}

View File

@@ -14,8 +14,8 @@ namespace FlaxEngine
{
internal static class Invoker
{
internal delegate object MarshalAndInvokeDelegate(object delegateContext, IntPtr instancePtr, IntPtr paramPtr);
internal delegate object InvokeThunkDelegate(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs);
internal delegate IntPtr MarshalAndInvokeDelegate(object delegateContext, IntPtr instancePtr, IntPtr paramPtr);
internal delegate IntPtr InvokeThunkDelegate(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs);
internal static T* ToPointer<T>(IntPtr ptr) where T : unmanaged
{
@@ -48,6 +48,22 @@ namespace FlaxEngine
return lambda.Compile();
}
internal static IntPtr MarshalReturnValue<TRet>(ref TRet returnValue)
{
if (typeof(TRet) == typeof(string))
return ManagedString.ToNative(Unsafe.As<string>(returnValue));
else if (typeof(TRet) == typeof(IntPtr))
return (IntPtr)(object)returnValue;
else if (typeof(TRet) == typeof(bool))
return (bool)(object)returnValue ? boolTruePtr : boolFalsePtr;
else if (typeof(TRet) == typeof(Type))
return returnValue != null ? GCHandle.ToIntPtr(GetOrAddTypeGCHandle(Unsafe.As<Type>(returnValue))) : IntPtr.Zero;
else if (typeof(TRet) == typeof(object[]))
return returnValue != null ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.Get(ManagedArrayToGCHandleArray(Unsafe.As<object[]>(returnValue))), GCHandleType.Weak)) : IntPtr.Zero;
else
return returnValue != null ? GCHandle.ToIntPtr(GCHandle.Alloc(returnValue, GCHandleType.Weak)) : IntPtr.Zero;
}
internal static class InvokerNoRet0<TInstance>
{
@@ -64,22 +80,22 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
deleg(GCHandle.FromIntPtr(instancePtr).Target);
return null;
return IntPtr.Zero;
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
deleg(GCHandle.FromIntPtr(instancePtr).Target);
return null;
return IntPtr.Zero;
}
}
@@ -98,7 +114,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -113,10 +129,10 @@ namespace FlaxEngine
if (types[0].IsByRef)
MarshalHelper<T1>.ToNative(ref param1, param1Ptr);
return null;
return IntPtr.Zero;
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -124,7 +140,7 @@ namespace FlaxEngine
deleg(GCHandle.FromIntPtr(instancePtr).Target, param1);
return null;
return IntPtr.Zero;
}
}
@@ -143,7 +159,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -163,10 +179,10 @@ namespace FlaxEngine
if (types[1].IsByRef)
MarshalHelper<T2>.ToNative(ref param2, param2Ptr);
return null;
return IntPtr.Zero;
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -175,7 +191,7 @@ namespace FlaxEngine
deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2);
return null;
return IntPtr.Zero;
}
}
@@ -194,7 +210,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -219,10 +235,10 @@ namespace FlaxEngine
if (types[2].IsByRef)
MarshalHelper<T3>.ToNative(ref param3, param3Ptr);
return null;
return IntPtr.Zero;
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -232,7 +248,7 @@ namespace FlaxEngine
deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2, param3);
return null;
return IntPtr.Zero;
}
}
@@ -251,7 +267,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -281,10 +297,10 @@ namespace FlaxEngine
if (types[3].IsByRef)
MarshalHelper<T4>.ToNative(ref param4, param4Ptr);
return null;
return IntPtr.Zero;
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -295,7 +311,7 @@ namespace FlaxEngine
deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2, param3, param4);
return null;
return IntPtr.Zero;
}
}
@@ -314,22 +330,22 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
deleg();
return null;
return IntPtr.Zero;
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
deleg();
return null;
return IntPtr.Zero;
}
}
@@ -348,7 +364,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -363,10 +379,10 @@ namespace FlaxEngine
if (types[0].IsByRef)
MarshalHelper<T1>.ToNative(ref param1, param1Ptr);
return null;
return IntPtr.Zero;
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -374,7 +390,7 @@ namespace FlaxEngine
deleg(param1);
return null;
return IntPtr.Zero;
}
}
@@ -393,7 +409,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -413,10 +429,10 @@ namespace FlaxEngine
if (types[1].IsByRef)
MarshalHelper<T2>.ToNative(ref param2, param2Ptr);
return null;
return IntPtr.Zero;
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -425,7 +441,7 @@ namespace FlaxEngine
deleg(param1, param2);
return null;
return IntPtr.Zero;
}
}
@@ -444,7 +460,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -469,10 +485,10 @@ namespace FlaxEngine
if (types[2].IsByRef)
MarshalHelper<T3>.ToNative(ref param3, param3Ptr);
return null;
return IntPtr.Zero;
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -482,7 +498,7 @@ namespace FlaxEngine
deleg(param1, param2, param3);
return null;
return IntPtr.Zero;
}
}
@@ -501,7 +517,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -531,10 +547,10 @@ namespace FlaxEngine
if (types[3].IsByRef)
MarshalHelper<T4>.ToNative(ref param4, param4Ptr);
return null;
return IntPtr.Zero;
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -545,7 +561,7 @@ namespace FlaxEngine
deleg(param1, param2, param3, param4);
return null;
return IntPtr.Zero;
}
}
@@ -564,22 +580,22 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target);
return ret;
return MarshalReturnValue(ref ret);
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target);
return ret;
return MarshalReturnValue(ref ret);
}
}
@@ -598,7 +614,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -613,10 +629,10 @@ namespace FlaxEngine
if (types[0].IsByRef)
MarshalHelper<T1>.ToNative(ref param1, param1Ptr);
return ret;
return MarshalReturnValue(ref ret);
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -624,7 +640,7 @@ namespace FlaxEngine
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, param1);
return ret;
return MarshalReturnValue(ref ret);
}
}
@@ -643,7 +659,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -663,10 +679,10 @@ namespace FlaxEngine
if (types[1].IsByRef)
MarshalHelper<T2>.ToNative(ref param2, param2Ptr);
return ret;
return MarshalReturnValue(ref ret);
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -675,7 +691,7 @@ namespace FlaxEngine
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2);
return ret;
return MarshalReturnValue(ref ret);
}
}
@@ -694,7 +710,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -719,10 +735,10 @@ namespace FlaxEngine
if (types[2].IsByRef)
MarshalHelper<T3>.ToNative(ref param3, param3Ptr);
return ret;
return MarshalReturnValue(ref ret);
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -732,7 +748,7 @@ namespace FlaxEngine
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2, param3);
return ret;
return MarshalReturnValue(ref ret);
}
}
@@ -751,7 +767,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -781,10 +797,10 @@ namespace FlaxEngine
if (types[3].IsByRef)
MarshalHelper<T4>.ToNative(ref param4, param4Ptr);
return ret;
return MarshalReturnValue(ref ret);
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -795,7 +811,7 @@ namespace FlaxEngine
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2, param3, param4);
return ret;
return MarshalReturnValue(ref ret);
}
}
@@ -814,22 +830,22 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
TRet ret = deleg();
return ret;
return MarshalReturnValue(ref ret);
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
TRet ret = deleg();
return ret;
return MarshalReturnValue(ref ret);
}
}
@@ -848,7 +864,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -863,10 +879,10 @@ namespace FlaxEngine
if (types[0].IsByRef)
MarshalHelper<T1>.ToNative(ref param1, param1Ptr);
return ret;
return MarshalReturnValue(ref ret);
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -874,7 +890,7 @@ namespace FlaxEngine
TRet ret = deleg(param1);
return ret;
return MarshalReturnValue(ref ret);
}
}
@@ -893,7 +909,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -913,10 +929,10 @@ namespace FlaxEngine
if (types[1].IsByRef)
MarshalHelper<T2>.ToNative(ref param2, param2Ptr);
return ret;
return MarshalReturnValue(ref ret);
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -925,7 +941,7 @@ namespace FlaxEngine
TRet ret = deleg(param1, param2);
return ret;
return MarshalReturnValue(ref ret);
}
}
@@ -944,7 +960,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -969,10 +985,10 @@ namespace FlaxEngine
if (types[2].IsByRef)
MarshalHelper<T3>.ToNative(ref param3, param3Ptr);
return ret;
return MarshalReturnValue(ref ret);
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -982,7 +998,7 @@ namespace FlaxEngine
TRet ret = deleg(param1, param2, param3);
return ret;
return MarshalReturnValue(ref ret);
}
}
@@ -1001,7 +1017,7 @@ namespace FlaxEngine
return Unsafe.As<ThunkInvokerDelegate>(CreateDelegateFromMethod(method, false));
}
internal static object 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);
@@ -1031,10 +1047,10 @@ namespace FlaxEngine
if (types[3].IsByRef)
MarshalHelper<T4>.ToNative(ref param4, param4Ptr);
return ret;
return MarshalReturnValue(ref ret);
}
internal static unsafe object InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -1045,7 +1061,7 @@ namespace FlaxEngine
TRet ret = deleg(param1, param2, param3, param4);
return ret;
return MarshalReturnValue(ref ret);
}
}
}