summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2014-04-01 00:34:13 +0200
committerMike Pall <mike>2014-04-01 00:34:13 +0200
commitcaefd06871a6e2e673520d8565a51257e735a097 (patch)
tree1f49a3202d1cd039d4a4a2c613c198f7c805ff07
parentb65515fb4831d3cd9071c31ed56ba2a95578189a (diff)
parent19b69f21d409375ad8362c04186b246c1749fc8e (diff)
downloadluajit-caefd06871a6e2e673520d8565a51257e735a097.tar.gz
luajit-caefd06871a6e2e673520d8565a51257e735a097.tar.bz2
luajit-caefd06871a6e2e673520d8565a51257e735a097.zip
Merge branch 'master' into v2.1
-rw-r--r--src/lj_carith.c6
-rw-r--r--src/lj_crecord.c61
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. */
1352static void crec_arith_meta(jit_State *J, CTState *cts, RecordFFData *rd) 1352static 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
1382void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) 1390void 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}