Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix il2cpp error (take 2) #548

Merged
merged 3 commits into from
Jul 8, 2024
Merged

Fix il2cpp error (take 2) #548

merged 3 commits into from
Jul 8, 2024

Conversation

mtmk
Copy link
Collaborator

@mtmk mtmk commented Jul 6, 2024

Previous commit about this issue reverted since it wasn't fixing the issue. The actual error was:

Error: IL2CPP error for method 'System.Char[] NATS.Client.Core.Internal.NuidWriter::Refresh(System.UInt64&)' in assembly NATS.Client.Core.dll
System.ArgumentOutOfRangeException:
 Cannot create a constant value for types of System.UIntPtr for System.UIntPtr NATS.Client.Core.Internal.NuidWriter::NuidLength (Parameter 'declaredParameterOrFieldType')

With this fix now it compiles fine:
image

Looking at Unsafe.Add examples passing in uint or int instead of nuint is fine:

e.g. https://github.com/dotnet/runtime/blob/a7efcd9ca9255dc9faa8b4a2761cdfdb62619610/src/libraries/System.Private.CoreLib/src/System/Buffer.cs#L84

Note: I had to revert the last two commits (so ignore the previous four commits) to main which was done by mistake without PRs.

cc @galvesribeiro

mtmk added 2 commits July 6, 2024 18:40
Previous commit about this issue reverted since it wasn't fixing the issue. The actual error was:

Error: IL2CPP error for method 'System.Char[] NATS.Client.Core.Internal.NuidWriter::Refresh(System.UInt64&)' in assembly NATS.Client.Core.dll
System.ArgumentOutOfRangeException:
 Cannot create a constant value for types of System.UIntPtr for System.UIntPtr NATS.Client.Core.Internal.NuidWriter::NuidLength (Parameter 'declaredParameterOrFieldType')

 Looking at Unsafe.Add examples passing in uint or int instead of nuint is fine:

 e.g. https://github.com/dotnet/runtime/blob/a7efcd9ca9255dc9faa8b4a2761cdfdb62619610/src/libraries/System.Private.CoreLib/src/System/Buffer.cs#L84

 Note: I had to revert the last two commits (so ignore the previous four commits) to main which was done by mistake without PRs.
@mtmk mtmk requested a review from to11mtm July 6, 2024 17:53
@to11mtm
Copy link
Collaborator

to11mtm commented Jul 6, 2024

For the sake of general review and future doc ; what are all of the 'conditions' we had to fix or deal with?

I think this would be good for general doc as well as putting together for future 'contributor guidelines' to help with knowing how to do the needful with IL2CPP

As it stands, I don't have bandwidth to test locally so will refrain from any approval but will take a look. <3

Copy link
Collaborator

@to11mtm to11mtm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks OK but per other comments we should doc what we are learning along the way.

Comment on lines 13 to 18
{
internal const nuint NuidLength = PrefixLength + SequentialLength;
private const nuint Base = 62;
internal const uint NuidLength = PrefixLength + SequentialLength;
private const uint Base = 62;
private const ulong MaxSequential = 839299365868340224; // 62^10
private const uint PrefixLength = 12;
private const nuint SequentialLength = 10;
private const uint SequentialLength = 10;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH I think this is probably better for comprehension sake anyway (i.e. scoping/etc)

@mtmk
Copy link
Collaborator Author

mtmk commented Jul 6, 2024

To elaborate a bit more: in the previous PR #543 I wrongly thought the IL2CPP error was caused by the inner method local reuse and my oversight in testing in Unity for some reason I thought it was fixing the issue. But after the preview release trying it again in a fresh unity project I realized the compile error was still there for Linux IL2CPP builds. Looking at the error more closely it looks like IL2CPP can't deal with nuint (UIntPtr) constants. Changing the type to uint instead fixed the error and it looked like passing uint instead of nuint to Unsafe.Add() calls did not make any difference in tests, also found example usages in dotnet/runtime which used int instead.

Also to note, fairly extensive tests for NuidWrite are passing as well:

  Passed NATS.Client.Core.Tests.NuidWriterTests.AllNuidsAreUnique_SmallSequentials [18 s]
  Passed NATS.Client.Core.Tests.NuidWriterTests.Only_last_few_digits_change [< 1 ms]
  Passed NATS.Client.Core.Tests.NuidWriterTests.NewInbox_NuidAppended(prefix: null) [< 1 ms]
  Passed NATS.Client.Core.Tests.NuidWriterTests.NewInbox_NuidAppended(prefix: "__INBOX") [< 1 ms]
  Passed NATS.Client.Core.Tests.NuidWriterTests.NewInbox_NuidAppended(prefix: "long-inbox-prefix-above-stackalloc-limit-of-64") [1 ms]
  Passed NATS.Client.Core.Tests.NuidWriterTests.NewInbox_NuidAppended(prefix: "") [< 1 ms]
  Passed NATS.Client.Core.Tests.NuidWriterTests.GetNextNuid_PrefixRenewed_Char [1 ms]
  Passed NATS.Client.Core.Tests.NuidWriterTests.GetNextNuid_BufferToShort_False_Char [1 ms]
  Passed NATS.Client.Core.Tests.NuidWriterTests.GetPrefix_PrefixAsExpected [< 1 ms]

As shown above in the main description local testing of Unity build completed successfully proving the fix works.

@galvesribeiro
Copy link
Collaborator

Looking at the error more closely it looks like IL2CPP can't deal with nuint (UIntPtr) constants.

Yeah, I think I saw something related to this when nuint was introduced. I think it is because of the runtime version Unity uses which doesn't have support to it and since IL2CPP is tied to it, it would fail.

@mtmk mtmk requested a review from caleblloyd July 6, 2024 20:28
@mtmk
Copy link
Collaborator Author

mtmk commented Jul 8, 2024

@to11mtm, @stebet, @rickdotnet, @caleblloyd sorry to pull you all in, it'd be good to have more eyes on this PR. It's a simple change but because of my wrong fix then a revert it became a little messy.

Tha change is very simple actually. NuidLength type is changed from nuint to uint to keep mono/unity il2cpp compilation happy. So the impact afaik, is where NuidLength type affecting the use of Unsafe.Add<char>(ref char source, nuint elementOffset) in this loop.

https://github.com/nats-io/nats.net.v2/blob/aceae9d4b902ecfc8e237606e3703ce1d96bc699/src/NATS.Client.Core/Internal/NuidWriter.cs#L74-L80

Before the change second parameter of Unsafe.Add nuint elementOffset had the exact matching type but now it is converted from uint to nuint. Now I don't have a lot of experience with intptrs but given the value of NuidLength is a const 22 (it's not like it can go near type bounds i.e. int.MaxValue) even if the platform JIT targeting is 32-bit I'm guessing we should be OK. Adding to that I did find examples of Unsafe.Add usage in dotnet/runtime which is using int as the second param:

https://github.com/dotnet/runtime/blob/a7efcd9ca9255dc9faa8b4a2761cdfdb62619610/src/libraries/System.Private.CoreLib/src/System/Buffer.cs#L83-L85

I feel this is good since tests are passing as well. Not sure how much more validation we can do. Let me know what you think.

@mtmk mtmk mentioned this pull request Jul 8, 2024
Copy link
Collaborator

@galvesribeiro galvesribeiro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mtmk mtmk merged commit e38156e into main Jul 8, 2024
10 checks passed
@mtmk mtmk deleted the fix-il2cpp-error-2 branch July 8, 2024 18:42
mtmk added a commit that referenced this pull request Jul 8, 2024
* Fix il2cpp error (take 2) (#548)
@mtmk mtmk mentioned this pull request Jul 8, 2024
mtmk added a commit that referenced this pull request Jul 8, 2024
* Fix il2cpp error (take 2) (#548)
@jasper-d
Copy link
Contributor

jasper-d commented Jul 8, 2024

@mtmk This looks good too :)

The change from nuint to uint adds an extra move inside the for loop (x64), but that is hardly measurable because the multiplications inside the loop are dominating.

mtmk added a commit that referenced this pull request Jul 9, 2024
* Fix Unity il2cpp error (#548)
* Full coverage kv management methods (#535)
* Remove unnecessary comment and configuration modification (#537)
* Add KV Filtering of keys (#545)
* netstandard Nullable ref fix (#542)
* Fixed version number sent to server and changed lang to .NET from C#.… (#541)
@mtmk mtmk mentioned this pull request Jul 9, 2024
mtmk added a commit that referenced this pull request Jul 9, 2024
* Fix Unity il2cpp error (#548)
* Full coverage kv management methods (#535)
* Remove unnecessary comment and configuration modification (#537)
* Add KV Filtering of keys (#545)
* netstandard Nullable ref fix (#542)
* Fixed version number sent to server and changed lang to .NET from C#.… (#541)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants