diff options
Diffstat (limited to 'lcode.c')
-rw-r--r-- | lcode.c | 23 |
1 files changed, 13 insertions, 10 deletions
@@ -71,7 +71,7 @@ int luaK_jump (FuncState *fs) { | |||
71 | 71 | ||
72 | static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) { | 72 | static 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) { | |||
127 | static Instruction *getjumpcontrol (FuncState *fs, int pc) { | 127 | static 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 | ||
314 | static void dischargejumps (FuncState *fs, expdesc *e, int reg) { | 313 | static 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: { |