Merge 21707b9637 into 93e87998b2
This commit is contained in:
commit
fff6858a8f
@ -238,6 +238,7 @@ static void LJ_FASTCALL recff_getmetatable(jit_State *J, RecordFFData *rd)
|
|||||||
RecordIndex ix;
|
RecordIndex ix;
|
||||||
ix.tab = tr;
|
ix.tab = tr;
|
||||||
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
||||||
|
ix.mtspec = 0;
|
||||||
if (lj_record_mm_lookup(J, &ix, MM_metatable))
|
if (lj_record_mm_lookup(J, &ix, MM_metatable))
|
||||||
J->base[0] = ix.mobj;
|
J->base[0] = ix.mobj;
|
||||||
else
|
else
|
||||||
@ -254,6 +255,7 @@ static void LJ_FASTCALL recff_setmetatable(jit_State *J, RecordFFData *rd)
|
|||||||
RecordIndex ix;
|
RecordIndex ix;
|
||||||
ix.tab = tr;
|
ix.tab = tr;
|
||||||
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
||||||
|
ix.mtspec = 0;
|
||||||
lj_record_mm_lookup(J, &ix, MM_metatable); /* Guard for no __metatable. */
|
lj_record_mm_lookup(J, &ix, MM_metatable); /* Guard for no __metatable. */
|
||||||
fref = emitir(IRT(IR_FREF, IRT_PGC), tr, IRFL_TAB_META);
|
fref = emitir(IRT(IR_FREF, IRT_PGC), tr, IRFL_TAB_META);
|
||||||
mtref = tref_isnil(mt) ? lj_ir_knull(J, IRT_TAB) : mt;
|
mtref = tref_isnil(mt) ? lj_ir_knull(J, IRT_TAB) : mt;
|
||||||
@ -402,6 +404,7 @@ static int recff_metacall(jit_State *J, RecordFFData *rd, MMS mm)
|
|||||||
RecordIndex ix;
|
RecordIndex ix;
|
||||||
ix.tab = J->base[0];
|
ix.tab = J->base[0];
|
||||||
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
copyTV(J->L, &ix.tabv, &rd->argv[0]);
|
||||||
|
ix.mtspec = 1;
|
||||||
if (lj_record_mm_lookup(J, &ix, mm)) { /* Has metamethod? */
|
if (lj_record_mm_lookup(J, &ix, mm)) { /* Has metamethod? */
|
||||||
int errcode;
|
int errcode;
|
||||||
TValue argv0;
|
TValue argv0;
|
||||||
@ -561,6 +564,7 @@ static void LJ_FASTCALL recff_next(jit_State *J, RecordFFData *rd)
|
|||||||
ix.idxchain = (J->framedepth && frame_islua(J->L->base-1) &&
|
ix.idxchain = (J->framedepth && frame_islua(J->L->base-1) &&
|
||||||
bc_b(frame_pc(J->L->base-1)[-1])-1 < 2);
|
bc_b(frame_pc(J->L->base-1)[-1])-1 < 2);
|
||||||
ix.mobj = 0; /* We don't need the next index. */
|
ix.mobj = 0; /* We don't need the next index. */
|
||||||
|
ix.mtspec = 0;
|
||||||
rd->nres = lj_record_next(J, &ix);
|
rd->nres = lj_record_next(J, &ix);
|
||||||
J->base[0] = ix.key;
|
J->base[0] = ix.key;
|
||||||
J->base[1] = ix.val;
|
J->base[1] = ix.val;
|
||||||
|
|||||||
@ -687,6 +687,7 @@ static LoopEvent rec_itern(jit_State *J, BCReg ra, BCReg rb)
|
|||||||
copyTV(J->L, &ix.keyv, &J->L->base[ra-1]);
|
copyTV(J->L, &ix.keyv, &J->L->base[ra-1]);
|
||||||
ix.idxchain = (rb < 3); /* Omit value type check, if unused. */
|
ix.idxchain = (rb < 3); /* Omit value type check, if unused. */
|
||||||
ix.mobj = 1; /* We need the next index, too. */
|
ix.mobj = 1; /* We need the next index, too. */
|
||||||
|
ix.mtspec = 0;
|
||||||
J->maxslot = ra + lj_record_next(J, &ix);
|
J->maxslot = ra + lj_record_next(J, &ix);
|
||||||
J->needsnap = 1;
|
J->needsnap = 1;
|
||||||
if (!tref_isnil(ix.key)) { /* Looping back? */
|
if (!tref_isnil(ix.key)) { /* Looping back? */
|
||||||
@ -819,6 +820,7 @@ static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs)
|
|||||||
if (!tref_isfunc(fbase[0])) { /* Resolve __call metamethod. */
|
if (!tref_isfunc(fbase[0])) { /* Resolve __call metamethod. */
|
||||||
ix.tab = fbase[0];
|
ix.tab = fbase[0];
|
||||||
copyTV(J->L, &ix.tabv, functv);
|
copyTV(J->L, &ix.tabv, functv);
|
||||||
|
ix.mtspec = 1;
|
||||||
if (!lj_record_mm_lookup(J, &ix, MM_call) || !tref_isfunc(ix.mobj))
|
if (!lj_record_mm_lookup(J, &ix, MM_call) || !tref_isfunc(ix.mobj))
|
||||||
lj_trace_err(J, LJ_TRERR_NOMM);
|
lj_trace_err(J, LJ_TRERR_NOMM);
|
||||||
for (i = ++nargs; i > LJ_FR2; i--) /* Shift arguments up. */
|
for (i = ++nargs; i > LJ_FR2; i--) /* Shift arguments up. */
|
||||||
@ -1110,8 +1112,15 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
|
|||||||
GG_OFS(g.gcroot[GCROOT_BASEMT+itypemap(&ix->tabv)]));
|
GG_OFS(g.gcroot[GCROOT_BASEMT+itypemap(&ix->tabv)]));
|
||||||
goto nocheck;
|
goto nocheck;
|
||||||
}
|
}
|
||||||
ix->mt = mt ? mix.tab : TREF_NIL;
|
if (ix->mtspec && mt) {
|
||||||
emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB));
|
TRef kmt = lj_ir_ktab(J, mt);
|
||||||
|
emitir(IRTG(IR_EQ, IRT_TAB), mix.tab, kmt);
|
||||||
|
mix.tab = kmt;
|
||||||
|
ix->mt = kmt;
|
||||||
|
} else {
|
||||||
|
ix->mt = mt ? mix.tab : TREF_NIL;
|
||||||
|
emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB));
|
||||||
|
}
|
||||||
nocheck:
|
nocheck:
|
||||||
if (mt) {
|
if (mt) {
|
||||||
GCstr *mmstr = mmname_str(J2G(J), mm);
|
GCstr *mmstr = mmname_str(J2G(J), mm);
|
||||||
@ -1165,6 +1174,7 @@ static TRef rec_mm_len(jit_State *J, TRef tr, TValue *tv)
|
|||||||
RecordIndex ix;
|
RecordIndex ix;
|
||||||
ix.tab = tr;
|
ix.tab = tr;
|
||||||
copyTV(J->L, &ix.tabv, tv);
|
copyTV(J->L, &ix.tabv, tv);
|
||||||
|
ix.mtspec = 1;
|
||||||
if (lj_record_mm_lookup(J, &ix, MM_len)) {
|
if (lj_record_mm_lookup(J, &ix, MM_len)) {
|
||||||
BCReg func = rec_mm_prep(J, lj_cont_ra);
|
BCReg func = rec_mm_prep(J, lj_cont_ra);
|
||||||
TRef *base = J->base + func;
|
TRef *base = J->base + func;
|
||||||
@ -2116,6 +2126,7 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
|||||||
ix.tab = top[-1];
|
ix.tab = top[-1];
|
||||||
ix.key = top[0];
|
ix.key = top[0];
|
||||||
memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv)); /* Save slots. */
|
memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv)); /* Save slots. */
|
||||||
|
ix.mtspec = 1;
|
||||||
rec_mm_arith(J, &ix, MM_concat); /* Call __concat metamethod. */
|
rec_mm_arith(J, &ix, MM_concat); /* Call __concat metamethod. */
|
||||||
memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
|
memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
|
||||||
return 0; /* No result yet. */
|
return 0; /* No result yet. */
|
||||||
@ -2320,6 +2331,7 @@ void lj_record_ins(jit_State *J)
|
|||||||
rc = lj_ir_kint(J, 0);
|
rc = lj_ir_kint(J, 0);
|
||||||
ta = IRT_INT;
|
ta = IRT_INT;
|
||||||
} else {
|
} else {
|
||||||
|
ix.mtspec = 1;
|
||||||
rec_mm_comp(J, &ix, (int)op);
|
rec_mm_comp(J, &ix, (int)op);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2343,10 +2355,12 @@ void lj_record_ins(jit_State *J)
|
|||||||
int diff;
|
int diff;
|
||||||
rec_comp_prep(J);
|
rec_comp_prep(J);
|
||||||
diff = lj_record_objcmp(J, ra, rc, rav, rcv);
|
diff = lj_record_objcmp(J, ra, rc, rav, rcv);
|
||||||
if (diff == 2 || !(tref_istab(ra) || tref_isudata(ra)))
|
if (diff == 2 || !(tref_istab(ra) || tref_isudata(ra))) {
|
||||||
rec_comp_fixup(J, J->pc, ((int)op & 1) == !diff);
|
rec_comp_fixup(J, J->pc, ((int)op & 1) == !diff);
|
||||||
else if (diff == 1) /* Only check __eq if different, but same type. */
|
} else if (diff == 1) { /* Only check __eq if different, but same type. */
|
||||||
|
ix.mtspec = 1;
|
||||||
rec_mm_equal(J, &ix, (int)op);
|
rec_mm_equal(J, &ix, (int)op);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2397,6 +2411,7 @@ void lj_record_ins(jit_State *J)
|
|||||||
} else {
|
} else {
|
||||||
ix.tab = rc;
|
ix.tab = rc;
|
||||||
copyTV(J->L, &ix.tabv, rcv);
|
copyTV(J->L, &ix.tabv, rcv);
|
||||||
|
ix.mtspec = 1;
|
||||||
rc = rec_mm_arith(J, &ix, MM_unm);
|
rc = rec_mm_arith(J, &ix, MM_unm);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2413,27 +2428,33 @@ void lj_record_ins(jit_State *J)
|
|||||||
case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN:
|
case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN:
|
||||||
case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: {
|
case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: {
|
||||||
MMS mm = bcmode_mm(op);
|
MMS mm = bcmode_mm(op);
|
||||||
if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
|
if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) {
|
||||||
rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv,
|
rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv,
|
||||||
(int)mm - (int)MM_add + (int)IR_ADD);
|
(int)mm - (int)MM_add + (int)IR_ADD);
|
||||||
else
|
} else {
|
||||||
|
ix.mtspec = 1;
|
||||||
rc = rec_mm_arith(J, &ix, mm);
|
rc = rec_mm_arith(J, &ix, mm);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BC_MODVN: case BC_MODVV:
|
case BC_MODVN: case BC_MODVV:
|
||||||
recmod:
|
recmod:
|
||||||
if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
|
if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) {
|
||||||
rc = lj_opt_narrow_mod(J, rb, rc, rbv, rcv);
|
rc = lj_opt_narrow_mod(J, rb, rc, rbv, rcv);
|
||||||
else
|
} else {
|
||||||
|
ix.mtspec = 1;
|
||||||
rc = rec_mm_arith(J, &ix, MM_mod);
|
rc = rec_mm_arith(J, &ix, MM_mod);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BC_POW:
|
case BC_POW:
|
||||||
if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
|
if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) {
|
||||||
rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv, IR_POW);
|
rc = lj_opt_narrow_arith(J, rb, rc, rbv, rcv, IR_POW);
|
||||||
else
|
} else {
|
||||||
|
ix.mtspec = 1;
|
||||||
rc = rec_mm_arith(J, &ix, MM_pow);
|
rc = rec_mm_arith(J, &ix, MM_pow);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* -- Miscellaneous ops ------------------------------------------------- */
|
/* -- Miscellaneous ops ------------------------------------------------- */
|
||||||
@ -2487,6 +2508,7 @@ void lj_record_ins(jit_State *J)
|
|||||||
settabV(J->L, &ix.tabv, tabref(J->fn->l.env));
|
settabV(J->L, &ix.tabv, tabref(J->fn->l.env));
|
||||||
ix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), getcurrf(J), IRFL_FUNC_ENV);
|
ix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), getcurrf(J), IRFL_FUNC_ENV);
|
||||||
ix.idxchain = LJ_MAX_IDXCHAIN;
|
ix.idxchain = LJ_MAX_IDXCHAIN;
|
||||||
|
ix.mtspec = 0;
|
||||||
rc = lj_record_idx(J, &ix);
|
rc = lj_record_idx(J, &ix);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2496,6 +2518,7 @@ void lj_record_ins(jit_State *J)
|
|||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case BC_TGETV: case BC_TGETS: case BC_TSETV: case BC_TSETS:
|
case BC_TGETV: case BC_TGETS: case BC_TSETV: case BC_TSETS:
|
||||||
ix.idxchain = LJ_MAX_IDXCHAIN;
|
ix.idxchain = LJ_MAX_IDXCHAIN;
|
||||||
|
ix.mtspec = tref_isk(ix.key) && tref_isstr(ix.key);
|
||||||
rc = lj_record_idx(J, &ix);
|
rc = lj_record_idx(J, &ix);
|
||||||
break;
|
break;
|
||||||
case BC_TGETR: case BC_TSETR:
|
case BC_TGETR: case BC_TSETR:
|
||||||
|
|||||||
@ -23,7 +23,8 @@ typedef struct RecordIndex {
|
|||||||
TRef val; /* Value reference for a store or 0 for a load. */
|
TRef val; /* Value reference for a store or 0 for a load. */
|
||||||
TRef mt; /* Metatable reference. */
|
TRef mt; /* Metatable reference. */
|
||||||
TRef mobj; /* Metamethod object reference. */
|
TRef mobj; /* Metamethod object reference. */
|
||||||
int idxchain; /* Index indirections left or 0 for raw lookup. */
|
short idxchain; /* Index indirections left or 0 for raw lookup. */
|
||||||
|
short mtspec; /* Specialize to metatable. */
|
||||||
} RecordIndex;
|
} RecordIndex;
|
||||||
|
|
||||||
LJ_FUNC int lj_record_objcmp(jit_State *J, TRef a, TRef b,
|
LJ_FUNC int lj_record_objcmp(jit_State *J, TRef a, TRef b,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user