diff options
author | Mike Pall <mike> | 2011-12-01 16:27:24 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-12-01 16:27:24 +0100 |
commit | e162d8cef0d1d62e3c43c23a6b28ebed68fdf7a0 (patch) | |
tree | 5cc53810465344b93638ddcb8ff65ca2da107cbf /src | |
parent | ff7e9bc464878994714346ac9efae4e87b065076 (diff) | |
download | luajit-e162d8cef0d1d62e3c43c23a6b28ebed68fdf7a0.tar.gz luajit-e162d8cef0d1d62e3c43c23a6b28ebed68fdf7a0.tar.bz2 luajit-e162d8cef0d1d62e3c43c23a6b28ebed68fdf7a0.zip |
FFI: Fix stack adjustment for calls to stdcall/fastcall functions.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_asm_x86.h | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index 4d47e389..0eca5d5c 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
@@ -593,13 +593,14 @@ static void asm_callx(ASMState *as, IRIns *ir) | |||
593 | CCallInfo ci; | 593 | CCallInfo ci; |
594 | IRRef func; | 594 | IRRef func; |
595 | IRIns *irf; | 595 | IRIns *irf; |
596 | int32_t spadj = 0; | ||
596 | ci.flags = asm_callx_flags(as, ir); | 597 | ci.flags = asm_callx_flags(as, ir); |
597 | asm_collectargs(as, ir, &ci, args); | 598 | asm_collectargs(as, ir, &ci, args); |
598 | asm_setupresult(as, ir, &ci); | 599 | asm_setupresult(as, ir, &ci); |
599 | #if LJ_32 | 600 | #if LJ_32 |
600 | /* Have to readjust stack after non-cdecl calls due to callee cleanup. */ | 601 | /* Have to readjust stack after non-cdecl calls due to callee cleanup. */ |
601 | if ((ci.flags & CCI_CC_MASK) != CCI_CC_CDECL) | 602 | if ((ci.flags & CCI_CC_MASK) != CCI_CC_CDECL) |
602 | emit_spsub(as, 4 * asm_count_call_slots(as, &ci, args)); | 603 | spadj = 4 * asm_count_call_slots(as, &ci, args); |
603 | #endif | 604 | #endif |
604 | func = ir->op2; irf = IR(func); | 605 | func = ir->op2; irf = IR(func); |
605 | if (irf->o == IR_CARG) { func = irf->op1; irf = IR(func); } | 606 | if (irf->o == IR_CARG) { func = irf->op1; irf = IR(func); } |
@@ -608,7 +609,10 @@ static void asm_callx(ASMState *as, IRIns *ir) | |||
608 | /* Use a (hoistable) non-scratch register for indirect calls. */ | 609 | /* Use a (hoistable) non-scratch register for indirect calls. */ |
609 | RegSet allow = (RSET_GPR & ~RSET_SCRATCH); | 610 | RegSet allow = (RSET_GPR & ~RSET_SCRATCH); |
610 | Reg r = ra_alloc1(as, func, allow); | 611 | Reg r = ra_alloc1(as, func, allow); |
612 | if (LJ_32) emit_spsub(as, spadj); /* Above code may cause restores! */ | ||
611 | emit_rr(as, XO_GROUP5, XOg_CALL, r); | 613 | emit_rr(as, XO_GROUP5, XOg_CALL, r); |
614 | } else if (LJ_32) { | ||
615 | emit_spsub(as, spadj); | ||
612 | } | 616 | } |
613 | asm_gencall(as, &ci, args); | 617 | asm_gencall(as, &ci, args); |
614 | } | 618 | } |