diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index ae2b5d51edc5e1..9e6f1d9a5a810a 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -218,6 +218,7 @@ static size_t CreateDispatchTokenForMethod(MethodDesc* pMD) // Call invoker helpers provided by platform. void InvokeManagedMethod(MethodDesc *pMD, int8_t *pArgs, int8_t *pRet, PCODE target, Object** pContinuationRet); void InvokeUnmanagedMethod(MethodDesc *targetMethod, int8_t *pArgs, int8_t *pRet, PCODE callTarget); +void InvokeUnmanagedMethodInPreemptiveMode(MethodDesc *targetMethod, int8_t *pArgs, int8_t *pRet, PCODE callTarget); void InvokeCalliStub(PCODE ftn, InterpreterCalliCookie cookie, int8_t *pArgs, int8_t *pRet, Object** pContinuationRet); void InvokeUnmanagedCalli(PCODE ftn, InterpreterCalliCookie cookie, int8_t *pArgs, int8_t *pRet); void InvokeDelegateInvokeMethod(MethodDesc *pMDDelegateInvoke, int8_t *pArgs, int8_t *pRet, PCODE target, Object** pContinuationRet); @@ -232,6 +233,15 @@ LONG IgnoreCppExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID pv) : EXCEPTION_EXECUTE_HANDLER; } +NOINLINE static void DECLSPEC_NORETURN RethrowLastThrownObject() +{ + WRAPPER_NO_CONTRACT; + + GCX_COOP(); + OBJECTREF ohThrowable = GetThread()->LastThrownObject(); + DispatchManagedException(ohThrowable); +} + template std::invoke_result_t CallWithSEHWrapper(Function function) { @@ -253,9 +263,7 @@ std::invoke_result_t CallWithSEHWrapper(Function function) // INSTALL_/UNINSTALL_UNWIND_AND_CONTINUE_HANDLER in the InterpExecMethod. // The managed ones are represented by SEH exception, which cannot be handled there // because it is not possible to handle both SEH and C++ exceptions in the same frame. - GCX_COOP_NO_DTOR(); - OBJECTREF ohThrowable = GetThread()->LastThrownObject(); - DispatchManagedException(ohThrowable); + RethrowLastThrownObject(); } PAL_ENDTRY @@ -285,10 +293,8 @@ void InvokeUnmanagedMethodWithTransition(MethodDesc *targetMethod, int8_t *stack PAL_TRY(Param *, pParam, ¶m) { - GCX_PREEMP_NO_DTOR(); // WASM-TODO: Handle unmanaged calling conventions - InvokeManagedMethod(pParam->targetMethod, pParam->pArgs, pParam->pRet, pParam->callTarget, NULL); - GCX_PREEMP_NO_DTOR_END(); + InvokeUnmanagedMethodInPreemptiveMode(pParam->targetMethod, pParam->pArgs, pParam->pRet, pParam->callTarget); } PAL_EXCEPT_FILTER(IgnoreCppExceptionFilter) { @@ -298,9 +304,7 @@ void InvokeUnmanagedMethodWithTransition(MethodDesc *targetMethod, int8_t *stack // INSTALL_/UNINSTALL_UNWIND_AND_CONTINUE_HANDLER in the InterpExecMethod. // The managed ones are represented by SEH exception, which cannot be handled there // because it is not possible to handle both SEH and C++ exceptions in the same frame. - GCX_COOP_NO_DTOR(); - OBJECTREF ohThrowable = GetThread()->LastThrownObject(); - DispatchManagedException(ohThrowable); + RethrowLastThrownObject(); } PAL_ENDTRY @@ -616,6 +620,14 @@ CallStubHeader *CreateNativeToInterpreterCallStub(InterpMethod* pInterpMethod) } #endif // !TARGET_WASM +void InvokeUnmanagedMethodInPreemptiveMode(MethodDesc *targetMethod, int8_t *pArgs, int8_t *pRet, PCODE callTarget) +{ + WRAPPER_NO_CONTRACT; + + GCX_PREEMP(); + InvokeUnmanagedMethod(targetMethod, pArgs, pRet, callTarget); +} + #ifdef _DEBUG void DBG_PrintInterpreterStack() { @@ -4809,7 +4821,7 @@ do \ } catch (const ResumeAfterCatchException& ex) { - GCX_COOP_NO_DTOR(); + _ASSERTE(GetThread()->PreemptiveGCDisabled()); ex.GetResumeContext(&resumeSP, &resumeIP); _ASSERTE(resumeSP != 0 && resumeIP != 0);