aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2011-02-17 00:44:14 +0100
committerMike Pall <mike>2011-02-17 00:44:14 +0100
commit03946ac978d9a1a3230619e3da048002e5fda2d1 (patch)
treec0a7b8edaccf789f128468320d451d9a1fee1495
parent963f05c7e153714921484e0de71a7cb6bab338d9 (diff)
downloadluajit-03946ac978d9a1a3230619e3da048002e5fda2d1.tar.gz
luajit-03946ac978d9a1a3230619e3da048002e5fda2d1.tar.bz2
luajit-03946ac978d9a1a3230619e3da048002e5fda2d1.zip
DUALNUM: Add integer type to core VM.
-rw-r--r--src/lib_base.c28
-rw-r--r--src/lib_io.c42
-rw-r--r--src/lib_jit.c25
-rw-r--r--src/lib_math.c2
-rw-r--r--src/lib_string.c6
-rw-r--r--src/lib_table.c8
-rw-r--r--src/lj_api.c103
-rw-r--r--src/lj_ctype.c2
-rw-r--r--src/lj_def.h1
-rw-r--r--src/lj_dispatch.c2
-rw-r--r--src/lj_err.c12
-rw-r--r--src/lj_func.c4
-rw-r--r--src/lj_lex.c9
-rw-r--r--src/lj_lib.c14
-rw-r--r--src/lj_lib.h4
-rw-r--r--src/lj_meta.c12
-rw-r--r--src/lj_obj.c4
-rw-r--r--src/lj_obj.h63
-rw-r--r--src/lj_parse.c129
-rw-r--r--src/lj_snap.c2
-rw-r--r--src/lj_str.c79
-rw-r--r--src/lj_str.h8
-rw-r--r--src/lj_tab.c33
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
610LUALIB_API int luaopen_base(lua_State *L) 618LUALIB_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
196static int io_file_read(lua_State *L, FILE *fp, int start) 196static 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)
70LJLIB_CF(jit_flush) 70LJLIB_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)
129LJLIB_PUSH(top-2) /* Upvalue holds userdata with RandomState. */ 129LJLIB_PUSH(top-2) /* Upvalue holds userdata with RandomState. */
130LJLIB_CF(math_random) LJLIB_REC(.) 130LJLIB_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
62LJLIB_ASM(string_char) 62LJLIB_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
116LUA_API int lua_gettop(lua_State *L) 116LUA_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
121LUA_API void lua_settop(lua_State *L, int idx) 121LUA_API void lua_settop(lua_State *L, int idx)
@@ -186,7 +186,7 @@ LUA_API void lua_pushvalue(lua_State *L, int idx)
186LUA_API int lua_type(lua_State *L, int idx) 186LUA_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
240LUA_API int lua_isstring(lua_State *L, int idx) 240LUA_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
246LUA_API int lua_isuserdata(lua_State *L, int idx) 246LUA_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
552LUA_API void lua_pushinteger(lua_State *L, lua_Integer n) 571LUA_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. */
523GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size) 523GCstr *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. */
540LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions, 540LJ_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. */
648LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec, 648LJ_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
163int32_t lj_lib_checkint(lua_State *L, int narg) 163int32_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
168int32_t lj_lib_optint(lua_State *L, int narg, int32_t def) 172int32_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);
41LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg); 41LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg);
42LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst); 42LJ_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
760static 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
769static 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. */
747static LJ_AINLINE void copyTV(lua_State *L, TValue *o1, const TValue *o2) 784static 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
814static 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
822static 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. */
79static LJ_AINLINE void expr_init(ExpDesc *e, ExpKind k, uint32_t info) 80static 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. */
88static 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. */
87typedef struct FuncScope { 95typedef 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. */
178static BCReg const_num(FuncState *fs, ExpDesc *e) 189static 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)
191static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype) 202static 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)
720static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2) 738static 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)
986static void var_add(LexState *ls, BCReg nvars) 1022static 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. */
173int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n) 173int 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
181int 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. */
179int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n) 187int 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 }
209parsedbl: 234parsedbl:
@@ -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. */
268char * 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. */
243GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np) 278GCstr * 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. */
252GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k) 286GCstr * 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
293GCstr * 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. */
23LJ_FUNC int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n); 23LJ_FUNC int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n);
24LJ_FUNC int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n); 24LJ_FUNC int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n);
25LJ_FUNC int LJ_FASTCALL lj_str_tonumber(GCstr *str, TValue *n);
25LJ_FUNC size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o); 26LJ_FUNC size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o);
27LJ_FUNC char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k);
26LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np); 28LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np);
27#if LJ_HASJIT
28LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k); 29LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k);
29#endif 30LJ_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. */
32LJ_FUNC const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp); 36LJ_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. */
35static Node *hashkey(const GCtab *t, cTValue *key) 35static 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
276static uint32_t countint(cTValue *key, uint32_t *bins) 277static 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. */
518static uint32_t keyindex(lua_State *L, GCtab *t, cTValue *key) 526static 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)) {