From a4d3080fe3d07af9d2d3124b8f49eadda7c21b44 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 2 Apr 2008 14:38:54 -0300 Subject: [PATCH] SETLIST extra argument now is an "instruction" (OP_EXTRAARG) --- lcode.c | 14 +++++++++++--- ldebug.c | 18 +++++++----------- lopcodes.c | 4 +++- lopcodes.h | 52 ++++++++++++++++++++++++++++++++++------------------ ltests.c | 5 ++++- lvm.c | 11 +++++++++-- 6 files changed, 68 insertions(+), 36 deletions(-) diff --git a/lcode.c b/lcode.c index 853cffe2..96ef6b96 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.33 2007/03/27 14:11:38 roberto Exp roberto $ +** $Id: lcode.c,v 2.34 2007/05/04 18:41:49 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -824,16 +824,24 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { } +static int luaK_codeAx (FuncState *fs, OpCode o, int a) { + lua_assert(getOpMode(o) == iAx); + return luaK_code(fs, CREATE_Ax(o, a)); +} + + 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; lua_assert(tostore != 0); if (c <= MAXARG_C) luaK_codeABC(fs, OP_SETLIST, base, b, c); - else { + else if (c <= MAXARG_Ax) { luaK_codeABC(fs, OP_SETLIST, base, b, 0); - luaK_code(fs, cast(Instruction, c)); + luaK_codeAx(fs, OP_EXTRAARG, c); } + else + luaX_syntaxerror(fs->ls, "constructor too long"); fs->freereg = base + 1; /* free registers with list values */ } diff --git a/ldebug.c b/ldebug.c index e76da28c..eb11ce17 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.36 2007/05/09 15:49:36 roberto Exp roberto $ +** $Id: ldebug.c,v 2.37 2007/05/29 18:59:59 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -331,9 +331,9 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { int b = 0; int c = 0; check(op < NUM_OPCODES); - checkreg(pt, a); switch (getOpMode(op)) { case iABC: { + checkreg(pt, a); b = GETARG_B(i); c = GETARG_C(i); check(checkArgMode(pt, b, getBMode(op))); @@ -341,31 +341,27 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { break; } case iABx: { + checkreg(pt, a); b = GETARG_Bx(i); if (getBMode(op) == OpArgK) check(b < pt->sizek); break; } case iAsBx: { + checkreg(pt, a); b = GETARG_sBx(i); if (getBMode(op) == OpArgR) { int dest = pc+1+b; check(0 <= dest && dest < pt->sizecode); - if (dest > 0) { - /* cannot jump to a setlist count */ - Instruction d = pt->code[dest-1]; - check(!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)); - } } break; } + case iAx: break; } if (testAMode(op)) { if (a == reg) last = pc; /* change register `a' */ } - if (testTMode(op)) { - check(pc+2 < pt->sizecode); /* check skip */ + if (testTMode(op)) check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); - } switch (op) { case OP_LOADBOOL: { check(c == 0 || pc+2 < pt->sizecode); /* check its jump */ @@ -433,7 +429,7 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { } case OP_SETLIST: { if (b > 0) checkreg(pt, a + b); - if (c == 0) pc++; + if (c == 0) check(GET_OPCODE(pt->code[pc + 1]) == OP_EXTRAARG); break; } case OP_CLOSURE: { diff --git a/lopcodes.c b/lopcodes.c index b298b410..133860fc 100644 --- a/lopcodes.c +++ b/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.37 2005/11/08 19:45:36 roberto Exp roberto $ +** $Id: lopcodes.c,v 1.38 2006/09/11 14:07:24 roberto Exp roberto $ ** See Copyright Notice in lua.h */ @@ -52,6 +52,7 @@ const char *const luaP_opnames[NUM_OPCODES+1] = { "CLOSE", "CLOSURE", "VARARG", + "EXTRAARG", NULL }; @@ -98,5 +99,6 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ + ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ }; diff --git a/lopcodes.h b/lopcodes.h index 634a13f3..d52afc1d 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.125 2006/03/14 19:04:44 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.126 2006/09/11 14:07:24 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -28,7 +28,7 @@ ===========================================================================*/ -enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ +enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ /* @@ -38,6 +38,7 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ #define SIZE_B 9 #define SIZE_Bx (SIZE_C + SIZE_B) #define SIZE_A 8 +#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A) #define SIZE_OP 6 @@ -46,6 +47,7 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ #define POS_C (POS_A + SIZE_A) #define POS_B (POS_C + SIZE_C) #define POS_Bx POS_C +#define POS_Ax POS_A /* @@ -61,6 +63,12 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ #define MAXARG_sBx MAX_INT #endif +#if SIZE_Ax < LUAI_BITSINT-1 +#define MAXARG_Ax ((1<>POS_A) & MASK1(SIZE_A,0))) -#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ - ((cast(Instruction, u)<>pos) & MASK1(size,0))) +#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ + ((cast(Instruction, v)<>POS_B) & MASK1(SIZE_B,0))) -#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ - ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) -#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ - ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) -#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ - ((cast(Instruction, b)<=) R(A)*/ OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ -OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ +OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ + +OP_EXTRAARG/* Ax extra argument for previous opcode */ } OpCode; -#define NUM_OPCODES (cast(int, OP_VARARG) + 1) +#define NUM_OPCODES (cast(int, OP_EXTRAARG) + 1) @@ -224,7 +240,7 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ (*) 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 real C + if (C == 0) then next `instruction' is EXTRAARG(real C) (*) For comparisons, A specifies what condition the test should accept (true or false). diff --git a/ltests.c b/ltests.c index ffed7d1d..37d26927 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.46 2008/02/11 19:04:16 roberto Exp roberto $ +** $Id: ltests.c,v 2.47 2008/02/19 18:55:09 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -410,6 +410,9 @@ static char *buildop (Proto *p, int pc, char *buff) { case iAsBx: sprintf(buff+strlen(buff), "%-12s%4d %4d", name, GETARG_A(i), GETARG_sBx(i)); break; + case iAx: + sprintf(buff+strlen(buff), "%-12s%4d", name, GETARG_Ax(i)); + break; } return buff; } diff --git a/lvm.c b/lvm.c index 6e227053..b295d5eb 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.72 2007/06/19 19:48:15 roberto Exp roberto $ +** $Id: lvm.c,v 2.73 2007/09/10 17:59:32 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -704,7 +704,10 @@ void luaV_execute (lua_State *L, int nexeccalls) { int last; Table *h; if (n == 0) n = cast_int(L->top - ra) - 1; - if (c == 0) c = cast_int(*L->savedpc++); + if (c == 0) { + lua_assert(GET_OPCODE(*L->savedpc) == OP_EXTRAARG); + c = GETARG_Ax(*L->savedpc++); + } runtime_check(L, ttistable(ra)); h = hvalue(ra); last = ((c-1)*LFIELDS_PER_FLUSH) + n; @@ -764,6 +767,10 @@ void luaV_execute (lua_State *L, int nexeccalls) { } continue; } + case OP_EXTRAARG: { + luaG_runerror(L, "bad opcode"); + return; + } } } }