Skip to content

Commit 3650ff3

Browse files
authored
Fix interpreter jmp to pinvoke (#121329)
The interpreter compiler ignores tail call prefix for tail calls (and jmp) to pinvokes that are not marshalled. But it is not injecting "ret" IR opcode after the call returns, which results in BADCODE reported by the compiler. There are several coreclr tests in the JIT/jit64/mcc/interop that fail due to that. This change adds injecting proper form of "ret" IR opcode after such calls.
1 parent 5075f72 commit 3650ff3

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

src/coreclr/interpreter/compiler.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4183,6 +4183,7 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
41834183
int32_t newObjDVar = -1;
41844184
InterpType ctorType = InterpTypeO;
41854185
int32_t vtsize = 0;
4186+
bool injectRet = false;
41864187

41874188
if (newObjThisArgLocation != INT_MAX)
41884189
{
@@ -4393,7 +4394,11 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
43934394
{
43944395
// Tail call target needs to be IL
43954396
if (tailcall && isPInvoke && !isMarshaledPInvoke)
4397+
{
43964398
tailcall = false;
4399+
// We need to inject ret after a jmp when we can't use a tail call
4400+
injectRet = isJmp;
4401+
}
43974402

43984403
// Normal call
43994404
InterpOpcode opcode;
@@ -4530,6 +4535,28 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re
45304535
m_pLastNewIns->info.pCallInfo = (InterpCallInfo*)AllocMemPool0(sizeof (InterpCallInfo));
45314536
m_pLastNewIns->info.pCallInfo->pCallArgs = callArgs;
45324537

4538+
if (injectRet)
4539+
{
4540+
// Jmp to PInvoke was converted to normal pinvoke, so we need to inject a ret after the call
4541+
switch (GetInterpType(callInfo.sig.retType))
4542+
{
4543+
case InterpTypeVT:
4544+
{
4545+
AddIns(INTOP_RET_VT);
4546+
m_pLastNewIns->SetSVar(dVar);
4547+
m_pLastNewIns->data[0] = m_pVars[dVar].size;
4548+
break;
4549+
}
4550+
case InterpTypeVoid:
4551+
AddIns(INTOP_RET_VOID);
4552+
break;
4553+
default:
4554+
AddIns(INTOP_RET);
4555+
m_pLastNewIns->SetSVar(dVar);
4556+
break;
4557+
}
4558+
}
4559+
45334560
m_ip += 5;
45344561
}
45354562

0 commit comments

Comments
 (0)