2
0
Эх сурвалжийг харах

new function 'tointeger' + 'luaV_arith' replaced by 'luaT_trybinTM'

Roberto Ierusalimschy 12 жил өмнө
parent
commit
88bf2f83c0
4 өөрчлөгдсөн 70 нэмэгдсэн , 100 устгасан
  1. 20 46
      lapi.c
  2. 3 14
      ltable.c
  3. 41 37
      lvm.c
  4. 6 3
      lvm.h

+ 20 - 46
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);
 }

+ 3 - 14
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 */
     }

+ 41 - 37
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,

+ 6 - 3
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