aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-11-24 12:59:22 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-11-24 12:59:22 -0200
commitbf163ea7f0b1ba56f684b134ee7688f84ef74ac4 (patch)
tree2d93a664f3033f7ccb6350eb0814619b4fbc757c
parent075661ffde8cdd48dcb7e4e2033408cee4535edf (diff)
downloadlua-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.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/lcode.c b/lcode.c
index f2d876fe..ddbc6522 100644
--- a/lcode.c
+++ b/lcode.c
@@ -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
804static 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*/
811static 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: {