aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-08 12:50:23 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-08 12:50:23 -0200
commit26679ea35bf261f2b5edc2fb2f5cc4df483fd50d (patch)
tree94c99ed74251cdf3e10a7e52560c3a7a78053ad1
parentc3e5946fb2b7b5781d9bca9d303967abe6263482 (diff)
downloadlua-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.c6
-rw-r--r--ldebug.c4
-rw-r--r--lobject.c4
-rw-r--r--lstrlib.c80
-rw-r--r--ltable.c6
-rw-r--r--ltm.c5
-rw-r--r--lvm.c60
-rw-r--r--lvm.h9
8 files changed, 126 insertions, 48 deletions
diff --git a/lcode.c b/lcode.c
index 5ca597eb..c36a49ad 100644
--- a/lcode.c
+++ b/lcode.c
@@ -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);
diff --git a/ldebug.c b/ldebug.c
index e1f9c015..037809a2 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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*/
671l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { 671l_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}
diff --git a/lobject.c b/lobject.c
index 470d75db..32cdc4b0 100644
--- a/lobject.c
+++ b/lobject.c
@@ -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 }
diff --git a/lstrlib.c b/lstrlib.c
index c7cfa421..626c9159 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -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
223static 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
242static 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
223static int arith (lua_State *L, int op, const char *mtname) { 252static 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 */ 261static 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
302static int bitwise_band (lua_State *L) {
303 return bitwise(L, LUA_OPBAND, "__band");
304}
305
306static int bitwise_bor (lua_State *L) {
307 return bitwise(L, LUA_OPBOR, "__bor");
308}
309
310static int bitwise_bxor (lua_State *L) {
311 return bitwise(L, LUA_OPBXOR, "__bxor");
312}
313
314static int bitwise_shl (lua_State *L) {
315 return bitwise(L, LUA_OPSHL, "__shl");
316}
317
318static int bitwise_shr (lua_State *L) {
319 return bitwise(L, LUA_OPSHR, "__shr");
320}
321
322static int bitwise_bnot (lua_State *L) {
323 return bitwise(L, LUA_OPBNOT, "__bnot");
324}
325
270 326
271static const luaL_Reg stringmetamethods[] = { 327static 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};
diff --git a/ltable.c b/ltable.c
index 37fc3d0b..33c6852a 100644
--- a/ltable.c
+++ b/ltable.c
@@ -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 */
diff --git a/ltm.c b/ltm.c
index 91f622e4..4c03d2e4 100644
--- a/ltm.c
+++ b/ltm.c
@@ -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");
diff --git a/lvm.c b/lvm.c
index 009dfc57..24208cdd 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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*/
93int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { 93int 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*/
113int 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) {
133static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, 140static 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 {
diff --git a/lvm.h b/lvm.h
index 6bb5818d..c2e25574 100644
--- a/lvm.h
+++ b/lvm.h
@@ -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);
100LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 106LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
101LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); 107LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
102LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); 108LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
109LUAI_FUNC int luaV_flttointeger (const TValue *obj, lua_Integer *p, int mode);
103LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, 110LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
104 StkId val, const TValue *slot); 111 StkId val, const TValue *slot);
105LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 112LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,