-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Parse CallConvSwift in CoreCLR/NativeAOT #96707
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
Changes from 9 commits
a7e3ee4
8027343
e056d69
d667148
db1abd0
9b642c0
ebe34e0
e873f64
de1f23a
2ac4812
fc5c9ff
0e9934b
82764a1
b115352
4bea8a5
1b8eb2c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
jkoritzinsky marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,7 +40,7 @@ public enum UnmanagedCallingConventions | |
| // Unmanaged = 0x00000009, - this one is always translated to cdecl/stdcall | ||
|
|
||
| // The ones higher than 0xF are defined by the type system | ||
| // There are no such calling conventions yet. | ||
| Swift = 0x00000010 | ||
| } | ||
|
|
||
| public static class CallingConventionExtensions | ||
|
|
@@ -135,6 +135,27 @@ public static UnmanagedCallingConventions GetPInvokeMethodCallingConventions(thi | |
| return result; | ||
| } | ||
|
|
||
| public static UnmanagedCallingConventions GetDelegateCallingConventions(this TypeDesc delegateType) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method doesn't appear used. Is that intentional?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed the usage of it during a refactor. I think it's still useful to have, but we can remove it and re-add later when we have a use case. |
||
| { | ||
| Debug.Assert(delegateType.IsDelegate); | ||
|
|
||
| if (delegateType is not EcmaType ecmaDelegate) | ||
|
AaronRobinsonMSFT marked this conversation as resolved.
Outdated
|
||
| { | ||
| return GetPlatformDefaultUnmanagedCallingConvention(delegateType.Context); | ||
| } | ||
|
|
||
| MethodSignatureFlags unmanagedCallConv = ecmaDelegate.GetDelegatePInvokeFlags().UnmanagedCallingConvention; | ||
| if (unmanagedCallConv != MethodSignatureFlags.None) | ||
| { | ||
| Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionCdecl == (int)UnmanagedCallingConventions.Cdecl | ||
| && (int)MethodSignatureFlags.UnmanagedCallingConventionStdCall == (int)UnmanagedCallingConventions.Stdcall | ||
| && (int)MethodSignatureFlags.UnmanagedCallingConventionThisCall == (int)UnmanagedCallingConventions.Thiscall); | ||
| return (UnmanagedCallingConventions)unmanagedCallConv; | ||
| } | ||
|
|
||
| return GetPlatformDefaultUnmanagedCallingConvention(delegateType.Context); | ||
| } | ||
|
|
||
| private static UnmanagedCallingConventions GetUnmanagedCallingConventionFromAttribute(CustomAttributeValue<TypeDesc> attributeWithCallConvsArray, TypeSystemContext context) | ||
| { | ||
| ImmutableArray<CustomAttributeTypedArgument<TypeDesc>> callConvArray = default; | ||
|
|
@@ -181,6 +202,7 @@ private static UnmanagedCallingConventions AccumulateCallingConventions(Unmanage | |
| "CallConvThiscall" => UnmanagedCallingConventions.Thiscall, | ||
| "CallConvSuppressGCTransition" => UnmanagedCallingConventions.IsSuppressGcTransition, | ||
| "CallConvMemberFunction" => UnmanagedCallingConventions.IsMemberFunction, | ||
| "CallConvSwift" => UnmanagedCallingConventions.Swift, | ||
| _ => null | ||
| }; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -120,6 +120,20 @@ public static bool IsMarshallingRequired(MethodDesc targetMethod) | |
| if (MarshalHelpers.ShouldCheckForPendingException(targetMethod.Context.Target, metadata)) | ||
| return true; | ||
|
|
||
| if (targetMethod.GetPInvokeMethodCallingConventions() == UnmanagedCallingConventions.Swift) | ||
| { | ||
| // Swift calling convention has strict rules about value types that the JIT does not implement. | ||
| // Skip stub generation of Swift methods with value types to allow an exception at runtime. | ||
| foreach (var param in targetMethod.Signature) | ||
| { | ||
| if (param is { IsValueType: true, IsEnum: false, IsPrimitive: false } | ||
| && !MarshalHelpers.IsSwiftIntrinsicValueType(param)) | ||
| { | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| var marshallers = GetMarshallersForMethod(targetMethod); | ||
| for (int i = 0; i < marshallers.Length; i++) | ||
| { | ||
|
|
@@ -130,8 +144,48 @@ public static bool IsMarshallingRequired(MethodDesc targetMethod) | |
| return false; | ||
| } | ||
|
|
||
| public static bool IsMarshallingRequired(MethodSignature methodSig, ModuleDesc moduleContext, UnmanagedCallingConventions callingConvention) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Why do we need a new overload though? I would expect the existing
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the other overload, we can extract the calling convention from the MethodSignature. This overload is for UnmanagedCallersOnly methods where the callconv is in the attribute, not the managed signature.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The parameter is still unused, is that intentional?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it's intentional that it's unused. |
||
| { | ||
| if (callingConvention == UnmanagedCallingConventions.Swift) | ||
| { | ||
| // Swift calling convention has strict rules about value types that the JIT does not implement. | ||
| // Skip stub generation of Swift methods with value types to allow an exception at runtime. | ||
| foreach (var param in methodSig) | ||
| { | ||
| if (param is { IsValueType: true, IsEnum: false, IsPrimitive: false } | ||
| && !MarshalHelpers.IsSwiftIntrinsicValueType(param)) | ||
| { | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Marshaller[] marshallers = GetMarshallersForSignature(methodSig, System.Array.Empty<ParameterMetadata>(), moduleContext); | ||
| for (int i = 0; i < marshallers.Length; i++) | ||
| { | ||
| if (marshallers[i].IsMarshallingRequired()) | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| public static bool IsMarshallingRequired(MethodSignature methodSig, ParameterMetadata[] paramMetadata, ModuleDesc moduleContext) | ||
| { | ||
| if (methodSig.GetStandaloneMethodSignatureCallingConventions() == UnmanagedCallingConventions.Swift) | ||
| { | ||
| // Swift calling convention has strict rules about value types that the JIT does not implement. | ||
| // Skip stub generation of Swift methods with value types to allow an exception at runtime. | ||
| foreach (var param in methodSig) | ||
| { | ||
| if (param is { IsValueType: true, IsEnum: false, IsPrimitive: false } | ||
| && !MarshalHelpers.IsSwiftIntrinsicValueType(param)) | ||
| { | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Marshaller[] marshallers = GetMarshallersForSignature(methodSig, paramMetadata, moduleContext); | ||
| for (int i = 0; i < marshallers.Length; i++) | ||
| { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.