summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c10
-rw-r--r--lobject.c9
-rw-r--r--lvm.c39
-rw-r--r--lvm.h4
4 files changed, 32 insertions, 30 deletions
diff --git a/lcode.c b/lcode.c
index 4dd823f2..34dadd1f 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.71 2013/06/25 18:57:18 roberto Exp roberto $ 2** $Id: lcode.c,v 2.72 2013/08/30 16:01:37 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*/
@@ -754,12 +754,14 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
754 TValue v1, v2, res; 754 TValue v1, v2, res;
755 lua_Integer i; 755 lua_Integer i;
756 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2)) 756 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2))
757 return 0; 757 return 0; /* non-numeric operands */
758 if (op == OP_IDIV && 758 if (op == OP_IDIV &&
759 (!tointeger(&v1, &i) || !tointeger(&v2, &i) || i == 0)) 759 (!tointeger(&v1, &i) || !tointeger(&v2, &i) || i == 0))
760 return 0; /* avoid division by 0 and conversion errors */ 760 return 0; /* avoid division by 0 and conversion errors */
761 if (op == OP_MOD && ttisinteger(&v1) && ttisinteger(&v2) && ivalue(&v2) == 0) 761 if (ttisinteger(&v1) && ttisinteger(&v2) && /* for integer operations... */
762 return 0; /* avoid module by 0 at compile time */ 762 ((op == OP_MOD && ivalue(&v2) == 0) || /* ...avoid module by 0... */
763 (op == OP_POW && ivalue(&v2) < 0))) /* ...and negative exponents */
764 return 0;
763 luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res); 765 luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res);
764 if (ttisinteger(&res)) { 766 if (ttisinteger(&res)) {
765 e1->k = VKINT; 767 e1->k = VKINT;
diff --git a/lobject.c b/lobject.c
index 92721332..32f4a191 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 2.67 2013/06/25 18:58:32 roberto Exp roberto $ 2** $Id: lobject.c,v 2.68 2013/07/10 17:15:12 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*/
@@ -77,7 +77,7 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
77 case LUA_OPSUB:return intop(-, v1, v2); 77 case LUA_OPSUB:return intop(-, v1, v2);
78 case LUA_OPMUL:return intop(*, v1, v2); 78 case LUA_OPMUL:return intop(*, v1, v2);
79 case LUA_OPMOD: return luaV_mod(L, v1, v2); 79 case LUA_OPMOD: return luaV_mod(L, v1, v2);
80 case LUA_OPPOW: return luaV_pow(v1, v2); 80 case LUA_OPPOW: return luaV_pow(L, v1, v2);
81 case LUA_OPUNM: return intop(-, 0, v1); 81 case LUA_OPUNM: return intop(-, 0, v1);
82 default: lua_assert(0); return 0; 82 default: lua_assert(0); return 0;
83 } 83 }
@@ -110,8 +110,7 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
110 } 110 }
111 else { /* other operations */ 111 else { /* other operations */
112 lua_Number n1; lua_Number n2; 112 lua_Number n1; lua_Number n2;
113 if (ttisinteger(p1) && ttisinteger(p2) && op != LUA_OPDIV && 113 if (ttisinteger(p1) && ttisinteger(p2) && op != LUA_OPDIV) {
114 (op != LUA_OPPOW || ivalue(p2) >= 0)) {
115 setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); 114 setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
116 return; 115 return;
117 } 116 }
@@ -122,7 +121,7 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
122 /* else go to the end */ 121 /* else go to the end */
123 } 122 }
124 /* could not perform raw operation; try metmethod */ 123 /* could not perform raw operation; try metmethod */
125 lua_assert(L != NULL); /* cannot fail when folding (compile time) */ 124 lua_assert(L != NULL); /* should not fail when folding (compile time) */
126 luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD)); 125 luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD));
127} 126}
128 127
diff --git a/lvm.c b/lvm.c
index cba196b0..354f40d9 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.179 2013/08/27 18:53:35 roberto Exp roberto $ 2** $Id: lvm.c,v 2.180 2013/08/29 13:49:57 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*/
@@ -333,8 +333,7 @@ lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y) {
333 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */ 333 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
334 if (y == 0) 334 if (y == 0)
335 luaG_runerror(L, "attempt to divide by zero"); 335 luaG_runerror(L, "attempt to divide by zero");
336 else /* -1 */ 336 return intop(-, 0, x); /* y==-1; avoid overflow with 0x80000...//-1 */
337 return intop(-, 0, x); /* avoid overflow with 0x80000... */
338 } 337 }
339 else { 338 else {
340 lua_Integer d = x / y; /* perform division */ 339 lua_Integer d = x / y; /* perform division */
@@ -350,8 +349,7 @@ lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) {
350 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */ 349 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
351 if (y == 0) 350 if (y == 0)
352 luaG_runerror(L, "attempt to perform 'n%%0'"); 351 luaG_runerror(L, "attempt to perform 'n%%0'");
353 else /* -1 */ 352 return 0; /* y==-1; avoid overflow with 0x80000...%-1 */
354 return 0; /* avoid overflow with 0x80000... */
355 } 353 }
356 else { 354 else {
357 lua_Integer r = x % y; 355 lua_Integer r = x % y;
@@ -363,16 +361,21 @@ lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) {
363} 361}
364 362
365 363
366lua_Integer luaV_pow (lua_Integer x, lua_Integer y) { 364lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y) {
367 lua_Integer r = 1; 365 if (y <= 0) { /* special cases: 0 or negative exponent */
368 lua_assert(y >= 0); 366 if (y < 0)
369 if (y == 0) return r; 367 luaG_runerror(L, "integer exponentiation with negative exponent");
370 for (; y > 1; y >>= 1) { 368 return 1; /* x^0 == 1 */
371 if (y & 1) r = intop(*, r, x); 369 }
372 x = intop(*, x, x); 370 else {
371 lua_Integer r = 1;
372 for (; y > 1; y >>= 1) {
373 if (y & 1) r = intop(*, r, x);
374 x = intop(*, x, x);
375 }
376 r = intop(*, r, x);
377 return r;
373 } 378 }
374 r = intop(*, r, x);
375 return r;
376} 379}
377 380
378 381
@@ -685,11 +688,9 @@ void luaV_execute (lua_State *L) {
685 TValue *rb = RKB(i); 688 TValue *rb = RKB(i);
686 TValue *rc = RKC(i); 689 TValue *rc = RKC(i);
687 lua_Number nb; lua_Number nc; 690 lua_Number nb; lua_Number nc;
688 lua_Integer ic; 691 if (ttisinteger(rb) && ttisinteger(rc)) {
689 if (ttisinteger(rb) && ttisinteger(rc) && 692 lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
690 (ic = ivalue(rc)) >= 0) { 693 setivalue(ra, luaV_pow(L, ib, ic));
691 lua_Integer ib = ivalue(rb);
692 setivalue(ra, luaV_pow(ib, ic));
693 } 694 }
694 else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { 695 else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
695 setnvalue(ra, luai_numpow(L, nb, nc)); 696 setnvalue(ra, luai_numpow(L, nb, nc));
diff --git a/lvm.h b/lvm.h
index b352e8ed..56713c83 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 2.22 2013/04/29 17:12:50 roberto Exp roberto $ 2** $Id: lvm.h,v 2.23 2013/05/02 12:31:26 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*/
@@ -43,7 +43,7 @@ LUAI_FUNC void luaV_execute (lua_State *L);
43LUAI_FUNC void luaV_concat (lua_State *L, int total); 43LUAI_FUNC void luaV_concat (lua_State *L, int total);
44LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); 44LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
45LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); 45LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
46LUAI_FUNC lua_Integer luaV_pow (lua_Integer x, lua_Integer y); 46LUAI_FUNC lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y);
47LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 47LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
48 48
49#endif 49#endif