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 | } |
