diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-08 12:50:23 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-08 12:50:23 -0200 |
| commit | 26679ea35bf261f2b5edc2fb2f5cc4df483fd50d (patch) | |
| tree | 94c99ed74251cdf3e10a7e52560c3a7a78053ad1 | |
| parent | c3e5946fb2b7b5781d9bca9d303967abe6263482 (diff) | |
| download | lua-26679ea35bf261f2b5edc2fb2f5cc4df483fd50d.tar.gz lua-26679ea35bf261f2b5edc2fb2f5cc4df483fd50d.tar.bz2 lua-26679ea35bf261f2b5edc2fb2f5cc4df483fd50d.zip | |
new function 'luaV_flttointeger' to convert floats to integers (without
string coercions) + string operands to bitwise operations handled
by string metamethods
| -rw-r--r-- | lcode.c | 6 | ||||
| -rw-r--r-- | ldebug.c | 4 | ||||
| -rw-r--r-- | lobject.c | 4 | ||||
| -rw-r--r-- | lstrlib.c | 80 | ||||
| -rw-r--r-- | ltable.c | 6 | ||||
| -rw-r--r-- | ltm.c | 5 | ||||
| -rw-r--r-- | lvm.c | 60 | ||||
| -rw-r--r-- | lvm.h | 9 |
8 files changed, 126 insertions, 48 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 2.130 2017/10/04 21:56:32 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.131 2017/11/07 17:20:42 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -611,7 +611,7 @@ static void luaK_float (FuncState *fs, int reg, lua_Number f) { | |||
| 611 | TValue v; | 611 | TValue v; |
| 612 | lua_Integer fi; | 612 | lua_Integer fi; |
| 613 | setfltvalue(&v, f); | 613 | setfltvalue(&v, f); |
| 614 | if (luaV_tointeger(&v, &fi, 0) && | 614 | if (luaV_flttointeger(&v, &fi, 0) && |
| 615 | l_castS2U(fi) + MAXARG_sBx <= l_castS2U(MAXARG_Bx)) | 615 | l_castS2U(fi) + MAXARG_sBx <= l_castS2U(MAXARG_Bx)) |
| 616 | luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); | 616 | luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); |
| 617 | else | 617 | else |
| @@ -1146,7 +1146,7 @@ static int validop (int op, TValue *v1, TValue *v2) { | |||
| 1146 | case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: | 1146 | case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: |
| 1147 | case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */ | 1147 | case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */ |
| 1148 | lua_Integer i; | 1148 | lua_Integer i; |
| 1149 | return (tointeger(v1, &i) && tointeger(v2, &i)); | 1149 | return (tointegerns(v1, &i) && tointegerns(v2, &i)); |
| 1150 | } | 1150 | } |
| 1151 | case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */ | 1151 | case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */ |
| 1152 | return (nvalue(v2) != 0); | 1152 | return (nvalue(v2) != 0); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 2.140 2017/11/07 13:25:26 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.141 2017/11/07 17:20:42 roberto Exp roberto $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -670,7 +670,7 @@ l_noret luaG_opinterror (lua_State *L, const TValue *p1, | |||
| 670 | */ | 670 | */ |
| 671 | l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { | 671 | l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { |
| 672 | lua_Integer temp; | 672 | lua_Integer temp; |
| 673 | if (!tointeger(p1, &temp)) | 673 | if (!tointegerns(p1, &temp)) |
| 674 | p2 = p1; | 674 | p2 = p1; |
| 675 | luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2)); | 675 | luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2)); |
| 676 | } | 676 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 2.117 2017/07/07 16:34:32 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 2.118 2017/10/10 20:05:40 roberto Exp roberto $ |
| 3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -127,7 +127,7 @@ int luaO_rawarith (lua_State *L, int op, const TValue *p1, const TValue *p2, | |||
| 127 | case LUA_OPSHL: case LUA_OPSHR: | 127 | case LUA_OPSHL: case LUA_OPSHR: |
| 128 | case LUA_OPBNOT: { /* operate only on integers */ | 128 | case LUA_OPBNOT: { /* operate only on integers */ |
| 129 | lua_Integer i1; lua_Integer i2; | 129 | lua_Integer i1; lua_Integer i2; |
| 130 | if (tointeger(p1, &i1) && tointeger(p2, &i2)) { | 130 | if (tointegerns(p1, &i1) && tointegerns(p2, &i2)) { |
| 131 | setivalue(res, intarith(L, op, i1, i2)); | 131 | setivalue(res, intarith(L, op, i1, i2)); |
| 132 | return 1; | 132 | return 1; |
| 133 | } | 133 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstrlib.c,v 1.256 2017/05/19 16:29:40 roberto Exp roberto $ | 2 | ** $Id: lstrlib.c,v 1.257 2017/07/07 16:34:32 roberto Exp roberto $ |
| 3 | ** Standard library for string operations and pattern-matching | 3 | ** Standard library for string operations and pattern-matching |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -220,17 +220,49 @@ static int tonum (lua_State *L, int arg) { | |||
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | 222 | ||
| 223 | static int toint (lua_State *L, int arg) { | ||
| 224 | if (!tonum(L, arg)) | ||
| 225 | return 0; /* not coercible to a number */ | ||
| 226 | else if (lua_isinteger(L, arg)) | ||
| 227 | return 1; /* already an integer */ | ||
| 228 | else { /* a float */ | ||
| 229 | int ok; | ||
| 230 | lua_Integer n = lua_tointegerx(L, arg, &ok); | ||
| 231 | if (!ok) | ||
| 232 | return 0; | ||
| 233 | else { | ||
| 234 | lua_pop(L, 1); /* remove the float */ | ||
| 235 | lua_pushinteger(L, n); /* push an integer */ | ||
| 236 | return 1; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | |||
| 242 | static void trymt (lua_State *L, const char *mtname) { | ||
| 243 | lua_settop(L, 2); /* back to the original arguments */ | ||
| 244 | if (lua_type(L, 2) == LUA_TSTRING || !luaL_getmetafield(L, 2, mtname)) | ||
| 245 | luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2, | ||
| 246 | luaL_typename(L, -2), luaL_typename(L, -1)); | ||
| 247 | lua_insert(L, -3); /* put metamethod before arguments */ | ||
| 248 | lua_call(L, 2, 1); /* call metamethod */ | ||
| 249 | } | ||
| 250 | |||
| 251 | |||
| 223 | static int arith (lua_State *L, int op, const char *mtname) { | 252 | static int arith (lua_State *L, int op, const char *mtname) { |
| 224 | if (tonum(L, 1) && tonum(L, 2)) | 253 | if (tonum(L, 1) && tonum(L, 2)) |
| 225 | lua_arith(L, op); /* result will be on the top */ | 254 | lua_arith(L, op); /* result will be on the top */ |
| 226 | else { | 255 | else |
| 227 | lua_settop(L, 2); /* back to the original arguments */ | 256 | trymt(L, mtname); |
| 228 | if (lua_type(L, 2) == LUA_TSTRING || !luaL_getmetafield(L, 2, mtname)) | 257 | return 1; |
| 229 | return luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2, | 258 | } |
| 230 | luaL_typename(L, -2), luaL_typename(L, -1)); | 259 | |
| 231 | lua_insert(L, -3); /* put metamethod before arguments */ | 260 | |
| 232 | lua_call(L, 2, 1); /* call metamethod */ | 261 | static int bitwise (lua_State *L, int op, const char *mtname) { |
| 233 | } | 262 | if (toint(L, 1) && toint(L, 2)) |
| 263 | lua_arith(L, op); /* result will be on the top */ | ||
| 264 | else | ||
| 265 | trymt(L, mtname); | ||
| 234 | return 1; | 266 | return 1; |
| 235 | } | 267 | } |
| 236 | 268 | ||
| @@ -267,6 +299,30 @@ static int arith_unm (lua_State *L) { | |||
| 267 | return arith(L, LUA_OPUNM, "__unm"); | 299 | return arith(L, LUA_OPUNM, "__unm"); |
| 268 | } | 300 | } |
| 269 | 301 | ||
| 302 | static int bitwise_band (lua_State *L) { | ||
| 303 | return bitwise(L, LUA_OPBAND, "__band"); | ||
| 304 | } | ||
| 305 | |||
| 306 | static int bitwise_bor (lua_State *L) { | ||
| 307 | return bitwise(L, LUA_OPBOR, "__bor"); | ||
| 308 | } | ||
| 309 | |||
| 310 | static int bitwise_bxor (lua_State *L) { | ||
| 311 | return bitwise(L, LUA_OPBXOR, "__bxor"); | ||
| 312 | } | ||
| 313 | |||
| 314 | static int bitwise_shl (lua_State *L) { | ||
| 315 | return bitwise(L, LUA_OPSHL, "__shl"); | ||
| 316 | } | ||
| 317 | |||
| 318 | static int bitwise_shr (lua_State *L) { | ||
| 319 | return bitwise(L, LUA_OPSHR, "__shr"); | ||
| 320 | } | ||
| 321 | |||
| 322 | static int bitwise_bnot (lua_State *L) { | ||
| 323 | return bitwise(L, LUA_OPBNOT, "__bnot"); | ||
| 324 | } | ||
| 325 | |||
| 270 | 326 | ||
| 271 | static const luaL_Reg stringmetamethods[] = { | 327 | static const luaL_Reg stringmetamethods[] = { |
| 272 | {"__add", arith_add}, | 328 | {"__add", arith_add}, |
| @@ -277,6 +333,12 @@ static const luaL_Reg stringmetamethods[] = { | |||
| 277 | {"__div", arith_div}, | 333 | {"__div", arith_div}, |
| 278 | {"__idiv", arith_idiv}, | 334 | {"__idiv", arith_idiv}, |
| 279 | {"__unm", arith_unm}, | 335 | {"__unm", arith_unm}, |
| 336 | {"__band", bitwise_band}, | ||
| 337 | {"__bor", bitwise_bor}, | ||
| 338 | {"__bxor", bitwise_bxor}, | ||
| 339 | {"__shl", bitwise_shl}, | ||
| 340 | {"__shr", bitwise_shr}, | ||
| 341 | {"__bnot", bitwise_bnot}, | ||
| 280 | {"__index", NULL}, /* placeholder */ | 342 | {"__index", NULL}, /* placeholder */ |
| 281 | {NULL, NULL} | 343 | {NULL, NULL} |
| 282 | }; | 344 | }; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 2.124 2017/06/12 14:21:44 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.125 2017/06/29 15:06:44 roberto Exp roberto $ |
| 3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -495,7 +495,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | |||
| 495 | if (ttisnil(key)) luaG_runerror(L, "table index is nil"); | 495 | if (ttisnil(key)) luaG_runerror(L, "table index is nil"); |
| 496 | else if (ttisfloat(key)) { | 496 | else if (ttisfloat(key)) { |
| 497 | lua_Integer k; | 497 | lua_Integer k; |
| 498 | if (luaV_tointeger(key, &k, 0)) { /* does index fit in an integer? */ | 498 | if (luaV_flttointeger(key, &k, 0)) { /* does index fit in an integer? */ |
| 499 | setivalue(&aux, k); | 499 | setivalue(&aux, k); |
| 500 | key = &aux; /* insert it as an integer */ | 500 | key = &aux; /* insert it as an integer */ |
| 501 | } | 501 | } |
| @@ -604,7 +604,7 @@ const TValue *luaH_get (Table *t, const TValue *key) { | |||
| 604 | case LUA_TNIL: return luaO_nilobject; | 604 | case LUA_TNIL: return luaO_nilobject; |
| 605 | case LUA_TNUMFLT: { | 605 | case LUA_TNUMFLT: { |
| 606 | lua_Integer k; | 606 | lua_Integer k; |
| 607 | if (luaV_tointeger(key, &k, 0)) /* index is int? */ | 607 | if (luaV_flttointeger(key, &k, 0)) /* index is an integral? */ |
| 608 | return luaH_getint(t, k); /* use specialized version */ | 608 | return luaH_getint(t, k); /* use specialized version */ |
| 609 | /* else... */ | 609 | /* else... */ |
| 610 | } /* FALLTHROUGH */ | 610 | } /* FALLTHROUGH */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.c,v 2.45 2017/10/04 15:49:05 roberto Exp $ | 2 | ** $Id: ltm.c,v 2.47 2017/11/07 13:25:26 roberto Exp roberto $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -153,8 +153,7 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
| 153 | /* call never returns, but to avoid warnings: *//* FALLTHROUGH */ | 153 | /* call never returns, but to avoid warnings: *//* FALLTHROUGH */ |
| 154 | case TM_BAND: case TM_BOR: case TM_BXOR: | 154 | case TM_BAND: case TM_BOR: case TM_BXOR: |
| 155 | case TM_SHL: case TM_SHR: case TM_BNOT: { | 155 | case TM_SHL: case TM_SHR: case TM_BNOT: { |
| 156 | lua_Number dummy; | 156 | if (ttisnumber(p1) && ttisnumber(p2)) |
| 157 | if (tonumber(p1, &dummy) && tonumber(p2, &dummy)) | ||
| 158 | luaG_tointerror(L, p1, p2); | 157 | luaG_tointerror(L, p1, p2); |
| 159 | else | 158 | else |
| 160 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); | 159 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.306 2017/11/07 13:25:26 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.307 2017/11/07 17:20:42 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -74,7 +74,7 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) { | |||
| 74 | *n = cast_num(ivalue(obj)); | 74 | *n = cast_num(ivalue(obj)); |
| 75 | return 1; | 75 | return 1; |
| 76 | } | 76 | } |
| 77 | else if (cvt2num(obj) && /* string convertible to number? */ | 77 | else if (cvt2num(obj) && /* string coercible to number? */ |
| 78 | luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) { | 78 | luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) { |
| 79 | *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */ | 79 | *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */ |
| 80 | return 1; | 80 | return 1; |
| @@ -85,15 +85,15 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) { | |||
| 85 | 85 | ||
| 86 | 86 | ||
| 87 | /* | 87 | /* |
| 88 | ** try to convert a value to an integer, rounding according to 'mode': | 88 | ** try to convert a float to an integer, rounding according to 'mode': |
| 89 | ** mode == 0: accepts only integral values | 89 | ** mode == 0: accepts only integral values |
| 90 | ** mode == 1: takes the floor of the number | 90 | ** mode == 1: takes the floor of the number |
| 91 | ** mode == 2: takes the ceil of the number | 91 | ** mode == 2: takes the ceil of the number |
| 92 | */ | 92 | */ |
| 93 | int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | 93 | int luaV_flttointeger (const TValue *obj, lua_Integer *p, int mode) { |
| 94 | TValue v; | 94 | if (!ttisfloat(obj)) |
| 95 | again: | 95 | return 0; |
| 96 | if (ttisfloat(obj)) { | 96 | else { |
| 97 | lua_Number n = fltvalue(obj); | 97 | lua_Number n = fltvalue(obj); |
| 98 | lua_Number f = l_floor(n); | 98 | lua_Number f = l_floor(n); |
| 99 | if (n != f) { /* not an integral value? */ | 99 | if (n != f) { /* not an integral value? */ |
| @@ -103,16 +103,23 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | |||
| 103 | } | 103 | } |
| 104 | return lua_numbertointeger(f, p); | 104 | return lua_numbertointeger(f, p); |
| 105 | } | 105 | } |
| 106 | else if (ttisinteger(obj)) { | 106 | } |
| 107 | |||
| 108 | |||
| 109 | /* | ||
| 110 | ** try to convert a value to an integer. ("Fast track" is handled | ||
| 111 | ** by macro 'tointeger'.) | ||
| 112 | */ | ||
| 113 | int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | ||
| 114 | TValue v; | ||
| 115 | if (cvt2num(obj) && luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) | ||
| 116 | obj = &v; /* change string to its corresponding number */ | ||
| 117 | if (ttisinteger(obj)) { | ||
| 107 | *p = ivalue(obj); | 118 | *p = ivalue(obj); |
| 108 | return 1; | 119 | return 1; |
| 109 | } | 120 | } |
| 110 | else if (cvt2num(obj) && | 121 | else |
| 111 | luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) { | 122 | return luaV_flttointeger(obj, p, mode); |
| 112 | obj = &v; | ||
| 113 | goto again; /* convert result from 'luaO_str2num' to an integer */ | ||
| 114 | } | ||
| 115 | return 0; /* conversion failed */ | ||
| 116 | } | 123 | } |
| 117 | 124 | ||
| 118 | 125 | ||
| @@ -120,9 +127,9 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | |||
| 120 | ** Try to convert a 'for' limit to an integer, preserving the semantics | 127 | ** Try to convert a 'for' limit to an integer, preserving the semantics |
| 121 | ** of the loop. (The following explanation assumes a non-negative step; | 128 | ** of the loop. (The following explanation assumes a non-negative step; |
| 122 | ** it is valid for negative steps mutatis mutandis.) | 129 | ** it is valid for negative steps mutatis mutandis.) |
| 123 | ** If the limit can be converted to an integer, rounding down, that is | 130 | ** If the limit is an integer or can be converted to an integer, |
| 124 | ** it. | 131 | ** rounding down, that is it. |
| 125 | ** Otherwise, check whether the limit can be converted to a number. If | 132 | ** Otherwise, check whether the limit can be converted to a float. If |
| 126 | ** the number is too large, it is OK to set the limit as LUA_MAXINTEGER, | 133 | ** the number is too large, it is OK to set the limit as LUA_MAXINTEGER, |
| 127 | ** which means no limit. If the number is too negative, the loop | 134 | ** which means no limit. If the number is too negative, the loop |
| 128 | ** should not run, because any initial integer value is larger than the | 135 | ** should not run, because any initial integer value is larger than the |
| @@ -133,7 +140,10 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | |||
| 133 | static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, | 140 | static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, |
| 134 | int *stopnow) { | 141 | int *stopnow) { |
| 135 | *stopnow = 0; /* usually, let loops run */ | 142 | *stopnow = 0; /* usually, let loops run */ |
| 136 | if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */ | 143 | if (ttisinteger(obj)) |
| 144 | *p = ivalue(obj); | ||
| 145 | else if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) { | ||
| 146 | /* not coercible to in integer */ | ||
| 137 | lua_Number n; /* try to convert to float */ | 147 | lua_Number n; /* try to convert to float */ |
| 138 | if (!tonumber(obj, &n)) /* cannot convert to float? */ | 148 | if (!tonumber(obj, &n)) /* cannot convert to float? */ |
| 139 | return 0; /* not a number */ | 149 | return 0; /* not a number */ |
| @@ -411,7 +421,7 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { | |||
| 411 | return 0; /* only numbers can be equal with different variants */ | 421 | return 0; /* only numbers can be equal with different variants */ |
| 412 | else { /* two numbers with different variants */ | 422 | else { /* two numbers with different variants */ |
| 413 | lua_Integer i1, i2; /* compare them as integers */ | 423 | lua_Integer i1, i2; /* compare them as integers */ |
| 414 | return (tointeger(t1, &i1) && tointeger(t2, &i2) && i1 == i2); | 424 | return (tointegerns(t1, &i1) && tointegerns(t2, &i2) && i1 == i2); |
| 415 | } | 425 | } |
| 416 | } | 426 | } |
| 417 | /* values have same type and same variant */ | 427 | /* values have same type and same variant */ |
| @@ -1144,7 +1154,7 @@ void luaV_execute (lua_State *L) { | |||
| 1144 | TValue *rb = vRB(i); | 1154 | TValue *rb = vRB(i); |
| 1145 | TValue *rc = vRC(i); | 1155 | TValue *rc = vRC(i); |
| 1146 | lua_Integer ib; lua_Integer ic; | 1156 | lua_Integer ib; lua_Integer ic; |
| 1147 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | 1157 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { |
| 1148 | setivalue(s2v(ra), intop(&, ib, ic)); | 1158 | setivalue(s2v(ra), intop(&, ib, ic)); |
| 1149 | } | 1159 | } |
| 1150 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); } | 1160 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); } |
| @@ -1154,7 +1164,7 @@ void luaV_execute (lua_State *L) { | |||
| 1154 | TValue *rb = vRB(i); | 1164 | TValue *rb = vRB(i); |
| 1155 | TValue *rc = vRC(i); | 1165 | TValue *rc = vRC(i); |
| 1156 | lua_Integer ib; lua_Integer ic; | 1166 | lua_Integer ib; lua_Integer ic; |
| 1157 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | 1167 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { |
| 1158 | setivalue(s2v(ra), intop(|, ib, ic)); | 1168 | setivalue(s2v(ra), intop(|, ib, ic)); |
| 1159 | } | 1169 | } |
| 1160 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); } | 1170 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); } |
| @@ -1164,7 +1174,7 @@ void luaV_execute (lua_State *L) { | |||
| 1164 | TValue *rb = vRB(i); | 1174 | TValue *rb = vRB(i); |
| 1165 | TValue *rc = vRC(i); | 1175 | TValue *rc = vRC(i); |
| 1166 | lua_Integer ib; lua_Integer ic; | 1176 | lua_Integer ib; lua_Integer ic; |
| 1167 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | 1177 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { |
| 1168 | setivalue(s2v(ra), intop(^, ib, ic)); | 1178 | setivalue(s2v(ra), intop(^, ib, ic)); |
| 1169 | } | 1179 | } |
| 1170 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } | 1180 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } |
| @@ -1174,7 +1184,7 @@ void luaV_execute (lua_State *L) { | |||
| 1174 | TValue *rb = vRB(i); | 1184 | TValue *rb = vRB(i); |
| 1175 | TValue *rc = vRC(i); | 1185 | TValue *rc = vRC(i); |
| 1176 | lua_Integer ib; lua_Integer ic; | 1186 | lua_Integer ib; lua_Integer ic; |
| 1177 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | 1187 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { |
| 1178 | setivalue(s2v(ra), luaV_shiftl(ib, ic)); | 1188 | setivalue(s2v(ra), luaV_shiftl(ib, ic)); |
| 1179 | } | 1189 | } |
| 1180 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); } | 1190 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); } |
| @@ -1184,7 +1194,7 @@ void luaV_execute (lua_State *L) { | |||
| 1184 | TValue *rb = vRB(i); | 1194 | TValue *rb = vRB(i); |
| 1185 | TValue *rc = vRC(i); | 1195 | TValue *rc = vRC(i); |
| 1186 | lua_Integer ib; lua_Integer ic; | 1196 | lua_Integer ib; lua_Integer ic; |
| 1187 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | 1197 | if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) { |
| 1188 | setivalue(s2v(ra), luaV_shiftl(ib, -ic)); | 1198 | setivalue(s2v(ra), luaV_shiftl(ib, -ic)); |
| 1189 | } | 1199 | } |
| 1190 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); } | 1200 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); } |
| @@ -1248,7 +1258,7 @@ void luaV_execute (lua_State *L) { | |||
| 1248 | vmcase(OP_BNOT) { | 1258 | vmcase(OP_BNOT) { |
| 1249 | TValue *rb = vRB(i); | 1259 | TValue *rb = vRB(i); |
| 1250 | lua_Integer ib; | 1260 | lua_Integer ib; |
| 1251 | if (tointeger(rb, &ib)) { | 1261 | if (tointegerns(rb, &ib)) { |
| 1252 | setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib)); | 1262 | setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib)); |
| 1253 | } | 1263 | } |
| 1254 | else { | 1264 | else { |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.h,v 2.45 2017/06/29 15:06:44 roberto Exp roberto $ | 2 | ** $Id: lvm.h,v 2.46 2017/07/07 16:34:32 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -53,6 +53,12 @@ | |||
| 53 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I)) | 53 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I)) |
| 54 | 54 | ||
| 55 | 55 | ||
| 56 | /* convert an object to an integer (without string coercion) */ | ||
| 57 | #define tointegerns(o,i) \ | ||
| 58 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) \ | ||
| 59 | : luaV_flttointeger(o,i,LUA_FLOORN2I)) | ||
| 60 | |||
| 61 | |||
| 56 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) | 62 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) |
| 57 | 63 | ||
| 58 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) | 64 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) |
| @@ -100,6 +106,7 @@ LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); | |||
| 100 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); | 106 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); |
| 101 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); | 107 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); |
| 102 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); | 108 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); |
| 109 | LUAI_FUNC int luaV_flttointeger (const TValue *obj, lua_Integer *p, int mode); | ||
| 103 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, | 110 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, |
| 104 | StkId val, const TValue *slot); | 111 | StkId val, const TValue *slot); |
| 105 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | 112 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, |
