better information about instruction behavior (use of arguments)

This commit is contained in:
Roberto Ierusalimschy 2003-05-14 09:09:12 -03:00
parent 6d268b0b00
commit c116dcb92b
5 changed files with 100 additions and 86 deletions

10
lcode.c
View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */
};

View File

@ -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

14
lvm.c
View File

@ -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))