aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2016-01-04 11:40:57 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2016-01-04 11:40:57 -0200
commitb12b635a9052240538daf0d049834b60aa64b435 (patch)
treedb7df4a80a7180044dd8ab407b5ac4b64e172308
parent7cd7c2e0a1e947bbcb03da123b31f4f74b366020 (diff)
downloadlua-b12b635a9052240538daf0d049834b60aa64b435.tar.gz
lua-b12b635a9052240538daf0d049834b60aa64b435.tar.bz2
lua-b12b635a9052240538daf0d049834b60aa64b435.zip
more refactoring
-rw-r--r--lcode.c191
1 files changed, 97 insertions, 94 deletions
diff --git a/lcode.c b/lcode.c
index a15e8dcc..a274e974 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.103 2015/11/19 19:16:22 roberto Exp roberto $ 2** $Id: lcode.c,v 2.106 2015/12/18 13:53:36 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*/
@@ -401,6 +401,24 @@ static void freeexp (FuncState *fs, expdesc *e) {
401 401
402 402
403/* 403/*
404** Free registers used by expressions 'e1' and 'e2' (if any) in proper
405** order.
406*/
407static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
408 int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1;
409 int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1;
410 if (r1 > r2) {
411 freereg(fs, r1);
412 freereg(fs, r2);
413 }
414 else {
415 freereg(fs, r2);
416 freereg(fs, r1);
417 }
418}
419
420
421/*
404** Add constant 'v' to prototype's list of constants (field 'k'). 422** Add constant 'v' to prototype's list of constants (field 'k').
405** Use scanner's table to cache position of constants in constant list 423** Use scanner's table to cache position of constants in constant list
406** and try to reuse constants. Because some values should not be used 424** and try to reuse constants. Because some values should not be used
@@ -531,33 +549,35 @@ void luaK_setoneret (FuncState *fs, expdesc *e) {
531 549
532 550
533/* 551/*
534** Ensure that expression 'e' has a value somewhere (either it 552** Ensure that expression 'e' is not a variable.
535** is a constant or result is in a register).
536*/ 553*/
537void luaK_dischargevars (FuncState *fs, expdesc *e) { 554void luaK_dischargevars (FuncState *fs, expdesc *e) {
538 switch (e->k) { 555 switch (e->k) {
539 case VLOCAL: { 556 case VLOCAL: { /* already in a register */
540 e->k = VNONRELOC; /* becomes a non-relocatable value */ 557 e->k = VNONRELOC; /* becomes a non-relocatable value */
541 break; 558 break;
542 } 559 }
543 case VUPVAL: { 560 case VUPVAL: { /* move value to some (pending) register */
544 e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); 561 e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
545 e->k = VRELOCABLE; 562 e->k = VRELOCABLE;
546 break; 563 break;
547 } 564 }
548 case VINDEXED: { 565 case VINDEXED: {
549 OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */ 566 OpCode op;
550 freereg(fs, e->u.ind.idx); 567 freereg(fs, e->u.ind.idx);
551 if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */ 568 if (e->u.ind.vt == VLOCAL) { /* is 't' in a register? */
552 freereg(fs, e->u.ind.t); 569 freereg(fs, e->u.ind.t);
553 op = OP_GETTABLE; 570 op = OP_GETTABLE;
554 } 571 }
572 else {
573 lua_assert(e->u.ind.vt == VUPVAL);
574 op = OP_GETTABUP; /* 't' is in an upvalue */
575 }
555 e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); 576 e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
556 e->k = VRELOCABLE; 577 e->k = VRELOCABLE;
557 break; 578 break;
558 } 579 }
559 case VVARARG: 580 case VVARARG: case VCALL: {
560 case VCALL: {
561 luaK_setoneret(fs, e); 581 luaK_setoneret(fs, e);
562 break; 582 break;
563 } 583 }
@@ -731,36 +751,22 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
731** Ensures final expression result is in a valid R/K index 751** Ensures final expression result is in a valid R/K index
732** (that is, it is either in a register or in 'k' with an index 752** (that is, it is either in a register or in 'k' with an index
733** in the range of R/K indices). 753** in the range of R/K indices).
754** Returns R/K index.
734*/ 755*/
735int luaK_exp2RK (FuncState *fs, expdesc *e) { 756int luaK_exp2RK (FuncState *fs, expdesc *e) {
736 luaK_exp2val(fs, e); 757 luaK_exp2val(fs, e);
737 switch (e->k) { /* handle constants */ 758 switch (e->k) { /* move constants to 'k' */
738 case VTRUE: 759 case VTRUE: e->u.info = boolK(fs, 1); goto vk;
739 case VFALSE: 760 case VFALSE: e->u.info = boolK(fs, 0); goto vk;
740 case VNIL: { 761 case VNIL: e->u.info = nilK(fs); goto vk;
741 if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */ 762 case VKINT: e->u.info = luaK_intK(fs, e->u.ival); goto vk;
742 e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); 763 case VKFLT: e->u.info = luaK_numberK(fs, e->u.nval); goto vk;
743 e->k = VK; 764 case VK:
744 return RKASK(e->u.info);
745 }
746 else break;
747 }
748 case VKINT: {
749 e->u.info = luaK_intK(fs, e->u.ival);
750 e->k = VK;
751 goto vk;
752 }
753 case VKFLT: {
754 e->u.info = luaK_numberK(fs, e->u.nval);
755 e->k = VK;
756 }
757 /* FALLTHROUGH */
758 case VK: {
759 vk: 765 vk:
766 e->k = VK;
760 if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */ 767 if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
761 return RKASK(e->u.info); 768 return RKASK(e->u.info);
762 else break; 769 else break;
763 }
764 default: break; 770 default: break;
765 } 771 }
766 /* not a constant in the right range: put it in a register */ 772 /* not a constant in the right range: put it in a register */
@@ -988,65 +994,62 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
988 994
989 995
990/* 996/*
991** Emit code for binary and unary expressions that "produce values" 997** Emit code for unary expressions that "produce values"
992** (everything but logical operators 'and', 'or' and comparison 998** (everything but 'not').
999** Expression to produce final result will be encoded in 'e'.
1000*/
1001static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
1002 int r = luaK_exp2anyreg(fs, e); /* opcodes operate only on registers */
1003 freeexp(fs, e);
1004 e->u.info = luaK_codeABC(fs, op, 0, r, 0); /* generate opcode */
1005 e->k = VRELOCABLE; /* all those operations are relocatable */
1006 luaK_fixline(fs, line);
1007}
1008
1009
1010/*
1011** Emit code for binary expressions that "produce values"
1012** (everything but logical operators 'and'/'or' and comparison
993** operators). 1013** operators).
994** First try to do constant folding (only for numeric [arithmetic and 1014** Expression to produce final result will be encoded in 'e1'.
995** bitwise] operations, which is what 'lua_arith' accepts). Expression
996** to produce final result will be encoded in 'e1'.
997** (The "free registers in proper order" reason is tricky: because
998** expression evaluation can be delayed, the final numbering for
999** registers in 'e1' and 'e2' depends on how each one was delayed.)
1000*/ 1015*/
1001static void codeexpval (FuncState *fs, OpCode op, 1016static void codebinexpval (FuncState *fs, OpCode op,
1002 expdesc *e1, expdesc *e2, int line) { 1017 expdesc *e1, expdesc *e2, int line) {
1003 lua_assert(OP_ADD <= op && op <= OP_CONCAT); 1018 int rk1 = luaK_exp2RK(fs, e1); /* both operands are "RK" */
1004 if (op <= OP_BNOT && constfolding(fs, (op - OP_ADD) + LUA_OPADD, e1, e2)) 1019 int rk2 = luaK_exp2RK(fs, e2);
1005 return; /* result has been folded */ 1020 freeexps(fs, e1, e2);
1006 else { 1021 e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2); /* generate opcode */
1007 int o1, o2; 1022 e1->k = VRELOCABLE; /* all those operations are relocatable */
1008 /* move operands to registers (if needed) */ 1023 luaK_fixline(fs, line);
1009 if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { /* unary op? */
1010 o2 = 0; /* no second expression */
1011 o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */
1012 }
1013 else { /* regular case (binary operators) */
1014 o2 = luaK_exp2RK(fs, e2); /* both operands are "RK" */
1015 o1 = luaK_exp2RK(fs, e1);
1016 }
1017 if (o1 > o2) { /* free registers in proper order */
1018 freeexp(fs, e1);
1019 freeexp(fs, e2);
1020 }
1021 else {
1022 freeexp(fs, e2);
1023 freeexp(fs, e1);
1024 }
1025 e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); /* generate opcode */
1026 e1->k = VRELOCABLE; /* all those operations are relocatable */
1027 luaK_fixline(fs, line);
1028 }
1029} 1024}
1030 1025
1031 1026
1032/* 1027/*
1033** Emit code for comparisons. 1028** Emit code for comparisons.
1034** Code will jump if result equals 'cond' ('cond' true <=> code will 1029** 'e1' was already put in R/K form by 'luaK_infix'.
1035** jump if result is true).
1036*/ 1030*/
1037static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, 1031static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1038 expdesc *e2) { 1032 int rk1 = (e1->k == VK) ? RKASK(e1->u.info)
1039 int o1 = luaK_exp2RK(fs, e1); 1033 : check_exp(e1->k == VNONRELOC, e1->u.info);
1040 int o2 = luaK_exp2RK(fs, e2); 1034 int rk2 = luaK_exp2RK(fs, e2);
1041 lua_assert(OP_EQ <= op && op <= OP_LE); /* comparison operation */ 1035 freeexps(fs, e1, e2);
1042 freeexp(fs, e2); 1036 switch (opr) {
1043 freeexp(fs, e1); 1037 case OPR_NE: { /* '(a ~= b)' ==> 'not (a == b)' */
1044 if (cond == 0 && op != OP_EQ) { 1038 e1->u.info = condjump(fs, OP_EQ, 0, rk1, rk2);
1045 int temp; /* exchange args to replace by '<' or '<=' */ 1039 break;
1046 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ 1040 }
1047 cond = 1; 1041 case OPR_GT: case OPR_GE: {
1042 /* '(a > b)' ==> '(b < a)'; '(a >= b)' ==> '(b <= a)' */
1043 OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
1044 e1->u.info = condjump(fs, op, 1, rk2, rk1); /* invert operands */
1045 break;
1046 }
1047 default: { /* '==', '<', '<=' use their own opcodes */
1048 OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ);
1049 e1->u.info = condjump(fs, op, 1, rk1, rk2);
1050 break;
1051 }
1048 } 1052 }
1049 e1->u.info = condjump(fs, op, cond, o1, o2);
1050 e1->k = VJMP; 1053 e1->k = VJMP;
1051} 1054}
1052 1055
@@ -1055,13 +1058,15 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
1055** Aplly prefix operation 'op' to expression 'e'. 1058** Aplly prefix operation 'op' to expression 'e'.
1056*/ 1059*/
1057void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { 1060void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
1058 expdesc e2; /* fake 2nd operand */ 1061 static expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; /* fake 2nd operand */
1059 e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
1060 switch (op) { 1062 switch (op) {
1061 case OPR_MINUS: case OPR_BNOT: case OPR_LEN: { 1063 case OPR_MINUS: case OPR_BNOT:
1062 codeexpval(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line); 1064 if (constfolding(fs, op + LUA_OPUNM, e, &ef))
1065 break;
1066 /* else go through */
1067 case OPR_LEN:
1068 codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line);
1063 break; 1069 break;
1064 }
1065 case OPR_NOT: codenot(fs, e); break; 1070 case OPR_NOT: codenot(fs, e); break;
1066 default: lua_assert(0); 1071 default: lua_assert(0);
1067 } 1072 }
@@ -1137,7 +1142,7 @@ void luaK_posfix (FuncState *fs, BinOpr op,
1137 } 1142 }
1138 else { 1143 else {
1139 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ 1144 luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
1140 codeexpval(fs, OP_CONCAT, e1, e2, line); 1145 codebinexpval(fs, OP_CONCAT, e1, e2, line);
1141 } 1146 }
1142 break; 1147 break;
1143 } 1148 }
@@ -1145,15 +1150,13 @@ void luaK_posfix (FuncState *fs, BinOpr op,
1145 case OPR_IDIV: case OPR_MOD: case OPR_POW: 1150 case OPR_IDIV: case OPR_MOD: case OPR_POW:
1146 case OPR_BAND: case OPR_BOR: case OPR_BXOR: 1151 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
1147 case OPR_SHL: case OPR_SHR: { 1152 case OPR_SHL: case OPR_SHR: {
1148 codeexpval(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line); 1153 if (!constfolding(fs, op + LUA_OPADD, e1, e2))
1149 break; 1154 codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line);
1150 }
1151 case OPR_EQ: case OPR_LT: case OPR_LE: {
1152 codecomp(fs, cast(OpCode, (op - OPR_EQ) + OP_EQ), 1, e1, e2);
1153 break; 1155 break;
1154 } 1156 }
1157 case OPR_EQ: case OPR_LT: case OPR_LE:
1155 case OPR_NE: case OPR_GT: case OPR_GE: { 1158 case OPR_NE: case OPR_GT: case OPR_GE: {
1156 codecomp(fs, cast(OpCode, (op - OPR_NE) + OP_EQ), 0, e1, e2); 1159 codecomp(fs, op, e1, e2);
1157 break; 1160 break;
1158 } 1161 }
1159 default: lua_assert(0); 1162 default: lua_assert(0);