Browse Source

new simetric format for ABC instructions, to avoid exchanging operands
for `commutative' operators

Roberto Ierusalimschy 23 years ago
parent
commit
6c283b2f4f
7 changed files with 131 additions and 153 deletions
  1. 26 41
      lcode.c
  2. 13 6
      ldebug.c
  3. 2 2
      ldebug.h
  4. 39 43
      lopcodes.c
  5. 24 24
      lopcodes.h
  6. 5 5
      lparser.c
  7. 22 32
      lvm.c

+ 26 - 41
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.108 2002/06/13 13:39:55 roberto Exp $
+** $Id: lcode.c,v 1.109 2002/08/05 14:07:34 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -100,14 +100,14 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) {
 static int need_value (FuncState *fs, int list, int cond) {
   for (; list != NO_JUMP; list = luaK_getjump(fs, list)) {
     Instruction i = *getjumpcontrol(fs, list);
-    if (GET_OPCODE(i) != OP_TEST || GETARG_B(i) != cond) return 1;
+    if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;
   }
   return 0;  /* not found */
 }
 
 
 static void patchtestreg (Instruction *i, int reg) {
-  if (reg == NO_REG) reg = GETARG_C(*i);
+  if (reg == NO_REG) reg = GETARG_B(*i);
   SETARG_A(*i, reg);
 }
 
@@ -122,7 +122,7 @@ static void luaK_patchlistaux (FuncState *fs, int list,
       luaK_fixjump(fs, list, dtarget);  /* jump to default target */
     }
     else {
-      if (GETARG_B(*i)) {
+      if (GETARG_C(*i)) {
         lua_assert(ttarget != NO_JUMP);
         patchtestreg(i, treg);
         luaK_fixjump(fs, list, ttarget);
@@ -409,7 +409,7 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
     }
     default: break;
   }
-  /* not a constant in the right range: put in a register */
+  /* not a constant in the right range: put it in a register */
   return luaK_exp2anyreg(fs, e);
 }
 
@@ -432,8 +432,8 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) {
       break;
     }
     case VINDEXED: {
-      int e = luaK_exp2anyreg(fs, exp);
-      luaK_codeABC(fs, OP_SETTABLE, e, var->info, var->aux);
+      int e = luaK_exp2RK(fs, exp);
+      luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e);
       break;
     }
     default: {
@@ -460,8 +460,9 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
 
 static void invertjump (FuncState *fs, expdesc *e) {
   Instruction *pc = getjumpcontrol(fs, e->info);
-  lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT));
-  SETARG_B(*pc, !(GETARG_B(*pc)));
+  lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) &&
+             GET_OPCODE(*pc) != OP_TEST);
+  SETARG_A(*pc, !(GETARG_A(*pc)));
 }
 
 
@@ -470,13 +471,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
     Instruction ie = getcode(fs, e);
     if (GET_OPCODE(ie) == OP_NOT) {
       fs->pc--;  /* remove previous OP_NOT */
-      return luaK_condjump(fs, OP_TEST, NO_REG, !cond ,GETARG_B(ie));
+      return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
     }
     /* else go through */
   }
   discharge2anyreg(fs, e);
   freeexp(fs, e);
-  return luaK_condjump(fs, OP_TEST, NO_REG, cond, e->info);
+  return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond);
 }
 
 
@@ -605,11 +606,6 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
       luaK_exp2nextreg(fs, v);  /* operand must be on the `stack' */
       break;
     }
-    case OPR_SUB: case OPR_DIV: case OPR_POW: {
-      /* non-comutative operators */
-      luaK_exp2anyreg(fs, v);  /* first operand must be a register */
-      break;
-    }
     default: {
       luaK_exp2RK(fs, v);
       break;
@@ -619,13 +615,11 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
 
 
 static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
-                       int o1, int o2, int ic) {
+                       int o1, int o2) {
   switch (op) {
     case OPR_SUB:
     case OPR_DIV:
     case OPR_POW:
-      lua_assert(!ic);
-      /* go through */
     case OPR_ADD:
     case OPR_MULT: {  /* ORDER OPR */
       OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD);
@@ -635,20 +629,21 @@ static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
     }
     case OPR_NE:
     case OPR_EQ: {
-      res->info = luaK_condjump(fs, OP_EQ, o1, (op == OPR_EQ), o2);
+      res->info = luaK_condjump(fs, OP_EQ, (op == OPR_EQ), o1, o2);
       res->k = VJMP;
       break;
     }
-    case OPR_LT:
-    case OPR_LE:
     case OPR_GT:
     case OPR_GE: {  /* ORDER OPR */
-      OpCode opc;
-      int i = op - OPR_LT;
-      if (ic)  /* operands were interchanged? */
-        i = (i+2)&3;  /* correct operator */
-      opc = cast(OpCode, i + OP_LT);
-      res->info = luaK_condjump(fs, opc, o1, 1, o2);
+      int temp;
+      temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */
+      op -= 2;  /* GT -> LT, GE -> LE */
+      /* go through */
+    }
+    case OPR_LT:
+    case OPR_LE: {
+      OpCode opc = cast(OpCode, (op - OPR_LT) + OP_LT);
+      res->info = luaK_condjump(fs, opc, 1, o1, o2);
       res->k = VJMP;
       break;
     }
@@ -691,21 +686,11 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
       break;
     }
     default: {
-      int o1, o2;
-      int ic;  /* interchange flag */
-      if (e1->k != VK) {  /* not a constant operator? */
-        o1 = e1->info;
-        o2 = luaK_exp2RK(fs, e2);  /* maybe other operator is constant... */
-        ic = 0;
-      }
-      else {  /* interchange operands */
-        o2 = luaK_exp2RK(fs, e1);  /* constant must be 2nd operand */
-        o1 = luaK_exp2anyreg(fs, e2);  /* other operator must be in register */
-        ic = 1;
-      }
+      int o1 = luaK_exp2RK(fs, e1);
+      int o2 = luaK_exp2RK(fs, e2);
       freeexp(fs, e2);
       freeexp(fs, e1);
-      codebinop(fs, e1, op, o1, o2, ic);
+      codebinop(fs, e1, op, o1, o2);
     }
   }
 }

+ 13 - 6
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 1.131 2002/08/08 20:08:41 roberto Exp roberto $
+** $Id: ldebug.c,v 1.132 2002/08/12 17:23:12 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -269,6 +269,11 @@ static int checkopenop (const Proto *pt, int pc) {
 }
 
 
+static int checkRK (const Proto *pt, int r) {
+  return (r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek));
+}
+
+
 static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
   int pc;
   int last;  /* stores position of last instruction that changed `reg' */
@@ -285,11 +290,13 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
       case iABC: {
         b = GETARG_B(i);
         c = GETARG_C(i);
-        if (testOpMode(op, OpModeBreg))
+        if (testOpMode(op, OpModeBreg)) {
           checkreg(pt, b);
-        if (testOpMode(op, OpModeCreg))
-          check(c < pt->maxstacksize ||
-               (c >= MAXSTACK && c-MAXSTACK < pt->sizek));
+        }
+        else if (testOpMode(op, OpModeBrk))
+          check(checkRK(pt, b));
+        if (testOpMode(op, OpModeCrk))
+          check(checkRK(pt, c));
         break;
       }
       case iABx: {
@@ -496,7 +503,7 @@ void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
 }
 
 
-void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2) {
+void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2) {
   TObject temp;
   if (luaV_tonumber(p1, &temp) == NULL)
     p2 = p1;  /* first operand is wrong */

+ 2 - 2
ldebug.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.h,v 1.29 2002/08/08 20:08:41 roberto Exp roberto $
+** $Id: ldebug.h,v 1.30 2002/08/12 17:23:12 roberto Exp roberto $
 ** Auxiliary functions from Debug Interface module
 ** See Copyright Notice in lua.h
 */
@@ -23,7 +23,7 @@
 
 void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
 void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
-void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2);
+void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2);
 int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2);
 void luaG_runerror (lua_State *L, const char *fmt, ...);
 void luaG_errormsg (lua_State *L);

+ 39 - 43
lopcodes.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.c,v 1.19 2002/05/13 13:09:00 roberto Exp roberto $
+** $Id: lopcodes.c,v 1.20 2002/06/12 14:51:31 roberto Exp roberto $
 ** extracted automatically from lopcodes.h by mkprint.lua
 ** DO NOT EDIT
 ** See Copyright Notice in lua.h
@@ -39,8 +39,6 @@ const char *const luaP_opnames[] = {
   "EQ",
   "LT",
   "LE",
-  "GT",
-  "GE",
   "TEST",
   "CALL",
   "TAILCALL",
@@ -56,49 +54,47 @@ const char *const luaP_opnames[] = {
 
 #endif
 
-#define opmode(t,x,b,c,sa,k,m) (((t)<<OpModeT) | \
-   ((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \
+#define opmode(t,b,bk,ck,sa,k,m) (((t)<<OpModeT) | \
+   ((b)<<OpModeBreg) | ((bk)<<OpModeBrk) | ((ck)<<OpModeCrk) | \
    ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m))
 
 
 const lu_byte luaP_opmodes[NUM_OPCODES] = {
-/*       T _ B C sA K mode		   opcode    */
-  opmode(0,0,1,0, 1,0,iABC)		/* OP_MOVE */
- ,opmode(0,0,0,0, 1,1,iABx)		/* OP_LOADK */
- ,opmode(0,0,0,0, 1,0,iABC)		/* OP_LOADBOOL */
- ,opmode(0,0,1,0, 1,0,iABC)		/* OP_LOADNIL */
- ,opmode(0,0,0,0, 1,0,iABC)		/* OP_GETUPVAL */
- ,opmode(0,0,0,0, 1,1,iABx)		/* OP_GETGLOBAL */
- ,opmode(0,0,1,1, 1,0,iABC)		/* OP_GETTABLE */
- ,opmode(0,0,0,0, 0,1,iABx)		/* OP_SETGLOBAL */
- ,opmode(0,0,0,0, 0,0,iABC)		/* OP_SETUPVAL */
- ,opmode(0,0,1,1, 0,0,iABC)		/* OP_SETTABLE */
- ,opmode(0,0,0,0, 1,0,iABC)		/* OP_NEWTABLE */
- ,opmode(0,0,1,1, 1,0,iABC)		/* OP_SELF */
- ,opmode(0,0,1,1, 1,0,iABC)		/* OP_ADD */
- ,opmode(0,0,1,1, 1,0,iABC)		/* OP_SUB */
- ,opmode(0,0,1,1, 1,0,iABC)		/* OP_MUL */
- ,opmode(0,0,1,1, 1,0,iABC)		/* OP_DIV */
- ,opmode(0,0,1,1, 1,0,iABC)		/* OP_POW */
- ,opmode(0,0,1,0, 1,0,iABC)		/* OP_UNM */
- ,opmode(0,0,1,0, 1,0,iABC)		/* OP_NOT */
- ,opmode(0,0,1,1, 1,0,iABC)		/* OP_CONCAT */
- ,opmode(0,0,0,0, 0,0,iAsBx)		/* OP_JMP */
- ,opmode(1,0,0,1, 0,0,iABC)		/* OP_EQ */
- ,opmode(1,0,0,1, 0,0,iABC)		/* OP_LT */
- ,opmode(1,0,0,1, 0,0,iABC)		/* OP_LE */
- ,opmode(1,0,0,1, 0,0,iABC)		/* OP_GT */
- ,opmode(1,0,0,1, 0,0,iABC)		/* OP_GE */
- ,opmode(1,0,0,1, 1,0,iABC)		/* OP_TEST */
- ,opmode(0,0,0,0, 0,0,iABC)		/* OP_CALL */
- ,opmode(0,0,0,0, 0,0,iABC)		/* OP_TAILCALL */
- ,opmode(0,0,0,0, 0,0,iABC)		/* OP_RETURN */
- ,opmode(0,0,0,0, 0,0,iAsBx)		/* OP_FORLOOP */
- ,opmode(1,0,0,0, 0,0,iABC)		/* OP_TFORLOOP */
- ,opmode(0,0,0,0, 0,0,iAsBx)		/* OP_TFORPREP */
- ,opmode(0,0,0,0, 0,0,iABx)		/* OP_SETLIST */
- ,opmode(0,0,0,0, 0,0,iABx)		/* OP_SETLISTO */
- ,opmode(0,0,0,0, 0,0,iABC)		/* OP_CLOSE */
- ,opmode(0,0,0,0, 1,0,iABx)		/* OP_CLOSURE */
+/*       T  B Bk Ck sA  K  mode			   opcode    */
+  opmode(0, 1, 0, 0, 1, 0, iABC)		/* OP_MOVE */
+ ,opmode(0, 0, 0, 0, 1, 1, iABx)		/* OP_LOADK */
+ ,opmode(0, 0, 0, 0, 1, 0, iABC)		/* OP_LOADBOOL */
+ ,opmode(0, 1, 0, 0, 1, 0, iABC)		/* OP_LOADNIL */
+ ,opmode(0, 0, 0, 0, 1, 0, iABC)		/* OP_GETUPVAL */
+ ,opmode(0, 0, 0, 0, 1, 1, iABx)		/* OP_GETGLOBAL */
+ ,opmode(0, 1, 0, 1, 1, 0, iABC)		/* OP_GETTABLE */
+ ,opmode(0, 0, 0, 0, 0, 1, iABx)		/* OP_SETGLOBAL */
+ ,opmode(0, 0, 0, 0, 0, 0, iABC)		/* OP_SETUPVAL */
+ ,opmode(0, 0, 1, 1, 0, 0, iABC)		/* OP_SETTABLE */
+ ,opmode(0, 0, 0, 0, 1, 0, iABC)		/* OP_NEWTABLE */
+ ,opmode(0, 1, 0, 1, 1, 0, iABC)		/* OP_SELF */
+ ,opmode(0, 0, 1, 1, 1, 0, iABC)		/* OP_ADD */
+ ,opmode(0, 0, 1, 1, 1, 0, iABC)		/* OP_SUB */
+ ,opmode(0, 0, 1, 1, 1, 0, iABC)		/* OP_MUL */
+ ,opmode(0, 0, 1, 1, 1, 0, iABC)		/* OP_DIV */
+ ,opmode(0, 0, 1, 1, 1, 0, iABC)		/* OP_POW */
+ ,opmode(0, 1, 0, 0, 1, 0, iABC)		/* OP_UNM */
+ ,opmode(0, 1, 0, 0, 1, 0, iABC)		/* OP_NOT */
+ ,opmode(0, 1, 0, 1, 1, 0, iABC)		/* OP_CONCAT */
+ ,opmode(0, 0, 0, 0, 0, 0, iAsBx)		/* OP_JMP */
+ ,opmode(1, 0, 1, 1, 0, 0, iABC)		/* OP_EQ */
+ ,opmode(1, 0, 1, 1, 0, 0, iABC)		/* OP_LT */
+ ,opmode(1, 0, 1, 1, 0, 0, iABC)		/* OP_LE */
+ ,opmode(1, 1, 0, 0, 1, 0, iABC)		/* OP_TEST */
+ ,opmode(0, 0, 0, 0, 0, 0, iABC)		/* OP_CALL */
+ ,opmode(0, 0, 0, 0, 0, 0, iABC)		/* OP_TAILCALL */
+ ,opmode(0, 0, 0, 0, 0, 0, iABC)		/* OP_RETURN */
+ ,opmode(0, 0, 0, 0, 0, 0, iAsBx)		/* OP_FORLOOP */
+ ,opmode(1, 0, 0, 0, 0, 0, iABC)		/* OP_TFORLOOP */
+ ,opmode(0, 0, 0, 0, 0, 0, iAsBx)		/* OP_TFORPREP */
+ ,opmode(0, 0, 0, 0, 0, 0, iABx)		/* OP_SETLIST */
+ ,opmode(0, 0, 0, 0, 0, 0, iABx)		/* OP_SETLISTO */
+ ,opmode(0, 0, 0, 0, 0, 0, iABC)		/* OP_CLOSE */
+ ,opmode(0, 0, 0, 0, 1, 0, iABx)		/* OP_CLOSURE */
 };
 

+ 24 - 24
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.99 2002/06/12 14:51:31 roberto Exp $
+** $Id: lopcodes.h,v 1.100 2002/08/05 14:46:43 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -14,9 +14,9 @@
   We assume that instructions are unsigned numbers.
   All instructions have an opcode in the first 6 bits.
   Instructions can have the following fields:
-	`A' : 8 bits (25-32)
-	`B' : 8 bits (17-24)
-	`C' : 10 bits (7-16)
+	`A' : 8 bits
+	`B' : 9 bits
+	`C' : 9 bits
 	`Bx' : 18 bits (`B' and `C' together)
 	`sBx' : signed Bx
 
@@ -34,8 +34,8 @@ enum OpMode {iABC, iABx, iAsBx};  /* basic instruction format */
 /*
 ** size and position of opcode arguments.
 */
-#define SIZE_C		10
-#define SIZE_B		8
+#define SIZE_C		9
+#define SIZE_B		9
 #define SIZE_Bx		(SIZE_C + SIZE_B)
 #define SIZE_A		8
 
@@ -112,16 +112,15 @@ enum OpMode {iABC, iABx, iAsBx};  /* basic instruction format */
 
 
 /*
-** invalid registers that fits in 8 bits
+** invalid register that fits in 8 bits
 */
 #define NO_REG		MAXARG_A
-#define NO_REG1		(NO_REG+1)
 
 
 /*
 ** R(x) - register
 ** Kst(x) - constant (in constant table)
-** R/K(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK)
+** RK(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK)
 */
 
 typedef enum {
@@ -135,21 +134,21 @@ OP_LOADNIL,/*	A B	R(A) := ... := R(B) := nil			*/
 OP_GETUPVAL,/*	A B	R(A) := UpValue[B]				*/
 
 OP_GETGLOBAL,/*	A Bx	R(A) := Gbl[Kst(Bx)]				*/
-OP_GETTABLE,/*	A B C	R(A) := R(B)[R/K(C)]				*/
+OP_GETTABLE,/*	A B C	R(A) := R(B)[RK(C)]				*/
 
 OP_SETGLOBAL,/*	A Bx	Gbl[Kst(Bx)] := R(A)				*/
 OP_SETUPVAL,/*	A B	UpValue[B] := R(A)				*/
-OP_SETTABLE,/*	A B C	R(B)[R/K(C)] := R(A)				*/
+OP_SETTABLE,/*	A B C	R(A)[RK(B)] := RK(C)				*/
 
 OP_NEWTABLE,/*	A B C	R(A) := {} (size = B,C)				*/
 
-OP_SELF,/*	A B C	R(A+1) := R(B); R(A) := R(B)[R/K(C)]		*/
+OP_SELF,/*	A B C	R(A+1) := R(B); R(A) := R(B)[RK(C)]		*/
 
-OP_ADD,/*	A B C	R(A) := R(B) + R/K(C)				*/
-OP_SUB,/*	A B C	R(A) := R(B) - R/K(C)				*/
-OP_MUL,/*	A B C	R(A) := R(B) * R/K(C)				*/
-OP_DIV,/*	A B C	R(A) := R(B) / R/K(C)				*/
-OP_POW,/*	A B C	R(A) := R(B) ^ R/K(C)				*/
+OP_ADD,/*	A B C	R(A) := RK(B) + RK(C)				*/
+OP_SUB,/*	A B C	R(A) := RK(B) - RK(C)				*/
+OP_MUL,/*	A B C	R(A) := RK(B) * RK(C)				*/
+OP_DIV,/*	A B C	R(A) := RK(B) / RK(C)				*/
+OP_POW,/*	A B C	R(A) := RK(B) ^ RK(C)				*/
 OP_UNM,/*	A B	R(A) := -R(B)					*/
 OP_NOT,/*	A B	R(A) := not R(B)				*/
 
@@ -157,13 +156,11 @@ OP_CONCAT,/*	A B C	R(A) := R(B).. ... ..R(C)			*/
 
 OP_JMP,/*	sBx	PC += sBx					*/
 
-OP_EQ,/*	A B C	if ((R(A) == R/K(C)) ~= B) then pc++		*/
-OP_LT,/*	A B C	if ((R(A) <  R/K(C)) ~= B) then pc++  		*/
-OP_LE,/*	A B C	if ((R(A) <= R/K(C)) ~= B) then pc++  		*/
-OP_GT,/*	A B C	if ((R(A) >  R/K(C)) ~= B) then pc++  		*/
-OP_GE,/*	A B C	if ((R(A) >= R/K(C)) ~= B) then pc++  		*/
+OP_EQ,/*	A B C	if ((RK(B) == RK(C)) ~= A) then pc++		*/
+OP_LT,/*	A B C	if ((RK(B) <  RK(C)) ~= A) then pc++  		*/
+OP_LE,/*	A B C	if ((RK(B) <= RK(C)) ~= A) then pc++  		*/
 
-OP_TEST,/*	A B C	if (R(C) <=> B) then R(A) := R(C) else pc++	*/ 
+OP_TEST,/*	A B C	if (R(B) <=> C) then R(A) := R(B) else pc++	*/ 
 
 OP_CALL,/*	A B C	R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
 OP_TAILCALL,/*	A B C	return R(A)(R(A+1), ... ,R(A+B-1))		*/
@@ -207,12 +204,15 @@ OP_CLOSURE/*	A Bx	R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))	*/
 */  
 enum OpModeMask {
   OpModeBreg = 2,       /* B is a register */
-  OpModeCreg,           /* C is a register/constant */
+  OpModeBrk,		/* B is a register/constant */
+  OpModeCrk,           /* C is a register/constant */
   OpModesetA,           /* instruction set register A */
   OpModeK,              /* Bx is a constant */
   OpModeT		/* operator is a test */
+  
 };
 
+
 extern const lu_byte luaP_opmodes[NUM_OPCODES];
 
 #define getOpMode(m)            (cast(enum OpMode, luaP_opmodes[m] & 3))

+ 5 - 5
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.190 2002/07/04 18:23:42 roberto Exp $
+** $Id: lparser.c,v 1.191 2002/08/05 17:35:45 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -324,7 +324,7 @@ static void open_func (LexState *ls, FuncState *fs) {
   fs->bl = NULL;
   f->code = NULL;
   f->source = ls->source;
-  f->maxstacksize = 1;  /* register 0 is always valid */
+  f->maxstacksize = 2;  /* registers 0/1 are always valid */
   f->numparams = 0;  /* default for main chunk */
   f->is_vararg = 0;  /* default for main chunk */
 }
@@ -489,8 +489,8 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
   check(ls, '=');
   luaK_exp2RK(fs, &key);
   expr(ls, &val);
-  luaK_exp2anyreg(fs, &val);
-  luaK_codeABC(fs, OP_SETTABLE, val.info, cc->t->info, luaK_exp2RK(fs, &key));
+  luaK_codeABC(fs, OP_SETTABLE, cc->t->info, luaK_exp2RK(fs, &key),
+                                             luaK_exp2RK(fs, &val));
   fs->freereg = reg;  /* free registers */
 }
 
@@ -735,7 +735,7 @@ static const struct {
   lu_byte right; /* right priority */
 } priority[] = {  /* ORDER OPR */
    {6, 6}, {6, 6}, {7, 7}, {7, 7},  /* arithmetic */
-   {10, 9}, {5, 4},                  /* power and concat (right associative) */
+   {10, 9}, {5, 4},                 /* power and concat (right associative) */
    {3, 3}, {3, 3},                  /* equality */
    {3, 3}, {3, 3}, {3, 3}, {3, 3},  /* order */
    {2, 2}, {1, 1}                   /* logical (and/or) */

+ 22 - 32
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.251 2002/08/07 19:22:39 roberto Exp roberto $
+** $Id: lvm.c,v 1.252 2002/08/12 17:23:12 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -318,7 +318,8 @@ void luaV_concat (lua_State *L, int total, int last) {
 }
 
 
-static void Arith (lua_State *L, StkId ra, StkId rb, StkId rc, TMS op) {
+static void Arith (lua_State *L, StkId ra,
+                   const TObject *rb, const TObject *rc, TMS op) {
   TObject tempb, tempc;
   const TObject *b, *c;
   if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
@@ -356,10 +357,9 @@ static void Arith (lua_State *L, StkId ra, StkId rb, StkId rc, TMS op) {
 
 #define RA(i)	(base+GETARG_A(i))
 #define RB(i)	(base+GETARG_B(i))
+#define RKB(i)	((GETARG_B(i) < MAXSTACK) ? RB(i) : k+GETARG_B(i)-MAXSTACK)
 #define RC(i)	(base+GETARG_C(i))
-#define RKC(i)	((GETARG_C(i) < MAXSTACK) ? \
-			base+GETARG_C(i) : \
-			k+GETARG_C(i)-MAXSTACK)
+#define RKC(i)	((GETARG_C(i) < MAXSTACK) ? RC(i) : k+GETARG_C(i)-MAXSTACK)
 #define KBx(i)	(k+GETARG_Bx(i))
 
 
@@ -423,7 +423,7 @@ StkId luaV_execute (lua_State *L) {
         break;
       }
       case OP_GETGLOBAL: {
-        StkId rb = KBx(i);
+        TObject *rb = KBx(i);
         const TObject *v;
         lua_assert(ttisstring(rb) && ttistable(&cl->g));
         v = luaH_getstr(hvalue(&cl->g), tsvalue(rb));
@@ -456,7 +456,7 @@ StkId luaV_execute (lua_State *L) {
         break;
       }
       case OP_SETTABLE: {
-        luaV_settable(L, RB(i), RKC(i), ra);
+        luaV_settable(L, ra, RKB(i), RKC(i));
         break;
       }
       case OP_NEWTABLE: {
@@ -482,8 +482,8 @@ StkId luaV_execute (lua_State *L) {
         break;
       }
       case OP_ADD: {
-        StkId rb = RB(i);
-        StkId rc = RKC(i);
+        TObject *rb = RKB(i);
+        TObject *rc = RKC(i);
         if (ttisnumber(rb) && ttisnumber(rc)) {
           setnvalue(ra, nvalue(rb) + nvalue(rc));
         }
@@ -492,8 +492,8 @@ StkId luaV_execute (lua_State *L) {
         break;
       }
       case OP_SUB: {
-        StkId rb = RB(i);
-        StkId rc = RKC(i);
+        TObject *rb = RKB(i);
+        TObject *rc = RKC(i);
         if (ttisnumber(rb) && ttisnumber(rc)) {
           setnvalue(ra, nvalue(rb) - nvalue(rc));
         }
@@ -502,8 +502,8 @@ StkId luaV_execute (lua_State *L) {
         break;
       }
       case OP_MUL: {
-        StkId rb = RB(i);
-        StkId rc = RKC(i);
+        TObject *rb = RKB(i);
+        TObject *rc = RKC(i);
         if (ttisnumber(rb) && ttisnumber(rc)) {
           setnvalue(ra, nvalue(rb) * nvalue(rc));
         }
@@ -512,8 +512,8 @@ StkId luaV_execute (lua_State *L) {
         break;
       }
       case OP_DIV: {
-        StkId rb = RB(i);
-        StkId rc = RKC(i);
+        TObject *rb = RKB(i);
+        TObject *rc = RKC(i);
         if (ttisnumber(rb) && ttisnumber(rc)) {
           setnvalue(ra, nvalue(rb) / nvalue(rc));
         }
@@ -522,7 +522,7 @@ StkId luaV_execute (lua_State *L) {
         break;
       }
       case OP_POW: {
-        Arith(L, ra, RB(i), RKC(i), TM_POW);
+        Arith(L, ra, RKB(i), RKC(i), TM_POW);
         break;
       }
       case OP_UNM: {
@@ -556,35 +556,25 @@ StkId luaV_execute (lua_State *L) {
         break;
       }
       case OP_EQ: {  /* skip next instruction if test fails */
-        if (equalobj(L, ra, RKC(i)) != GETARG_B(i)) pc++;
+        if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
         else dojump(pc, GETARG_sBx(*pc) + 1);
         break;
       }
       case OP_LT: {
-        if (luaV_lessthan(L, ra, RKC(i)) != GETARG_B(i)) pc++;
+        if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
         else dojump(pc, GETARG_sBx(*pc) + 1);
         break;
       }
       case OP_LE: {
-        if (luaV_lessequal(L, ra, RKC(i)) != GETARG_B(i)) pc++;
-        else dojump(pc, GETARG_sBx(*pc) + 1);
-        break;
-      }
-      case OP_GT: {
-        if (luaV_lessthan(L, RKC(i), ra) != GETARG_B(i)) pc++;
-        else dojump(pc, GETARG_sBx(*pc) + 1);
-        break;
-      }
-      case OP_GE: {
-        if (luaV_lessequal(L, RKC(i), ra) != GETARG_B(i)) pc++;
+        if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(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++;
+        TObject *rb = RB(i);
+        if (l_isfalse(rb) == GETARG_C(i)) pc++;
         else {
-          setobj(ra, rc);
+          setobj(ra, rb);
           dojump(pc, GETARG_sBx(*pc) + 1);
         }
         break;