aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/lcode.c b/lcode.c
index a93b52b9..835dc25d 100644
--- a/lcode.c
+++ b/lcode.c
@@ -71,7 +71,7 @@ int luaK_jump (FuncState *fs) {
71 71
72static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) { 72static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) {
73 luaK_codeABC(fs, op, A, B, C); 73 luaK_codeABC(fs, op, A, B, C);
74 return luaK_codeAsBc(fs, OP_CJMP, 0, NO_JUMP); 74 return luaK_codeAsBc(fs, OP_JMP, 0, NO_JUMP);
75} 75}
76 76
77 77
@@ -127,12 +127,11 @@ static int luaK_getjump (FuncState *fs, int pc) {
127static Instruction *getjumpcontrol (FuncState *fs, int pc) { 127static Instruction *getjumpcontrol (FuncState *fs, int pc) {
128 Instruction *pi = &fs->f->code[pc]; 128 Instruction *pi = &fs->f->code[pc];
129 OpCode op = GET_OPCODE(*pi); 129 OpCode op = GET_OPCODE(*pi);
130 if (op == OP_CJMP) 130 lua_assert(op == OP_JMP || op == OP_FORLOOP || op == OP_TFORLOOP);
131 if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT))
131 return pi-1; 132 return pi-1;
132 else { 133 else
133 lua_assert(op == OP_JMP || op == OP_FORLOOP || op == OP_TFORLOOP);
134 return pi; 134 return pi;
135 }
136} 135}
137 136
138 137
@@ -312,18 +311,23 @@ static int code_label (FuncState *fs, int A, int b, int jump) {
312 311
313 312
314static void dischargejumps (FuncState *fs, expdesc *e, int reg) { 313static void dischargejumps (FuncState *fs, expdesc *e, int reg) {
315 if (hasjumps(e)) { 314 if (e->k == VJMP || hasjumps(e)) {
316 int final; /* position after whole expression */ 315 int final; /* position after whole expression */
317 int p_f = NO_JUMP; /* position of an eventual PUSH false */ 316 int p_f = NO_JUMP; /* position of an eventual PUSH false */
318 int p_t = NO_JUMP; /* position of an eventual PUSH true */ 317 int p_t = NO_JUMP; /* position of an eventual PUSH true */
319 if (need_value(fs, e->f, OP_TESTF) || need_value(fs, e->t, OP_TESTT)) { 318 if (e->k == VJMP || need_value(fs, e->f, OP_TESTF) ||
319 need_value(fs, e->t, OP_TESTT)) {
320 /* expression needs values */ 320 /* expression needs values */
321 if (e->k != VJMP) { 321 if (e->k != VJMP) {
322 luaK_getlabel(fs); /* these instruction may be jump target */ 322 luaK_getlabel(fs); /* these instruction may be jump target */
323 luaK_codeAsBc(fs, OP_JMP, 0, 2); /* to jump over both pushes */ 323 luaK_codeAsBc(fs, OP_JMP, 0, 2); /* to jump over both pushes */
324 } 324 }
325 p_f = code_label(fs, reg, 0, 1); 325 else { /* last expression is a conditional (test + jump) */
326 p_t = code_label(fs, reg, 1, 0); 326 fs->pc--; /* remove its jump */
327 lua_assert(testOpMode(GET_OPCODE(fs->f->code[fs->pc - 1]), OpModeT));
328 }
329 p_t = code_label(fs, reg, 1, 1);
330 p_f = code_label(fs, reg, 0, 0);
327 } 331 }
328 final = luaK_getlabel(fs); 332 final = luaK_getlabel(fs);
329 luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f); 333 luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
@@ -389,7 +393,6 @@ static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) {
389 break; 393 break;
390 } 394 }
391 case VJMP: { 395 case VJMP: {
392 luaK_concat(fs, &e->t, e->u.i.info); /* put this jump in `t' list */
393 break; 396 break;
394 } 397 }
395 default: { 398 default: {