Skip to content
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

Enable non-blittable struct returns on UnmanagedCallersOnly #45625

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
0302e18
Allow non-primitive struct returns to not require a stub. Fixes #35928.
jkoritzinsky Dec 3, 2020
ee5264f
Support propagating the UnmanagedCallersOnly calling convention to th…
jkoritzinsky Dec 4, 2020
96e5e0f
Support passing through the calling convention for UnmanagedCallersOn…
jkoritzinsky Dec 5, 2020
1b3ed1a
Fix clang errors.
jkoritzinsky Dec 5, 2020
79b5916
Fix stack calculation.
jkoritzinsky Dec 7, 2020
2723dc6
Fix usings
jkoritzinsky Dec 7, 2020
d0e811b
Clean up jitinterface.
jkoritzinsky Dec 7, 2020
5d83953
Remove invalid assert.
jkoritzinsky Dec 7, 2020
6fe0f4e
Fix up stdcall name mangling lookup.
jkoritzinsky Dec 7, 2020
2e3fecc
Fix flag condition.
jkoritzinsky Dec 8, 2020
7fa08ca
Merge branch 'master' of github.com:dotnet/runtime into unmanaged-cal…
jkoritzinsky Dec 8, 2020
e2a9d40
Use the register var type when copying from the register to the stack.
jkoritzinsky Dec 8, 2020
74a69e5
Change flag check for readability.
jkoritzinsky Dec 8, 2020
c12cc51
Rename variables to remove shadowing.
jkoritzinsky Dec 8, 2020
6345e3e
Fix formatting.
jkoritzinsky Dec 8, 2020
f08c166
Create new getEntryPointCallConv method on the EE-JIT interface to ha…
jkoritzinsky Dec 9, 2020
e598176
Remove unreachable code.
jkoritzinsky Dec 9, 2020
8ea0869
Remove now unused getUnmanagedCallConv jitinterface method (replaced …
jkoritzinsky Dec 9, 2020
6fb1e8c
Merge branch 'master' of github.com:dotnet/runtime into unmanaged-cal…
jkoritzinsky Dec 9, 2020
bcf270d
Fix formatting.
jkoritzinsky Dec 9, 2020
d2e016c
Rename getEntryPointCallConv and only call it with a method when it's…
jkoritzinsky Dec 10, 2020
b809ff8
Pass SuppressGCTransition through the getUnmanagedCallConv JIT-EE int…
jkoritzinsky Dec 11, 2020
ddb885f
Refactor callconv handling so we can handle reverse P/Invokes with th…
jkoritzinsky Dec 11, 2020
0b98994
Clean up whitespace.
jkoritzinsky Dec 11, 2020
3f0c7f9
Pass MethodIL as the scope for the signature to enable propagating do…
jkoritzinsky Dec 11, 2020
af41c1b
Remove usages of CORINFO_CALLCONV_FOO where FOO is an unmanaged callc…
jkoritzinsky Dec 12, 2020
2db1966
SuppressGC cleanup.
jkoritzinsky Dec 12, 2020
477ae3c
Rename superpmi struct
jkoritzinsky Dec 12, 2020
be82f96
Add default condition to make clang happy.
jkoritzinsky Dec 12, 2020
dd0c692
change enums to make clang happy.
jkoritzinsky Dec 12, 2020
8ba8f9b
Remove CORINFO_CALLCONV_C and family from interpreter.
jkoritzinsky Dec 12, 2020
31eb30a
Fix up handling of managed function pointers and remove invalid assert.
jkoritzinsky Dec 14, 2020
1be214b
Continue to use sigflag for suppressgc workaround.
jkoritzinsky Dec 14, 2020
1440fad
Clean up comment wording.
jkoritzinsky Dec 14, 2020
ed5b32e
Remove more MethodIL passing we don't need any more
jkoritzinsky Dec 14, 2020
3d5c8e2
Update src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
jkoritzinsky Dec 14, 2020
05e4efe
Merge branch 'master' of github.com:dotnet/runtime into unmanaged-cal…
jkoritzinsky Dec 14, 2020
dead19d
Fix SigTypeContext creation.
jkoritzinsky Dec 14, 2020
6465ce0
Merge branch 'master' of github.com:dotnet/runtime into unmanaged-cal…
jkoritzinsky Dec 14, 2020
6a4cbeb
Pass context by ptr.
jkoritzinsky Dec 14, 2020
6b870e6
Fix formatting.
jkoritzinsky Dec 14, 2020
792d56f
Clear the Reverse P/Invoke flag when compiling inlinees. It's only ne…
jkoritzinsky Dec 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 65 additions & 12 deletions src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#if READYTORUN
using System.Reflection.Metadata.Ecma335;
using ILCompiler.DependencyAnalysis.ReadyToRun;
using System.Reflection.Metadata;
jkoritzinsky marked this conversation as resolved.
Show resolved Hide resolved
using System.Collections.Immutable;
#endif

namespace Internal.JitInterface
Expand Down Expand Up @@ -474,13 +476,13 @@ private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORIN
methodInfo->options |= CorInfoOptions.CORINFO_GENERICS_CTXT_FROM_METHODTABLE;
}
methodInfo->regionKind = CorInfoRegionKind.CORINFO_REGION_NONE;
Get_CORINFO_SIG_INFO(method, &methodInfo->args);
Get_CORINFO_SIG_INFO(method, &methodInfo->args, checkUnmanagedCallersOnly: true);
Get_CORINFO_SIG_INFO(methodIL.GetLocals(), &methodInfo->locals);

return true;
}

private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false)
private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false, bool checkUnmanagedCallersOnly = false)
{
Get_CORINFO_SIG_INFO(method.Signature, sig);

Expand Down Expand Up @@ -520,6 +522,54 @@ private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool
{
sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_PARAMTYPE;
}
else if (checkUnmanagedCallersOnly && method.IsUnmanagedCallersOnly)
{
CustomAttributeValue<TypeDesc> unmanagedCallersOnlyAttribute = ((EcmaMethod)method).GetDecodedCustomAttribute("System.Runtime.InteropServices", "UnmanagedCallersOnlyAttribute").Value;
sig->callConv = GetUnmanagedCallingConventionFromAttribute(unmanagedCallersOnlyAttribute);
}
}

private CorInfoCallConv GetUnmanagedCallingConventionFromAttribute(CustomAttributeValue<TypeDesc> unmanagedCallersOnlyAttribute)
{
CorInfoCallConv callConv = (CorInfoCallConv)PlatformDefaultUnmanagedCallingConvention();

ImmutableArray<CustomAttributeTypedArgument<TypeDesc>> callConvArray = default;
foreach (var arg in unmanagedCallersOnlyAttribute.NamedArguments)
{
if (arg.Name == "CallConvs")
{
callConvArray = (ImmutableArray<CustomAttributeTypedArgument<TypeDesc>>)arg.Value;
}
}

// No calling convention was specified in the attribute, so return the default.
if (callConvArray.IsDefault)
{
return callConv;
}

bool found = false;
foreach (CustomAttributeTypedArgument<TypeDesc> type in callConvArray)
{
if (!(type.Value is DefType defType))
continue;

if (defType.Namespace != "System.Runtime.CompilerServices")
continue;

CorInfoCallConv? callConvLocal = GetCallingConventionForCallConvType(defType);

if (callConvLocal.HasValue)
{
// Error if there are multiple recognized calling conventions
if (found)
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramMultipleCallConv, MethodBeingCompiled);

callConv = callConvLocal.Value;
found = true;
}
}
return callConv;
}

private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signature, out CorInfoCallConv callConv)
Expand All @@ -545,22 +595,14 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur
if (defType.Namespace != "System.Runtime.CompilerServices")
continue;

// Look for a recognized calling convention in metadata.
CorInfoCallConv? callConvLocal = defType.Name switch
{
"CallConvCdecl" => CorInfoCallConv.CORINFO_CALLCONV_C,
"CallConvStdcall" => CorInfoCallConv.CORINFO_CALLCONV_STDCALL,
"CallConvFastcall" => CorInfoCallConv.CORINFO_CALLCONV_FASTCALL,
"CallConvThiscall" => CorInfoCallConv.CORINFO_CALLCONV_THISCALL,
_ => null
};
CorInfoCallConv? callConvLocal = GetCallingConventionForCallConvType(defType);

if (callConvLocal.HasValue)
{
// Error if there are multiple recognized calling conventions
if (found)
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramMultipleCallConv, MethodBeingCompiled);

callConv = callConvLocal.Value;
found = true;
}
Expand All @@ -569,6 +611,17 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur
return found;
}

private static CorInfoCallConv? GetCallingConventionForCallConvType(DefType defType) =>
// Look for a recognized calling convention in metadata.
defType.Name switch
{
"CallConvCdecl" => CorInfoCallConv.CORINFO_CALLCONV_C,
jkoritzinsky marked this conversation as resolved.
Show resolved Hide resolved
"CallConvStdcall" => CorInfoCallConv.CORINFO_CALLCONV_STDCALL,
"CallConvFastcall" => CorInfoCallConv.CORINFO_CALLCONV_FASTCALL,
"CallConvThiscall" => CorInfoCallConv.CORINFO_CALLCONV_THISCALL,
_ => null
};

private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* sig)
{
sig->callConv = (CorInfoCallConv)(signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask);
Expand Down
16 changes: 1 addition & 15 deletions src/coreclr/src/vm/dllimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3227,21 +3227,7 @@ BOOL NDirect::MarshalingRequired(
return TRUE;
}
#endif

// return value is fine as long as it can be normalized to an integer
if (i == 0)
{
CorElementType normalizedType = hndArgType.GetInternalCorElementType();
if (normalizedType == ELEMENT_TYPE_VALUETYPE)
{
// it is a structure even after normalization
return TRUE;
}
}
else
{
dwStackSize += StackElemSize(hndArgType.GetSize());
}
dwStackSize += StackElemSize(hndArgType.GetSize());
break;
}

Expand Down
Loading