Check for upvalue state transition in IR_UREFO.
Thanks to Peter Cawley. #1085
This commit is contained in:
@@ -1207,22 +1207,29 @@ nolo:
|
||||
static void asm_uref(ASMState *as, IRIns *ir)
|
||||
{
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
if (irref_isk(ir->op1)) {
|
||||
int guarded = (irt_t(ir->t) & (IRT_GUARD|IRT_TYPE)) == (IRT_GUARD|IRT_PGC);
|
||||
if (irref_isk(ir->op1) && !guarded) {
|
||||
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
||||
MRef *v = &gcref(fn->l.uvptr[(ir->op2 >> 8)])->uv.v;
|
||||
emit_lsptr(as, MIPSI_AL, dest, v, RSET_GPR);
|
||||
} else {
|
||||
Reg uv = ra_scratch(as, RSET_GPR);
|
||||
Reg func = ra_alloc1(as, ir->op1, RSET_GPR);
|
||||
if (ir->o == IR_UREFC) {
|
||||
asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO);
|
||||
emit_tsi(as, MIPSI_AADDIU, dest, uv, (int32_t)offsetof(GCupval, tv));
|
||||
emit_tsi(as, MIPSI_LBU, RID_TMP, uv, (int32_t)offsetof(GCupval, closed));
|
||||
if (guarded)
|
||||
asm_guard(as, ir->o == IR_UREFC ? MIPSI_BEQ : MIPSI_BNE, RID_TMP, RID_ZERO);
|
||||
if (ir->o == IR_UREFC)
|
||||
emit_tsi(as, MIPSI_AADDIU, dest, dest, (int32_t)offsetof(GCupval, tv));
|
||||
else
|
||||
emit_tsi(as, MIPSI_AL, dest, dest, (int32_t)offsetof(GCupval, v));
|
||||
if (guarded)
|
||||
emit_tsi(as, MIPSI_LBU, RID_TMP, dest, (int32_t)offsetof(GCupval, closed));
|
||||
if (irref_isk(ir->op1)) {
|
||||
GCfunc *fn = ir_kfunc(IR(ir->op1));
|
||||
GCobj *o = gcref(fn->l.uvptr[(ir->op2 >> 8)]);
|
||||
emit_loada(as, dest, o);
|
||||
} else {
|
||||
emit_tsi(as, MIPSI_AL, dest, uv, (int32_t)offsetof(GCupval, v));
|
||||
emit_tsi(as, MIPSI_AL, dest, ra_alloc1(as, ir->op1, RSET_GPR),
|
||||
(int32_t)offsetof(GCfuncL, uvptr) +
|
||||
(int32_t)sizeof(MRef) * (int32_t)(ir->op2 >> 8));
|
||||
}
|
||||
emit_tsi(as, MIPSI_AL, uv, func, (int32_t)offsetof(GCfuncL, uvptr) +
|
||||
(int32_t)sizeof(MRef) * (int32_t)(ir->op2 >> 8));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user