diff options
author | Mike Pall <mike> | 2022-12-22 00:52:04 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2022-12-22 00:52:04 +0100 |
commit | a04480e311f93d3ceb2f92549cad3fffa38250ef (patch) | |
tree | a9e2102ac93d2e358d6fd8735cdb8949409f746d | |
parent | 8625eee71f16a3a780ec92bc303c17456efc7fb3 (diff) | |
parent | 8a5e398c52c7f8ca3e1a0e574cc2ba38224b759b (diff) | |
download | luajit-a04480e311f93d3ceb2f92549cad3fffa38250ef.tar.gz luajit-a04480e311f93d3ceb2f92549cad3fffa38250ef.tar.bz2 luajit-a04480e311f93d3ceb2f92549cad3fffa38250ef.zip |
Merge branch 'master' into v2.1
-rw-r--r-- | src/lib_base.c | 2 | ||||
-rw-r--r-- | src/lib_bit.c | 3 | ||||
-rw-r--r-- | src/lj_asm_mips.h | 2 | ||||
-rw-r--r-- | src/lj_carith.c | 2 | ||||
-rw-r--r-- | src/lj_cparse.c | 2 | ||||
-rw-r--r-- | src/lj_crecord.c | 3 | ||||
-rw-r--r-- | src/lj_ctype.c | 2 | ||||
-rw-r--r-- | src/lj_emit_arm.h | 2 | ||||
-rw-r--r-- | src/lj_emit_arm64.h | 9 | ||||
-rw-r--r-- | src/lj_obj.h | 2 | ||||
-rw-r--r-- | src/lj_opt_fold.c | 6 | ||||
-rw-r--r-- | src/lj_parse.c | 12 | ||||
-rw-r--r-- | src/lj_strfmt.c | 4 | ||||
-rw-r--r-- | src/lj_strscan.c | 26 | ||||
-rw-r--r-- | src/lj_vmmath.c | 6 |
15 files changed, 43 insertions, 40 deletions
diff --git a/src/lib_base.c b/src/lib_base.c index 98ec67c7..c59d54a2 100644 --- a/src/lib_base.c +++ b/src/lib_base.c | |||
@@ -303,7 +303,7 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) | |||
303 | while (lj_char_isspace((unsigned char)(*ep))) ep++; | 303 | while (lj_char_isspace((unsigned char)(*ep))) ep++; |
304 | if (*ep == '\0') { | 304 | if (*ep == '\0') { |
305 | if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u+neg)) { | 305 | if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u+neg)) { |
306 | if (neg) ul = (unsigned long)-(long)ul; | 306 | if (neg) ul = ~ul+1u; |
307 | setintV(L->base-1-LJ_FR2, (int32_t)ul); | 307 | setintV(L->base-1-LJ_FR2, (int32_t)ul); |
308 | } else { | 308 | } else { |
309 | lua_Number n = (lua_Number)ul; | 309 | lua_Number n = (lua_Number)ul; |
diff --git a/src/lib_bit.c b/src/lib_bit.c index 38c0f578..e08cd883 100644 --- a/src/lib_bit.c +++ b/src/lib_bit.c | |||
@@ -155,7 +155,8 @@ LJLIB_CF(bit_tohex) LJLIB_REC(.) | |||
155 | #endif | 155 | #endif |
156 | SBuf *sb = lj_buf_tmp_(L); | 156 | SBuf *sb = lj_buf_tmp_(L); |
157 | SFormat sf = (STRFMT_UINT|STRFMT_T_HEX); | 157 | SFormat sf = (STRFMT_UINT|STRFMT_T_HEX); |
158 | if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; } | 158 | if (n < 0) { n = (int32_t)(~(uint32_t)n+1u); sf |= STRFMT_F_UPPER; } |
159 | if ((uint32_t)n > 254) n = 254; | ||
159 | sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC); | 160 | sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC); |
160 | #if LJ_HASFFI | 161 | #if LJ_HASFFI |
161 | if (n < 16) b &= ((uint64_t)1 << 4*n)-1; | 162 | if (n < 16) b &= ((uint64_t)1 << 4*n)-1; |
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index 1686b40f..ac2d2662 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h | |||
@@ -1894,7 +1894,7 @@ static void asm_arithov(ASMState *as, IRIns *ir) | |||
1894 | lj_assertA(!irt_is64(ir->t), "bad usage"); | 1894 | lj_assertA(!irt_is64(ir->t), "bad usage"); |
1895 | if (irref_isk(ir->op2)) { | 1895 | if (irref_isk(ir->op2)) { |
1896 | int k = IR(ir->op2)->i; | 1896 | int k = IR(ir->op2)->i; |
1897 | if (ir->o == IR_SUBOV) k = -k; | 1897 | if (ir->o == IR_SUBOV) k = (int)(~(unsigned int)k+1u); |
1898 | if (checki16(k)) { /* (dest < left) == (k >= 0 ? 1 : 0) */ | 1898 | if (checki16(k)) { /* (dest < left) == (k >= 0 ? 1 : 0) */ |
1899 | left = ra_alloc1(as, ir->op1, RSET_GPR); | 1899 | left = ra_alloc1(as, ir->op1, RSET_GPR); |
1900 | asm_guard(as, k >= 0 ? MIPSI_BNE : MIPSI_BEQ, RID_TMP, RID_ZERO); | 1900 | asm_guard(as, k >= 0 ? MIPSI_BNE : MIPSI_BEQ, RID_TMP, RID_ZERO); |
diff --git a/src/lj_carith.c b/src/lj_carith.c index 1a2a058f..2e8504a9 100644 --- a/src/lj_carith.c +++ b/src/lj_carith.c | |||
@@ -207,7 +207,7 @@ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm) | |||
207 | else | 207 | else |
208 | *up = lj_carith_powu64(u0, u1); | 208 | *up = lj_carith_powu64(u0, u1); |
209 | break; | 209 | break; |
210 | case MM_unm: *up = (uint64_t)-(int64_t)u0; break; | 210 | case MM_unm: *up = ~u0+1u; break; |
211 | default: | 211 | default: |
212 | lj_assertL(0, "bad metamethod %d", mm); | 212 | lj_assertL(0, "bad metamethod %d", mm); |
213 | break; | 213 | break; |
diff --git a/src/lj_cparse.c b/src/lj_cparse.c index 7fd83997..126032d5 100644 --- a/src/lj_cparse.c +++ b/src/lj_cparse.c | |||
@@ -488,7 +488,7 @@ static void cp_expr_prefix(CPState *cp, CPValue *k) | |||
488 | } else if (cp_opt(cp, '+')) { | 488 | } else if (cp_opt(cp, '+')) { |
489 | cp_expr_unary(cp, k); /* Nothing to do (well, integer promotion). */ | 489 | cp_expr_unary(cp, k); /* Nothing to do (well, integer promotion). */ |
490 | } else if (cp_opt(cp, '-')) { | 490 | } else if (cp_opt(cp, '-')) { |
491 | cp_expr_unary(cp, k); k->i32 = -k->i32; | 491 | cp_expr_unary(cp, k); k->i32 = (int32_t)(~(uint32_t)k->i32+1); |
492 | } else if (cp_opt(cp, '~')) { | 492 | } else if (cp_opt(cp, '~')) { |
493 | cp_expr_unary(cp, k); k->i32 = ~k->i32; | 493 | cp_expr_unary(cp, k); k->i32 = ~k->i32; |
494 | } else if (cp_opt(cp, '!')) { | 494 | } else if (cp_opt(cp, '!')) { |
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index e0f581ca..9c9b6ccb 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -1879,7 +1879,8 @@ TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr) | |||
1879 | } else { | 1879 | } else { |
1880 | n = id ? 16 : 8; | 1880 | n = id ? 16 : 8; |
1881 | } | 1881 | } |
1882 | if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; } | 1882 | if (n < 0) { n = (int32_t)(~n+1u); sf |= STRFMT_F_UPPER; } |
1883 | if ((uint32_t)n > 254) n = 254; | ||
1883 | sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC); | 1884 | sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC); |
1884 | if (id) { | 1885 | if (id) { |
1885 | tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]); | 1886 | tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]); |
diff --git a/src/lj_ctype.c b/src/lj_ctype.c index 10322c00..73481e63 100644 --- a/src/lj_ctype.c +++ b/src/lj_ctype.c | |||
@@ -582,7 +582,7 @@ GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned) | |||
582 | if (isunsigned) { | 582 | if (isunsigned) { |
583 | *--p = 'U'; | 583 | *--p = 'U'; |
584 | } else if ((int64_t)n < 0) { | 584 | } else if ((int64_t)n < 0) { |
585 | n = (uint64_t)-(int64_t)n; | 585 | n = ~n+1u; |
586 | sign = 1; | 586 | sign = 1; |
587 | } | 587 | } |
588 | do { *--p = (char)('0' + n % 10); } while (n /= 10); | 588 | do { *--p = (char)('0' + n % 10); } while (n /= 10); |
diff --git a/src/lj_emit_arm.h b/src/lj_emit_arm.h index cfb174f4..0fd2aa05 100644 --- a/src/lj_emit_arm.h +++ b/src/lj_emit_arm.h | |||
@@ -157,7 +157,7 @@ static int emit_kdelta2(ASMState *as, Reg rd, int32_t i) | |||
157 | if (other) { | 157 | if (other) { |
158 | int32_t delta = i - other; | 158 | int32_t delta = i - other; |
159 | uint32_t sh, inv = 0, k2, k; | 159 | uint32_t sh, inv = 0, k2, k; |
160 | if (delta < 0) { delta = -delta; inv = ARMI_ADD^ARMI_SUB; } | 160 | if (delta < 0) { delta = (int32_t)(~(uint32_t)delta+1u); inv = ARMI_ADD^ARMI_SUB; } |
161 | sh = lj_ffs(delta) & ~1; | 161 | sh = lj_ffs(delta) & ~1; |
162 | k2 = emit_isk12(0, delta & (255 << sh)); | 162 | k2 = emit_isk12(0, delta & (255 << sh)); |
163 | k = emit_isk12(0, delta & ~(255 << sh)); | 163 | k = emit_isk12(0, delta & ~(255 << sh)); |
diff --git a/src/lj_emit_arm64.h b/src/lj_emit_arm64.h index c4b4c147..0ddba4a3 100644 --- a/src/lj_emit_arm64.h +++ b/src/lj_emit_arm64.h | |||
@@ -27,8 +27,8 @@ static uint64_t get_k64val(ASMState *as, IRRef ref) | |||
27 | /* Encode constant in K12 format for data processing instructions. */ | 27 | /* Encode constant in K12 format for data processing instructions. */ |
28 | static uint32_t emit_isk12(int64_t n) | 28 | static uint32_t emit_isk12(int64_t n) |
29 | { | 29 | { |
30 | uint64_t k = (n < 0) ? -n : n; | 30 | uint64_t k = n < 0 ? ~(uint64_t)n+1u : (uint64_t)n; |
31 | uint32_t m = (n < 0) ? 0x40000000 : 0; | 31 | uint32_t m = n < 0 ? 0x40000000 : 0; |
32 | if (k < 0x1000) { | 32 | if (k < 0x1000) { |
33 | return A64I_K12|m|A64F_U12(k); | 33 | return A64I_K12|m|A64F_U12(k); |
34 | } else if ((k & 0xfff000) == k) { | 34 | } else if ((k & 0xfff000) == k) { |
@@ -177,7 +177,7 @@ static int emit_kdelta(ASMState *as, Reg rd, uint64_t k, int lim) | |||
177 | emit_dm(as, A64I_MOVx, rd, r); | 177 | emit_dm(as, A64I_MOVx, rd, r); |
178 | return 1; | 178 | return 1; |
179 | } else { | 179 | } else { |
180 | uint32_t k12 = emit_isk12(delta < 0 ? -delta : delta); | 180 | uint32_t k12 = emit_isk12(delta < 0 ? (int64_t)(~(uint64_t)delta+1u) : delta); |
181 | if (k12) { | 181 | if (k12) { |
182 | emit_dn(as, (delta < 0 ? A64I_SUBx : A64I_ADDx)^k12, rd, r); | 182 | emit_dn(as, (delta < 0 ? A64I_SUBx : A64I_ADDx)^k12, rd, r); |
183 | return 1; | 183 | return 1; |
@@ -417,7 +417,8 @@ static void emit_addptr(ASMState *as, Reg r, int32_t ofs) | |||
417 | { | 417 | { |
418 | if (ofs) | 418 | if (ofs) |
419 | emit_opk(as, ofs < 0 ? A64I_SUBx : A64I_ADDx, r, r, | 419 | emit_opk(as, ofs < 0 ? A64I_SUBx : A64I_ADDx, r, r, |
420 | ofs < 0 ? -ofs : ofs, rset_exclude(RSET_GPR, r)); | 420 | ofs < 0 ? (int32_t)(~(uint32_t)ofs+1u) : ofs, |
421 | rset_exclude(RSET_GPR, r)); | ||
421 | } | 422 | } |
422 | 423 | ||
423 | #define emit_spsub(as, ofs) emit_addptr(as, RID_SP, -(ofs)) | 424 | #define emit_spsub(as, ofs) emit_addptr(as, RID_SP, -(ofs)) |
diff --git a/src/lj_obj.h b/src/lj_obj.h index 67e41181..e541387f 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
@@ -413,7 +413,7 @@ typedef struct GCproto { | |||
413 | #define PROTO_UV_IMMUTABLE 0x4000 /* Immutable upvalue. */ | 413 | #define PROTO_UV_IMMUTABLE 0x4000 /* Immutable upvalue. */ |
414 | 414 | ||
415 | #define proto_kgc(pt, idx) \ | 415 | #define proto_kgc(pt, idx) \ |
416 | check_exp((uintptr_t)(intptr_t)(idx) >= (uintptr_t)-(intptr_t)(pt)->sizekgc, \ | 416 | check_exp((uintptr_t)(intptr_t)(idx) >= ~(uintptr_t)(pt)->sizekgc+1u, \ |
417 | gcref(mref((pt)->k, GCRef)[(idx)])) | 417 | gcref(mref((pt)->k, GCRef)[(idx)])) |
418 | #define proto_knumtv(pt, idx) \ | 418 | #define proto_knumtv(pt, idx) \ |
419 | check_exp((uintptr_t)(idx) < (pt)->sizekn, &mref((pt)->k, TValue)[(idx)]) | 419 | check_exp((uintptr_t)(idx) < (pt)->sizekn, &mref((pt)->k, TValue)[(idx)]) |
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 7ef09a1f..c8f5397d 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
@@ -267,7 +267,7 @@ static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op) | |||
267 | case IR_SUB: k1 -= k2; break; | 267 | case IR_SUB: k1 -= k2; break; |
268 | case IR_MUL: k1 *= k2; break; | 268 | case IR_MUL: k1 *= k2; break; |
269 | case IR_MOD: k1 = lj_vm_modi(k1, k2); break; | 269 | case IR_MOD: k1 = lj_vm_modi(k1, k2); break; |
270 | case IR_NEG: k1 = -k1; break; | 270 | case IR_NEG: k1 = (int32_t)(~(uint32_t)k1+1u); break; |
271 | case IR_BAND: k1 &= k2; break; | 271 | case IR_BAND: k1 &= k2; break; |
272 | case IR_BOR: k1 |= k2; break; | 272 | case IR_BOR: k1 |= k2; break; |
273 | case IR_BXOR: k1 ^= k2; break; | 273 | case IR_BXOR: k1 ^= k2; break; |
@@ -1366,7 +1366,7 @@ LJFOLDF(simplify_intsub_k) | |||
1366 | if (fright->i == 0) /* i - 0 ==> i */ | 1366 | if (fright->i == 0) /* i - 0 ==> i */ |
1367 | return LEFTFOLD; | 1367 | return LEFTFOLD; |
1368 | fins->o = IR_ADD; /* i - k ==> i + (-k) */ | 1368 | fins->o = IR_ADD; /* i - k ==> i + (-k) */ |
1369 | fins->op2 = (IRRef1)lj_ir_kint(J, -fright->i); /* Overflow for -2^31 ok. */ | 1369 | fins->op2 = (IRRef1)lj_ir_kint(J, (int32_t)(~(uint32_t)fright->i+1u)); /* Overflow for -2^31 ok. */ |
1370 | return RETRYFOLD; | 1370 | return RETRYFOLD; |
1371 | } | 1371 | } |
1372 | 1372 | ||
@@ -1397,7 +1397,7 @@ LJFOLDF(simplify_intsub_k64) | |||
1397 | if (k == 0) /* i - 0 ==> i */ | 1397 | if (k == 0) /* i - 0 ==> i */ |
1398 | return LEFTFOLD; | 1398 | return LEFTFOLD; |
1399 | fins->o = IR_ADD; /* i - k ==> i + (-k) */ | 1399 | fins->o = IR_ADD; /* i - k ==> i + (-k) */ |
1400 | fins->op2 = (IRRef1)lj_ir_kint64(J, (uint64_t)-(int64_t)k); | 1400 | fins->op2 = (IRRef1)lj_ir_kint64(J, ~k+1u); |
1401 | return RETRYFOLD; | 1401 | return RETRYFOLD; |
1402 | } | 1402 | } |
1403 | 1403 | ||
diff --git a/src/lj_parse.c b/src/lj_parse.c index 9ddf60ed..64ae2c16 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
@@ -964,22 +964,22 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) | |||
964 | #if LJ_HASFFI | 964 | #if LJ_HASFFI |
965 | if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */ | 965 | if (e->k == VKCDATA) { /* Fold in-place since cdata is not interned. */ |
966 | GCcdata *cd = cdataV(&e->u.nval); | 966 | GCcdata *cd = cdataV(&e->u.nval); |
967 | int64_t *p = (int64_t *)cdataptr(cd); | 967 | uint64_t *p = (uint64_t *)cdataptr(cd); |
968 | if (cd->ctypeid == CTID_COMPLEX_DOUBLE) | 968 | if (cd->ctypeid == CTID_COMPLEX_DOUBLE) |
969 | p[1] ^= (int64_t)U64x(80000000,00000000); | 969 | p[1] ^= U64x(80000000,00000000); |
970 | else | 970 | else |
971 | *p = -*p; | 971 | *p = ~*p+1u; |
972 | return; | 972 | return; |
973 | } else | 973 | } else |
974 | #endif | 974 | #endif |
975 | if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */ | 975 | if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */ |
976 | TValue *o = expr_numtv(e); | 976 | TValue *o = expr_numtv(e); |
977 | if (tvisint(o)) { | 977 | if (tvisint(o)) { |
978 | int32_t k = intV(o); | 978 | int32_t k = intV(o), negk = (int32_t)(~(uint32_t)k+1u); |
979 | if (k == -k) | 979 | if (k == negk) |
980 | setnumV(o, -(lua_Number)k); | 980 | setnumV(o, -(lua_Number)k); |
981 | else | 981 | else |
982 | setintV(o, -k); | 982 | setintV(o, negk); |
983 | return; | 983 | return; |
984 | } else { | 984 | } else { |
985 | o->u64 ^= U64x(80000000,00000000); | 985 | o->u64 ^= U64x(80000000,00000000); |
diff --git a/src/lj_strfmt.c b/src/lj_strfmt.c index 5c808290..71ee9f62 100644 --- a/src/lj_strfmt.c +++ b/src/lj_strfmt.c | |||
@@ -102,7 +102,7 @@ retlit: | |||
102 | char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k) | 102 | char * LJ_FASTCALL lj_strfmt_wint(char *p, int32_t k) |
103 | { | 103 | { |
104 | uint32_t u = (uint32_t)k; | 104 | uint32_t u = (uint32_t)k; |
105 | if (k < 0) { u = (uint32_t)-k; *p++ = '-'; } | 105 | if (k < 0) { u = ~u+1u; *p++ = '-'; } |
106 | if (u < 10000) { | 106 | if (u < 10000) { |
107 | if (u < 10) goto dig1; | 107 | if (u < 10) goto dig1; |
108 | if (u < 100) goto dig2; | 108 | if (u < 100) goto dig2; |
@@ -287,7 +287,7 @@ SBuf *lj_strfmt_putfxint(SBuf *sb, SFormat sf, uint64_t k) | |||
287 | /* Figure out signed prefixes. */ | 287 | /* Figure out signed prefixes. */ |
288 | if (STRFMT_TYPE(sf) == STRFMT_INT) { | 288 | if (STRFMT_TYPE(sf) == STRFMT_INT) { |
289 | if ((int64_t)k < 0) { | 289 | if ((int64_t)k < 0) { |
290 | k = (uint64_t)-(int64_t)k; | 290 | k = ~k+1u; |
291 | prefix = 256 + '-'; | 291 | prefix = 256 + '-'; |
292 | } else if ((sf & STRFMT_F_PLUS)) { | 292 | } else if ((sf & STRFMT_F_PLUS)) { |
293 | prefix = 256 + '+'; | 293 | prefix = 256 + '+'; |
diff --git a/src/lj_strscan.c b/src/lj_strscan.c index 1d1c1c74..4ca848ec 100644 --- a/src/lj_strscan.c +++ b/src/lj_strscan.c | |||
@@ -124,19 +124,19 @@ static StrScanFmt strscan_hex(const uint8_t *p, TValue *o, | |||
124 | case STRSCAN_INT: | 124 | case STRSCAN_INT: |
125 | if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg && | 125 | if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg && |
126 | !(x == 0 && neg)) { | 126 | !(x == 0 && neg)) { |
127 | o->i = neg ? -(int32_t)x : (int32_t)x; | 127 | o->i = neg ? (int32_t)(~x+1u) : (int32_t)x; |
128 | return STRSCAN_INT; /* Fast path for 32 bit integers. */ | 128 | return STRSCAN_INT; /* Fast path for 32 bit integers. */ |
129 | } | 129 | } |
130 | if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; } | 130 | if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; } |
131 | /* fallthrough */ | 131 | /* fallthrough */ |
132 | case STRSCAN_U32: | 132 | case STRSCAN_U32: |
133 | if (dig > 8) return STRSCAN_ERROR; | 133 | if (dig > 8) return STRSCAN_ERROR; |
134 | o->i = neg ? -(int32_t)x : (int32_t)x; | 134 | o->i = neg ? (int32_t)(~x+1u) : (int32_t)x; |
135 | return STRSCAN_U32; | 135 | return STRSCAN_U32; |
136 | case STRSCAN_I64: | 136 | case STRSCAN_I64: |
137 | case STRSCAN_U64: | 137 | case STRSCAN_U64: |
138 | if (dig > 16) return STRSCAN_ERROR; | 138 | if (dig > 16) return STRSCAN_ERROR; |
139 | o->u64 = neg ? (uint64_t)-(int64_t)x : x; | 139 | o->u64 = neg ? ~x+1u : x; |
140 | return fmt; | 140 | return fmt; |
141 | default: | 141 | default: |
142 | break; | 142 | break; |
@@ -168,12 +168,12 @@ static StrScanFmt strscan_oct(const uint8_t *p, TValue *o, | |||
168 | /* fallthrough */ | 168 | /* fallthrough */ |
169 | case STRSCAN_U32: | 169 | case STRSCAN_U32: |
170 | if ((x >> 32)) return STRSCAN_ERROR; | 170 | if ((x >> 32)) return STRSCAN_ERROR; |
171 | o->i = neg ? -(int32_t)x : (int32_t)x; | 171 | o->i = neg ? (int32_t)(~(uint32_t)x+1u) : (int32_t)x; |
172 | break; | 172 | break; |
173 | default: | 173 | default: |
174 | case STRSCAN_I64: | 174 | case STRSCAN_I64: |
175 | case STRSCAN_U64: | 175 | case STRSCAN_U64: |
176 | o->u64 = neg ? (uint64_t)-(int64_t)x : x; | 176 | o->u64 = neg ? ~x+1u : x; |
177 | break; | 177 | break; |
178 | } | 178 | } |
179 | return fmt; | 179 | return fmt; |
@@ -229,18 +229,18 @@ static StrScanFmt strscan_dec(const uint8_t *p, TValue *o, | |||
229 | switch (fmt) { | 229 | switch (fmt) { |
230 | case STRSCAN_INT: | 230 | case STRSCAN_INT: |
231 | if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) { | 231 | if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) { |
232 | o->i = neg ? -(int32_t)x : (int32_t)x; | 232 | o->i = neg ? (int32_t)(~x+1u) : (int32_t)x; |
233 | return STRSCAN_INT; /* Fast path for 32 bit integers. */ | 233 | return STRSCAN_INT; /* Fast path for 32 bit integers. */ |
234 | } | 234 | } |
235 | if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; goto plainnumber; } | 235 | if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; goto plainnumber; } |
236 | /* fallthrough */ | 236 | /* fallthrough */ |
237 | case STRSCAN_U32: | 237 | case STRSCAN_U32: |
238 | if ((x >> 32) != 0) return STRSCAN_ERROR; | 238 | if ((x >> 32) != 0) return STRSCAN_ERROR; |
239 | o->i = neg ? -(int32_t)x : (int32_t)x; | 239 | o->i = neg ? (int32_t)(~x+1u) : (int32_t)x; |
240 | return STRSCAN_U32; | 240 | return STRSCAN_U32; |
241 | case STRSCAN_I64: | 241 | case STRSCAN_I64: |
242 | case STRSCAN_U64: | 242 | case STRSCAN_U64: |
243 | o->u64 = neg ? (uint64_t)-(int64_t)x : x; | 243 | o->u64 = neg ? ~x+1u : x; |
244 | return fmt; | 244 | return fmt; |
245 | default: | 245 | default: |
246 | plainnumber: /* Fast path for plain numbers < 2^63. */ | 246 | plainnumber: /* Fast path for plain numbers < 2^63. */ |
@@ -348,18 +348,18 @@ static StrScanFmt strscan_bin(const uint8_t *p, TValue *o, | |||
348 | switch (fmt) { | 348 | switch (fmt) { |
349 | case STRSCAN_INT: | 349 | case STRSCAN_INT: |
350 | if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) { | 350 | if (!(opt & STRSCAN_OPT_TONUM) && x < 0x80000000u+neg) { |
351 | o->i = neg ? -(int32_t)x : (int32_t)x; | 351 | o->i = neg ? (int32_t)(~x+1u) : (int32_t)x; |
352 | return STRSCAN_INT; /* Fast path for 32 bit integers. */ | 352 | return STRSCAN_INT; /* Fast path for 32 bit integers. */ |
353 | } | 353 | } |
354 | if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; } | 354 | if (!(opt & STRSCAN_OPT_C)) { fmt = STRSCAN_NUM; break; } |
355 | /* fallthrough */ | 355 | /* fallthrough */ |
356 | case STRSCAN_U32: | 356 | case STRSCAN_U32: |
357 | if (dig > 32) return STRSCAN_ERROR; | 357 | if (dig > 32) return STRSCAN_ERROR; |
358 | o->i = neg ? -(int32_t)x : (int32_t)x; | 358 | o->i = neg ? (int32_t)(~x+1u) : (int32_t)x; |
359 | return STRSCAN_U32; | 359 | return STRSCAN_U32; |
360 | case STRSCAN_I64: | 360 | case STRSCAN_I64: |
361 | case STRSCAN_U64: | 361 | case STRSCAN_U64: |
362 | o->u64 = neg ? (uint64_t)-(int64_t)x : x; | 362 | o->u64 = neg ? ~x+1u : x; |
363 | return fmt; | 363 | return fmt; |
364 | default: | 364 | default: |
365 | break; | 365 | break; |
@@ -468,7 +468,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o, | |||
468 | if (xx >= STRSCAN_MAXEXP) return STRSCAN_ERROR; | 468 | if (xx >= STRSCAN_MAXEXP) return STRSCAN_ERROR; |
469 | p++; | 469 | p++; |
470 | } | 470 | } |
471 | ex += negx ? -(int32_t)xx : (int32_t)xx; | 471 | ex += negx ? (int32_t)(~xx+1u) : (int32_t)xx; |
472 | } | 472 | } |
473 | 473 | ||
474 | /* Parse suffix. */ | 474 | /* Parse suffix. */ |
@@ -507,7 +507,7 @@ StrScanFmt lj_strscan_scan(const uint8_t *p, MSize len, TValue *o, | |||
507 | o->n = -0.0; | 507 | o->n = -0.0; |
508 | return STRSCAN_NUM; | 508 | return STRSCAN_NUM; |
509 | } else { | 509 | } else { |
510 | o->i = neg ? -(int32_t)x : (int32_t)x; | 510 | o->i = neg ? (int32_t)(~x+1u) : (int32_t)x; |
511 | return STRSCAN_INT; | 511 | return STRSCAN_INT; |
512 | } | 512 | } |
513 | } | 513 | } |
diff --git a/src/lj_vmmath.c b/src/lj_vmmath.c index d0febd81..4fa79ae4 100644 --- a/src/lj_vmmath.c +++ b/src/lj_vmmath.c | |||
@@ -75,11 +75,11 @@ int32_t LJ_FASTCALL lj_vm_modi(int32_t a, int32_t b) | |||
75 | uint32_t y, ua, ub; | 75 | uint32_t y, ua, ub; |
76 | /* This must be checked before using this function. */ | 76 | /* This must be checked before using this function. */ |
77 | lj_assertX(b != 0, "modulo with zero divisor"); | 77 | lj_assertX(b != 0, "modulo with zero divisor"); |
78 | ua = a < 0 ? (uint32_t)-a : (uint32_t)a; | 78 | ua = a < 0 ? ~(uint32_t)a+1u : (uint32_t)a; |
79 | ub = b < 0 ? (uint32_t)-b : (uint32_t)b; | 79 | ub = b < 0 ? ~(uint32_t)b+1u : (uint32_t)b; |
80 | y = ua % ub; | 80 | y = ua % ub; |
81 | if (y != 0 && (a^b) < 0) y = y - ub; | 81 | if (y != 0 && (a^b) < 0) y = y - ub; |
82 | if (((int32_t)y^b) < 0) y = (uint32_t)-(int32_t)y; | 82 | if (((int32_t)y^b) < 0) y = ~y+1u; |
83 | return (int32_t)y; | 83 | return (int32_t)y; |
84 | } | 84 | } |
85 | #endif | 85 | #endif |