mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
DUALNUM: Handle integer type in x86/x64 interpreter and libraries.
This commit is contained in:
parent
c031d4b6a0
commit
cead25f928
3234
src/buildvm_x64.h
3234
src/buildvm_x64.h
File diff suppressed because it is too large
Load Diff
3222
src/buildvm_x64win.h
3222
src/buildvm_x64win.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
3529
src/buildvm_x86.h
3529
src/buildvm_x86.h
File diff suppressed because it is too large
Load Diff
@ -197,6 +197,18 @@ LJLIB_ASM(tonumber) LJLIB_REC(.)
|
|||||||
#if LJ_HASFFI
|
#if LJ_HASFFI
|
||||||
if (tviscdata(o)) {
|
if (tviscdata(o)) {
|
||||||
CTState *cts = ctype_cts(L);
|
CTState *cts = ctype_cts(L);
|
||||||
|
if (LJ_DUALNUM) {
|
||||||
|
CType *ct = ctype_raw(cts, cdataV(o)->typeid);
|
||||||
|
if (ctype_isinteger_or_bool(ct->info)) {
|
||||||
|
int64_t i;
|
||||||
|
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT64), (uint8_t *)&i, o, 0);
|
||||||
|
if ((ct->size == 8 && (ct->info & CTF_UNSIGNED)) ?
|
||||||
|
(uint64_t)i <= 0x7fffffffu : checki32(i)) {
|
||||||
|
setintV(L->base-1, (int32_t)i);
|
||||||
|
return FFH_RES(1);
|
||||||
|
} /* else: retry and convert to double. */
|
||||||
|
}
|
||||||
|
}
|
||||||
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE),
|
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE),
|
||||||
(uint8_t *)&(L->base-1)->n, o, 0);
|
(uint8_t *)&(L->base-1)->n, o, 0);
|
||||||
return FFH_RES(1);
|
return FFH_RES(1);
|
||||||
@ -294,7 +306,7 @@ LJLIB_ASM(pairs)
|
|||||||
LJLIB_NOREGUV LJLIB_ASM(ipairs_aux) LJLIB_REC(.)
|
LJLIB_NOREGUV LJLIB_ASM(ipairs_aux) LJLIB_REC(.)
|
||||||
{
|
{
|
||||||
lj_lib_checktab(L, 1);
|
lj_lib_checktab(L, 1);
|
||||||
lj_lib_checknum(L, 2);
|
lj_lib_checkint(L, 2);
|
||||||
return FFH_UNREACHABLE;
|
return FFH_UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
LJLIB_ASM(bit_tobit) LJLIB_REC(bit_unary IR_TOBIT)
|
LJLIB_ASM(bit_tobit) LJLIB_REC(bit_unary IR_TOBIT)
|
||||||
{
|
{
|
||||||
lj_lib_checknum(L, 1);
|
lj_lib_checknumber(L, 1);
|
||||||
return FFH_RETRY;
|
return FFH_RETRY;
|
||||||
}
|
}
|
||||||
LJLIB_ASM_(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
|
LJLIB_ASM_(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
|
||||||
@ -29,8 +29,8 @@ LJLIB_ASM_(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP)
|
|||||||
|
|
||||||
LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL)
|
LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL)
|
||||||
{
|
{
|
||||||
lj_lib_checknum(L, 1);
|
lj_lib_checknumber(L, 1);
|
||||||
lj_lib_checknum(L, 2);
|
lj_lib_checkbit(L, 2);
|
||||||
return FFH_RETRY;
|
return FFH_RETRY;
|
||||||
}
|
}
|
||||||
LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR)
|
LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR)
|
||||||
@ -41,7 +41,7 @@ LJLIB_ASM_(bit_ror) LJLIB_REC(bit_shift IR_BROR)
|
|||||||
LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND)
|
LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
do { lj_lib_checknum(L, ++i); } while (L->base+i < L->top);
|
do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
|
||||||
return FFH_RETRY;
|
return FFH_RETRY;
|
||||||
}
|
}
|
||||||
LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR)
|
LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR)
|
||||||
@ -51,8 +51,8 @@ LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR)
|
|||||||
|
|
||||||
LJLIB_CF(bit_tohex)
|
LJLIB_CF(bit_tohex)
|
||||||
{
|
{
|
||||||
uint32_t b = (uint32_t)lj_num2bit(lj_lib_checknum(L, 1));
|
uint32_t b = (uint32_t)lj_lib_checkbit(L, 1);
|
||||||
int32_t i, n = L->base+1 >= L->top ? 8 : lj_num2bit(lj_lib_checknum(L, 2));
|
int32_t i, n = L->base+1 >= L->top ? 8 : lj_lib_checkbit(L, 2);
|
||||||
const char *hexdigits = "0123456789abcdef";
|
const char *hexdigits = "0123456789abcdef";
|
||||||
char buf[8];
|
char buf[8];
|
||||||
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
|
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
|
||||||
|
@ -137,6 +137,13 @@ static int io_file_readnum(lua_State *L, FILE *fp)
|
|||||||
{
|
{
|
||||||
lua_Number d;
|
lua_Number d;
|
||||||
if (fscanf(fp, LUA_NUMBER_SCAN, &d) == 1) {
|
if (fscanf(fp, LUA_NUMBER_SCAN, &d) == 1) {
|
||||||
|
if (LJ_DUALNUM) {
|
||||||
|
int32_t i = lj_num2int(d);
|
||||||
|
if (d == (lua_Number)i && !tvismzero((cTValue *)&d)) {
|
||||||
|
setintV(L->top++, i);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
setnumV(L->top++, d);
|
setnumV(L->top++, d);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
@ -217,7 +224,7 @@ static int io_file_read(lua_State *L, FILE *fp, int start)
|
|||||||
io_file_readchars(L, fp, ~((size_t)0));
|
io_file_readchars(L, fp, ~((size_t)0));
|
||||||
else
|
else
|
||||||
lj_err_arg(L, n+1, LJ_ERR_INVFMT);
|
lj_err_arg(L, n+1, LJ_ERR_INVFMT);
|
||||||
} else if (tvisnum(L->base+n)) {
|
} else if (tvisnumber(L->base+n)) {
|
||||||
size_t len = (size_t)lj_lib_checkint(L, n+1);
|
size_t len = (size_t)lj_lib_checkint(L, n+1);
|
||||||
ok = len ? io_file_readchars(L, fp, len) : io_file_testeof(L, fp);
|
ok = len ? io_file_readchars(L, fp, len) : io_file_testeof(L, fp);
|
||||||
} else {
|
} else {
|
||||||
|
@ -21,12 +21,17 @@
|
|||||||
|
|
||||||
LJLIB_ASM(math_abs) LJLIB_REC(.)
|
LJLIB_ASM(math_abs) LJLIB_REC(.)
|
||||||
{
|
{
|
||||||
lj_lib_checknum(L, 1);
|
lj_lib_checknumber(L, 1);
|
||||||
return FFH_RETRY;
|
return FFH_RETRY;
|
||||||
}
|
}
|
||||||
LJLIB_ASM_(math_floor) LJLIB_REC(math_round IRFPM_FLOOR)
|
LJLIB_ASM_(math_floor) LJLIB_REC(math_round IRFPM_FLOOR)
|
||||||
LJLIB_ASM_(math_ceil) LJLIB_REC(math_round IRFPM_CEIL)
|
LJLIB_ASM_(math_ceil) LJLIB_REC(math_round IRFPM_CEIL)
|
||||||
LJLIB_ASM_(math_sqrt) LJLIB_REC(math_unary IRFPM_SQRT)
|
|
||||||
|
LJLIB_ASM(math_sqrt) LJLIB_REC(math_unary IRFPM_SQRT)
|
||||||
|
{
|
||||||
|
lj_lib_checknum(L, 1);
|
||||||
|
return FFH_RETRY;
|
||||||
|
}
|
||||||
LJLIB_ASM_(math_log) LJLIB_REC(math_unary IRFPM_LOG)
|
LJLIB_ASM_(math_log) LJLIB_REC(math_unary IRFPM_LOG)
|
||||||
LJLIB_ASM_(math_log10) LJLIB_REC(math_unary IRFPM_LOG10)
|
LJLIB_ASM_(math_log10) LJLIB_REC(math_unary IRFPM_LOG10)
|
||||||
LJLIB_ASM_(math_exp) LJLIB_REC(math_unary IRFPM_EXP)
|
LJLIB_ASM_(math_exp) LJLIB_REC(math_unary IRFPM_EXP)
|
||||||
@ -61,7 +66,7 @@ LJLIB_ASM_(math_fmod)
|
|||||||
LJLIB_ASM(math_min) LJLIB_REC(math_minmax IR_MIN)
|
LJLIB_ASM(math_min) LJLIB_REC(math_minmax IR_MIN)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
do { lj_lib_checknum(L, ++i); } while (L->base+i < L->top);
|
do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
|
||||||
return FFH_RETRY;
|
return FFH_RETRY;
|
||||||
}
|
}
|
||||||
LJLIB_ASM_(math_max) LJLIB_REC(math_minmax IR_MAX)
|
LJLIB_ASM_(math_max) LJLIB_REC(math_minmax IR_MAX)
|
||||||
@ -137,13 +142,42 @@ LJLIB_CF(math_random) LJLIB_REC(.)
|
|||||||
u.u64 = lj_math_random_step(rs);
|
u.u64 = lj_math_random_step(rs);
|
||||||
d = u.d - 1.0;
|
d = u.d - 1.0;
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
|
#if LJ_DUALNUM
|
||||||
|
int isint = 1;
|
||||||
|
double r1;
|
||||||
|
lj_lib_checknumber(L, 1);
|
||||||
|
if (tvisint(L->base)) {
|
||||||
|
r1 = (lua_Number)intV(L->base);
|
||||||
|
} else {
|
||||||
|
isint = 0;
|
||||||
|
r1 = numV(L->base);
|
||||||
|
}
|
||||||
|
#else
|
||||||
double r1 = lj_lib_checknum(L, 1);
|
double r1 = lj_lib_checknum(L, 1);
|
||||||
|
#endif
|
||||||
if (n == 1) {
|
if (n == 1) {
|
||||||
d = floor(d*r1) + 1.0; /* d is an int in range [1, r1] */
|
d = floor(d*r1) + 1.0; /* d is an int in range [1, r1] */
|
||||||
} else {
|
} else {
|
||||||
|
#if LJ_DUALNUM
|
||||||
|
double r2;
|
||||||
|
lj_lib_checknumber(L, 2);
|
||||||
|
if (tvisint(L->base+1)) {
|
||||||
|
r2 = (lua_Number)intV(L->base+1);
|
||||||
|
} else {
|
||||||
|
isint = 0;
|
||||||
|
r2 = numV(L->base+1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
double r2 = lj_lib_checknum(L, 2);
|
double r2 = lj_lib_checknum(L, 2);
|
||||||
|
#endif
|
||||||
d = floor(d*(r2-r1+1.0)) + r1; /* d is an int in range [r1, r2] */
|
d = floor(d*(r2-r1+1.0)) + r1; /* d is an int in range [r1, r2] */
|
||||||
}
|
}
|
||||||
|
#if LJ_DUALNUM
|
||||||
|
if (isint) {
|
||||||
|
setintV(L->top-1, lj_num2int(d));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} /* else: d is a double in range [0, 1] */
|
} /* else: d is a double in range [0, 1] */
|
||||||
setnumV(L->top++, d);
|
setnumV(L->top++, d);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -217,7 +217,7 @@ static const char *searchpath (lua_State *L, const char *name,
|
|||||||
lua_pushliteral(L, ""); /* error accumulator */
|
lua_pushliteral(L, ""); /* error accumulator */
|
||||||
while ((path = pushnexttemplate(L, path)) != NULL) {
|
while ((path = pushnexttemplate(L, path)) != NULL) {
|
||||||
const char *filename = luaL_gsub(L, lua_tostring(L, -1),
|
const char *filename = luaL_gsub(L, lua_tostring(L, -1),
|
||||||
LUA_PATH_MARK, name);
|
LUA_PATH_MARK, name);
|
||||||
lua_remove(L, -2); /* remove path template */
|
lua_remove(L, -2); /* remove path template */
|
||||||
if (readable(filename)) /* does file exist and is readable? */
|
if (readable(filename)) /* does file exist and is readable? */
|
||||||
return filename; /* return that file name */
|
return filename; /* return that file name */
|
||||||
|
@ -702,6 +702,38 @@ static void addintlen(char *form)
|
|||||||
form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
|
form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned LUA_INTFRM_T num2intfrm(lua_State *L, int arg)
|
||||||
|
{
|
||||||
|
if (sizeof(LUA_INTFRM_T) == 4) {
|
||||||
|
return (LUA_INTFRM_T)lj_lib_checkbit(L, arg);
|
||||||
|
} else {
|
||||||
|
cTValue *o;
|
||||||
|
lj_lib_checknumber(L, arg);
|
||||||
|
o = L->base+arg-1;
|
||||||
|
if (tvisint(o))
|
||||||
|
return (LUA_INTFRM_T)intV(o);
|
||||||
|
else
|
||||||
|
return (LUA_INTFRM_T)numV(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned LUA_INTFRM_T num2uintfrm(lua_State *L, int arg)
|
||||||
|
{
|
||||||
|
if (sizeof(LUA_INTFRM_T) == 4) {
|
||||||
|
return (unsigned LUA_INTFRM_T)lj_lib_checkbit(L, arg);
|
||||||
|
} else {
|
||||||
|
cTValue *o;
|
||||||
|
lj_lib_checknumber(L, arg);
|
||||||
|
o = L->base+arg-1;
|
||||||
|
if (tvisint(o))
|
||||||
|
return (unsigned LUA_INTFRM_T)intV(o);
|
||||||
|
else if ((int32_t)o->u32.hi < 0)
|
||||||
|
return (unsigned LUA_INTFRM_T)(LUA_INTFRM_T)numV(o);
|
||||||
|
else
|
||||||
|
return (unsigned LUA_INTFRM_T)numV(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LJLIB_CF(string_format)
|
LJLIB_CF(string_format)
|
||||||
{
|
{
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
@ -726,11 +758,11 @@ LJLIB_CF(string_format)
|
|||||||
break;
|
break;
|
||||||
case 'd': case 'i':
|
case 'd': case 'i':
|
||||||
addintlen(form);
|
addintlen(form);
|
||||||
sprintf(buff, form, (LUA_INTFRM_T)lj_lib_checknum(L, arg));
|
sprintf(buff, form, num2intfrm(L, arg));
|
||||||
break;
|
break;
|
||||||
case 'o': case 'u': case 'x': case 'X':
|
case 'o': case 'u': case 'x': case 'X':
|
||||||
addintlen(form);
|
addintlen(form);
|
||||||
sprintf(buff, form, (unsigned LUA_INTFRM_T)lj_lib_checknum(L, arg));
|
sprintf(buff, form, num2uintfrm(L, arg));
|
||||||
break;
|
break;
|
||||||
case 'e': case 'E': case 'f': case 'g': case 'G': {
|
case 'e': case 'E': case 'f': case 'g': case 'G': {
|
||||||
TValue tv;
|
TValue tv;
|
||||||
|
41
src/lj_lib.c
41
src/lj_lib.c
@ -151,13 +151,29 @@ GCstr *lj_lib_optstr(lua_State *L, int narg)
|
|||||||
return (o < L->top && !tvisnil(o)) ? lj_lib_checkstr(L, narg) : NULL;
|
return (o < L->top && !tvisnil(o)) ? lj_lib_checkstr(L, narg) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LJ_DUALNUM
|
||||||
|
void lj_lib_checknumber(lua_State *L, int 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);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
lua_Number lj_lib_checknum(lua_State *L, int narg)
|
lua_Number lj_lib_checknum(lua_State *L, int narg)
|
||||||
{
|
{
|
||||||
TValue *o = L->base + narg-1;
|
TValue *o = L->base + narg-1;
|
||||||
if (!(o < L->top &&
|
if (!(o < L->top &&
|
||||||
(tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
|
(tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
|
||||||
lj_err_argt(L, narg, LUA_TNUMBER);
|
lj_err_argt(L, narg, LUA_TNUMBER);
|
||||||
return numberVnum(o);
|
if (LJ_UNLIKELY(tvisint(o))) {
|
||||||
|
lua_Number n = (lua_Number)intV(o);
|
||||||
|
setnumV(o, n);
|
||||||
|
return n;
|
||||||
|
} else {
|
||||||
|
return numV(o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t lj_lib_checkint(lua_State *L, int narg)
|
int32_t lj_lib_checkint(lua_State *L, int narg)
|
||||||
@ -166,7 +182,13 @@ int32_t lj_lib_checkint(lua_State *L, int narg)
|
|||||||
if (!(o < L->top &&
|
if (!(o < L->top &&
|
||||||
(tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
|
(tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))))
|
||||||
lj_err_argt(L, narg, LUA_TNUMBER);
|
lj_err_argt(L, narg, LUA_TNUMBER);
|
||||||
return numberVint(o);
|
if (LJ_LIKELY(tvisint(o))) {
|
||||||
|
return intV(o);
|
||||||
|
} else {
|
||||||
|
int32_t i = lj_num2int(numV(o));
|
||||||
|
if (LJ_DUALNUM) setintV(o, i);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t lj_lib_optint(lua_State *L, int narg, int32_t def)
|
int32_t lj_lib_optint(lua_State *L, int narg, int32_t def)
|
||||||
@ -175,6 +197,21 @@ int32_t lj_lib_optint(lua_State *L, int narg, int32_t def)
|
|||||||
return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def;
|
return (o < L->top && !tvisnil(o)) ? lj_lib_checkint(L, narg) : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t lj_lib_checkbit(lua_State *L, int 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);
|
||||||
|
if (LJ_LIKELY(tvisint(o))) {
|
||||||
|
return intV(o);
|
||||||
|
} else {
|
||||||
|
int32_t i = lj_num2bit(numV(o));
|
||||||
|
if (LJ_DUALNUM) setintV(o, i);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GCfunc *lj_lib_checkfunc(lua_State *L, int narg)
|
GCfunc *lj_lib_checkfunc(lua_State *L, int narg)
|
||||||
{
|
{
|
||||||
TValue *o = L->base + narg-1;
|
TValue *o = L->base + narg-1;
|
||||||
|
@ -33,9 +33,15 @@
|
|||||||
LJ_FUNC TValue *lj_lib_checkany(lua_State *L, int narg);
|
LJ_FUNC TValue *lj_lib_checkany(lua_State *L, int narg);
|
||||||
LJ_FUNC GCstr *lj_lib_checkstr(lua_State *L, int narg);
|
LJ_FUNC GCstr *lj_lib_checkstr(lua_State *L, int narg);
|
||||||
LJ_FUNC GCstr *lj_lib_optstr(lua_State *L, int narg);
|
LJ_FUNC GCstr *lj_lib_optstr(lua_State *L, int narg);
|
||||||
|
#if LJ_DUALNUM
|
||||||
|
LJ_FUNC void lj_lib_checknumber(lua_State *L, int narg);
|
||||||
|
#else
|
||||||
|
#define lj_lib_checknumber(L, narg) lj_lib_checknum((L), (narg))
|
||||||
|
#endif
|
||||||
LJ_FUNC lua_Number lj_lib_checknum(lua_State *L, int narg);
|
LJ_FUNC lua_Number lj_lib_checknum(lua_State *L, int narg);
|
||||||
LJ_FUNC int32_t lj_lib_checkint(lua_State *L, int narg);
|
LJ_FUNC int32_t lj_lib_checkint(lua_State *L, int narg);
|
||||||
LJ_FUNC int32_t lj_lib_optint(lua_State *L, int narg, int32_t def);
|
LJ_FUNC int32_t lj_lib_optint(lua_State *L, int narg, int32_t def);
|
||||||
|
LJ_FUNC int32_t lj_lib_checkbit(lua_State *L, int narg);
|
||||||
LJ_FUNC GCfunc *lj_lib_checkfunc(lua_State *L, int narg);
|
LJ_FUNC GCfunc *lj_lib_checkfunc(lua_State *L, int narg);
|
||||||
LJ_FUNC GCtab *lj_lib_checktab(lua_State *L, int narg);
|
LJ_FUNC GCtab *lj_lib_checktab(lua_State *L, int narg);
|
||||||
LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg);
|
LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg);
|
||||||
|
@ -385,10 +385,21 @@ void lj_meta_call(lua_State *L, TValue *func, TValue *top)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Helper for FORI. Coercion. */
|
/* Helper for FORI. Coercion. */
|
||||||
void LJ_FASTCALL lj_meta_for(lua_State *L, TValue *base)
|
void LJ_FASTCALL lj_meta_for(lua_State *L, TValue *o)
|
||||||
{
|
{
|
||||||
if (!str2num(base, base)) lj_err_msg(L, LJ_ERR_FORINIT);
|
if (!(tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o))))
|
||||||
if (!str2num(base+1, base+1)) lj_err_msg(L, LJ_ERR_FORLIM);
|
lj_err_msg(L, LJ_ERR_FORINIT);
|
||||||
if (!str2num(base+2, base+2)) lj_err_msg(L, LJ_ERR_FORSTEP);
|
if (!(tvisnumber(o+1) || (tvisstr(o+1) && lj_str_tonumber(strV(o+1), o+1))))
|
||||||
|
lj_err_msg(L, LJ_ERR_FORLIM);
|
||||||
|
if (!(tvisnumber(o+2) || (tvisstr(o+2) && lj_str_tonumber(strV(o+2), o+2))))
|
||||||
|
lj_err_msg(L, LJ_ERR_FORSTEP);
|
||||||
|
#if LJ_DUALNUM
|
||||||
|
/* Ensure all slots are integers or all slots are numbers. */
|
||||||
|
if (!(tvisint(o) && tvisint(o+1) && tvisint(o+2))) {
|
||||||
|
if (tvisint(o)) setnumV(o, (lua_Number)intV(o));
|
||||||
|
if (tvisint(o+1)) setnumV(o+1, (lua_Number)intV(o+1));
|
||||||
|
if (tvisint(o+2)) setnumV(o+2, (lua_Number)intV(o+2));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,6 +935,7 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e)
|
|||||||
setnumV(o, -(lua_Number)k);
|
setnumV(o, -(lua_Number)k);
|
||||||
else
|
else
|
||||||
setintV(o, -k);
|
setintV(o, -k);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
o->u64 ^= U64x(80000000,00000000);
|
o->u64 ^= U64x(80000000,00000000);
|
||||||
return;
|
return;
|
||||||
|
@ -187,7 +187,7 @@ int LJ_FASTCALL lj_str_tonumber(GCstr *str, TValue *n)
|
|||||||
int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n)
|
int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n)
|
||||||
{
|
{
|
||||||
#if LJ_DUALNUM
|
#if LJ_DUALNUM
|
||||||
int sign = 0;
|
int sign = 1;
|
||||||
#else
|
#else
|
||||||
lua_Number sign = 1;
|
lua_Number sign = 1;
|
||||||
#endif
|
#endif
|
||||||
@ -216,7 +216,7 @@ int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n)
|
|||||||
while (LJ_UNLIKELY(lj_char_isspace(*p))) p++;
|
while (LJ_UNLIKELY(lj_char_isspace(*p))) p++;
|
||||||
if (LJ_LIKELY(*p == '\0')) {
|
if (LJ_LIKELY(*p == '\0')) {
|
||||||
#if LJ_DUALNUM
|
#if LJ_DUALNUM
|
||||||
if (!sign) {
|
if (sign == 1) {
|
||||||
if (k < 0x80000000u) {
|
if (k < 0x80000000u) {
|
||||||
setintV(n, (int32_t)k);
|
setintV(n, (int32_t)k);
|
||||||
return 1;
|
return 1;
|
||||||
@ -225,10 +225,9 @@ int LJ_FASTCALL lj_str_numconv(const char *s, TValue *n)
|
|||||||
setintV(n, -(int32_t)k);
|
setintV(n, -(int32_t)k);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
setnumV(n, sign * (lua_Number)k);
|
setnumV(n, sign * (lua_Number)k);
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parsedbl:
|
parsedbl:
|
||||||
|
@ -27,7 +27,7 @@ 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_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);
|
LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np);
|
||||||
LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k);
|
LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k);
|
||||||
LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o);
|
LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o);
|
||||||
|
|
||||||
#define LJ_STR_INTBUF (1+10)
|
#define LJ_STR_INTBUF (1+10)
|
||||||
#define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR
|
#define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR
|
||||||
|
Loading…
Reference in New Issue
Block a user