From f1318d3c8add216b7e381d43e9b647c0b5701579 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 15 Jul 2025 16:33:57 +0200 Subject: [PATCH] Fix interpreter passing managed "this" in presence of return buffer The CallStubGenerator is using the native x64 Windows calling convention for the case when both "this" and "return buffer" arguments are passed to native callees. However, the CLR ABI diverges from this convention. While the native one passes the return buffer first and the this pointer second, the CLR ABI always passes the "this" pointer first. This fixes a number of failures on the runtime startup path when running interpreted. --- src/coreclr/vm/callstubgenerator.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/coreclr/vm/callstubgenerator.cpp b/src/coreclr/vm/callstubgenerator.cpp index bfc3931e0e0474..19b94af4766fb0 100644 --- a/src/coreclr/vm/callstubgenerator.cpp +++ b/src/coreclr/vm/callstubgenerator.cpp @@ -1417,23 +1417,8 @@ void CallStubGenerator::ComputeCallStub(MetaSig &sig, PCODE *pRoutines) #endif // The "this" argument register is not enumerated by the arg iterator, so // we need to "inject" it here. -#if defined(TARGET_WINDOWS) && defined(TARGET_AMD64) - if (argIt.HasRetBuffArg()) - { -#if LOG_COMPUTE_CALL_STUB - printf("argIt.HasRetBuffArg() on WINDOWS AMD64\n"); -#endif - // The return buffer on Windows AMD64 is passed in the first argument register, so the - // "this" argument is be passed in the second argument register. - m_r1 = 1; - m_r2 = 1; - } - else -#endif // TARGET_WINDOWS && TARGET_AMD64 - { - // The "this" pointer is passed in the first argument register. - m_r1 = 0; - } + // CLR ABI specifies that unlike the native Windows x64 calling convention, it is passed in the first argument register. + m_r1 = 0; } if (argIt.HasParamType())