From 4427dda116d81ef0d041c4b258432da824ad3685 Mon Sep 17 00:00:00 2001 From: Francois Perrad Date: Sat, 25 Mar 2017 12:07:16 +0100 Subject: [PATCH] backport math.tointeger from 5.3 --- src/lib_math.c | 13 +++++++++++++ src/lj_api.c | 40 +++++++++++++++++++++++++++++++++------- src/lua.h | 2 ++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/lib_math.c b/src/lib_math.c index 073a628a..e35e1c49 100644 --- a/src/lib_math.c +++ b/src/lib_math.c @@ -94,6 +94,19 @@ LJLIB_ASM(math_min) LJLIB_REC(math_minmax IR_MIN) } LJLIB_ASM_(math_max) LJLIB_REC(math_minmax IR_MAX) +LJLIB_CF(math_tointeger) +{ + int valid; + lua_Integer n = lua_tointegerx(L, 1, &valid); + if (valid) + lua_pushinteger(L, n); + else { + luaL_checkany(L, 1); + lua_pushnil(L); /* value is not convertible to integer */ + } + return 1; +} + LJLIB_CF(math_type) { if (lua_type(L, 1) == LUA_TNUMBER) { diff --git a/src/lj_api.c b/src/lj_api.c index f1c704da..802e76a8 100644 --- a/src/lj_api.c +++ b/src/lj_api.c @@ -319,16 +319,25 @@ LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2) } } -LUA_API lua_Number lua_tonumber(lua_State *L, int idx) +LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) { cTValue *o = index2adr(L, idx); TValue tmp; - if (LJ_LIKELY(tvisnumber(o))) + if (LJ_LIKELY(tvisnumber(o))) { + if (pisnum) *pisnum = 1; return numberVnum(o); - else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) + } else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) { + if (pisnum) *pisnum = 1; return numV(&tmp); - else + } else { + if (pisnum) *pisnum = 0; return 0; + } +} + +LUA_API lua_Number lua_tonumber(lua_State *L, int idx) +{ + return lua_tonumberx(L, idx, NULL); } LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx) @@ -355,22 +364,34 @@ LUALIB_API lua_Number luaL_optnumber(lua_State *L, int idx, lua_Number def) return numV(&tmp); } -LUA_API lua_Integer lua_tointeger(lua_State *L, int idx) +LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) { cTValue *o = index2adr(L, idx); TValue tmp; lua_Number n; if (LJ_LIKELY(tvisint(o))) { + if (pisnum) *pisnum = 1; return intV(o); } else if (LJ_LIKELY(tvisnum(o))) { n = numV(o); } else { - if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) + if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) { + if (pisnum) *pisnum = 0; return 0; - if (tvisint(&tmp)) + } + if (tvisint(&tmp)) { + if (pisnum) *pisnum = 1; return (lua_Integer)intV(&tmp); + } n = numV(&tmp); } +#if LJ52 + if ((lua_Number)(lua_Integer)n != n) { + if (pisnum) *pisnum = 0; + return 0; + } +#endif + if (pisnum) *pisnum = 1; #if LJ_64 return (lua_Integer)n; #else @@ -378,6 +399,11 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx) #endif } +LUA_API lua_Integer lua_tointeger(lua_State *L, int idx) +{ + return lua_tointegerx(L, idx, NULL); +} + LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx) { cTValue *o = index2adr(L, idx); diff --git a/src/lua.h b/src/lua.h index bee120ef..31571252 100644 --- a/src/lua.h +++ b/src/lua.h @@ -347,6 +347,8 @@ LUA_API void *lua_upvalueid (lua_State *L, int idx, int n); LUA_API void lua_upvaluejoin (lua_State *L, int idx1, int n1, int idx2, int n2); LUA_API int lua_loadx (lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); +LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum); +LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum); /* From Lua 5.3. */ LUA_API int lua_isinteger (lua_State *L, int idx);