mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 23:44:08 +00:00
Check for non-numeric string operands when recording arithmetic operations.
Non-numeric operands cause a fall through into the corresponding metamethod.
This commit is contained in:
parent
ac9193cfeb
commit
a9d583b937
@ -31,6 +31,7 @@
|
|||||||
#include "lj_record.h"
|
#include "lj_record.h"
|
||||||
#include "lj_ffrecord.h"
|
#include "lj_ffrecord.h"
|
||||||
#include "lj_snap.h"
|
#include "lj_snap.h"
|
||||||
|
#include "lj_strscan.h"
|
||||||
#include "lj_dispatch.h"
|
#include "lj_dispatch.h"
|
||||||
#include "lj_vm.h"
|
#include "lj_vm.h"
|
||||||
|
|
||||||
@ -962,6 +963,23 @@ nocheck:
|
|||||||
return 0; /* No metamethod. */
|
return 0; /* No metamethod. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if no metamethod call is required for the given arguments. */
|
||||||
|
static int rec_isnumericarith(jit_State *J,
|
||||||
|
TRef rb, TValue *rbv,
|
||||||
|
TRef rc, TValue *rcv) {
|
||||||
|
if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) {
|
||||||
|
TValue tmp;
|
||||||
|
if ((tref_isstr(rb) && !lj_strscan_num(strV(rbv), &tmp)) ||
|
||||||
|
(tref_isstr(rb) && !lj_strscan_num(strV(rbv), &tmp))) {
|
||||||
|
/* Would need an inverted STRTO for this case. */
|
||||||
|
lj_trace_err_info(J, LJ_TRERR_NYIMM);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Record call to arithmetic metamethod. */
|
/* Record call to arithmetic metamethod. */
|
||||||
static TRef rec_mm_arith(jit_State *J, RecordIndex *ix, MMS mm)
|
static TRef rec_mm_arith(jit_State *J, RecordIndex *ix, MMS mm)
|
||||||
{
|
{
|
||||||
@ -2127,7 +2145,7 @@ void lj_record_ins(jit_State *J)
|
|||||||
/* -- Arithmetic ops ---------------------------------------------------- */
|
/* -- Arithmetic ops ---------------------------------------------------- */
|
||||||
|
|
||||||
case BC_UNM:
|
case BC_UNM:
|
||||||
if (tref_isnumber_str(rc)) {
|
if (rec_isnumericarith(J, rc, rcv, rc, rcv)) {
|
||||||
rc = lj_opt_narrow_unm(J, rc, rcv);
|
rc = lj_opt_narrow_unm(J, rc, rcv);
|
||||||
} else {
|
} else {
|
||||||
ix.tab = rc;
|
ix.tab = rc;
|
||||||
@ -2148,9 +2166,10 @@ 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 (rec_isnumericarith(J, rb, rbv, rc, rcv)) {
|
||||||
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
|
||||||
rc = rec_mm_arith(J, &ix, mm);
|
rc = rec_mm_arith(J, &ix, mm);
|
||||||
break;
|
break;
|
||||||
@ -2158,14 +2177,14 @@ void lj_record_ins(jit_State *J)
|
|||||||
|
|
||||||
case BC_MODVN: case BC_MODVV:
|
case BC_MODVN: case BC_MODVV:
|
||||||
recmod:
|
recmod:
|
||||||
if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
|
if (rec_isnumericarith(J, rb, rbv, rc, rcv))
|
||||||
rc = lj_opt_narrow_mod(J, rb, rc, rcv);
|
rc = lj_opt_narrow_mod(J, rb, rc, rcv);
|
||||||
else
|
else
|
||||||
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 (rec_isnumericarith(J, rb, rbv, rc, rcv))
|
||||||
rc = lj_opt_narrow_pow(J, lj_ir_tonum(J, rb), rc, rcv);
|
rc = lj_opt_narrow_pow(J, lj_ir_tonum(J, rb), rc, rcv);
|
||||||
else
|
else
|
||||||
rc = rec_mm_arith(J, &ix, MM_pow);
|
rc = rec_mm_arith(J, &ix, MM_pow);
|
||||||
|
@ -14,6 +14,7 @@ TREDEF(SNAPOV, "too many snapshots")
|
|||||||
TREDEF(BLACKL, "blacklisted")
|
TREDEF(BLACKL, "blacklisted")
|
||||||
TREDEF(RETRY, "retry recording")
|
TREDEF(RETRY, "retry recording")
|
||||||
TREDEF(NYIBC, "NYI: bytecode %d")
|
TREDEF(NYIBC, "NYI: bytecode %d")
|
||||||
|
TREDEF(NYIMM, "NYI: arithmetic metamethod on non-numeric strings")
|
||||||
|
|
||||||
/* Recording loop ops. */
|
/* Recording loop ops. */
|
||||||
TREDEF(LLEAVE, "leaving loop in root trace")
|
TREDEF(LLEAVE, "leaving loop in root trace")
|
||||||
|
Loading…
Reference in New Issue
Block a user