diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index bdaa0e4f..83972db9 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -1958,14 +1958,15 @@ LJFOLDF(abc_fwd) LJFOLD(ABC any KINT) LJFOLDF(abc_k) { + PHIBARRIER(fleft); if (LJ_LIKELY(J->flags & JIT_F_OPT_ABC)) { IRRef ref = J->chain[IR_ABC]; IRRef asize = fins->op1; while (ref > asize) { IRIns *ir = IR(ref); if (ir->op1 == asize && irref_isk(ir->op2)) { - int32_t k = IR(ir->op2)->i; - if (fright->i > k) + uint32_t k = (uint32_t)IR(ir->op2)->i; + if ((uint32_t)fright->i > k) ir->op2 = fins->op2; return DROPFOLD; } diff --git a/src/lj_opt_sink.c b/src/lj_opt_sink.c index 5306a7db..f1a67fa1 100644 --- a/src/lj_opt_sink.c +++ b/src/lj_opt_sink.c @@ -36,12 +36,14 @@ static IRIns *sink_checkalloc(jit_State *J, IRIns *irs) } /* Recursively check whether a value depends on a PHI. */ -static int sink_phidep(jit_State *J, IRRef ref) +static int sink_phidep(jit_State *J, IRRef ref, int *workp) { IRIns *ir = IR(ref); + if (!*workp) return 1; /* Give up and pretend it does. */ + (*workp)--; if (irt_isphi(ir->t)) return 1; - if (ir->op1 >= REF_FIRST && sink_phidep(J, ir->op1)) return 1; - if (ir->op2 >= REF_FIRST && sink_phidep(J, ir->op2)) return 1; + if (ir->op1 >= REF_FIRST && sink_phidep(J, ir->op1, workp)) return 1; + if (ir->op2 >= REF_FIRST && sink_phidep(J, ir->op2, workp)) return 1; return 0; } @@ -56,7 +58,13 @@ static int sink_checkphi(jit_State *J, IRIns *ira, IRRef ref) return 1; /* Sinkable PHI. */ } /* Otherwise the value must be loop-invariant. */ - return ref < J->loopref && !sink_phidep(J, ref); + if (ref < J->loopref) { + /* Check for PHI dependencies, but give up after reasonable effort. */ + int work = 64; + return !sink_phidep(J, ref, &work); + } else { + return 0; /* Loop-variant. */ + } } return 1; /* Constant (non-PHI). */ } diff --git a/src/lj_strscan.c b/src/lj_strscan.c index f681fbb0..173455b4 100644 --- a/src/lj_strscan.c +++ b/src/lj_strscan.c @@ -63,6 +63,7 @@ #define STRSCAN_MAXDIG 800 /* 772 + extra are sufficient. */ #define STRSCAN_DDIG (STRSCAN_DIG/2) #define STRSCAN_DMASK (STRSCAN_DDIG-1) +#define STRSCAN_MAXEXP (1 << 20) /* Helpers for circular buffer. */ #define DNEXT(a) (((a)+1) & STRSCAN_DMASK) @@ -121,7 +122,8 @@ static StrScanFmt strscan_hex(const uint8_t *p, TValue *o, /* Format-specific handling. */ switch (fmt) { case STRSCAN_INT: - if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) { + if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg && + !(x == 0 && neg)) { o->i = neg ? -(int32_t)x : (int32_t)x; return STRSCAN_INT; /* Fast path for 32 bit integers. */ } @@ -448,6 +450,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o, if (dig) { ex = (int32_t)(dp-(p-1)); dp = p-1; while (ex < 0 && *dp-- == '0') ex++, dig--; /* Skip trailing zeros. */ + if (ex <= -STRSCAN_MAXEXP) return STRSCAN_ERROR; if (base == 16) ex *= 4; } } @@ -461,7 +464,8 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o, if (!lj_char_isdigit(*p)) return STRSCAN_ERROR; xx = (*p++ & 15); while (lj_char_isdigit(*p)) { - if (xx < 65536) xx = xx * 10 + (*p & 15); + xx = xx * 10 + (*p & 15); + if (xx >= STRSCAN_MAXEXP) return STRSCAN_ERROR; p++; } ex += negx ? -(int32_t)xx : (int32_t)xx; @@ -499,6 +503,9 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o, if ((opt & STRSCAN_OPT_TONUM)) { o->n = neg ? -(double)x : (double)x; return STRSCAN_NUM; + } else if (x == 0 && neg) { + o->n = -0.0; + return STRSCAN_NUM; } else { o->i = neg ? -(int32_t)x : (int32_t)x; return STRSCAN_INT; @@ -516,7 +523,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o, fmt = strscan_dec(sp, o, fmt, opt, ex, neg, dig); /* Try to convert number to integer, if requested. */ - if (fmt == STRSCAN_NUM && (opt & STRSCAN_OPT_TOINT)) { + if (fmt == STRSCAN_NUM && (opt & STRSCAN_OPT_TOINT) && !tvismzero(o)) { double n = o->n; int32_t i = lj_num2int(n); if (n == (lua_Number)i) { o->i = i; return STRSCAN_INT; }