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 r12, TMPQ
|.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 LFUNC:KBASE, [BASE-8]
| mov KBASE, LFUNC:KBASE->pc
| mov KBASE, [KBASE+PC2PROTO(k)]
| mov dword [DISPATCH+DISPATCH_GL(jit_L)], 0
| 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
| mov FCARG1, L:RB
| 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_PC, pc);
mres = (int32_t)(snap->nslots - baseslot - bc_a(*pc));
mres = (int32_t)(snap->nslots - baseslot);
switch (bc_op(*pc)) {
case BC_CALLM: case BC_CALLMT: mres -= (int32_t)(1 + bc_c(*pc)); break;
case BC_RETM: mres -= (int32_t)bc_d(*pc); break;
case BC_TSETM: break;
default: mres = 0; break;
case BC_CALLM: case BC_CALLMT:
mres -= (int32_t)(1 + bc_a(*pc) + bc_c(*pc)); break;
case BC_RETM: mres -= (int32_t)(bc_a(*pc) + bc_d(*pc)); 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. */
} else if (baseslot) {

View File

@ -254,16 +254,13 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
GCfunc *fn = ir_kfunc(ir);
if (isluafunc(fn)) {
MSize framesize = funcproto(fn)->framesize;
TValue *fs;
L->base = ++o;
if (LJ_UNLIKELY(o + framesize > L->maxstack)) { /* Grow again? */
ptrdiff_t fsave = savestack(L, frame);
L->top = o;
lj_state_growstack(L, framesize);
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:
return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc));
default:
if (bc_op(*pc) >= BC_FUNCF)
return (int)((BCReg)(L->top - L->base) + 1);
return 0;
}
}