Browse Source

new simetric format for ABC instructions, to avoid exchanging operands

for `commutative' operators
v5-2
Roberto Ierusalimschy 23 years ago
parent
commit
6c283b2f4f
  1. 67
      lcode.c
  2. 19
      ldebug.c
  3. 4
      ldebug.h
  4. 82
      lopcodes.c
  5. 48
      lopcodes.h
  6. 10
      lparser.c
  7. 54
      lvm.c

67
lcode.c

@ -1,5 +1,5 @@
/* /*
** $Id: lcode.c,v 1.108 2002/06/13 13:39:55 roberto Exp $ ** $Id: lcode.c,v 1.109 2002/08/05 14:07:34 roberto Exp roberto $
** Code generator for Lua ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -100,14 +100,14 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) {
static int need_value (FuncState *fs, int list, int cond) { static int need_value (FuncState *fs, int list, int cond) {
for (; list != NO_JUMP; list = luaK_getjump(fs, list)) { for (; list != NO_JUMP; list = luaK_getjump(fs, list)) {
Instruction i = *getjumpcontrol(fs, list); Instruction i = *getjumpcontrol(fs, list);
if (GET_OPCODE(i) != OP_TEST || GETARG_B(i) != cond) return 1; if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1;
} }
return 0; /* not found */ return 0; /* not found */
} }
static void patchtestreg (Instruction *i, int reg) { static void patchtestreg (Instruction *i, int reg) {
if (reg == NO_REG) reg = GETARG_C(*i); if (reg == NO_REG) reg = GETARG_B(*i);
SETARG_A(*i, reg); SETARG_A(*i, reg);
} }
@ -122,7 +122,7 @@ static void luaK_patchlistaux (FuncState *fs, int list,
luaK_fixjump(fs, list, dtarget); /* jump to default target */ luaK_fixjump(fs, list, dtarget); /* jump to default target */
} }
else { else {
if (GETARG_B(*i)) { if (GETARG_C(*i)) {
lua_assert(ttarget != NO_JUMP); lua_assert(ttarget != NO_JUMP);
patchtestreg(i, treg); patchtestreg(i, treg);
luaK_fixjump(fs, list, ttarget); luaK_fixjump(fs, list, ttarget);
@ -409,7 +409,7 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
} }
default: break; default: break;
} }
/* not a constant in the right range: put in a register */ /* not a constant in the right range: put it in a register */
return luaK_exp2anyreg(fs, e); return luaK_exp2anyreg(fs, e);
} }
@ -432,8 +432,8 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) {
break; break;
} }
case VINDEXED: { case VINDEXED: {
int e = luaK_exp2anyreg(fs, exp); int e = luaK_exp2RK(fs, exp);
luaK_codeABC(fs, OP_SETTABLE, e, var->info, var->aux); luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e);
break; break;
} }
default: { default: {
@ -460,8 +460,9 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
static void invertjump (FuncState *fs, expdesc *e) { static void invertjump (FuncState *fs, expdesc *e) {
Instruction *pc = getjumpcontrol(fs, e->info); Instruction *pc = getjumpcontrol(fs, e->info);
lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT)); lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) &&
SETARG_B(*pc, !(GETARG_B(*pc))); GET_OPCODE(*pc) != OP_TEST);
SETARG_A(*pc, !(GETARG_A(*pc)));
} }
@ -470,13 +471,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
Instruction ie = getcode(fs, e); Instruction ie = getcode(fs, e);
if (GET_OPCODE(ie) == OP_NOT) { if (GET_OPCODE(ie) == OP_NOT) {
fs->pc--; /* remove previous OP_NOT */ fs->pc--; /* remove previous OP_NOT */
return luaK_condjump(fs, OP_TEST, NO_REG, !cond ,GETARG_B(ie)); return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond);
} }
/* else go through */ /* else go through */
} }
discharge2anyreg(fs, e); discharge2anyreg(fs, e);
freeexp(fs, e); freeexp(fs, e);
return luaK_condjump(fs, OP_TEST, NO_REG, cond, e->info); return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond);
} }
@ -605,11 +606,6 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
break; break;
} }
case OPR_SUB: case OPR_DIV: case OPR_POW: {
/* non-comutative operators */
luaK_exp2anyreg(fs, v); /* first operand must be a register */
break;
}
default: { default: {
luaK_exp2RK(fs, v); luaK_exp2RK(fs, v);
break; break;
@ -619,13 +615,11 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
static void codebinop (FuncState *fs, expdesc *res, BinOpr op, static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
int o1, int o2, int ic) { int o1, int o2) {
switch (op) { switch (op) {
case OPR_SUB: case OPR_SUB:
case OPR_DIV: case OPR_DIV:
case OPR_POW: case OPR_POW:
lua_assert(!ic);
/* go through */
case OPR_ADD: case OPR_ADD:
case OPR_MULT: { /* ORDER OPR */ case OPR_MULT: { /* ORDER OPR */
OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD);
@ -635,20 +629,21 @@ static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
} }
case OPR_NE: case OPR_NE:
case OPR_EQ: { case OPR_EQ: {
res->info = luaK_condjump(fs, OP_EQ, o1, (op == OPR_EQ), o2); res->info = luaK_condjump(fs, OP_EQ, (op == OPR_EQ), o1, o2);
res->k = VJMP; res->k = VJMP;
break; break;
} }
case OPR_LT:
case OPR_LE:
case OPR_GT: case OPR_GT:
case OPR_GE: { /* ORDER OPR */ case OPR_GE: { /* ORDER OPR */
OpCode opc; int temp;
int i = op - OPR_LT; temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
if (ic) /* operands were interchanged? */ op -= 2; /* GT -> LT, GE -> LE */
i = (i+2)&3; /* correct operator */ /* go through */
opc = cast(OpCode, i + OP_LT); }
res->info = luaK_condjump(fs, opc, o1, 1, o2); case OPR_LT:
case OPR_LE: {
OpCode opc = cast(OpCode, (op - OPR_LT) + OP_LT);
res->info = luaK_condjump(fs, opc, 1, o1, o2);
res->k = VJMP; res->k = VJMP;
break; break;
} }
@ -691,21 +686,11 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
break; break;
} }
default: { default: {
int o1, o2; int o1 = luaK_exp2RK(fs, e1);
int ic; /* interchange flag */ int o2 = luaK_exp2RK(fs, e2);
if (e1->k != VK) { /* not a constant operator? */
o1 = e1->info;
o2 = luaK_exp2RK(fs, e2); /* maybe other operator is constant... */
ic = 0;
}
else { /* interchange operands */
o2 = luaK_exp2RK(fs, e1); /* constant must be 2nd operand */
o1 = luaK_exp2anyreg(fs, e2); /* other operator must be in register */
ic = 1;
}
freeexp(fs, e2); freeexp(fs, e2);
freeexp(fs, e1); freeexp(fs, e1);
codebinop(fs, e1, op, o1, o2, ic); codebinop(fs, e1, op, o1, o2);
} }
} }
} }

19
ldebug.c

@ -1,5 +1,5 @@
/* /*
** $Id: ldebug.c,v 1.131 2002/08/08 20:08:41 roberto Exp roberto $ ** $Id: ldebug.c,v 1.132 2002/08/12 17:23:12 roberto Exp roberto $
** Debug Interface ** Debug Interface
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -269,6 +269,11 @@ 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 Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
int pc; int pc;
int last; /* stores position of last instruction that changed `reg' */ int last; /* stores position of last instruction that changed `reg' */
@ -285,11 +290,13 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
case iABC: { case iABC: {
b = GETARG_B(i); b = GETARG_B(i);
c = GETARG_C(i); c = GETARG_C(i);
if (testOpMode(op, OpModeBreg)) if (testOpMode(op, OpModeBreg)) {
checkreg(pt, b); checkreg(pt, b);
if (testOpMode(op, OpModeCreg)) }
check(c < pt->maxstacksize || else if (testOpMode(op, OpModeBrk))
(c >= MAXSTACK && c-MAXSTACK < pt->sizek)); check(checkRK(pt, b));
if (testOpMode(op, OpModeCrk))
check(checkRK(pt, c));
break; break;
} }
case iABx: { case iABx: {
@ -496,7 +503,7 @@ void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
} }
void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2) { void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2) {
TObject temp; TObject temp;
if (luaV_tonumber(p1, &temp) == NULL) if (luaV_tonumber(p1, &temp) == NULL)
p2 = p1; /* first operand is wrong */ p2 = p1; /* first operand is wrong */

4
ldebug.h

@ -1,5 +1,5 @@
/* /*
** $Id: ldebug.h,v 1.29 2002/08/08 20:08:41 roberto Exp roberto $ ** $Id: ldebug.h,v 1.30 2002/08/12 17:23:12 roberto Exp roberto $
** Auxiliary functions from Debug Interface module ** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -23,7 +23,7 @@
void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
void luaG_concaterror (lua_State *L, StkId p1, StkId p2); void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
void luaG_aritherror (lua_State *L, StkId p1, const TObject *p2); void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2);
int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2);
void luaG_runerror (lua_State *L, const char *fmt, ...); void luaG_runerror (lua_State *L, const char *fmt, ...);
void luaG_errormsg (lua_State *L); void luaG_errormsg (lua_State *L);

82
lopcodes.c

@ -1,5 +1,5 @@
/* /*
** $Id: lopcodes.c,v 1.19 2002/05/13 13:09:00 roberto Exp roberto $ ** $Id: lopcodes.c,v 1.20 2002/06/12 14:51:31 roberto Exp roberto $
** extracted automatically from lopcodes.h by mkprint.lua ** extracted automatically from lopcodes.h by mkprint.lua
** DO NOT EDIT ** DO NOT EDIT
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
@ -39,8 +39,6 @@ const char *const luaP_opnames[] = {
"EQ", "EQ",
"LT", "LT",
"LE", "LE",
"GT",
"GE",
"TEST", "TEST",
"CALL", "CALL",
"TAILCALL", "TAILCALL",
@ -56,49 +54,47 @@ const char *const luaP_opnames[] = {
#endif #endif
#define opmode(t,x,b,c,sa,k,m) (((t)<<OpModeT) | \ #define opmode(t,b,bk,ck,sa,k,m) (((t)<<OpModeT) | \
((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \ ((b)<<OpModeBreg) | ((bk)<<OpModeBrk) | ((ck)<<OpModeCrk) | \
((sa)<<OpModesetA) | ((k)<<OpModeK) | (m)) ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m))
const lu_byte luaP_opmodes[NUM_OPCODES] = { const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T _ B C sA K mode opcode */ /* T B Bk Ck sA K mode opcode */
opmode(0,0,1,0, 1,0,iABC) /* OP_MOVE */ 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, 1, iABx) /* OP_LOADK */
,opmode(0,0,0,0, 1,0,iABC) /* OP_LOADBOOL */ ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_LOADBOOL */
,opmode(0,0,1,0, 1,0,iABC) /* OP_LOADNIL */ ,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, 0, iABC) /* OP_GETUPVAL */
,opmode(0,0,0,0, 1,1,iABx) /* OP_GETGLOBAL */ ,opmode(0, 0, 0, 0, 1, 1, iABx) /* OP_GETGLOBAL */
,opmode(0,0,1,1, 1,0,iABC) /* OP_GETTABLE */ ,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, 1, iABx) /* OP_SETGLOBAL */
,opmode(0,0,0,0, 0,0,iABC) /* OP_SETUPVAL */ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */
,opmode(0,0,1,1, 0,0,iABC) /* OP_SETTABLE */ ,opmode(0, 0, 1, 1, 0, 0, iABC) /* OP_SETTABLE */
,opmode(0,0,0,0, 1,0,iABC) /* OP_NEWTABLE */ ,opmode(0, 0, 0, 0, 1, 0, iABC) /* OP_NEWTABLE */
,opmode(0,0,1,1, 1,0,iABC) /* OP_SELF */ ,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_ADD */
,opmode(0,0,1,1, 1,0,iABC) /* OP_SUB */ ,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_MUL */
,opmode(0,0,1,1, 1,0,iABC) /* OP_DIV */ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_DIV */
,opmode(0,0,1,1, 1,0,iABC) /* OP_POW */ ,opmode(0, 0, 1, 1, 1, 0, iABC) /* OP_POW */
,opmode(0,0,1,0, 1,0,iABC) /* OP_UNM */ ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_UNM */
,opmode(0,0,1,0, 1,0,iABC) /* OP_NOT */ ,opmode(0, 1, 0, 0, 1, 0, iABC) /* OP_NOT */
,opmode(0,0,1,1, 1,0,iABC) /* OP_CONCAT */ ,opmode(0, 1, 0, 1, 1, 0, iABC) /* OP_CONCAT */
,opmode(0,0,0,0, 0,0,iAsBx) /* OP_JMP */ ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_JMP */
,opmode(1,0,0,1, 0,0,iABC) /* OP_EQ */ ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_EQ */
,opmode(1,0,0,1, 0,0,iABC) /* OP_LT */ ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LT */
,opmode(1,0,0,1, 0,0,iABC) /* OP_LE */ ,opmode(1, 0, 1, 1, 0, 0, iABC) /* OP_LE */
,opmode(1,0,0,1, 0,0,iABC) /* OP_GT */ ,opmode(1, 1, 0, 0, 1, 0, iABC) /* OP_TEST */
,opmode(1,0,0,1, 0,0,iABC) /* OP_GE */ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CALL */
,opmode(1,0,0,1, 1,0,iABC) /* OP_TEST */ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_TAILCALL */
,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_RETURN */
,opmode(0,0,0,0, 0,0,iABC) /* OP_TAILCALL */ ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_FORLOOP */
,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */ ,opmode(1, 0, 0, 0, 0, 0, iABC) /* OP_TFORLOOP */
,opmode(0,0,0,0, 0,0,iAsBx) /* OP_FORLOOP */ ,opmode(0, 0, 0, 0, 0, 0, iAsBx) /* OP_TFORPREP */
,opmode(1,0,0,0, 0,0,iABC) /* OP_TFORLOOP */ ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLIST */
,opmode(0,0,0,0, 0,0,iAsBx) /* OP_TFORPREP */ ,opmode(0, 0, 0, 0, 0, 0, iABx) /* OP_SETLISTO */
,opmode(0,0,0,0, 0,0,iABx) /* OP_SETLIST */ ,opmode(0, 0, 0, 0, 0, 0, iABC) /* OP_CLOSE */
,opmode(0,0,0,0, 0,0,iABx) /* OP_SETLISTO */ ,opmode(0, 0, 0, 0, 1, 0, iABx) /* OP_CLOSURE */
,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */
,opmode(0,0,0,0, 1,0,iABx) /* OP_CLOSURE */
}; };

48
lopcodes.h

@ -1,5 +1,5 @@
/* /*
** $Id: lopcodes.h,v 1.99 2002/06/12 14:51:31 roberto Exp $ ** $Id: lopcodes.h,v 1.100 2002/08/05 14:46:43 roberto Exp roberto $
** Opcodes for Lua virtual machine ** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -14,9 +14,9 @@
We assume that instructions are unsigned numbers. We assume that instructions are unsigned numbers.
All instructions have an opcode in the first 6 bits. All instructions have an opcode in the first 6 bits.
Instructions can have the following fields: Instructions can have the following fields:
`A' : 8 bits (25-32) `A' : 8 bits
`B' : 8 bits (17-24) `B' : 9 bits
`C' : 10 bits (7-16) `C' : 9 bits
`Bx' : 18 bits (`B' and `C' together) `Bx' : 18 bits (`B' and `C' together)
`sBx' : signed Bx `sBx' : signed Bx
@ -34,8 +34,8 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
/* /*
** size and position of opcode arguments. ** size and position of opcode arguments.
*/ */
#define SIZE_C 10 #define SIZE_C 9
#define SIZE_B 8 #define SIZE_B 9
#define SIZE_Bx (SIZE_C + SIZE_B) #define SIZE_Bx (SIZE_C + SIZE_B)
#define SIZE_A 8 #define SIZE_A 8
@ -112,16 +112,15 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
/* /*
** invalid registers that fits in 8 bits ** invalid register that fits in 8 bits
*/ */
#define NO_REG MAXARG_A #define NO_REG MAXARG_A
#define NO_REG1 (NO_REG+1)
/* /*
** R(x) - register ** R(x) - register
** Kst(x) - constant (in constant table) ** Kst(x) - constant (in constant table)
** R/K(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK) ** RK(x) == if x < MAXSTACK then R(x) else Kst(x-MAXSTACK)
*/ */
typedef enum { typedef enum {
@ -135,21 +134,21 @@ OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
OP_GETUPVAL,/* A B R(A) := UpValue[B] */ 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)] */
OP_GETTABLE,/* A B C R(A) := R(B)[R/K(C)] */ 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)] := R(A) */
OP_SETUPVAL,/* A B UpValue[B] := R(A) */ OP_SETUPVAL,/* A B UpValue[B] := R(A) */
OP_SETTABLE,/* A B C R(B)[R/K(C)] := R(A) */ OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */ OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[R/K(C)] */ OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
OP_ADD,/* A B C R(A) := R(B) + R/K(C) */ OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
OP_SUB,/* A B C R(A) := R(B) - R/K(C) */ OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
OP_MUL,/* A B C R(A) := R(B) * R/K(C) */ OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
OP_DIV,/* A B C R(A) := R(B) / R/K(C) */ OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
OP_POW,/* A B C R(A) := R(B) ^ R/K(C) */ OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
OP_UNM,/* A B R(A) := -R(B) */ OP_UNM,/* A B R(A) := -R(B) */
OP_NOT,/* A B R(A) := not R(B) */ OP_NOT,/* A B R(A) := not R(B) */
@ -157,13 +156,11 @@ OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
OP_JMP,/* sBx PC += sBx */ OP_JMP,/* sBx PC += sBx */
OP_EQ,/* A B C if ((R(A) == R/K(C)) ~= B) then pc++ */ OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((R(A) < R/K(C)) ~= B) then pc++ */ OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((R(A) <= R/K(C)) ~= B) then pc++ */ OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
OP_GT,/* A B C if ((R(A) > R/K(C)) ~= B) then pc++ */
OP_GE,/* A B C if ((R(A) >= R/K(C)) ~= B) then pc++ */
OP_TEST,/* A B C if (R(C) <=> B) then R(A) := R(C) else pc++ */ OP_TEST,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
@ -207,12 +204,15 @@ OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
*/ */
enum OpModeMask { enum OpModeMask {
OpModeBreg = 2, /* B is a register */ OpModeBreg = 2, /* B is a register */
OpModeCreg, /* C is a register/constant */ OpModeBrk, /* B is a register/constant */
OpModeCrk, /* C is a register/constant */
OpModesetA, /* instruction set register A */ OpModesetA, /* instruction set register A */
OpModeK, /* Bx is a constant */ OpModeK, /* Bx is a constant */
OpModeT /* operator is a test */ OpModeT /* operator is a test */
}; };
extern const lu_byte luaP_opmodes[NUM_OPCODES]; extern const lu_byte luaP_opmodes[NUM_OPCODES];
#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))

10
lparser.c

@ -1,5 +1,5 @@
/* /*
** $Id: lparser.c,v 1.190 2002/07/04 18:23:42 roberto Exp $ ** $Id: lparser.c,v 1.191 2002/08/05 17:35:45 roberto Exp roberto $
** Lua Parser ** Lua Parser
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -324,7 +324,7 @@ static void open_func (LexState *ls, FuncState *fs) {
fs->bl = NULL; fs->bl = NULL;
f->code = NULL; f->code = NULL;
f->source = ls->source; f->source = ls->source;
f->maxstacksize = 1; /* register 0 is always valid */ f->maxstacksize = 2; /* registers 0/1 are always valid */
f->numparams = 0; /* default for main chunk */ f->numparams = 0; /* default for main chunk */
f->is_vararg = 0; /* default for main chunk */ f->is_vararg = 0; /* default for main chunk */
} }
@ -489,8 +489,8 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
check(ls, '='); check(ls, '=');
luaK_exp2RK(fs, &key); luaK_exp2RK(fs, &key);
expr(ls, &val); expr(ls, &val);
luaK_exp2anyreg(fs, &val); luaK_codeABC(fs, OP_SETTABLE, cc->t->info, luaK_exp2RK(fs, &key),
luaK_codeABC(fs, OP_SETTABLE, val.info, cc->t->info, luaK_exp2RK(fs, &key)); luaK_exp2RK(fs, &val));
fs->freereg = reg; /* free registers */ fs->freereg = reg; /* free registers */
} }
@ -735,7 +735,7 @@ static const struct {
lu_byte right; /* right priority */ lu_byte right; /* right priority */
} priority[] = { /* ORDER OPR */ } priority[] = { /* ORDER OPR */
{6, 6}, {6, 6}, {7, 7}, {7, 7}, /* arithmetic */ {6, 6}, {6, 6}, {7, 7}, {7, 7}, /* arithmetic */
{10, 9}, {5, 4}, /* power and concat (right associative) */ {10, 9}, {5, 4}, /* power and concat (right associative) */
{3, 3}, {3, 3}, /* equality */ {3, 3}, {3, 3}, /* equality */
{3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
{2, 2}, {1, 1} /* logical (and/or) */ {2, 2}, {1, 1} /* logical (and/or) */

54
lvm.c

@ -1,5 +1,5 @@
/* /*
** $Id: lvm.c,v 1.251 2002/08/07 19:22:39 roberto Exp roberto $ ** $Id: lvm.c,v 1.252 2002/08/12 17:23:12 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -318,7 +318,8 @@ void luaV_concat (lua_State *L, int total, int last) {
} }
static void Arith (lua_State *L, StkId ra, StkId rb, StkId rc, TMS op) { static void Arith (lua_State *L, StkId ra,
const TObject *rb, const TObject *rc, TMS op) {
TObject tempb, tempc; TObject tempb, tempc;
const TObject *b, *c; const TObject *b, *c;
if ((b = luaV_tonumber(rb, &tempb)) != NULL && if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
@ -356,10 +357,9 @@ static void Arith (lua_State *L, StkId ra, StkId rb, StkId rc, TMS op) {
#define RA(i) (base+GETARG_A(i)) #define RA(i) (base+GETARG_A(i))
#define RB(i) (base+GETARG_B(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 RC(i) (base+GETARG_C(i))
#define RKC(i) ((GETARG_C(i) < MAXSTACK) ? \ #define RKC(i) ((GETARG_C(i) < MAXSTACK) ? RC(i) : k+GETARG_C(i)-MAXSTACK)
base+GETARG_C(i) : \
k+GETARG_C(i)-MAXSTACK)
#define KBx(i) (k+GETARG_Bx(i)) #define KBx(i) (k+GETARG_Bx(i))
@ -423,7 +423,7 @@ StkId luaV_execute (lua_State *L) {
break; break;
} }
case OP_GETGLOBAL: { case OP_GETGLOBAL: {
StkId rb = KBx(i); TObject *rb = KBx(i);
const TObject *v; const TObject *v;
lua_assert(ttisstring(rb) && ttistable(&cl->g)); lua_assert(ttisstring(rb) && ttistable(&cl->g));
v = luaH_getstr(hvalue(&cl->g), tsvalue(rb)); v = luaH_getstr(hvalue(&cl->g), tsvalue(rb));
@ -456,7 +456,7 @@ StkId luaV_execute (lua_State *L) {
break; break;
} }
case OP_SETTABLE: { case OP_SETTABLE: {
luaV_settable(L, RB(i), RKC(i), ra); luaV_settable(L, ra, RKB(i), RKC(i));
break; break;
} }
case OP_NEWTABLE: { case OP_NEWTABLE: {
@ -482,8 +482,8 @@ StkId luaV_execute (lua_State *L) {
break; break;
} }
case OP_ADD: { case OP_ADD: {
StkId rb = RB(i); TObject *rb = RKB(i);
StkId rc = RKC(i); TObject *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) { if (ttisnumber(rb) && ttisnumber(rc)) {
setnvalue(ra, nvalue(rb) + nvalue(rc)); setnvalue(ra, nvalue(rb) + nvalue(rc));
} }
@ -492,8 +492,8 @@ StkId luaV_execute (lua_State *L) {
break; break;
} }
case OP_SUB: { case OP_SUB: {
StkId rb = RB(i); TObject *rb = RKB(i);
StkId rc = RKC(i); TObject *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) { if (ttisnumber(rb) && ttisnumber(rc)) {
setnvalue(ra, nvalue(rb) - nvalue(rc)); setnvalue(ra, nvalue(rb) - nvalue(rc));
} }
@ -502,8 +502,8 @@ StkId luaV_execute (lua_State *L) {
break; break;
} }
case OP_MUL: { case OP_MUL: {
StkId rb = RB(i); TObject *rb = RKB(i);
StkId rc = RKC(i); TObject *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) { if (ttisnumber(rb) && ttisnumber(rc)) {
setnvalue(ra, nvalue(rb) * nvalue(rc)); setnvalue(ra, nvalue(rb) * nvalue(rc));
} }
@ -512,8 +512,8 @@ StkId luaV_execute (lua_State *L) {
break; break;
} }
case OP_DIV: { case OP_DIV: {
StkId rb = RB(i); TObject *rb = RKB(i);
StkId rc = RKC(i); TObject *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) { if (ttisnumber(rb) && ttisnumber(rc)) {
setnvalue(ra, nvalue(rb) / nvalue(rc)); setnvalue(ra, nvalue(rb) / nvalue(rc));
} }
@ -522,7 +522,7 @@ StkId luaV_execute (lua_State *L) {
break; break;
} }
case OP_POW: { case OP_POW: {
Arith(L, ra, RB(i), RKC(i), TM_POW); Arith(L, ra, RKB(i), RKC(i), TM_POW);
break; break;
} }
case OP_UNM: { case OP_UNM: {
@ -556,35 +556,25 @@ StkId luaV_execute (lua_State *L) {
break; break;
} }
case OP_EQ: { /* skip next instruction if test fails */ case OP_EQ: { /* skip next instruction if test fails */
if (equalobj(L, ra, RKC(i)) != GETARG_B(i)) pc++; if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
else dojump(pc, GETARG_sBx(*pc) + 1); else dojump(pc, GETARG_sBx(*pc) + 1);
break; break;
} }
case OP_LT: { case OP_LT: {
if (luaV_lessthan(L, ra, RKC(i)) != GETARG_B(i)) pc++; if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
else dojump(pc, GETARG_sBx(*pc) + 1); else dojump(pc, GETARG_sBx(*pc) + 1);
break; break;
} }
case OP_LE: { case OP_LE: {
if (luaV_lessequal(L, ra, RKC(i)) != GETARG_B(i)) pc++; if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
else dojump(pc, GETARG_sBx(*pc) + 1);
break;
}
case OP_GT: {
if (luaV_lessthan(L, RKC(i), ra) != GETARG_B(i)) pc++;
else dojump(pc, GETARG_sBx(*pc) + 1);
break;
}
case OP_GE: {
if (luaV_lessequal(L, RKC(i), ra) != GETARG_B(i)) pc++;
else dojump(pc, GETARG_sBx(*pc) + 1); else dojump(pc, GETARG_sBx(*pc) + 1);
break; break;
} }
case OP_TEST: { case OP_TEST: {
StkId rc = RKC(i); TObject *rb = RB(i);
if (l_isfalse(rc) == GETARG_B(i)) pc++; if (l_isfalse(rb) == GETARG_C(i)) pc++;
else { else {
setobj(ra, rc); setobj(ra, rb);
dojump(pc, GETARG_sBx(*pc) + 1); dojump(pc, GETARG_sBx(*pc) + 1);
} }
break; break;

Loading…
Cancel
Save