From 9c1854d269a1b5aa1a566d5594b1bbaa502685db Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Wed, 24 Jun 2026 09:43:08 -0700 Subject: [PATCH] [wasm] Fix reflection invoke of R2R-compiled methods CallDescrWorkerInternal only dispatched to interpreted targets: for an R2R method GetInterpreterCode() stays null after the prestub, so it ran the interpreter with a null target, executed nothing, and left the return buffer aliasing the arguments. Dispatch through InvokeManagedMethod (the interpreter-to-R2R thunk) when there is no interpreter code, as ExecuteInterpretedMethodWithArgs_PortableEntryPoint_Complex already does. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/coreclr/vm/wasm/calldescrworkerwasm.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/wasm/calldescrworkerwasm.cpp b/src/coreclr/vm/wasm/calldescrworkerwasm.cpp index ad7581265efb1a..629faf0a88dd16 100644 --- a/src/coreclr/vm/wasm/calldescrworkerwasm.cpp +++ b/src/coreclr/vm/wasm/calldescrworkerwasm.cpp @@ -38,5 +38,18 @@ extern "C" void STDCALL CallDescrWorkerInternal(CallDescrData* pCallDescrData) retBuff = &pCallDescrData->returnValue; } - ExecuteInterpretedMethodWithArgs((TADDR)targetIp, args, argsSize, retBuff, (PCODE)&CallDescrWorkerInternal); + if (targetIp == NULL) + { + // The target has no interpreter code because it is R2R (native Wasm) compiled. + // Dispatch to the native entry point via the interpreter-to-R2R thunk, mirroring + // ExecuteInterpretedMethodWithArgs_PortableEntryPoint_Complex. Calling the + // interpreter with a NULL target would not execute the method and would leave the + // return buffer aliasing the incoming arguments. + ManagedMethodParam param = { pMethod, args, (int8_t*)retBuff, (PCODE)NULL, NULL }; + InvokeManagedMethod(¶m); + } + else + { + ExecuteInterpretedMethodWithArgs((TADDR)targetIp, args, argsSize, retBuff, (PCODE)&CallDescrWorkerInternal); + } }