aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-12-29 14:49:25 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-12-29 14:49:25 -0200
commit8e5290d81eb0ff32a4d1d41685f682ab62498da5 (patch)
tree92a6f2b5305eb8c3e29b044265d80e5324ad0380
parenta1c37f834ae433e05409cd30bd9450d5e8707e7a (diff)
downloadlua-8e5290d81eb0ff32a4d1d41685f682ab62498da5.tar.gz
lua-8e5290d81eb0ff32a4d1d41685f682ab62498da5.tar.bz2
lua-8e5290d81eb0ff32a4d1d41685f682ab62498da5.zip
all "divisions" (div,idiv,mod) by zero are not folded, to avoid
problems during compilation + does not fold zero results, as they can collapse with -0.0 and the ANSI test to distinguish both needs a division by zero (which we are trying to avoid) + removed macro 'luai_numinvalidop' (as its main use case were divisions by zero)
-rw-r--r--lcode.c34
1 files changed, 10 insertions, 24 deletions
diff --git a/lcode.c b/lcode.c
index f84b7b6b..eae7e7d7 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.97 2014/11/24 14:59:22 roberto Exp roberto $ 2** $Id: lcode.c,v 2.98 2014/12/19 13:36:32 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*/
@@ -33,14 +33,6 @@
33#define MAXREGS 250 33#define MAXREGS 250
34 34
35 35
36/* test for x == -0 ('signbit' needs 'math.h') */
37#if defined(signbit)
38#define isminuszero(x) ((x) == 0.0 && signbit(x))
39#else
40#define isminuszero(x) ((x) == 0.0 && 1.0/(x) < 0.0)
41#endif
42
43
44#define hasjumps(e) ((e)->t != (e)->f) 36#define hasjumps(e) ((e)->t != (e)->f)
45 37
46 38
@@ -364,14 +356,8 @@ int luaK_intK (FuncState *fs, lua_Integer n) {
364} 356}
365 357
366 358
367/*
368** Both NaN and -0.0 should not go to the constant table, as they have
369** problems with the hashing. (NaN is not a valid key, -0.0 collides
370** with +0.0.)
371*/
372static int luaK_numberK (FuncState *fs, lua_Number r) { 359static int luaK_numberK (FuncState *fs, lua_Number r) {
373 TValue o; 360 TValue o;
374 lua_assert(!luai_numisnan(r) && !isminuszero(r));
375 setfltvalue(&o, r); 361 setfltvalue(&o, r);
376 return addk(fs, &o, &o); 362 return addk(fs, &o, &o);
377} 363}
@@ -761,14 +747,14 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
761** return false if folding can raise an error 747** return false if folding can raise an error
762*/ 748*/
763static int validop (int op, TValue *v1, TValue *v2) { 749static int validop (int op, TValue *v1, TValue *v2) {
764 lua_Integer i;
765 if (luai_numinvalidop(op, nvalue(v1), nvalue(v2))) return 0;
766 switch (op) { 750 switch (op) {
767 case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: 751 case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
768 case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: /* conversion errors */ 752 case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */
753 lua_Integer i;
769 return (tointeger(v1, &i) && tointeger(v2, &i)); 754 return (tointeger(v1, &i) && tointeger(v2, &i));
770 case LUA_OPIDIV: case LUA_OPMOD: /* integer division by 0 */ 755 }
771 return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0); 756 case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */
757 return (nvalue(v2) != 0);
772 default: return 1; /* everything else is valid */ 758 default: return 1; /* everything else is valid */
773 } 759 }
774} 760}
@@ -781,15 +767,15 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
781 TValue v1, v2, res; 767 TValue v1, v2, res;
782 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) 768 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
783 return 0; /* non-numeric operands or not safe to fold */ 769 return 0; /* non-numeric operands or not safe to fold */
784 luaO_arith(fs->ls->L, op, &v1, &v2, &res); 770 luaO_arith(fs->ls->L, op, &v1, &v2, &res); /* does operation */
785 if (ttisinteger(&res)) { 771 if (ttisinteger(&res)) {
786 e1->k = VKINT; 772 e1->k = VKINT;
787 e1->u.ival = ivalue(&res); 773 e1->u.ival = ivalue(&res);
788 } 774 }
789 else { 775 else { /* folds neither NaN nor 0.0 (to avoid collapsing with -0.0) */
790 lua_Number n = fltvalue(&res); 776 lua_Number n = fltvalue(&res);
791 if (luai_numisnan(n) || isminuszero(n)) 777 if (luai_numisnan(n) || n == 0)
792 return 0; /* folds neither NaN nor -0 */ 778 return 0;
793 e1->k = VKFLT; 779 e1->k = VKFLT;
794 e1->u.nval = n; 780 e1->u.nval = n;
795 } 781 }