From 88bf2f83c035e612db103d7138a8312c455e4c88 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 29 Apr 2013 14:12:50 -0300 Subject: [PATCH] new function 'tointeger' + 'luaV_arith' replaced by 'luaT_trybinTM' --- lapi.c | 66 +++++++++++++++-------------------------------- ltable.c | 17 +++--------- lvm.c | 78 +++++++++++++++++++++++++++++--------------------------- lvm.h | 9 ++++--- 4 files changed, 70 insertions(+), 100 deletions(-) diff --git a/lapi.c b/lapi.c index 7ad8817d..e870afd2 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.176 2013/04/26 16:03:50 roberto Exp roberto $ +** $Id: lapi.c,v 2.177 2013/04/26 19:51:17 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -311,10 +311,9 @@ LUA_API void lua_arith (lua_State *L, int op) { o1 = L->top - 2; o2 = L->top - 1; if (tonumber(o1, &n1) && tonumber(o2, &n2)) { - setnvalue(o1, luaO_arith(op, n1, n2)); + setnvalue(o1, luaO_numarith(op, n1, n2)); } - else - luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD)); + else luaT_trybinTM(L, o1, o2, o1, cast(TMS, op - LUA_OPADD + TM_ADD)); L->top--; lua_unlock(L); } @@ -339,53 +338,30 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { } -LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) { +LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) { lua_Number n; const TValue *o = index2addr(L, idx); - if (tonumber(o, &n)) { - if (isnum) *isnum = 1; - return n; - } - else { - if (isnum) *isnum = 0; - return 0; - } + int isnum = tonumber(o, &n); + if (!isnum) + n = 0; /* call to 'tonumber' may change 'n' even if it fails */ + if (pisnum) *pisnum = isnum; + return n; } -LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) { - lua_Number n; +LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) { + lua_Integer res; const TValue *o = index2addr(L, idx); - if (ttisinteger(o)) { - if (isnum) *isnum = 1; - return ivalue(o); - } - else if (tonumber(o, &n)) { - lua_Integer res; - lua_number2integer(res, n); - if (isnum) *isnum = 1; - return res; - } - else { - if (isnum) *isnum = 0; - return 0; - } + int isnum = tointeger(o, &res); + if (!isnum) + res = 0; /* call to 'tointeger' may change 'n' even if it fails */ + if (pisnum) *pisnum = isnum; + return res; } -LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) { - lua_Number n; - const TValue *o = index2addr(L, idx); - if (tonumber(o, &n)) { - lua_Unsigned res; - lua_number2unsigned(res, n); - if (isnum) *isnum = 1; - return res; - } - else { - if (isnum) *isnum = 0; - return 0; - } +LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *pisnum) { + return lua_tointegerx(L, idx, pisnum); /* at least for now... <<<< */ } @@ -491,17 +467,15 @@ LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { lua_lock(L); - setivalue(L->top, cast_num(n)); + setivalue(L->top, n); api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) { - lua_Number n; lua_lock(L); - n = lua_unsigned2number(u); - setnvalue(L->top, n); + setivalue(L->top, cast_integer(u)); api_incr_top(L); lua_unlock(L); } diff --git a/ltable.c b/ltable.c index 00906642..2e95ce26 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.73 2013/04/15 15:44:46 roberto Exp roberto $ +** $Id: ltable.c,v 2.74 2013/04/26 15:39:25 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -123,17 +123,6 @@ static Node *mainposition (const Table *t, const TValue *key) { } -static int numisint (lua_Number n, lua_Integer *p) { - lua_Integer k; - lua_number2integer(k, n); - if (luai_numeq(cast_num(k), n)) { /* 'k' is int? */ - *p = k; - return 1; - } - return 0; -} - - /* ** returns the index for `key' if `key' is an appropriate key to live in ** the array part of the table, -1 otherwise. @@ -423,7 +412,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { lua_Integer k; if (luai_numisnan(L, n)) luaG_runerror(L, "table index is NaN"); - if (numisint(n, &k)) { /* index is int? */ + if (luaV_numtointeger(n, &k)) { /* index is int? */ setivalue(&aux, k); key = &aux; /* insert it as an integer */ } @@ -505,7 +494,7 @@ const TValue *luaH_get (Table *t, const TValue *key) { case LUA_TNIL: return luaO_nilobject; case LUA_TNUMFLT: { lua_Integer k; - if (numisint(fltvalue(key), &k)) /* index is int? */ + if (luaV_numtointeger(fltvalue(key), &k)) /* index is int? */ return luaH_getint(t, k); /* use specialized version */ /* else go through */ } diff --git a/lvm.c b/lvm.c index 815c864a..4f32a3e0 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.165 2013/04/26 16:06:53 roberto Exp roberto $ +** $Id: lvm.c,v 2.166 2013/04/26 19:51:17 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -56,6 +56,28 @@ int luaV_tostring (lua_State *L, StkId obj) { } +int luaV_numtointeger (lua_Number n, lua_Integer *p) { + lua_Integer k; + lua_number2integer(k, n); + if (luai_numeq(cast_num(k), n)) { /* 'k' is int? */ + *p = k; + return 1; + } + return 0; +} + + +int luaV_tointeger_ (const TValue *obj, lua_Integer *p) { + lua_Number n; + lua_assert(!ttisinteger(obj)); + if (tonumber(obj, &n)) { + n = l_mathop(floor)(n); + return luaV_numtointeger(n, p); + } + else return 0; +} + + void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { int loop; for (loop = 0; loop < MAXTAGLOOP; loop++) { @@ -225,10 +247,8 @@ void luaV_concat (lua_State *L, int total) { do { StkId top = L->top; int n = 2; /* number of elements handled in this pass (at least 2) */ - if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { - if (!luaT_callbinTM(L, top-2, top-1, top-2, TM_CONCAT)) - luaG_concaterror(L, top-2, top-1); - } + if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) + luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT); else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ (void)tostring(L, top - 2); /* result is first operand */ else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { @@ -335,18 +355,6 @@ lua_Integer luaV_pow (lua_Integer x, lua_Integer y) { } -void luaV_arith (lua_State *L, StkId ra, const TValue *rb, - const TValue *rc, TMS op) { - lua_Number b, c; - if (tonumber(rb, &b) && tonumber(rc, &c)) { - lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, b, c); - setnvalue(ra, res); - } - else if (!luaT_callbinTM(L, rb, rc, ra, op)) - luaG_aritherror(L, rb, rc); -} - - /* ** check whether cached closure in prototype 'p' may be reused, that is, ** whether there is a cached closure with the same upvalues needed by @@ -422,7 +430,7 @@ void luaV_finishOp (lua_State *L) { break; } case OP_CONCAT: { - StkId top = L->top - 1; /* top when 'luaT_callbinTM' was called */ + StkId top = L->top - 1; /* top when 'luaT_trybinTM' was called */ int b = GETARG_B(inst); /* first element to concatenate */ int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ setobj2s(L, top - 2, top); /* put TM result in proper position */ @@ -586,12 +594,12 @@ void luaV_execute (lua_State *L) { lua_Number nb; lua_Number nc; if (ttisinteger(rb) && ttisinteger(rc)) { lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); - setivalue(ra, ib + ic); + setivalue(ra, cast_integer(cast_unsigned(ib) + cast_unsigned(ic))); } else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { setnvalue(ra, luai_numadd(L, nb, nc)); } - else { Protect(luaV_arith(L, ra, rb, rc, TM_ADD)); } + else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); } ) vmcase(OP_SUB, TValue *rb = RKB(i); @@ -599,12 +607,12 @@ void luaV_execute (lua_State *L) { lua_Number nb; lua_Number nc; if (ttisinteger(rb) && ttisinteger(rc)) { lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); - setivalue(ra, ib - ic); + setivalue(ra, cast_integer(cast_unsigned(ib) - cast_unsigned(ic))); } else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { setnvalue(ra, luai_numsub(L, nb, nc)); } - else { Protect(luaV_arith(L, ra, rb, rc, TM_SUB)); } + else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); } ) vmcase(OP_MUL, TValue *rb = RKB(i); @@ -612,12 +620,12 @@ void luaV_execute (lua_State *L) { lua_Number nb; lua_Number nc; if (ttisinteger(rb) && ttisinteger(rc)) { lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); - setivalue(ra, ib * ic); + setivalue(ra, cast_integer(cast_unsigned(ib) * cast_unsigned(ic))); } else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { setnvalue(ra, luai_nummul(L, nb, nc)); } - else { Protect(luaV_arith(L, ra, rb, rc, TM_MUL)); } + else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); } ) vmcase(OP_DIV, /* float division (always with floats) */ TValue *rb = RKB(i); @@ -626,20 +634,16 @@ void luaV_execute (lua_State *L) { if (tonumber(rb, &nb) && tonumber(rc, &nc)) { setnvalue(ra, luai_numdiv(L, nb, nc)); } - else { Protect(luaV_arith(L, ra, rb, rc, TM_DIV)); } + else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); } ) vmcase(OP_IDIV, /* integer division */ TValue *rb = RKB(i); TValue *rc = RKC(i); - lua_Number nb; lua_Number nc; - if (ttisinteger(rb) && ttisinteger(rc)) { - lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); + lua_Integer ib; lua_Integer ic; + if (tointeger(rb, &ib) && tointeger(rc, &ic)) { setivalue(ra, luaV_div(L, ib, ic)); } - else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { - setnvalue(ra, luai_numidiv(L, nb, nc)); - } - else { Protect(luaV_arith(L, ra, rb, rc, TM_IDIV)); } + else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); } ) vmcase(OP_MOD, TValue *rb = RKB(i); @@ -652,7 +656,7 @@ void luaV_execute (lua_State *L) { else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { setnvalue(ra, luai_nummod(L, nb, nc)); } - else { Protect(luaV_arith(L, ra, rb, rc, TM_MOD)); } + else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); } ) vmcase(OP_POW, TValue *rb = RKB(i); @@ -667,20 +671,20 @@ void luaV_execute (lua_State *L) { else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { setnvalue(ra, luai_numpow(L, nb, nc)); } - else { Protect(luaV_arith(L, ra, rb, rc, TM_POW)); } + else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); } ) vmcase(OP_UNM, TValue *rb = RB(i); + lua_Number nb; if (ttisinteger(rb)) { lua_Integer ib = ivalue(rb); setivalue(ra, -ib); } - else if (ttisfloat(rb)) { - lua_Number nb = fltvalue(rb); + else if (tonumber(rb, &nb)) { setnvalue(ra, luai_numunm(L, nb)); } else { - Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); + Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); } ) vmcase(OP_NOT, diff --git a/lvm.h b/lvm.h index 9d0d66ca..591c94ec 100644 --- a/lvm.h +++ b/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 2.20 2013/04/25 19:12:41 roberto Exp roberto $ +** $Id: lvm.h,v 2.21 2013/04/26 16:03:50 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -18,6 +18,9 @@ #define tonumber(o,n) \ (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) +#define tointeger(o,i) \ + (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger_(o,i)) + #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) @@ -26,6 +29,8 @@ LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); +LUAI_FUNC int luaV_tointeger_ (const TValue *obj, lua_Integer *p); +LUAI_FUNC int luaV_numtointeger (lua_Number n, lua_Integer *p); LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val); @@ -37,8 +42,6 @@ LUAI_FUNC void luaV_concat (lua_State *L, int total); LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); LUAI_FUNC lua_Integer luaV_pow (lua_Integer x, lua_Integer y); -LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb, - const TValue *rc, TMS op); LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); #endif