-
Notifications
You must be signed in to change notification settings - Fork 5.3k
[DRAFT] [clr-interp] Fix some interop suite issues #122656
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
base: main
Are you sure you want to change the base?
[DRAFT] [clr-interp] Fix some interop suite issues #122656
Conversation
- The HasUnmanagedCallersOnlyAttribute api is... not as accurate as I'd like. See comment in the code
- Fix an issue with platform detection where we are attempting to test COM interop tests with the interpreter enabled - Fix an issue with creating a delegate to a method marked with an [UnmanagedCallersOnly] attribute. NOTE: This fix is probably not acceptable for long term usage as it injects a very expensive metadata lookup into the slow path delegate contruction logic.
|
@AaronRobinsonMSFT @jkoritzinsky do you have an opinion on the check of HasUnmanagedCallersOnlyAttribute in the delegate constructor. We currently have a check for it in optimized delegate construction, which is almost always used by the JIT, but I need to know if we really need that to work, or if it's just a convenience feature that it fails. |
|
/azp run runtime-interpreter |
|
Azure Pipelines successfully started running 1 pipeline(s). |
| if (Nullable::IsNullableType(pMeth->GetMethodTable())) | ||
| COMPlusThrow(kNotSupportedException); | ||
|
|
||
| // Do not allow static methods with [UnmanagedCallersOnlyAttribute] to be a delegate target. |
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.
Most delegate constructor go via optimized path, so this is incomplete.
Our strategy has been to delay this check until the UnmanagedCallersOnly method is actually called and produce a fail-fast with a good error message in that case:
runtime/src/coreclr/vm/jithelpers.cpp
Line 997 in a83d76a
| void ReversePInvokeBadTransition() |
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 optimized path already has this check. The question is should the slow path ALSO have the check.
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 optimized path already has this check. The question is should the slow path ALSO have the check.
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.
Where is this check on the optimized path?
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.
It's in the optimized delegate creation path called by the jit. I could replicate that if needed in the interpreter compiler. Search for the comment. I copied it verbatim.
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.
It's in the optimized delegate creation path called by the jit. I could replicate that if needed in the interpreter compiler. Search for the comment. I copied it verbatim.
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 see it now. I think it is an oversight that we check for it on the fast path. It is inconsistent with the lazy check that we do everywhere else. For example, you can create delegate pointing to UMCO via reflection just fine (it will fail once you try to call it):
public class Program
{
static void Main()
{
typeof(Program).GetMethod("Test").CreateDelegate<Action>();
}
[UnmanagedCallersOnly]
public static void Test() { }
}
This fixes several issues: