diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-03-06 13:15:18 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-03-06 13:15:18 -0300 |
| commit | 5ff1c18a715b842a6146a6a07d99c84f48cac999 (patch) | |
| tree | b90579a688fd971f80e7628cba179fdf389a27c8 | |
| parent | 99ac4a260fc1bf958515c1816d866852194493f2 (diff) | |
| download | lua-5ff1c18a715b842a6146a6a07d99c84f48cac999.tar.gz lua-5ff1c18a715b842a6146a6a07d99c84f48cac999.tar.bz2 lua-5ff1c18a715b842a6146a6a07d99c84f48cac999.zip | |
back with 'L' for macros 'luai_num*', but now with a new macro
'luai_numinvalidop' to protect constant folding
| -rw-r--r-- | lcode.c | 6 | ||||
| -rw-r--r-- | lobject.c | 23 | ||||
| -rw-r--r-- | luaconf.h | 23 | ||||
| -rw-r--r-- | lvm.c | 22 |
4 files changed, 43 insertions, 31 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 2.80 2014/03/06 13:39:05 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.81 2014/03/06 13:58:28 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 | */ |
| @@ -754,7 +754,11 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | |||
| 754 | ** return false if folding can raise an error | 754 | ** return false if folding can raise an error |
| 755 | */ | 755 | */ |
| 756 | static int validop (OpCode op, TValue *v1, TValue *v2) { | 756 | static int validop (OpCode op, TValue *v1, TValue *v2) { |
| 757 | lua_Number a, b; | ||
| 757 | lua_Integer i; | 758 | lua_Integer i; |
| 759 | (void)a; (void)b; /* macro may not use its arguments */ | ||
| 760 | if (luai_numinvalidop(op, (tonumber(v1, &a), a), (tonumber(v2, &b), b))) | ||
| 761 | return 0; | ||
| 758 | switch (op) { | 762 | switch (op) { |
| 759 | case LUA_OPIDIV: /* division by 0 and conversion errors */ | 763 | case LUA_OPIDIV: /* division by 0 and conversion errors */ |
| 760 | return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0); | 764 | return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 2.73 2014/02/06 15:59:24 roberto Exp $ | 2 | ** $Id: lobject.c,v 2.74 2014/02/26 15:27:56 roberto Exp roberto $ |
| 3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -91,15 +91,16 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | 93 | ||
| 94 | static lua_Number numarith (int op, lua_Number v1, lua_Number v2) { | 94 | static lua_Number numarith (lua_State *L, int op, lua_Number v1, |
| 95 | lua_Number v2) { | ||
| 95 | switch (op) { | 96 | switch (op) { |
| 96 | case LUA_OPADD: return luai_numadd(v1, v2); | 97 | case LUA_OPADD: return luai_numadd(L, v1, v2); |
| 97 | case LUA_OPSUB: return luai_numsub(v1, v2); | 98 | case LUA_OPSUB: return luai_numsub(L, v1, v2); |
| 98 | case LUA_OPMUL: return luai_nummul(v1, v2); | 99 | case LUA_OPMUL: return luai_nummul(L, v1, v2); |
| 99 | case LUA_OPDIV: return luai_numdiv(v1, v2); | 100 | case LUA_OPDIV: return luai_numdiv(L, v1, v2); |
| 100 | case LUA_OPMOD: return luai_nummod(v1, v2); | 101 | case LUA_OPMOD: return luai_nummod(L, v1, v2); |
| 101 | case LUA_OPPOW: return luai_numpow(v1, v2); | 102 | case LUA_OPPOW: return luai_numpow(L, v1, v2); |
| 102 | case LUA_OPUNM: return luai_numunm(v1); | 103 | case LUA_OPUNM: return luai_numunm(L, v1); |
| 103 | default: lua_assert(0); return 0; | 104 | default: lua_assert(0); return 0; |
| 104 | } | 105 | } |
| 105 | } | 106 | } |
| @@ -121,7 +122,7 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, | |||
| 121 | case LUA_OPDIV: { /* operates only on floats */ | 122 | case LUA_OPDIV: { /* operates only on floats */ |
| 122 | lua_Number n1; lua_Number n2; | 123 | lua_Number n1; lua_Number n2; |
| 123 | if (tonumber(p1, &n1) && tonumber(p2, &n2)) { | 124 | if (tonumber(p1, &n1) && tonumber(p2, &n2)) { |
| 124 | setnvalue(res, numarith(op, n1, n2)); | 125 | setnvalue(res, numarith(L, op, n1, n2)); |
| 125 | return; | 126 | return; |
| 126 | } | 127 | } |
| 127 | else break; /* go to the end */ | 128 | else break; /* go to the end */ |
| @@ -133,7 +134,7 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, | |||
| 133 | return; | 134 | return; |
| 134 | } | 135 | } |
| 135 | else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { | 136 | else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { |
| 136 | setnvalue(res, numarith(op, n1, n2)); | 137 | setnvalue(res, numarith(L, op, n1, n2)); |
| 137 | return; | 138 | return; |
| 138 | } | 139 | } |
| 139 | else break; /* go to the end */ | 140 | else break; /* go to the end */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: luaconf.h,v 1.189 2014/01/27 13:34:32 roberto Exp roberto $ | 2 | ** $Id: luaconf.h,v 1.190 2014/02/26 15:27:56 roberto Exp roberto $ |
| 3 | ** Configuration file for Lua | 3 | ** Configuration file for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -488,17 +488,17 @@ | |||
| 488 | /* the following operations need the math library */ | 488 | /* the following operations need the math library */ |
| 489 | #if defined(lobject_c) || defined(lvm_c) | 489 | #if defined(lobject_c) || defined(lvm_c) |
| 490 | #include <math.h> | 490 | #include <math.h> |
| 491 | #define luai_nummod(a,b) ((a) - l_floor((a)/(b))*(b)) | 491 | #define luai_nummod(L,a,b) ((void)L, (a) - l_floor((a)/(b))*(b)) |
| 492 | #define luai_numpow(a,b) (l_mathop(pow)(a,b)) | 492 | #define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b)) |
| 493 | #endif | 493 | #endif |
| 494 | 494 | ||
| 495 | /* these are quite standard operations */ | 495 | /* these are quite standard operations */ |
| 496 | #if defined(LUA_CORE) | 496 | #if defined(LUA_CORE) |
| 497 | #define luai_numadd(a,b) ((a)+(b)) | 497 | #define luai_numadd(L,a,b) ((a)+(b)) |
| 498 | #define luai_numsub(a,b) ((a)-(b)) | 498 | #define luai_numsub(L,a,b) ((a)-(b)) |
| 499 | #define luai_nummul(a,b) ((a)*(b)) | 499 | #define luai_nummul(L,a,b) ((a)*(b)) |
| 500 | #define luai_numdiv(a,b) ((a)/(b)) | 500 | #define luai_numdiv(L,a,b) ((a)/(b)) |
| 501 | #define luai_numunm(a) (-(a)) | 501 | #define luai_numunm(L,a) (-(a)) |
| 502 | #define luai_numeq(a,b) ((a)==(b)) | 502 | #define luai_numeq(a,b) ((a)==(b)) |
| 503 | #define luai_numlt(a,b) ((a)<(b)) | 503 | #define luai_numlt(a,b) ((a)<(b)) |
| 504 | #define luai_numle(a,b) ((a)<=(b)) | 504 | #define luai_numle(a,b) ((a)<=(b)) |
| @@ -506,6 +506,13 @@ | |||
| 506 | #endif | 506 | #endif |
| 507 | 507 | ||
| 508 | 508 | ||
| 509 | /* | ||
| 510 | ** The following macro checks whether an operation is not safe to be | ||
| 511 | ** performed by the constant folder. It should result in zero only if | ||
| 512 | ** the operation is safe. | ||
| 513 | */ | ||
| 514 | #define luai_numinvalidop(op,a,b) 0 | ||
| 515 | |||
| 509 | 516 | ||
| 510 | /* | 517 | /* |
| 511 | @@ LUA_INTEGER is the integer type used by Lua. | 518 | @@ LUA_INTEGER is the integer type used by Lua. |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.185 2014/01/27 13:34:32 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.186 2014/02/05 19:14:53 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -633,7 +633,7 @@ void luaV_execute (lua_State *L) { | |||
| 633 | setivalue(ra, intop(+, ib, ic)); | 633 | setivalue(ra, intop(+, ib, ic)); |
| 634 | } | 634 | } |
| 635 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | 635 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { |
| 636 | setnvalue(ra, luai_numadd(nb, nc)); | 636 | setnvalue(ra, luai_numadd(L, nb, nc)); |
| 637 | } | 637 | } |
| 638 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); } | 638 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); } |
| 639 | ) | 639 | ) |
| @@ -646,7 +646,7 @@ void luaV_execute (lua_State *L) { | |||
| 646 | setivalue(ra, intop(-, ib, ic)); | 646 | setivalue(ra, intop(-, ib, ic)); |
| 647 | } | 647 | } |
| 648 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | 648 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { |
| 649 | setnvalue(ra, luai_numsub(nb, nc)); | 649 | setnvalue(ra, luai_numsub(L, nb, nc)); |
| 650 | } | 650 | } |
| 651 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); } | 651 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); } |
| 652 | ) | 652 | ) |
| @@ -659,7 +659,7 @@ void luaV_execute (lua_State *L) { | |||
| 659 | setivalue(ra, intop(*, ib, ic)); | 659 | setivalue(ra, intop(*, ib, ic)); |
| 660 | } | 660 | } |
| 661 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | 661 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { |
| 662 | setnvalue(ra, luai_nummul(nb, nc)); | 662 | setnvalue(ra, luai_nummul(L, nb, nc)); |
| 663 | } | 663 | } |
| 664 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); } | 664 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); } |
| 665 | ) | 665 | ) |
| @@ -668,7 +668,7 @@ void luaV_execute (lua_State *L) { | |||
| 668 | TValue *rc = RKC(i); | 668 | TValue *rc = RKC(i); |
| 669 | lua_Number nb; lua_Number nc; | 669 | lua_Number nb; lua_Number nc; |
| 670 | if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | 670 | if (tonumber(rb, &nb) && tonumber(rc, &nc)) { |
| 671 | setnvalue(ra, luai_numdiv(nb, nc)); | 671 | setnvalue(ra, luai_numdiv(L, nb, nc)); |
| 672 | } | 672 | } |
| 673 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); } | 673 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); } |
| 674 | ) | 674 | ) |
| @@ -735,7 +735,7 @@ void luaV_execute (lua_State *L) { | |||
| 735 | setivalue(ra, luaV_mod(L, ib, ic)); | 735 | setivalue(ra, luaV_mod(L, ib, ic)); |
| 736 | } | 736 | } |
| 737 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | 737 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { |
| 738 | setnvalue(ra, luai_nummod(nb, nc)); | 738 | setnvalue(ra, luai_nummod(L, nb, nc)); |
| 739 | } | 739 | } |
| 740 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); } | 740 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); } |
| 741 | ) | 741 | ) |
| @@ -748,7 +748,7 @@ void luaV_execute (lua_State *L) { | |||
| 748 | setivalue(ra, luaV_pow(L, ib, ic)); | 748 | setivalue(ra, luaV_pow(L, ib, ic)); |
| 749 | } | 749 | } |
| 750 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | 750 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { |
| 751 | setnvalue(ra, luai_numpow(nb, nc)); | 751 | setnvalue(ra, luai_numpow(L, nb, nc)); |
| 752 | } | 752 | } |
| 753 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); } | 753 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); } |
| 754 | ) | 754 | ) |
| @@ -760,7 +760,7 @@ void luaV_execute (lua_State *L) { | |||
| 760 | setivalue(ra, intop(-, 0, ib)); | 760 | setivalue(ra, intop(-, 0, ib)); |
| 761 | } | 761 | } |
| 762 | else if (tonumber(rb, &nb)) { | 762 | else if (tonumber(rb, &nb)) { |
| 763 | setnvalue(ra, luai_numunm(nb)); | 763 | setnvalue(ra, luai_numunm(L, nb)); |
| 764 | } | 764 | } |
| 765 | else { | 765 | else { |
| 766 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); | 766 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); |
| @@ -911,10 +911,10 @@ void luaV_execute (lua_State *L) { | |||
| 911 | } | 911 | } |
| 912 | else { /* floating count */ | 912 | else { /* floating count */ |
| 913 | lua_Number step = fltvalue(ra + 2); | 913 | lua_Number step = fltvalue(ra + 2); |
| 914 | lua_Number idx = luai_numadd(fltvalue(ra), step); /* inc. index */ | 914 | lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */ |
| 915 | lua_Number limit = fltvalue(ra + 1); | 915 | lua_Number limit = fltvalue(ra + 1); |
| 916 | if (luai_numlt(0, step) ? luai_numle(idx, limit) | 916 | if (luai_numlt(0, step) ? luai_numle(idx, limit) |
| 917 | : luai_numle(limit, idx)) { | 917 | : luai_numle(limit, idx)) { |
| 918 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ | 918 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ |
| 919 | setnvalue(ra, idx); /* update internal index... */ | 919 | setnvalue(ra, idx); /* update internal index... */ |
| 920 | setnvalue(ra + 3, idx); /* ...and external index */ | 920 | setnvalue(ra + 3, idx); /* ...and external index */ |
| @@ -938,7 +938,7 @@ void luaV_execute (lua_State *L) { | |||
| 938 | setnvalue(pstep, nstep); | 938 | setnvalue(pstep, nstep); |
| 939 | if (!tonumber(init, &ninit)) | 939 | if (!tonumber(init, &ninit)) |
| 940 | luaG_runerror(L, LUA_QL("for") " initial value must be a number"); | 940 | luaG_runerror(L, LUA_QL("for") " initial value must be a number"); |
| 941 | setnvalue(ra, luai_numsub(ninit, nstep)); | 941 | setnvalue(ra, luai_numsub(L, ninit, nstep)); |
| 942 | } | 942 | } |
| 943 | ci->u.l.savedpc += GETARG_sBx(i); | 943 | ci->u.l.savedpc += GETARG_sBx(i); |
| 944 | ) | 944 | ) |
