diff options
author | Mike Pall <mike> | 2011-02-17 00:44:14 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-02-17 00:44:14 +0100 |
commit | 03946ac978d9a1a3230619e3da048002e5fda2d1 (patch) | |
tree | c0a7b8edaccf789f128468320d451d9a1fee1495 | |
parent | 963f05c7e153714921484e0de71a7cb6bab338d9 (diff) | |
download | luajit-03946ac978d9a1a3230619e3da048002e5fda2d1.tar.gz luajit-03946ac978d9a1a3230619e3da048002e5fda2d1.tar.bz2 luajit-03946ac978d9a1a3230619e3da048002e5fda2d1.zip |
DUALNUM: Add integer type to core VM.
-rw-r--r-- | src/lib_base.c | 28 | ||||
-rw-r--r-- | src/lib_io.c | 42 | ||||
-rw-r--r-- | src/lib_jit.c | 25 | ||||
-rw-r--r-- | src/lib_math.c | 2 | ||||
-rw-r--r-- | src/lib_string.c | 6 | ||||
-rw-r--r-- | src/lib_table.c | 8 | ||||
-rw-r--r-- | src/lj_api.c | 103 | ||||
-rw-r--r-- | src/lj_ctype.c | 2 | ||||
-rw-r--r-- | src/lj_def.h | 1 | ||||
-rw-r--r-- | src/lj_dispatch.c | 2 | ||||
-rw-r--r-- | src/lj_err.c | 12 | ||||
-rw-r--r-- | src/lj_func.c | 4 | ||||
-rw-r--r-- | src/lj_lex.c | 9 | ||||
-rw-r--r-- | src/lj_lib.c | 14 | ||||
-rw-r--r-- | src/lj_lib.h | 4 | ||||
-rw-r--r-- | src/lj_meta.c | 12 | ||||
-rw-r--r-- | src/lj_obj.c | 4 | ||||
-rw-r--r-- | src/lj_obj.h | 63 | ||||
-rw-r--r-- | src/lj_parse.c | 129 | ||||
-rw-r--r-- | src/lj_snap.c | 2 | ||||
-rw-r--r-- | src/lj_str.c | 79 | ||||
-rw-r--r-- | src/lj_str.h | 8 | ||||
-rw-r--r-- | src/lj_tab.c | 33 |
23 files changed, 403 insertions, 189 deletions
diff --git a/src/lib_base.c b/src/lib_base.c index 1a9a6df2..746a4fd6 100644 --- a/src/lib_base.c +++ b/src/lib_base.c | |||
@@ -190,8 +190,8 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) | |||
190 | int32_t base = lj_lib_optint(L, 2, 10); | 190 | int32_t base = lj_lib_optint(L, 2, 10); |
191 | if (base == 10) { | 191 | if (base == 10) { |
192 | TValue *o = lj_lib_checkany(L, 1); | 192 | TValue *o = lj_lib_checkany(L, 1); |
193 | if (tvisnum(o) || (tvisstr(o) && lj_str_tonum(strV(o), o))) { | 193 | if (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o))) { |
194 | setnumV(L->base-1, numV(o)); | 194 | copyTV(L, L->base-1, o); |
195 | return FFH_RES(1); | 195 | return FFH_RES(1); |
196 | } | 196 | } |
197 | #if LJ_HASFFI | 197 | #if LJ_HASFFI |
@@ -212,7 +212,10 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) | |||
212 | if (p != ep) { | 212 | if (p != ep) { |
213 | while (lj_char_isspace((unsigned char)(*ep))) ep++; | 213 | while (lj_char_isspace((unsigned char)(*ep))) ep++; |
214 | if (*ep == '\0') { | 214 | if (*ep == '\0') { |
215 | setnumV(L->base-1, cast_num(ul)); | 215 | if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u)) |
216 | setintV(L->base-1, (int32_t)ul); | ||
217 | else | ||
218 | setnumV(L->base-1, (lua_Number)ul); | ||
216 | return FFH_RES(1); | 219 | return FFH_RES(1); |
217 | } | 220 | } |
218 | } | 221 | } |
@@ -234,8 +237,8 @@ LJLIB_ASM(tostring) LJLIB_REC(.) | |||
234 | return FFH_TAILCALL; | 237 | return FFH_TAILCALL; |
235 | } else { | 238 | } else { |
236 | GCstr *s; | 239 | GCstr *s; |
237 | if (tvisnum(o)) { | 240 | if (tvisnumber(o)) { |
238 | s = lj_str_fromnum(L, &o->n); | 241 | s = lj_str_fromnumber(L, o); |
239 | } else if (tvispri(o)) { | 242 | } else if (tvispri(o)) { |
240 | s = strV(lj_lib_upvalue(L, -(int32_t)itype(o))); | 243 | s = strV(lj_lib_upvalue(L, -(int32_t)itype(o))); |
241 | } else { | 244 | } else { |
@@ -359,7 +362,7 @@ static const char *reader_func(lua_State *L, void *ud, size_t *size) | |||
359 | if (tvisnil(L->top)) { | 362 | if (tvisnil(L->top)) { |
360 | *size = 0; | 363 | *size = 0; |
361 | return NULL; | 364 | return NULL; |
362 | } else if (tvisstr(L->top) || tvisnum(L->top)) { | 365 | } else if (tvisstr(L->top) || tvisnumber(L->top)) { |
363 | copyTV(L, L->base+2, L->top); /* Anchor string in reserved stack slot. */ | 366 | copyTV(L, L->base+2, L->top); /* Anchor string in reserved stack slot. */ |
364 | return lua_tolstring(L, 3, size); | 367 | return lua_tolstring(L, 3, size); |
365 | } else { | 368 | } else { |
@@ -385,7 +388,7 @@ LJLIB_CF(dofile) | |||
385 | if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != 0) | 388 | if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != 0) |
386 | lua_error(L); | 389 | lua_error(L); |
387 | lua_call(L, 0, LUA_MULTRET); | 390 | lua_call(L, 0, LUA_MULTRET); |
388 | return cast_int(L->top - L->base) - 1; | 391 | return (int)(L->top - L->base) - 1; |
389 | } | 392 | } |
390 | 393 | ||
391 | /* -- Base library: GC control -------------------------------------------- */ | 394 | /* -- Base library: GC control -------------------------------------------- */ |
@@ -402,7 +405,7 @@ LJLIB_CF(collectgarbage) | |||
402 | "\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul"); | 405 | "\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul"); |
403 | int32_t data = lj_lib_optint(L, 2, 0); | 406 | int32_t data = lj_lib_optint(L, 2, 0); |
404 | if (opt == LUA_GCCOUNT) { | 407 | if (opt == LUA_GCCOUNT) { |
405 | setnumV(L->top, cast_num(G(L)->gc.total)/1024.0); | 408 | setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0); |
406 | } else { | 409 | } else { |
407 | int res = lua_gc(L, opt, data); | 410 | int res = lua_gc(L, opt, data); |
408 | if (opt == LUA_GCSTEP) | 411 | if (opt == LUA_GCSTEP) |
@@ -464,8 +467,13 @@ LJLIB_CF(print) | |||
464 | if (shortcut && tvisstr(o)) { | 467 | if (shortcut && tvisstr(o)) { |
465 | str = strVdata(o); | 468 | str = strVdata(o); |
466 | size = strV(o)->len; | 469 | size = strV(o)->len; |
470 | } else if (shortcut && tvisint(o)) { | ||
471 | char buf[LJ_STR_INTBUF]; | ||
472 | char *p = lj_str_bufint(buf, intV(o)); | ||
473 | size = (size_t)(buf+LJ_STR_INTBUF-p); | ||
474 | str = p; | ||
467 | } else if (shortcut && tvisnum(o)) { | 475 | } else if (shortcut && tvisnum(o)) { |
468 | char buf[LUAI_MAXNUMBER2STR]; | 476 | char buf[LJ_STR_NUMBUF]; |
469 | size = lj_str_bufnum(buf, o); | 477 | size = lj_str_bufnum(buf, o); |
470 | str = buf; | 478 | str = buf; |
471 | } else { | 479 | } else { |
@@ -604,7 +612,7 @@ static void newproxy_weaktable(lua_State *L) | |||
604 | setgcref(t->metatable, obj2gco(t)); | 612 | setgcref(t->metatable, obj2gco(t)); |
605 | setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")), | 613 | setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")), |
606 | lj_str_newlit(L, "kv")); | 614 | lj_str_newlit(L, "kv")); |
607 | t->nomm = cast_byte(~(1u<<MM_mode)); | 615 | t->nomm = (uint8_t)(~(1u<<MM_mode)); |
608 | } | 616 | } |
609 | 617 | ||
610 | LUALIB_API int luaopen_base(lua_State *L) | 618 | LUALIB_API int luaopen_base(lua_State *L) |
diff --git a/src/lib_io.c b/src/lib_io.c index 307d005c..66b174f8 100644 --- a/src/lib_io.c +++ b/src/lib_io.c | |||
@@ -195,7 +195,7 @@ static int io_file_readchars(lua_State *L, FILE *fp, size_t n) | |||
195 | 195 | ||
196 | static int io_file_read(lua_State *L, FILE *fp, int start) | 196 | static int io_file_read(lua_State *L, FILE *fp, int start) |
197 | { | 197 | { |
198 | int ok, n, nargs = cast_int(L->top - L->base) - start; | 198 | int ok, n, nargs = (int)(L->top - L->base) - start; |
199 | clearerr(fp); | 199 | clearerr(fp); |
200 | if (nargs == 0) { | 200 | if (nargs == 0) { |
201 | ok = io_file_readline(L, fp); | 201 | ok = io_file_readline(L, fp); |
@@ -240,10 +240,15 @@ static int io_file_write(lua_State *L, FILE *fp, int start) | |||
240 | if (tvisstr(tv)) { | 240 | if (tvisstr(tv)) { |
241 | MSize len = strV(tv)->len; | 241 | MSize len = strV(tv)->len; |
242 | status = status && (fwrite(strVdata(tv), 1, len, fp) == len); | 242 | status = status && (fwrite(strVdata(tv), 1, len, fp) == len); |
243 | } else if (tvisint(tv)) { | ||
244 | char buf[LJ_STR_INTBUF]; | ||
245 | char *p = lj_str_bufint(buf, intV(tv)); | ||
246 | size_t len = (size_t)(buf+LJ_STR_INTBUF-p); | ||
247 | status = status && (fwrite(p, 1, len, fp) == len); | ||
243 | } else if (tvisnum(tv)) { | 248 | } else if (tvisnum(tv)) { |
244 | status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0); | 249 | status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0); |
245 | } else { | 250 | } else { |
246 | lj_err_argt(L, cast_int(tv - L->base) + 1, LUA_TSTRING); | 251 | lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING); |
247 | } | 252 | } |
248 | } | 253 | } |
249 | return io_pushresult(L, status, NULL); | 254 | return io_pushresult(L, status, NULL); |
@@ -279,37 +284,42 @@ LJLIB_CF(io_method_seek) | |||
279 | { | 284 | { |
280 | FILE *fp = io_tofile(L)->fp; | 285 | FILE *fp = io_tofile(L)->fp; |
281 | int opt = lj_lib_checkopt(L, 2, 1, "\3set\3cur\3end"); | 286 | int opt = lj_lib_checkopt(L, 2, 1, "\3set\3cur\3end"); |
282 | lua_Number ofs; | 287 | int64_t ofs = 0; |
288 | cTValue *o; | ||
283 | int res; | 289 | int res; |
284 | if (opt == 0) opt = SEEK_SET; | 290 | if (opt == 0) opt = SEEK_SET; |
285 | else if (opt == 1) opt = SEEK_CUR; | 291 | else if (opt == 1) opt = SEEK_CUR; |
286 | else if (opt == 2) opt = SEEK_END; | 292 | else if (opt == 2) opt = SEEK_END; |
287 | lj_lib_opt(L, 3, | 293 | o = L->base+2; |
288 | ofs = lj_lib_checknum(L, 3); | 294 | if (o < L->top) { |
289 | , | 295 | if (tvisint(o)) |
290 | ofs = 0; | 296 | ofs = (int64_t)intV(o); |
291 | ) | 297 | else if (tvisnum(o)) |
298 | ofs = (int64_t)numV(o); | ||
299 | else if (!tvisnil(o)) | ||
300 | lj_err_argt(L, 3, LUA_TNUMBER); | ||
301 | } | ||
292 | #if LJ_TARGET_POSIX | 302 | #if LJ_TARGET_POSIX |
293 | res = fseeko(fp, (int64_t)ofs, opt); | 303 | res = fseeko(fp, ofs, opt); |
294 | #elif _MSC_VER >= 1400 | 304 | #elif _MSC_VER >= 1400 |
295 | res = _fseeki64(fp, (int64_t)ofs, opt); | 305 | res = _fseeki64(fp, ofs, opt); |
296 | #elif defined(__MINGW32__) | 306 | #elif defined(__MINGW32__) |
297 | res = fseeko64(fp, (int64_t)ofs, opt); | 307 | res = fseeko64(fp, ofs, opt); |
298 | #else | 308 | #else |
299 | res = fseek(fp, (long)ofs, opt); | 309 | res = fseek(fp, (long)ofs, opt); |
300 | #endif | 310 | #endif |
301 | if (res) | 311 | if (res) |
302 | return io_pushresult(L, 0, NULL); | 312 | return io_pushresult(L, 0, NULL); |
303 | #if LJ_TARGET_POSIX | 313 | #if LJ_TARGET_POSIX |
304 | ofs = cast_num(ftello(fp)); | 314 | ofs = ftello(fp); |
305 | #elif _MSC_VER >= 1400 | 315 | #elif _MSC_VER >= 1400 |
306 | ofs = cast_num(_ftelli64(fp)); | 316 | ofs = _ftelli64(fp); |
307 | #elif defined(__MINGW32__) | 317 | #elif defined(__MINGW32__) |
308 | ofs = cast_num(ftello64(fp)); | 318 | ofs = ftello64(fp); |
309 | #else | 319 | #else |
310 | ofs = cast_num(ftell(fp)); | 320 | ofs = (int64_t)ftell(fp); |
311 | #endif | 321 | #endif |
312 | setnumV(L->top-1, ofs); | 322 | setint64V(L->top-1, ofs); |
313 | return 1; | 323 | return 1; |
314 | } | 324 | } |
315 | 325 | ||
diff --git a/src/lib_jit.c b/src/lib_jit.c index 66a00523..8f809875 100644 --- a/src/lib_jit.c +++ b/src/lib_jit.c | |||
@@ -70,7 +70,7 @@ LJLIB_CF(jit_off) | |||
70 | LJLIB_CF(jit_flush) | 70 | LJLIB_CF(jit_flush) |
71 | { | 71 | { |
72 | #if LJ_HASJIT | 72 | #if LJ_HASJIT |
73 | if (L->base < L->top && (tvisnum(L->base) || tvisstr(L->base))) { | 73 | if (L->base < L->top && !tvisnil(L->base)) { |
74 | int traceno = lj_lib_checkint(L, 1); | 74 | int traceno = lj_lib_checkint(L, 1); |
75 | luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE); | 75 | luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE); |
76 | return 0; | 76 | return 0; |
@@ -202,8 +202,8 @@ LJLIB_CF(jit_util_funcinfo) | |||
202 | t = tabV(L->top-1); | 202 | t = tabV(L->top-1); |
203 | if (!iscfunc(fn)) | 203 | if (!iscfunc(fn)) |
204 | setintfield(L, t, "ffid", fn->c.ffid); | 204 | setintfield(L, t, "ffid", fn->c.ffid); |
205 | setnumV(lj_tab_setstr(L, t, lj_str_newlit(L, "addr")), | 205 | setintptrV(lj_tab_setstr(L, t, lj_str_newlit(L, "addr")), |
206 | cast_num((intptr_t)fn->c.f)); | 206 | (intptr_t)(void *)fn->c.f); |
207 | setintfield(L, t, "upvalues", fn->c.nupvalues); | 207 | setintfield(L, t, "upvalues", fn->c.nupvalues); |
208 | } | 208 | } |
209 | return 1; | 209 | return 1; |
@@ -233,7 +233,7 @@ LJLIB_CF(jit_util_funck) | |||
233 | ptrdiff_t idx = (ptrdiff_t)lj_lib_checkint(L, 2); | 233 | ptrdiff_t idx = (ptrdiff_t)lj_lib_checkint(L, 2); |
234 | if (idx >= 0) { | 234 | if (idx >= 0) { |
235 | if (idx < (ptrdiff_t)pt->sizekn) { | 235 | if (idx < (ptrdiff_t)pt->sizekn) { |
236 | setnumV(L->top-1, proto_knum(pt, idx)); | 236 | copyTV(L, L->top-1, proto_knumtv(pt, idx)); |
237 | return 1; | 237 | return 1; |
238 | } | 238 | } |
239 | } else { | 239 | } else { |
@@ -358,7 +358,7 @@ LJLIB_CF(jit_util_tracemc) | |||
358 | GCtrace *T = jit_checktrace(L); | 358 | GCtrace *T = jit_checktrace(L); |
359 | if (T && T->mcode != NULL) { | 359 | if (T && T->mcode != NULL) { |
360 | setstrV(L, L->top-1, lj_str_new(L, (const char *)T->mcode, T->szmcode)); | 360 | setstrV(L, L->top-1, lj_str_new(L, (const char *)T->mcode, T->szmcode)); |
361 | setnumV(L->top++, cast_num((intptr_t)T->mcode)); | 361 | setintptrV(L->top++, (intptr_t)(void *)T->mcode); |
362 | setintV(L->top++, T->mcloop); | 362 | setintV(L->top++, T->mcloop); |
363 | return 3; | 363 | return 3; |
364 | } | 364 | } |
@@ -371,7 +371,7 @@ LJLIB_CF(jit_util_traceexitstub) | |||
371 | ExitNo exitno = (ExitNo)lj_lib_checkint(L, 1); | 371 | ExitNo exitno = (ExitNo)lj_lib_checkint(L, 1); |
372 | jit_State *J = L2J(L); | 372 | jit_State *J = L2J(L); |
373 | if (exitno < EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR) { | 373 | if (exitno < EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR) { |
374 | setnumV(L->top-1, cast_num((intptr_t)exitstub_addr(J, exitno))); | 374 | setintptrV(L->top-1, (intptr_t)(void *)exitstub_addr(J, exitno)); |
375 | return 1; | 375 | return 1; |
376 | } | 376 | } |
377 | return 0; | 377 | return 0; |
@@ -382,7 +382,7 @@ LJLIB_CF(jit_util_ircalladdr) | |||
382 | { | 382 | { |
383 | uint32_t idx = (uint32_t)lj_lib_checkint(L, 1); | 383 | uint32_t idx = (uint32_t)lj_lib_checkint(L, 1); |
384 | if (idx < IRCALL__MAX) { | 384 | if (idx < IRCALL__MAX) { |
385 | setnumV(L->top-1, cast_num((uintptr_t)(void *)lj_ir_callinfo[idx].func)); | 385 | setintptrV(L->top-1, (intptr_t)(void *)lj_ir_callinfo[idx].func); |
386 | return 1; | 386 | return 1; |
387 | } | 387 | } |
388 | return 0; | 388 | return 0; |
@@ -462,11 +462,14 @@ static int jitopt_param(jit_State *J, const char *str) | |||
462 | int i; | 462 | int i; |
463 | for (i = 0; i < JIT_P__MAX; i++) { | 463 | for (i = 0; i < JIT_P__MAX; i++) { |
464 | size_t len = *(const uint8_t *)lst; | 464 | size_t len = *(const uint8_t *)lst; |
465 | TValue tv; | ||
466 | lua_assert(len != 0); | 465 | lua_assert(len != 0); |
467 | if (strncmp(str, lst+1, len) == 0 && str[len] == '=' && | 466 | if (strncmp(str, lst+1, len) == 0 && str[len] == '=') { |
468 | lj_str_numconv(&str[len+1], &tv)) { | 467 | int32_t n = 0; |
469 | J->param[i] = lj_num2int(tv.n); | 468 | const char *p = &str[len+1]; |
469 | while (*p >= '0' && *p <= '9') | ||
470 | n = n*10 + (*p++ - '0'); | ||
471 | if (*p) return 0; /* Malformed number. */ | ||
472 | J->param[i] = n; | ||
470 | if (i == JIT_P_hotloop) | 473 | if (i == JIT_P_hotloop) |
471 | lj_dispatch_init_hotcount(J2G(J)); | 474 | lj_dispatch_init_hotcount(J2G(J)); |
472 | return 1; /* Ok. */ | 475 | return 1; /* Ok. */ |
diff --git a/src/lib_math.c b/src/lib_math.c index 79d91e73..46841e08 100644 --- a/src/lib_math.c +++ b/src/lib_math.c | |||
@@ -129,7 +129,7 @@ static void random_init(RandomState *rs, double d) | |||
129 | LJLIB_PUSH(top-2) /* Upvalue holds userdata with RandomState. */ | 129 | LJLIB_PUSH(top-2) /* Upvalue holds userdata with RandomState. */ |
130 | LJLIB_CF(math_random) LJLIB_REC(.) | 130 | LJLIB_CF(math_random) LJLIB_REC(.) |
131 | { | 131 | { |
132 | int n = cast_int(L->top - L->base); | 132 | int n = (int)(L->top - L->base); |
133 | RandomState *rs = (RandomState *)(uddata(udataV(lj_lib_upvalue(L, 1)))); | 133 | RandomState *rs = (RandomState *)(uddata(udataV(lj_lib_upvalue(L, 1)))); |
134 | U64double u; | 134 | U64double u; |
135 | double d; | 135 | double d; |
diff --git a/src/lib_string.c b/src/lib_string.c index 0b1c98a9..61f73060 100644 --- a/src/lib_string.c +++ b/src/lib_string.c | |||
@@ -61,7 +61,7 @@ LJLIB_ASM(string_byte) LJLIB_REC(string_range 0) | |||
61 | 61 | ||
62 | LJLIB_ASM(string_char) | 62 | LJLIB_ASM(string_char) |
63 | { | 63 | { |
64 | int i, nargs = cast_int(L->top - L->base); | 64 | int i, nargs = (int)(L->top - L->base); |
65 | char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, (size_t)nargs); | 65 | char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, (size_t)nargs); |
66 | for (i = 1; i <= nargs; i++) { | 66 | for (i = 1; i <= nargs; i++) { |
67 | int32_t k = lj_lib_checkint(L, i); | 67 | int32_t k = lj_lib_checkint(L, i); |
@@ -737,7 +737,7 @@ LJLIB_CF(string_format) | |||
737 | tv.n = lj_lib_checknum(L, arg); | 737 | tv.n = lj_lib_checknum(L, arg); |
738 | if (LJ_UNLIKELY((tv.u32.hi << 1) >= 0xffe00000)) { | 738 | if (LJ_UNLIKELY((tv.u32.hi << 1) >= 0xffe00000)) { |
739 | /* Canonicalize output of non-finite values. */ | 739 | /* Canonicalize output of non-finite values. */ |
740 | char *p, nbuf[LUAI_MAXNUMBER2STR]; | 740 | char *p, nbuf[LJ_STR_NUMBUF]; |
741 | size_t len = lj_str_bufnum(nbuf, &tv); | 741 | size_t len = lj_str_bufnum(nbuf, &tv); |
742 | if (strfrmt[-1] == 'E' || strfrmt[-1] == 'G') { | 742 | if (strfrmt[-1] == 'E' || strfrmt[-1] == 'G') { |
743 | nbuf[len-3] = nbuf[len-3] - 0x20; | 743 | nbuf[len-3] = nbuf[len-3] - 0x20; |
@@ -801,7 +801,7 @@ LUALIB_API int luaopen_string(lua_State *L) | |||
801 | g = G(L); | 801 | g = G(L); |
802 | setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt)); | 802 | setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt)); |
803 | settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1)); | 803 | settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1)); |
804 | mt->nomm = cast_byte(~(1u<<MM_index)); | 804 | mt->nomm = (uint8_t)(~(1u<<MM_index)); |
805 | return 1; | 805 | return 1; |
806 | } | 806 | } |
807 | 807 | ||
diff --git a/src/lib_table.c b/src/lib_table.c index 8ae54167..fab6b1f4 100644 --- a/src/lib_table.c +++ b/src/lib_table.c | |||
@@ -82,8 +82,10 @@ LJLIB_CF(table_maxn) | |||
82 | } | 82 | } |
83 | node = noderef(t->node); | 83 | node = noderef(t->node); |
84 | for (i = (ptrdiff_t)t->hmask; i >= 0; i--) | 84 | for (i = (ptrdiff_t)t->hmask; i >= 0; i--) |
85 | if (tvisnum(&node[i].key) && numV(&node[i].key) > m) | 85 | if (tvisnumber(&node[i].key)) { |
86 | m = numV(&node[i].key); | 86 | lua_Number n = numberVnum(&node[i].key); |
87 | if (n > m) m = n; | ||
88 | } | ||
87 | setnumV(L->top-1, m); | 89 | setnumV(L->top-1, m); |
88 | return 1; | 90 | return 1; |
89 | } | 91 | } |
@@ -154,7 +156,7 @@ LJLIB_CF(table_concat) | |||
154 | cTValue *o; | 156 | cTValue *o; |
155 | lua_rawgeti(L, 1, i); | 157 | lua_rawgeti(L, 1, i); |
156 | o = L->top-1; | 158 | o = L->top-1; |
157 | if (!(tvisstr(o) || tvisnum(o))) | 159 | if (!(tvisstr(o) || tvisnumber(o))) |
158 | lj_err_callerv(L, LJ_ERR_TABCAT, typename(o), i); | 160 | lj_err_callerv(L, LJ_ERR_TABCAT, typename(o), i); |
159 | luaL_addvalue(&b); | 161 | luaL_addvalue(&b); |
160 | if (i++ == e) break; | 162 | if (i++ == e) break; |
diff --git a/src/lj_api.c b/src/lj_api.c index 92699078..f33748ce 100644 --- a/src/lj_api.c +++ b/src/lj_api.c | |||
@@ -115,7 +115,7 @@ LUA_API void lua_xmove(lua_State *from, lua_State *to, int n) | |||
115 | 115 | ||
116 | LUA_API int lua_gettop(lua_State *L) | 116 | LUA_API int lua_gettop(lua_State *L) |
117 | { | 117 | { |
118 | return cast_int(L->top - L->base); | 118 | return (int)(L->top - L->base); |
119 | } | 119 | } |
120 | 120 | ||
121 | LUA_API void lua_settop(lua_State *L, int idx) | 121 | LUA_API void lua_settop(lua_State *L, int idx) |
@@ -186,7 +186,7 @@ LUA_API void lua_pushvalue(lua_State *L, int idx) | |||
186 | LUA_API int lua_type(lua_State *L, int idx) | 186 | LUA_API int lua_type(lua_State *L, int idx) |
187 | { | 187 | { |
188 | cTValue *o = index2adr(L, idx); | 188 | cTValue *o = index2adr(L, idx); |
189 | if (tvisnum(o)) { | 189 | if (tvisnumber(o)) { |
190 | return LUA_TNUMBER; | 190 | return LUA_TNUMBER; |
191 | #if LJ_64 | 191 | #if LJ_64 |
192 | } else if (tvislightud(o)) { | 192 | } else if (tvislightud(o)) { |
@@ -234,13 +234,13 @@ LUA_API int lua_isnumber(lua_State *L, int idx) | |||
234 | { | 234 | { |
235 | cTValue *o = index2adr(L, idx); | 235 | cTValue *o = index2adr(L, idx); |
236 | TValue tmp; | 236 | TValue tmp; |
237 | return (tvisnum(o) || (tvisstr(o) && lj_str_tonum(strV(o), &tmp))); | 237 | return (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), &tmp))); |
238 | } | 238 | } |
239 | 239 | ||
240 | LUA_API int lua_isstring(lua_State *L, int idx) | 240 | LUA_API int lua_isstring(lua_State *L, int idx) |
241 | { | 241 | { |
242 | cTValue *o = index2adr(L, idx); | 242 | cTValue *o = index2adr(L, idx); |
243 | return (tvisstr(o) || tvisnum(o)); | 243 | return (tvisstr(o) || tvisnumber(o)); |
244 | } | 244 | } |
245 | 245 | ||
246 | LUA_API int lua_isuserdata(lua_State *L, int idx) | 246 | LUA_API int lua_isuserdata(lua_State *L, int idx) |
@@ -260,8 +260,10 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2) | |||
260 | { | 260 | { |
261 | cTValue *o1 = index2adr(L, idx1); | 261 | cTValue *o1 = index2adr(L, idx1); |
262 | cTValue *o2 = index2adr(L, idx2); | 262 | cTValue *o2 = index2adr(L, idx2); |
263 | if (tvisnum(o1) && tvisnum(o2)) { | 263 | if (tvisint(o1) && tvisint(o2)) { |
264 | return numV(o1) == numV(o2); | 264 | return intV(o1) == intV(o2); |
265 | } else if (tvisnumber(o1) && tvisnumber(o2)) { | ||
266 | return numberVnum(o1) == numberVnum(o2); | ||
265 | } else if (itype(o1) != itype(o2)) { | 267 | } else if (itype(o1) != itype(o2)) { |
266 | return 0; | 268 | return 0; |
267 | } else if (tvispri(o1)) { | 269 | } else if (tvispri(o1)) { |
@@ -293,8 +295,10 @@ LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2) | |||
293 | cTValue *o2 = index2adr(L, idx2); | 295 | cTValue *o2 = index2adr(L, idx2); |
294 | if (o1 == niltv(L) || o2 == niltv(L)) { | 296 | if (o1 == niltv(L) || o2 == niltv(L)) { |
295 | return 0; | 297 | return 0; |
296 | } else if (tvisnum(o1) && tvisnum(o2)) { | 298 | } else if (tvisint(o1) && tvisint(o2)) { |
297 | return numV(o1) < numV(o2); | 299 | return intV(o1) < intV(o2); |
300 | } else if (tvisnumber(o1) && tvisnumber(o2)) { | ||
301 | return numberVnum(o1) < numberVnum(o2); | ||
298 | } else { | 302 | } else { |
299 | TValue *base = lj_meta_comp(L, o1, o2, 0); | 303 | TValue *base = lj_meta_comp(L, o1, o2, 0); |
300 | if ((uintptr_t)base <= 1) { | 304 | if ((uintptr_t)base <= 1) { |
@@ -312,8 +316,8 @@ LUA_API lua_Number lua_tonumber(lua_State *L, int idx) | |||
312 | { | 316 | { |
313 | cTValue *o = index2adr(L, idx); | 317 | cTValue *o = index2adr(L, idx); |
314 | TValue tmp; | 318 | TValue tmp; |
315 | if (LJ_LIKELY(tvisnum(o))) | 319 | if (LJ_LIKELY(tvisnumber(o))) |
316 | return numV(o); | 320 | return numberVnum(o); |
317 | else if (tvisstr(o) && lj_str_tonum(strV(o), &tmp)) | 321 | else if (tvisstr(o) && lj_str_tonum(strV(o), &tmp)) |
318 | return numV(&tmp); | 322 | return numV(&tmp); |
319 | else | 323 | else |
@@ -324,8 +328,8 @@ LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx) | |||
324 | { | 328 | { |
325 | cTValue *o = index2adr(L, idx); | 329 | cTValue *o = index2adr(L, idx); |
326 | TValue tmp; | 330 | TValue tmp; |
327 | if (tvisnum(o)) | 331 | if (LJ_LIKELY(tvisnumber(o))) |
328 | return numV(o); | 332 | return numberVnum(o); |
329 | else if (!(tvisstr(o) && lj_str_tonum(strV(o), &tmp))) | 333 | else if (!(tvisstr(o) && lj_str_tonum(strV(o), &tmp))) |
330 | lj_err_argt(L, idx, LUA_TNUMBER); | 334 | lj_err_argt(L, idx, LUA_TNUMBER); |
331 | return numV(&tmp); | 335 | return numV(&tmp); |
@@ -335,8 +339,8 @@ LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def) | |||
335 | { | 339 | { |
336 | cTValue *o = index2adr(L, idx); | 340 | cTValue *o = index2adr(L, idx); |
337 | TValue tmp; | 341 | TValue tmp; |
338 | if (tvisnum(o)) | 342 | if (LJ_LIKELY(tvisnumber(o))) |
339 | return numV(o); | 343 | return numberVnum(o); |
340 | else if (tvisnil(o)) | 344 | else if (tvisnil(o)) |
341 | return def; | 345 | return def; |
342 | else if (!(tvisstr(o) && lj_str_tonum(strV(o), &tmp))) | 346 | else if (!(tvisstr(o) && lj_str_tonum(strV(o), &tmp))) |
@@ -349,12 +353,17 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx) | |||
349 | cTValue *o = index2adr(L, idx); | 353 | cTValue *o = index2adr(L, idx); |
350 | TValue tmp; | 354 | TValue tmp; |
351 | lua_Number n; | 355 | lua_Number n; |
352 | if (LJ_LIKELY(tvisnum(o))) | 356 | if (LJ_LIKELY(tvisint(o))) { |
357 | return intV(o); | ||
358 | } else if (LJ_LIKELY(tvisnum(o))) { | ||
353 | n = numV(o); | 359 | n = numV(o); |
354 | else if (tvisstr(o) && lj_str_tonum(strV(o), &tmp)) | 360 | } else { |
361 | if (!(tvisstr(o) && lj_str_tonumber(strV(o), &tmp))) | ||
362 | return 0; | ||
363 | if (tvisint(&tmp)) | ||
364 | return (lua_Integer)intV(&tmp); | ||
355 | n = numV(&tmp); | 365 | n = numV(&tmp); |
356 | else | 366 | } |
357 | return 0; | ||
358 | #if LJ_64 | 367 | #if LJ_64 |
359 | return (lua_Integer)n; | 368 | return (lua_Integer)n; |
360 | #else | 369 | #else |
@@ -367,12 +376,17 @@ LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx) | |||
367 | cTValue *o = index2adr(L, idx); | 376 | cTValue *o = index2adr(L, idx); |
368 | TValue tmp; | 377 | TValue tmp; |
369 | lua_Number n; | 378 | lua_Number n; |
370 | if (LJ_LIKELY(tvisnum(o))) | 379 | if (LJ_LIKELY(tvisint(o))) { |
380 | return intV(o); | ||
381 | } else if (LJ_LIKELY(tvisnum(o))) { | ||
371 | n = numV(o); | 382 | n = numV(o); |
372 | else if (tvisstr(o) && lj_str_tonum(strV(o), &tmp)) | 383 | } else { |
384 | if (!(tvisstr(o) && lj_str_tonumber(strV(o), &tmp))) | ||
385 | lj_err_argt(L, idx, LUA_TNUMBER); | ||
386 | if (tvisint(&tmp)) | ||
387 | return (lua_Integer)intV(&tmp); | ||
373 | n = numV(&tmp); | 388 | n = numV(&tmp); |
374 | else | 389 | } |
375 | lj_err_argt(L, idx, LUA_TNUMBER); | ||
376 | #if LJ_64 | 390 | #if LJ_64 |
377 | return (lua_Integer)n; | 391 | return (lua_Integer)n; |
378 | #else | 392 | #else |
@@ -385,14 +399,19 @@ LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def) | |||
385 | cTValue *o = index2adr(L, idx); | 399 | cTValue *o = index2adr(L, idx); |
386 | TValue tmp; | 400 | TValue tmp; |
387 | lua_Number n; | 401 | lua_Number n; |
388 | if (LJ_LIKELY(tvisnum(o))) | 402 | if (LJ_LIKELY(tvisint(o))) { |
403 | return intV(o); | ||
404 | } else if (LJ_LIKELY(tvisnum(o))) { | ||
389 | n = numV(o); | 405 | n = numV(o); |
390 | else if (tvisnil(o)) | 406 | } else if (tvisnil(o)) { |
391 | return def; | 407 | return def; |
392 | else if (tvisstr(o) && lj_str_tonum(strV(o), &tmp)) | 408 | } else { |
409 | if (!(tvisstr(o) && lj_str_tonumber(strV(o), &tmp))) | ||
410 | lj_err_argt(L, idx, LUA_TNUMBER); | ||
411 | if (tvisint(&tmp)) | ||
412 | return (lua_Integer)intV(&tmp); | ||
393 | n = numV(&tmp); | 413 | n = numV(&tmp); |
394 | else | 414 | } |
395 | lj_err_argt(L, idx, LUA_TNUMBER); | ||
396 | #if LJ_64 | 415 | #if LJ_64 |
397 | return (lua_Integer)n; | 416 | return (lua_Integer)n; |
398 | #else | 417 | #else |
@@ -412,10 +431,10 @@ LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len) | |||
412 | GCstr *s; | 431 | GCstr *s; |
413 | if (LJ_LIKELY(tvisstr(o))) { | 432 | if (LJ_LIKELY(tvisstr(o))) { |
414 | s = strV(o); | 433 | s = strV(o); |
415 | } else if (tvisnum(o)) { | 434 | } else if (tvisnumber(o)) { |
416 | lj_gc_check(L); | 435 | lj_gc_check(L); |
417 | o = index2adr(L, idx); /* GC may move the stack. */ | 436 | o = index2adr(L, idx); /* GC may move the stack. */ |
418 | s = lj_str_fromnum(L, &o->n); | 437 | s = lj_str_fromnumber(L, o); |
419 | } else { | 438 | } else { |
420 | if (len != NULL) *len = 0; | 439 | if (len != NULL) *len = 0; |
421 | return NULL; | 440 | return NULL; |
@@ -430,10 +449,10 @@ LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len) | |||
430 | GCstr *s; | 449 | GCstr *s; |
431 | if (LJ_LIKELY(tvisstr(o))) { | 450 | if (LJ_LIKELY(tvisstr(o))) { |
432 | s = strV(o); | 451 | s = strV(o); |
433 | } else if (tvisnum(o)) { | 452 | } else if (tvisnumber(o)) { |
434 | lj_gc_check(L); | 453 | lj_gc_check(L); |
435 | o = index2adr(L, idx); /* GC may move the stack. */ | 454 | o = index2adr(L, idx); /* GC may move the stack. */ |
436 | s = lj_str_fromnum(L, &o->n); | 455 | s = lj_str_fromnumber(L, o); |
437 | } else { | 456 | } else { |
438 | lj_err_argt(L, idx, LUA_TSTRING); | 457 | lj_err_argt(L, idx, LUA_TSTRING); |
439 | } | 458 | } |
@@ -451,10 +470,10 @@ LUALIB_API const char *luaL_optlstring(lua_State *L, int idx, | |||
451 | } else if (tvisnil(o)) { | 470 | } else if (tvisnil(o)) { |
452 | if (len != NULL) *len = def ? strlen(def) : 0; | 471 | if (len != NULL) *len = def ? strlen(def) : 0; |
453 | return def; | 472 | return def; |
454 | } else if (tvisnum(o)) { | 473 | } else if (tvisnumber(o)) { |
455 | lj_gc_check(L); | 474 | lj_gc_check(L); |
456 | o = index2adr(L, idx); /* GC may move the stack. */ | 475 | o = index2adr(L, idx); /* GC may move the stack. */ |
457 | s = lj_str_fromnum(L, &o->n); | 476 | s = lj_str_fromnumber(L, o); |
458 | } else { | 477 | } else { |
459 | lj_err_argt(L, idx, LUA_TSTRING); | 478 | lj_err_argt(L, idx, LUA_TSTRING); |
460 | } | 479 | } |
@@ -484,8 +503,8 @@ LUA_API size_t lua_objlen(lua_State *L, int idx) | |||
484 | return cast(size_t, lj_tab_len(tabV(o))); | 503 | return cast(size_t, lj_tab_len(tabV(o))); |
485 | else if (tvisudata(o)) | 504 | else if (tvisudata(o)) |
486 | return udataV(o)->len; | 505 | return udataV(o)->len; |
487 | else if (tvisnum(o)) | 506 | else if (tvisnumber(o)) |
488 | return lj_str_fromnum(L, &o->n)->len; | 507 | return lj_str_fromnumber(L, o)->len; |
489 | else | 508 | else |
490 | return 0; | 509 | return 0; |
491 | } | 510 | } |
@@ -551,7 +570,7 @@ LUA_API void lua_pushnumber(lua_State *L, lua_Number n) | |||
551 | 570 | ||
552 | LUA_API void lua_pushinteger(lua_State *L, lua_Integer n) | 571 | LUA_API void lua_pushinteger(lua_State *L, lua_Integer n) |
553 | { | 572 | { |
554 | setnumV(L->top, cast_num(n)); | 573 | setintptrV(L->top, n); |
555 | incr_top(L); | 574 | incr_top(L); |
556 | } | 575 | } |
557 | 576 | ||
@@ -687,7 +706,7 @@ LUA_API void lua_concat(lua_State *L, int n) | |||
687 | L->top -= n; | 706 | L->top -= n; |
688 | break; | 707 | break; |
689 | } | 708 | } |
690 | n -= cast_int(L->top - top); | 709 | n -= (int)(L->top - top); |
691 | L->top = top+2; | 710 | L->top = top+2; |
692 | lj_vm_call(L, top, 1+1); | 711 | lj_vm_call(L, top, 1+1); |
693 | L->top--; | 712 | L->top--; |
@@ -1085,7 +1104,7 @@ LUA_API int lua_yield(lua_State *L, int nresults) | |||
1085 | setcont(top+1, lj_cont_hook); | 1104 | setcont(top+1, lj_cont_hook); |
1086 | setframe_pc(top+1, cframe_pc(cf)-1); | 1105 | setframe_pc(top+1, cframe_pc(cf)-1); |
1087 | setframe_gc(top+2, obj2gco(L)); | 1106 | setframe_gc(top+2, obj2gco(L)); |
1088 | top[2].fr.tp.ftsz = cast_int((char *)(top+3)-(char *)L->base)+FRAME_CONT; | 1107 | top[2].fr.tp.ftsz = (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT; |
1089 | L->top = L->base = top+3; | 1108 | L->top = L->base = top+3; |
1090 | } | 1109 | } |
1091 | L->cframe = NULL; | 1110 | L->cframe = NULL; |
@@ -1160,10 +1179,10 @@ LUA_API int lua_gc(lua_State *L, int what, int data) | |||
1160 | lj_gc_fullgc(L); | 1179 | lj_gc_fullgc(L); |
1161 | break; | 1180 | break; |
1162 | case LUA_GCCOUNT: | 1181 | case LUA_GCCOUNT: |
1163 | res = cast_int(g->gc.total >> 10); | 1182 | res = (int)(g->gc.total >> 10); |
1164 | break; | 1183 | break; |
1165 | case LUA_GCCOUNTB: | 1184 | case LUA_GCCOUNTB: |
1166 | res = cast_int(g->gc.total & 0x3ff); | 1185 | res = (int)(g->gc.total & 0x3ff); |
1167 | break; | 1186 | break; |
1168 | case LUA_GCSTEP: { | 1187 | case LUA_GCSTEP: { |
1169 | MSize a = (MSize)data << 10; | 1188 | MSize a = (MSize)data << 10; |
@@ -1176,11 +1195,11 @@ LUA_API int lua_gc(lua_State *L, int what, int data) | |||
1176 | break; | 1195 | break; |
1177 | } | 1196 | } |
1178 | case LUA_GCSETPAUSE: | 1197 | case LUA_GCSETPAUSE: |
1179 | res = cast_int(g->gc.pause); | 1198 | res = (int)(g->gc.pause); |
1180 | g->gc.pause = (MSize)data; | 1199 | g->gc.pause = (MSize)data; |
1181 | break; | 1200 | break; |
1182 | case LUA_GCSETSTEPMUL: | 1201 | case LUA_GCSETSTEPMUL: |
1183 | res = cast_int(g->gc.stepmul); | 1202 | res = (int)(g->gc.stepmul); |
1184 | g->gc.stepmul = (MSize)data; | 1203 | g->gc.stepmul = (MSize)data; |
1185 | break; | 1204 | break; |
1186 | default: | 1205 | default: |
diff --git a/src/lj_ctype.c b/src/lj_ctype.c index 585039ef..956f0a09 100644 --- a/src/lj_ctype.c +++ b/src/lj_ctype.c | |||
@@ -522,7 +522,7 @@ GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned) | |||
522 | /* Convert complex to string with 'i' or 'I' suffix. */ | 522 | /* Convert complex to string with 'i' or 'I' suffix. */ |
523 | GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size) | 523 | GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size) |
524 | { | 524 | { |
525 | char buf[2*LUAI_MAXNUMBER2STR+2+1]; | 525 | char buf[2*LJ_STR_NUMBUF+2+1]; |
526 | TValue re, im; | 526 | TValue re, im; |
527 | size_t len; | 527 | size_t len; |
528 | if (size == 2*sizeof(double)) { | 528 | if (size == 2*sizeof(double)) { |
diff --git a/src/lj_def.h b/src/lj_def.h index ac457cf5..f6f03318 100644 --- a/src/lj_def.h +++ b/src/lj_def.h | |||
@@ -81,7 +81,6 @@ typedef unsigned __int32 uintptr_t; | |||
81 | #define U64x(hi, lo) (((uint64_t)0x##hi << 32) + (uint64_t)0x##lo) | 81 | #define U64x(hi, lo) (((uint64_t)0x##hi << 32) + (uint64_t)0x##lo) |
82 | #define cast_byte(i) cast(uint8_t, (i)) | 82 | #define cast_byte(i) cast(uint8_t, (i)) |
83 | #define cast_num(i) cast(lua_Number, (i)) | 83 | #define cast_num(i) cast(lua_Number, (i)) |
84 | #define cast_int(i) cast(int, (i)) | ||
85 | #define i32ptr(p) ((int32_t)(intptr_t)(void *)(p)) | 84 | #define i32ptr(p) ((int32_t)(intptr_t)(void *)(p)) |
86 | #define u32ptr(p) ((uint32_t)(intptr_t)(void *)(p)) | 85 | #define u32ptr(p) ((uint32_t)(intptr_t)(void *)(p)) |
87 | 86 | ||
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c index a8aa0731..0b14e21c 100644 --- a/src/lj_dispatch.c +++ b/src/lj_dispatch.c | |||
@@ -320,7 +320,7 @@ static void callhook(lua_State *L, int event, BCLine line) | |||
320 | ar.event = event; | 320 | ar.event = event; |
321 | ar.currentline = line; | 321 | ar.currentline = line; |
322 | /* Top frame, nextframe = NULL. */ | 322 | /* Top frame, nextframe = NULL. */ |
323 | ar.i_ci = cast_int((L->base-1) - tvref(L->stack)); | 323 | ar.i_ci = (int)((L->base-1) - tvref(L->stack)); |
324 | lj_state_checkstack(L, 1+LUA_MINSTACK); | 324 | lj_state_checkstack(L, 1+LUA_MINSTACK); |
325 | hook_enter(g); | 325 | hook_enter(g); |
326 | hookf(L, &ar); | 326 | hookf(L, &ar); |
diff --git a/src/lj_err.c b/src/lj_err.c index 12f32af2..2503c218 100644 --- a/src/lj_err.c +++ b/src/lj_err.c | |||
@@ -397,7 +397,7 @@ cTValue *lj_err_getframe(lua_State *L, int level, int *size) | |||
397 | if (frame_gc(frame) == obj2gco(L)) | 397 | if (frame_gc(frame) == obj2gco(L)) |
398 | level++; /* Skip dummy frames. See lj_meta_call(). */ | 398 | level++; /* Skip dummy frames. See lj_meta_call(). */ |
399 | if (level-- == 0) { | 399 | if (level-- == 0) { |
400 | *size = cast_int(nextframe - frame); | 400 | *size = (int)(nextframe - frame); |
401 | return frame; /* Level found. */ | 401 | return frame; /* Level found. */ |
402 | } | 402 | } |
403 | nextframe = frame; | 403 | nextframe = frame; |
@@ -418,7 +418,7 @@ LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar) | |||
418 | int size; | 418 | int size; |
419 | cTValue *frame = lj_err_getframe(L, level, &size); | 419 | cTValue *frame = lj_err_getframe(L, level, &size); |
420 | if (frame) { | 420 | if (frame) { |
421 | ar->i_ci = (size << 16) + cast_int(frame - tvref(L->stack)); | 421 | ar->i_ci = (size << 16) + (int)(frame - tvref(L->stack)); |
422 | return 1; | 422 | return 1; |
423 | } else { | 423 | } else { |
424 | ar->i_ci = level - size; | 424 | ar->i_ci = level - size; |
@@ -486,7 +486,7 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
486 | if (cframe_canyield(cf)) { /* Resume? */ | 486 | if (cframe_canyield(cf)) { /* Resume? */ |
487 | if (errcode) { | 487 | if (errcode) { |
488 | L->cframe = NULL; | 488 | L->cframe = NULL; |
489 | L->status = cast_byte(errcode); | 489 | L->status = (uint8_t)errcode; |
490 | } | 490 | } |
491 | return cf; | 491 | return cf; |
492 | } | 492 | } |
@@ -534,7 +534,7 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
534 | #define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */ | 534 | #define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */ |
535 | #define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (_Unwind_Exception_Class)(c)) | 535 | #define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (_Unwind_Exception_Class)(c)) |
536 | #define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff) | 536 | #define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff) |
537 | #define LJ_UEXCLASS_ERRCODE(cl) (cast_int((cl) & 0xff)) | 537 | #define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff)) |
538 | 538 | ||
539 | /* DWARF2 personality handler referenced from interpreter .eh_frame. */ | 539 | /* DWARF2 personality handler referenced from interpreter .eh_frame. */ |
540 | LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions, | 540 | LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions, |
@@ -642,7 +642,7 @@ extern __DestructExceptionObject(EXCEPTION_RECORD *rec, int nothrow); | |||
642 | #define LJ_EXCODE ((DWORD)0xe24c4a00) | 642 | #define LJ_EXCODE ((DWORD)0xe24c4a00) |
643 | #define LJ_EXCODE_MAKE(c) (LJ_EXCODE | (DWORD)(c)) | 643 | #define LJ_EXCODE_MAKE(c) (LJ_EXCODE | (DWORD)(c)) |
644 | #define LJ_EXCODE_CHECK(cl) (((cl) ^ LJ_EXCODE) <= 0xff) | 644 | #define LJ_EXCODE_CHECK(cl) (((cl) ^ LJ_EXCODE) <= 0xff) |
645 | #define LJ_EXCODE_ERRCODE(cl) (cast_int((cl) & 0xff)) | 645 | #define LJ_EXCODE_ERRCODE(cl) ((int)((cl) & 0xff)) |
646 | 646 | ||
647 | /* Win64 exception handler for interpreter frame. */ | 647 | /* Win64 exception handler for interpreter frame. */ |
648 | LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec, | 648 | LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec, |
@@ -945,7 +945,7 @@ LJ_NORET LJ_NOINLINE static void err_argmsg(lua_State *L, int narg, | |||
945 | const char *fname = "?"; | 945 | const char *fname = "?"; |
946 | const char *ftype = getfuncname(L, L->base - 1, &fname); | 946 | const char *ftype = getfuncname(L, L->base - 1, &fname); |
947 | if (narg < 0 && narg > LUA_REGISTRYINDEX) | 947 | if (narg < 0 && narg > LUA_REGISTRYINDEX) |
948 | narg = cast_int(L->top - L->base) + narg + 1; | 948 | narg = (int)(L->top - L->base) + narg + 1; |
949 | if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */ | 949 | if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */ |
950 | msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg); | 950 | msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg); |
951 | else | 951 | else |
diff --git a/src/lj_func.c b/src/lj_func.c index 83dab3b1..b3564091 100644 --- a/src/lj_func.c +++ b/src/lj_func.c | |||
@@ -98,7 +98,7 @@ GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env) | |||
98 | GCfunc *fn = cast(GCfunc *, lj_mem_newgco(L, sizeCfunc(nelems))); | 98 | GCfunc *fn = cast(GCfunc *, lj_mem_newgco(L, sizeCfunc(nelems))); |
99 | fn->c.gct = ~LJ_TFUNC; | 99 | fn->c.gct = ~LJ_TFUNC; |
100 | fn->c.ffid = FF_C; | 100 | fn->c.ffid = FF_C; |
101 | fn->c.nupvalues = cast_byte(nelems); | 101 | fn->c.nupvalues = (uint8_t)nelems; |
102 | /* NOBARRIER: The GCfunc is new (marked white). */ | 102 | /* NOBARRIER: The GCfunc is new (marked white). */ |
103 | setmref(fn->c.pc, &G(L)->bc_cfunc_ext); | 103 | setmref(fn->c.pc, &G(L)->bc_cfunc_ext); |
104 | setgcref(fn->c.env, obj2gco(env)); | 104 | setgcref(fn->c.env, obj2gco(env)); |
@@ -110,7 +110,7 @@ GCfunc *lj_func_newL(lua_State *L, GCproto *pt, GCtab *env) | |||
110 | GCfunc *fn = cast(GCfunc *, lj_mem_newgco(L, sizeLfunc((MSize)pt->sizeuv))); | 110 | GCfunc *fn = cast(GCfunc *, lj_mem_newgco(L, sizeLfunc((MSize)pt->sizeuv))); |
111 | fn->l.gct = ~LJ_TFUNC; | 111 | fn->l.gct = ~LJ_TFUNC; |
112 | fn->l.ffid = FF_LUA; | 112 | fn->l.ffid = FF_LUA; |
113 | fn->l.nupvalues = cast_byte(pt->sizeuv); | 113 | fn->l.nupvalues = (uint8_t)pt->sizeuv; |
114 | /* NOBARRIER: Really a setgcref. But the GCfunc is new (marked white). */ | 114 | /* NOBARRIER: Really a setgcref. But the GCfunc is new (marked white). */ |
115 | setmref(fn->l.pc, proto_bc(pt)); | 115 | setmref(fn->l.pc, proto_bc(pt)); |
116 | setgcref(fn->l.env, obj2gco(env)); | 116 | setgcref(fn->l.env, obj2gco(env)); |
diff --git a/src/lj_lex.c b/src/lj_lex.c index ac0d1e95..78458572 100644 --- a/src/lj_lex.c +++ b/src/lj_lex.c | |||
@@ -170,10 +170,15 @@ static void lex_number(LexState *ls, TValue *tv) | |||
170 | if (c == 'I') { /* Return cdata holding a complex number. */ | 170 | if (c == 'I') { /* Return cdata holding a complex number. */ |
171 | GCcdata *cd = lj_cdata_new_(ls->L, CTID_COMPLEX_DOUBLE, 2*sizeof(double)); | 171 | GCcdata *cd = lj_cdata_new_(ls->L, CTID_COMPLEX_DOUBLE, 2*sizeof(double)); |
172 | ((double *)cdataptr(cd))[0] = 0; | 172 | ((double *)cdataptr(cd))[0] = 0; |
173 | ((double *)cdataptr(cd))[1] = tv->n; | 173 | ((double *)cdataptr(cd))[1] = numberVnum(tv); |
174 | lj_parse_keepcdata(ls, tv, cd); | 174 | lj_parse_keepcdata(ls, tv, cd); |
175 | } | 175 | } |
176 | #endif | 176 | #endif |
177 | if (LJ_DUALNUM && tvisnum(tv)) { | ||
178 | int32_t k = lj_num2int(numV(tv)); | ||
179 | if ((lua_Number)k == numV(tv)) /* -0 cannot end up here. */ | ||
180 | setintV(tv, k); | ||
181 | } | ||
177 | return; | 182 | return; |
178 | } | 183 | } |
179 | lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER); | 184 | lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER); |
@@ -506,7 +511,7 @@ void lj_lex_init(lua_State *L) | |||
506 | for (i = 0; i < TK_RESERVED; i++) { | 511 | for (i = 0; i < TK_RESERVED; i++) { |
507 | GCstr *s = lj_str_newz(L, tokennames[i]); | 512 | GCstr *s = lj_str_newz(L, tokennames[i]); |
508 | fixstring(s); /* Reserved words are never collected. */ | 513 | fixstring(s); /* Reserved words are never collected. */ |
509 | s->reserved = cast_byte(i+1); | 514 | s->reserved = (uint8_t)(i+1); |
510 | } | 515 | } |
511 | } | 516 | } |
512 | 517 | ||
diff --git a/src/lj_lib.c b/src/lj_lib.c index a6681f2b..930e59a0 100644 --- a/src/lj_lib.c +++ b/src/lj_lib.c | |||
@@ -135,8 +135,8 @@ GCstr *lj_lib_checkstr(lua_State *L, int narg) | |||
135 | if (o < L->top) { | 135 | if (o < L->top) { |
136 | if (LJ_LIKELY(tvisstr(o))) { | 136 | if (LJ_LIKELY(tvisstr(o))) { |
137 | return strV(o); | 137 | return strV(o); |
138 | } else if (tvisnum(o)) { | 138 | } else if (tvisnumber(o)) { |
139 | GCstr *s = lj_str_fromnum(L, &o->n); | 139 | GCstr *s = lj_str_fromnumber(L, o); |
140 | setstrV(L, o, s); | 140 | setstrV(L, o, s); |
141 | return s; | 141 | return s; |
142 | } | 142 | } |
@@ -155,14 +155,18 @@ lua_Number lj_lib_checknum(lua_State *L, int narg) | |||
155 | { | 155 | { |
156 | TValue *o = L->base + narg-1; | 156 | TValue *o = L->base + narg-1; |
157 | if (!(o < L->top && | 157 | if (!(o < L->top && |
158 | (tvisnum(o) || (tvisstr(o) && lj_str_tonum(strV(o), o))))) | 158 | (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o))))) |
159 | lj_err_argt(L, narg, LUA_TNUMBER); | 159 | lj_err_argt(L, narg, LUA_TNUMBER); |
160 | return numV(o); | 160 | return numberVnum(o); |
161 | } | 161 | } |
162 | 162 | ||
163 | int32_t lj_lib_checkint(lua_State *L, int narg) | 163 | int32_t lj_lib_checkint(lua_State *L, int narg) |
164 | { | 164 | { |
165 | return lj_num2int(lj_lib_checknum(L, narg)); | 165 | TValue *o = L->base + narg-1; |
166 | if (!(o < L->top && | ||
167 | (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o))))) | ||
168 | lj_err_argt(L, narg, LUA_TNUMBER); | ||
169 | return numberVint(o); | ||
166 | } | 170 | } |
167 | 171 | ||
168 | int32_t lj_lib_optint(lua_State *L, int narg, int32_t def) | 172 | int32_t lj_lib_optint(lua_State *L, int narg, int32_t def) |
diff --git a/src/lj_lib.h b/src/lj_lib.h index b9bd4c2d..ae4be384 100644 --- a/src/lj_lib.h +++ b/src/lj_lib.h | |||
@@ -41,10 +41,6 @@ LJ_FUNC GCtab *lj_lib_checktab(lua_State *L, int narg); | |||
41 | LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg); | 41 | LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg); |
42 | LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst); | 42 | LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst); |
43 | 43 | ||
44 | #define lj_lib_opt(L, narg, gotarg, noarg) \ | ||
45 | { TValue *_o = L->base + (narg)-1; \ | ||
46 | if (_o < L->top && !tvisnil(_o)) { gotarg } else { noarg } } | ||
47 | |||
48 | /* Avoid including lj_frame.h. */ | 44 | /* Avoid including lj_frame.h. */ |
49 | #define lj_lib_upvalue(L, n) \ | 45 | #define lj_lib_upvalue(L, n) \ |
50 | (&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1]) | 46 | (&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1]) |
diff --git a/src/lj_meta.c b/src/lj_meta.c index 0df1de08..32024e85 100644 --- a/src/lj_meta.c +++ b/src/lj_meta.c | |||
@@ -44,7 +44,7 @@ cTValue *lj_meta_cache(GCtab *mt, MMS mm, GCstr *name) | |||
44 | cTValue *mo = lj_tab_getstr(mt, name); | 44 | cTValue *mo = lj_tab_getstr(mt, name); |
45 | lua_assert(mm <= MM_FAST); | 45 | lua_assert(mm <= MM_FAST); |
46 | if (!mo || tvisnil(mo)) { /* No metamethod? */ | 46 | if (!mo || tvisnil(mo)) { /* No metamethod? */ |
47 | mt->nomm |= cast_byte(1u<<mm); /* Set negative cache flag. */ | 47 | mt->nomm |= (uint8_t)(1u<<mm); /* Set negative cache flag. */ |
48 | return NULL; | 48 | return NULL; |
49 | } | 49 | } |
50 | return mo; | 50 | return mo; |
@@ -156,6 +156,8 @@ static cTValue *str2num(cTValue *o, TValue *n) | |||
156 | { | 156 | { |
157 | if (tvisnum(o)) | 157 | if (tvisnum(o)) |
158 | return o; | 158 | return o; |
159 | else if (tvisint(o)) | ||
160 | return (setnumV(n, (lua_Number)intV(o)), n); | ||
159 | else if (tvisstr(o) && lj_str_tonum(strV(o), n)) | 161 | else if (tvisstr(o) && lj_str_tonum(strV(o), n)) |
160 | return n; | 162 | return n; |
161 | else | 163 | else |
@@ -192,8 +194,8 @@ static LJ_AINLINE int tostring(lua_State *L, TValue *o) | |||
192 | { | 194 | { |
193 | if (tvisstr(o)) { | 195 | if (tvisstr(o)) { |
194 | return 1; | 196 | return 1; |
195 | } else if (tvisnum(o)) { | 197 | } else if (tvisnumber(o)) { |
196 | setstrV(L, o, lj_str_fromnum(L, &o->n)); | 198 | setstrV(L, o, lj_str_fromnumber(L, o)); |
197 | return 1; | 199 | return 1; |
198 | } else { | 200 | } else { |
199 | return 0; | 201 | return 0; |
@@ -205,12 +207,12 @@ TValue *lj_meta_cat(lua_State *L, TValue *top, int left) | |||
205 | { | 207 | { |
206 | do { | 208 | do { |
207 | int n = 1; | 209 | int n = 1; |
208 | if (!(tvisstr(top-1) || tvisnum(top-1)) || !tostring(L, top)) { | 210 | if (!(tvisstr(top-1) || tvisnumber(top-1)) || !tostring(L, top)) { |
209 | cTValue *mo = lj_meta_lookup(L, top-1, MM_concat); | 211 | cTValue *mo = lj_meta_lookup(L, top-1, MM_concat); |
210 | if (tvisnil(mo)) { | 212 | if (tvisnil(mo)) { |
211 | mo = lj_meta_lookup(L, top, MM_concat); | 213 | mo = lj_meta_lookup(L, top, MM_concat); |
212 | if (tvisnil(mo)) { | 214 | if (tvisnil(mo)) { |
213 | if (tvisstr(top-1) || tvisnum(top-1)) top++; | 215 | if (tvisstr(top-1) || tvisnumber(top-1)) top++; |
214 | lj_err_optype(L, top-1, LJ_ERR_OPCAT); | 216 | lj_err_optype(L, top-1, LJ_ERR_OPCAT); |
215 | return NULL; /* unreachable */ | 217 | return NULL; /* unreachable */ |
216 | } | 218 | } |
diff --git a/src/lj_obj.c b/src/lj_obj.c index 60f5dd3a..1476f0b2 100644 --- a/src/lj_obj.c +++ b/src/lj_obj.c | |||
@@ -27,9 +27,9 @@ int lj_obj_equal(cTValue *o1, cTValue *o2) | |||
27 | return 1; | 27 | return 1; |
28 | if (!tvisnum(o1)) | 28 | if (!tvisnum(o1)) |
29 | return gcrefeq(o1->gcr, o2->gcr); | 29 | return gcrefeq(o1->gcr, o2->gcr); |
30 | } else if (!tvisnum(o1) || !tvisnum(o2)) { | 30 | } else if (!tvisnumber(o1) || !tvisnumber(o2)) { |
31 | return 0; | 31 | return 0; |
32 | } | 32 | } |
33 | return numV(o1) == numV(o2); | 33 | return numberVnum(o1) == numberVnum(o2); |
34 | } | 34 | } |
35 | 35 | ||
diff --git a/src/lj_obj.h b/src/lj_obj.h index 1bd50809..88289f3e 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
@@ -140,7 +140,10 @@ typedef LJ_ALIGN(8) union TValue { | |||
140 | lua_Number n; /* Number object overlaps split tag/value object. */ | 140 | lua_Number n; /* Number object overlaps split tag/value object. */ |
141 | struct { | 141 | struct { |
142 | LJ_ENDIAN_LOHI( | 142 | LJ_ENDIAN_LOHI( |
143 | GCRef gcr; /* GCobj reference (if any). */ | 143 | union { |
144 | GCRef gcr; /* GCobj reference (if any). */ | ||
145 | int32_t i; /* Integer value. */ | ||
146 | }; | ||
144 | , uint32_t it; /* Internal object tag. Must overlap MSW of number. */ | 147 | , uint32_t it; /* Internal object tag. Must overlap MSW of number. */ |
145 | ) | 148 | ) |
146 | }; | 149 | }; |
@@ -180,6 +183,7 @@ typedef const TValue cTValue; | |||
180 | ** lightuserdata | itype | void * | (32 bit platforms) | 183 | ** lightuserdata | itype | void * | (32 bit platforms) |
181 | ** lightuserdata |ffff| void * | (64 bit platforms, 47 bit pointers) | 184 | ** lightuserdata |ffff| void * | (64 bit platforms, 47 bit pointers) |
182 | ** GC objects | itype | GCRef | | 185 | ** GC objects | itype | GCRef | |
186 | ** int (LJ_DUALNUM)| itype | int | | ||
183 | ** number -------double------ | 187 | ** number -------double------ |
184 | ** | 188 | ** |
185 | ** ORDER LJ_T | 189 | ** ORDER LJ_T |
@@ -203,6 +207,7 @@ typedef const TValue cTValue; | |||
203 | /* This is just the canonical number type used in some places. */ | 207 | /* This is just the canonical number type used in some places. */ |
204 | #define LJ_TNUMX (~13u) | 208 | #define LJ_TNUMX (~13u) |
205 | 209 | ||
210 | /* Integers have itype == LJ_TISNUM doubles have itype < LJ_TISNUM */ | ||
206 | #if LJ_64 | 211 | #if LJ_64 |
207 | #define LJ_TISNUM 0xfffeffffu | 212 | #define LJ_TISNUM 0xfffeffffu |
208 | #else | 213 | #else |
@@ -322,6 +327,8 @@ typedef struct GCproto { | |||
322 | gcref(mref((pt)->k, GCRef)[(idx)])) | 327 | gcref(mref((pt)->k, GCRef)[(idx)])) |
323 | #define proto_knum(pt, idx) \ | 328 | #define proto_knum(pt, idx) \ |
324 | check_exp((uintptr_t)(idx) < (pt)->sizekn, mref((pt)->k, lua_Number)[(idx)]) | 329 | check_exp((uintptr_t)(idx) < (pt)->sizekn, mref((pt)->k, lua_Number)[(idx)]) |
330 | #define proto_knumtv(pt, idx) \ | ||
331 | check_exp((uintptr_t)(idx) < (pt)->sizekn, &mref((pt)->k, TValue)[(idx)]) | ||
325 | #define proto_bc(pt) ((BCIns *)((char *)(pt) + sizeof(GCproto))) | 332 | #define proto_bc(pt) ((BCIns *)((char *)(pt) + sizeof(GCproto))) |
326 | #define proto_bcpos(pt, pc) ((BCPos)((pc) - proto_bc(pt))) | 333 | #define proto_bcpos(pt, pc) ((BCPos)((pc) - proto_bc(pt))) |
327 | #define proto_uv(pt) (mref((pt)->uv, uint16_t)) | 334 | #define proto_uv(pt) (mref((pt)->uv, uint16_t)) |
@@ -650,7 +657,9 @@ typedef union GCobj { | |||
650 | #define tviscdata(o) (itype(o) == LJ_TCDATA) | 657 | #define tviscdata(o) (itype(o) == LJ_TCDATA) |
651 | #define tvistab(o) (itype(o) == LJ_TTAB) | 658 | #define tvistab(o) (itype(o) == LJ_TTAB) |
652 | #define tvisudata(o) (itype(o) == LJ_TUDATA) | 659 | #define tvisudata(o) (itype(o) == LJ_TUDATA) |
653 | #define tvisnum(o) (itype(o) <= LJ_TISNUM) | 660 | #define tvisnumber(o) (itype(o) <= LJ_TISNUM) |
661 | #define tvisint(o) (LJ_DUALNUM && itype(o) == LJ_TISNUM) | ||
662 | #define tvisnum(o) (itype(o) < LJ_TISNUM) | ||
654 | 663 | ||
655 | #define tvistruecond(o) (itype(o) < LJ_TISTRUECOND) | 664 | #define tvistruecond(o) (itype(o) < LJ_TISTRUECOND) |
656 | #define tvispri(o) (itype(o) >= LJ_TISPRI) | 665 | #define tvispri(o) (itype(o) >= LJ_TISPRI) |
@@ -659,6 +668,11 @@ typedef union GCobj { | |||
659 | 668 | ||
660 | /* Special macros to test numbers for NaN, +0, -0, +1 and raw equality. */ | 669 | /* Special macros to test numbers for NaN, +0, -0, +1 and raw equality. */ |
661 | #define tvisnan(o) ((o)->n != (o)->n) | 670 | #define tvisnan(o) ((o)->n != (o)->n) |
671 | #if LJ_64 | ||
672 | #define tviszero(o) (((o)->u64 << 1) == 0) | ||
673 | #else | ||
674 | #define tviszero(o) (((o)->u32.lo | ((o)->u32.hi << 1)) == 0) | ||
675 | #endif | ||
662 | #define tvispzero(o) ((o)->u64 == 0) | 676 | #define tvispzero(o) ((o)->u64 == 0) |
663 | #define tvismzero(o) ((o)->u64 == U64x(80000000,00000000)) | 677 | #define tvismzero(o) ((o)->u64 == U64x(80000000,00000000)) |
664 | #define tvispone(o) ((o)->u64 == U64x(3ff00000,00000000)) | 678 | #define tvispone(o) ((o)->u64 == U64x(3ff00000,00000000)) |
@@ -667,9 +681,9 @@ typedef union GCobj { | |||
667 | /* Macros to convert type ids. */ | 681 | /* Macros to convert type ids. */ |
668 | #if LJ_64 | 682 | #if LJ_64 |
669 | #define itypemap(o) \ | 683 | #define itypemap(o) \ |
670 | (tvisnum(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o)) | 684 | (tvisnumber(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o)) |
671 | #else | 685 | #else |
672 | #define itypemap(o) (tvisnum(o) ? ~LJ_TNUMX : ~itype(o)) | 686 | #define itypemap(o) (tvisnumber(o) ? ~LJ_TNUMX : ~itype(o)) |
673 | #endif | 687 | #endif |
674 | 688 | ||
675 | /* Macros to get tagged values. */ | 689 | /* Macros to get tagged values. */ |
@@ -690,6 +704,7 @@ typedef union GCobj { | |||
690 | #define tabV(o) check_exp(tvistab(o), &gcval(o)->tab) | 704 | #define tabV(o) check_exp(tvistab(o), &gcval(o)->tab) |
691 | #define udataV(o) check_exp(tvisudata(o), &gcval(o)->ud) | 705 | #define udataV(o) check_exp(tvisudata(o), &gcval(o)->ud) |
692 | #define numV(o) check_exp(tvisnum(o), (o)->n) | 706 | #define numV(o) check_exp(tvisnum(o), (o)->n) |
707 | #define intV(o) check_exp(tvisint(o), (int32_t)(o)->i) | ||
693 | 708 | ||
694 | /* Macros to set tagged values. */ | 709 | /* Macros to set tagged values. */ |
695 | #define setitype(o, i) ((o)->it = (i)) | 710 | #define setitype(o, i) ((o)->it = (i)) |
@@ -741,7 +756,29 @@ define_setV(setudataV, GCudata, LJ_TUDATA) | |||
741 | #define setnanV(o) ((o)->u64 = U64x(fff80000,00000000)) | 756 | #define setnanV(o) ((o)->u64 = U64x(fff80000,00000000)) |
742 | #define setpinfV(o) ((o)->u64 = U64x(7ff00000,00000000)) | 757 | #define setpinfV(o) ((o)->u64 = U64x(7ff00000,00000000)) |
743 | #define setminfV(o) ((o)->u64 = U64x(fff00000,00000000)) | 758 | #define setminfV(o) ((o)->u64 = U64x(fff00000,00000000)) |
744 | #define setintV(o, i) ((o)->n = cast_num((int32_t)(i))) | 759 | |
760 | static LJ_AINLINE void setintV(TValue *o, int32_t i) | ||
761 | { | ||
762 | #if LJ_DUALNUM | ||
763 | o->i = (uint32_t)i; setitype(o, LJ_TISNUM); | ||
764 | #else | ||
765 | o->n = (lua_Number)i; | ||
766 | #endif | ||
767 | } | ||
768 | |||
769 | static LJ_AINLINE void setint64V(TValue *o, int64_t i) | ||
770 | { | ||
771 | if (LJ_DUALNUM && LJ_LIKELY(i == (int64_t)(int32_t)i)) | ||
772 | setintV(o, (int32_t)i); | ||
773 | else | ||
774 | setnumV(o, (lua_Number)i); | ||
775 | } | ||
776 | |||
777 | #if LJ_64 | ||
778 | #define setintptrV(o, i) setint64V((o), (i)) | ||
779 | #else | ||
780 | #define setintptrV(o, i) setintV((o), (i)) | ||
781 | #endif | ||
745 | 782 | ||
746 | /* Copy tagged values. */ | 783 | /* Copy tagged values. */ |
747 | static LJ_AINLINE void copyTV(lua_State *L, TValue *o1, const TValue *o2) | 784 | static LJ_AINLINE void copyTV(lua_State *L, TValue *o1, const TValue *o2) |
@@ -774,6 +811,22 @@ static LJ_AINLINE uint64_t lj_num2u64(lua_Number n) | |||
774 | return (uint64_t)n; | 811 | return (uint64_t)n; |
775 | } | 812 | } |
776 | 813 | ||
814 | static LJ_AINLINE int32_t numberVint(cTValue *o) | ||
815 | { | ||
816 | if (LJ_LIKELY(tvisint(o))) | ||
817 | return intV(o); | ||
818 | else | ||
819 | return lj_num2int(numV(o)); | ||
820 | } | ||
821 | |||
822 | static LJ_AINLINE lua_Number numberVnum(cTValue *o) | ||
823 | { | ||
824 | if (LJ_UNLIKELY(tvisint(o))) | ||
825 | return (lua_Number)intV(o); | ||
826 | else | ||
827 | return numV(o); | ||
828 | } | ||
829 | |||
777 | /* -- Miscellaneous object handling --------------------------------------- */ | 830 | /* -- Miscellaneous object handling --------------------------------------- */ |
778 | 831 | ||
779 | /* Names and maps for internal and external object tags. */ | 832 | /* Names and maps for internal and external object tags. */ |
diff --git a/src/lj_parse.c b/src/lj_parse.c index 0f5577e1..858891d2 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
@@ -73,7 +73,8 @@ typedef struct ExpDesc { | |||
73 | #define expr_isnumk_nojump(e) (expr_isnumk(e) && !expr_hasjump(e)) | 73 | #define expr_isnumk_nojump(e) (expr_isnumk(e) && !expr_hasjump(e)) |
74 | #define expr_isstrk(e) ((e)->k == VKSTR) | 74 | #define expr_isstrk(e) ((e)->k == VKSTR) |
75 | 75 | ||
76 | #define expr_numV(e) check_exp(expr_isnumk((e)), numV(&(e)->u.nval)) | 76 | #define expr_numtv(e) check_exp(expr_isnumk((e)), &(e)->u.nval) |
77 | #define expr_numberV(e) numberVnum(expr_numtv((e))) | ||
77 | 78 | ||
78 | /* Initialize expression. */ | 79 | /* Initialize expression. */ |
79 | static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info) | 80 | static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info) |
@@ -83,6 +84,13 @@ static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info) | |||
83 | e->f = e->t = NO_JMP; | 84 | e->f = e->t = NO_JMP; |
84 | } | 85 | } |
85 | 86 | ||
87 | /* Check number constant for +-0. */ | ||
88 | static int expr_numiszero(ExpDesc *e) | ||
89 | { | ||
90 | TValue *o = expr_numtv(e); | ||
91 | return tvisint(o) ? (intV(o) == 0) : tviszero(o); | ||
92 | } | ||
93 | |||
86 | /* Per-function linked list of scope blocks. */ | 94 | /* Per-function linked list of scope blocks. */ |
87 | typedef struct FuncScope { | 95 | typedef struct FuncScope { |
88 | struct FuncScope *prev; /* Link to outer scope. */ | 96 | struct FuncScope *prev; /* Link to outer scope. */ |
@@ -174,16 +182,19 @@ LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what) | |||
174 | /* Return bytecode encoding for primitive constant. */ | 182 | /* Return bytecode encoding for primitive constant. */ |
175 | #define const_pri(e) check_exp((e)->k <= VKTRUE, (e)->k) | 183 | #define const_pri(e) check_exp((e)->k <= VKTRUE, (e)->k) |
176 | 184 | ||
185 | #define tvhaskslot(o) ((o)->u32.hi == 0) | ||
186 | #define tvkslot(o) ((o)->u32.lo) | ||
187 | |||
177 | /* Add a number constant. */ | 188 | /* Add a number constant. */ |
178 | static BCReg const_num(FuncState *fs, ExpDesc *e) | 189 | static BCReg const_num(FuncState *fs, ExpDesc *e) |
179 | { | 190 | { |
180 | lua_State *L = fs->L; | 191 | lua_State *L = fs->L; |
181 | TValue *val; | 192 | TValue *o; |
182 | lua_assert(expr_isnumk(e)); | 193 | lua_assert(expr_isnumk(e)); |
183 | val = lj_tab_set(L, fs->kt, &e->u.nval); | 194 | o = lj_tab_set(L, fs->kt, &e->u.nval); |
184 | if (tvisnum(val)) | 195 | if (tvhaskslot(o)) |
185 | return val->u32.lo; | 196 | return tvkslot(o); |
186 | val->u64 = fs->nkn; | 197 | o->u64 = fs->nkn; |
187 | return fs->nkn++; | 198 | return fs->nkn++; |
188 | } | 199 | } |
189 | 200 | ||
@@ -191,13 +202,13 @@ static BCReg const_num(FuncState *fs, ExpDesc *e) | |||
191 | static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype) | 202 | static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype) |
192 | { | 203 | { |
193 | lua_State *L = fs->L; | 204 | lua_State *L = fs->L; |
194 | TValue o, *val; | 205 | TValue key, *o; |
195 | setgcV(L, &o, gc, itype); | 206 | setgcV(L, &key, gc, itype); |
196 | /* NOBARRIER: the key is new or kept alive. */ | 207 | /* NOBARRIER: the key is new or kept alive. */ |
197 | val = lj_tab_set(L, fs->kt, &o); | 208 | o = lj_tab_set(L, fs->kt, &key); |
198 | if (tvisnum(val)) | 209 | if (tvhaskslot(o)) |
199 | return val->u32.lo; | 210 | return tvkslot(o); |
200 | val->u64 = fs->nkgc; | 211 | o->u64 = fs->nkgc; |
201 | return fs->nkgc++; | 212 | return fs->nkgc++; |
202 | } | 213 | } |
203 | 214 | ||
@@ -344,7 +355,7 @@ static void bcreg_bump(FuncState *fs, BCReg n) | |||
344 | if (sz > fs->framesize) { | 355 | if (sz > fs->framesize) { |
345 | if (sz >= LJ_MAX_SLOTS) | 356 | if (sz >= LJ_MAX_SLOTS) |
346 | err_syntax(fs->ls, LJ_ERR_XSLOTS); | 357 | err_syntax(fs->ls, LJ_ERR_XSLOTS); |
347 | fs->framesize = cast_byte(sz); | 358 | fs->framesize = (uint8_t)sz; |
348 | } | 359 | } |
349 | } | 360 | } |
350 | 361 | ||
@@ -478,11 +489,18 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg) | |||
478 | if (e->k == VKSTR) { | 489 | if (e->k == VKSTR) { |
479 | ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e)); | 490 | ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e)); |
480 | } else if (e->k == VKNUM) { | 491 | } else if (e->k == VKNUM) { |
481 | lua_Number n = expr_numV(e); | 492 | #if LJ_DUALNUM |
493 | cTValue *tv = expr_numtv(e); | ||
494 | if (tvisint(tv) && checki16(intV(tv))) | ||
495 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)intV(tv)); | ||
496 | else | ||
497 | #else | ||
498 | lua_Number n = expr_numberV(e); | ||
482 | int32_t k = lj_num2int(n); | 499 | int32_t k = lj_num2int(n); |
483 | if (checki16(k) && n == cast_num(k)) | 500 | if (checki16(k) && n == (lua_Number)k) |
484 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); | 501 | ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k); |
485 | else | 502 | else |
503 | #endif | ||
486 | ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); | 504 | ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); |
487 | #if LJ_HASFFI | 505 | #if LJ_HASFFI |
488 | } else if (e->k == VKCDATA) { | 506 | } else if (e->k == VKCDATA) { |
@@ -720,10 +738,19 @@ static void bcemit_branch_f(FuncState *fs, ExpDesc *e) | |||
720 | static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) | 738 | static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) |
721 | { | 739 | { |
722 | TValue o; | 740 | TValue o; |
741 | lua_Number n; | ||
723 | if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0; | 742 | if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0; |
724 | setnumV(&o, lj_vm_foldarith(expr_numV(e1), expr_numV(e2), (int)opr-OPR_ADD)); | 743 | n = lj_vm_foldarith(expr_numberV(e1), expr_numberV(e2), (int)opr-OPR_ADD); |
744 | setnumV(&o, n); | ||
725 | if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ | 745 | if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */ |
726 | setnumV(&e1->u.nval, numV(&o)); | 746 | if (LJ_DUALNUM) { |
747 | int32_t k = lj_num2int(n); | ||
748 | if ((lua_Number)k == n) { | ||
749 | setintV(&e1->u.nval, k); | ||
750 | return 1; | ||
751 | } | ||
752 | } | ||
753 | setnumV(&e1->u.nval, n); | ||
727 | return 1; | 754 | return 1; |
728 | } | 755 | } |
729 | 756 | ||
@@ -900,9 +927,18 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) | |||
900 | return; | 927 | return; |
901 | } else | 928 | } else |
902 | #endif | 929 | #endif |
903 | if (expr_isnumk(e) && expr_numV(e) != 0) { /* Avoid folding to -0. */ | 930 | if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */ |
904 | e->u.nval.u64 ^= U64x(80000000,00000000); | 931 | TValue *o = expr_numtv(e); |
905 | return; | 932 | if (tvisint(o)) { |
933 | int32_t k = intV(o); | ||
934 | if (k == -k) | ||
935 | setnumV(o, -(lua_Number)k); | ||
936 | else | ||
937 | setintV(o, -k); | ||
938 | } else { | ||
939 | o->u64 ^= U64x(80000000,00000000); | ||
940 | return; | ||
941 | } | ||
906 | } | 942 | } |
907 | } | 943 | } |
908 | expr_toanyreg(fs, e); | 944 | expr_toanyreg(fs, e); |
@@ -986,7 +1022,7 @@ static void var_new(LexState *ls, BCReg n, GCstr *name) | |||
986 | static void var_add(LexState *ls, BCReg nvars) | 1022 | static void var_add(LexState *ls, BCReg nvars) |
987 | { | 1023 | { |
988 | FuncState *fs = ls->fs; | 1024 | FuncState *fs = ls->fs; |
989 | fs->nactvar = cast_byte(fs->nactvar + nvars); | 1025 | fs->nactvar = (uint8_t)(fs->nactvar + nvars); |
990 | for (; nvars; nvars--) | 1026 | for (; nvars; nvars--) |
991 | var_get(ls, fs, fs->nactvar - nvars).startpc = fs->pc; | 1027 | var_get(ls, fs, fs->nactvar - nvars).startpc = fs->pc; |
992 | } | 1028 | } |
@@ -1094,16 +1130,33 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr) | |||
1094 | kt = fs->kt; | 1130 | kt = fs->kt; |
1095 | array = tvref(kt->array); | 1131 | array = tvref(kt->array); |
1096 | for (i = 0; i < kt->asize; i++) | 1132 | for (i = 0; i < kt->asize; i++) |
1097 | if (tvisnum(&array[i])) | 1133 | if (tvhaskslot(&array[i])) { |
1098 | ((lua_Number *)kptr)[array[i].u32.lo] = cast_num(i); | 1134 | TValue *tv = &((TValue *)kptr)[tvkslot(&array[i])]; |
1135 | if (LJ_DUALNUM) | ||
1136 | setintV(tv, (int32_t)i); | ||
1137 | else | ||
1138 | setnumV(tv, (lua_Number)i); | ||
1139 | } | ||
1099 | node = noderef(kt->node); | 1140 | node = noderef(kt->node); |
1100 | hmask = kt->hmask; | 1141 | hmask = kt->hmask; |
1101 | for (i = 0; i <= hmask; i++) { | 1142 | for (i = 0; i <= hmask; i++) { |
1102 | Node *n = &node[i]; | 1143 | Node *n = &node[i]; |
1103 | if (tvisnum(&n->val)) { | 1144 | if (tvhaskslot(&n->val)) { |
1104 | ptrdiff_t kidx = (ptrdiff_t)n->val.u32.lo; | 1145 | ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val); |
1146 | lua_assert(!tvisint(&n->key)); | ||
1105 | if (tvisnum(&n->key)) { | 1147 | if (tvisnum(&n->key)) { |
1106 | ((lua_Number *)kptr)[kidx] = numV(&n->key); | 1148 | TValue *tv = &((TValue *)kptr)[kidx]; |
1149 | if (LJ_DUALNUM) { | ||
1150 | lua_Number nn = numV(&n->key); | ||
1151 | int32_t k = lj_num2int(nn); | ||
1152 | lua_assert(!tvismzero(&n->key)); | ||
1153 | if ((lua_Number)k == nn) | ||
1154 | setintV(tv, k); | ||
1155 | else | ||
1156 | *tv = n->key; | ||
1157 | } else { | ||
1158 | *tv = n->key; | ||
1159 | } | ||
1107 | } else { | 1160 | } else { |
1108 | GCobj *o = gcV(&n->key); | 1161 | GCobj *o = gcV(&n->key); |
1109 | setgcref(((GCRef *)kptr)[~kidx], o); | 1162 | setgcref(((GCRef *)kptr)[~kidx], o); |
@@ -1286,12 +1339,22 @@ static void expr_index(FuncState *fs, ExpDesc *t, ExpDesc *e) | |||
1286 | /* Already called: expr_toval(fs, e). */ | 1339 | /* Already called: expr_toval(fs, e). */ |
1287 | t->k = VINDEXED; | 1340 | t->k = VINDEXED; |
1288 | if (expr_isnumk(e)) { | 1341 | if (expr_isnumk(e)) { |
1289 | lua_Number n = expr_numV(e); | 1342 | #if LJ_DUALNUM |
1343 | if (tvisint(expr_numtv(e))) { | ||
1344 | int32_t k = intV(expr_numtv(e)); | ||
1345 | if (checku8(k)) { | ||
1346 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ | ||
1347 | return; | ||
1348 | } | ||
1349 | } | ||
1350 | #else | ||
1351 | lua_Number n = expr_numberV(e); | ||
1290 | int32_t k = lj_num2int(n); | 1352 | int32_t k = lj_num2int(n); |
1291 | if (checku8(k) && n == cast_num(k)) { | 1353 | if (checku8(k) && n == (lua_Number)k) { |
1292 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ | 1354 | t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */ |
1293 | return; | 1355 | return; |
1294 | } | 1356 | } |
1357 | #endif | ||
1295 | } else if (expr_isstrk(e)) { | 1358 | } else if (expr_isstrk(e)) { |
1296 | BCReg idx = const_str(fs, e); | 1359 | BCReg idx = const_str(fs, e); |
1297 | if (idx <= BCMAX_C) { | 1360 | if (idx <= BCMAX_C) { |
@@ -1331,8 +1394,8 @@ static void expr_kvalue(TValue *v, ExpDesc *e) | |||
1331 | setgcref(v->gcr, obj2gco(e->u.sval)); | 1394 | setgcref(v->gcr, obj2gco(e->u.sval)); |
1332 | setitype(v, LJ_TSTR); | 1395 | setitype(v, LJ_TSTR); |
1333 | } else { | 1396 | } else { |
1334 | lua_assert(e->k == VKNUM); | 1397 | lua_assert(tvisnumber(expr_numtv(e))); |
1335 | setnumV(v, expr_numV(e)); | 1398 | *v = *expr_numtv(e); |
1336 | } | 1399 | } |
1337 | } | 1400 | } |
1338 | 1401 | ||
@@ -1357,7 +1420,7 @@ static void expr_table(LexState *ls, ExpDesc *e) | |||
1357 | if (ls->token == '[') { | 1420 | if (ls->token == '[') { |
1358 | expr_bracket(ls, &key); /* Already calls expr_toval. */ | 1421 | expr_bracket(ls, &key); /* Already calls expr_toval. */ |
1359 | if (!expr_isk(&key)) expr_index(fs, e, &key); | 1422 | if (!expr_isk(&key)) expr_index(fs, e, &key); |
1360 | if (expr_isnumk(&key) && expr_numV(&key) == 0) needarr = 1; else nhash++; | 1423 | if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++; |
1361 | lex_check(ls, '='); | 1424 | lex_check(ls, '='); |
1362 | } else if (ls->token == TK_name && lj_lex_lookahead(ls) == '=') { | 1425 | } else if (ls->token == TK_name && lj_lex_lookahead(ls) == '=') { |
1363 | expr_str(ls, &key); | 1426 | expr_str(ls, &key); |
@@ -2119,10 +2182,10 @@ static int predict_next(LexState *ls, FuncState *fs, BCPos pc) | |||
2119 | case BC_GGET: | 2182 | case BC_GGET: |
2120 | /* There's no inverse index (yet), so lookup the strings. */ | 2183 | /* There's no inverse index (yet), so lookup the strings. */ |
2121 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs")); | 2184 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs")); |
2122 | if (o && tvisnum(o) && o->u32.lo == bc_d(ins)) | 2185 | if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) |
2123 | return 1; | 2186 | return 1; |
2124 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next")); | 2187 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next")); |
2125 | if (o && tvisnum(o) && o->u32.lo == bc_d(ins)) | 2188 | if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) |
2126 | return 1; | 2189 | return 1; |
2127 | return 0; | 2190 | return 0; |
2128 | default: | 2191 | default: |
diff --git a/src/lj_snap.c b/src/lj_snap.c index fa2a20e0..e04da81f 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
@@ -289,7 +289,7 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
289 | Reg r = regsp_reg(rs); | 289 | Reg r = regsp_reg(rs); |
290 | lua_assert(ra_hasreg(r)); | 290 | lua_assert(ra_hasreg(r)); |
291 | if (irt_isinteger(t)) { | 291 | if (irt_isinteger(t)) { |
292 | setintV(o, ex->gpr[r-RID_MIN_GPR]); | 292 | setintV(o, (int32_t)ex->gpr[r-RID_MIN_GPR]); |
293 | } else if (irt_isnum(t)) { | 293 | } else if (irt_isnum(t)) { |
294 | setnumV(o, ex->fpr[r-RID_MIN_FPR]); | 294 | setnumV(o, ex->fpr[r-RID_MIN_FPR]); |
295 | #if LJ_64 | 295 | #if LJ_64 |
diff --git a/src/lj_str.c b/src/lj_str.c index 20049ab3..dea02858 100644 --- a/src/lj_str.c +++ b/src/lj_str.c | |||
@@ -172,13 +172,25 @@ void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s) | |||
172 | /* Convert string object to number. */ | 172 | /* Convert string object to number. */ |
173 | int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n) | 173 | int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n) |
174 | { | 174 | { |
175 | int ok = lj_str_numconv(strdata(str), n); | ||
176 | if (ok && tvisint(n)) | ||
177 | setnumV(n, (lua_Number)intV(n)); | ||
178 | return ok; | ||
179 | } | ||
180 | |||
181 | int LJ_FASTCALL lj_str_tonumber(GCstr *str, TValue *n) | ||
182 | { | ||
175 | return lj_str_numconv(strdata(str), n); | 183 | return lj_str_numconv(strdata(str), n); |
176 | } | 184 | } |
177 | 185 | ||
178 | /* Convert string to number. */ | 186 | /* Convert string to number. */ |
179 | int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n) | 187 | int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n) |
180 | { | 188 | { |
189 | #if LJ_DUALNUM | ||
190 | int sign = 0; | ||
191 | #else | ||
181 | lua_Number sign = 1; | 192 | lua_Number sign = 1; |
193 | #endif | ||
182 | const uint8_t *p = (const uint8_t *)s; | 194 | const uint8_t *p = (const uint8_t *)s; |
183 | while (lj_char_isspace(*p)) p++; | 195 | while (lj_char_isspace(*p)) p++; |
184 | if (*p == '-') { p++; sign = -1; } else if (*p == '+') { p++; } | 196 | if (*p == '-') { p++; sign = -1; } else if (*p == '+') { p++; } |
@@ -189,21 +201,34 @@ int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n) | |||
189 | if (!lj_char_isxdigit(*p)) | 201 | if (!lj_char_isxdigit(*p)) |
190 | return 0; /* Don't accept '0x' without hex digits. */ | 202 | return 0; /* Don't accept '0x' without hex digits. */ |
191 | do { | 203 | do { |
192 | if (k >= 0x10000000) goto parsedbl; | 204 | if (k >= 0x10000000u) goto parsedbl; |
193 | k = (k << 4) + (*p & 15u); | 205 | k = (k << 4) + (*p & 15u); |
194 | if (!lj_char_isdigit(*p)) k += 9; | 206 | if (!lj_char_isdigit(*p)) k += 9; |
195 | p++; | 207 | p++; |
196 | } while (lj_char_isxdigit(*p)); | 208 | } while (lj_char_isxdigit(*p)); |
197 | } else { | 209 | } else { |
198 | while ((uint32_t)(*p - '0') < 10) { | 210 | while ((uint32_t)(*p - '0') < 10) { |
199 | if (k >= 0x19999999) goto parsedbl; | 211 | if (LJ_UNLIKELY(k >= 429496729) && (k != 429496729 || *p > '5')) |
212 | goto parsedbl; | ||
200 | k = k * 10u + (uint32_t)(*p++ - '0'); | 213 | k = k * 10u + (uint32_t)(*p++ - '0'); |
201 | } | 214 | } |
202 | } | 215 | } |
203 | while (LJ_UNLIKELY(lj_char_isspace(*p))) p++; | 216 | while (LJ_UNLIKELY(lj_char_isspace(*p))) p++; |
204 | if (LJ_LIKELY(*p == '\0')) { | 217 | if (LJ_LIKELY(*p == '\0')) { |
205 | setnumV(n, sign * cast_num(k)); | 218 | #if LJ_DUALNUM |
219 | if (!sign) { | ||
220 | if (k < 0x80000000u) { | ||
221 | setintV(n, (int32_t)k); | ||
222 | return 1; | ||
223 | } | ||
224 | } else if (k <= 0x80000000u) { | ||
225 | setintV(n, -(int32_t)k); | ||
226 | return 1; | ||
227 | } | ||
228 | #else | ||
229 | setnumV(n, sign * (lua_Number)k); | ||
206 | return 1; | 230 | return 1; |
231 | #endif | ||
207 | } | 232 | } |
208 | } | 233 | } |
209 | parsedbl: | 234 | parsedbl: |
@@ -239,26 +264,36 @@ size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o) | |||
239 | } | 264 | } |
240 | } | 265 | } |
241 | 266 | ||
267 | /* Print integer to buffer. Returns pointer to start. */ | ||
268 | char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k) | ||
269 | { | ||
270 | uint32_t u = (uint32_t)(k < 0 ? -k : k); | ||
271 | p += 1+10; | ||
272 | do { *--p = (char)('0' + u % 10); } while (u /= 10); | ||
273 | if (k < 0) *--p = '-'; | ||
274 | return p; | ||
275 | } | ||
276 | |||
242 | /* Convert number to string. */ | 277 | /* Convert number to string. */ |
243 | GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np) | 278 | GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np) |
244 | { | 279 | { |
245 | char buf[LUAI_MAXNUMBER2STR]; | 280 | char buf[LJ_STR_NUMBUF]; |
246 | size_t len = lj_str_bufnum(buf, (TValue *)np); | 281 | size_t len = lj_str_bufnum(buf, (TValue *)np); |
247 | return lj_str_new(L, buf, len); | 282 | return lj_str_new(L, buf, len); |
248 | } | 283 | } |
249 | 284 | ||
250 | #if LJ_HASJIT | ||
251 | /* Convert integer to string. */ | 285 | /* Convert integer to string. */ |
252 | GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k) | 286 | GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k) |
253 | { | 287 | { |
254 | char s[1+10]; | 288 | char s[1+10]; |
255 | char *p = s+sizeof(s); | 289 | char *p = lj_str_bufint(s, k); |
256 | uint32_t i = (uint32_t)(k < 0 ? -k : k); | ||
257 | do { *--p = (char)('0' + i % 10); } while (i /= 10); | ||
258 | if (k < 0) *--p = '-'; | ||
259 | return lj_str_new(L, p, (size_t)(s+sizeof(s)-p)); | 290 | return lj_str_new(L, p, (size_t)(s+sizeof(s)-p)); |
260 | } | 291 | } |
261 | #endif | 292 | |
293 | GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o) | ||
294 | { | ||
295 | return tvisint(o) ? lj_str_fromint(L, intV(o)) : lj_str_fromnum(L, &o->n); | ||
296 | } | ||
262 | 297 | ||
263 | /* -- String formatting --------------------------------------------------- */ | 298 | /* -- String formatting --------------------------------------------------- */ |
264 | 299 | ||
@@ -307,38 +342,34 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp) | |||
307 | addchar(L, sb, va_arg(argp, int)); | 342 | addchar(L, sb, va_arg(argp, int)); |
308 | break; | 343 | break; |
309 | case 'd': { | 344 | case 'd': { |
310 | char buff[1+10]; | 345 | char buf[LJ_STR_INTBUF]; |
311 | char *p = buff+sizeof(buff); | 346 | char *p = lj_str_bufint(buf, va_arg(argp, int32_t)); |
312 | int32_t k = va_arg(argp, int32_t); | 347 | addstr(L, sb, p, (MSize)(buf+LJ_STR_INTBUF-p)); |
313 | uint32_t i = (uint32_t)(k < 0 ? -k : k); | ||
314 | do { *--p = (char)('0' + i % 10); } while (i /= 10); | ||
315 | if (k < 0) *--p = '-'; | ||
316 | addstr(L, sb, p, (MSize)(buff+sizeof(buff)-p)); | ||
317 | break; | 348 | break; |
318 | } | 349 | } |
319 | case 'f': { | 350 | case 'f': { |
320 | char buf[LUAI_MAXNUMBER2STR]; | 351 | char buf[LJ_STR_NUMBUF]; |
321 | TValue tv; | 352 | TValue tv; |
322 | MSize len; | 353 | MSize len; |
323 | tv.n = cast_num(va_arg(argp, LUAI_UACNUMBER)); | 354 | tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER)); |
324 | len = (MSize)lj_str_bufnum(buf, &tv); | 355 | len = (MSize)lj_str_bufnum(buf, &tv); |
325 | addstr(L, sb, buf, len); | 356 | addstr(L, sb, buf, len); |
326 | break; | 357 | break; |
327 | } | 358 | } |
328 | case 'p': { | 359 | case 'p': { |
329 | #define FMTP_CHARS (2*sizeof(ptrdiff_t)) | 360 | #define FMTP_CHARS (2*sizeof(ptrdiff_t)) |
330 | char buff[2+FMTP_CHARS]; | 361 | char buf[2+FMTP_CHARS]; |
331 | ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *)); | 362 | ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *)); |
332 | ptrdiff_t i, lasti = 2+FMTP_CHARS; | 363 | ptrdiff_t i, lasti = 2+FMTP_CHARS; |
333 | #if LJ_64 | 364 | #if LJ_64 |
334 | if ((p >> 32) == 0) /* Shorten output for true 32 bit pointers. */ | 365 | if ((p >> 32) == 0) /* Shorten output for true 32 bit pointers. */ |
335 | lasti = 2+2*4; | 366 | lasti = 2+2*4; |
336 | #endif | 367 | #endif |
337 | buff[0] = '0'; | 368 | buf[0] = '0'; |
338 | buff[1] = 'x'; | 369 | buf[1] = 'x'; |
339 | for (i = lasti-1; i >= 2; i--, p >>= 4) | 370 | for (i = lasti-1; i >= 2; i--, p >>= 4) |
340 | buff[i] = "0123456789abcdef"[(p & 15)]; | 371 | buf[i] = "0123456789abcdef"[(p & 15)]; |
341 | addstr(L, sb, buff, (MSize)lasti); | 372 | addstr(L, sb, buf, (MSize)lasti); |
342 | break; | 373 | break; |
343 | } | 374 | } |
344 | case '%': | 375 | case '%': |
diff --git a/src/lj_str.h b/src/lj_str.h index 26b932e0..406e2522 100644 --- a/src/lj_str.h +++ b/src/lj_str.h | |||
@@ -22,11 +22,15 @@ LJ_FUNC void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s); | |||
22 | /* Type conversions. */ | 22 | /* Type conversions. */ |
23 | LJ_FUNC int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n); | 23 | LJ_FUNC int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n); |
24 | LJ_FUNC int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n); | 24 | LJ_FUNC int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n); |
25 | LJ_FUNC int LJ_FASTCALL lj_str_tonumber(GCstr *str, TValue *n); | ||
25 | LJ_FUNC size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o); | 26 | LJ_FUNC size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o); |
27 | LJ_FUNC char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k); | ||
26 | LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np); | 28 | LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np); |
27 | #if LJ_HASJIT | ||
28 | LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k); | 29 | LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k); |
29 | #endif | 30 | LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o); |
31 | |||
32 | #define LJ_STR_INTBUF (1+10) | ||
33 | #define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR | ||
30 | 34 | ||
31 | /* String formatting. */ | 35 | /* String formatting. */ |
32 | LJ_FUNC const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp); | 36 | LJ_FUNC const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp); |
diff --git a/src/lj_tab.c b/src/lj_tab.c index d64a0426..c8e4efe1 100644 --- a/src/lj_tab.c +++ b/src/lj_tab.c | |||
@@ -34,6 +34,7 @@ static LJ_AINLINE Node *hashmask(const GCtab *t, uint32_t hash) | |||
34 | /* Hash an arbitrary key and return its anchor position in the hash table. */ | 34 | /* Hash an arbitrary key and return its anchor position in the hash table. */ |
35 | static Node *hashkey(const GCtab *t, cTValue *key) | 35 | static Node *hashkey(const GCtab *t, cTValue *key) |
36 | { | 36 | { |
37 | lua_assert(!tvisint(key)); | ||
37 | if (tvisstr(key)) | 38 | if (tvisstr(key)) |
38 | return hashstr(t, strV(key)); | 39 | return hashstr(t, strV(key)); |
39 | else if (tvisnum(key)) | 40 | else if (tvisnum(key)) |
@@ -100,7 +101,7 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits) | |||
100 | lua_assert((sizeof(GCtab) & 7) == 0); | 101 | lua_assert((sizeof(GCtab) & 7) == 0); |
101 | t = (GCtab *)lj_mem_newgco(L, sizetabcolo(asize)); | 102 | t = (GCtab *)lj_mem_newgco(L, sizetabcolo(asize)); |
102 | t->gct = ~LJ_TTAB; | 103 | t->gct = ~LJ_TTAB; |
103 | t->nomm = cast_byte(~0); | 104 | t->nomm = (uint8_t)~0; |
104 | t->colo = (int8_t)asize; | 105 | t->colo = (int8_t)asize; |
105 | setmref(t->array, (TValue *)((char *)t + sizeof(GCtab))); | 106 | setmref(t->array, (TValue *)((char *)t + sizeof(GCtab))); |
106 | setgcrefnull(t->metatable); | 107 | setgcrefnull(t->metatable); |
@@ -110,7 +111,7 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits) | |||
110 | } else { /* Otherwise separately allocate the array part. */ | 111 | } else { /* Otherwise separately allocate the array part. */ |
111 | t = lj_mem_newobj(L, GCtab); | 112 | t = lj_mem_newobj(L, GCtab); |
112 | t->gct = ~LJ_TTAB; | 113 | t->gct = ~LJ_TTAB; |
113 | t->nomm = cast_byte(~0); | 114 | t->nomm = (uint8_t)~0; |
114 | t->colo = 0; | 115 | t->colo = 0; |
115 | setmref(t->array, NULL); | 116 | setmref(t->array, NULL); |
116 | setgcrefnull(t->metatable); | 117 | setgcrefnull(t->metatable); |
@@ -275,10 +276,11 @@ static void resizetab(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits) | |||
275 | 276 | ||
276 | static uint32_t countint(cTValue *key, uint32_t *bins) | 277 | static uint32_t countint(cTValue *key, uint32_t *bins) |
277 | { | 278 | { |
279 | lua_assert(!tvisint(key)); | ||
278 | if (tvisnum(key)) { | 280 | if (tvisnum(key)) { |
279 | lua_Number nk = numV(key); | 281 | lua_Number nk = numV(key); |
280 | int32_t k = lj_num2int(nk); | 282 | int32_t k = lj_num2int(nk); |
281 | if ((uint32_t)k < LJ_MAX_ASIZE && nk == cast_num(k)) { | 283 | if ((uint32_t)k < LJ_MAX_ASIZE && nk == (lua_Number)k) { |
282 | bins[(k > 2 ? lj_fls((uint32_t)(k-1)) : 0)]++; | 284 | bins[(k > 2 ? lj_fls((uint32_t)(k-1)) : 0)]++; |
283 | return 1; | 285 | return 1; |
284 | } | 286 | } |
@@ -360,7 +362,7 @@ cTValue * LJ_FASTCALL lj_tab_getinth(GCtab *t, int32_t key) | |||
360 | { | 362 | { |
361 | TValue k; | 363 | TValue k; |
362 | Node *n; | 364 | Node *n; |
363 | k.n = cast_num(key); | 365 | k.n = (lua_Number)key; |
364 | n = hashnum(t, &k); | 366 | n = hashnum(t, &k); |
365 | do { | 367 | do { |
366 | if (tvisnum(&n->key) && n->key.n == k.n) | 368 | if (tvisnum(&n->key) && n->key.n == k.n) |
@@ -385,10 +387,14 @@ cTValue *lj_tab_get(lua_State *L, GCtab *t, cTValue *key) | |||
385 | cTValue *tv = lj_tab_getstr(t, strV(key)); | 387 | cTValue *tv = lj_tab_getstr(t, strV(key)); |
386 | if (tv) | 388 | if (tv) |
387 | return tv; | 389 | return tv; |
390 | } else if (tvisint(key)) { | ||
391 | cTValue *tv = lj_tab_getint(t, intV(key)); | ||
392 | if (tv) | ||
393 | return tv; | ||
388 | } else if (tvisnum(key)) { | 394 | } else if (tvisnum(key)) { |
389 | lua_Number nk = numV(key); | 395 | lua_Number nk = numV(key); |
390 | int32_t k = lj_num2int(nk); | 396 | int32_t k = lj_num2int(nk); |
391 | if (nk == cast_num(k)) { | 397 | if (nk == (lua_Number)k) { |
392 | cTValue *tv = lj_tab_getint(t, k); | 398 | cTValue *tv = lj_tab_getint(t, k); |
393 | if (tv) | 399 | if (tv) |
394 | return tv; | 400 | return tv; |
@@ -466,7 +472,7 @@ TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key) | |||
466 | { | 472 | { |
467 | TValue k; | 473 | TValue k; |
468 | Node *n; | 474 | Node *n; |
469 | k.n = cast_num(key); | 475 | k.n = (lua_Number)key; |
470 | n = hashnum(t, &k); | 476 | n = hashnum(t, &k); |
471 | do { | 477 | do { |
472 | if (tvisnum(&n->key) && n->key.n == k.n) | 478 | if (tvisnum(&n->key) && n->key.n == k.n) |
@@ -493,10 +499,12 @@ TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key) | |||
493 | t->nomm = 0; /* Invalidate negative metamethod cache. */ | 499 | t->nomm = 0; /* Invalidate negative metamethod cache. */ |
494 | if (tvisstr(key)) { | 500 | if (tvisstr(key)) { |
495 | return lj_tab_setstr(L, t, strV(key)); | 501 | return lj_tab_setstr(L, t, strV(key)); |
502 | } else if (tvisint(key)) { | ||
503 | return lj_tab_setint(L, t, intV(key)); | ||
496 | } else if (tvisnum(key)) { | 504 | } else if (tvisnum(key)) { |
497 | lua_Number nk = numV(key); | 505 | lua_Number nk = numV(key); |
498 | int32_t k = lj_num2int(nk); | 506 | int32_t k = lj_num2int(nk); |
499 | if (nk == cast_num(k)) | 507 | if (nk == (lua_Number)k) |
500 | return lj_tab_setint(L, t, k); | 508 | return lj_tab_setint(L, t, k); |
501 | if (tvisnan(key)) | 509 | if (tvisnan(key)) |
502 | lj_err_msg(L, LJ_ERR_NANIDX); | 510 | lj_err_msg(L, LJ_ERR_NANIDX); |
@@ -517,10 +525,17 @@ TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key) | |||
517 | /* Get the traversal index of a key. */ | 525 | /* Get the traversal index of a key. */ |
518 | static uint32_t keyindex(lua_State *L, GCtab *t, cTValue *key) | 526 | static uint32_t keyindex(lua_State *L, GCtab *t, cTValue *key) |
519 | { | 527 | { |
520 | if (tvisnum(key)) { | 528 | TValue tmp; |
529 | if (tvisint(key)) { | ||
530 | int32_t k = intV(key); | ||
531 | if ((uint32_t)k < t->asize) | ||
532 | return (uint32_t)k; /* Array key indexes: [0..t->asize-1] */ | ||
533 | setnumV(&tmp, (lua_Number)k); | ||
534 | key = &tmp; | ||
535 | } else if (tvisnum(key)) { | ||
521 | lua_Number nk = numV(key); | 536 | lua_Number nk = numV(key); |
522 | int32_t k = lj_num2int(nk); | 537 | int32_t k = lj_num2int(nk); |
523 | if ((uint32_t)k < t->asize && nk == cast_num(k)) | 538 | if ((uint32_t)k < t->asize && nk == (lua_Number)k) |
524 | return (uint32_t)k; /* Array key indexes: [0..t->asize-1] */ | 539 | return (uint32_t)k; /* Array key indexes: [0..t->asize-1] */ |
525 | } | 540 | } |
526 | if (!tvisnil(key)) { | 541 | if (!tvisnil(key)) { |