Browse Source

limit of constants per function changed to 2^26 using extra arguments
to opcodes LOADK, GETGLOBAL, and SETGLOBAL

Roberto Ierusalimschy 16 years ago
parent
commit
fcc46467fa
5 changed files with 86 additions and 66 deletions
  1. 54 49
      lcode.c
  2. 4 2
      lcode.h
  3. 4 2
      ldebug.c
  4. 9 6
      lopcodes.h
  5. 15 7
      lvm.c

+ 54 - 49
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 2.40 2009/06/18 16:35:05 roberto Exp roberto $
+** $Id: lcode.c,v 2.41 2009/08/10 15:31:44 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -191,6 +191,55 @@ void luaK_concat (FuncState *fs, int *l1, int l2) {
 }
 
 
+static int luaK_code (FuncState *fs, Instruction i) {
+  Proto *f = fs->f;
+  dischargejpc(fs);  /* `pc' will change */
+  /* put new instruction in code array */
+  luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
+                  MAX_INT, "opcodes");
+  f->code[fs->pc] = i;
+  /* save corresponding line information */
+  luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
+                  MAX_INT, "opcodes");
+  f->lineinfo[fs->pc] = fs->ls->lastline;
+  return fs->pc++;
+}
+
+
+int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
+  lua_assert(getOpMode(o) == iABC);
+  lua_assert(getBMode(o) != OpArgN || b == 0);
+  lua_assert(getCMode(o) != OpArgN || c == 0);
+  lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
+  return luaK_code(fs, CREATE_ABC(o, a, b, c));
+}
+
+
+int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
+  lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
+  lua_assert(getCMode(o) == OpArgN);
+  lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
+  return luaK_code(fs, CREATE_ABx(o, a, bc));
+}
+
+
+static int codeextraarg (FuncState *fs, int a) {
+  lua_assert(a <= MAXARG_Ax);
+  return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
+}
+
+
+int luaK_codeABxX (FuncState *fs, OpCode o, int reg, int k) {
+  if (k < MAXARG_Bx)
+    return luaK_codeABx(fs, o, reg, k + 1);
+  else {
+    int p = luaK_codeABx(fs, o, reg, 0);
+    codeextraarg(fs, k);
+    return p;
+  }
+}
+
+
 void luaK_checkstack (FuncState *fs, int n) {
   int newstack = fs->freereg + n;
   if (newstack > fs->f->maxstacksize) {
@@ -238,7 +287,7 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
   oldsize = f->sizek;
   k = fs->nk;
   setnvalue(idx, cast_num(k));
-  luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Bx, "constants");
+  luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
   while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
   setobj(L, &f->k[k], v);
   fs->nk++;
@@ -324,7 +373,7 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
       break;
     }
     case VGLOBAL: {
-      e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
+      e->u.s.info = luaK_codeABxX(fs, OP_GETGLOBAL, 0, e->u.s.info);
       e->k = VRELOCABLE;
       break;
     }
@@ -496,7 +545,7 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
     }
     case VGLOBAL: {
       int e = luaK_exp2anyreg(fs, ex);
-      luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
+      luaK_codeABxX(fs, OP_SETGLOBAL, e, var->u.s.info);
       break;
     }
     case VINDEXED: {
@@ -802,50 +851,6 @@ void luaK_fixline (FuncState *fs, int line) {
 }
 
 
-static int luaK_code (FuncState *fs, Instruction i) {
-  Proto *f = fs->f;
-  dischargejpc(fs);  /* `pc' will change */
-  /* put new instruction in code array */
-  luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
-                  MAX_INT, "opcodes");
-  f->code[fs->pc] = i;
-  /* save corresponding line information */
-  luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
-                  MAX_INT, "opcodes");
-  f->lineinfo[fs->pc] = fs->ls->lastline;
-  return fs->pc++;
-}
-
-
-int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
-  lua_assert(getOpMode(o) == iABC);
-  lua_assert(getBMode(o) != OpArgN || b == 0);
-  lua_assert(getCMode(o) != OpArgN || c == 0);
-  lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
-  return luaK_code(fs, CREATE_ABC(o, a, b, c));
-}
-
-
-int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
-  lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
-  lua_assert(getCMode(o) == OpArgN);
-  lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
-  return luaK_code(fs, CREATE_ABx(o, a, bc));
-}
-
-
-static int luaK_codeAx (FuncState *fs, OpCode o, int a) {
-  lua_assert(getOpMode(o) == iAx);
-  lua_assert(a <= MAXARG_Ax);
-  return luaK_code(fs, CREATE_Ax(o, a));
-}
-
-
-void luaK_codek (FuncState *fs, int reg, int k) {
-    luaK_codeABx(fs, OP_LOADK, reg, k);
-}
-
-
 void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
   int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
   int b = (tostore == LUA_MULTRET) ? 0 : tostore;
@@ -854,7 +859,7 @@ void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
     luaK_codeABC(fs, OP_SETLIST, base, b, c);
   else if (c <= MAXARG_Ax) {
     luaK_codeABC(fs, OP_SETLIST, base, b, 0);
-    luaK_codeAx(fs, OP_EXTRAARG, c);
+    codeextraarg(fs, c);
   }
   else
     luaX_syntaxerror(fs->ls, "constructor too long");

+ 4 - 2
lcode.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.h,v 1.50 2009/06/10 16:52:03 roberto Exp roberto $
+** $Id: lcode.h,v 1.51 2009/06/18 16:35:05 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -44,9 +44,11 @@ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
 
 #define luaK_jumpto(fs,t)	luaK_patchlist(fs, luaK_jump(fs), t)
 
-LUAI_FUNC void luaK_codek (FuncState *fs, int reg, int k);
+#define luaK_codek(fs,reg,k)	    luaK_codeABxX(fs, OP_LOADK, reg, k)
+
 LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
 LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
+LUAI_FUNC int luaK_codeABxX (FuncState *fs, OpCode o, int reg, int k);
 LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
 LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
 LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);

+ 4 - 2
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.52 2009/06/10 16:57:53 roberto Exp roberto $
+** $Id: ldebug.c,v 2.53 2009/08/07 16:17:41 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -299,7 +299,9 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
     switch (op) {
       case OP_GETGLOBAL: {
         if (reg == a) {
-          int g = GETARG_Bx(i);  /* global index */
+          int g = GETARG_Bx(i);
+          if (g != 0) g--;
+          else g = GETARG_Ax(p->code[++pc]);
           lua_assert(ttisstring(&p->k[g]));
           *name = svalue(&p->k[g]);
           what = "global";

+ 9 - 6
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.128 2008/10/30 15:39:30 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.129 2009/03/09 15:27:56 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -166,15 +166,15 @@ typedef enum {
 name		args	description
 ------------------------------------------------------------------------*/
 OP_MOVE,/*	A B	R(A) := R(B)					*/
-OP_LOADK,/*	A Bx	R(A) := Kst(Bx)					*/
+OP_LOADK,/*	A Bx	R(A) := Kst(Bx - 1)				*/
 OP_LOADBOOL,/*	A B C	R(A) := (Bool)B; if (C) pc++			*/
 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_GETGLOBAL,/*	A Bx	R(A) := Gbl[Kst(Bx - 1)]			*/
 OP_GETTABLE,/*	A B C	R(A) := R(B)[RK(C)]				*/
 
-OP_SETGLOBAL,/*	A Bx	Gbl[Kst(Bx)] := R(A)				*/
+OP_SETGLOBAL,/*	A Bx	Gbl[Kst(Bx - 1)] := R(A)			*/
 OP_SETUPVAL,/*	A B	UpValue[B] := R(A)				*/
 OP_SETTABLE,/*	A B C	R(A)[RK(B)] := RK(C)				*/
 
@@ -221,7 +221,7 @@ OP_VARARG,/*	A B	R(A), R(A+1), ..., R(A+B-1) = vararg		*/
 
 OP_TFORLOOP,/*	A sBx	if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
 
-OP_EXTRAARG/*	Ax	extra argument for previous opcode		*/
+OP_EXTRAARG/*	Ax	extra (larger) argument for previous opcode	*/
 } OpCode;
 
 
@@ -241,7 +241,10 @@ OP_EXTRAARG/*	Ax	extra argument for previous opcode		*/
   (*) In OP_RETURN, if (B == 0) then return up to `top'.
 
   (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next
-  `instruction' is EXTRAARG(real C).
+  'instruction' is EXTRAARG(real C).
+
+  (*) In OP_LOADK, OP_GETGLOBAL, and OP_SETGLOBAL, if (Bx == 0) then next
+  'instruction' is EXTRAARG(real Bx).
 
   (*) For comparisons, A specifies what condition the test should accept
   (true or false).

+ 15 - 7
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.95 2009/07/15 18:38:16 roberto Exp roberto $
+** $Id: lvm.c,v 2.96 2009/08/07 16:17:41 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -353,7 +353,12 @@ void luaV_finishOp (lua_State *L) {
   CallInfo *ci = L->ci;
   StkId base = ci->u.l.base;
   Instruction inst = *(ci->u.l.savedpc - 1);  /* interrupted instruction */
-  switch (GET_OPCODE(inst)) {  /* finish its execution */
+  OpCode op = GET_OPCODE(inst);
+  if (op == OP_EXTRAARG) {  /* extra argument? */
+    inst = *(ci->u.l.savedpc - 2);  /* get its 'main' instruction */
+    op = GET_OPCODE(inst);
+  }
+  switch (op) {  /* finish its execution */
     case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
     case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:
     case OP_GETGLOBAL: case OP_GETTABLE: case OP_SELF: {
@@ -365,7 +370,7 @@ void luaV_finishOp (lua_State *L) {
       L->top--;
       /* metamethod should not be called when operand is K */
       lua_assert(!ISK(GETARG_B(inst)));
-      if (GET_OPCODE(inst) == OP_LE &&  /* "<=" using "<" instead? */
+      if (op == OP_LE &&  /* "<=" using "<" instead? */
           ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
         res = !res;  /* invert result */
       lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
@@ -417,7 +422,8 @@ void luaV_finishOp (lua_State *L) {
 	ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
 #define RKC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
 	ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
-#define KBx(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
+#define KBx(i)  \
+  (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++)))
 
 
 #define dojump(i)	{ ci->u.l.savedpc += (i); luai_threadyield(L);}
@@ -468,7 +474,8 @@ void luaV_execute (lua_State *L) {
         continue;
       }
       case OP_LOADK: {
-        setobj2s(L, ra, KBx(i));
+        TValue *rb = KBx(i);
+        setobj2s(L, ra, rb);
         continue;
       }
       case OP_LOADBOOL: {
@@ -502,9 +509,10 @@ void luaV_execute (lua_State *L) {
       }
       case OP_SETGLOBAL: {
         TValue g;
+        TValue *rb = KBx(i);
         sethvalue(L, &g, cl->env);
-        lua_assert(ttisstring(KBx(i)));
-        Protect(luaV_settable(L, &g, KBx(i), ra));
+        lua_assert(ttisstring(rb));
+        Protect(luaV_settable(L, &g, rb, ra));
         continue;
       }
       case OP_SETUPVAL: {