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