From d47081a3f3c60007f652c8617b58d98ce79bd224 Mon Sep 17 00:00:00 2001 From: Fadi Hanna Date: Wed, 27 Nov 2019 13:35:29 -0800 Subject: [PATCH] Fix EH handling in PInvoke stubs and remove workaround (#327) * Fix EH handling in PInvoke stubs and remove workaround The fix in the JIT is to inline the raw PInvoke call if: 1) We are compiling a PInvoke IL Stub 2) We are compiling using the PInvoke helpers --- src/coreclr/src/jit/importer.cpp | 7 +++++++ .../ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs | 14 ++------------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index ddf1099..79e9880 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -6393,6 +6393,13 @@ bool Compiler::impCanPInvokeInlineCallSite(BasicBlock* block) // jit\jit64\ebvts\mcpp\sources2\ijw\__clrcall\vector_ctor_dtor.02\deldtor_clr.exe if (block->hasTryIndex()) { + // This does not apply to the raw pinvoke call that is inside the pinvoke + // ILStub. In this case, we have to inline the raw pinvoke call into the stub, + // otherwise we would end up with a stub that recursively calls itself, and end + // up with a stack overflow. + if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB) && opts.ShouldUsePInvokeHelpers()) + return true; + return false; } #endif // _TARGET_64BIT_ diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs index bfc2511..c557265 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs @@ -76,13 +76,6 @@ namespace Internal.IL.Stubs private MethodIL EmitIL() { - // Temp workaround to disable PInvoke stubs that require marshalling. - // https://github.com/dotnet/runtime/issues/248 - { - if (Marshaller.IsMarshallingRequired(_targetMethod)) - throw new NotSupportedException(); - } - if (!_importMetadata.Flags.PreserveSig) throw new NotSupportedException(); @@ -95,13 +88,11 @@ namespace Internal.IL.Stubs ILCodeStream unmarshallingCodestream = pInvokeILCodeStreams.UnmarshallingCodestream; ILCodeStream cleanupCodestream = pInvokeILCodeStreams.CleanupCodeStream; - /* Temp workaround: disable EH blocks because of https://github.com/dotnet/runtime/issues/248 - // Marshalling is wrapped in a finally block to guarantee cleanup ILExceptionRegionBuilder tryFinally = emitter.NewFinallyRegion(); marshallingCodestream.BeginTry(tryFinally); - cleanupCodestream.BeginHandler(tryFinally);*/ + cleanupCodestream.BeginHandler(tryFinally); // Marshal the arguments for (int i = 0; i < _marshallers.Length; i++) @@ -112,12 +103,11 @@ namespace Internal.IL.Stubs EmitPInvokeCall(pInvokeILCodeStreams); ILCodeLabel lReturn = emitter.NewCodeLabel(); - /* Temp workaround: disable EH blocks because of https://github.com/dotnet/runtime/issues/248 unmarshallingCodestream.Emit(ILOpcode.leave, lReturn); unmarshallingCodestream.EndTry(tryFinally); cleanupCodestream.Emit(ILOpcode.endfinally); - cleanupCodestream.EndHandler(tryFinally);*/ + cleanupCodestream.EndHandler(tryFinally); cleanupCodestream.EmitLabel(lReturn); -- 2.7.4