Open extraes opened 1 month ago
This line is the one that's throwing.
*(System.IntPtr*)((byte*)ptr + checked((nuint)3u * unchecked((nuint)sizeof(System.IntPtr)))) = IL2CPP.il2cpp_object_unbox(IL2CPP.Il2CppObjectBaseToPtrNotNull(cancellationToken));
Should it be this instead?
*(System.IntPtr*)((byte*)ptr + checked((nuint)3u * unchecked((nuint)sizeof(System.IntPtr)))) = cancellationToken is null ? 0 : IL2CPP.il2cpp_object_unbox(IL2CPP.Il2CppObjectBaseToPtrNotNull(cancellationToken));
Or does the pointer need to be non-zero?
If so, your solution seems like the sensible thing to generate into the code.
As an example and for ease of demonstration, unhollowed code from BONELAB is provided:
The relevant portions are the following:
CancellationToken cancellationToken = null
IL2CPP.il2cpp_object_unbox(IL2CPP.Il2CppObjectBaseToPtrNotNull(cancellationToken))
The parameter is of class type
CancellationToken
, extendingIl2CppSystem.ValueType
(unhollowed version of the structCancellationToken
) In the source code for this method in the UniTask repository, this parameter is normally defined asCancellationToken cancellationToken = default(CancellationToken)
The unhollowed parameter being defined as null causes a problem when this method is called without filling out all parameters, because obviouslyIl2CppObjectBaseToPtrNotNull
throws an exception when it is null.This can be remedied on a per-method basis by prefixing the offending methods and replacing parameters, but this is manual and still represents a bug in the generated IL. A solution could be making the IL mirror
IL2CPP.Il2CppObjectBaseToPtrNotNull(cancellationToken ?? new CancellationToken())
, or keep a cached copy of a default CancellationToken and retrieving that field, to avoid recreating objects, but there's more complexity to keeping that field and possibly making sure it's not collected.