diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-11-24 12:59:22 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-11-24 12:59:22 -0200 |
commit | bf163ea7f0b1ba56f684b134ee7688f84ef74ac4 (patch) | |
tree | 2d93a664f3033f7ccb6350eb0814619b4fbc757c | |
parent | 075661ffde8cdd48dcb7e4e2033408cee4535edf (diff) | |
download | lua-bf163ea7f0b1ba56f684b134ee7688f84ef74ac4.tar.gz lua-bf163ea7f0b1ba56f684b134ee7688f84ef74ac4.tar.bz2 lua-bf163ea7f0b1ba56f684b134ee7688f84ef74ac4.zip |
bug ('#3' causes seg. fault in 5.3-beta) + comments + 'codearith' ->
'codeexpval' (confusion about what operations function accept was
one of the reasons for the bug)
-rw-r--r-- | lcode.c | 37 |
1 files changed, 24 insertions, 13 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 2.95 2014/11/02 19:19:04 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.96 2014/11/21 12:15:57 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 | */ |
@@ -801,19 +801,30 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) { | |||
801 | } | 801 | } |
802 | 802 | ||
803 | 803 | ||
804 | static void codearith (FuncState *fs, OpCode op, | 804 | /* |
805 | expdesc *e1, expdesc *e2, int line) { | 805 | ** Code for binary and unary expressions that "produce values" |
806 | if (!constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2)) { | 806 | ** (arithmetic operations, bitwise operations, concat, length). First |
807 | ** try to do constant folding (only for numeric [arithmetic and | ||
808 | ** bitwise] operations, which is what 'lua_arith' accepts). | ||
809 | ** Expression to produce final result will be encoded in 'e1'. | ||
810 | */ | ||
811 | static void codeexpval (FuncState *fs, OpCode op, | ||
812 | expdesc *e1, expdesc *e2, int line) { | ||
813 | lua_assert(op >= OP_ADD); | ||
814 | if (op <= OP_BNOT && constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2)) | ||
815 | return; /* result has been folded */ | ||
816 | else { | ||
807 | int o1, o2; | 817 | int o1, o2; |
808 | if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { | 818 | /* move operands to registers (if needed) */ |
809 | o2 = 0; | 819 | if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { /* unary op? */ |
820 | o2 = 0; /* no second expression */ | ||
810 | o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */ | 821 | o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */ |
811 | } | 822 | } |
812 | else { /* regular case (binary operators) */ | 823 | else { /* regular case (binary operators) */ |
813 | o2 = luaK_exp2RK(fs, e2); | 824 | o2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */ |
814 | o1 = luaK_exp2RK(fs, e1); | 825 | o1 = luaK_exp2RK(fs, e1); |
815 | } | 826 | } |
816 | if (o1 > o2) { | 827 | if (o1 > o2) { /* free registers in proper order */ |
817 | freeexp(fs, e1); | 828 | freeexp(fs, e1); |
818 | freeexp(fs, e2); | 829 | freeexp(fs, e2); |
819 | } | 830 | } |
@@ -821,8 +832,8 @@ static void codearith (FuncState *fs, OpCode op, | |||
821 | freeexp(fs, e2); | 832 | freeexp(fs, e2); |
822 | freeexp(fs, e1); | 833 | freeexp(fs, e1); |
823 | } | 834 | } |
824 | e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); | 835 | e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); /* generate opcode */ |
825 | e1->k = VRELOCABLE; | 836 | e1->k = VRELOCABLE; /* all those operations are relocable */ |
826 | luaK_fixline(fs, line); | 837 | luaK_fixline(fs, line); |
827 | } | 838 | } |
828 | } | 839 | } |
@@ -849,7 +860,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { | |||
849 | e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0; | 860 | e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0; |
850 | switch (op) { | 861 | switch (op) { |
851 | case OPR_MINUS: case OPR_BNOT: case OPR_LEN: { | 862 | case OPR_MINUS: case OPR_BNOT: case OPR_LEN: { |
852 | codearith(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line); | 863 | codeexpval(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line); |
853 | break; | 864 | break; |
854 | } | 865 | } |
855 | case OPR_NOT: codenot(fs, e); break; | 866 | case OPR_NOT: codenot(fs, e); break; |
@@ -915,7 +926,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, | |||
915 | } | 926 | } |
916 | else { | 927 | else { |
917 | luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ | 928 | luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ |
918 | codearith(fs, OP_CONCAT, e1, e2, line); | 929 | codeexpval(fs, OP_CONCAT, e1, e2, line); |
919 | } | 930 | } |
920 | break; | 931 | break; |
921 | } | 932 | } |
@@ -923,7 +934,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, | |||
923 | case OPR_IDIV: case OPR_MOD: case OPR_POW: | 934 | case OPR_IDIV: case OPR_MOD: case OPR_POW: |
924 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: | 935 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: |
925 | case OPR_SHL: case OPR_SHR: { | 936 | case OPR_SHL: case OPR_SHR: { |
926 | codearith(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line); | 937 | codeexpval(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line); |
927 | break; | 938 | break; |
928 | } | 939 | } |
929 | case OPR_EQ: case OPR_LT: case OPR_LE: { | 940 | case OPR_EQ: case OPR_LT: case OPR_LE: { |