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
** 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) {
for (; list != NO_JUMP; list = luaK_getjump(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 */
}
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);
}
@ -122,7 +122,7 @@ static void luaK_patchlistaux (FuncState *fs, int list,
luaK_fixjump(fs, list, dtarget); /* jump to default target */
}
else {
if (GETARG_B(*i)) {
if (GETARG_C(*i)) {
lua_assert(ttarget != NO_JUMP);
patchtestreg(i, treg);
luaK_fixjump(fs, list, ttarget);
@ -409,7 +409,7 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
}
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);
}
@ -432,8 +432,8 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) {
break;
}
case VINDEXED: {
int e = luaK_exp2anyreg(fs, exp);
luaK_codeABC(fs, OP_SETTABLE, e, var->info, var->aux);
int e = luaK_exp2RK(fs, exp);
luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e);
break;
}
default: {
@ -460,8 +460,9 @@ 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));
SETARG_B(*pc, !(GETARG_B(*pc)));
lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) &&
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);
if (GET_OPCODE(ie) == 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 */
}
discharge2anyreg(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' */
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: {
luaK_exp2RK(fs, v);
break;
@ -619,13 +615,11 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
int o1, int o2, int ic) {
int o1, int o2) {
switch (op) {
case OPR_SUB:
case OPR_DIV:
case OPR_POW:
lua_assert(!ic);
/* go through */
case OPR_ADD:
case OPR_MULT: { /* ORDER OPR */
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_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;
break;
}
case OPR_LT:
case OPR_LE:
case OPR_GT:
case OPR_GE: { /* ORDER OPR */
OpCode opc;
int i = op - OPR_LT;
if (ic) /* operands were interchanged? */
i = (i+2)&3; /* correct operator */
opc = cast(OpCode, i + OP_LT);
res->info = luaK_condjump(fs, opc, o1, 1, o2);
int temp;
temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
op -= 2; /* GT -> LT, GE -> LE */
/* go through */
}
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;
break;
}
@ -691,21 +686,11 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
break;
}
default: {
int o1, o2;
int ic; /* interchange flag */
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;
}
int o1 = luaK_exp2RK(fs, e1);
int o2 = luaK_exp2RK(fs, e2);
freeexp(fs, e2);
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
** 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) {
int pc;
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: {
b = GETARG_B(i);
c = GETARG_C(i);
if (testOpMode(op, OpModeBreg))
if (testOpMode(op, OpModeBreg)) {
checkreg(pt, b);
if (testOpMode(op, OpModeCreg))
check(c < pt->maxstacksize ||
(c >= MAXSTACK && c-MAXSTACK < pt->sizek));
}
else if (testOpMode(op, OpModeBrk))
check(checkRK(pt, b));
if (testOpMode(op, OpModeCrk))
check(checkRK(pt, c));
break;
}
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;
if (luaV_tonumber(p1, &temp) == NULL)
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
** See Copyright Notice in lua.h
*/
@ -23,7 +23,7 @@
void luaG_typeerror (lua_State *L, const TObject *o, const char *opname);
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);
void luaG_runerror (lua_State *L, const char *fmt, ...);
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
** DO NOT EDIT
** See Copyright Notice in lua.h
@ -39,8 +39,6 @@ const char *const luaP_opnames[] = {
"EQ",
"LT",
"LE",
"GT",
"GE",
"TEST",
"CALL",
"TAILCALL",
@ -56,49 +54,47 @@ const char *const luaP_opnames[] = {
#endif
#define opmode(t,x,b,c,sa,k,m) (((t)<<OpModeT) | \
((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \
#define opmode(t,b,bk,ck,sa,k,m) (((t)<<OpModeT) | \
((b)<<OpModeBreg) | ((bk)<<OpModeBrk) | ((ck)<<OpModeCrk) | \
((sa)<<OpModesetA) | ((k)<<OpModeK) | (m))
const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T _ B C sA K mode opcode */
opmode(0,0,1,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,0,1,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,0,1,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,0,1,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,0,1,0, 1,0,iABC) /* OP_UNM */
,opmode(0,0,1,0, 1,0,iABC) /* OP_NOT */
,opmode(0,0,1,1, 1,0,iABC) /* OP_CONCAT */
,opmode(0,0,0,0, 0,0,iAsBx) /* OP_JMP */
,opmode(1,0,0,1, 0,0,iABC) /* OP_EQ */
,opmode(1,0,0,1, 0,0,iABC) /* OP_LT */
,opmode(1,0,0,1, 0,0,iABC) /* OP_LE */
,opmode(1,0,0,1, 0,0,iABC) /* OP_GT */
,opmode(1,0,0,1, 0,0,iABC) /* OP_GE */
,opmode(1,0,0,1, 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(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 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(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 */
};

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
** See Copyright Notice in lua.h
*/
@ -14,9 +14,9 @@
We assume that instructions are unsigned numbers.
All instructions have an opcode in the first 6 bits.
Instructions can have the following fields:
`A' : 8 bits (25-32)
`B' : 8 bits (17-24)
`C' : 10 bits (7-16)
`A' : 8 bits
`B' : 9 bits
`C' : 9 bits
`Bx' : 18 bits (`B' and `C' together)
`sBx' : signed Bx
@ -34,8 +34,8 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
/*
** size and position of opcode arguments.
*/
#define SIZE_C 10
#define SIZE_B 8
#define SIZE_C 9
#define SIZE_B 9
#define SIZE_Bx (SIZE_C + SIZE_B)
#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_REG1 (NO_REG+1)
/*
** R(x) - register
** 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 {
@ -135,21 +134,21 @@ 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_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_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_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_SUB,/* A B C R(A) := R(B) - R/K(C) */
OP_MUL,/* A B C R(A) := R(B) * R/K(C) */
OP_DIV,/* A B C R(A) := R(B) / R/K(C) */
OP_POW,/* 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) := RK(B) - RK(C) */
OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
OP_UNM,/* A B R(A) := -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_EQ,/* A B C if ((R(A) == R/K(C)) ~= B) then pc++ */
OP_LT,/* A B C if ((R(A) < R/K(C)) ~= B) then pc++ */
OP_LE,/* A B C if ((R(A) <= R/K(C)) ~= B) 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_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) 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_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 {
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 */
OpModeK, /* Bx is a constant */
OpModeT /* operator is a test */
};
extern const lu_byte luaP_opmodes[NUM_OPCODES];
#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
** See Copyright Notice in lua.h
*/
@ -324,7 +324,7 @@ static void open_func (LexState *ls, FuncState *fs) {
fs->bl = NULL;
f->code = NULL;
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->is_vararg = 0; /* default for main chunk */
}
@ -489,8 +489,8 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
check(ls, '=');
luaK_exp2RK(fs, &key);
expr(ls, &val);
luaK_exp2anyreg(fs, &val);
luaK_codeABC(fs, OP_SETTABLE, val.info, cc->t->info, luaK_exp2RK(fs, &key));
luaK_codeABC(fs, OP_SETTABLE, cc->t->info, luaK_exp2RK(fs, &key),
luaK_exp2RK(fs, &val));
fs->freereg = reg; /* free registers */
}
@ -735,7 +735,7 @@ static const struct {
lu_byte right; /* right priority */
} priority[] = { /* ORDER OPR */
{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}, {3, 3}, {3, 3}, /* order */
{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
** 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;
const TObject *b, *c;
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 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) ? \
base+GETARG_C(i) : \
k+GETARG_C(i)-MAXSTACK)
#define RKC(i) ((GETARG_C(i) < MAXSTACK) ? RC(i) : k+GETARG_C(i)-MAXSTACK)
#define KBx(i) (k+GETARG_Bx(i))
@ -423,7 +423,7 @@ StkId luaV_execute (lua_State *L) {
break;
}
case OP_GETGLOBAL: {
StkId rb = KBx(i);
TObject *rb = KBx(i);
const TObject *v;
lua_assert(ttisstring(rb) && ttistable(&cl->g));
v = luaH_getstr(hvalue(&cl->g), tsvalue(rb));
@ -456,7 +456,7 @@ StkId luaV_execute (lua_State *L) {
break;
}
case OP_SETTABLE: {
luaV_settable(L, RB(i), RKC(i), ra);
luaV_settable(L, ra, RKB(i), RKC(i));
break;
}
case OP_NEWTABLE: {
@ -482,8 +482,8 @@ StkId luaV_execute (lua_State *L) {
break;
}
case OP_ADD: {
StkId rb = RB(i);
StkId rc = RKC(i);
TObject *rb = RKB(i);
TObject *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
setnvalue(ra, nvalue(rb) + nvalue(rc));
}
@ -492,8 +492,8 @@ StkId luaV_execute (lua_State *L) {
break;
}
case OP_SUB: {
StkId rb = RB(i);
StkId rc = RKC(i);
TObject *rb = RKB(i);
TObject *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
setnvalue(ra, nvalue(rb) - nvalue(rc));
}
@ -502,8 +502,8 @@ StkId luaV_execute (lua_State *L) {
break;
}
case OP_MUL: {
StkId rb = RB(i);
StkId rc = RKC(i);
TObject *rb = RKB(i);
TObject *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
setnvalue(ra, nvalue(rb) * nvalue(rc));
}
@ -512,8 +512,8 @@ StkId luaV_execute (lua_State *L) {
break;
}
case OP_DIV: {
StkId rb = RB(i);
StkId rc = RKC(i);
TObject *rb = RKB(i);
TObject *rc = RKC(i);
if (ttisnumber(rb) && ttisnumber(rc)) {
setnvalue(ra, nvalue(rb) / nvalue(rc));
}
@ -522,7 +522,7 @@ StkId luaV_execute (lua_State *L) {
break;
}
case OP_POW: {
Arith(L, ra, RB(i), RKC(i), TM_POW);
Arith(L, ra, RKB(i), RKC(i), TM_POW);
break;
}
case OP_UNM: {
@ -556,35 +556,25 @@ StkId luaV_execute (lua_State *L) {
break;
}
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);
break;
}
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);
break;
}
case OP_LE: {
if (luaV_lessequal(L, ra, RKC(i)) != GETARG_B(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++;
if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
else dojump(pc, GETARG_sBx(*pc) + 1);
break;
}
case OP_TEST: {
StkId rc = RKC(i);
if (l_isfalse(rc) == GETARG_B(i)) pc++;
TObject *rb = RB(i);
if (l_isfalse(rb) == GETARG_C(i)) pc++;
else {
setobj(ra, rc);
setobj(ra, rb);
dojump(pc, GETARG_sBx(*pc) + 1);
}
break;

Loading…
Cancel
Save