commit c116dcb92b2ee36ef5c4541a88e73540837f1057
parent 6d268b0b00ae63e5d06aedc4fb3cec105123a565
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 14 May 2003 09:08:50 -0300
better information about instruction behavior (use of arguments)
Diffstat:
M | lcode.c | | | 10 | ++++++---- |
M | ldebug.c | | | 47 | +++++++++++++++++++++++++++-------------------- |
M | lopcodes.c | | | 85 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
M | lopcodes.h | | | 30 | ++++++++++++++++++------------ |
M | lvm.c | | | 14 | ++++++++------ |
5 files changed, 100 insertions(+), 86 deletions(-)
diff --git a/lcode.c b/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 1.116 2003/02/27 12:33:07 roberto Exp roberto $
+** $Id: lcode.c,v 1.117 2003/04/03 13:35:34 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -88,7 +88,7 @@ static int luaK_getjump (FuncState *fs, int pc) {
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
Instruction *pi = &fs->f->code[pc];
- if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT))
+ if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
return pi-1;
else
return pi;
@@ -462,8 +462,7 @@ 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) &&
- GET_OPCODE(*pc) != OP_TEST);
+ lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TEST);
SETARG_A(*pc, !(GETARG_A(*pc)));
}
@@ -703,12 +702,15 @@ int luaK_code (FuncState *fs, Instruction i, int line) {
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);
return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
}
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);
return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
}
diff --git a/ldebug.c b/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 1.151 2003/04/28 13:31:06 roberto Exp roberto $
+** $Id: ldebug.c,v 1.152 2003/05/13 20:15:59 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -296,8 +296,16 @@ 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 int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
+ switch (mode) {
+ case OpArgN: check(r == 0); break;
+ case OpArgU: break;
+ case OpArgR: checkreg(pt, r); break;
+ case OpArgK:
+ check(r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek));
+ break;
+ }
+ return 1;
}
@@ -317,29 +325,28 @@ 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)) {
- checkreg(pt, b);
- }
- else if (testOpMode(op, OpModeBrk))
- check(checkRK(pt, b));
- if (testOpMode(op, OpModeCrk))
- check(checkRK(pt, c));
+ check(checkArgMode(pt, b, getBMode(op)));
+ check(checkArgMode(pt, c, getCMode(op)));
break;
}
case iABx: {
b = GETARG_Bx(i);
- if (testOpMode(op, OpModeK)) check(b < pt->sizek);
+ if (getBMode(op) == OpArgK) check(b < pt->sizek);
break;
}
case iAsBx: {
b = GETARG_sBx(i);
+ if (getBMode(op) == OpArgR) {
+ int dest = pc+1+b;
+ check(0 <= dest && dest < pt->sizecode);
+ }
break;
}
}
- if (testOpMode(op, OpModesetA)) {
+ if (testAMode(op)) {
if (a == reg) last = pc; /* change register `a' */
}
- if (testOpMode(op, OpModeT)) {
+ if (testTMode(op)) {
check(pc+2 < pt->sizecode); /* check skip */
check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
}
@@ -369,21 +376,21 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
break;
}
case OP_CONCAT: {
- /* `c' is a register, and at least two operands */
- check(c < MAXSTACK && b < c);
+ check(b < c); /* at least two operands */
break;
}
- case OP_TFORLOOP:
- checkreg(pt, a+5);
+ case OP_TFORLOOP: {
+ checkreg(pt, a+5); /* space for control variables */
if (reg >= a) last = pc; /* affect all registers above base */
- /* go through */
+ break;
+ }
+ case OP_TFORPREP:
case OP_FORLOOP:
case OP_FORPREP:
- checkreg(pt, a+2);
+ checkreg(pt, a+3);
/* go through */
case OP_JMP: {
int dest = pc+1+b;
- check(0 <= dest && dest < pt->sizecode);
/* not full check and jump is forward and do not skip `lastpc'? */
if (reg != NO_REG && pc < dest && dest <= lastpc)
pc += b; /* do the jump */
diff --git a/lopcodes.c b/lopcodes.c
@@ -1,7 +1,5 @@
/*
-** $Id: lopcodes.c,v 1.22 2002/12/04 17:38:31 roberto Exp roberto $
-** extracted automatically from lopcodes.h by mkprint.lua
-** DO NOT EDIT
+** $Id: lopcodes.c,v 1.23 2003/05/13 20:15:59 roberto Exp roberto $
** See Copyright Notice in lua.h
*/
@@ -14,6 +12,8 @@
#include "lopcodes.h"
+/* ORDER OP */
+
#ifdef LUA_OPNAMES
const char *const luaP_opnames[] = {
@@ -57,48 +57,45 @@ const char *const luaP_opnames[] = {
#endif
-#define opmode(t,b,bk,ck,sa,k,m) (((t)<<OpModeT) | \
- ((b)<<OpModeBreg) | ((bk)<<OpModeBrk) | ((ck)<<OpModeCrk) | \
- ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m))
-
+#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
const lu_byte luaP_opmodes[NUM_OPCODES] = {
-/* 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(0, 0, 0, 0, 0, 0, iAsBx) /* OP_FORPREP */
- ,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 A B C mode opcode */
+ opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
+ ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
+ ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
+ ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
+ ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
+ ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
+ ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
+ ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
+ ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
+ ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
+ ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
+ ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
+ ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
+ ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_TFORPREP */
+ ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLIST */
+ ,opmode(0, 0, OpArgU, OpArgN, iABx) /* OP_SETLISTO */
+ ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
+ ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
};
diff --git a/lopcodes.h b/lopcodes.h
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.h,v 1.102 2002/08/21 18:56:09 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.103 2003/05/13 20:15:59 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -206,22 +206,28 @@ OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
/*
-** masks for instruction properties
+** masks for instruction properties. The format is:
+** bits 0-1: op mode
+** bits 2-3: C arg mode
+** bits 4-5: B arg mode
+** bit 6: instruction set register A
+** bit 7: operator is a test
*/
-enum OpModeMask {
- OpModeBreg = 2, /* B is a register */
- 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 */
-};
+enum OpArgMask {
+ OpArgN, /* argument is not used */
+ OpArgU, /* argument is used */
+ OpArgR, /* argument is a register or a jump offset */
+ OpArgK /* argument is a constant or register/constant */
+};
extern const lu_byte luaP_opmodes[NUM_OPCODES];
-#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
-#define testOpMode(m, b) (luaP_opmodes[m] & (1 << (b)))
+#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
+#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
+#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
+#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
+#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
#ifdef LUA_OPNAMES
diff --git a/lvm.c b/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 1.285 2003/05/05 18:39:57 roberto Exp roberto $
+** $Id: lvm.c,v 1.286 2003/05/13 20:15:59 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -361,11 +361,13 @@ static void Arith (lua_State *L, StkId ra,
#define RA(i) (base+GETARG_A(i))
/* to be used after possible stack reallocation */
#define XRA(i) (L->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) ? RC(i) : k+GETARG_C(i)-MAXSTACK)
-#define KBx(i) (k+GETARG_Bx(i))
+#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
+#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
+#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
+ (GETARG_B(i) < MAXSTACK) ? base+GETARG_B(i) : k+GETARG_B(i)-MAXSTACK)
+#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
+ (GETARG_C(i) < MAXSTACK) ? base+GETARG_C(i) : k+GETARG_C(i)-MAXSTACK)
+#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
#define dojump(pc, i) ((pc) += (i))