From 9f654ce129ff05f27ef7844af6a775b883d2d3e8 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 7 Jun 2022 10:42:07 -0700 Subject: Remove complex marshalling support from crossgen2 (#70183) --- .../Common/TypeSystem/Interop/IL/Marshaller.cs | 134 --------------------- .../Common/TypeSystem/Interop/InteropTypes.cs | 5 - .../ReadyToRunCompilationModuleGroupBase.cs | 17 --- .../IL/Stubs/PInvokeILEmitter.cs | 27 +---- .../Interop/IL/Marshaller.ReadyToRun.cs | 16 +-- src/coreclr/vm/dllimport.cpp | 2 +- 6 files changed, 5 insertions(+), 196 deletions(-) diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs index 490e804dda6..0e38a100098 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs @@ -1544,16 +1544,12 @@ namespace Internal.TypeSystem.Interop } else { -#if READYTORUN - throw new NotSupportedException(); -#else var helper = Context.GetHelperEntryPoint("InteropHelpers", "StringToUnicodeBuffer"); LoadManagedValue(codeStream); codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); StoreNativeValue(codeStream); -#endif } } @@ -1593,11 +1589,6 @@ namespace Internal.TypeSystem.Interop class AnsiStringMarshaller : Marshaller { -#if READYTORUN - const int MAX_LOCAL_BUFFER_LENGTH = 260 + 1; // MAX_PATH + 1 - - private ILLocalVariable? _localBuffer = null; -#endif internal override bool CleanupRequired { @@ -1620,80 +1611,6 @@ namespace Internal.TypeSystem.Interop // // ANSI marshalling. Allocate a byte array, copy characters // - -#if READYTORUN - var stringToAnsi = - Context.SystemModule.GetKnownType("System.StubHelpers", "CSTRMarshaler") - .GetKnownMethod("ConvertToNative", null); - - bool bPassByValueInOnly = In && !Out && !IsManagedByRef; - - if (bPassByValueInOnly) - { - var bufSize = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Int32)); - _localBuffer = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.IntPtr)); - - // LocalBuffer = 0 - codeStream.Emit(ILOpcode.ldnull); - codeStream.EmitStLoc((ILLocalVariable)_localBuffer); - - var noOptimize = emitter.NewCodeLabel(); - - // if == NULL, goto NoOptimize - LoadManagedValue(codeStream); - codeStream.Emit(ILOpcode.brfalse, noOptimize); - - // String.Length + 2 - LoadManagedValue(codeStream); - var stringLen = - Context.GetWellKnownType(WellKnownType.String) - .GetKnownMethod("get_Length", null); - codeStream.Emit(ILOpcode.call, emitter.NewToken(stringLen)); - codeStream.EmitLdc(2); - codeStream.Emit(ILOpcode.add); - - // (String.Length + 2) * GetMaxDBCSCharByteSize() - codeStream.Emit(ILOpcode.ldsfld, emitter.NewToken(Context.SystemModule.GetKnownType( - "System.Runtime.InteropServices","Marshal") - .GetKnownField("SystemMaxDBCSCharSize"))); - codeStream.Emit(ILOpcode.mul_ovf); - - // BufSize = (String.Length + 2) * GetMaxDBCSCharByteSize() - codeStream.EmitStLoc(bufSize); - - // if (MAX_LOCAL_BUFFER_LENGTH < BufSize ) goto NoOptimize - codeStream.EmitLdc(MAX_LOCAL_BUFFER_LENGTH + 1); - codeStream.EmitLdLoc(bufSize); - codeStream.Emit(ILOpcode.clt); - codeStream.Emit(ILOpcode.brtrue, noOptimize); - - // LocalBuffer = localloc(BufSize); - codeStream.EmitLdLoc(bufSize); - codeStream.Emit(ILOpcode.localloc); - codeStream.EmitStLoc((ILLocalVariable)_localBuffer); - - // NoOptimize: - codeStream.EmitLabel(noOptimize); - } - - int flags = (PInvokeFlags.BestFitMapping ? 0x1 : 0) - | (PInvokeFlags.ThrowOnUnmappableChar ? 0x100 : 0); - - // CSTRMarshaler.ConvertToNative pManaged, dwAnsiMarshalFlags, pLocalBuffer - codeStream.EmitLdc(flags); - LoadManagedValue(codeStream); - - if (_localBuffer.HasValue) - { - codeStream.EmitLdLoc((ILLocalVariable)_localBuffer); - } - else - { - codeStream.Emit(ILOpcode.ldnull); - } - - codeStream.Emit(ILOpcode.call, emitter.NewToken(stringToAnsi)); -#else LoadManagedValue(codeStream); var stringToAnsi = Context.GetHelperEntryPoint("InteropHelpers", "StringToAnsiString"); @@ -1701,7 +1618,6 @@ namespace Internal.TypeSystem.Interop codeStream.Emit(PInvokeFlags.ThrowOnUnmappableChar ? ILOpcode.ldc_i4_1 : ILOpcode.ldc_i4_0); codeStream.Emit(ILOpcode.call, emitter.NewToken(stringToAnsi)); -#endif StoreNativeValue(codeStream); } @@ -1709,14 +1625,7 @@ namespace Internal.TypeSystem.Interop protected override void TransformNativeToManaged(ILCodeStream codeStream) { ILEmitter emitter = _ilCodeStreams.Emitter; - -#if READYTORUN - var ansiToString = - Context.SystemModule.GetKnownType("System.StubHelpers", "CSTRMarshaler") - .GetKnownMethod("ConvertToManaged", null); -#else var ansiToString = Context.GetHelperEntryPoint("InteropHelpers", "AnsiStringToString"); -#endif LoadNativeValue(codeStream); codeStream.Emit(ILOpcode.call, emitter.NewToken(ansiToString)); StoreManagedValue(codeStream); @@ -1725,30 +1634,6 @@ namespace Internal.TypeSystem.Interop protected override void EmitCleanupManaged(ILCodeStream codeStream) { var emitter = _ilCodeStreams.Emitter; -#if READYTORUN - var optimize = emitter.NewCodeLabel(); - - MethodDesc clearNative = - Context.SystemModule.GetKnownType("System.StubHelpers", "CSTRMarshaler") - .GetKnownMethod("ClearNative", null); - - if (_localBuffer.HasValue) - { - // if (m_dwLocalBuffer) goto Optimize - codeStream.EmitLdLoc((ILLocalVariable)_localBuffer); - codeStream.Emit(ILOpcode.brtrue, optimize); - } - - LoadNativeValue(codeStream); - // static void m_idClearNative(IntPtr ptr) - codeStream.Emit(ILOpcode.call, emitter.NewToken(clearNative)); - - // Optimize: - if (_localBuffer != default) - { - codeStream.EmitLabel(optimize); - } -#else var lNullCheck = emitter.NewCodeLabel(); // Check for null array @@ -1760,7 +1645,6 @@ namespace Internal.TypeSystem.Interop InteropTypes.GetMarshal(Context).GetKnownMethod("FreeCoTaskMem", null))); codeStream.EmitLabel(lNullCheck); -#endif } } @@ -2042,11 +1926,7 @@ namespace Internal.TypeSystem.Interop codeStream.Emit(ILOpcode.brfalse, lNullPointer); codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken( -#if READYTORUN - InteropTypes.GetMarshal(Context).GetKnownMethod("GetFunctionPointerForDelegate", -#else InteropTypes.GetPInvokeMarshal(Context).GetKnownMethod("GetFunctionPointerForDelegate", -#endif new MethodSignature(MethodSignatureFlags.Static, 0, Context.GetWellKnownType(WellKnownType.IntPtr), new TypeDesc[] { Context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType } )))); @@ -2070,19 +1950,6 @@ namespace Internal.TypeSystem.Interop LoadNativeValue(codeStream); codeStream.Emit(ILOpcode.dup); codeStream.Emit(ILOpcode.brfalse, lNullPointer); - -#if READYTORUN - TypeDesc systemType = Context.SystemModule.GetKnownType("System", "Type"); - - codeStream.Emit(ILOpcode.ldtoken, _ilCodeStreams.Emitter.NewToken(ManagedType)); - codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken(systemType.GetKnownMethod("GetTypeFromHandle", null))); - - codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken( - InteropTypes.GetMarshal(Context).GetKnownMethod("GetDelegateForFunctionPointer", - new MethodSignature(MethodSignatureFlags.Static, 0, Context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType, - new TypeDesc[] { Context.GetWellKnownType(WellKnownType.IntPtr), systemType } - )))); -#else codeStream.Emit(ILOpcode.ldtoken, _ilCodeStreams.Emitter.NewToken(ManagedType)); codeStream.Emit(ILOpcode.call, _ilCodeStreams.Emitter.NewToken( @@ -2090,7 +1957,6 @@ namespace Internal.TypeSystem.Interop new MethodSignature(MethodSignatureFlags.Static, 0, Context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType, new TypeDesc[] { Context.GetWellKnownType(WellKnownType.IntPtr), Context.GetWellKnownType(WellKnownType.RuntimeTypeHandle) } )))); -#endif codeStream.Emit(ILOpcode.br, lDone); diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs b/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs index ac32fbbe546..d78b275f49e 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs @@ -44,11 +44,6 @@ namespace Internal.TypeSystem.Interop return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "MemoryMarshal"); } - public static MetadataType GetStubHelpers(TypeSystemContext context) - { - return context.SystemModule.GetKnownType("System.StubHelpers", "StubHelpers"); - } - public static MetadataType GetNativeFunctionPointerWrapper(TypeSystemContext context) { return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "NativeFunctionPointerWrapper"); diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs index 680081a0567..d87baeff11f 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs @@ -349,23 +349,6 @@ namespace ILCompiler public sealed override bool GeneratesPInvoke(MethodDesc method) { - // PInvokes depend on details of the core library, so for now only compile them if: - // 1) We're compiling the core library module, or - // 2) We're compiling any module, and no marshalling is needed - // - // TODO Future: consider compiling PInvokes with complex marshalling in version bubble - // mode when the core library is included in the bubble. - - Debug.Assert(method is EcmaMethod); - - // If the PInvoke is declared on an external module, we can only compile it if - // that module is part of the version bubble. - if (!_versionBubbleModuleSet.Contains(((EcmaMethod)method).Module)) - return false; - - if (((EcmaMethod)method).Module.Equals(method.Context.SystemModule)) - return true; - return !Marshaller.IsMarshallingRequired(method); } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs index 6fc1687d7a7..e34694b5019 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs @@ -41,22 +41,6 @@ namespace Internal.IL.Stubs TypeDesc nativeReturnType = _marshallers[0].NativeParameterType; TypeDesc[] nativeParameterTypes = new TypeDesc[_marshallers.Length - 1]; - MetadataType stubHelpersType = InteropTypes.GetStubHelpers(context); - - // if the SetLastError flag is set in DllImport, clear the error code before doing P/Invoke - if (_importMetadata.Flags.SetLastError) - { - if (!MarshalHelpers.IsRuntimeMarshallingEnabled(((MetadataType)_targetMethod.OwningType).Module)) - { - // 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))); - } - for (int i = 1; i < _marshallers.Length; i++) { nativeParameterTypes[i - 1] = _marshallers[i].NativeParameterType; @@ -69,14 +53,6 @@ namespace Internal.IL.Stubs var rawTargetMethod = new PInvokeTargetNativeMethod(_targetMethod, nativeSig); callsiteSetupCodeStream.Emit(ILOpcode.call, emitter.NewToken(rawTargetMethod)); - - // if the SetLastError flag is set in DllImport, call the PInvokeMarshal.SaveLastError - // so that last error can be used later by calling Marshal.GetLastPInvokeError - if (_importMetadata.Flags.SetLastError) - { - callsiteSetupCodeStream.Emit(ILOpcode.call, emitter.NewToken( - stubHelpersType.GetKnownMethod("SetLastError", null))); - } } private MethodIL EmitIL() @@ -93,6 +69,9 @@ namespace Internal.IL.Stubs if (_targetMethod.HasCustomAttribute("System.Runtime.InteropServices", "LCIDConversionAttribute")) throw new NotSupportedException(); + if (_importMetadata.Flags.SetLastError) + throw new NotSupportedException(); + PInvokeILCodeStreams pInvokeILCodeStreams = new PInvokeILCodeStreams(); ILEmitter emitter = pInvokeILCodeStreams.Emitter; ILCodeStream marshallingCodestream = pInvokeILCodeStreams.MarshallingCodeStream; 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 ddb1d24c1b5..b7843dca9ea 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 @@ -9,6 +9,7 @@ namespace Internal.TypeSystem.Interop { protected static Marshaller CreateMarshaller(MarshallerKind kind) { + // ReadyToRun only supports emitting IL for blittable types switch (kind) { case MarshallerKind.Enum: @@ -16,23 +17,8 @@ namespace Internal.TypeSystem.Interop case MarshallerKind.BlittableStruct: case MarshallerKind.UnicodeChar: return new BlittableValueMarshaller(); - case MarshallerKind.BlittableStructPtr: - return new BlittableStructPtrMarshaller(); - case MarshallerKind.BlittableArray: - return new BlittableArrayMarshaller(); - case MarshallerKind.Bool: - case MarshallerKind.CBool: - return new BooleanMarshaller(); - case MarshallerKind.AnsiString: - return new AnsiStringMarshaller(); - case MarshallerKind.SafeHandle: - return new SafeHandleMarshaller(); - case MarshallerKind.UnicodeString: - return new UnicodeStringMarshaller(); case MarshallerKind.VoidReturn: return new VoidReturnMarshaller(); - case MarshallerKind.FunctionPointer: - return new DelegateMarshaller(); default: // ensures we don't throw during create marshaller. We will throw NSE // during EmitIL which will be handled. diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index 359d68855c5..dceb6f6b89f 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -3366,7 +3366,7 @@ BOOL NDirect::MarshalingRequired( default: { - if (CorTypeInfo::IsPrimitiveType(type) || type == ELEMENT_TYPE_FNPTR) + if (CorTypeInfo::IsPrimitiveType(type) || type == ELEMENT_TYPE_PTR || type == ELEMENT_TYPE_FNPTR) { if (i > 0) -- cgit v1.2.3