diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-05-09 11:14:34 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-05-09 11:14:34 -0300 |
| commit | 78b40bf57db59aa35c9f1cbbd6482dc17e4306de (patch) | |
| tree | 64d06e1c13d99a9b4d9d201ef5bafd6989446880 | |
| parent | 01f1ac36b13f4fb23527785add70afe64f275944 (diff) | |
| download | lua-78b40bf57db59aa35c9f1cbbd6482dc17e4306de.tar.gz lua-78b40bf57db59aa35c9f1cbbd6482dc17e4306de.tar.bz2 lua-78b40bf57db59aa35c9f1cbbd6482dc17e4306de.zip | |
`skip' instructions must be followed by a jump
| -rw-r--r-- | lcode.c | 23 | ||||
| -rw-r--r-- | ldebug.c | 9 | ||||
| -rw-r--r-- | lvm.c | 12 |
3 files changed, 23 insertions, 21 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 1.98 2002/05/06 15:51:41 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.99 2002/05/07 17:36:56 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 | */ |
| @@ -338,22 +338,19 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) { | |||
| 338 | 338 | ||
| 339 | static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) { | 339 | static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) { |
| 340 | discharge2reg(fs, e, reg); | 340 | discharge2reg(fs, e, reg); |
| 341 | if (e->k == VJMP || hasjumps(e)) { | 341 | if (e->k == VJMP) |
| 342 | luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */ | ||
| 343 | if (hasjumps(e)) { | ||
| 342 | int final; /* position after whole expression */ | 344 | int final; /* position after whole expression */ |
| 343 | int p_f = NO_JUMP; /* position of an eventual PUSH false */ | 345 | int p_f = NO_JUMP; /* position of an eventual LOAD false */ |
| 344 | int p_t = NO_JUMP; /* position of an eventual PUSH true */ | 346 | int p_t = NO_JUMP; /* position of an eventual LOAD true */ |
| 345 | if (e->k == VJMP || need_value(fs, e->t, 1) | 347 | if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) { |
| 346 | || need_value(fs, e->f, 0)) { | ||
| 347 | if (e->k != VJMP) { | 348 | if (e->k != VJMP) { |
| 348 | luaK_getlabel(fs); /* these instruction may be jump target */ | 349 | luaK_getlabel(fs); /* this instruction may be a jump target */ |
| 349 | luaK_codeAsBx(fs, OP_JMP, 0, 2); /* to jump over both pushes */ | 350 | luaK_codeAsBx(fs, OP_JMP, 0, 2); /* to jump over both pushes */ |
| 350 | } | 351 | } |
| 351 | else { /* last expression is a conditional (test + jump) */ | 352 | p_f = code_label(fs, reg, 0, 1); |
| 352 | fs->pc--; /* remove its jump */ | 353 | p_t = code_label(fs, reg, 1, 0); |
| 353 | lua_assert(testOpMode(GET_OPCODE(fs->f->code[fs->pc - 1]), OpModeT)); | ||
| 354 | } | ||
| 355 | p_t = code_label(fs, reg, 1, 1); | ||
| 356 | p_f = code_label(fs, reg, 0, 0); | ||
| 357 | } | 354 | } |
| 358 | final = luaK_getlabel(fs); | 355 | final = luaK_getlabel(fs); |
| 359 | luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f); | 356 | luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 1.111 2002/05/02 13:06:20 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.112 2002/05/07 17:36:56 roberto Exp roberto $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -270,8 +270,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
| 270 | int pc; | 270 | int pc; |
| 271 | int last; /* stores position of last instruction that changed `reg' */ | 271 | int last; /* stores position of last instruction that changed `reg' */ |
| 272 | last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ | 272 | last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ |
| 273 | if (reg == NO_REG) /* full check? */ | 273 | check(precheck(pt)); |
| 274 | check(precheck(pt)); | ||
| 275 | for (pc = 0; pc < lastpc; pc++) { | 274 | for (pc = 0; pc < lastpc; pc++) { |
| 276 | const Instruction i = pt->code[pc]; | 275 | const Instruction i = pt->code[pc]; |
| 277 | OpCode op = GET_OPCODE(i); | 276 | OpCode op = GET_OPCODE(i); |
| @@ -303,8 +302,10 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { | |||
| 303 | if (testOpMode(op, OpModesetA)) { | 302 | if (testOpMode(op, OpModesetA)) { |
| 304 | if (a == reg) last = pc; /* change register `a' */ | 303 | if (a == reg) last = pc; /* change register `a' */ |
| 305 | } | 304 | } |
| 306 | if (testOpMode(op, OpModeT)) | 305 | if (testOpMode(op, OpModeT)) { |
| 307 | check(pc+2 < pt->sizecode); /* check skip */ | 306 | check(pc+2 < pt->sizecode); /* check skip */ |
| 307 | check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); | ||
| 308 | } | ||
| 308 | switch (op) { | 309 | switch (op) { |
| 309 | case OP_LOADBOOL: { | 310 | case OP_LOADBOOL: { |
| 310 | check(c == 0 || pc+2 < pt->sizecode); /* check its jump */ | 311 | check(c == 0 || pc+2 < pt->sizecode); /* check its jump */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.228 2002/05/02 13:06:20 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.229 2002/05/06 15:51:41 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -449,16 +449,21 @@ StkId luaV_execute (lua_State *L) { | |||
| 449 | } | 449 | } |
| 450 | case OP_EQ: { /* skip next instruction if test fails */ | 450 | case OP_EQ: { /* skip next instruction if test fails */ |
| 451 | if (luaO_equalObj(ra, RKC(i)) != GETARG_B(i)) pc++; | 451 | if (luaO_equalObj(ra, RKC(i)) != GETARG_B(i)) pc++; |
| 452 | else dojump(pc, GETARG_sBx(*pc) + 1); | ||
| 452 | break; | 453 | break; |
| 453 | } | 454 | } |
| 454 | case OP_CMP: { | 455 | case OP_CMP: { |
| 455 | if (!(luaV_cmp(L, ra, RKC(i), GETARG_B(i)))) pc++; | 456 | if (!(luaV_cmp(L, ra, RKC(i), GETARG_B(i)))) pc++; |
| 457 | else dojump(pc, GETARG_sBx(*pc) + 1); | ||
| 456 | break; | 458 | break; |
| 457 | } | 459 | } |
| 458 | case OP_TEST: { | 460 | case OP_TEST: { |
| 459 | StkId rc = RKC(i); | 461 | StkId rc = RKC(i); |
| 460 | if (l_isfalse(rc) == GETARG_B(i)) pc++; | 462 | if (l_isfalse(rc) == GETARG_B(i)) pc++; |
| 461 | else setobj(ra, rc); | 463 | else { |
| 464 | setobj(ra, rc); | ||
| 465 | dojump(pc, GETARG_sBx(*pc) + 1); | ||
| 466 | } | ||
| 462 | break; | 467 | break; |
| 463 | } | 468 | } |
| 464 | case OP_CALL: { | 469 | case OP_CALL: { |
| @@ -519,7 +524,6 @@ StkId luaV_execute (lua_State *L) { | |||
| 519 | } | 524 | } |
| 520 | case OP_FORLOOP: { | 525 | case OP_FORLOOP: { |
| 521 | lua_Number step, index, limit; | 526 | lua_Number step, index, limit; |
| 522 | int j = GETARG_sBx(i); | ||
| 523 | const TObject *plimit = ra+1; | 527 | const TObject *plimit = ra+1; |
| 524 | const TObject *pstep = ra+2; | 528 | const TObject *pstep = ra+2; |
| 525 | if (ttype(ra) != LUA_TNUMBER) | 529 | if (ttype(ra) != LUA_TNUMBER) |
| @@ -532,7 +536,7 @@ StkId luaV_execute (lua_State *L) { | |||
| 532 | index = nvalue(ra) + step; /* increment index */ | 536 | index = nvalue(ra) + step; /* increment index */ |
| 533 | limit = nvalue(plimit); | 537 | limit = nvalue(plimit); |
| 534 | if (step > 0 ? index <= limit : index >= limit) { | 538 | if (step > 0 ? index <= limit : index >= limit) { |
| 535 | dojump(pc, j); /* jump back */ | 539 | dojump(pc, GETARG_sBx(i)); /* jump back */ |
| 536 | chgnvalue(ra, index); /* update index */ | 540 | chgnvalue(ra, index); /* update index */ |
| 537 | } | 541 | } |
| 538 | break; | 542 | break; |
