Skip to content

Commit

Permalink
Parse CallConvSwift in CoreCLR/NativeAOT (#96707)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkoritzinsky authored Jan 30, 2024
1 parent 5155263 commit f48a99e
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/coreclr/inc/corhdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5605,7 +5605,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;
}
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,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
Expand Down Expand Up @@ -4124,7 +4127,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<ParameterMetadata>(), ((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);
}
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<TypeDesc> attributeWithCallConvsArray, TypeSystemContext context)
{
ImmutableArray<CustomAttributeTypedArgument<TypeDesc>> callConvArray = default;
Expand Down Expand Up @@ -181,6 +200,7 @@ private static UnmanagedCallingConventions AccumulateCallingConventions(Unmanage
"CallConvThiscall" => UnmanagedCallingConventions.Thiscall,
"CallConvSuppressGCTransition" => UnmanagedCallingConventions.IsSuppressGcTransition,
"CallConvMemberFunction" => UnmanagedCallingConventions.IsMemberFunction,
"CallConvSwift" => UnmanagedCallingConventions.Swift,
_ => null
};

Expand Down Expand Up @@ -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()
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<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)
{
Marshaller[] marshallers = GetMarshallersForSignature(methodSig, paramMetadata, moduleContext);
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/vm/callconvbuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/corelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,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)
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/vm/dllimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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);
}
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/vm/stubgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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
{
Expand All @@ -19,7 +20,8 @@ namespace System.Runtime.InteropServices.Swift
/// </code>
/// </para>
/// </remarks>
[CLSCompliantAttribute(false)]
[CLSCompliant(false)]
[Intrinsic]
public readonly unsafe struct SwiftSelf
{
/// <summary>
Expand Down Expand Up @@ -52,7 +54,8 @@ public SwiftSelf(void* value)
/// </code>
/// </para>
/// </remarks>
[CLSCompliantAttribute(false)]
[CLSCompliant(false)]
[Intrinsic]
public readonly unsafe struct SwiftError
{
/// <summary>
Expand Down

0 comments on commit f48a99e

Please sign in to comment.