diff --git a/src/coreclr/inc/corhdr.h b/src/coreclr/inc/corhdr.h index 5c645000ce87d6..3f67b33da9162a 100644 --- a/src/coreclr/inc/corhdr.h +++ b/src/coreclr/inc/corhdr.h @@ -1715,6 +1715,7 @@ typedef enum LoadHintEnum #define CMOD_CALLCONV_NAME_STDCALL "CallConvStdcall" #define CMOD_CALLCONV_NAME_THISCALL "CallConvThiscall" #define CMOD_CALLCONV_NAME_FASTCALL "CallConvFastcall" +#define CMOD_CALLCONV_NAME_SWIFT "CallConvSwift" #define CMOD_CALLCONV_NAME_SUPPRESSGCTRANSITION "CallConvSuppressGCTransition" #define CMOD_CALLCONV_NAME_MEMBERFUNCTION "CallConvMemberFunction" diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index e957885418ca7b..7c9db074608a2a 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -772,7 +772,8 @@ enum class CorInfoCallConvExtension // New calling conventions supported with the extensible calling convention encoding go here. CMemberFunction, StdcallMemberFunction, - FastcallMemberFunction + FastcallMemberFunction, + Swift }; #ifdef TARGET_X86 diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index ff087f04e4b0e9..c4454530ca1529 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -5592,7 +5592,8 @@ void Compiler::impCheckForPInvokeCall( // return here without inlining the native call. if (unmanagedCallConv == CorInfoCallConvExtension::Managed || unmanagedCallConv == CorInfoCallConvExtension::Fastcall || - unmanagedCallConv == CorInfoCallConvExtension::FastcallMemberFunction) + unmanagedCallConv == CorInfoCallConvExtension::FastcallMemberFunction || + unmanagedCallConv == CorInfoCallConvExtension::Swift) { return; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index cadc58a7014516..c3f59cff76d24b 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1590,6 +1590,9 @@ private static CorInfoCallConvExtension ToCorInfoCallConvExtension(UnmanagedCall case UnmanagedCallingConventions.Fastcall: result = CorInfoCallConvExtension.Fastcall; break; + case UnmanagedCallingConventions.Swift: + result = CorInfoCallConvExtension.Swift; + break; default: ThrowHelper.ThrowInvalidProgramException(); result = CorInfoCallConvExtension.Managed; // unreachable @@ -4099,7 +4102,7 @@ private uint getJitFlags(ref CORJIT_FLAGS flags, uint sizeInBytes) #if READYTORUN // TODO: enable this check in full AOT - if (Marshaller.IsMarshallingRequired(this.MethodBeingCompiled.Signature, Array.Empty(), ((MetadataType)this.MethodBeingCompiled.OwningType).Module)) // Only blittable arguments + if (Marshaller.IsMarshallingRequired(this.MethodBeingCompiled.Signature, ((MetadataType)this.MethodBeingCompiled.OwningType).Module, this.MethodBeingCompiled.GetUnmanagedCallersOnlyMethodCallingConventions())) // Only blittable arguments { ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramNonBlittableTypes, this.MethodBeingCompiled); } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 394a7a4bbac91b..00414e6192d492 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -392,7 +392,8 @@ public enum CorInfoCallConvExtension // New calling conventions supported with the extensible calling convention encoding go here. CMemberFunction, StdcallMemberFunction, - FastcallMemberFunction + FastcallMemberFunction, + Swift } public enum CORINFO_CALLINFO_FLAGS diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/UnmanagedCallingConventions.cs b/src/coreclr/tools/Common/TypeSystem/Interop/UnmanagedCallingConventions.cs index 5ba886b68c265b..98cdb658a42248 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/UnmanagedCallingConventions.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/UnmanagedCallingConventions.cs @@ -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,25 @@ public static UnmanagedCallingConventions GetPInvokeMethodCallingConventions(thi return result; } + public static UnmanagedCallingConventions GetDelegateCallingConventions(this TypeDesc delegateType) + { + Debug.Assert(delegateType.IsDelegate); + + if (delegateType is EcmaType ecmaDelegate) + { + 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 attributeWithCallConvsArray, TypeSystemContext context) { ImmutableArray> callConvArray = default; @@ -181,6 +200,7 @@ private static UnmanagedCallingConventions AccumulateCallingConventions(Unmanage "CallConvThiscall" => UnmanagedCallingConventions.Thiscall, "CallConvSuppressGCTransition" => UnmanagedCallingConventions.IsSuppressGcTransition, "CallConvMemberFunction" => UnmanagedCallingConventions.IsMemberFunction, + "CallConvSwift" => UnmanagedCallingConventions.Swift, _ => null }; @@ -218,6 +238,7 @@ public static EmbeddedSignatureData[] EncodeAsEmbeddedSignatureData(this Unmanag UnmanagedCallingConventions.Stdcall => "CallConvStdcall", UnmanagedCallingConventions.Fastcall => "CallConvFastcall", UnmanagedCallingConventions.Thiscall => "CallConvThiscall", + UnmanagedCallingConventions.Swift => "CallConvSwift", _ => throw new InvalidProgramException() }); } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs index 33fd2eb6fba480..d827aed4673c78 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs @@ -130,6 +130,18 @@ public static bool IsMarshallingRequired(MethodDesc targetMethod) return false; } + public static bool IsMarshallingRequired(MethodSignature methodSig, ModuleDesc moduleContext, UnmanagedCallingConventions callingConvention) + { + Marshaller[] marshallers = GetMarshallersForSignature(methodSig, System.Array.Empty(), 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) { Marshaller[] marshallers = GetMarshallersForSignature(methodSig, paramMetadata, moduleContext); diff --git a/src/coreclr/vm/callconvbuilder.cpp b/src/coreclr/vm/callconvbuilder.cpp index 0ba5934c9f9a7b..20f95f12224105 100644 --- a/src/coreclr/vm/callconvbuilder.cpp +++ b/src/coreclr/vm/callconvbuilder.cpp @@ -53,7 +53,8 @@ namespace BASE_CALL_CONV(CMOD_CALLCONV_NAME_CDECL, C) \ BASE_CALL_CONV(CMOD_CALLCONV_NAME_STDCALL, Stdcall) \ BASE_CALL_CONV(CMOD_CALLCONV_NAME_THISCALL, Thiscall) \ - BASE_CALL_CONV(CMOD_CALLCONV_NAME_FASTCALL, Fastcall) + BASE_CALL_CONV(CMOD_CALLCONV_NAME_FASTCALL, Fastcall) \ + BASE_CALL_CONV(CMOD_CALLCONV_NAME_SWIFT, Swift) #define DECLARE_MOD_CALL_CONVS \ CALL_CONV_MODIFIER(CMOD_CALLCONV_NAME_SUPPRESSGCTRANSITION, CALL_CONV_MOD_SUPPRESSGCTRANSITION) \ @@ -176,6 +177,8 @@ namespace return CorInfoCallConvExtension::FastcallMemberFunction; case CorInfoCallConvExtension::Thiscall: return CorInfoCallConvExtension::Thiscall; + case CorInfoCallConvExtension::Swift: + return CorInfoCallConvExtension::Swift; default: _ASSERTE("Calling convention is not an unmanaged base calling convention."); return baseCallConv; diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 2fc34d04372c5e..6b926cce40a08e 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -749,6 +749,7 @@ DEFINE_CLASS(CALLCONV_THISCALL, CompilerServices, CallConvThi DEFINE_CLASS(CALLCONV_FASTCALL, CompilerServices, CallConvFastcall) DEFINE_CLASS(CALLCONV_SUPPRESSGCTRANSITION, CompilerServices, CallConvSuppressGCTransition) DEFINE_CLASS(CALLCONV_MEMBERFUNCTION, CompilerServices, CallConvMemberFunction) +DEFINE_CLASS(CALLCONV_SWIFT, CompilerServices, CallConvSwift) DEFINE_CLASS_U(Interop, SafeHandle, SafeHandle) DEFINE_FIELD_U(_ctorStackTrace, SafeHandle, m_ctorStackTrace) diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index 5dbea392d6b2a4..28c3a3422e5884 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -3167,7 +3167,6 @@ HRESULT NDirect::HasNAT_LAttribute(IMDInternalImport *pInternalImport, mdToken t return S_FALSE; } - // Either MD or signature & module must be given. /*static*/ BOOL NDirect::MarshalingRequired( @@ -4257,7 +4256,8 @@ static void CreateNDirectStubAccessMetadata( { if (unmgdCallConv == CorInfoCallConvExtension::Managed || unmgdCallConv == CorInfoCallConvExtension::Fastcall || - unmgdCallConv == CorInfoCallConvExtension::FastcallMemberFunction) + unmgdCallConv == CorInfoCallConvExtension::FastcallMemberFunction || + unmgdCallConv == CorInfoCallConvExtension::Swift) { COMPlusThrow(kTypeLoadException, IDS_INVALID_PINVOKE_CALLCONV); } diff --git a/src/coreclr/vm/stubgen.cpp b/src/coreclr/vm/stubgen.cpp index 78e7fb621c90d5..5f18e8f5d9123f 100644 --- a/src/coreclr/vm/stubgen.cpp +++ b/src/coreclr/vm/stubgen.cpp @@ -2819,6 +2819,9 @@ void ILStubLinker::SetStubTargetCallingConv(CorInfoCallConvExtension callConv) m_nativeFnSigBuilder.AddCallConvModOpt(GetToken(CoreLibBinder::GetClass(CLASS__CALLCONV_FASTCALL))); m_nativeFnSigBuilder.AddCallConvModOpt(GetToken(CoreLibBinder::GetClass(CLASS__CALLCONV_MEMBERFUNCTION))); break; + case CorInfoCallConvExtension::Swift: + m_nativeFnSigBuilder.AddCallConvModOpt(GetToken(CoreLibBinder::GetClass(CLASS__CALLCONV_SWIFT))); + break; default: _ASSERTE("Unknown calling convention. Unable to encode it in the native function pointer signature."); break; diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Swift/SwiftTypes.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Swift/SwiftTypes.cs index a07be15ad44cac..13803374073b81 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Swift/SwiftTypes.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Swift/SwiftTypes.cs @@ -1,5 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.CompilerServices; namespace System.Runtime.InteropServices.Swift { @@ -19,7 +20,8 @@ namespace System.Runtime.InteropServices.Swift /// /// /// - [CLSCompliantAttribute(false)] + [CLSCompliant(false)] + [Intrinsic] public readonly unsafe struct SwiftSelf { /// @@ -52,7 +54,8 @@ public SwiftSelf(void* value) /// /// /// - [CLSCompliantAttribute(false)] + [CLSCompliant(false)] + [Intrinsic] public readonly unsafe struct SwiftError { ///