diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-12-29 14:49:25 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-12-29 14:49:25 -0200 |
commit | 8e5290d81eb0ff32a4d1d41685f682ab62498da5 (patch) | |
tree | 92a6f2b5305eb8c3e29b044265d80e5324ad0380 | |
parent | a1c37f834ae433e05409cd30bd9450d5e8707e7a (diff) | |
download | lua-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.c | 34 |
1 files changed, 10 insertions, 24 deletions
@@ -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 | */ | ||
372 | static int luaK_numberK (FuncState *fs, lua_Number r) { | 359 | static 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 | */ |
763 | static int validop (int op, TValue *v1, TValue *v2) { | 749 | static 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 | } |