[mono] Add support for UnmanagedCallersOnlyAttribute#38728
[mono] Add support for UnmanagedCallersOnlyAttribute#38728lambdageek merged 27 commits intodotnet:masterfrom
Conversation
|
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
e05143d to
fe9f96c
Compare
|
Looks ok. |
1 byte, I think - AOT uses the same value encoding as CIL images - small values (<127) encode to one byte. |
|
Should pass the positive tests now. Negative tests will still fail. |
|
I misunderstood the test - it's in fact just crashing. So there's nothing to detect. Mono's behavior of not crashing is ok. |
|
Some progress on the negative tests. The InvalidProgramException ones should be in good shape. |
|
The |
…elegate class In that case, create a wrapper based on the signature of the method itself. TODO: - check that the method is static - check that the method does not have any marshal info (currently it's assumed to not be present and ignored)
…thout a delegate class Bump the AOT file format
…llersOnly methods
…wrapper The wrapper might be called from a thread that's not attached to the runtime, and the jump trampoline will look at TLS vars that are not initialized
…agedCallersOnly method
…UnmanagedCallersOnly methods Instead of throwing while JITing (or transforming), throw when the LDFTN is executed.
9317eb0 to
6e85742
Compare
|
JIT is passing all the tests except |
throw NotSupportedException
|
Once I see the JIT pass all the tests, I'll bump the test back to Pri1 and then the PR is basically complete. |
|
From https://helix.dot.net/api/2019-06-17/jobs/51ac422f-058f-4fa3-aa34-f41bb363a4fb/workitems/Interop/console the "runtime (Mono Pri0 Runtime Tests Run OSX x64 release)" JIT job: As previously mentioned, the interpreter job is failing due to #38897, so this is the best we'll get for now. |
CoffeeFlux
left a comment
There was a problem hiding this comment.
Lots of questions but looks fine to me. Would be really good if Zoltan gets a chance to look at this before it's merged since I'm not terribly confident in my review of the code generation parts. Thanks!
| csig = mono_metadata_signature_dup_full (get_method_image (method), sig); | ||
| csig->pinvoke = 0; | ||
| res = mono_mb_create_and_cache_full (cache, method, mb, csig, | ||
| csig->param_count + 16, info, NULL); |
There was a problem hiding this comment.
Where is this 16 coming from? It looks like it's used elsewhere, but I'm not familiar enough with this code to understand why.
There was a problem hiding this comment.
I don't know. I'm cargo-culting the other mono_mb_create_and_cache_full calls in this function.
There was a problem hiding this comment.
Ugh, that's what I feared. @vargaz any idea? For my own learning if nothing else :)
There was a problem hiding this comment.
No idea, it probably comes from the fact that these are wrappers so the deepest stack will be calling the 'wrapped' method, so param_count + is good for max stack.
src/mono/mono/metadata/marshal.c
Outdated
| return NULL; | ||
| } | ||
| if (!method_signature_is_blittable (invoke_sig)) { | ||
| mono_error_set_invalid_program (error, "method %s with UnmanagedCallersOnlyAttribute has non-blittable parameters", mono_method_full_name (method, TRUE)); |
There was a problem hiding this comment.
It could also have a non-blittable return type. I'd change this error slightly to reflect that.
src/mono/mono/metadata/marshal.c
Outdated
| { | ||
| ERROR_DECL (attr_error); | ||
| MonoClass *attr_klass = NULL; | ||
| #ifdef ENABLE_NETCORE |
There was a problem hiding this comment.
I guess this accomplishes the same thing, but wouldn't it be clearer to immediately return false on non-netcore?
src/mono/mono/metadata/marshal.c
Outdated
| case MONO_TYPE_R8: | ||
| case MONO_TYPE_I: | ||
| case MONO_TYPE_U: | ||
| case MONO_TYPE_CHAR: |
There was a problem hiding this comment.
I think char shouldn't be here. Doesn't look like it's supposed to be blittable. (mono_class_setup_mono_type doesn't set the blittable bit on it)
There was a problem hiding this comment.
Ah yeah, good catch. Yes, it's definitely not for the same reason as string—ambiguity over converting to ANSI, UTF-8, or UTF-16.
Co-authored-by: Ryan Lucia <ryan@luciaonline.net>
| #endif | ||
|
|
||
| static gboolean | ||
| type_is_blittable (MonoType *type) |
There was a problem hiding this comment.
There is already a class->blittable flag.
There was a problem hiding this comment.
We discussed this, but it's not the same because of byref types.
When we see a method tagged with
UnmanagedCallersOnlyAttributein anldtninstruction, load a pointer to a native-to-managed wrapper instead of a pointer to the managed method.See https://github.com/dotnet/csharplang/blob/master/proposals/functionpointers.md#systemruntimeinteropservicesunmanagedcallersonlyattribute
TODO:
Figure out why the CoreCLR tests are either not running or somehow passing.The tests are in https://github.com/dotnet/runtime/tree/master/src/coreclr/tests/src/Interop/UnmanagedCallersOnly which doesn't seem to be in https://github.com/dotnet/runtime/blob/master/src/coreclr/tests/issues.targets but in that case Mono should be failing a number of the tests in there on CI.It's because we only run P0 tests on CI for Mono. I temporarily set it to P0 for this PR just to watch the tests fail.