-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Support generic arguments for calli in CoreCLR #97079
Conversation
We still need a reasonable failure mode for the unsupported cases. Please make sure to add tests for them. |
Also #9136 (comment) : Would it make sense to enable this only when runtime marshalling is disabled for the assembly? |
We already disallow any runtime marshalling against |
Your change applies to all unmanaged pointers though, not just UnmanagedCallersaOnly. |
1e45b6f
to
0327254
Compare
I added a guard to make sure no marshaling is required for calli. |
This needs tests and fixes for bugs discovered by the tests. |
551e349
to
a10142c
Compare
src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointer.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
src/tests/issues.targets
Outdated
@@ -1221,6 +1221,9 @@ | |||
<ExcludeList Include="$(XunitTestBinBase)/Interop/StringMarshalling/BSTR/BSTRTest/**"> | |||
<Issue>Crashes during LLVM AOT compilation.</Issue> | |||
</ExcludeList> | |||
<ExcludeList Include="$(XunitTestBinBase)/Interop/MarshalAPI/FunctionPointer/FunctionPtrTest/*"> | |||
<Issue>Generic calli support not implemented yet in mono.</Issue> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How hard is it to implement generic unmanaged calli support in Mono?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on my conversations with @lambdageek I think generics support at some of these interop margins are a bit tricky in mono.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, that's unfortunate.
We try to maintain feature parity between all runtimes. We need to figure out what we are going to do about Mono support before enabling it for CoreCLR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example from the issue descriptions works in net8.0 Mono already with JIT and interpreter. I haven't tried the examples from the rest of the added test.
The thing that Aaron is talking about is that mono doesn't have great support for creating wrapper methods that are themselves generic (ie: they have generic method params). We would need that for the generic UnsafeAccessor
work - the issue there is that we need to generate a generic method. Likewise if it was legal to do something like this:
void *pGenericFn = &SomeGenericUnsafeCallersOnlyMethod;
[UnsafeCallersOnly]
unsafe void SomeGenericUnsafeCallersOnlyMethod<T>(T *) where T : unmanaged { ... }
we would need to generate a generic wrapper.
For unmanaged function pointers we create wrappers around the &Func
- ldftn SomeUnmanagedCallersOnlyMethod
actually returns the address of the wrapper that has the native, not managed, calling convention.
At the calli
, we don't need to do anything special almost all the time.
The one place where we might get into trouble is if we need to do a call out using generic sharing, or gsharedvt (universal generic sharing): That is Foo<int>.Call<int>(...)
from the issue description, but compiled for ios, for example. I haven't tried it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The failures are probably going to be with generic sharing and aot. The JIT should work fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, that's unfortunate.
We try to maintain feature parity between all runtimes. We need to figure out what we are going to do about Mono support before enabling it for CoreCLR.
The tests were actually passing on mono, except mono-llvm-aot failed to build the negative tests (RunInvalidGenericFunctionPointerTest).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please factor out the negative cases into separate test and only disable those for Mono?
Handling of negative cases by llvm-aot should not be blocking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems that even if we removed negative cases, mono-aot-llvm still fail to compile (but with a different error message).
src/tests/Interop/MarshalAPI/FunctionPointer/FunctionPointer.cs
Outdated
Show resolved
Hide resolved
Is there anything I can do to make this PR get merged? Maybe I should disable the generic calli tests until mono impl ready to unblock the CI? |
Do you plan to work on the mono impl? |
I can try but I don't have experience with the mono codebase. Maybe need some help when implement this for mono. |
@vargaz @lambdageek Do you have any advice for how to implement this for Mono? (If you prefer to merge this PR as is and deal with the mono implementation separately, that's fine too.) |
Would be better to merge this and disable the failing tests on mono. |
@hez2010 Could you please do that? |
Done. CI failures are unrelated. |
@@ -21,6 +21,8 @@ | |||
<Compile Include="LayoutClass/*.cs" /> | |||
<Compile Include="ArrayMarshalling/**/*.cs" /> | |||
<Compile Include="MarshalAPI/**/*.cs" /> | |||
<!-- Disable build of GenericFunctionPointer tests on mono --> | |||
<Compile Condition="'$(RuntimeFlavor)' == 'mono'" Remove="MarshalAPI/FunctionPointer/GenericFunctionPointer.cs" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that the conditional compilation like this is violating invariants of the test builds. From https://github.com/dotnet/runtime/blob/main/docs/workflow/testing/coreclr/test-configuration.md#adding-test-guidelines: "Therefore the managed portion of each test must not contain - Target platform dependent conditionally included files"
The pattern to disable tests for Mono is <CLRTestTargetUnsupported Condition="'$(RuntimeFlavor)' == 'mono'">true</CLRTestTargetUnsupported>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do build the tests separately for Mono and CoreCLR builds (and we depend on this in the test source generator today).
I think this is fine for now (and is better than splitting out these tests into a separate process just to avoid running these tests on Mono).
src/tests/Interop/Interop.csproj
Outdated
@@ -21,6 +21,8 @@ | |||
<Compile Include="LayoutClass/*.cs" /> | |||
<Compile Include="ArrayMarshalling/**/*.cs" /> | |||
<Compile Include="MarshalAPI/**/*.cs" /> | |||
<!-- Disable build of GenericFunctionPointer tests on mono --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a link to an issue that tracks implementing this feature in Mono.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
@dotnet/interop-contrib Could you please review this as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
This reverts commit 15ff723.
Adding generic arguments support for calli in CoreCLR.
We don't need to handle generics in
DynamicMethodDesc
as it won't be a generic method definition and the generic arguments here can only be blittable types (so no generic sharing).Note that this has already been supported by NativeAOT.
Output:
Resolves #9136