|
|
|
|
@@ -107,17 +107,13 @@ namespace FlaxEngine.Interop
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !USE_AOT
|
|
|
|
|
#if !USE_AOT && !DOTNET_HOST_MONO
|
|
|
|
|
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "__unmanagedPtr")]
|
|
|
|
|
extern static ref IntPtr GetUnmanagedPtrFieldReference(Object obj);
|
|
|
|
|
|
|
|
|
|
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "__internalId")]
|
|
|
|
|
extern static ref Guid GetInternalIdFieldReference(Object obj);
|
|
|
|
|
|
|
|
|
|
// Cache offsets to frequently accessed fields of FlaxEngine.Object
|
|
|
|
|
private static int unmanagedPtrFieldOffset = IntPtr.Size + (Unsafe.Read<int>((typeof(FlaxEngine.Object).GetField("__unmanagedPtr", BindingFlags.Instance | BindingFlags.NonPublic).FieldHandle.Value + 4 + IntPtr.Size).ToPointer()) & 0xFFFFFF);
|
|
|
|
|
private static int internalIdFieldOffset = IntPtr.Size + (Unsafe.Read<int>((typeof(FlaxEngine.Object).GetField("__internalId", BindingFlags.Instance | BindingFlags.NonPublic).FieldHandle.Value + 4 + IntPtr.Size).ToPointer()) & 0xFFFFFF);
|
|
|
|
|
|
|
|
|
|
[UnmanagedCallersOnly]
|
|
|
|
|
internal static void ScriptingObjectSetInternalValues(ManagedHandle objectHandle, IntPtr unmanagedPtr, IntPtr idPtr)
|
|
|
|
|
{
|
|
|
|
|
@@ -418,14 +414,21 @@ namespace FlaxEngine.Interop
|
|
|
|
|
if (field.IsLiteral)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
#if DOTNET_HOST_CORECLR
|
|
|
|
|
// Get the address of the field, source: https://stackoverflow.com/a/56512720
|
|
|
|
|
int fieldOffset = Unsafe.Read<int>((field.FieldHandle.Value + 4 + IntPtr.Size).ToPointer()) & 0xFFFFFF;
|
|
|
|
|
if (!type.IsValueType)
|
|
|
|
|
fieldOffset += IntPtr.Size;
|
|
|
|
|
return fieldOffset;
|
|
|
|
|
#elif DOTNET_HOST_MONO
|
|
|
|
|
// Get the address from _MonoClassField::offset, source: https://meetemq.com/2023/09/10/nets-fields-and-their-offsets/
|
|
|
|
|
IntPtr fieldOffsetPtr = (IntPtr*)field.FieldHandle.Value; // Pointer to MonoClassField
|
|
|
|
|
fieldOffsetPtr += 3; // Skip three pointers (type, name, parent_and_flags)
|
|
|
|
|
return *(int*)fieldOffsetPtr - IntPtr.Size * 2; // Load the value of a pointer (4 bytes, int32), then subtracting 16 bytes from it (2 pointers for vtable and threadsync)
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Helper utility to set field of the referenced value via reflection.
|
|
|
|
|
/// </summary>
|
|
|
|
|
@@ -756,12 +759,12 @@ namespace FlaxEngine.Interop
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
throw new NativeInteropException($"Invalid field with offset {fieldOffset} to marshal for type {typeof(T).Name}");
|
|
|
|
|
throw new NativeInteropException($"Invalid field with offset {fieldOffset} to marshal for type {typeof(T).FullName}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void ToManagedFieldPointerValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct
|
|
|
|
|
{
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
IntPtr fieldValue = Unsafe.Read<IntPtr>(nativeFieldPtr.ToPointer());
|
|
|
|
|
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, fieldValue);
|
|
|
|
|
#else
|
|
|
|
|
@@ -773,7 +776,7 @@ namespace FlaxEngine.Interop
|
|
|
|
|
|
|
|
|
|
private static void ToManagedFieldPointerReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class
|
|
|
|
|
{
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
IntPtr fieldValue = Unsafe.Read<IntPtr>(nativeFieldPtr.ToPointer());
|
|
|
|
|
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, fieldValue);
|
|
|
|
|
#else
|
|
|
|
|
@@ -785,7 +788,7 @@ namespace FlaxEngine.Interop
|
|
|
|
|
|
|
|
|
|
private static void ToNativeFieldPointerValueType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : struct
|
|
|
|
|
{
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
object boxed = field.GetValue(fieldOwner);
|
|
|
|
|
IntPtr fieldValue = new IntPtr(Pointer.Unbox(boxed));
|
|
|
|
|
#else
|
|
|
|
|
@@ -797,7 +800,7 @@ namespace FlaxEngine.Interop
|
|
|
|
|
|
|
|
|
|
private static void ToNativeFieldPointerReferenceType(FieldInfo field, int fieldOffset, ref T fieldOwner, IntPtr nativeFieldPtr, out int fieldSize) // where T : class
|
|
|
|
|
{
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
object boxed = field.GetValue(fieldOwner);
|
|
|
|
|
IntPtr fieldValue = new IntPtr(Pointer.Unbox(boxed));
|
|
|
|
|
#else
|
|
|
|
|
@@ -845,13 +848,13 @@ namespace FlaxEngine.Interop
|
|
|
|
|
fieldSize += (nativeFieldPtr - fieldStartPtr).ToInt32();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
TField fieldValue = default;
|
|
|
|
|
#else
|
|
|
|
|
ref TField fieldValue = ref FieldHelper.GetValueTypeFieldReference<T, TField>(fieldOffset, ref fieldOwner);
|
|
|
|
|
#endif
|
|
|
|
|
MarshalHelper<TField>.ToManaged(ref fieldValue, nativeFieldPtr, false);
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, fieldValue);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
@@ -866,13 +869,13 @@ namespace FlaxEngine.Interop
|
|
|
|
|
fieldSize += (nativeFieldPtr - fieldStartPtr).ToInt32();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
TField fieldValue = default;
|
|
|
|
|
#else
|
|
|
|
|
ref TField fieldValue = ref FieldHelper.GetReferenceTypeFieldReference<T, TField>(fieldOffset, ref fieldOwner);
|
|
|
|
|
#endif
|
|
|
|
|
MarshalHelper<TField>.ToManaged(ref fieldValue, nativeFieldPtr, false);
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, fieldValue);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
@@ -885,13 +888,13 @@ namespace FlaxEngine.Interop
|
|
|
|
|
nativeFieldPtr = EnsureAlignment(nativeFieldPtr, IntPtr.Size);
|
|
|
|
|
fieldSize += (nativeFieldPtr - fieldStartPtr).ToInt32();
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
TField[] fieldValue = (TField[])field.GetValue(fieldOwner);
|
|
|
|
|
#else
|
|
|
|
|
ref TField[] fieldValue = ref FieldHelper.GetValueTypeFieldReference<T, TField[]>(fieldOffset, ref fieldOwner);
|
|
|
|
|
#endif
|
|
|
|
|
MarshalHelper<TField[]>.ToManaged(ref fieldValue, Unsafe.Read<IntPtr>(nativeFieldPtr.ToPointer()), false);
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, fieldValue);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
@@ -904,13 +907,13 @@ namespace FlaxEngine.Interop
|
|
|
|
|
nativeFieldPtr = EnsureAlignment(nativeFieldPtr, IntPtr.Size);
|
|
|
|
|
fieldSize += (nativeFieldPtr - fieldStartPtr).ToInt32();
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
TField[] fieldValue = null;
|
|
|
|
|
#else
|
|
|
|
|
ref TField[] fieldValue = ref FieldHelper.GetReferenceTypeFieldReference<T, TField[]>(fieldOffset, ref fieldOwner);
|
|
|
|
|
#endif
|
|
|
|
|
MarshalHelper<TField[]>.ToManaged(ref fieldValue, Unsafe.Read<IntPtr>(nativeFieldPtr.ToPointer()), false);
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, fieldValue);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
@@ -925,7 +928,7 @@ namespace FlaxEngine.Interop
|
|
|
|
|
fieldSize += (nativeFieldPtr - startPtr).ToInt32();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
TField fieldValue = (TField)field.GetValue(fieldOwner);
|
|
|
|
|
#else
|
|
|
|
|
ref TField fieldValue = ref FieldHelper.GetValueTypeFieldReference<T, TField>(fieldOffset, ref fieldOwner);
|
|
|
|
|
@@ -978,13 +981,13 @@ namespace FlaxEngine.Interop
|
|
|
|
|
nativeFieldPtr = EnsureAlignment(nativeFieldPtr, IntPtr.Size);
|
|
|
|
|
fieldSize += (nativeFieldPtr - fieldStartPtr).ToInt32();
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
TField fieldValue = null;
|
|
|
|
|
#else
|
|
|
|
|
ref TField fieldValue = ref FieldHelper.GetValueTypeFieldReference<T, TField>(fieldOffset, ref fieldOwner);
|
|
|
|
|
#endif
|
|
|
|
|
MarshalHelper<TField>.ToManaged(ref fieldValue, Unsafe.Read<IntPtr>(nativeFieldPtr.ToPointer()), false);
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, fieldValue);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
@@ -996,13 +999,13 @@ namespace FlaxEngine.Interop
|
|
|
|
|
nativeFieldPtr = EnsureAlignment(nativeFieldPtr, IntPtr.Size);
|
|
|
|
|
fieldSize += (nativeFieldPtr - fieldStartPtr).ToInt32();
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
TField fieldValue = default;
|
|
|
|
|
#else
|
|
|
|
|
ref TField fieldValue = ref FieldHelper.GetReferenceTypeFieldReference<T, TField>(fieldOffset, ref fieldOwner);
|
|
|
|
|
#endif
|
|
|
|
|
MarshalHelper<TField>.ToManaged(ref fieldValue, Unsafe.Read<IntPtr>(nativeFieldPtr.ToPointer()), false);
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, fieldValue);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
@@ -1014,13 +1017,13 @@ namespace FlaxEngine.Interop
|
|
|
|
|
nativeFieldPtr = EnsureAlignment(nativeFieldPtr, IntPtr.Size);
|
|
|
|
|
fieldSize += (nativeFieldPtr - fieldStartPtr).ToInt32();
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
TField[] fieldValue = null;
|
|
|
|
|
#else
|
|
|
|
|
ref TField[] fieldValue = ref FieldHelper.GetValueTypeFieldReference<T, TField[]>(fieldOffset, ref fieldOwner);
|
|
|
|
|
#endif
|
|
|
|
|
MarshalHelper<TField[]>.ToManaged(ref fieldValue, Unsafe.Read<IntPtr>(nativeFieldPtr.ToPointer()), false);
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, fieldValue);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
@@ -1032,13 +1035,13 @@ namespace FlaxEngine.Interop
|
|
|
|
|
nativeFieldPtr = EnsureAlignment(nativeFieldPtr, IntPtr.Size);
|
|
|
|
|
fieldSize += (nativeFieldPtr - fieldStartPtr).ToInt32();
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
TField[] fieldValue = null;
|
|
|
|
|
#else
|
|
|
|
|
ref TField[] fieldValue = ref FieldHelper.GetReferenceTypeFieldReference<T, TField[]>(fieldOffset, ref fieldOwner);
|
|
|
|
|
#endif
|
|
|
|
|
MarshalHelper<TField[]>.ToManaged(ref fieldValue, Unsafe.Read<IntPtr>(nativeFieldPtr.ToPointer()), false);
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
FieldHelper.SetReferenceTypeField(field, ref fieldOwner, fieldValue);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
@@ -1050,7 +1053,7 @@ namespace FlaxEngine.Interop
|
|
|
|
|
nativeFieldPtr = EnsureAlignment(nativeFieldPtr, IntPtr.Size);
|
|
|
|
|
fieldSize += (nativeFieldPtr - fieldStartPtr).ToInt32();
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
TField fieldValue = (TField)field.GetValue(fieldOwner);
|
|
|
|
|
#else
|
|
|
|
|
ref TField fieldValue = ref FieldHelper.GetValueTypeFieldReference<T, TField>(fieldOffset, ref fieldOwner);
|
|
|
|
|
@@ -1065,7 +1068,7 @@ namespace FlaxEngine.Interop
|
|
|
|
|
nativeFieldPtr = EnsureAlignment(nativeFieldPtr, IntPtr.Size);
|
|
|
|
|
fieldSize += (nativeFieldPtr - fieldStartPtr).ToInt32();
|
|
|
|
|
|
|
|
|
|
#if USE_AOT
|
|
|
|
|
#if USE_AOT || DOTNET_HOST_MONO
|
|
|
|
|
TField fieldValue = (TField)field.GetValue(fieldOwner);
|
|
|
|
|
#else
|
|
|
|
|
ref TField fieldValue = ref FieldHelper.GetReferenceTypeFieldReference<T, TField>(fieldOffset, ref fieldOwner);
|
|
|
|
|
@@ -1439,7 +1442,7 @@ namespace FlaxEngine.Interop
|
|
|
|
|
return RuntimeHelpers.GetUninitializedObject(wrappedType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !USE_AOT
|
|
|
|
|
#if !USE_AOT && !DOTNET_HOST_MONO
|
|
|
|
|
internal object CreateScriptingObject(IntPtr unmanagedPtr, IntPtr idPtr)
|
|
|
|
|
{
|
|
|
|
|
object obj = RuntimeHelpers.GetUninitializedObject(wrappedType);
|
|
|
|
|
|