mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +00:00
DUALNUM: Add integer type to core VM.
This commit is contained in:
parent
963f05c7e1
commit
03946ac978
@ -190,8 +190,8 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
|
||||
int32_t base = lj_lib_optint(L, 2, 10);
|
||||
if (base == 10) {
|
||||
TValue *o = lj_lib_checkany(L, 1);
|
||||
if (tvisnum(o) || (tvisstr(o) && lj_str_tonum(strV(o), o))) {
|
||||
setnumV(L->base-1, numV(o));
|
||||
if (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o))) {
|
||||
copyTV(L, L->base-1, o);
|
||||
return FFH_RES(1);
|
||||
}
|
||||
#if LJ_HASFFI
|
||||
@ -212,7 +212,10 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
|
||||
if (p != ep) {
|
||||
while (lj_char_isspace((unsigned char)(*ep))) ep++;
|
||||
if (*ep == '\0') {
|
||||
setnumV(L->base-1, cast_num(ul));
|
||||
if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u))
|
||||
setintV(L->base-1, (int32_t)ul);
|
||||
else
|
||||
setnumV(L->base-1, (lua_Number)ul);
|
||||
return FFH_RES(1);
|
||||
}
|
||||
}
|
||||
@ -234,8 +237,8 @@ LJLIB_ASM(tostring) LJLIB_REC(.)
|
||||
return FFH_TAILCALL;
|
||||
} else {
|
||||
GCstr *s;
|
||||
if (tvisnum(o)) {
|
||||
s = lj_str_fromnum(L, &o->n);
|
||||
if (tvisnumber(o)) {
|
||||
s = lj_str_fromnumber(L, o);
|
||||
} else if (tvispri(o)) {
|
||||
s = strV(lj_lib_upvalue(L, -(int32_t)itype(o)));
|
||||
} else {
|
||||
@ -359,7 +362,7 @@ static const char *reader_func(lua_State *L, void *ud, size_t *size)
|
||||
if (tvisnil(L->top)) {
|
||||
*size = 0;
|
||||
return NULL;
|
||||
} else if (tvisstr(L->top) || tvisnum(L->top)) {
|
||||
} else if (tvisstr(L->top) || tvisnumber(L->top)) {
|
||||
copyTV(L, L->base+2, L->top); /* Anchor string in reserved stack slot. */
|
||||
return lua_tolstring(L, 3, size);
|
||||
} else {
|
||||
@ -385,7 +388,7 @@ LJLIB_CF(dofile)
|
||||
if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != 0)
|
||||
lua_error(L);
|
||||
lua_call(L, 0, LUA_MULTRET);
|
||||
return cast_int(L->top - L->base) - 1;
|
||||
return (int)(L->top - L->base) - 1;
|
||||
}
|
||||
|
||||
/* -- Base library: GC control -------------------------------------------- */
|
||||
@ -402,7 +405,7 @@ LJLIB_CF(collectgarbage)
|
||||
"\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul");
|
||||
int32_t data = lj_lib_optint(L, 2, 0);
|
||||
if (opt == LUA_GCCOUNT) {
|
||||
setnumV(L->top, cast_num(G(L)->gc.total)/1024.0);
|
||||
setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0);
|
||||
} else {
|
||||
int res = lua_gc(L, opt, data);
|
||||
if (opt == LUA_GCSTEP)
|
||||
@ -464,8 +467,13 @@ LJLIB_CF(print)
|
||||
if (shortcut && tvisstr(o)) {
|
||||
str = strVdata(o);
|
||||
size = strV(o)->len;
|
||||
} else if (shortcut && tvisint(o)) {
|
||||
char buf[LJ_STR_INTBUF];
|
||||
char *p = lj_str_bufint(buf, intV(o));
|
||||
size = (size_t)(buf+LJ_STR_INTBUF-p);
|
||||
str = p;
|
||||
} else if (shortcut && tvisnum(o)) {
|
||||
char buf[LUAI_MAXNUMBER2STR];
|
||||
char buf[LJ_STR_NUMBUF];
|
||||
size = lj_str_bufnum(buf, o);
|
||||
str = buf;
|
||||
} else {
|
||||
@ -604,7 +612,7 @@ static void newproxy_weaktable(lua_State *L)
|
||||
setgcref(t->metatable, obj2gco(t));
|
||||
setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")),
|
||||
lj_str_newlit(L, "kv"));
|
||||
t->nomm = cast_byte(~(1u<<MM_mode));
|
||||
t->nomm = (uint8_t)(~(1u<<MM_mode));
|
||||
}
|
||||
|
||||
LUALIB_API int luaopen_base(lua_State *L)
|
||||
|
42
src/lib_io.c
42
src/lib_io.c
@ -195,7 +195,7 @@ static int io_file_readchars(lua_State *L, FILE *fp, size_t n)
|
||||
|
||||
static int io_file_read(lua_State *L, FILE *fp, int start)
|
||||
{
|
||||
int ok, n, nargs = cast_int(L->top - L->base) - start;
|
||||
int ok, n, nargs = (int)(L->top - L->base) - start;
|
||||
clearerr(fp);
|
||||
if (nargs == 0) {
|
||||
ok = io_file_readline(L, fp);
|
||||
@ -240,10 +240,15 @@ static int io_file_write(lua_State *L, FILE *fp, int start)
|
||||
if (tvisstr(tv)) {
|
||||
MSize len = strV(tv)->len;
|
||||
status = status && (fwrite(strVdata(tv), 1, len, fp) == len);
|
||||
} else if (tvisint(tv)) {
|
||||
char buf[LJ_STR_INTBUF];
|
||||
char *p = lj_str_bufint(buf, intV(tv));
|
||||
size_t len = (size_t)(buf+LJ_STR_INTBUF-p);
|
||||
status = status && (fwrite(p, 1, len, fp) == len);
|
||||
} else if (tvisnum(tv)) {
|
||||
status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0);
|
||||
} else {
|
||||
lj_err_argt(L, cast_int(tv - L->base) + 1, LUA_TSTRING);
|
||||
lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
|
||||
}
|
||||
}
|
||||
return io_pushresult(L, status, NULL);
|
||||
@ -279,37 +284,42 @@ LJLIB_CF(io_method_seek)
|
||||
{
|
||||
FILE *fp = io_tofile(L)->fp;
|
||||
int opt = lj_lib_checkopt(L, 2, 1, "\3set\3cur\3end");
|
||||
lua_Number ofs;
|
||||
int64_t ofs = 0;
|
||||
cTValue *o;
|
||||
int res;
|
||||
if (opt == 0) opt = SEEK_SET;
|
||||
else if (opt == 1) opt = SEEK_CUR;
|
||||
else if (opt == 2) opt = SEEK_END;
|
||||
lj_lib_opt(L, 3,
|
||||
ofs = lj_lib_checknum(L, 3);
|
||||
,
|
||||
ofs = 0;
|
||||
)
|
||||
o = L->base+2;
|
||||
if (o < L->top) {
|
||||
if (tvisint(o))
|
||||
ofs = (int64_t)intV(o);
|
||||
else if (tvisnum(o))
|
||||
ofs = (int64_t)numV(o);
|
||||
else if (!tvisnil(o))
|
||||
lj_err_argt(L, 3, LUA_TNUMBER);
|
||||
}
|
||||
#if LJ_TARGET_POSIX
|
||||
res = fseeko(fp, (int64_t)ofs, opt);
|
||||
res = fseeko(fp, ofs, opt);
|
||||
#elif _MSC_VER >= 1400
|
||||
res = _fseeki64(fp, (int64_t)ofs, opt);
|
||||
res = _fseeki64(fp, ofs, opt);
|
||||
#elif defined(__MINGW32__)
|
||||
res = fseeko64(fp, (int64_t)ofs, opt);
|
||||
res = fseeko64(fp, ofs, opt);
|
||||
#else
|
||||
res = fseek(fp, (long)ofs, opt);
|
||||
#endif
|
||||
if (res)
|
||||
return io_pushresult(L, 0, NULL);
|
||||
#if LJ_TARGET_POSIX
|
||||
ofs = cast_num(ftello(fp));
|
||||
ofs = ftello(fp);
|
||||
#elif _MSC_VER >= 1400
|
||||
ofs = cast_num(_ftelli64(fp));
|
||||
ofs = _ftelli64(fp);
|
||||
#elif defined(__MINGW32__)
|
||||
ofs = cast_num(ftello64(fp));
|
||||
ofs = ftello64(fp);
|
||||
#else
|
||||
ofs = cast_num(ftell(fp));
|
||||
ofs = (int64_t)ftell(fp);
|
||||
#endif
|
||||
setnumV(L->top-1, ofs);
|
||||
setint64V(L->top-1, ofs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ LJLIB_CF(jit_off)
|
||||
LJLIB_CF(jit_flush)
|
||||
{
|
||||
#if LJ_HASJIT
|
||||
if (L->base < L->top && (tvisnum(L->base) || tvisstr(L->base))) {
|
||||
if (L->base < L->top && !tvisnil(L->base)) {
|
||||
int traceno = lj_lib_checkint(L, 1);
|
||||
luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE);
|
||||
return 0;
|
||||
@ -202,8 +202,8 @@ LJLIB_CF(jit_util_funcinfo)
|
||||
t = tabV(L->top-1);
|
||||
if (!iscfunc(fn))
|
||||
setintfield(L, t, "ffid", fn->c.ffid);
|
||||
setnumV(lj_tab_setstr(L, t, lj_str_newlit(L, "addr")),
|
||||
cast_num((intptr_t)fn->c.f));
|
||||
setintptrV(lj_tab_setstr(L, t, lj_str_newlit(L, "addr")),
|
||||
(intptr_t)(void *)fn->c.f);
|
||||
setintfield(L, t, "upvalues", fn->c.nupvalues);
|
||||
}
|
||||
return 1;
|
||||
@ -233,7 +233,7 @@ LJLIB_CF(jit_util_funck)
|
||||
ptrdiff_t idx = (ptrdiff_t)lj_lib_checkint(L, 2);
|
||||
if (idx >= 0) {
|
||||
if (idx < (ptrdiff_t)pt->sizekn) {
|
||||
setnumV(L->top-1, proto_knum(pt, idx));
|
||||
copyTV(L, L->top-1, proto_knumtv(pt, idx));
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
@ -358,7 +358,7 @@ LJLIB_CF(jit_util_tracemc)
|
||||
GCtrace *T = jit_checktrace(L);
|
||||
if (T && T->mcode != NULL) {
|
||||
setstrV(L, L->top-1, lj_str_new(L, (const char *)T->mcode, T->szmcode));
|
||||
setnumV(L->top++, cast_num((intptr_t)T->mcode));
|
||||
setintptrV(L->top++, (intptr_t)(void *)T->mcode);
|
||||
setintV(L->top++, T->mcloop);
|
||||
return 3;
|
||||
}
|
||||
@ -371,7 +371,7 @@ LJLIB_CF(jit_util_traceexitstub)
|
||||
ExitNo exitno = (ExitNo)lj_lib_checkint(L, 1);
|
||||
jit_State *J = L2J(L);
|
||||
if (exitno < EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR) {
|
||||
setnumV(L->top-1, cast_num((intptr_t)exitstub_addr(J, exitno)));
|
||||
setintptrV(L->top-1, (intptr_t)(void *)exitstub_addr(J, exitno));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -382,7 +382,7 @@ LJLIB_CF(jit_util_ircalladdr)
|
||||
{
|
||||
uint32_t idx = (uint32_t)lj_lib_checkint(L, 1);
|
||||
if (idx < IRCALL__MAX) {
|
||||
setnumV(L->top-1, cast_num((uintptr_t)(void *)lj_ir_callinfo[idx].func));
|
||||
setintptrV(L->top-1, (intptr_t)(void *)lj_ir_callinfo[idx].func);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -462,11 +462,14 @@ static int jitopt_param(jit_State *J, const char *str)
|
||||
int i;
|
||||
for (i = 0; i < JIT_P__MAX; i++) {
|
||||
size_t len = *(const uint8_t *)lst;
|
||||
TValue tv;
|
||||
lua_assert(len != 0);
|
||||
if (strncmp(str, lst+1, len) == 0 && str[len] == '=' &&
|
||||
lj_str_numconv(&str[len+1], &tv)) {
|
||||
J->param[i] = lj_num2int(tv.n);
|
||||
if (strncmp(str, lst+1, len) == 0 && str[len] == '=') {
|
||||
int32_t n = 0;
|
||||
const char *p = &str[len+1];
|
||||
while (*p >= '0' && *p <= '9')
|
||||
n = n*10 + (*p++ - '0');
|
||||
if (*p) return 0; /* Malformed number. */
|
||||
J->param[i] = n;
|
||||
if (i == JIT_P_hotloop)
|
||||
lj_dispatch_init_hotcount(J2G(J));
|
||||
return 1; /* Ok. */
|
||||
|
@ -129,7 +129,7 @@ static void random_init(RandomState *rs, double d)
|
||||
LJLIB_PUSH(top-2) /* Upvalue holds userdata with RandomState. */
|
||||
LJLIB_CF(math_random) LJLIB_REC(.)
|
||||
{
|
||||
int n = cast_int(L->top - L->base);
|
||||
int n = (int)(L->top - L->base);
|
||||
RandomState *rs = (RandomState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
|
||||
U64double u;
|
||||
double d;
|
||||
|
@ -61,7 +61,7 @@ LJLIB_ASM(string_byte) LJLIB_REC(string_range 0)
|
||||
|
||||
LJLIB_ASM(string_char)
|
||||
{
|
||||
int i, nargs = cast_int(L->top - L->base);
|
||||
int i, nargs = (int)(L->top - L->base);
|
||||
char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, (size_t)nargs);
|
||||
for (i = 1; i <= nargs; i++) {
|
||||
int32_t k = lj_lib_checkint(L, i);
|
||||
@ -737,7 +737,7 @@ LJLIB_CF(string_format)
|
||||
tv.n = lj_lib_checknum(L, arg);
|
||||
if (LJ_UNLIKELY((tv.u32.hi << 1) >= 0xffe00000)) {
|
||||
/* Canonicalize output of non-finite values. */
|
||||
char *p, nbuf[LUAI_MAXNUMBER2STR];
|
||||
char *p, nbuf[LJ_STR_NUMBUF];
|
||||
size_t len = lj_str_bufnum(nbuf, &tv);
|
||||
if (strfrmt[-1] == 'E' || strfrmt[-1] == 'G') {
|
||||
nbuf[len-3] = nbuf[len-3] - 0x20;
|
||||
@ -801,7 +801,7 @@ LUALIB_API int luaopen_string(lua_State *L)
|
||||
g = G(L);
|
||||
setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt));
|
||||
settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1));
|
||||
mt->nomm = cast_byte(~(1u<<MM_index));
|
||||
mt->nomm = (uint8_t)(~(1u<<MM_index));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -82,8 +82,10 @@ LJLIB_CF(table_maxn)
|
||||
}
|
||||
node = noderef(t->node);
|
||||
for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
|
||||
if (tvisnum(&node[i].key) && numV(&node[i].key) > m)
|
||||
m = numV(&node[i].key);
|
||||
if (tvisnumber(&node[i].key)) {
|
||||
lua_Number n = numberVnum(&node[i].key);
|
||||
if (n > m) m = n;
|
||||
}
|
||||
setnumV(L->top-1, m);
|
||||
return 1;
|
||||
}
|
||||
@ -154,7 +156,7 @@ LJLIB_CF(table_concat)
|
||||
cTValue *o;
|
||||
lua_rawgeti(L, 1, i);
|
||||
o = L->top-1;
|
||||
if (!(tvisstr(o) || tvisnum(o)))
|
||||
if (!(tvisstr(o) || tvisnumber(o)))
|
||||
lj_err_callerv(L, LJ_ERR_TABCAT, typename(o), i);
|
||||
luaL_addvalue(&b);
|
||||
if (i++ == e) break;
|
||||
|
103
src/lj_api.c
103
src/lj_api.c
@ -115,7 +115,7 @@ LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
|
||||
|
||||
LUA_API int lua_gettop(lua_State *L)
|
||||
{
|
||||
return cast_int(L->top - L->base);
|
||||
return (int)(L->top - L->base);
|
||||
}
|
||||
|
||||
LUA_API void lua_settop(lua_State *L, int idx)
|
||||
@ -186,7 +186,7 @@ LUA_API void lua_pushvalue(lua_State *L, int idx)
|
||||
LUA_API int lua_type(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
if (tvisnum(o)) {
|
||||
if (tvisnumber(o)) {
|
||||
return LUA_TNUMBER;
|
||||
#if LJ_64
|
||||
} else if (tvislightud(o)) {
|
||||
@ -234,13 +234,13 @@ LUA_API int lua_isnumber(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
TValue tmp;
|
||||
return (tvisnum(o) || (tvisstr(o) && lj_str_tonum(strV(o), &tmp)));
|
||||
return (tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), &tmp)));
|
||||
}
|
||||
|
||||
LUA_API int lua_isstring(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
return (tvisstr(o) || tvisnum(o));
|
||||
return (tvisstr(o) || tvisnumber(o));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
cTValue *o1 = index2adr(L, idx1);
|
||||
cTValue *o2 = index2adr(L, idx2);
|
||||
if (tvisnum(o1) && tvisnum(o2)) {
|
||||
return numV(o1) == numV(o2);
|
||||
if (tvisint(o1) && tvisint(o2)) {
|
||||
return intV(o1) == intV(o2);
|
||||
} else if (tvisnumber(o1) && tvisnumber(o2)) {
|
||||
return numberVnum(o1) == numberVnum(o2);
|
||||
} else if (itype(o1) != itype(o2)) {
|
||||
return 0;
|
||||
} else if (tvispri(o1)) {
|
||||
@ -293,8 +295,10 @@ LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
|
||||
cTValue *o2 = index2adr(L, idx2);
|
||||
if (o1 == niltv(L) || o2 == niltv(L)) {
|
||||
return 0;
|
||||
} else if (tvisnum(o1) && tvisnum(o2)) {
|
||||
return numV(o1) < numV(o2);
|
||||
} else if (tvisint(o1) && tvisint(o2)) {
|
||||
return intV(o1) < intV(o2);
|
||||
} else if (tvisnumber(o1) && tvisnumber(o2)) {
|
||||
return numberVnum(o1) < numberVnum(o2);
|
||||
} else {
|
||||
TValue *base = lj_meta_comp(L, o1, o2, 0);
|
||||
if ((uintptr_t)base <= 1) {
|
||||
@ -312,8 +316,8 @@ LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
TValue tmp;
|
||||
if (LJ_LIKELY(tvisnum(o)))
|
||||
return numV(o);
|
||||
if (LJ_LIKELY(tvisnumber(o)))
|
||||
return numberVnum(o);
|
||||
else if (tvisstr(o) && lj_str_tonum(strV(o), &tmp))
|
||||
return numV(&tmp);
|
||||
else
|
||||
@ -324,8 +328,8 @@ LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
TValue tmp;
|
||||
if (tvisnum(o))
|
||||
return numV(o);
|
||||
if (LJ_LIKELY(tvisnumber(o)))
|
||||
return numberVnum(o);
|
||||
else if (!(tvisstr(o) && lj_str_tonum(strV(o), &tmp)))
|
||||
lj_err_argt(L, idx, LUA_TNUMBER);
|
||||
return numV(&tmp);
|
||||
@ -335,8 +339,8 @@ LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def)
|
||||
{
|
||||
cTValue *o = index2adr(L, idx);
|
||||
TValue tmp;
|
||||
if (tvisnum(o))
|
||||
return numV(o);
|
||||
if (LJ_LIKELY(tvisnumber(o)))
|
||||
return numberVnum(o);
|
||||
else if (tvisnil(o))
|
||||
return def;
|
||||
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)
|
||||
cTValue *o = index2adr(L, idx);
|
||||
TValue tmp;
|
||||
lua_Number n;
|
||||
if (LJ_LIKELY(tvisnum(o)))
|
||||
if (LJ_LIKELY(tvisint(o))) {
|
||||
return intV(o);
|
||||
} else if (LJ_LIKELY(tvisnum(o))) {
|
||||
n = numV(o);
|
||||
else if (tvisstr(o) && lj_str_tonum(strV(o), &tmp))
|
||||
} else {
|
||||
if (!(tvisstr(o) && lj_str_tonumber(strV(o), &tmp)))
|
||||
return 0;
|
||||
if (tvisint(&tmp))
|
||||
return (lua_Integer)intV(&tmp);
|
||||
n = numV(&tmp);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#if LJ_64
|
||||
return (lua_Integer)n;
|
||||
#else
|
||||
@ -367,12 +376,17 @@ LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
|
||||
cTValue *o = index2adr(L, idx);
|
||||
TValue tmp;
|
||||
lua_Number n;
|
||||
if (LJ_LIKELY(tvisnum(o)))
|
||||
if (LJ_LIKELY(tvisint(o))) {
|
||||
return intV(o);
|
||||
} else if (LJ_LIKELY(tvisnum(o))) {
|
||||
n = numV(o);
|
||||
else if (tvisstr(o) && lj_str_tonum(strV(o), &tmp))
|
||||
} else {
|
||||
if (!(tvisstr(o) && lj_str_tonumber(strV(o), &tmp)))
|
||||
lj_err_argt(L, idx, LUA_TNUMBER);
|
||||
if (tvisint(&tmp))
|
||||
return (lua_Integer)intV(&tmp);
|
||||
n = numV(&tmp);
|
||||
else
|
||||
lj_err_argt(L, idx, LUA_TNUMBER);
|
||||
}
|
||||
#if LJ_64
|
||||
return (lua_Integer)n;
|
||||
#else
|
||||
@ -385,14 +399,19 @@ LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
|
||||
cTValue *o = index2adr(L, idx);
|
||||
TValue tmp;
|
||||
lua_Number n;
|
||||
if (LJ_LIKELY(tvisnum(o)))
|
||||
if (LJ_LIKELY(tvisint(o))) {
|
||||
return intV(o);
|
||||
} else if (LJ_LIKELY(tvisnum(o))) {
|
||||
n = numV(o);
|
||||
else if (tvisnil(o))
|
||||
} else if (tvisnil(o)) {
|
||||
return def;
|
||||
else if (tvisstr(o) && lj_str_tonum(strV(o), &tmp))
|
||||
} else {
|
||||
if (!(tvisstr(o) && lj_str_tonumber(strV(o), &tmp)))
|
||||
lj_err_argt(L, idx, LUA_TNUMBER);
|
||||
if (tvisint(&tmp))
|
||||
return (lua_Integer)intV(&tmp);
|
||||
n = numV(&tmp);
|
||||
else
|
||||
lj_err_argt(L, idx, LUA_TNUMBER);
|
||||
}
|
||||
#if LJ_64
|
||||
return (lua_Integer)n;
|
||||
#else
|
||||
@ -412,10 +431,10 @@ LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
|
||||
GCstr *s;
|
||||
if (LJ_LIKELY(tvisstr(o))) {
|
||||
s = strV(o);
|
||||
} else if (tvisnum(o)) {
|
||||
} else if (tvisnumber(o)) {
|
||||
lj_gc_check(L);
|
||||
o = index2adr(L, idx); /* GC may move the stack. */
|
||||
s = lj_str_fromnum(L, &o->n);
|
||||
s = lj_str_fromnumber(L, o);
|
||||
} else {
|
||||
if (len != NULL) *len = 0;
|
||||
return NULL;
|
||||
@ -430,10 +449,10 @@ LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
|
||||
GCstr *s;
|
||||
if (LJ_LIKELY(tvisstr(o))) {
|
||||
s = strV(o);
|
||||
} else if (tvisnum(o)) {
|
||||
} else if (tvisnumber(o)) {
|
||||
lj_gc_check(L);
|
||||
o = index2adr(L, idx); /* GC may move the stack. */
|
||||
s = lj_str_fromnum(L, &o->n);
|
||||
s = lj_str_fromnumber(L, o);
|
||||
} else {
|
||||
lj_err_argt(L, idx, LUA_TSTRING);
|
||||
}
|
||||
@ -451,10 +470,10 @@ LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
|
||||
} else if (tvisnil(o)) {
|
||||
if (len != NULL) *len = def ? strlen(def) : 0;
|
||||
return def;
|
||||
} else if (tvisnum(o)) {
|
||||
} else if (tvisnumber(o)) {
|
||||
lj_gc_check(L);
|
||||
o = index2adr(L, idx); /* GC may move the stack. */
|
||||
s = lj_str_fromnum(L, &o->n);
|
||||
s = lj_str_fromnumber(L, o);
|
||||
} else {
|
||||
lj_err_argt(L, idx, LUA_TSTRING);
|
||||
}
|
||||
@ -484,8 +503,8 @@ LUA_API size_t lua_objlen(lua_State *L, int idx)
|
||||
return cast(size_t, lj_tab_len(tabV(o)));
|
||||
else if (tvisudata(o))
|
||||
return udataV(o)->len;
|
||||
else if (tvisnum(o))
|
||||
return lj_str_fromnum(L, &o->n)->len;
|
||||
else if (tvisnumber(o))
|
||||
return lj_str_fromnumber(L, o)->len;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@ -551,7 +570,7 @@ LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
|
||||
|
||||
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
|
||||
{
|
||||
setnumV(L->top, cast_num(n));
|
||||
setintptrV(L->top, n);
|
||||
incr_top(L);
|
||||
}
|
||||
|
||||
@ -687,7 +706,7 @@ LUA_API void lua_concat(lua_State *L, int n)
|
||||
L->top -= n;
|
||||
break;
|
||||
}
|
||||
n -= cast_int(L->top - top);
|
||||
n -= (int)(L->top - top);
|
||||
L->top = top+2;
|
||||
lj_vm_call(L, top, 1+1);
|
||||
L->top--;
|
||||
@ -1085,7 +1104,7 @@ LUA_API int lua_yield(lua_State *L, int nresults)
|
||||
setcont(top+1, lj_cont_hook);
|
||||
setframe_pc(top+1, cframe_pc(cf)-1);
|
||||
setframe_gc(top+2, obj2gco(L));
|
||||
top[2].fr.tp.ftsz = cast_int((char *)(top+3)-(char *)L->base)+FRAME_CONT;
|
||||
top[2].fr.tp.ftsz = (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT;
|
||||
L->top = L->base = top+3;
|
||||
}
|
||||
L->cframe = NULL;
|
||||
@ -1160,10 +1179,10 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
|
||||
lj_gc_fullgc(L);
|
||||
break;
|
||||
case LUA_GCCOUNT:
|
||||
res = cast_int(g->gc.total >> 10);
|
||||
res = (int)(g->gc.total >> 10);
|
||||
break;
|
||||
case LUA_GCCOUNTB:
|
||||
res = cast_int(g->gc.total & 0x3ff);
|
||||
res = (int)(g->gc.total & 0x3ff);
|
||||
break;
|
||||
case LUA_GCSTEP: {
|
||||
MSize a = (MSize)data << 10;
|
||||
@ -1176,11 +1195,11 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
|
||||
break;
|
||||
}
|
||||
case LUA_GCSETPAUSE:
|
||||
res = cast_int(g->gc.pause);
|
||||
res = (int)(g->gc.pause);
|
||||
g->gc.pause = (MSize)data;
|
||||
break;
|
||||
case LUA_GCSETSTEPMUL:
|
||||
res = cast_int(g->gc.stepmul);
|
||||
res = (int)(g->gc.stepmul);
|
||||
g->gc.stepmul = (MSize)data;
|
||||
break;
|
||||
default:
|
||||
|
@ -522,7 +522,7 @@ GCstr *lj_ctype_repr_int64(lua_State *L, uint64_t n, int isunsigned)
|
||||
/* Convert complex to string with 'i' or 'I' suffix. */
|
||||
GCstr *lj_ctype_repr_complex(lua_State *L, void *sp, CTSize size)
|
||||
{
|
||||
char buf[2*LUAI_MAXNUMBER2STR+2+1];
|
||||
char buf[2*LJ_STR_NUMBUF+2+1];
|
||||
TValue re, im;
|
||||
size_t len;
|
||||
if (size == 2*sizeof(double)) {
|
||||
|
@ -81,7 +81,6 @@ typedef unsigned __int32 uintptr_t;
|
||||
#define U64x(hi, lo) (((uint64_t)0x##hi << 32) + (uint64_t)0x##lo)
|
||||
#define cast_byte(i) cast(uint8_t, (i))
|
||||
#define cast_num(i) cast(lua_Number, (i))
|
||||
#define cast_int(i) cast(int, (i))
|
||||
#define i32ptr(p) ((int32_t)(intptr_t)(void *)(p))
|
||||
#define u32ptr(p) ((uint32_t)(intptr_t)(void *)(p))
|
||||
|
||||
|
@ -320,7 +320,7 @@ static void callhook(lua_State *L, int event, BCLine line)
|
||||
ar.event = event;
|
||||
ar.currentline = line;
|
||||
/* Top frame, nextframe = NULL. */
|
||||
ar.i_ci = cast_int((L->base-1) - tvref(L->stack));
|
||||
ar.i_ci = (int)((L->base-1) - tvref(L->stack));
|
||||
lj_state_checkstack(L, 1+LUA_MINSTACK);
|
||||
hook_enter(g);
|
||||
hookf(L, &ar);
|
||||
|
12
src/lj_err.c
12
src/lj_err.c
@ -397,7 +397,7 @@ cTValue *lj_err_getframe(lua_State *L, int level, int *size)
|
||||
if (frame_gc(frame) == obj2gco(L))
|
||||
level++; /* Skip dummy frames. See lj_meta_call(). */
|
||||
if (level-- == 0) {
|
||||
*size = cast_int(nextframe - frame);
|
||||
*size = (int)(nextframe - frame);
|
||||
return frame; /* Level found. */
|
||||
}
|
||||
nextframe = frame;
|
||||
@ -418,7 +418,7 @@ LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar)
|
||||
int size;
|
||||
cTValue *frame = lj_err_getframe(L, level, &size);
|
||||
if (frame) {
|
||||
ar->i_ci = (size << 16) + cast_int(frame - tvref(L->stack));
|
||||
ar->i_ci = (size << 16) + (int)(frame - tvref(L->stack));
|
||||
return 1;
|
||||
} else {
|
||||
ar->i_ci = level - size;
|
||||
@ -486,7 +486,7 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode)
|
||||
if (cframe_canyield(cf)) { /* Resume? */
|
||||
if (errcode) {
|
||||
L->cframe = NULL;
|
||||
L->status = cast_byte(errcode);
|
||||
L->status = (uint8_t)errcode;
|
||||
}
|
||||
return cf;
|
||||
}
|
||||
@ -534,7 +534,7 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode)
|
||||
#define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */
|
||||
#define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (_Unwind_Exception_Class)(c))
|
||||
#define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff)
|
||||
#define LJ_UEXCLASS_ERRCODE(cl) (cast_int((cl) & 0xff))
|
||||
#define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff))
|
||||
|
||||
/* DWARF2 personality handler referenced from interpreter .eh_frame. */
|
||||
LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions,
|
||||
@ -642,7 +642,7 @@ extern __DestructExceptionObject(EXCEPTION_RECORD *rec, int nothrow);
|
||||
#define LJ_EXCODE ((DWORD)0xe24c4a00)
|
||||
#define LJ_EXCODE_MAKE(c) (LJ_EXCODE | (DWORD)(c))
|
||||
#define LJ_EXCODE_CHECK(cl) (((cl) ^ LJ_EXCODE) <= 0xff)
|
||||
#define LJ_EXCODE_ERRCODE(cl) (cast_int((cl) & 0xff))
|
||||
#define LJ_EXCODE_ERRCODE(cl) ((int)((cl) & 0xff))
|
||||
|
||||
/* Win64 exception handler for interpreter frame. */
|
||||
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,
|
||||
const char *fname = "?";
|
||||
const char *ftype = getfuncname(L, L->base - 1, &fname);
|
||||
if (narg < 0 && narg > LUA_REGISTRYINDEX)
|
||||
narg = cast_int(L->top - L->base) + narg + 1;
|
||||
narg = (int)(L->top - L->base) + narg + 1;
|
||||
if (ftype && ftype[3] == 'h' && --narg == 0) /* Check for "method". */
|
||||
msg = lj_str_pushf(L, err2msg(LJ_ERR_BADSELF), fname, msg);
|
||||
else
|
||||
|
@ -98,7 +98,7 @@ GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env)
|
||||
GCfunc *fn = cast(GCfunc *, lj_mem_newgco(L, sizeCfunc(nelems)));
|
||||
fn->c.gct = ~LJ_TFUNC;
|
||||
fn->c.ffid = FF_C;
|
||||
fn->c.nupvalues = cast_byte(nelems);
|
||||
fn->c.nupvalues = (uint8_t)nelems;
|
||||
/* NOBARRIER: The GCfunc is new (marked white). */
|
||||
setmref(fn->c.pc, &G(L)->bc_cfunc_ext);
|
||||
setgcref(fn->c.env, obj2gco(env));
|
||||
@ -110,7 +110,7 @@ GCfunc *lj_func_newL(lua_State *L, GCproto *pt, GCtab *env)
|
||||
GCfunc *fn = cast(GCfunc *, lj_mem_newgco(L, sizeLfunc((MSize)pt->sizeuv)));
|
||||
fn->l.gct = ~LJ_TFUNC;
|
||||
fn->l.ffid = FF_LUA;
|
||||
fn->l.nupvalues = cast_byte(pt->sizeuv);
|
||||
fn->l.nupvalues = (uint8_t)pt->sizeuv;
|
||||
/* NOBARRIER: Really a setgcref. But the GCfunc is new (marked white). */
|
||||
setmref(fn->l.pc, proto_bc(pt));
|
||||
setgcref(fn->l.env, obj2gco(env));
|
||||
|
@ -170,10 +170,15 @@ static void lex_number(LexState *ls, TValue *tv)
|
||||
if (c == 'I') { /* Return cdata holding a complex number. */
|
||||
GCcdata *cd = lj_cdata_new_(ls->L, CTID_COMPLEX_DOUBLE, 2*sizeof(double));
|
||||
((double *)cdataptr(cd))[0] = 0;
|
||||
((double *)cdataptr(cd))[1] = tv->n;
|
||||
((double *)cdataptr(cd))[1] = numberVnum(tv);
|
||||
lj_parse_keepcdata(ls, tv, cd);
|
||||
}
|
||||
#endif
|
||||
if (LJ_DUALNUM && tvisnum(tv)) {
|
||||
int32_t k = lj_num2int(numV(tv));
|
||||
if ((lua_Number)k == numV(tv)) /* -0 cannot end up here. */
|
||||
setintV(tv, k);
|
||||
}
|
||||
return;
|
||||
}
|
||||
lj_lex_error(ls, TK_number, LJ_ERR_XNUMBER);
|
||||
@ -506,7 +511,7 @@ void lj_lex_init(lua_State *L)
|
||||
for (i = 0; i < TK_RESERVED; i++) {
|
||||
GCstr *s = lj_str_newz(L, tokennames[i]);
|
||||
fixstring(s); /* Reserved words are never collected. */
|
||||
s->reserved = cast_byte(i+1);
|
||||
s->reserved = (uint8_t)(i+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
14
src/lj_lib.c
14
src/lj_lib.c
@ -135,8 +135,8 @@ GCstr *lj_lib_checkstr(lua_State *L, int narg)
|
||||
if (o < L->top) {
|
||||
if (LJ_LIKELY(tvisstr(o))) {
|
||||
return strV(o);
|
||||
} else if (tvisnum(o)) {
|
||||
GCstr *s = lj_str_fromnum(L, &o->n);
|
||||
} else if (tvisnumber(o)) {
|
||||
GCstr *s = lj_str_fromnumber(L, o);
|
||||
setstrV(L, o, s);
|
||||
return s;
|
||||
}
|
||||
@ -155,14 +155,18 @@ lua_Number lj_lib_checknum(lua_State *L, int narg)
|
||||
{
|
||||
TValue *o = L->base + narg-1;
|
||||
if (!(o < L->top &&
|
||||
(tvisnum(o) || (tvisstr(o) && lj_str_tonum(strV(o), o)))))
|
||||
(tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
|
||||
lj_err_argt(L, narg, LUA_TNUMBER);
|
||||
return numV(o);
|
||||
return numberVnum(o);
|
||||
}
|
||||
|
||||
int32_t lj_lib_checkint(lua_State *L, int narg)
|
||||
{
|
||||
return lj_num2int(lj_lib_checknum(L, narg));
|
||||
TValue *o = L->base + narg-1;
|
||||
if (!(o < L->top &&
|
||||
(tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
|
||||
lj_err_argt(L, narg, LUA_TNUMBER);
|
||||
return numberVint(o);
|
||||
}
|
||||
|
||||
int32_t lj_lib_optint(lua_State *L, int narg, int32_t def)
|
||||
|
@ -41,10 +41,6 @@ LJ_FUNC GCtab *lj_lib_checktab(lua_State *L, int narg);
|
||||
LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg);
|
||||
LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst);
|
||||
|
||||
#define lj_lib_opt(L, narg, gotarg, noarg) \
|
||||
{ TValue *_o = L->base + (narg)-1; \
|
||||
if (_o < L->top && !tvisnil(_o)) { gotarg } else { noarg } }
|
||||
|
||||
/* Avoid including lj_frame.h. */
|
||||
#define lj_lib_upvalue(L, n) \
|
||||
(&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1])
|
||||
|
@ -44,7 +44,7 @@ cTValue *lj_meta_cache(GCtab *mt, MMS mm, GCstr *name)
|
||||
cTValue *mo = lj_tab_getstr(mt, name);
|
||||
lua_assert(mm <= MM_FAST);
|
||||
if (!mo || tvisnil(mo)) { /* No metamethod? */
|
||||
mt->nomm |= cast_byte(1u<<mm); /* Set negative cache flag. */
|
||||
mt->nomm |= (uint8_t)(1u<<mm); /* Set negative cache flag. */
|
||||
return NULL;
|
||||
}
|
||||
return mo;
|
||||
@ -156,6 +156,8 @@ static cTValue *str2num(cTValue *o, TValue *n)
|
||||
{
|
||||
if (tvisnum(o))
|
||||
return o;
|
||||
else if (tvisint(o))
|
||||
return (setnumV(n, (lua_Number)intV(o)), n);
|
||||
else if (tvisstr(o) && lj_str_tonum(strV(o), n))
|
||||
return n;
|
||||
else
|
||||
@ -192,8 +194,8 @@ static LJ_AINLINE int tostring(lua_State *L, TValue *o)
|
||||
{
|
||||
if (tvisstr(o)) {
|
||||
return 1;
|
||||
} else if (tvisnum(o)) {
|
||||
setstrV(L, o, lj_str_fromnum(L, &o->n));
|
||||
} else if (tvisnumber(o)) {
|
||||
setstrV(L, o, lj_str_fromnumber(L, o));
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
@ -205,12 +207,12 @@ TValue *lj_meta_cat(lua_State *L, TValue *top, int left)
|
||||
{
|
||||
do {
|
||||
int n = 1;
|
||||
if (!(tvisstr(top-1) || tvisnum(top-1)) || !tostring(L, top)) {
|
||||
if (!(tvisstr(top-1) || tvisnumber(top-1)) || !tostring(L, top)) {
|
||||
cTValue *mo = lj_meta_lookup(L, top-1, MM_concat);
|
||||
if (tvisnil(mo)) {
|
||||
mo = lj_meta_lookup(L, top, MM_concat);
|
||||
if (tvisnil(mo)) {
|
||||
if (tvisstr(top-1) || tvisnum(top-1)) top++;
|
||||
if (tvisstr(top-1) || tvisnumber(top-1)) top++;
|
||||
lj_err_optype(L, top-1, LJ_ERR_OPCAT);
|
||||
return NULL; /* unreachable */
|
||||
}
|
||||
|
@ -27,9 +27,9 @@ int lj_obj_equal(cTValue *o1, cTValue *o2)
|
||||
return 1;
|
||||
if (!tvisnum(o1))
|
||||
return gcrefeq(o1->gcr, o2->gcr);
|
||||
} else if (!tvisnum(o1) || !tvisnum(o2)) {
|
||||
} else if (!tvisnumber(o1) || !tvisnumber(o2)) {
|
||||
return 0;
|
||||
}
|
||||
return numV(o1) == numV(o2);
|
||||
return numberVnum(o1) == numberVnum(o2);
|
||||
}
|
||||
|
||||
|
63
src/lj_obj.h
63
src/lj_obj.h
@ -140,7 +140,10 @@ typedef LJ_ALIGN(8) union TValue {
|
||||
lua_Number n; /* Number object overlaps split tag/value object. */
|
||||
struct {
|
||||
LJ_ENDIAN_LOHI(
|
||||
GCRef gcr; /* GCobj reference (if any). */
|
||||
union {
|
||||
GCRef gcr; /* GCobj reference (if any). */
|
||||
int32_t i; /* Integer value. */
|
||||
};
|
||||
, uint32_t it; /* Internal object tag. Must overlap MSW of number. */
|
||||
)
|
||||
};
|
||||
@ -180,6 +183,7 @@ typedef const TValue cTValue;
|
||||
** lightuserdata | itype | void * | (32 bit platforms)
|
||||
** lightuserdata |ffff| void * | (64 bit platforms, 47 bit pointers)
|
||||
** GC objects | itype | GCRef |
|
||||
** int (LJ_DUALNUM)| itype | int |
|
||||
** number -------double------
|
||||
**
|
||||
** ORDER LJ_T
|
||||
@ -203,6 +207,7 @@ typedef const TValue cTValue;
|
||||
/* This is just the canonical number type used in some places. */
|
||||
#define LJ_TNUMX (~13u)
|
||||
|
||||
/* Integers have itype == LJ_TISNUM doubles have itype < LJ_TISNUM */
|
||||
#if LJ_64
|
||||
#define LJ_TISNUM 0xfffeffffu
|
||||
#else
|
||||
@ -322,6 +327,8 @@ typedef struct GCproto {
|
||||
gcref(mref((pt)->k, GCRef)[(idx)]))
|
||||
#define proto_knum(pt, idx) \
|
||||
check_exp((uintptr_t)(idx) < (pt)->sizekn, mref((pt)->k, lua_Number)[(idx)])
|
||||
#define proto_knumtv(pt, idx) \
|
||||
check_exp((uintptr_t)(idx) < (pt)->sizekn, &mref((pt)->k, TValue)[(idx)])
|
||||
#define proto_bc(pt) ((BCIns *)((char *)(pt) + sizeof(GCproto)))
|
||||
#define proto_bcpos(pt, pc) ((BCPos)((pc) - proto_bc(pt)))
|
||||
#define proto_uv(pt) (mref((pt)->uv, uint16_t))
|
||||
@ -650,7 +657,9 @@ typedef union GCobj {
|
||||
#define tviscdata(o) (itype(o) == LJ_TCDATA)
|
||||
#define tvistab(o) (itype(o) == LJ_TTAB)
|
||||
#define tvisudata(o) (itype(o) == LJ_TUDATA)
|
||||
#define tvisnum(o) (itype(o) <= LJ_TISNUM)
|
||||
#define tvisnumber(o) (itype(o) <= LJ_TISNUM)
|
||||
#define tvisint(o) (LJ_DUALNUM && itype(o) == LJ_TISNUM)
|
||||
#define tvisnum(o) (itype(o) < LJ_TISNUM)
|
||||
|
||||
#define tvistruecond(o) (itype(o) < LJ_TISTRUECOND)
|
||||
#define tvispri(o) (itype(o) >= LJ_TISPRI)
|
||||
@ -659,6 +668,11 @@ typedef union GCobj {
|
||||
|
||||
/* Special macros to test numbers for NaN, +0, -0, +1 and raw equality. */
|
||||
#define tvisnan(o) ((o)->n != (o)->n)
|
||||
#if LJ_64
|
||||
#define tviszero(o) (((o)->u64 << 1) == 0)
|
||||
#else
|
||||
#define tviszero(o) (((o)->u32.lo | ((o)->u32.hi << 1)) == 0)
|
||||
#endif
|
||||
#define tvispzero(o) ((o)->u64 == 0)
|
||||
#define tvismzero(o) ((o)->u64 == U64x(80000000,00000000))
|
||||
#define tvispone(o) ((o)->u64 == U64x(3ff00000,00000000))
|
||||
@ -667,9 +681,9 @@ typedef union GCobj {
|
||||
/* Macros to convert type ids. */
|
||||
#if LJ_64
|
||||
#define itypemap(o) \
|
||||
(tvisnum(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o))
|
||||
(tvisnumber(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o))
|
||||
#else
|
||||
#define itypemap(o) (tvisnum(o) ? ~LJ_TNUMX : ~itype(o))
|
||||
#define itypemap(o) (tvisnumber(o) ? ~LJ_TNUMX : ~itype(o))
|
||||
#endif
|
||||
|
||||
/* Macros to get tagged values. */
|
||||
@ -690,6 +704,7 @@ typedef union GCobj {
|
||||
#define tabV(o) check_exp(tvistab(o), &gcval(o)->tab)
|
||||
#define udataV(o) check_exp(tvisudata(o), &gcval(o)->ud)
|
||||
#define numV(o) check_exp(tvisnum(o), (o)->n)
|
||||
#define intV(o) check_exp(tvisint(o), (int32_t)(o)->i)
|
||||
|
||||
/* Macros to set tagged values. */
|
||||
#define setitype(o, i) ((o)->it = (i))
|
||||
@ -741,7 +756,29 @@ define_setV(setudataV, GCudata, LJ_TUDATA)
|
||||
#define setnanV(o) ((o)->u64 = U64x(fff80000,00000000))
|
||||
#define setpinfV(o) ((o)->u64 = U64x(7ff00000,00000000))
|
||||
#define setminfV(o) ((o)->u64 = U64x(fff00000,00000000))
|
||||
#define setintV(o, i) ((o)->n = cast_num((int32_t)(i)))
|
||||
|
||||
static LJ_AINLINE void setintV(TValue *o, int32_t i)
|
||||
{
|
||||
#if LJ_DUALNUM
|
||||
o->i = (uint32_t)i; setitype(o, LJ_TISNUM);
|
||||
#else
|
||||
o->n = (lua_Number)i;
|
||||
#endif
|
||||
}
|
||||
|
||||
static LJ_AINLINE void setint64V(TValue *o, int64_t i)
|
||||
{
|
||||
if (LJ_DUALNUM && LJ_LIKELY(i == (int64_t)(int32_t)i))
|
||||
setintV(o, (int32_t)i);
|
||||
else
|
||||
setnumV(o, (lua_Number)i);
|
||||
}
|
||||
|
||||
#if LJ_64
|
||||
#define setintptrV(o, i) setint64V((o), (i))
|
||||
#else
|
||||
#define setintptrV(o, i) setintV((o), (i))
|
||||
#endif
|
||||
|
||||
/* Copy tagged values. */
|
||||
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)
|
||||
return (uint64_t)n;
|
||||
}
|
||||
|
||||
static LJ_AINLINE int32_t numberVint(cTValue *o)
|
||||
{
|
||||
if (LJ_LIKELY(tvisint(o)))
|
||||
return intV(o);
|
||||
else
|
||||
return lj_num2int(numV(o));
|
||||
}
|
||||
|
||||
static LJ_AINLINE lua_Number numberVnum(cTValue *o)
|
||||
{
|
||||
if (LJ_UNLIKELY(tvisint(o)))
|
||||
return (lua_Number)intV(o);
|
||||
else
|
||||
return numV(o);
|
||||
}
|
||||
|
||||
/* -- Miscellaneous object handling --------------------------------------- */
|
||||
|
||||
/* Names and maps for internal and external object tags. */
|
||||
|
129
src/lj_parse.c
129
src/lj_parse.c
@ -73,7 +73,8 @@ typedef struct ExpDesc {
|
||||
#define expr_isnumk_nojump(e) (expr_isnumk(e) && !expr_hasjump(e))
|
||||
#define expr_isstrk(e) ((e)->k == VKSTR)
|
||||
|
||||
#define expr_numV(e) check_exp(expr_isnumk((e)), numV(&(e)->u.nval))
|
||||
#define expr_numtv(e) check_exp(expr_isnumk((e)), &(e)->u.nval)
|
||||
#define expr_numberV(e) numberVnum(expr_numtv((e)))
|
||||
|
||||
/* Initialize expression. */
|
||||
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)
|
||||
e->f = e->t = NO_JMP;
|
||||
}
|
||||
|
||||
/* Check number constant for +-0. */
|
||||
static int expr_numiszero(ExpDesc *e)
|
||||
{
|
||||
TValue *o = expr_numtv(e);
|
||||
return tvisint(o) ? (intV(o) == 0) : tviszero(o);
|
||||
}
|
||||
|
||||
/* Per-function linked list of scope blocks. */
|
||||
typedef struct FuncScope {
|
||||
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)
|
||||
/* Return bytecode encoding for primitive constant. */
|
||||
#define const_pri(e) check_exp((e)->k <= VKTRUE, (e)->k)
|
||||
|
||||
#define tvhaskslot(o) ((o)->u32.hi == 0)
|
||||
#define tvkslot(o) ((o)->u32.lo)
|
||||
|
||||
/* Add a number constant. */
|
||||
static BCReg const_num(FuncState *fs, ExpDesc *e)
|
||||
{
|
||||
lua_State *L = fs->L;
|
||||
TValue *val;
|
||||
TValue *o;
|
||||
lua_assert(expr_isnumk(e));
|
||||
val = lj_tab_set(L, fs->kt, &e->u.nval);
|
||||
if (tvisnum(val))
|
||||
return val->u32.lo;
|
||||
val->u64 = fs->nkn;
|
||||
o = lj_tab_set(L, fs->kt, &e->u.nval);
|
||||
if (tvhaskslot(o))
|
||||
return tvkslot(o);
|
||||
o->u64 = fs->nkn;
|
||||
return fs->nkn++;
|
||||
}
|
||||
|
||||
@ -191,13 +202,13 @@ static BCReg const_num(FuncState *fs, ExpDesc *e)
|
||||
static BCReg const_gc(FuncState *fs, GCobj *gc, uint32_t itype)
|
||||
{
|
||||
lua_State *L = fs->L;
|
||||
TValue o, *val;
|
||||
setgcV(L, &o, gc, itype);
|
||||
TValue key, *o;
|
||||
setgcV(L, &key, gc, itype);
|
||||
/* NOBARRIER: the key is new or kept alive. */
|
||||
val = lj_tab_set(L, fs->kt, &o);
|
||||
if (tvisnum(val))
|
||||
return val->u32.lo;
|
||||
val->u64 = fs->nkgc;
|
||||
o = lj_tab_set(L, fs->kt, &key);
|
||||
if (tvhaskslot(o))
|
||||
return tvkslot(o);
|
||||
o->u64 = fs->nkgc;
|
||||
return fs->nkgc++;
|
||||
}
|
||||
|
||||
@ -344,7 +355,7 @@ static void bcreg_bump(FuncState *fs, BCReg n)
|
||||
if (sz > fs->framesize) {
|
||||
if (sz >= LJ_MAX_SLOTS)
|
||||
err_syntax(fs->ls, LJ_ERR_XSLOTS);
|
||||
fs->framesize = cast_byte(sz);
|
||||
fs->framesize = (uint8_t)sz;
|
||||
}
|
||||
}
|
||||
|
||||
@ -478,11 +489,18 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
|
||||
if (e->k == VKSTR) {
|
||||
ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e));
|
||||
} else if (e->k == VKNUM) {
|
||||
lua_Number n = expr_numV(e);
|
||||
#if LJ_DUALNUM
|
||||
cTValue *tv = expr_numtv(e);
|
||||
if (tvisint(tv) && checki16(intV(tv)))
|
||||
ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)intV(tv));
|
||||
else
|
||||
#else
|
||||
lua_Number n = expr_numberV(e);
|
||||
int32_t k = lj_num2int(n);
|
||||
if (checki16(k) && n == cast_num(k))
|
||||
if (checki16(k) && n == (lua_Number)k)
|
||||
ins = BCINS_AD(BC_KSHORT, reg, (BCReg)(uint16_t)k);
|
||||
else
|
||||
#endif
|
||||
ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e));
|
||||
#if LJ_HASFFI
|
||||
} else if (e->k == VKCDATA) {
|
||||
@ -720,10 +738,19 @@ static void bcemit_branch_f(FuncState *fs, ExpDesc *e)
|
||||
static int foldarith(BinOpr opr, ExpDesc *e1, ExpDesc *e2)
|
||||
{
|
||||
TValue o;
|
||||
lua_Number n;
|
||||
if (!expr_isnumk_nojump(e1) || !expr_isnumk_nojump(e2)) return 0;
|
||||
setnumV(&o, lj_vm_foldarith(expr_numV(e1), expr_numV(e2), (int)opr-OPR_ADD));
|
||||
n = lj_vm_foldarith(expr_numberV(e1), expr_numberV(e2), (int)opr-OPR_ADD);
|
||||
setnumV(&o, n);
|
||||
if (tvisnan(&o) || tvismzero(&o)) return 0; /* Avoid NaN and -0 as consts. */
|
||||
setnumV(&e1->u.nval, numV(&o));
|
||||
if (LJ_DUALNUM) {
|
||||
int32_t k = lj_num2int(n);
|
||||
if ((lua_Number)k == n) {
|
||||
setintV(&e1->u.nval, k);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
setnumV(&e1->u.nval, n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -900,9 +927,18 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
|
||||
return;
|
||||
} else
|
||||
#endif
|
||||
if (expr_isnumk(e) && expr_numV(e) != 0) { /* Avoid folding to -0. */
|
||||
e->u.nval.u64 ^= U64x(80000000,00000000);
|
||||
return;
|
||||
if (expr_isnumk(e) && !expr_numiszero(e)) { /* Avoid folding to -0. */
|
||||
TValue *o = expr_numtv(e);
|
||||
if (tvisint(o)) {
|
||||
int32_t k = intV(o);
|
||||
if (k == -k)
|
||||
setnumV(o, -(lua_Number)k);
|
||||
else
|
||||
setintV(o, -k);
|
||||
} else {
|
||||
o->u64 ^= U64x(80000000,00000000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
expr_toanyreg(fs, e);
|
||||
@ -986,7 +1022,7 @@ static void var_new(LexState *ls, BCReg n, GCstr *name)
|
||||
static void var_add(LexState *ls, BCReg nvars)
|
||||
{
|
||||
FuncState *fs = ls->fs;
|
||||
fs->nactvar = cast_byte(fs->nactvar + nvars);
|
||||
fs->nactvar = (uint8_t)(fs->nactvar + nvars);
|
||||
for (; nvars; nvars--)
|
||||
var_get(ls, fs, fs->nactvar - nvars).startpc = fs->pc;
|
||||
}
|
||||
@ -1094,16 +1130,33 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr)
|
||||
kt = fs->kt;
|
||||
array = tvref(kt->array);
|
||||
for (i = 0; i < kt->asize; i++)
|
||||
if (tvisnum(&array[i]))
|
||||
((lua_Number *)kptr)[array[i].u32.lo] = cast_num(i);
|
||||
if (tvhaskslot(&array[i])) {
|
||||
TValue *tv = &((TValue *)kptr)[tvkslot(&array[i])];
|
||||
if (LJ_DUALNUM)
|
||||
setintV(tv, (int32_t)i);
|
||||
else
|
||||
setnumV(tv, (lua_Number)i);
|
||||
}
|
||||
node = noderef(kt->node);
|
||||
hmask = kt->hmask;
|
||||
for (i = 0; i <= hmask; i++) {
|
||||
Node *n = &node[i];
|
||||
if (tvisnum(&n->val)) {
|
||||
ptrdiff_t kidx = (ptrdiff_t)n->val.u32.lo;
|
||||
if (tvhaskslot(&n->val)) {
|
||||
ptrdiff_t kidx = (ptrdiff_t)tvkslot(&n->val);
|
||||
lua_assert(!tvisint(&n->key));
|
||||
if (tvisnum(&n->key)) {
|
||||
((lua_Number *)kptr)[kidx] = numV(&n->key);
|
||||
TValue *tv = &((TValue *)kptr)[kidx];
|
||||
if (LJ_DUALNUM) {
|
||||
lua_Number nn = numV(&n->key);
|
||||
int32_t k = lj_num2int(nn);
|
||||
lua_assert(!tvismzero(&n->key));
|
||||
if ((lua_Number)k == nn)
|
||||
setintV(tv, k);
|
||||
else
|
||||
*tv = n->key;
|
||||
} else {
|
||||
*tv = n->key;
|
||||
}
|
||||
} else {
|
||||
GCobj *o = gcV(&n->key);
|
||||
setgcref(((GCRef *)kptr)[~kidx], o);
|
||||
@ -1286,12 +1339,22 @@ static void expr_index(FuncState *fs, ExpDesc *t, ExpDesc *e)
|
||||
/* Already called: expr_toval(fs, e). */
|
||||
t->k = VINDEXED;
|
||||
if (expr_isnumk(e)) {
|
||||
lua_Number n = expr_numV(e);
|
||||
#if LJ_DUALNUM
|
||||
if (tvisint(expr_numtv(e))) {
|
||||
int32_t k = intV(expr_numtv(e));
|
||||
if (checku8(k)) {
|
||||
t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
lua_Number n = expr_numberV(e);
|
||||
int32_t k = lj_num2int(n);
|
||||
if (checku8(k) && n == cast_num(k)) {
|
||||
if (checku8(k) && n == (lua_Number)k) {
|
||||
t->u.s.aux = BCMAX_C+1+(uint32_t)k; /* 256..511: const byte key */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
} else if (expr_isstrk(e)) {
|
||||
BCReg idx = const_str(fs, e);
|
||||
if (idx <= BCMAX_C) {
|
||||
@ -1331,8 +1394,8 @@ static void expr_kvalue(TValue *v, ExpDesc *e)
|
||||
setgcref(v->gcr, obj2gco(e->u.sval));
|
||||
setitype(v, LJ_TSTR);
|
||||
} else {
|
||||
lua_assert(e->k == VKNUM);
|
||||
setnumV(v, expr_numV(e));
|
||||
lua_assert(tvisnumber(expr_numtv(e)));
|
||||
*v = *expr_numtv(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1357,7 +1420,7 @@ static void expr_table(LexState *ls, ExpDesc *e)
|
||||
if (ls->token == '[') {
|
||||
expr_bracket(ls, &key); /* Already calls expr_toval. */
|
||||
if (!expr_isk(&key)) expr_index(fs, e, &key);
|
||||
if (expr_isnumk(&key) && expr_numV(&key) == 0) needarr = 1; else nhash++;
|
||||
if (expr_isnumk(&key) && expr_numiszero(&key)) needarr = 1; else nhash++;
|
||||
lex_check(ls, '=');
|
||||
} else if (ls->token == TK_name && lj_lex_lookahead(ls) == '=') {
|
||||
expr_str(ls, &key);
|
||||
@ -2119,10 +2182,10 @@ static int predict_next(LexState *ls, FuncState *fs, BCPos pc)
|
||||
case BC_GGET:
|
||||
/* There's no inverse index (yet), so lookup the strings. */
|
||||
o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs"));
|
||||
if (o && tvisnum(o) && o->u32.lo == bc_d(ins))
|
||||
if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins))
|
||||
return 1;
|
||||
o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next"));
|
||||
if (o && tvisnum(o) && o->u32.lo == bc_d(ins))
|
||||
if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins))
|
||||
return 1;
|
||||
return 0;
|
||||
default:
|
||||
|
@ -289,7 +289,7 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
|
||||
Reg r = regsp_reg(rs);
|
||||
lua_assert(ra_hasreg(r));
|
||||
if (irt_isinteger(t)) {
|
||||
setintV(o, ex->gpr[r-RID_MIN_GPR]);
|
||||
setintV(o, (int32_t)ex->gpr[r-RID_MIN_GPR]);
|
||||
} else if (irt_isnum(t)) {
|
||||
setnumV(o, ex->fpr[r-RID_MIN_FPR]);
|
||||
#if LJ_64
|
||||
|
79
src/lj_str.c
79
src/lj_str.c
@ -171,6 +171,14 @@ void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s)
|
||||
|
||||
/* Convert string object to number. */
|
||||
int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n)
|
||||
{
|
||||
int ok = lj_str_numconv(strdata(str), n);
|
||||
if (ok && tvisint(n))
|
||||
setnumV(n, (lua_Number)intV(n));
|
||||
return ok;
|
||||
}
|
||||
|
||||
int LJ_FASTCALL lj_str_tonumber(GCstr *str, TValue *n)
|
||||
{
|
||||
return lj_str_numconv(strdata(str), n);
|
||||
}
|
||||
@ -178,7 +186,11 @@ int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n)
|
||||
/* Convert string to number. */
|
||||
int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n)
|
||||
{
|
||||
#if LJ_DUALNUM
|
||||
int sign = 0;
|
||||
#else
|
||||
lua_Number sign = 1;
|
||||
#endif
|
||||
const uint8_t *p = (const uint8_t *)s;
|
||||
while (lj_char_isspace(*p)) p++;
|
||||
if (*p == '-') { p++; sign = -1; } else if (*p == '+') { p++; }
|
||||
@ -189,21 +201,34 @@ int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n)
|
||||
if (!lj_char_isxdigit(*p))
|
||||
return 0; /* Don't accept '0x' without hex digits. */
|
||||
do {
|
||||
if (k >= 0x10000000) goto parsedbl;
|
||||
if (k >= 0x10000000u) goto parsedbl;
|
||||
k = (k << 4) + (*p & 15u);
|
||||
if (!lj_char_isdigit(*p)) k += 9;
|
||||
p++;
|
||||
} while (lj_char_isxdigit(*p));
|
||||
} else {
|
||||
while ((uint32_t)(*p - '0') < 10) {
|
||||
if (k >= 0x19999999) goto parsedbl;
|
||||
if (LJ_UNLIKELY(k >= 429496729) && (k != 429496729 || *p > '5'))
|
||||
goto parsedbl;
|
||||
k = k * 10u + (uint32_t)(*p++ - '0');
|
||||
}
|
||||
}
|
||||
while (LJ_UNLIKELY(lj_char_isspace(*p))) p++;
|
||||
if (LJ_LIKELY(*p == '\0')) {
|
||||
setnumV(n, sign * cast_num(k));
|
||||
#if LJ_DUALNUM
|
||||
if (!sign) {
|
||||
if (k < 0x80000000u) {
|
||||
setintV(n, (int32_t)k);
|
||||
return 1;
|
||||
}
|
||||
} else if (k <= 0x80000000u) {
|
||||
setintV(n, -(int32_t)k);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
setnumV(n, sign * (lua_Number)k);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
parsedbl:
|
||||
@ -239,26 +264,36 @@ size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o)
|
||||
}
|
||||
}
|
||||
|
||||
/* Print integer to buffer. Returns pointer to start. */
|
||||
char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k)
|
||||
{
|
||||
uint32_t u = (uint32_t)(k < 0 ? -k : k);
|
||||
p += 1+10;
|
||||
do { *--p = (char)('0' + u % 10); } while (u /= 10);
|
||||
if (k < 0) *--p = '-';
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Convert number to string. */
|
||||
GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np)
|
||||
{
|
||||
char buf[LUAI_MAXNUMBER2STR];
|
||||
char buf[LJ_STR_NUMBUF];
|
||||
size_t len = lj_str_bufnum(buf, (TValue *)np);
|
||||
return lj_str_new(L, buf, len);
|
||||
}
|
||||
|
||||
#if LJ_HASJIT
|
||||
/* Convert integer to string. */
|
||||
GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k)
|
||||
{
|
||||
char s[1+10];
|
||||
char *p = s+sizeof(s);
|
||||
uint32_t i = (uint32_t)(k < 0 ? -k : k);
|
||||
do { *--p = (char)('0' + i % 10); } while (i /= 10);
|
||||
if (k < 0) *--p = '-';
|
||||
char *p = lj_str_bufint(s, k);
|
||||
return lj_str_new(L, p, (size_t)(s+sizeof(s)-p));
|
||||
}
|
||||
#endif
|
||||
|
||||
GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o)
|
||||
{
|
||||
return tvisint(o) ? lj_str_fromint(L, intV(o)) : lj_str_fromnum(L, &o->n);
|
||||
}
|
||||
|
||||
/* -- String formatting --------------------------------------------------- */
|
||||
|
||||
@ -307,38 +342,34 @@ const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp)
|
||||
addchar(L, sb, va_arg(argp, int));
|
||||
break;
|
||||
case 'd': {
|
||||
char buff[1+10];
|
||||
char *p = buff+sizeof(buff);
|
||||
int32_t k = va_arg(argp, int32_t);
|
||||
uint32_t i = (uint32_t)(k < 0 ? -k : k);
|
||||
do { *--p = (char)('0' + i % 10); } while (i /= 10);
|
||||
if (k < 0) *--p = '-';
|
||||
addstr(L, sb, p, (MSize)(buff+sizeof(buff)-p));
|
||||
char buf[LJ_STR_INTBUF];
|
||||
char *p = lj_str_bufint(buf, va_arg(argp, int32_t));
|
||||
addstr(L, sb, p, (MSize)(buf+LJ_STR_INTBUF-p));
|
||||
break;
|
||||
}
|
||||
case 'f': {
|
||||
char buf[LUAI_MAXNUMBER2STR];
|
||||
char buf[LJ_STR_NUMBUF];
|
||||
TValue tv;
|
||||
MSize len;
|
||||
tv.n = cast_num(va_arg(argp, LUAI_UACNUMBER));
|
||||
tv.n = (lua_Number)(va_arg(argp, LUAI_UACNUMBER));
|
||||
len = (MSize)lj_str_bufnum(buf, &tv);
|
||||
addstr(L, sb, buf, len);
|
||||
break;
|
||||
}
|
||||
case 'p': {
|
||||
#define FMTP_CHARS (2*sizeof(ptrdiff_t))
|
||||
char buff[2+FMTP_CHARS];
|
||||
char buf[2+FMTP_CHARS];
|
||||
ptrdiff_t p = (ptrdiff_t)(va_arg(argp, void *));
|
||||
ptrdiff_t i, lasti = 2+FMTP_CHARS;
|
||||
#if LJ_64
|
||||
if ((p >> 32) == 0) /* Shorten output for true 32 bit pointers. */
|
||||
lasti = 2+2*4;
|
||||
#endif
|
||||
buff[0] = '0';
|
||||
buff[1] = 'x';
|
||||
buf[0] = '0';
|
||||
buf[1] = 'x';
|
||||
for (i = lasti-1; i >= 2; i--, p >>= 4)
|
||||
buff[i] = "0123456789abcdef"[(p & 15)];
|
||||
addstr(L, sb, buff, (MSize)lasti);
|
||||
buf[i] = "0123456789abcdef"[(p & 15)];
|
||||
addstr(L, sb, buf, (MSize)lasti);
|
||||
break;
|
||||
}
|
||||
case '%':
|
||||
|
@ -22,11 +22,15 @@ LJ_FUNC void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s);
|
||||
/* Type conversions. */
|
||||
LJ_FUNC int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n);
|
||||
LJ_FUNC int LJ_FASTCALL lj_str_tonum(GCstr *str, TValue *n);
|
||||
LJ_FUNC int LJ_FASTCALL lj_str_tonumber(GCstr *str, TValue *n);
|
||||
LJ_FUNC size_t LJ_FASTCALL lj_str_bufnum(char *s, cTValue *o);
|
||||
LJ_FUNC char * LJ_FASTCALL lj_str_bufint(char *p, int32_t k);
|
||||
LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np);
|
||||
#if LJ_HASJIT
|
||||
LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k);
|
||||
#endif
|
||||
LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o);
|
||||
|
||||
#define LJ_STR_INTBUF (1+10)
|
||||
#define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR
|
||||
|
||||
/* String formatting. */
|
||||
LJ_FUNC const char *lj_str_pushvf(lua_State *L, const char *fmt, va_list argp);
|
||||
|
33
src/lj_tab.c
33
src/lj_tab.c
@ -34,6 +34,7 @@ static LJ_AINLINE Node *hashmask(const GCtab *t, uint32_t hash)
|
||||
/* Hash an arbitrary key and return its anchor position in the hash table. */
|
||||
static Node *hashkey(const GCtab *t, cTValue *key)
|
||||
{
|
||||
lua_assert(!tvisint(key));
|
||||
if (tvisstr(key))
|
||||
return hashstr(t, strV(key));
|
||||
else if (tvisnum(key))
|
||||
@ -100,7 +101,7 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits)
|
||||
lua_assert((sizeof(GCtab) & 7) == 0);
|
||||
t = (GCtab *)lj_mem_newgco(L, sizetabcolo(asize));
|
||||
t->gct = ~LJ_TTAB;
|
||||
t->nomm = cast_byte(~0);
|
||||
t->nomm = (uint8_t)~0;
|
||||
t->colo = (int8_t)asize;
|
||||
setmref(t->array, (TValue *)((char *)t + sizeof(GCtab)));
|
||||
setgcrefnull(t->metatable);
|
||||
@ -110,7 +111,7 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits)
|
||||
} else { /* Otherwise separately allocate the array part. */
|
||||
t = lj_mem_newobj(L, GCtab);
|
||||
t->gct = ~LJ_TTAB;
|
||||
t->nomm = cast_byte(~0);
|
||||
t->nomm = (uint8_t)~0;
|
||||
t->colo = 0;
|
||||
setmref(t->array, NULL);
|
||||
setgcrefnull(t->metatable);
|
||||
@ -275,10 +276,11 @@ static void resizetab(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits)
|
||||
|
||||
static uint32_t countint(cTValue *key, uint32_t *bins)
|
||||
{
|
||||
lua_assert(!tvisint(key));
|
||||
if (tvisnum(key)) {
|
||||
lua_Number nk = numV(key);
|
||||
int32_t k = lj_num2int(nk);
|
||||
if ((uint32_t)k < LJ_MAX_ASIZE && nk == cast_num(k)) {
|
||||
if ((uint32_t)k < LJ_MAX_ASIZE && nk == (lua_Number)k) {
|
||||
bins[(k > 2 ? lj_fls((uint32_t)(k-1)) : 0)]++;
|
||||
return 1;
|
||||
}
|
||||
@ -360,7 +362,7 @@ cTValue * LJ_FASTCALL lj_tab_getinth(GCtab *t, int32_t key)
|
||||
{
|
||||
TValue k;
|
||||
Node *n;
|
||||
k.n = cast_num(key);
|
||||
k.n = (lua_Number)key;
|
||||
n = hashnum(t, &k);
|
||||
do {
|
||||
if (tvisnum(&n->key) && n->key.n == k.n)
|
||||
@ -385,10 +387,14 @@ cTValue *lj_tab_get(lua_State *L, GCtab *t, cTValue *key)
|
||||
cTValue *tv = lj_tab_getstr(t, strV(key));
|
||||
if (tv)
|
||||
return tv;
|
||||
} else if (tvisint(key)) {
|
||||
cTValue *tv = lj_tab_getint(t, intV(key));
|
||||
if (tv)
|
||||
return tv;
|
||||
} else if (tvisnum(key)) {
|
||||
lua_Number nk = numV(key);
|
||||
int32_t k = lj_num2int(nk);
|
||||
if (nk == cast_num(k)) {
|
||||
if (nk == (lua_Number)k) {
|
||||
cTValue *tv = lj_tab_getint(t, k);
|
||||
if (tv)
|
||||
return tv;
|
||||
@ -466,7 +472,7 @@ TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key)
|
||||
{
|
||||
TValue k;
|
||||
Node *n;
|
||||
k.n = cast_num(key);
|
||||
k.n = (lua_Number)key;
|
||||
n = hashnum(t, &k);
|
||||
do {
|
||||
if (tvisnum(&n->key) && n->key.n == k.n)
|
||||
@ -493,10 +499,12 @@ TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key)
|
||||
t->nomm = 0; /* Invalidate negative metamethod cache. */
|
||||
if (tvisstr(key)) {
|
||||
return lj_tab_setstr(L, t, strV(key));
|
||||
} else if (tvisint(key)) {
|
||||
return lj_tab_setint(L, t, intV(key));
|
||||
} else if (tvisnum(key)) {
|
||||
lua_Number nk = numV(key);
|
||||
int32_t k = lj_num2int(nk);
|
||||
if (nk == cast_num(k))
|
||||
if (nk == (lua_Number)k)
|
||||
return lj_tab_setint(L, t, k);
|
||||
if (tvisnan(key))
|
||||
lj_err_msg(L, LJ_ERR_NANIDX);
|
||||
@ -517,10 +525,17 @@ TValue *lj_tab_set(lua_State *L, GCtab *t, cTValue *key)
|
||||
/* Get the traversal index of a key. */
|
||||
static uint32_t keyindex(lua_State *L, GCtab *t, cTValue *key)
|
||||
{
|
||||
if (tvisnum(key)) {
|
||||
TValue tmp;
|
||||
if (tvisint(key)) {
|
||||
int32_t k = intV(key);
|
||||
if ((uint32_t)k < t->asize)
|
||||
return (uint32_t)k; /* Array key indexes: [0..t->asize-1] */
|
||||
setnumV(&tmp, (lua_Number)k);
|
||||
key = &tmp;
|
||||
} else if (tvisnum(key)) {
|
||||
lua_Number nk = numV(key);
|
||||
int32_t k = lj_num2int(nk);
|
||||
if ((uint32_t)k < t->asize && nk == cast_num(k))
|
||||
if ((uint32_t)k < t->asize && nk == (lua_Number)k)
|
||||
return (uint32_t)k; /* Array key indexes: [0..t->asize-1] */
|
||||
}
|
||||
if (!tvisnil(key)) {
|
||||
|
Loading…
Reference in New Issue
Block a user