Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
95c08cf
Add the DisableRuntimeMarshallingAttribute to the build.
jkoritzinsky Dec 15, 2021
225dea7
Add initial test suite
jkoritzinsky Dec 17, 2021
7c85f02
Implement support in IL stubs for the "disabled runtime marshalling" …
jkoritzinsky Dec 28, 2021
132dc67
Add testing for inlining IL stubs.
jkoritzinsky Dec 28, 2021
70f2fab
Block SetLastError and LCID support when DisableRuntimeMarshallingAtt…
jkoritzinsky Dec 28, 2021
ae4f309
Bump NativeAOT-only R2R version header (missed previously)
jkoritzinsky Jan 3, 2022
8681adf
Implement support in crossgen2 and NativeAOT
jkoritzinsky Jan 3, 2022
7700998
Clean up the test tree and update the tests to fail more reliably whe…
jkoritzinsky Jan 3, 2022
20094a2
Fix NativeAOT and clean up crossgen2
jkoritzinsky Jan 3, 2022
f9f070f
Add a test for NoPreserveSig with DisableRuntimeMarshalling
jkoritzinsky Jan 4, 2022
e0ee72e
Merge branch 'main' of github.com:dotnet/runtime into disableruntimem…
jkoritzinsky Jan 4, 2022
694f5fb
Assign hr in SUCCEEDED macro.
jkoritzinsky Jan 4, 2022
9ca4274
PR feedback.
jkoritzinsky Jan 4, 2022
e84d87d
Block varargs in disabled marshalling mode.
jkoritzinsky Jan 4, 2022
a4a8c99
Fix typo
jkoritzinsky Jan 4, 2022
a0953a2
Block types that have a field that is auto-layout somewhere in their …
jkoritzinsky Jan 5, 2022
118e21c
Fix typo
jkoritzinsky Jan 5, 2022
57c5553
Revert the AutoLayoutOrHasAutoLayoutFIeld check in the "marshalling e…
jkoritzinsky Jan 5, 2022
8c7efa3
Only set scope when it isn't null (it's null for some cases).
jkoritzinsky Jan 5, 2022
ce914dc
Fix narrowing conversion failure.
jkoritzinsky Jan 5, 2022
e72845f
First pass simple implementation in Mono
jkoritzinsky Jan 5, 2022
bcfa307
Fix assert to still work for the built-in marshalling system
jkoritzinsky Jan 6, 2022
abf48cb
S_FALSE is a thing
jkoritzinsky Jan 6, 2022
517833f
Fix type load failures caused by eager type handle loading.
jkoritzinsky Jan 6, 2022
8eee013
Get MethodILScope from the calling method when available (this covers…
jkoritzinsky Jan 6, 2022
9d58b3f
Add const modifier.
jkoritzinsky Jan 6, 2022
9bb7a62
Try 2 to fix const modifiers
jkoritzinsky Jan 6, 2022
887e20a
Fix compilation of NativeAOT jitinterface
jkoritzinsky Jan 6, 2022
a8671be
Fix type lookup in Mono
jkoritzinsky Jan 6, 2022
e1d26fc
Merge branch 'disableruntimemarshalling' of github.com:jkoritzinsky/r…
jkoritzinsky Jan 6, 2022
f928557
Use try_get model for getting the attribute type in the case of failu…
jkoritzinsky Jan 6, 2022
754ffaf
Handle void and generic instantiations
jkoritzinsky Jan 6, 2022
149ba9f
Update auto-layout check to check recursively in layout.
jkoritzinsky Jan 6, 2022
82c0086
Enhance test suite with more tests for UnmanagedCallersOnly, generics…
jkoritzinsky Jan 6, 2022
d759243
Fix IL and a few typos
jkoritzinsky Jan 7, 2022
4218e1d
Set a value in the padding for easier debugging.
jkoritzinsky Jan 7, 2022
54dc419
Create sig->marshalling_disabled to track when marshalling is disable…
jkoritzinsky Jan 7, 2022
5ae53f8
Fix running test suite on Mono + Mini JIT
jkoritzinsky Jan 8, 2022
41a4474
Fix recursive type load failure by only checking the "has auto-layout…
jkoritzinsky Jan 10, 2022
adb46bc
Fix mono windows build.
jkoritzinsky Jan 10, 2022
1b26307
Feedback from Michal.
jkoritzinsky Jan 10, 2022
5c70dc2
Fix bug in EcmaAssembly.HasAssemblyCustomAttribute
jkoritzinsky Jan 10, 2022
b8588dc
Make the runtime flavor check in the wrapper generator case-invariant
jkoritzinsky Jan 10, 2022
f2d91ff
Use helper method since various different platforms/configurations th…
jkoritzinsky Jan 10, 2022
f2f773d
Fix AutoLayout test refactor and use a dummy value for the padding fi…
jkoritzinsky Jan 10, 2022
46c12bb
Add an explicit test for using enums as they're a little weird and ne…
jkoritzinsky Jan 10, 2022
4c49207
Fix build-time test filtering in xunit wrapper generator.
jkoritzinsky Jan 11, 2022
a660f12
Fix some x86-specific issues
jkoritzinsky Jan 11, 2022
f0c86ec
Merge branch 'disableruntimemarshalling' of E:/home/jekoritz/runtime …
jkoritzinsky Jan 11, 2022
57c482b
Add a nice big comment block.
jkoritzinsky Jan 11, 2022
d0e12db
Fix x86
jkoritzinsky Jan 11, 2022
7524223
Refactor tests so we can skip one on Mono since Char->char lossy conv…
jkoritzinsky Jan 11, 2022
b62fd52
Disable test in issues.targets until an alternative solution is reached.
jkoritzinsky Jan 11, 2022
e3b7686
Add another SkipOnMono attribute in the "Enabled" test suite.
jkoritzinsky Jan 11, 2022
2ecd865
Merge branch 'disableruntimemarshalling' of github.com:jkoritzinsky/r…
jkoritzinsky Jan 11, 2022
7b0f9b2
Apply UnmangedFunctionPointerAttribute to help hint to the Mono LLVM …
jkoritzinsky Jan 11, 2022
3122f76
Unify on "runtime marshalling" terminology
jkoritzinsky Jan 13, 2022
0d1f54e
Clean up unused usings.
jkoritzinsky Jan 13, 2022
6a08e87
Address Jan's feedback except for applying the attribute to CoreLib.
jkoritzinsky Jan 15, 2022
9e0fc41
PR feedback.
jkoritzinsky Jan 20, 2022
0896e44
Mono throws an InvalidProgramException for varargs
jkoritzinsky Jan 20, 2022
3609c82
Fix copy-paste issue.
jkoritzinsky Jan 20, 2022
74b0f61
Make sure we use the P/Invoke's Module and not the caller's module wh…
jkoritzinsky Jan 21, 2022
f496d66
Handle how LLVM AOT reports the failure to handle varargs (EEE)
jkoritzinsky Jan 21, 2022
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
Prev Previous commit
Next Next commit
Implement support in crossgen2 and NativeAOT
  • Loading branch information
jkoritzinsky committed Jan 3, 2022
commit 8681adf4324eafc5e01118eb4643b0b4b5669a0b
2 changes: 1 addition & 1 deletion src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3747,7 +3747,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>())) // Only blittable arguments
if (Marshaller.IsMarshallingRequired(this.MethodBeingCompiled.Signature, Array.Empty<ParameterMetadata>(), ((MetadataType)this.MethodBeingCompiled.OwningType).Module)) // Only blittable arguments
{
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramNonBlittableTypes, this.MethodBeingCompiled);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ public partial class CalliMarshallingMethodThunk : ILStubMethod
private MethodSignature _signature;

public CalliMarshallingMethodThunk(MethodSignature targetSignature, TypeDesc owningType,
InteropStateManager interopStateManager)
InteropStateManager interopStateManager,
bool useRuntimeMarshalling)
{
_targetSignature = targetSignature;
_owningType = owningType;
_interopStateManager = interopStateManager;
UseRuntimeMarshalling = useRuntimeMarshalling;
}

public MethodSignature TargetSignature
Expand Down Expand Up @@ -79,6 +81,8 @@ public override string Name
}
}

public bool UseRuntimeMarshalling { get; }

public override PInvokeMetadata GetPInvokeMethodMetadata()
{
// Return PInvokeAttributes.PreserveSig to circumvent marshalling required checks
Expand Down
48 changes: 34 additions & 14 deletions src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeILEmitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,21 @@ private static Marshaller[] InitializeMarshallers(MethodDesc targetMethod, Inter
{
MarshalDirection direction = MarshalDirection.Forward;
MethodSignature methodSig;
bool runtimeMarshallingEnabled;
switch (targetMethod)
{
case DelegateMarshallingMethodThunk delegateMethod:
methodSig = delegateMethod.DelegateSignature;
direction = delegateMethod.Direction;
runtimeMarshallingEnabled = MarshalHelpers.IsRuntimeMarshallingEnabled(delegateMethod.DelegateType.Module);
break;
case CalliMarshallingMethodThunk calliMethod:
methodSig = calliMethod.TargetSignature;
runtimeMarshallingEnabled = calliMethod.UseRuntimeMarshalling;
break;
default:
methodSig = targetMethod.Signature;
runtimeMarshallingEnabled = MarshalHelpers.IsRuntimeMarshallingEnabled(((EcmaMethod)targetMethod).Module);
break;
}
int indexOffset = 0;
Expand Down Expand Up @@ -114,20 +118,36 @@ private static Marshaller[] InitializeMarshallers(MethodDesc targetMethod, Inter
parameterType = methodSig[i - 1];
}

marshallers[i] = Marshaller.CreateMarshaller(parameterType,
parameterIndex,
methodSig.GetEmbeddedSignatureData(),
MarshallerType.Argument,
parameterMetadata.MarshalAsDescriptor,
direction,
marshallers,
interopStateManager,
indexOffset + parameterMetadata.Index,
flags,
parameterMetadata.In,
isHRSwappedRetVal ? true : parameterMetadata.Out,
isHRSwappedRetVal ? false : parameterMetadata.Return
);
if (runtimeMarshallingEnabled)
{
marshallers[i] = Marshaller.CreateMarshaller(parameterType,
parameterIndex,
methodSig.GetEmbeddedSignatureData(),
MarshallerType.Argument,
parameterMetadata.MarshalAsDescriptor,
direction,
marshallers,
interopStateManager,
indexOffset + parameterMetadata.Index,
flags,
parameterMetadata.In,
isHRSwappedRetVal ? true : parameterMetadata.Out,
isHRSwappedRetVal ? false : parameterMetadata.Return
);
}
else
{
marshallers[i] = Marshaller.CreateDisabledRuntimeMarshallingMarshaller(
parameterType,
parameterIndex,
MarshallerType.Argument,
direction,
marshallers,
interopStateManager,
indexOffset + parameterMetadata.Index,
flags,
parameterMetadata.Return);
}
}

return marshallers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public static MethodIL EmitExceptionBody(string message, MethodDesc method)
TypeSystemContext context = method.Context;
MethodSignature ctorSignature = new MethodSignature(0, 0, context.GetWellKnownType(WellKnownType.Void),
new TypeDesc[] { context.GetWellKnownType(WellKnownType.String) });
MethodDesc exceptionCtor = method.Context.GetWellKnownType(WellKnownType.Exception).GetKnownMethod(".ctor", ctorSignature);
MethodDesc exceptionCtor = InteropTypes.GetMarshalDirectiveException(context).GetKnownMethod(".ctor", ctorSignature);

ILCodeStream codeStream = emitter.NewCodeStream();
codeStream.Emit(ILOpcode.ldstr, emitter.NewToken(message));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Internal.IL;
using Debug = System.Diagnostics.Debug;
using Internal.IL.Stubs;
using Internal.TypeSystem.Ecma;

namespace Internal.TypeSystem.Interop
{
Expand Down Expand Up @@ -844,6 +845,24 @@ private static MarshallerKind GetArrayElementMarshallerKind(
}
}

internal static MarshallerKind GetRuntimeDisabledMarshallingMarshallerKind(
TypeDesc type)
{
if (type.IsPrimitive && type.Category != TypeFlags.Void)
{
return MarshallerKind.BlittableValue;
}
else if (type.IsPointer || type.IsFunctionPointer)
{
return MarshallerKind.BlittableValue;
}
else if (type.IsValueType && !((DefType)type).ContainsGCPointers)
{
return MarshallerKind.BlittableValue;
}
return MarshallerKind.Invalid;
}

internal static bool ShouldCheckForPendingException(TargetDetails target, PInvokeMetadata metadata)
{
if (!target.IsOSX)
Expand All @@ -861,5 +880,10 @@ internal static bool ShouldCheckForPendingException(TargetDetails target, PInvok
return metadata.Module.Equals(ObjectiveCLibrary)
&& metadata.Name.StartsWith(ObjectiveCMsgSend);
}

public static bool IsRuntimeMarshallingEnabled(ModuleDesc module)
{
return module.Assembly is not EcmaAssembly assembly || assembly.HasAssemblyCustomAttribute("System.Runtime.CompilerServices", "DisableRuntimeMarshallingAttribute");
}
}
}
52 changes: 52 additions & 0 deletions src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,58 @@ public static Marshaller CreateMarshaller(TypeDesc parameterType,

return marshaller;
}

/// <summary>
/// Create a marshaller
/// </summary>
/// <param name="parameterType">type of the parameter to marshal</param>
/// <returns>The created Marshaller</returns>
public static Marshaller CreateDisabledRuntimeMarshallingMarshaller(TypeDesc parameterType,
int? parameterIndex,
MarshallerType marshallerType,
MarshalDirection direction,
Marshaller[] marshallers,
#if !READYTORUN
InteropStateManager interopStateManager,
#endif
int index,
PInvokeFlags flags,
bool isReturn)
{
bool isAnsi = flags.CharSet switch
{
CharSet.Ansi => true,
CharSet.Unicode => false,
CharSet.Auto => !parameterType.Context.Target.IsWindows,
_ => true
};

MarshallerKind marshallerKind = MarshalHelpers.GetRuntimeDisabledMarshallingMarshallerKind(parameterType);

TypeSystemContext context = parameterType.Context;
// Create the marshaller based on MarshallerKind
Marshaller marshaller = CreateMarshaller(marshallerKind);
marshaller.Context = context;
#if !READYTORUN
marshaller.InteropStateManager = interopStateManager;
#endif
marshaller.MarshallerKind = marshallerKind;
marshaller.MarshallerType = marshallerType;
marshaller.ElementMarshallerKind = MarshallerKind.Unknown;
marshaller.ManagedParameterType = parameterType;
marshaller.ManagedType = parameterType.IsByRef ? parameterType.GetParameterType() : parameterType;
marshaller.Return = isReturn;
marshaller.IsManagedByRef = parameterType.IsByRef;
marshaller.IsNativeByRef = marshaller.IsManagedByRef;
marshaller.MarshalDirection = direction;
marshaller.MarshalAsDescriptor = null;
marshaller.Marshallers = marshallers;
marshaller.Index = index;
marshaller.PInvokeFlags = flags;
marshaller.In = true;
marshaller.Out = marshaller.IsManagedByRef;
return marshaller;
}
#endregion


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ public FieldDesc GetPInvokeLazyFixupField(MethodDesc method)
return _pInvokeLazyFixupFieldHashtable.GetOrCreateValue(method);
}

public MethodDesc GetPInvokeCalliStub(MethodSignature signature)
public MethodDesc GetPInvokeCalliStub(MethodSignature signature, bool useRuntimeMarshalling)
{
return _pInvokeCalliHashtable.GetOrCreateValue(signature);
return _pInvokeCalliHashtable.GetOrCreateValue((signature, useRuntimeMarshalling));
}

private class NativeStructTypeHashtable : LockFreeReaderHashtable<MetadataType, NativeStructType>
Expand Down Expand Up @@ -478,12 +478,12 @@ public PInvokeLazyFixupFieldHashtable(DefType owningType)
}
}

private class PInvokeCalliHashtable : LockFreeReaderHashtable<MethodSignature, CalliMarshallingMethodThunk>
private class PInvokeCalliHashtable : LockFreeReaderHashtable<(MethodSignature Signature, bool UseRuntimeMarshalling), CalliMarshallingMethodThunk>
{
private readonly InteropStateManager _interopStateManager;
private readonly TypeDesc _owningType;

protected override int GetKeyHashCode(MethodSignature key)
protected override int GetKeyHashCode((MethodSignature Signature, bool UseRuntimeMarshalling) key)
{
return key.GetHashCode();
}
Expand All @@ -493,7 +493,7 @@ protected override int GetValueHashCode(CalliMarshallingMethodThunk value)
return value.TargetSignature.GetHashCode();
}

protected override bool CompareKeyToValue(MethodSignature key, CalliMarshallingMethodThunk value)
protected override bool CompareKeyToValue((MethodSignature Signature, bool UseRuntimeMarshalling) key, CalliMarshallingMethodThunk value)
{
return key.Equals(value.TargetSignature);
}
Expand All @@ -503,9 +503,9 @@ protected override bool CompareValueToValue(CalliMarshallingMethodThunk value1,
return value1.TargetSignature.Equals(value2.TargetSignature);
}

protected override CalliMarshallingMethodThunk CreateValueFromKey(MethodSignature key)
protected override CalliMarshallingMethodThunk CreateValueFromKey((MethodSignature Signature, bool UseRuntimeMarshalling) key)
{
return new CalliMarshallingMethodThunk(key, _owningType, _interopStateManager);
return new CalliMarshallingMethodThunk(key.Signature, _owningType, _interopStateManager, key.UseRuntimeMarshalling);
}

public PInvokeCalliHashtable(InteropStateManager interopStateManager, TypeDesc owningType)
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ public static MetadataType GetNativeFunctionPointerWrapper(TypeSystemContext con
return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "NativeFunctionPointerWrapper");
}

public static MetadataType GetMarshalDirectiveException(TypeSystemContext context)
{
return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "MarshalDirectiveException");
}

public static MetadataType GetVariant(TypeSystemContext context)
{
return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "Variant");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public UsageBasedInteropStubManager(InteropStateManager interopStateManager, PIn

public override void AddDependeciesDueToPInvoke(ref DependencyList dependencies, NodeFactory factory, MethodDesc method)
{
if (method.IsPInvoke)
if (method.IsPInvoke && method.OwningType is MetadataType type && MarshalHelpers.IsRuntimeMarshallingEnabled(type.Module))
{
dependencies = dependencies ?? new DependencyList();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ public override MethodIL GetMethodIL(MethodDesc method)
return PInvokeILEmitter.EmitIL(method, _pInvokeILEmitterConfiguration, _interopStateManager);
}

public MethodDesc GetCalliStub(MethodSignature signature)
public MethodDesc GetCalliStub(MethodSignature signature, bool useRuntimeMarshalling)
{
return _interopStateManager.GetPInvokeCalliStub(signature);
return _interopStateManager.GetPInvokeCalliStub(signature, useRuntimeMarshalling);
}

public string GetDirectCallExternName(MethodDesc method)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Internal.JitInterface;

using Debug = System.Diagnostics.Debug;
using Internal.TypeSystem.Ecma;

namespace Internal.IL.Stubs
{
Expand Down Expand Up @@ -46,6 +47,15 @@ private void EmitPInvokeCall(PInvokeILCodeStreams ilCodeStreams)
// if the SetLastError flag is set in DllImport, clear the error code before doing P/Invoke
if (_importMetadata.Flags.SetLastError)
{
if (_targetMethod is EcmaMethod ecmaMethod
&& ecmaMethod.Module.Assembly is EcmaAssembly assembly
&& assembly.HasAssemblyCustomAttribute("System.Runtime.CompilerServices", "DisableRuntimeMarshallingAttribute"))
{
// When runtime marshalling is disabled, we don't support generating the stub IL
// in Ready-to-Run so we can correctly throw an exception at runtime when the user tries to
// use SetLastError=true when marshalling is disabled.
throw new NotSupportedException();
}
callsiteSetupCodeStream.Emit(ILOpcode.call, emitter.NewToken(
stubHelpersType.GetKnownMethod("ClearLastError", null)));
}
Expand Down
Loading