diff options
Diffstat (limited to 'src/lj_record.c')
-rw-r--r-- | src/lj_record.c | 70 |
1 files changed, 62 insertions, 8 deletions
diff --git a/src/lj_record.c b/src/lj_record.c index e101ba23..68a233b9 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
@@ -168,8 +168,8 @@ static int rec_objcmp(jit_State *J, TRef a, TRef b, cTValue *av, cTValue *bv) | |||
168 | { | 168 | { |
169 | int diff = !lj_obj_equal(av, bv); | 169 | int diff = !lj_obj_equal(av, bv); |
170 | if (!tref_isk2(a, b)) { /* Shortcut, also handles primitives. */ | 170 | if (!tref_isk2(a, b)) { /* Shortcut, also handles primitives. */ |
171 | IRType ta = tref_type(a); | 171 | IRType ta = tref_isinteger(a) ? IRT_INT : tref_type(a); |
172 | IRType tb = tref_type(b); | 172 | IRType tb = tref_isinteger(b) ? IRT_INT : tref_type(b); |
173 | if (ta != tb) { | 173 | if (ta != tb) { |
174 | /* Widen mixed number/int comparisons to number/number comparison. */ | 174 | /* Widen mixed number/int comparisons to number/number comparison. */ |
175 | if (ta == IRT_INT && tb == IRT_NUM) { | 175 | if (ta == IRT_INT && tb == IRT_NUM) { |
@@ -447,7 +447,7 @@ static int rec_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm) | |||
447 | mix.tab = lj_ir_ktab(J, mt); | 447 | mix.tab = lj_ir_ktab(J, mt); |
448 | goto nocheck; | 448 | goto nocheck; |
449 | } | 449 | } |
450 | ix->mt = mix.tab; | 450 | ix->mt = mt ? mix.tab : TREF_NIL; |
451 | emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB)); | 451 | emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB)); |
452 | nocheck: | 452 | nocheck: |
453 | if (mt) { | 453 | if (mt) { |
@@ -457,6 +457,8 @@ nocheck: | |||
457 | copyTV(J->L, &ix->mobjv, mo); | 457 | copyTV(J->L, &ix->mobjv, mo); |
458 | ix->mtv = mt; | 458 | ix->mtv = mt; |
459 | settabV(J->L, &mix.tabv, mt); | 459 | settabV(J->L, &mix.tabv, mt); |
460 | if (isdead(J2G(J), obj2gco(mmstr))) | ||
461 | flipwhite(obj2gco(mmstr)); /* Need same logic as lj_str_new(). */ | ||
460 | setstrV(J->L, &mix.keyv, mmstr); | 462 | setstrV(J->L, &mix.keyv, mmstr); |
461 | mix.key = lj_ir_kstr(J, mmstr); | 463 | mix.key = lj_ir_kstr(J, mmstr); |
462 | mix.val = 0; | 464 | mix.val = 0; |
@@ -880,7 +882,7 @@ static void recff_nyi(jit_State *J, TRef *res, RecordFFData *rd) | |||
880 | lj_trace_err_info(J, LJ_TRERR_NYIFF); | 882 | lj_trace_err_info(J, LJ_TRERR_NYIFF); |
881 | } | 883 | } |
882 | 884 | ||
883 | LJ_NORET static void recff_err_ffu(jit_State *J, RecordFFData *rd) | 885 | LJ_NORET static void recff_err_nyi(jit_State *J, RecordFFData *rd) |
884 | { | 886 | { |
885 | setfuncV(J->L, &J->errinfo, rd->fn); | 887 | setfuncV(J->L, &J->errinfo, rd->fn); |
886 | lj_trace_err_info(J, LJ_TRERR_NYIFFU); | 888 | lj_trace_err_info(J, LJ_TRERR_NYIFFU); |
@@ -986,7 +988,7 @@ static void recff_tonumber(jit_State *J, TRef *res, RecordFFData *rd) | |||
986 | if (arg[1]) { | 988 | if (arg[1]) { |
987 | TRef base = lj_ir_toint(J, arg[1]); | 989 | TRef base = lj_ir_toint(J, arg[1]); |
988 | if (!tref_isk(base) || IR(tref_ref(base))->i != 10) | 990 | if (!tref_isk(base) || IR(tref_ref(base))->i != 10) |
989 | recff_err_ffu(J, rd); | 991 | recff_err_nyi(J, rd); |
990 | } | 992 | } |
991 | if (tref_isstr(tr)) | 993 | if (tref_isstr(tr)) |
992 | tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0); | 994 | tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0); |
@@ -1016,7 +1018,7 @@ static void recff_tostring(jit_State *J, TRef *res, RecordFFData *rd) | |||
1016 | } else if (tref_isnumber(tr)) { | 1018 | } else if (tref_isnumber(tr)) { |
1017 | res[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0); | 1019 | res[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0); |
1018 | } else { | 1020 | } else { |
1019 | recff_err_ffu(J, rd); | 1021 | recff_err_nyi(J, rd); |
1020 | } | 1022 | } |
1021 | } | 1023 | } |
1022 | } | 1024 | } |
@@ -1338,6 +1340,58 @@ static void recff_table_getn(jit_State *J, TRef *res, RecordFFData *rd) | |||
1338 | UNUSED(rd); | 1340 | UNUSED(rd); |
1339 | } | 1341 | } |
1340 | 1342 | ||
1343 | static void recff_table_remove(jit_State *J, TRef *res, RecordFFData *rd) | ||
1344 | { | ||
1345 | if (tref_istab(arg[0])) { | ||
1346 | if (!arg[1] || tref_isnil(arg[1])) { /* Simple pop: t[#t] = nil */ | ||
1347 | TRef trlen = emitir(IRTI(IR_TLEN), arg[0], 0); | ||
1348 | GCtab *t = tabV(&rd->argv[0]); | ||
1349 | MSize len = lj_tab_len(t); | ||
1350 | emitir(IRTGI(len ? IR_NE : IR_EQ), trlen, lj_ir_kint(J, 0)); | ||
1351 | if (len) { | ||
1352 | RecordIndex ix; | ||
1353 | ix.tab = arg[0]; | ||
1354 | ix.key = trlen; | ||
1355 | settabV(J->L, &ix.tabv, t); | ||
1356 | setintV(&ix.keyv, len); | ||
1357 | ix.idxchain = 0; | ||
1358 | if (rd->cres != 0) { /* Specialize load only if result needed. */ | ||
1359 | ix.val = 0; | ||
1360 | res[0] = rec_idx(J, &ix); /* Load previous value. */ | ||
1361 | /* Assumes ix.key/ix.tab is not modified for raw rec_idx(). */ | ||
1362 | } | ||
1363 | ix.val = TREF_NIL; | ||
1364 | rec_idx(J, &ix); /* Remove value. */ | ||
1365 | } else { | ||
1366 | rd->nres = 0; | ||
1367 | } | ||
1368 | } else { /* Complex case: remove in the middle. */ | ||
1369 | recff_err_nyi(J, rd); | ||
1370 | } | ||
1371 | } /* else: Interpreter will throw. */ | ||
1372 | } | ||
1373 | |||
1374 | static void recff_table_insert(jit_State *J, TRef *res, RecordFFData *rd) | ||
1375 | { | ||
1376 | rd->nres = 0; | ||
1377 | if (tref_istab(arg[0]) && arg[1]) { | ||
1378 | if (!arg[2]) { /* Simple push: t[#t+1] = v */ | ||
1379 | TRef trlen = emitir(IRTI(IR_TLEN), arg[0], 0); | ||
1380 | GCtab *t = tabV(&rd->argv[0]); | ||
1381 | RecordIndex ix; | ||
1382 | ix.tab = arg[0]; | ||
1383 | ix.val = arg[1]; | ||
1384 | ix.key = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1)); | ||
1385 | settabV(J->L, &ix.tabv, t); | ||
1386 | setintV(&ix.keyv, lj_tab_len(t) + 1); | ||
1387 | ix.idxchain = 0; | ||
1388 | rec_idx(J, &ix); /* Set new value. */ | ||
1389 | } else { /* Complex case: insert in the middle. */ | ||
1390 | recff_err_nyi(J, rd); | ||
1391 | } | ||
1392 | } /* else: Interpreter will throw. */ | ||
1393 | } | ||
1394 | |||
1341 | /* -- Record calls and returns -------------------------------------------- */ | 1395 | /* -- Record calls and returns -------------------------------------------- */ |
1342 | 1396 | ||
1343 | #undef arg | 1397 | #undef arg |
@@ -1618,8 +1672,8 @@ void lj_record_ins(jit_State *J) | |||
1618 | case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: | 1672 | case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: |
1619 | /* Emit nothing for two numeric or string consts. */ | 1673 | /* Emit nothing for two numeric or string consts. */ |
1620 | if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) { | 1674 | if (!(tref_isk2(ra,rc) && tref_isnumber_str(ra) && tref_isnumber_str(rc))) { |
1621 | IRType ta = tref_type(ra); | 1675 | IRType ta = tref_isinteger(ra) ? IRT_INT : tref_type(ra); |
1622 | IRType tc = tref_type(rc); | 1676 | IRType tc = tref_isinteger(rc) ? IRT_INT : tref_type(rc); |
1623 | int irop; | 1677 | int irop; |
1624 | if (ta != tc) { | 1678 | if (ta != tc) { |
1625 | /* Widen mixed number/int comparisons to number/number comparison. */ | 1679 | /* Widen mixed number/int comparisons to number/number comparison. */ |