mirror of https://github.com/rusefi/lua.git
integer exponentiation with negative exponent is invalid
This commit is contained in:
parent
1a19893d6f
commit
a8f8c7fd80
10
lcode.c
10
lcode.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lcode.c,v 2.71 2013/06/25 18:57:18 roberto Exp roberto $
|
||||
** $Id: lcode.c,v 2.72 2013/08/30 16:01:37 roberto Exp roberto $
|
||||
** Code generator for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -754,12 +754,14 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
|
|||
TValue v1, v2, res;
|
||||
lua_Integer i;
|
||||
if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2))
|
||||
return 0;
|
||||
return 0; /* non-numeric operands */
|
||||
if (op == OP_IDIV &&
|
||||
(!tointeger(&v1, &i) || !tointeger(&v2, &i) || i == 0))
|
||||
return 0; /* avoid division by 0 and conversion errors */
|
||||
if (op == OP_MOD && ttisinteger(&v1) && ttisinteger(&v2) && ivalue(&v2) == 0)
|
||||
return 0; /* avoid module by 0 at compile time */
|
||||
if (ttisinteger(&v1) && ttisinteger(&v2) && /* for integer operations... */
|
||||
((op == OP_MOD && ivalue(&v2) == 0) || /* ...avoid module by 0... */
|
||||
(op == OP_POW && ivalue(&v2) < 0))) /* ...and negative exponents */
|
||||
return 0;
|
||||
luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res);
|
||||
if (ttisinteger(&res)) {
|
||||
e1->k = VKINT;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lobject.c,v 2.67 2013/06/25 18:58:32 roberto Exp roberto $
|
||||
** $Id: lobject.c,v 2.68 2013/07/10 17:15:12 roberto Exp roberto $
|
||||
** Some generic functions over Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -77,7 +77,7 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
|
|||
case LUA_OPSUB:return intop(-, v1, v2);
|
||||
case LUA_OPMUL:return intop(*, v1, v2);
|
||||
case LUA_OPMOD: return luaV_mod(L, v1, v2);
|
||||
case LUA_OPPOW: return luaV_pow(v1, v2);
|
||||
case LUA_OPPOW: return luaV_pow(L, v1, v2);
|
||||
case LUA_OPUNM: return intop(-, 0, v1);
|
||||
default: lua_assert(0); return 0;
|
||||
}
|
||||
|
@ -110,8 +110,7 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
|
|||
}
|
||||
else { /* other operations */
|
||||
lua_Number n1; lua_Number n2;
|
||||
if (ttisinteger(p1) && ttisinteger(p2) && op != LUA_OPDIV &&
|
||||
(op != LUA_OPPOW || ivalue(p2) >= 0)) {
|
||||
if (ttisinteger(p1) && ttisinteger(p2) && op != LUA_OPDIV) {
|
||||
setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
|
||||
return;
|
||||
}
|
||||
|
@ -122,7 +121,7 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
|
|||
/* else go to the end */
|
||||
}
|
||||
/* could not perform raw operation; try metmethod */
|
||||
lua_assert(L != NULL); /* cannot fail when folding (compile time) */
|
||||
lua_assert(L != NULL); /* should not fail when folding (compile time) */
|
||||
luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD));
|
||||
}
|
||||
|
||||
|
|
39
lvm.c
39
lvm.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lvm.c,v 2.179 2013/08/27 18:53:35 roberto Exp roberto $
|
||||
** $Id: lvm.c,v 2.180 2013/08/29 13:49:57 roberto Exp roberto $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -333,8 +333,7 @@ lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y) {
|
|||
if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
|
||||
if (y == 0)
|
||||
luaG_runerror(L, "attempt to divide by zero");
|
||||
else /* -1 */
|
||||
return intop(-, 0, x); /* avoid overflow with 0x80000... */
|
||||
return intop(-, 0, x); /* y==-1; avoid overflow with 0x80000...//-1 */
|
||||
}
|
||||
else {
|
||||
lua_Integer d = x / y; /* perform division */
|
||||
|
@ -350,8 +349,7 @@ lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) {
|
|||
if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
|
||||
if (y == 0)
|
||||
luaG_runerror(L, "attempt to perform 'n%%0'");
|
||||
else /* -1 */
|
||||
return 0; /* avoid overflow with 0x80000... */
|
||||
return 0; /* y==-1; avoid overflow with 0x80000...%-1 */
|
||||
}
|
||||
else {
|
||||
lua_Integer r = x % y;
|
||||
|
@ -363,16 +361,21 @@ lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) {
|
|||
}
|
||||
|
||||
|
||||
lua_Integer luaV_pow (lua_Integer x, lua_Integer y) {
|
||||
lua_Integer r = 1;
|
||||
lua_assert(y >= 0);
|
||||
if (y == 0) return r;
|
||||
for (; y > 1; y >>= 1) {
|
||||
if (y & 1) r = intop(*, r, x);
|
||||
x = intop(*, x, x);
|
||||
lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y) {
|
||||
if (y <= 0) { /* special cases: 0 or negative exponent */
|
||||
if (y < 0)
|
||||
luaG_runerror(L, "integer exponentiation with negative exponent");
|
||||
return 1; /* x^0 == 1 */
|
||||
}
|
||||
else {
|
||||
lua_Integer r = 1;
|
||||
for (; y > 1; y >>= 1) {
|
||||
if (y & 1) r = intop(*, r, x);
|
||||
x = intop(*, x, x);
|
||||
}
|
||||
r = intop(*, r, x);
|
||||
return r;
|
||||
}
|
||||
r = intop(*, r, x);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
@ -685,11 +688,9 @@ void luaV_execute (lua_State *L) {
|
|||
TValue *rb = RKB(i);
|
||||
TValue *rc = RKC(i);
|
||||
lua_Number nb; lua_Number nc;
|
||||
lua_Integer ic;
|
||||
if (ttisinteger(rb) && ttisinteger(rc) &&
|
||||
(ic = ivalue(rc)) >= 0) {
|
||||
lua_Integer ib = ivalue(rb);
|
||||
setivalue(ra, luaV_pow(ib, ic));
|
||||
if (ttisinteger(rb) && ttisinteger(rc)) {
|
||||
lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
|
||||
setivalue(ra, luaV_pow(L, ib, ic));
|
||||
}
|
||||
else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
|
||||
setnvalue(ra, luai_numpow(L, nb, nc));
|
||||
|
|
4
lvm.h
4
lvm.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lvm.h,v 2.22 2013/04/29 17:12:50 roberto Exp roberto $
|
||||
** $Id: lvm.h,v 2.23 2013/05/02 12:31:26 roberto Exp roberto $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -43,7 +43,7 @@ LUAI_FUNC void luaV_execute (lua_State *L);
|
|||
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 lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y);
|
||||
LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue