From fcc46467fa92c8e9951e63baf2c3e1b22bf20a1f Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 23 Sep 2009 17:33:05 -0300 Subject: limit of constants per function changed to 2^26 using extra arguments to opcodes LOADK, GETGLOBAL, and SETGLOBAL --- lcode.c | 103 ++++++++++++++++++++++++++++++++----------------------------- lcode.h | 6 ++-- ldebug.c | 6 ++-- lopcodes.h | 15 +++++---- lvm.c | 22 ++++++++----- 5 files changed, 86 insertions(+), 66 deletions(-) diff --git a/lcode.c b/lcode.c index 1fe5874f..e0ac8c10 100644 --- a/lcode.c +++ b/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"); diff --git a/lcode.h b/lcode.h index 55426417..63371ad4 100644 --- a/lcode.h +++ b/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); diff --git a/ldebug.c b/ldebug.c index 58039611..8e63a4f9 100644 --- a/ldebug.c +++ b/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"; diff --git a/lopcodes.h b/lopcodes.h index 7471fedc..866c1641 100644 --- a/lopcodes.h +++ b/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). diff --git a/lvm.c b/lvm.c index d1c04835..f3a452de 100644 --- a/lvm.c +++ b/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: { -- cgit v1.2.3-55-g6feb