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 /lcode.c | |
| 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)
Diffstat (limited to 'lcode.c')
| -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: { |
