2
0
Эх сурвалжийг харах

array `luaK_opproperties' keeps delta stack and mode for each opcode

Roberto Ierusalimschy 25 жил өмнө
parent
commit
5c2dd7a9e0
6 өөрчлөгдсөн 166 нэмэгдсэн , 207 устгасан
  1. 119 139
      lcode.c
  2. 9 1
      lcode.h
  3. 2 2
      lopcodes.h
  4. 5 5
      lparser.c
  5. 29 58
      ltests.c
  6. 2 2
      lvm.c

+ 119 - 139
lcode.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lcode.c,v 1.29 2000/05/08 19:32:53 roberto Exp roberto $
+** $Id: lcode.c,v 1.30 2000/05/15 19:48:04 roberto Exp roberto $
 ** Code generator for Lua
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -37,7 +37,7 @@ static Instruction previous_instruction (FuncState *fs) {
 
 
 
 
 int luaK_jump (FuncState *fs) {
 int luaK_jump (FuncState *fs) {
-  int j = luaK_code0(fs, OP_JMP);
+  int j = luaK_code1(fs, OP_JMP, NO_JUMP);
   if (j == fs->lasttarget) {  /* possible jumps to this jump? */
   if (j == fs->lasttarget) {  /* possible jumps to this jump? */
     luaK_concat(fs, &j, fs->jlt);  /* keep them on hold */
     luaK_concat(fs, &j, fs->jlt);  /* keep them on hold */
     fs->jlt = NO_JUMP;
     fs->jlt = NO_JUMP;
@@ -279,7 +279,7 @@ static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {
       SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
       SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
   }
   }
   else
   else
-    luaK_code0(fs, jump);
+    luaK_code1(fs, jump, NO_JUMP);
   luaK_concat(fs, exitlist, fs->pc-1);  /* insert last jump in `exitlist' */
   luaK_concat(fs, exitlist, fs->pc-1);  /* insert last jump in `exitlist' */
   luaK_patchlist(fs, *golist, luaK_getlabel(fs));
   luaK_patchlist(fs, *golist, luaK_getlabel(fs));
   *golist = NO_JUMP;
   *golist = NO_JUMP;
@@ -324,10 +324,11 @@ void luaK_tostack (LexState *ls, expdesc *v, int onlyone) {
         if (ISJUMP(previous))
         if (ISJUMP(previous))
           luaK_concat(fs, &v->u.l.t, fs->pc-1);  /* put `previous' in t. list */
           luaK_concat(fs, &v->u.l.t, fs->pc-1);  /* put `previous' in t. list */
         else {
         else {
-          j = code_label(fs, OP_JMP, 0);  /* to jump over both pushes */
+          j = code_label(fs, OP_JMP, NO_JUMP);  /* to jump over both pushes */
           luaK_deltastack(fs, -1);  /* next PUSHes may be skipped */
           luaK_deltastack(fs, -1);  /* next PUSHes may be skipped */
         }
         }
         p_nil = code_label(fs, OP_PUSHNILJMP, 0);
         p_nil = code_label(fs, OP_PUSHNILJMP, 0);
+        luaK_deltastack(fs, -1);  /* next PUSH is skipped */
         p_1 = code_label(fs, OP_PUSHINT, 1);
         p_1 = code_label(fs, OP_PUSHINT, 1);
         luaK_patchlist(fs, j, luaK_getlabel(fs));
         luaK_patchlist(fs, j, luaK_getlabel(fs));
       }
       }
@@ -394,12 +395,12 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) {
       case '/': luaK_code0(fs, OP_DIV); break;
       case '/': luaK_code0(fs, OP_DIV); break;
       case '^': luaK_code0(fs, OP_POW); break;
       case '^': luaK_code0(fs, OP_POW); break;
       case TK_CONCAT: luaK_code1(fs, OP_CONCAT, 2); break;
       case TK_CONCAT: luaK_code1(fs, OP_CONCAT, 2); break;
-      case TK_EQ: luaK_code0(fs, OP_JMPEQ); break;
-      case TK_NE: luaK_code0(fs, OP_JMPNE); break;
-      case '>': luaK_code0(fs, OP_JMPGT); break;
-      case '<': luaK_code0(fs, OP_JMPLT); break;
-      case TK_GE: luaK_code0(fs, OP_JMPGE); break;
-      case TK_LE: luaK_code0(fs, OP_JMPLE); break;
+      case TK_EQ: luaK_code1(fs, OP_JMPEQ, NO_JUMP); break;
+      case TK_NE: luaK_code1(fs, OP_JMPNE, NO_JUMP); break;
+      case '>': luaK_code1(fs, OP_JMPGT, NO_JUMP); break;
+      case '<': luaK_code1(fs, OP_JMPLT, NO_JUMP); break;
+      case TK_GE: luaK_code1(fs, OP_JMPGE, NO_JUMP); break;
+      case TK_LE: luaK_code1(fs, OP_JMPLE, NO_JUMP); break;
     }
     }
   }
   }
 }
 }
@@ -415,196 +416,120 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
 }
 }
 
 
 
 
+#define VD	100	/* flag for variable delta */
+
 
 
 int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
 int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
   Instruction i = previous_instruction(fs);
   Instruction i = previous_instruction(fs);
-  int delta = 0;
-  enum {iO, iU, iS, iAB, iP} mode;  /* instruction format (or iP to optimize) */
-  mode = iP;
-
+  int delta = luaK_opproperties[o].delta;
+  int optm = 0;  /* 1 when there is an optimization */
   switch (o) {
   switch (o) {
 
 
     case OP_CLOSURE:
     case OP_CLOSURE:
       delta = -arg2+1;
       delta = -arg2+1;
-      mode = iAB;
-      break;
-
-    case OP_SETLINE:
-      mode = iU;
-      break;
-
-    case OP_CALL:
-      mode = iAB;
-      break;
-
-    case OP_PUSHINT:
-      delta = 1;
-      mode = iS;
       break;
       break;
 
 
     case OP_SETTABLE:
     case OP_SETTABLE:
-      delta = -arg2;
-      mode = iAB;
-      break;
-
     case OP_SETLIST:
     case OP_SETLIST:
-      delta = -(arg2+1);
-      mode = iAB;
+      delta = -arg2;
       break;
       break;
 
 
     case OP_SETMAP:
     case OP_SETMAP:
       delta = -2*(arg1+1);
       delta = -2*(arg1+1);
-      mode = iU;
-      break;
-
-    case OP_FORLOOP:
-      delta = -3;
-      arg1 = NO_JUMP;
-      mode = iS;
-      break;
-
-    case OP_SETLOCAL:
-    case OP_SETGLOBAL:
-      delta = -1;
-      mode = iU;
-      break;
-
-    case OP_FORPREP:
-    case OP_JMP:
-      arg1 = NO_JUMP;
-      mode = iS;
-      break;
-
-    case OP_LFORPREP:
-      delta = 3;
-      arg1 = NO_JUMP;
-      mode = iS;
-      break;
-
-    case OP_LFORLOOP:
-      delta = -4;
-      arg1 = NO_JUMP;
-      mode = iS;
-      break;
-
-    case OP_END:
-    case OP_PUSHNILJMP:
-    case OP_NOT:
-      mode = iO;
-      break;
-
-    case OP_PUSHSTRING:
-    case OP_PUSHNUM:
-    case OP_PUSHNEGNUM:
-    case OP_PUSHUPVALUE:
-    case OP_GETLOCAL:
-    case OP_GETGLOBAL:
-    case OP_PUSHSELF:
-    case OP_CREATETABLE:
-      delta = 1;
-      mode = iU;
-      break;
-
-    case OP_JMPLT:
-    case OP_JMPLE:
-    case OP_JMPGT:
-    case OP_JMPGE:
-      delta = -2;
-      arg1 = NO_JUMP;
-      mode = iS;
-      break;
-
-    case OP_MULT:
-    case OP_DIV:
-    case OP_POW:
-      delta = -1;
-      mode = iO;
       break;
       break;
 
 
     case OP_RETURN:
     case OP_RETURN:
       if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) {
       if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) {
         SET_OPCODE(i, OP_TAILCALL);
         SET_OPCODE(i, OP_TAILCALL);
         SETARG_B(i, arg1);
         SETARG_B(i, arg1);
+        optm = 1;
       }
       }
-      else mode = iU;
       break;
       break;
 
 
     case OP_PUSHNIL:
     case OP_PUSHNIL:
       delta = arg1;
       delta = arg1;
       switch(GET_OPCODE(i)) {
       switch(GET_OPCODE(i)) {
-        case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); break;
-        default: mode = iU; break;
+        case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break;
+        default: break;
       }
       }
       break;
       break;
 
 
     case OP_POP:
     case OP_POP:
       delta = -arg1;
       delta = -arg1;
       switch(GET_OPCODE(i)) {
       switch(GET_OPCODE(i)) {
-        case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); break;
-        default: mode = iU; break;
+        case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break;
+        default: break;
       }
       }
       break;
       break;
 
 
     case OP_GETTABLE:
     case OP_GETTABLE:
-      delta = -1;
       switch(GET_OPCODE(i)) {
       switch(GET_OPCODE(i)) {
-        case OP_PUSHSTRING: SET_OPCODE(i, OP_GETDOTTED); break;  /* `t.x' */
-        case OP_GETLOCAL: SET_OPCODE(i, OP_GETINDEXED); break;  /* `t[i]' */
-        default: mode = iO; break;
+        case OP_PUSHSTRING:  /* `t.x' */
+          SET_OPCODE(i, OP_GETDOTTED);
+          optm = 1;
+          break;
+        case OP_GETLOCAL:  /* `t[i]' */
+          SET_OPCODE(i, OP_GETINDEXED);
+          optm = 1;
+          break;
+        default: break;
       }
       }
       break;
       break;
 
 
     case OP_ADD:
     case OP_ADD:
-      delta = -1;
       switch(GET_OPCODE(i)) {
       switch(GET_OPCODE(i)) {
-        case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); break;  /* `a+k' */
-        default: mode = iO; break;
+        case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); optm = 1; break;  /* `a+k' */
+        default: break;
       }
       }
       break;
       break;
 
 
     case OP_SUB:
     case OP_SUB:
-      delta = -1;
       switch(GET_OPCODE(i)) {
       switch(GET_OPCODE(i)) {
-        case OP_PUSHINT: i = CREATE_S(OP_ADDI, -GETARG_S(i)); break; /* `a-k' */
-        default: mode = iO; break;
+        case OP_PUSHINT:  /* `a-k' */
+          i = CREATE_S(OP_ADDI, -GETARG_S(i));
+          optm = 1;
+          break;
+        default: break;
       }
       }
       break;
       break;
 
 
     case OP_CONCAT:
     case OP_CONCAT:
       delta = -arg1+1;
       delta = -arg1+1;
       switch(GET_OPCODE(i)) {
       switch(GET_OPCODE(i)) {
-        case OP_CONCAT: SETARG_U(i, GETARG_U(i)+1); break;  /* `a..b..c' */
-        default: mode = iU; break;
+        case OP_CONCAT:  /* `a..b..c' */
+          SETARG_U(i, GETARG_U(i)+1);
+          optm = 1;
+          break;
+        default: break;
       }
       }
       break;
       break;
 
 
     case OP_MINUS:
     case OP_MINUS:
       switch(GET_OPCODE(i)) {
       switch(GET_OPCODE(i)) {
-        case OP_PUSHINT: SETARG_S(i, -GETARG_S(i)); break;  /* `-k' */
-        case OP_PUSHNUM: SET_OPCODE(i, OP_PUSHNEGNUM); break;  /* `-k' */
-        default: mode = iO; break;
+        case OP_PUSHINT:  /* `-k' */
+          SETARG_S(i, -GETARG_S(i));
+          optm = 1;
+          break;
+        case OP_PUSHNUM:  /* `-k' */
+          SET_OPCODE(i, OP_PUSHNEGNUM);
+          optm = 1;
+          break;
+        default: break;
       }
       }
       break;
       break;
 
 
     case OP_JMPNE:
     case OP_JMPNE:
-      delta = -2;
-      if (i == CREATE_U(OP_PUSHNIL, 1))  /* `a~=nil' */
+      if (i == CREATE_U(OP_PUSHNIL, 1)) {  /* `a~=nil' */
         i = CREATE_S(OP_JMPT, NO_JUMP);
         i = CREATE_S(OP_JMPT, NO_JUMP);
-      else {
-        arg1 = NO_JUMP;
-        mode = iS;
+        optm = 1;
       }
       }
       break;
       break;
 
 
     case OP_JMPEQ:
     case OP_JMPEQ:
-      delta = -2;
       if (i == CREATE_U(OP_PUSHNIL, 1)) {  /* `a==nil' */
       if (i == CREATE_U(OP_PUSHNIL, 1)) {  /* `a==nil' */
         i = CREATE_0(OP_NOT);
         i = CREATE_0(OP_NOT);
         delta = -1;  /* just undo effect of previous PUSHNIL */
         delta = -1;  /* just undo effect of previous PUSHNIL */
-      }
-      else {
-        arg1 = NO_JUMP;
-        mode = iS;
+        optm = 1;
       }
       }
       break;
       break;
 
 
@@ -612,11 +537,9 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
     case OP_JMPF:
     case OP_JMPF:
     case OP_JMPONT:
     case OP_JMPONT:
     case OP_JMPONF:
     case OP_JMPONF:
-      delta = -1;
-      arg1 = NO_JUMP;
       switch (GET_OPCODE(i)) {
       switch (GET_OPCODE(i)) {
-        case OP_NOT: i = CREATE_S(invertjump(o), NO_JUMP); break;
-        default: mode = iS; break;
+        case OP_NOT: i = CREATE_S(invertjump(o), NO_JUMP); optm = 1; break;
+        default: break;
       }
       }
       break;
       break;
 
 
@@ -625,19 +548,23 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
     case OP_TAILCALL:
     case OP_TAILCALL:
     case OP_ADDI:
     case OP_ADDI:
       LUA_INTERNALERROR(L, "instruction used only for optimizations");
       LUA_INTERNALERROR(L, "instruction used only for optimizations");
-      return 0;  /* to avoid warnings */
+      break;
+
+    default:
+      LUA_ASSERT(L, delta != VD, "invalid delta");
+      break;
 
 
   }
   }
   luaK_deltastack(fs, delta);
   luaK_deltastack(fs, delta);
-  switch (mode) {  /* handle instruction formats */
+  if (optm) {  /* optimize: put instruction in place of last one */
+      fs->f->code[fs->pc-1] = i;  /* change previous instruction */
+      return fs->pc-1;  /* do not generate new instruction */
+  }
+  switch ((enum Mode)luaK_opproperties[o].mode) {
     case iO: i = CREATE_0(o); break;
     case iO: i = CREATE_0(o); break;
     case iU: i = CREATE_U(o, arg1); break;
     case iU: i = CREATE_U(o, arg1); break;
     case iS: i = CREATE_S(o, arg1); break;
     case iS: i = CREATE_S(o, arg1); break;
     case iAB: i = CREATE_AB(o, arg1, arg2); break;
     case iAB: i = CREATE_AB(o, arg1, arg2); break;
-    case iP: {  /* optimize: put instruction in place of last one */
-      fs->f->code[fs->pc-1] = i;  /* change previous instruction */
-      return fs->pc-1;
-    }
   }
   }
   /* actually create the new instruction */
   /* actually create the new instruction */
   luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT);
   luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT);
@@ -645,3 +572,56 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
   return fs->pc++;
   return fs->pc++;
 }
 }
 
 
+
+const struct OpProperties luaK_opproperties[OP_SETLINE+1] = {
+  {iO, 0},	/* OP_END */
+  {iU, 0},	/* OP_RETURN */
+  {iAB, 0},	/* OP_CALL */
+  {iAB, 0},	/* OP_TAILCALL */
+  {iU, VD},	/* OP_PUSHNIL */
+  {iU, VD},	/* OP_POP */
+  {iS, 1},	/* OP_PUSHINT */
+  {iU, 1},	/* OP_PUSHSTRING */
+  {iU, 1},	/* OP_PUSHNUM */
+  {iU, 1},	/* OP_PUSHNEGNUM */
+  {iU, 1},	/* OP_PUSHUPVALUE */
+  {iU, 1},	/* OP_GETLOCAL */
+  {iU, 1},	/* OP_GETGLOBAL */
+  {iO, -1},	/* OP_GETTABLE */
+  {iU, 0},	/* OP_GETDOTTED */
+  {iU, 0},	/* OP_GETINDEXED */
+  {iU, 1},	/* OP_PUSHSELF */
+  {iU, 1},	/* OP_CREATETABLE */
+  {iU, -1},	/* OP_SETLOCAL */
+  {iU, -1},	/* OP_SETGLOBAL */
+  {iAB, VD},	/* OP_SETTABLE */
+  {iAB, VD},	/* OP_SETLIST */
+  {iU, VD},	/* OP_SETMAP */
+  {iO, -1},	/* OP_ADD */
+  {iS, 0},	/* OP_ADDI */
+  {iO, -1},	/* OP_SUB */
+  {iO, -1},	/* OP_MULT */
+  {iO, -1},	/* OP_DIV */
+  {iO, -1},	/* OP_POW */
+  {iU, VD},	/* OP_CONCAT */
+  {iO, 0},	/* OP_MINUS */
+  {iO, 0},	/* OP_NOT */
+  {iS, -2},	/* OP_JMPNE */
+  {iS, -2},	/* OP_JMPEQ */
+  {iS, -2},	/* OP_JMPLT */
+  {iS, -2},	/* OP_JMPLE */
+  {iS, -2},	/* OP_JMPGT */
+  {iS, -2},	/* OP_JMPGE */
+  {iS, -1},	/* OP_JMPT */
+  {iS, -1},	/* OP_JMPF */
+  {iS, -1},	/* OP_JMPONT */
+  {iS, -1},	/* OP_JMPONF */
+  {iS, 0},	/* OP_JMP */
+  {iO, 1},	/* OP_PUSHNILJMP */
+  {iS, 0},	/* OP_FORPREP */
+  {iS, -3},	/* OP_FORLOOP */
+  {iS, 3},	/* OP_LFORPREP */
+  {iS, -4},	/* OP_LFORLOOP */
+  {iAB, VD},	/* OP_CLOSURE */
+  {iU, 0}	/* OP_SETLINE */
+};

+ 9 - 1
lcode.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lcode.h,v 1.11 2000/04/07 19:35:20 roberto Exp roberto $
+** $Id: lcode.h,v 1.12 2000/04/12 18:47:03 roberto Exp roberto $
 ** Code generator for Lua
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -20,6 +20,14 @@
 #define NO_JUMP (-1)
 #define NO_JUMP (-1)
 
 
 
 
+enum Mode {iO, iU, iS, iAB};  /* instruction format */
+
+extern const struct OpProperties {
+  char mode;
+  signed char delta;
+} luaK_opproperties[];
+
+
 void luaK_error (LexState *ls, const char *msg);
 void luaK_error (LexState *ls, const char *msg);
 int luaK_code0 (FuncState *fs, OpCode o);
 int luaK_code0 (FuncState *fs, OpCode o);
 int luaK_code1 (FuncState *fs, OpCode o, int arg1);
 int luaK_code1 (FuncState *fs, OpCode o, int arg1);

+ 2 - 2
lopcodes.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lopcodes.h,v 1.60 2000/04/27 17:39:15 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.61 2000/05/15 19:48:04 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -112,7 +112,7 @@ OP_SETLOCAL,/*	L	x		-		LOC[l]=x	*/
 OP_SETGLOBAL,/*	K	x		-		VAR[KSTR[k]]=x	*/
 OP_SETGLOBAL,/*	K	x		-		VAR[KSTR[k]]=x	*/
 OP_SETTABLE,/*	A B	v a_a-a_1 i t	(pops b values)	t[i]=v		*/
 OP_SETTABLE,/*	A B	v a_a-a_1 i t	(pops b values)	t[i]=v		*/
 
 
-OP_SETLIST,/*	A B	v_b-v_0 t	t		t[i+a*FPF]=v_i	*/
+OP_SETLIST,/*	A B	v_b-v_1 t	t		t[i+a*FPF]=v_i	*/
 OP_SETMAP,/*	U	v_u k_u - v_0 k_0 t	t	t[k_i]=v_i	*/
 OP_SETMAP,/*	U	v_u k_u - v_0 k_0 t	t	t[k_i]=v_i	*/
 
 
 OP_ADD,/*	-	y x		x+y				*/
 OP_ADD,/*	-	y x		x+y				*/

+ 5 - 5
lparser.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lparser.c,v 1.86 2000/05/12 18:12:04 roberto Exp roberto $
+** $Id: lparser.c,v 1.87 2000/05/15 19:48:04 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -626,12 +626,12 @@ static int listfields (LexState *ls) {
     checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH,
     checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH,
                "items in a list initializer");
                "items in a list initializer");
     if (++mod_n == LFIELDS_PER_FLUSH) {
     if (++mod_n == LFIELDS_PER_FLUSH) {
-      luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH-1);
+      luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH);
       mod_n = 0;
       mod_n = 0;
     }
     }
   }
   }
   if (mod_n > 0)
   if (mod_n > 0)
-    luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, mod_n-1);
+    luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, mod_n);
   return n;
   return n;
 }
 }
 
 
@@ -911,12 +911,12 @@ static void repeatstat (LexState *ls, int line) {
 
 
 static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) {
 static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) {
   FuncState *fs = ls->fs;
   FuncState *fs = ls->fs;
-  int prep = luaK_code0(fs, prepfor);
+  int prep = luaK_code1(fs, prepfor, NO_JUMP);
   int blockinit = luaK_getlabel(fs);
   int blockinit = luaK_getlabel(fs);
   check(ls, TK_DO);
   check(ls, TK_DO);
   block(ls);
   block(ls);
   luaK_patchlist(fs, prep, luaK_getlabel(fs));
   luaK_patchlist(fs, prep, luaK_getlabel(fs));
-  luaK_patchlist(fs, luaK_code0(fs, loopfor), blockinit);
+  luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit);
 }
 }
 
 
 
 

+ 29 - 58
ltests.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltests.c,v 1.18 2000/05/10 16:33:20 roberto Exp roberto $
+** $Id: ltests.c,v 1.19 2000/05/15 19:48:04 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -14,6 +14,7 @@
 
 
 #include "lapi.h"
 #include "lapi.h"
 #include "lauxlib.h"
 #include "lauxlib.h"
+#include "lcode.h"
 #include "ldo.h"
 #include "ldo.h"
 #include "lmem.h"
 #include "lmem.h"
 #include "lopcodes.h"
 #include "lopcodes.h"
@@ -49,71 +50,41 @@ static void setnameval (lua_State *L, lua_Object t, const char *name, int val) {
 */
 */
 
 
 
 
-#define O(o)	sprintf(buff, "%s", o)
-#define U(o)	sprintf(buff, "%-12s%4u", o, GETARG_U(i))
-#define S(o)	sprintf(buff, "%-12s%4d", o, GETARG_S(i))
-#define AB(o)	sprintf(buff, "%-12s%4d %4d", o, GETARG_A(i), GETARG_B(i))
-
+static const char *const instrname[OP_SETLINE+1] = {
+  "END", "RETURN", "CALL", "TAILCALL", "PUSHNIL", "POP", "PUSHINT", 
+  "PUSHSTRING", "PUSHNUM", "PUSHNEGNUM", "PUSHUPVALUE", "GETLOCAL", 
+  "GETGLOBAL", "GETTABLE", "GETDOTTED", "GETINDEXED", "PUSHSELF", 
+  "CREATETABLE", "SETLOCAL", "SETGLOBAL", "SETTABLE", "SETLIST", "SETMAP", 
+  "ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT", 
+  "JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF", 
+  "JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP", 
+  "LFORLOOP", "CLOSURE", "SETLINE"
+};
 
 
 
 
 static int pushop (lua_State *L, Instruction i) {
 static int pushop (lua_State *L, Instruction i) {
   char buff[100];
   char buff[100];
-  switch (GET_OPCODE(i)) {
-    case OP_END: O("END"); lua_pushstring(L, buff); return 0;
-    case OP_RETURN: U("RETURN"); break;
-    case OP_CALL: AB("CALL"); break;
-    case OP_TAILCALL: AB("TAILCALL"); break;
-    case OP_PUSHNIL: U("PUSHNIL"); break;
-    case OP_POP: U("POP"); break;
-    case OP_PUSHINT: S("PUSHINT"); break;
-    case OP_PUSHSTRING: U("PUSHSTRING"); break;
-    case OP_PUSHNUM: U("PUSHNUM"); break;
-    case OP_PUSHNEGNUM: U("PUSHNEGNUM"); break;
-    case OP_PUSHUPVALUE: U("PUSHUPVALUE"); break;
-    case OP_GETLOCAL: U("GETLOCAL"); break;
-    case OP_GETGLOBAL: U("GETGLOBAL"); break;
-    case OP_GETTABLE: O("GETTABLE"); break;
-    case OP_GETDOTTED: U("GETDOTTED"); break;
-    case OP_GETINDEXED: U("GETINDEXED"); break;
-    case OP_PUSHSELF: U("PUSHSELF"); break;
-    case OP_CREATETABLE: U("CREATETABLE"); break;
-    case OP_SETLOCAL: U("SETLOCAL"); break;
-    case OP_SETGLOBAL: U("SETGLOBAL"); break;
-    case OP_SETTABLE: AB("SETTABLE"); break;
-    case OP_SETLIST: AB("SETLIST"); break;
-    case OP_SETMAP: U("SETMAP"); break;
-    case OP_ADD: O("ADD"); break;
-    case OP_ADDI: S("ADDI"); break;
-    case OP_SUB: O("SUB"); break;
-    case OP_MULT: O("MULT"); break;
-    case OP_DIV: O("DIV"); break;
-    case OP_POW: O("POW"); break;
-    case OP_CONCAT: U("CONCAT"); break;
-    case OP_MINUS: O("MINUS"); break;
-    case OP_NOT: O("NOT"); break;
-    case OP_JMPNE: S("JMPNE"); break;
-    case OP_JMPEQ: S("JMPEQ"); break;
-    case OP_JMPLT: S("JMPLT"); break;
-    case OP_JMPLE: S("JMPLE"); break;
-    case OP_JMPGT: S("JMPGT"); break;
-    case OP_JMPGE: S("JMPGE"); break;
-    case OP_JMPT: S("JMPT"); break;
-    case OP_JMPF: S("JMPF"); break;
-    case OP_JMPONT: S("JMPONT"); break;
-    case OP_JMPONF: S("JMPONF"); break;
-    case OP_JMP: S("JMP"); break;
-    case OP_PUSHNILJMP: O("PUSHNILJMP"); break;
-    case OP_FORPREP: S("FORPREP"); break;
-    case OP_FORLOOP: S("FORLOOP"); break;
-    case OP_LFORPREP: S("LFORPREP"); break;
-    case OP_LFORLOOP: S("LFORLOOP"); break;
-    case OP_CLOSURE: AB("CLOSURE"); break;
-    case OP_SETLINE: U("SETLINE"); break;
+  OpCode o = GET_OPCODE(i);
+  const char *name = instrname[o];
+  switch ((enum Mode)luaK_opproperties[o].mode) {  
+    case iO:
+      sprintf(buff, "%s", name);
+      break;
+    case iU:
+      sprintf(buff, "%-12s%4u", name, GETARG_U(i));
+      break;
+    case iS:
+      sprintf(buff, "%-12s%4d", name, GETARG_S(i));
+      break;
+    case iAB:
+      sprintf(buff, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i));
+      break;
   }
   }
   lua_pushstring(L, buff);
   lua_pushstring(L, buff);
-  return 1;
+  return (o != OP_END);
 }
 }
 
 
+
 static void listcode (lua_State *L) {
 static void listcode (lua_State *L) {
   lua_Object o = luaL_nonnullarg(L, 1);
   lua_Object o = luaL_nonnullarg(L, 1);
   lua_Object t = lua_createtable(L);
   lua_Object t = lua_createtable(L);

+ 2 - 2
lvm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lvm.c,v 1.105 2000/05/08 19:32:53 roberto Exp roberto $
+** $Id: lvm.c,v 1.106 2000/05/15 19:48:04 roberto Exp roberto $
 ** Lua virtual machine
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -470,7 +470,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
 
 
       case OP_SETLIST: {
       case OP_SETLIST: {
         int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
         int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
-        int n = GETARG_B(i)+1;
+        int n = GETARG_B(i);
         Hash *arr = avalue(top-n-1);
         Hash *arr = avalue(top-n-1);
         L->top = top-n;  /* final value of `top' (in case of errors) */
         L->top = top-n;  /* final value of `top' (in case of errors) */
         for (; n; n--)
         for (; n; n--)