浏览代码

`skip' instructions must be followed by a jump

Roberto Ierusalimschy 23 年之前
父节点
当前提交
78b40bf57d
共有 3 个文件被更改,包括 23 次插入21 次删除
  1. 10 13
      lcode.c
  2. 5 4
      ldebug.c
  3. 8 4
      lvm.c

+ 10 - 13
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.98 2002/05/06 15:51:41 roberto Exp roberto $
+** $Id: lcode.c,v 1.99 2002/05/07 17:36:56 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -338,22 +338,19 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) {
 
 static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) {
   discharge2reg(fs, e, reg);
-  if (e->k == VJMP || hasjumps(e)) {
+  if (e->k == VJMP)
+    luaK_concat(fs, &e->t, e->info);  /* put this jump in `t' list */
+  if (hasjumps(e)) {
     int final;  /* position after whole expression */
-    int p_f = NO_JUMP;  /* position of an eventual PUSH false */
-    int p_t = NO_JUMP;  /* position of an eventual PUSH true */
-    if (e->k == VJMP || need_value(fs, e->t, 1)
-                     || need_value(fs, e->f, 0)) {
+    int p_f = NO_JUMP;  /* position of an eventual LOAD false */
+    int p_t = NO_JUMP;  /* position of an eventual LOAD true */
+    if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) {
       if (e->k != VJMP) {
-        luaK_getlabel(fs);  /* these instruction may be jump target */
+        luaK_getlabel(fs);  /* this instruction may be a jump target */
         luaK_codeAsBx(fs, OP_JMP, 0, 2);  /* to jump over both pushes */
       }
-      else {  /* last expression is a conditional (test + jump) */
-        fs->pc--;  /* remove its jump */
-        lua_assert(testOpMode(GET_OPCODE(fs->f->code[fs->pc - 1]), OpModeT));
-      }
-      p_t = code_label(fs, reg, 1, 1);
-      p_f = code_label(fs, reg, 0, 0);
+      p_f = code_label(fs, reg, 0, 1);
+      p_t = code_label(fs, reg, 1, 0);
     }
     final = luaK_getlabel(fs);
     luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);

+ 5 - 4
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 1.111 2002/05/02 13:06:20 roberto Exp roberto $
+** $Id: ldebug.c,v 1.112 2002/05/07 17:36:56 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -270,8 +270,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
   int pc;
   int last;  /* stores position of last instruction that changed `reg' */
   last = pt->sizecode-1;  /* points to final return (a `neutral' instruction) */
-  if (reg == NO_REG)  /* full check? */
-    check(precheck(pt));
+  check(precheck(pt));
   for (pc = 0; pc < lastpc; pc++) {
     const Instruction i = pt->code[pc];
     OpCode op = GET_OPCODE(i);
@@ -303,8 +302,10 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
     if (testOpMode(op, OpModesetA)) {
       if (a == reg) last = pc;  /* change register `a' */
     }
-    if (testOpMode(op, OpModeT))
+    if (testOpMode(op, OpModeT)) {
       check(pc+2 < pt->sizecode);  /* check skip */
+      check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
+    }
     switch (op) {
       case OP_LOADBOOL: {
         check(c == 0 || pc+2 < pt->sizecode);  /* check its jump */

+ 8 - 4
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.228 2002/05/02 13:06:20 roberto Exp roberto $
+** $Id: lvm.c,v 1.229 2002/05/06 15:51:41 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -449,16 +449,21 @@ StkId luaV_execute (lua_State *L) {
       }
       case OP_EQ: {  /* skip next instruction if test fails */
         if (luaO_equalObj(ra, RKC(i)) != GETARG_B(i)) pc++;
+        else dojump(pc, GETARG_sBx(*pc) + 1);
         break;
       }
       case OP_CMP: {
         if (!(luaV_cmp(L, ra, RKC(i), GETARG_B(i)))) pc++;
+        else dojump(pc, GETARG_sBx(*pc) + 1);
         break;
       }
       case OP_TEST: {
         StkId rc = RKC(i);
         if (l_isfalse(rc) == GETARG_B(i)) pc++;
-        else setobj(ra, rc);
+        else {
+          setobj(ra, rc);
+          dojump(pc, GETARG_sBx(*pc) + 1);
+        }
         break;
       }
       case OP_CALL: {
@@ -519,7 +524,6 @@ StkId luaV_execute (lua_State *L) {
       }
       case OP_FORLOOP: {
         lua_Number step, index, limit;
-        int j = GETARG_sBx(i);
         const TObject *plimit = ra+1;
         const TObject *pstep = ra+2;
         if (ttype(ra) != LUA_TNUMBER)
@@ -532,7 +536,7 @@ StkId luaV_execute (lua_State *L) {
         index = nvalue(ra) + step;  /* increment index */
         limit = nvalue(plimit);
         if (step > 0 ? index <= limit : index >= limit) {
-          dojump(pc, j);  /* jump back */
+          dojump(pc, GETARG_sBx(i));  /* jump back */
           chgnvalue(ra, index);  /* update index */
         }
         break;