#else // !TARGET_X86
// In case of helper dispatched tail calls, "thisptr" will be the third arg.
// The first two args are: real call target and addr of args copy routine.
- const unsigned argNum = 2;
+ const unsigned argNum = 2;
#endif // !TARGET_X86
fgArgTabEntry* thisArgTabEntry = comp->gtArgEntryByArgNum(call, argNum);
#if defined(TARGET_X86) || defined(TARGET_ARM)
GenTreeCall::Use* argList = comp->gtNewCallArgs(frameAddr);
#else
- GenTreeCall::Use* argList = comp->gtNewCallArgs(frameAddr, PhysReg(REG_SECRET_STUB_PARAM));
+ GenTreeCall::Use* argList = comp->gtNewCallArgs(frameAddr, PhysReg(REG_SECRET_STUB_PARAM));
#endif
GenTree* call = comp->gtNewHelperCallNode(CORINFO_HELP_INIT_PINVOKE_FRAME, TYP_I_IMPL, argList);
GenTree* frameAddr =
new (comp, GT_LCL_VAR_ADDR) GenTreeLclVar(GT_LCL_VAR_ADDR, TYP_BYREF, comp->lvaInlinedPInvokeFrameVar);
+#if defined(TARGET_X86) && !defined(UNIX_X86_ABI)
+ // On x86 targets, PInvoke calls need the size of the stack args in InlinedCallFrame.m_Datum.
+ // This is because the callee pops stack arguments, and we need to keep track of this during stack
+ // walking
+ const unsigned numStkArgBytes = call->fgArgInfo->GetNextSlotNum() * TARGET_POINTER_SIZE;
+ GenTree* stackBytes = comp->gtNewIconNode(numStkArgBytes, TYP_INT);
+ GenTreeCall::Use* args = comp->gtNewCallArgs(frameAddr, stackBytes);
+#else
+ GenTreeCall::Use* args = comp->gtNewCallArgs(frameAddr);
+#endif
// Insert call to CORINFO_HELP_JIT_PINVOKE_BEGIN
- GenTree* helperCall =
- comp->gtNewHelperCallNode(CORINFO_HELP_JIT_PINVOKE_BEGIN, TYP_VOID, comp->gtNewCallArgs(frameAddr));
+ GenTree* helperCall = comp->gtNewHelperCallNode(CORINFO_HELP_JIT_PINVOKE_BEGIN, TYP_VOID, args);
comp->fgMorphTree(helperCall);
BlockRange().InsertBefore(insertBefore, LIR::SeqTree(comp, helperCall));
;
; in:
-; InlinedCallFrame (ecx) = pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right
-; before actual InlinedCallFrame data)
-;
+; InlinedCallFrame (ecx) = pointer to the InlinedCallFrame data, including the GS cookie slot (GS cookie right
+; before actual InlinedCallFrame data)
+; StackArgumentsSize (edx) = Number of argument bytes pushed on the stack, which will be popped by the callee
;
_JIT_PInvokeBegin@4 PROC public
lea eax,[??_7InlinedCallFrame@@6B@]
mov dword ptr [ecx], eax
- mov dword ptr [ecx + InlinedCallFrame__m_Datum], 0
+ mov dword ptr [ecx + InlinedCallFrame__m_Datum], edx
mov eax, esp
return;
}
- DWORD stackArgSize = (DWORD) dac_cast<TADDR>(m_Datum);
+ DWORD stackArgSize = 0;
+
+#if !defined(UNIX_X86_ABI)
+ stackArgSize = (DWORD) dac_cast<TADDR>(m_Datum);
if (stackArgSize & ~0xFFFF)
{
stackArgSize = pMD->GetStackArgumentSize();
}
+#endif
/* The return address is just above the "ESP" */
pRD->PCTAddr = PTR_HOST_MEMBER_TADDR(InlinedCallFrame, this,