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 /src | |
| parent | 963f05c7e153714921484e0de71a7cb6bab338d9 (diff) | |
| download | luajit-03946ac978d9a1a3230619e3da048002e5fda2d1.tar.gz luajit-03946ac978d9a1a3230619e3da048002e5fda2d1.tar.bz2 luajit-03946ac978d9a1a3230619e3da048002e5fda2d1.zip | |
DUALNUM: Add integer type to core VM.
Diffstat (limited to 'src')
| -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)) { |
