Fix setup of RD when dispatching to function headers after exit.

This commit is contained in:
Mike Pall 2010-04-09 14:26:18 +02:00
parent db756430ee
commit fbe092c22d
7 changed files with 1822 additions and 1805 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2668,16 +2668,30 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse)
| mov r13, TMPa | mov r13, TMPa
| mov r12, TMPQ | mov r12, TMPQ
|.endif |.endif
| test RD, RD; js >2 // Check for error from exit. | test RD, RD; js >3 // Check for error from exit.
| mov MULTRES, RD | mov MULTRES, RD
| mov LFUNC:KBASE, [BASE-8] | mov LFUNC:KBASE, [BASE-8]
| mov KBASE, LFUNC:KBASE->pc | mov KBASE, LFUNC:KBASE->pc
| mov KBASE, [KBASE+PC2PROTO(k)] | mov KBASE, [KBASE+PC2PROTO(k)]
| mov dword [DISPATCH+DISPATCH_GL(jit_L)], 0 | mov dword [DISPATCH+DISPATCH_GL(jit_L)], 0
| set_vmstate INTERP | set_vmstate INTERP
| ins_next | // Modified copy of ins_next which handles function header dispatch, too.
| mov RC, [PC]
| movzx RA, RCH
| movzx OP, RCL
| add PC, 4
| shr RC, 16
| cmp OP, BC_FUNCF // Function header?
| jb >2
| mov RC, MULTRES // RC/RD holds nres+1.
|2:
|.if X64
| jmp aword [DISPATCH+OP*8]
|.else
| jmp aword [DISPATCH+OP*4]
|.endif
| |
|2: // Rethrow error from the right C frame. |3: // Rethrow error from the right C frame.
| neg RD | neg RD
| mov FCARG1, L:RB | mov FCARG1, L:RB
| mov FCARG2, RD | mov FCARG2, RD

File diff suppressed because it is too large Load Diff

View File

@ -3280,12 +3280,13 @@ static void asm_tail_link(ASMState *as)
} }
emit_loada(as, RID_DISPATCH, J2GG(as->J)->dispatch); emit_loada(as, RID_DISPATCH, J2GG(as->J)->dispatch);
emit_loada(as, RID_PC, pc); emit_loada(as, RID_PC, pc);
mres = (int32_t)(snap->nslots - baseslot - bc_a(*pc)); mres = (int32_t)(snap->nslots - baseslot);
switch (bc_op(*pc)) { switch (bc_op(*pc)) {
case BC_CALLM: case BC_CALLMT: mres -= (int32_t)(1 + bc_c(*pc)); break; case BC_CALLM: case BC_CALLMT:
case BC_RETM: mres -= (int32_t)bc_d(*pc); break; mres -= (int32_t)(1 + bc_a(*pc) + bc_c(*pc)); break;
case BC_TSETM: break; case BC_RETM: mres -= (int32_t)(bc_a(*pc) + bc_d(*pc)); break;
default: mres = 0; break; case BC_TSETM: mres -= (int32_t)bc_a(*pc); break;
default: if (bc_op(*pc) < BC_FUNCF) mres = 0; break;
} }
emit_loadi(as, RID_RET, mres); /* Return MULTRES or 0. */ emit_loadi(as, RID_RET, mres); /* Return MULTRES or 0. */
} else if (baseslot) { } else if (baseslot) {

View File

@ -254,16 +254,13 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
GCfunc *fn = ir_kfunc(ir); GCfunc *fn = ir_kfunc(ir);
if (isluafunc(fn)) { if (isluafunc(fn)) {
MSize framesize = funcproto(fn)->framesize; MSize framesize = funcproto(fn)->framesize;
TValue *fs;
L->base = ++o; L->base = ++o;
if (LJ_UNLIKELY(o + framesize > L->maxstack)) { /* Grow again? */ if (LJ_UNLIKELY(o + framesize > L->maxstack)) { /* Grow again? */
ptrdiff_t fsave = savestack(L, frame); ptrdiff_t fsave = savestack(L, frame);
L->top = o; L->top = o;
lj_state_growstack(L, framesize); lj_state_growstack(L, framesize);
frame = restorestack(L, fsave); frame = restorestack(L, fsave);
o = L->top;
} }
fs = o + framesize;
} }
} }
} }

View File

@ -716,6 +716,8 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr)
case BC_TSETM: case BC_TSETM:
return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc)); return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc));
default: default:
if (bc_op(*pc) >= BC_FUNCF)
return (int)((BCReg)(L->top - L->base) + 1);
return 0; return 0;
} }
} }