Skip to content

Commit ebe34e0

Browse files
committed
Allow vector types and SwiftSelf as parameter types for CallConvSwift signatures
1 parent 9b642c0 commit ebe34e0

File tree

5 files changed

+65
-13
lines changed

5 files changed

+65
-13
lines changed

src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,8 @@ public enum CorInfoCallConvExtension
392392
// New calling conventions supported with the extensible calling convention encoding go here.
393393
CMemberFunction,
394394
StdcallMemberFunction,
395-
FastcallMemberFunction
395+
FastcallMemberFunction,
396+
Swift
396397
}
397398

398399
public enum CORINFO_CALLINFO_FLAGS

src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeILEmitter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,8 @@ private PInvokeILStubMethodIL EmitIL()
394394
// Throw an exception if we encounter a value type that is not a primitive (and as such needs this lowering logic applied).
395395
foreach (var marshaller in _marshallers)
396396
{
397-
if (marshaller.ManagedType is DefType { IsValueType: true, IsEnum: false, IsPrimitive: false } paramType
398-
&& !VectorFieldLayoutAlgorithm.IsVectorType(paramType))
397+
if (marshaller.ManagedType is { IsValueType: true, IsEnum: false, IsPrimitive: false } param
398+
&& !MarshalHelpers.IsSwiftIntrinsicValueType(param))
399399
{
400400
throw new NotSupportedException();
401401
}

src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using Debug = System.Diagnostics.Debug;
66
using System.Runtime.InteropServices.ObjectiveC;
7+
using ILCompiler;
78
using Internal.TypeSystem.Ecma;
89

910
namespace Internal.TypeSystem.Interop
@@ -971,5 +972,23 @@ public static bool IsRuntimeMarshallingEnabled(ModuleDesc module)
971972
{
972973
return module.Assembly is not EcmaAssembly assembly || !assembly.HasAssemblyCustomAttribute("System.Runtime.CompilerServices", "DisableRuntimeMarshallingAttribute");
973974
}
975+
976+
public static bool IsSwiftIntrinsicValueType(TypeDesc type)
977+
{
978+
Debug.Assert(type.IsValueType && !type.IsPrimitive && !type.IsEnum);
979+
if (!type.IsIntrinsic)
980+
return false;
981+
982+
if (type is not DefType defType)
983+
return false;
984+
985+
if (VectorFieldLayoutAlgorithm.IsVectorType(defType))
986+
return true;
987+
988+
if (defType is { Namespace: "System.Runtime.InteropServices.Swift", Name: "SwiftSelf" })
989+
return true;
990+
991+
return false;
992+
}
974993
}
975994
}

src/coreclr/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ public static bool IsMarshallingRequired(MethodDesc targetMethod)
126126
// Skip stub generation of Swift methods with value types to allow an exception at runtime.
127127
foreach (var param in targetMethod.Signature)
128128
{
129-
if (param is DefType { IsValueType: true, IsEnum: false, IsPrimitive: false } defType
130-
&& !VectorFieldLayoutAlgorithm.IsVectorType(paramType))
129+
if (param is { IsValueType: true, IsEnum: false, IsPrimitive: false }
130+
&& !MarshalHelpers.IsSwiftIntrinsicValueType(param))
131131
{
132132
return true;
133133
}
@@ -152,8 +152,8 @@ public static bool IsMarshallingRequired(MethodSignature methodSig, ParameterMet
152152
// Skip stub generation of Swift methods with value types to allow an exception at runtime.
153153
foreach (var param in methodSig)
154154
{
155-
if (param is DefType { IsValueType: true, IsEnum: false, IsPrimitive: false } defType
156-
&& !VectorFieldLayoutAlgorithm.IsVectorType(paramType))
155+
if (param is { IsValueType: true, IsEnum: false, IsPrimitive: false }
156+
&& !MarshalHelpers.IsSwiftIntrinsicValueType(param))
157157
{
158158
return true;
159159
}

src/coreclr/vm/dllimport.cpp

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3167,6 +3167,40 @@ HRESULT NDirect::HasNAT_LAttribute(IMDInternalImport *pInternalImport, mdToken t
31673167
return S_FALSE;
31683168
}
31693169

3170+
namespace
3171+
{
3172+
bool IsSwiftIntrinsicValueType(TypeHandle hnd)
3173+
{
3174+
STANDARD_VM_CONTRACT;
3175+
3176+
_ASSERTE(hnd.IsValueType());
3177+
MethodTable* pMT = hnd.GetMethodTable();
3178+
if (!pMT->IsIntrinsicType())
3179+
return false;
3180+
3181+
LPCUTF8 namespaceName;
3182+
LPCUTF8 className = pMT->GetFullyQualifiedNameInfo(&namespaceName);
3183+
3184+
// We treat the .NET vector types as projections of the Swift SIMD intrinsic types.
3185+
if ((strcmp(className, "Vector512`1") == 0) || (strcmp(className, "Vector256`1") == 0) ||
3186+
(strcmp(className, "Vector128`1") == 0) || (strcmp(className, "Vector64`1") == 0))
3187+
{
3188+
_ASSERTE(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0);
3189+
return true;
3190+
}
3191+
3192+
// The SwiftSelf type is an intrinsic type that represents the Swift self register.
3193+
if (strcmp(className, "SwiftSelf") == 0)
3194+
{
3195+
_ASSERTE(strcmp(namespaceName, "System.Runtime.InteropServices.Swift") == 0);
3196+
return true;
3197+
}
3198+
3199+
// We don't need to treat the SwiftError type as an intrinsic here as it should always be passed
3200+
// as a SwiftError* parameter.
3201+
return false;
3202+
}
3203+
}
31703204

31713205
// Either MD or signature & module must be given.
31723206
/*static*/
@@ -3349,7 +3383,7 @@ BOOL NDirect::MarshalingRequired(
33493383
// Instead, we implement it in the projection layer. The runtime and JIT should only see pre-lowered, LLVM-IR-equivalent
33503384
// signatures.
33513385
// Require marshalling here so we can easily throw an exception during IL Stub generation.
3352-
return TRUE;
3386+
return !IsSwiftIntrinsicValueType(hndArgType);
33533387
}
33543388

33553389
if (i > 0)
@@ -4350,14 +4384,12 @@ static void CreateNDirectStubAccessMetadata(
43504384
{
43514385
// Swift has a very complicated lowering algorithm for structs. The .NET JIT does not support it,
43524386
// so throw an exception here if we encounter a signature that uses any value types.
4353-
if (msig.GetReturnTypeNormalized() == ELEMENT_TYPE_VALUETYPE)
4354-
{
4355-
COMPlusThrow(kNotSupportedException, IDS_EE_NDIRECT_SWIFT_VALUETYPE);
4356-
}
43574387

43584388
for (int i = 0; i < (*pNumArgs); i++)
43594389
{
4360-
if (msig.NextArgNormalized() == ELEMENT_TYPE_VALUETYPE)
4390+
TypeHandle hnd;
4391+
if (msig.NextArgNormalized(&hnd) == ELEMENT_TYPE_VALUETYPE
4392+
&& !IsSwiftIntrinsicValueType(hnd))
43614393
{
43624394
COMPlusThrow(kNotSupportedException, IDS_EE_NDIRECT_SWIFT_VALUETYPE);
43634395
}

0 commit comments

Comments
 (0)