aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c67
1 files changed, 26 insertions, 41 deletions
diff --git a/lcode.c b/lcode.c
index cd976cf0..61ff0701 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.108 2002/06/13 13:39:55 roberto Exp $ 2** $Id: lcode.c,v 1.109 2002/08/05 14:07:34 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*/
@@ -100,14 +100,14 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) {
100static int need_value (FuncState *fs, int list, int cond) { 100static int need_value (FuncState *fs, int list, int cond) {
101 for (; list != NO_JUMP; list = luaK_getjump(fs, list)) { 101 for (; list != NO_JUMP; list = luaK_getjump(fs, list)) {
102 Instruction i = *getjumpcontrol(fs, list); 102 Instruction i = *getjumpcontrol(fs, list);
103 if (GET_OPCODE(i) != OP_TEST || GETARG_B(i) != cond) return 1; 103 if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;
104 } 104 }
105 return 0; /* not found */ 105 return 0; /* not found */
106} 106}
107 107
108 108
109static void patchtestreg (Instruction *i, int reg) { 109static void patchtestreg (Instruction *i, int reg) {
110 if (reg == NO_REG) reg = GETARG_C(*i); 110 if (reg == NO_REG) reg = GETARG_B(*i);
111 SETARG_A(*i, reg); 111 SETARG_A(*i, reg);
112} 112}
113 113
@@ -122,7 +122,7 @@ static void luaK_patchlistaux (FuncState *fs, int list,
122 luaK_fixjump(fs, list, dtarget); /* jump to default target */ 122 luaK_fixjump(fs, list, dtarget); /* jump to default target */
123 } 123 }
124 else { 124 else {
125 if (GETARG_B(*i)) { 125 if (GETARG_C(*i)) {
126 lua_assert(ttarget != NO_JUMP); 126 lua_assert(ttarget != NO_JUMP);
127 patchtestreg(i, treg); 127 patchtestreg(i, treg);
128 luaK_fixjump(fs, list, ttarget); 128 luaK_fixjump(fs, list, ttarget);
@@ -409,7 +409,7 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
409 } 409 }
410 default: break; 410 default: break;
411 } 411 }
412 /* not a constant in the right range: put in a register */ 412 /* not a constant in the right range: put it in a register */
413 return luaK_exp2anyreg(fs, e); 413 return luaK_exp2anyreg(fs, e);
414} 414}
415 415
@@ -432,8 +432,8 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) {
432 break; 432 break;
433 } 433 }
434 case VINDEXED: { 434 case VINDEXED: {
435 int e = luaK_exp2anyreg(fs, exp); 435 int e = luaK_exp2RK(fs, exp);
436 luaK_codeABC(fs, OP_SETTABLE, e, var->info, var->aux); 436 luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e);
437 break; 437 break;
438 } 438 }
439 default: { 439 default: {
@@ -460,8 +460,9 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
460 460
461static void invertjump (FuncState *fs, expdesc *e) { 461static void invertjump (FuncState *fs, expdesc *e) {
462 Instruction *pc = getjumpcontrol(fs, e->info); 462 Instruction *pc = getjumpcontrol(fs, e->info);
463 lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT)); 463 lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) &&
464 SETARG_B(*pc, !(GETARG_B(*pc))); 464 GET_OPCODE(*pc) != OP_TEST);
465 SETARG_A(*pc, !(GETARG_A(*pc)));
465} 466}
466 467
467 468
@@ -470,13 +471,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
470 Instruction ie = getcode(fs, e); 471 Instruction ie = getcode(fs, e);
471 if (GET_OPCODE(ie) == OP_NOT) { 472 if (GET_OPCODE(ie) == OP_NOT) {
472 fs->pc--; /* remove previous OP_NOT */ 473 fs->pc--; /* remove previous OP_NOT */
473 return luaK_condjump(fs, OP_TEST, NO_REG, !cond ,GETARG_B(ie)); 474 return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
474 } 475 }
475 /* else go through */ 476 /* else go through */
476 } 477 }
477 discharge2anyreg(fs, e); 478 discharge2anyreg(fs, e);
478 freeexp(fs, e); 479 freeexp(fs, e);
479 return luaK_condjump(fs, OP_TEST, NO_REG, cond, e->info); 480 return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond);
480} 481}
481 482
482 483
@@ -605,11 +606,6 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
605 luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ 606 luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
606 break; 607 break;
607 } 608 }
608 case OPR_SUB: case OPR_DIV: case OPR_POW: {
609 /* non-comutative operators */
610 luaK_exp2anyreg(fs, v); /* first operand must be a register */
611 break;
612 }
613 default: { 609 default: {
614 luaK_exp2RK(fs, v); 610 luaK_exp2RK(fs, v);
615 break; 611 break;
@@ -619,13 +615,11 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
619 615
620 616
621static void codebinop (FuncState *fs, expdesc *res, BinOpr op, 617static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
622 int o1, int o2, int ic) { 618 int o1, int o2) {
623 switch (op) { 619 switch (op) {
624 case OPR_SUB: 620 case OPR_SUB:
625 case OPR_DIV: 621 case OPR_DIV:
626 case OPR_POW: 622 case OPR_POW:
627 lua_assert(!ic);
628 /* go through */
629 case OPR_ADD: 623 case OPR_ADD:
630 case OPR_MULT: { /* ORDER OPR */ 624 case OPR_MULT: { /* ORDER OPR */
631 OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); 625 OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD);
@@ -635,20 +629,21 @@ static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
635 } 629 }
636 case OPR_NE: 630 case OPR_NE:
637 case OPR_EQ: { 631 case OPR_EQ: {
638 res->info = luaK_condjump(fs, OP_EQ, o1, (op == OPR_EQ), o2); 632 res->info = luaK_condjump(fs, OP_EQ, (op == OPR_EQ), o1, o2);
639 res->k = VJMP; 633 res->k = VJMP;
640 break; 634 break;
641 } 635 }
642 case OPR_LT:
643 case OPR_LE:
644 case OPR_GT: 636 case OPR_GT:
645 case OPR_GE: { /* ORDER OPR */ 637 case OPR_GE: { /* ORDER OPR */
646 OpCode opc; 638 int temp;
647 int i = op - OPR_LT; 639 temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
648 if (ic) /* operands were interchanged? */ 640 op -= 2; /* GT -> LT, GE -> LE */
649 i = (i+2)&3; /* correct operator */ 641 /* go through */
650 opc = cast(OpCode, i + OP_LT); 642 }
651 res->info = luaK_condjump(fs, opc, o1, 1, o2); 643 case OPR_LT:
644 case OPR_LE: {
645 OpCode opc = cast(OpCode, (op - OPR_LT) + OP_LT);
646 res->info = luaK_condjump(fs, opc, 1, o1, o2);
652 res->k = VJMP; 647 res->k = VJMP;
653 break; 648 break;
654 } 649 }
@@ -691,21 +686,11 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
691 break; 686 break;
692 } 687 }
693 default: { 688 default: {
694 int o1, o2; 689 int o1 = luaK_exp2RK(fs, e1);
695 int ic; /* interchange flag */ 690 int o2 = luaK_exp2RK(fs, e2);
696 if (e1->k != VK) { /* not a constant operator? */
697 o1 = e1->info;
698 o2 = luaK_exp2RK(fs, e2); /* maybe other operator is constant... */
699 ic = 0;
700 }
701 else { /* interchange operands */
702 o2 = luaK_exp2RK(fs, e1); /* constant must be 2nd operand */
703 o1 = luaK_exp2anyreg(fs, e2); /* other operator must be in register */
704 ic = 1;
705 }
706 freeexp(fs, e2); 691 freeexp(fs, e2);
707 freeexp(fs, e1); 692 freeexp(fs, e1);
708 codebinop(fs, e1, op, o1, o2, ic); 693 codebinop(fs, e1, op, o1, o2);
709 } 694 }
710 } 695 }
711} 696}