diff --git a/lcode.c b/lcode.c index 1e85dde0..6d26bd5c 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.80 2014/03/06 13:39:05 roberto Exp roberto $ +** $Id: lcode.c,v 2.81 2014/03/06 13:58:28 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -754,7 +754,11 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { ** return false if folding can raise an error */ static int validop (OpCode op, TValue *v1, TValue *v2) { + lua_Number a, b; lua_Integer i; + (void)a; (void)b; /* macro may not use its arguments */ + if (luai_numinvalidop(op, (tonumber(v1, &a), a), (tonumber(v2, &b), b))) + return 0; switch (op) { case LUA_OPIDIV: /* division by 0 and conversion errors */ return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0); diff --git a/lobject.c b/lobject.c index 66027585..e80c8db7 100644 --- a/lobject.c +++ b/lobject.c @@ -1,5 +1,5 @@ /* -** $Id: lobject.c,v 2.73 2014/02/06 15:59:24 roberto Exp $ +** $Id: lobject.c,v 2.74 2014/02/26 15:27:56 roberto Exp roberto $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ @@ -91,15 +91,16 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, } -static lua_Number numarith (int op, lua_Number v1, lua_Number v2) { +static lua_Number numarith (lua_State *L, int op, lua_Number v1, + lua_Number v2) { switch (op) { - case LUA_OPADD: return luai_numadd(v1, v2); - case LUA_OPSUB: return luai_numsub(v1, v2); - case LUA_OPMUL: return luai_nummul(v1, v2); - case LUA_OPDIV: return luai_numdiv(v1, v2); - case LUA_OPMOD: return luai_nummod(v1, v2); - case LUA_OPPOW: return luai_numpow(v1, v2); - case LUA_OPUNM: return luai_numunm(v1); + case LUA_OPADD: return luai_numadd(L, v1, v2); + case LUA_OPSUB: return luai_numsub(L, v1, v2); + case LUA_OPMUL: return luai_nummul(L, v1, v2); + case LUA_OPDIV: return luai_numdiv(L, v1, v2); + case LUA_OPMOD: return luai_nummod(L, v1, v2); + case LUA_OPPOW: return luai_numpow(L, v1, v2); + case LUA_OPUNM: return luai_numunm(L, v1); default: lua_assert(0); return 0; } } @@ -121,7 +122,7 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, case LUA_OPDIV: { /* operates only on floats */ lua_Number n1; lua_Number n2; if (tonumber(p1, &n1) && tonumber(p2, &n2)) { - setnvalue(res, numarith(op, n1, n2)); + setnvalue(res, numarith(L, op, n1, n2)); return; } else break; /* go to the end */ @@ -133,7 +134,7 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, return; } else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { - setnvalue(res, numarith(op, n1, n2)); + setnvalue(res, numarith(L, op, n1, n2)); return; } else break; /* go to the end */ diff --git a/luaconf.h b/luaconf.h index 5b579bbf..075ab1f2 100644 --- a/luaconf.h +++ b/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.189 2014/01/27 13:34:32 roberto Exp roberto $ +** $Id: luaconf.h,v 1.190 2014/02/26 15:27:56 roberto Exp roberto $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -488,17 +488,17 @@ /* the following operations need the math library */ #if defined(lobject_c) || defined(lvm_c) #include -#define luai_nummod(a,b) ((a) - l_floor((a)/(b))*(b)) -#define luai_numpow(a,b) (l_mathop(pow)(a,b)) +#define luai_nummod(L,a,b) ((void)L, (a) - l_floor((a)/(b))*(b)) +#define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b)) #endif /* these are quite standard operations */ #if defined(LUA_CORE) -#define luai_numadd(a,b) ((a)+(b)) -#define luai_numsub(a,b) ((a)-(b)) -#define luai_nummul(a,b) ((a)*(b)) -#define luai_numdiv(a,b) ((a)/(b)) -#define luai_numunm(a) (-(a)) +#define luai_numadd(L,a,b) ((a)+(b)) +#define luai_numsub(L,a,b) ((a)-(b)) +#define luai_nummul(L,a,b) ((a)*(b)) +#define luai_numdiv(L,a,b) ((a)/(b)) +#define luai_numunm(L,a) (-(a)) #define luai_numeq(a,b) ((a)==(b)) #define luai_numlt(a,b) ((a)<(b)) #define luai_numle(a,b) ((a)<=(b)) @@ -506,6 +506,13 @@ #endif +/* +** The following macro checks whether an operation is not safe to be +** performed by the constant folder. It should result in zero only if +** the operation is safe. +*/ +#define luai_numinvalidop(op,a,b) 0 + /* @@ LUA_INTEGER is the integer type used by Lua. diff --git a/lvm.c b/lvm.c index 835e8e0f..12c68023 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.185 2014/01/27 13:34:32 roberto Exp roberto $ +** $Id: lvm.c,v 2.186 2014/02/05 19:14:53 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -633,7 +633,7 @@ void luaV_execute (lua_State *L) { setivalue(ra, intop(+, ib, ic)); } else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { - setnvalue(ra, luai_numadd(nb, nc)); + setnvalue(ra, luai_numadd(L, nb, nc)); } else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); } ) @@ -646,7 +646,7 @@ void luaV_execute (lua_State *L) { setivalue(ra, intop(-, ib, ic)); } else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { - setnvalue(ra, luai_numsub(nb, nc)); + setnvalue(ra, luai_numsub(L, nb, nc)); } else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); } ) @@ -659,7 +659,7 @@ void luaV_execute (lua_State *L) { setivalue(ra, intop(*, ib, ic)); } else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { - setnvalue(ra, luai_nummul(nb, nc)); + setnvalue(ra, luai_nummul(L, nb, nc)); } else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); } ) @@ -668,7 +668,7 @@ void luaV_execute (lua_State *L) { TValue *rc = RKC(i); lua_Number nb; lua_Number nc; if (tonumber(rb, &nb) && tonumber(rc, &nc)) { - setnvalue(ra, luai_numdiv(nb, nc)); + setnvalue(ra, luai_numdiv(L, nb, nc)); } else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); } ) @@ -735,7 +735,7 @@ void luaV_execute (lua_State *L) { setivalue(ra, luaV_mod(L, ib, ic)); } else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { - setnvalue(ra, luai_nummod(nb, nc)); + setnvalue(ra, luai_nummod(L, nb, nc)); } else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); } ) @@ -748,7 +748,7 @@ void luaV_execute (lua_State *L) { setivalue(ra, luaV_pow(L, ib, ic)); } else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { - setnvalue(ra, luai_numpow(nb, nc)); + setnvalue(ra, luai_numpow(L, nb, nc)); } else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); } ) @@ -760,7 +760,7 @@ void luaV_execute (lua_State *L) { setivalue(ra, intop(-, 0, ib)); } else if (tonumber(rb, &nb)) { - setnvalue(ra, luai_numunm(nb)); + setnvalue(ra, luai_numunm(L, nb)); } else { Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); @@ -911,10 +911,10 @@ void luaV_execute (lua_State *L) { } else { /* floating count */ lua_Number step = fltvalue(ra + 2); - lua_Number idx = luai_numadd(fltvalue(ra), step); /* inc. index */ + lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */ lua_Number limit = fltvalue(ra + 1); if (luai_numlt(0, step) ? luai_numle(idx, limit) - : luai_numle(limit, idx)) { + : luai_numle(limit, idx)) { ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ setnvalue(ra, idx); /* update internal index... */ setnvalue(ra + 3, idx); /* ...and external index */ @@ -938,7 +938,7 @@ void luaV_execute (lua_State *L) { setnvalue(pstep, nstep); if (!tonumber(init, &ninit)) luaG_runerror(L, LUA_QL("for") " initial value must be a number"); - setnvalue(ra, luai_numsub(ninit, nstep)); + setnvalue(ra, luai_numsub(L, ninit, nstep)); } ci->u.l.savedpc += GETARG_sBx(i); )