diff options
-rw-r--r-- | src/lj_carith.c | 6 | ||||
-rw-r--r-- | src/lj_crecord.c | 61 |
2 files changed, 38 insertions, 29 deletions
diff --git a/src/lj_carith.c b/src/lj_carith.c index d8b5f91a..1b1786a6 100644 --- a/src/lj_carith.c +++ b/src/lj_carith.c | |||
@@ -75,7 +75,7 @@ static int carith_checkarg(lua_State *L, CTState *cts, CDArith *ca) | |||
75 | ok = 1; | 75 | ok = 1; |
76 | } else { | 76 | } else { |
77 | ca->ct[1-i] = ct; /* Use enum to improve error message. */ | 77 | ca->ct[1-i] = ct; /* Use enum to improve error message. */ |
78 | ca->p[1-i] = NULL; | 78 | ca->p[1-i] = (void *)(intptr_t)1; /* To make it unequal. */ |
79 | break; | 79 | break; |
80 | } | 80 | } |
81 | } | 81 | } |
@@ -236,7 +236,9 @@ static int lj_carith_meta(lua_State *L, CTState *cts, CDArith *ca, MMS mm) | |||
236 | const char *repr[2]; | 236 | const char *repr[2]; |
237 | int i, isenum = -1, isstr = -1; | 237 | int i, isenum = -1, isstr = -1; |
238 | if (mm == MM_eq) { /* Equality checks never raise an error. */ | 238 | if (mm == MM_eq) { /* Equality checks never raise an error. */ |
239 | setboolV(L->top-1, 0); | 239 | int eq = ca->p[0] == ca->p[1]; |
240 | setboolV(L->top-1, eq); | ||
241 | setboolV(&G(L)->tmptv2, eq); /* Remember for trace recorder. */ | ||
240 | return 1; | 242 | return 1; |
241 | } | 243 | } |
242 | for (i = 0; i < 2; i++) { | 244 | for (i = 0; i < 2; i++) { |
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index a1e2c504..29733567 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -1349,7 +1349,8 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm) | |||
1349 | } | 1349 | } |
1350 | 1350 | ||
1351 | /* Record ctype arithmetic metamethods. */ | 1351 | /* Record ctype arithmetic metamethods. */ |
1352 | static void crec_arith_meta(jit_State *J, CTState *cts, RecordFFData *rd) | 1352 | static TRef crec_arith_meta(jit_State *J, TRef *sp, CTState *cts, |
1353 | RecordFFData *rd) | ||
1353 | { | 1354 | { |
1354 | cTValue *tv = NULL; | 1355 | cTValue *tv = NULL; |
1355 | if (J->base[0]) { | 1356 | if (J->base[0]) { |
@@ -1370,13 +1371,20 @@ static void crec_arith_meta(jit_State *J, CTState *cts, RecordFFData *rd) | |||
1370 | if (tvisfunc(tv)) { | 1371 | if (tvisfunc(tv)) { |
1371 | J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; | 1372 | J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; |
1372 | rd->nres = -1; /* Pending tailcall. */ | 1373 | rd->nres = -1; /* Pending tailcall. */ |
1373 | return; | 1374 | return 0; |
1374 | } /* NYI: non-function metamethods. */ | 1375 | } /* NYI: non-function metamethods. */ |
1375 | } else if ((MMS)rd->data == MM_eq) { | 1376 | } else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */ |
1376 | J->base[0] = TREF_FALSE; | 1377 | if (sp[0] && sp[1]) { |
1377 | return; | 1378 | /* Assume true comparison. Fixup and emit pending guard later. */ |
1379 | lj_ir_set(J, IRTG(IR_EQ, IRT_PTR), sp[0], sp[1]); | ||
1380 | J->postproc = LJ_POST_FIXGUARD; | ||
1381 | return TREF_TRUE; | ||
1382 | } else { | ||
1383 | return TREF_FALSE; | ||
1384 | } | ||
1378 | } | 1385 | } |
1379 | lj_trace_err(J, LJ_TRERR_BADTYPE); | 1386 | lj_trace_err(J, LJ_TRERR_BADTYPE); |
1387 | return 0; | ||
1380 | } | 1388 | } |
1381 | 1389 | ||
1382 | void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) | 1390 | void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) |
@@ -1389,7 +1397,7 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) | |||
1389 | TRef tr = J->base[i]; | 1397 | TRef tr = J->base[i]; |
1390 | CType *ct = ctype_get(cts, CTID_DOUBLE); | 1398 | CType *ct = ctype_get(cts, CTID_DOUBLE); |
1391 | if (!tr) { | 1399 | if (!tr) { |
1392 | goto trymeta; | 1400 | lj_trace_err(J, LJ_TRERR_BADTYPE); |
1393 | } else if (tref_iscdata(tr)) { | 1401 | } else if (tref_iscdata(tr)) { |
1394 | CTypeID id = argv2cdata(J, tr, &rd->argv[i])->ctypeid; | 1402 | CTypeID id = argv2cdata(J, tr, &rd->argv[i])->ctypeid; |
1395 | IRType t; | 1403 | IRType t; |
@@ -1419,11 +1427,12 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) | |||
1419 | } | 1427 | } |
1420 | if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); | 1428 | if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); |
1421 | if (ctype_isnum(ct->info)) { | 1429 | if (ctype_isnum(ct->info)) { |
1422 | if (t == IRT_CDATA) goto trymeta; | 1430 | if (t == IRT_CDATA) { |
1423 | if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); | 1431 | tr = 0; |
1424 | tr = emitir(IRT(IR_XLOAD, t), tr, 0); | 1432 | } else { |
1425 | } else if (!(ctype_isptr(ct->info) || ctype_isrefarray(ct->info))) { | 1433 | if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); |
1426 | goto trymeta; | 1434 | tr = emitir(IRT(IR_XLOAD, t), tr, 0); |
1435 | } | ||
1427 | } | 1436 | } |
1428 | } else if (tref_isnil(tr)) { | 1437 | } else if (tref_isnil(tr)) { |
1429 | tr = lj_ir_kptr(J, NULL); | 1438 | tr = lj_ir_kptr(J, NULL); |
@@ -1446,7 +1455,7 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) | |||
1446 | } /* else: interpreter will throw. */ | 1455 | } /* else: interpreter will throw. */ |
1447 | } /* else: interpreter will throw. */ | 1456 | } /* else: interpreter will throw. */ |
1448 | } else if (!tref_isnum(tr)) { | 1457 | } else if (!tref_isnum(tr)) { |
1449 | goto trymeta; | 1458 | tr = 0; |
1450 | } | 1459 | } |
1451 | ok: | 1460 | ok: |
1452 | s[i] = ct; | 1461 | s[i] = ct; |
@@ -1454,22 +1463,20 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) | |||
1454 | } | 1463 | } |
1455 | { | 1464 | { |
1456 | TRef tr; | 1465 | TRef tr; |
1457 | if ((tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) || | 1466 | if (!(tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) && |
1458 | (tr = crec_arith_ptr(J, sp, s, (MMS)rd->data))) { | 1467 | !(tr = crec_arith_ptr(J, sp, s, (MMS)rd->data)) && |
1459 | J->base[0] = tr; | 1468 | !(tr = crec_arith_meta(J, sp, cts, rd))) |
1460 | /* Fixup cdata comparisons, too. Avoids some cdata escapes. */ | 1469 | return; |
1461 | if (J->postproc == LJ_POST_FIXGUARD && frame_iscont(J->L->base-1) && | 1470 | J->base[0] = tr; |
1462 | !irt_isguard(J->guardemit)) { | 1471 | /* Fixup cdata comparisons, too. Avoids some cdata escapes. */ |
1463 | const BCIns *pc = frame_contpc(J->L->base-1) - 1; | 1472 | if (J->postproc == LJ_POST_FIXGUARD && frame_iscont(J->L->base-1) && |
1464 | if (bc_op(*pc) <= BC_ISNEP) { | 1473 | !irt_isguard(J->guardemit)) { |
1465 | setframe_pc(&J2G(J)->tmptv, pc); | 1474 | const BCIns *pc = frame_contpc(J->L->base-1) - 1; |
1466 | J2G(J)->tmptv.u32.lo = ((tref_istrue(tr) ^ bc_op(*pc)) & 1); | 1475 | if (bc_op(*pc) <= BC_ISNEP) { |
1467 | J->postproc = LJ_POST_FIXCOMP; | 1476 | setframe_pc(&J2G(J)->tmptv, pc); |
1468 | } | 1477 | J2G(J)->tmptv.u32.lo = ((tref_istrue(tr) ^ bc_op(*pc)) & 1); |
1478 | J->postproc = LJ_POST_FIXCOMP; | ||
1469 | } | 1479 | } |
1470 | } else { | ||
1471 | trymeta: | ||
1472 | crec_arith_meta(J, cts, rd); | ||
1473 | } | 1480 | } |
1474 | } | 1481 | } |
1475 | } | 1482 | } |