Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Il2CppInterop.Runtime/IL2CPP.cs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,27 @@ public static void FieldWriteWbarrierStub(IntPtr obj, IntPtr targetAddress, IntP
*(IntPtr*)targetAddress = value;
}

private static volatile bool s_fieldWriteWbarrierAvailable = true;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void FieldWriteWbarrier(IntPtr obj, IntPtr targetAddress, IntPtr value)
{
if (s_fieldWriteWbarrierAvailable)
{
try
{
il2cpp_gc_wbarrier_set_field(obj, targetAddress, value);
return;
}
catch (EntryPointNotFoundException)
{
s_fieldWriteWbarrierAvailable = false;
}
}

FieldWriteWbarrierStub(obj, targetAddress, value);
}

// IL2CPP Functions
[DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void il2cpp_init(IntPtr domain_name);
Expand Down
11 changes: 8 additions & 3 deletions Il2CppInterop.Runtime/Injection/ClassInjector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ public static void RegisterTypeInIl2Cpp(Type type, RegisterTypeOptions options)
.Where(IsFieldEligible)
.ToArray();
classPointer.FieldCount = (ushort)fieldsToInject.Length;
classPointer.HasReferences = baseClassPointer.HasReferences;

var il2cppFields =
(Il2CppFieldInfo*)Marshal.AllocHGlobal(classPointer.FieldCount * UnityVersionHandler.FieldInfoSize());
Expand All @@ -266,6 +267,9 @@ public static void RegisterTypeInIl2Cpp(Type type, RegisterTypeOptions options)
: fieldsToInject[i].FieldType.GenericTypeArguments[0];
var fieldAttributes = fieldsToInject[i].Attributes;
var fieldInfoClass = Il2CppClassPointerStore.GetNativeClassPointer(fieldType);
if (fieldInfoClass == IntPtr.Zero)
throw new Exception($"Type {fieldType} in {type}.{fieldsToInject[i].Name} doesn't exist in Il2Cpp");

if (!_injectedFieldTypes.TryGetValue((fieldType, fieldAttributes), out var fieldTypePtr))
{
var classType =
Expand All @@ -283,10 +287,11 @@ public static void RegisterTypeInIl2Cpp(Type type, RegisterTypeOptions options)
}

fieldInfo.Type = (Il2CppTypeStruct*)fieldTypePtr;
if (fieldInfoClass == IntPtr.Zero)
throw new Exception($"Type {fieldType} in {type}.{fieldsToInject[i].Name} doesn't exist in Il2Cpp");
var fieldIsValueType = IL2CPP.il2cpp_class_is_valuetype(fieldInfoClass);
classPointer.HasReferences |= !fieldIsValueType ||
IL2CPP.il2cpp_class_has_references(fieldInfoClass);

if (IL2CPP.il2cpp_class_is_valuetype(fieldInfoClass))
if (fieldIsValueType)
{
uint _align = 0;
var fieldSize = IL2CPP.il2cpp_class_value_size(fieldInfoClass, ref _align);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public TRefObj Value

public void Set(TRefObj value)
{
*GetPointerToData() = value != null ? value.Pointer : IntPtr.Zero;
var targetAddress = (IntPtr)GetPointerToData();
IL2CPP.FieldWriteWbarrier(_obj.Pointer, targetAddress,
value != null ? value.Pointer : IntPtr.Zero);
}

public static implicit operator TRefObj(Il2CppReferenceField<TRefObj> _this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ public string Value

public void Set(string value)
{
*GetPointerToData() = IL2CPP.ManagedStringToIl2Cpp(value);
var targetAddress = (IntPtr)GetPointerToData();
IL2CPP.FieldWriteWbarrier(_obj.Pointer, targetAddress,
IL2CPP.ManagedStringToIl2Cpp(value));
}

public static implicit operator string(Il2CppStringField _this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ public interface INativeClassStruct : INativeStruct
bool Initialized { get; set; }
bool InitializedAndNoError { get; set; }
bool SizeInited { get; set; }
bool HasReferences
{
get => false;
set { }
}
bool HasFinalize { get; set; }
bool IsVtableInitialized { get; set; }

Expand Down
Loading