From b32e435e50ad90a376d33097cb2a660227a6abd7 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Thu, 7 Aug 2025 09:56:36 +0200 Subject: [PATCH] Fix interpreter helper and stack size computation This change fixes two issues: * INTOP_CALL_HELPER_P_S was taking arguments from wrong locations in the instruction * The total stack size computation in the call stub generator was incorrect in case arguments smaller than 8 bytes were passed on the stack. --- src/coreclr/vm/callstubgenerator.cpp | 6 +----- src/coreclr/vm/interpexec.cpp | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/coreclr/vm/callstubgenerator.cpp b/src/coreclr/vm/callstubgenerator.cpp index 10855af6bc402f..02f275d9b9506a 100644 --- a/src/coreclr/vm/callstubgenerator.cpp +++ b/src/coreclr/vm/callstubgenerator.cpp @@ -1416,7 +1416,7 @@ void CallStubGenerator::ComputeCallStub(MetaSig &sig, PCODE *pRoutines) m_s1 = NoRange; // indicates that there is no active range of stack arguments m_s2 = 0; m_routineIndex = 0; - m_totalStackSize = 0; + m_totalStackSize = argIt.SizeOfArgStack(); #if LOG_COMPUTE_CALL_STUB printf("ComputeCallStub\n"); #endif @@ -1527,7 +1527,6 @@ void CallStubGenerator::ComputeCallStub(MetaSig &sig, PCODE *pRoutines) } else if (m_s1 != NoRange) { - m_totalStackSize += m_s2 - m_s1 + 1; pRoutines[m_routineIndex++] = GetStackRoutine(); pRoutines[m_routineIndex++] = ((int64_t)(m_s2 - m_s1 + 1) << 32) | m_s1; } @@ -1571,7 +1570,6 @@ void CallStubGenerator::ProcessArgument(ArgIterator *pArgIt, ArgLocDesc& argLocD { // No stack argument is used to pass the current argument, but we already have a range of stack arguments, // store the routine for the range - m_totalStackSize += m_s2 - m_s1 + 1; pRoutines[m_routineIndex++] = GetStackRoutine(); pRoutines[m_routineIndex++] = ((int64_t)(m_s2 - m_s1 + 1) << 32) | m_s1; m_s1 = NoRange; @@ -1650,7 +1648,6 @@ void CallStubGenerator::ProcessArgument(ArgIterator *pArgIt, ArgLocDesc& argLocD else { // Discontinuous range - store a routine for the current and start a new one - m_totalStackSize += m_s2 - m_s1 + 1; pRoutines[m_routineIndex++] = GetStackRoutine(); pRoutines[m_routineIndex++] = ((int64_t)(m_s2 - m_s1 + 1) << 32) | m_s1; m_s1 = argLocDesc.m_byteStackIndex; @@ -1699,7 +1696,6 @@ void CallStubGenerator::ProcessArgument(ArgIterator *pArgIt, ArgLocDesc& argLocD _ASSERTE(argLocDesc.m_byteStackIndex != -1); pRoutines[m_routineIndex++] = GetStackRefRoutine(); pRoutines[m_routineIndex++] = ((int64_t)pArgIt->GetArgSize() << 32) | argLocDesc.m_byteStackIndex; - m_totalStackSize += argLocDesc.m_byteStackSize; m_s1 = NoRange; } } diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index 3419a19710d3b3..881b58c4c3a469 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -1721,8 +1721,8 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_S: { - HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod, ip[2]); - void* helperArg = LOCAL_VAR(ip[3], void*); + HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); + void* helperArg = LOCAL_VAR(ip[2], void*); LOCAL_VAR(ip[1], void*) = helperFtn(helperArg); ip += 4;