details about opcode parameters

This commit is contained in:
Roberto Ierusalimschy 2001-06-11 11:56:42 -03:00
parent 79acf5ea60
commit 0a1b1acdd3
6 changed files with 94 additions and 96 deletions

19
lcode.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 1.72 2001/06/08 12:29:27 roberto Exp roberto $
** $Id: lcode.c,v 1.73 2001/06/08 19:00:57 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@ -69,8 +69,8 @@ int luaK_jump (FuncState *fs) {
}
static int luaK_condjump (FuncState *fs, OpCode op, int B, int C) {
luaK_codeABC(fs, op, NO_REG, B, C);
static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) {
luaK_codeABC(fs, op, A, B, C);
return luaK_codeAsBc(fs, OP_CJMP, 0, NO_JUMP);
}
@ -261,12 +261,11 @@ static int number_constant (FuncState *fs, lua_Number r) {
void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) {
if (e->k == VCALL) { /* expression is an open function call? */
int a = GETARG_A(getcode(fs, e));
int c = (nresults == LUA_MULTRET) ? NO_REG : a + nresults;
SETARG_C(getcode(fs, e), c);
if (nresults == LUA_MULTRET) nresults = NO_REG;
SETARG_C(getcode(fs, e), nresults);
if (nresults == 1) { /* `regular' expression? */
e->k = VNONRELOC;
e->u.i.info = a;
e->u.i.info = GETARG_A(getcode(fs, e));
}
}
}
@ -499,13 +498,13 @@ static int jumponcond (FuncState *fs, expdesc *e, OpCode op) {
if (GET_OPCODE(ie) == OP_NOT) {
op = invertoperator(op);
fs->pc--; /* remove previous OP_NOT */
return luaK_condjump(fs, op, GETARG_B(ie), 0);
return luaK_condjump(fs, op, NO_REG, GETARG_B(ie), 0);
}
/* else go through */
}
discharge2anyreg(fs, e);
freeexp(fs, e);
return luaK_condjump(fs, op, e->u.i.info, 0);
return luaK_condjump(fs, op, NO_REG, e->u.i.info, 0);
}
@ -748,7 +747,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
e1->k = VRELOCABLE;
}
else { /* jump */
e1->u.i.info = luaK_condjump(fs, opc, o1, o2);
e1->u.i.info = luaK_condjump(fs, opc, o1, 0, o2);
e1->k = VJMP;
}
}

View File

@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 1.80 2001/06/08 12:29:27 roberto Exp roberto $
** $Id: ldebug.c,v 1.81 2001/06/08 19:00:57 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@ -349,6 +349,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
int a = GETARG_A(i);
int b = 0;
int c = 0;
checkreg(pt, a);
switch (getOpMode(op)) {
case iABC: {
b = GETARG_B(i);
@ -370,7 +371,6 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
break;
}
}
if (testOpMode(op, OpModeAreg)) checkreg(pt, a);
if (testOpMode(op, OpModesetA)) {
if (a == reg) last = pc; /* change register `a' */
}
@ -414,20 +414,20 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
break;
}
case OP_CALL: {
if (b == NO_REG) b = pt->maxstacksize;
if (b != NO_REG) {
checkreg(pt, a+b);
}
if (c == NO_REG) {
check(checkopenop(pt->code[pc+1]));
c = 1;
}
check(b > a);
checkreg(pt, b-1);
checkreg(pt, c-1);
else if (c != 0)
checkreg(pt, a+c-1);
if (reg >= a) last = pc; /* affect all registers above base */
break;
}
case OP_RETURN: {
if (b == NO_REG) b = pt->maxstacksize;
checkreg(pt, b-1);
if (b != NO_REG && b != 0)
checkreg(pt, a+b-1);
break;
}
case OP_FORPREP:
@ -566,49 +566,49 @@ void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
#define opmode(t,a,b,c,sa,k,m) (((t)<<OpModeT) | \
((a)<<OpModeAreg) | ((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \
((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \
((sa)<<OpModesetA) | ((k)<<OpModeK) | (m))
const lu_byte luaG_opmodes[] = {
/* T A B C sA K mode opcode */
opmode(0,1,1,0, 1,0,iABC), /* OP_MOVE */
opmode(0,1,0,0, 1,1,iABc), /* OP_LOADK */
opmode(0,1,0,0, 1,0,iAsBc), /* OP_LOADINT */
opmode(0,1,1,0, 1,0,iABC), /* OP_LOADNIL */
opmode(0,1,0,0, 1,0,iABc), /* OP_LOADUPVAL */
opmode(0,1,0,0, 1,1,iABc), /* OP_GETGLOBAL */
opmode(0,1,1,1, 1,0,iABC), /* OP_GETTABLE */
opmode(0,1,0,0, 0,1,iABc), /* OP_SETGLOBAL */
opmode(0,1,1,1, 0,0,iABC), /* OP_SETTABLE */
opmode(0,1,0,0, 1,0,iABc), /* OP_NEWTABLE */
opmode(0,1,1,1, 1,0,iABC), /* OP_SELF */
opmode(0,1,1,1, 1,0,iABC), /* OP_ADD */
opmode(0,1,1,1, 1,0,iABC), /* OP_SUB */
opmode(0,1,1,1, 1,0,iABC), /* OP_MUL */
opmode(0,1,1,1, 1,0,iABC), /* OP_DIV */
opmode(0,1,1,1, 1,0,iABC), /* OP_POW */
opmode(0,1,1,0, 1,0,iABC), /* OP_UNM */
opmode(0,1,1,0, 1,0,iABC), /* OP_NOT */
opmode(0,1,1,1, 1,0,iABC), /* OP_CONCAT */
opmode(0,0,0,0, 0,0,iAsBc), /* OP_JMP */
opmode(0,0,0,0, 0,0,iAsBc), /* OP_CJMP */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTEQ */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTNE */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTLT */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTLE */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTGT */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTGE */
opmode(1,1,1,0, 1,0,iABC), /* OP_TESTT */
opmode(1,1,1,0, 1,0,iABC), /* OP_TESTF */
opmode(0,1,0,0, 1,0,iAsBc), /* OP_NILJMP */
opmode(0,1,0,0, 0,0,iABC), /* OP_CALL */
opmode(0,1,0,0, 0,0,iABC), /* OP_RETURN */
opmode(0,1,0,0, 0,0,iAsBc), /* OP_FORPREP */
opmode(0,1,0,0, 0,0,iAsBc), /* OP_FORLOOP */
/* T J B C sA K mode opcode */
opmode(0,0,1,0, 1,0,iABC), /* OP_MOVE */
opmode(0,0,0,0, 1,1,iABc), /* OP_LOADK */
opmode(0,0,0,0, 1,0,iAsBc), /* OP_LOADINT */
opmode(0,0,1,0, 1,0,iABC), /* OP_LOADNIL */
opmode(0,0,0,0, 1,0,iABc), /* OP_LOADUPVAL */
opmode(0,0,0,0, 1,1,iABc), /* OP_GETGLOBAL */
opmode(0,0,1,1, 1,0,iABC), /* OP_GETTABLE */
opmode(0,0,0,0, 0,1,iABc), /* OP_SETGLOBAL */
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,1,0,0, 0,0,iAsBc), /* OP_JMP */
opmode(0,1,0,0, 0,0,iAsBc), /* OP_CJMP */
opmode(1,0,0,1, 0,0,iABC), /* OP_TESTEQ */
opmode(1,0,0,1, 0,0,iABC), /* OP_TESTNE */
opmode(1,0,0,1, 0,0,iABC), /* OP_TESTLT */
opmode(1,0,0,1, 0,0,iABC), /* OP_TESTLE */
opmode(1,0,0,1, 0,0,iABC), /* OP_TESTGT */
opmode(1,0,0,1, 0,0,iABC), /* OP_TESTGE */
opmode(1,0,1,0, 1,0,iABC), /* OP_TESTT */
opmode(1,0,1,0, 1,0,iABC), /* OP_TESTF */
opmode(0,0,0,0, 1,0,iAsBc), /* OP_NILJMP */
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,iAsBc), /* OP_FORPREP */
opmode(0,0,0,0, 0,0,iAsBc), /* OP_FORLOOP */
opmode(0,1,0,0, 0,0,iAsBc), /* OP_TFORPREP */
opmode(0,1,0,0, 0,0,iAsBc), /* OP_TFORLOOP */
opmode(0,1,0,0, 0,0,iABc), /* OP_SETLIST */
opmode(0,1,0,0, 0,0,iABc), /* OP_SETLIST0 */
opmode(0,1,0,0, 0,0,iABc) /* OP_CLOSURE */
opmode(0,0,0,0, 0,0,iABc), /* OP_SETLIST */
opmode(0,0,0,0, 0,0,iABc), /* OP_SETLIST0 */
opmode(0,0,0,0, 0,0,iABc) /* OP_CLOSURE */
};

View File

@ -1,5 +1,5 @@
/*
** $Id: ldebug.h,v 1.12 2001/06/05 18:17:01 roberto Exp roberto $
** $Id: ldebug.h,v 1.13 2001/06/06 17:50:36 roberto Exp roberto $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
@ -18,8 +18,7 @@ enum OpMode {iABC, iABc, iAsBc}; /* basic instruction format */
** masks for instruction properties
*/
enum OpModeMask {
OpModeAreg = 2, /* A is a register */
OpModeBreg, /* B is a register */
OpModeBreg = 2, /* B is a register */
OpModeCreg, /* C is a register/constant */
OpModesetA, /* instruction set register A */
OpModeK, /* Bc is a constant */

View File

@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.73 2001/06/05 18:17:01 roberto Exp roberto $
** $Id: lopcodes.h,v 1.74 2001/06/08 19:00:57 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -153,20 +153,20 @@ OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
OP_JMP,/* sBc PC += sBc */
OP_CJMP,/* sBc if test then PC += sBc (see (1)) */
OP_TESTEQ,/* B C test := (R(B) == R/K(C)) */
OP_TESTNE,/* B C test := (R(B) ~= R/K(C)) */
OP_TESTLT,/* B C test := (R(B) < R/K(C)) */
OP_TESTLE,/* B C test := (R(B) <= R/K(C)) */
OP_TESTGT,/* B C test := (R(B) > R/K(C)) */
OP_TESTGE,/* B C test := (R(B) >= R/K(C)) */
OP_TESTEQ,/* A C test := (R(A) == R/K(C)) */
OP_TESTNE,/* A C test := (R(A) ~= R/K(C)) */
OP_TESTLT,/* A C test := (R(A) < R/K(C)) */
OP_TESTLE,/* A C test := (R(A) <= R/K(C)) */
OP_TESTGT,/* A C test := (R(A) > R/K(C)) */
OP_TESTGE,/* A C test := (R(A) >= R/K(C)) */
OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */
OP_TESTF,/* A B test := not R(B); if (test) R(A) := nil */
OP_NILJMP,/* A R(A) := nil; PC++; */
OP_CALL,/* A B C R(A), ... ,R(C-1) := R(A)(R(A+1), ... ,R(B-1)) */
OP_RETURN,/* A B return R(A), ... ,R(B-1) (see (3)) */
OP_CALL,/* A B C R(A), ... ,R(A+C-1) := R(A)(R(A+1), ... ,R(A+B))*/
OP_RETURN,/* A B return R(A), ... ,R(A+B-1) (see (3)) */
OP_FORPREP,/* A sBc */
OP_FORLOOP,/* A sBc */
@ -191,10 +191,10 @@ OP_CLOSURE /* A Bc R(A) := closure(KPROTO[Bc], R(A), ... ,R(A+n)) */
instructions OP_TEST* and OP_CJMP must always occur together.
(2) In OP_CALL, if (B == NO_REG) then B = top. C is the number of returns,
and can be NO_REG. OP_CALL always set "top" to last_result+1, so
next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use "top".
and can be NO_REG. OP_CALL can set `top' to last_result+1, so
next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
(3) In OP_RETURN, if (B == NO_REG) then B = top.
(3) In OP_RETURN, if (B == NO_REG) then return up to `top'
===========================================================================*/

View File

@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 1.146 2001/06/08 12:29:27 roberto Exp roberto $
** $Id: lparser.c,v 1.147 2001/06/08 19:00:57 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/
@ -415,7 +415,7 @@ static int explist1 (LexState *ls, expdesc *v) {
static void funcargs (LexState *ls, expdesc *f) {
FuncState *fs = ls->fs;
expdesc args;
int base, top;
int base, nparams;
switch (ls->t.token) {
case l_c('('): { /* funcargs -> `(' [ explist1 ] `)' */
int line = ls->linenumber;
@ -446,13 +446,13 @@ static void funcargs (LexState *ls, expdesc *f) {
lua_assert(f->k == VNONRELOC);
base = f->u.i.info; /* base register for call */
if (args.k == VCALL)
top = NO_REG; /* open call */
nparams = NO_REG; /* open call */
else {
if (args.k != VVOID)
luaK_exp2nextreg(fs, &args); /* close last argument */
top = fs->freereg;
nparams = fs->freereg - (base+1);
}
init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, top, base+1));
init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams, 1));
fs->freereg = base+1; /* call remove function and arguments and leaves
(unless changed) one result */
}
@ -1091,31 +1091,31 @@ static void retstat (LexState *ls) {
/* stat -> RETURN explist */
FuncState *fs = ls->fs;
expdesc e;
int first, last1; /* registers with returned values */
int first, nret; /* registers with returned values */
next(ls); /* skip RETURN */
if (block_follow(ls->t.token) || ls->t.token == l_c(';'))
first = last1 = 0; /* return no values */
first = nret = 0; /* return no values */
else {
int n = explist1(ls, &e); /* optional return values */
if (e.k == VCALL) {
luaK_setcallreturns(fs, &e, LUA_MULTRET);
first = fs->nactloc;
last1 = NO_REG; /* return all values */
nret = NO_REG; /* return all values */
}
else {
if (n == 1) { /* only one value? */
luaK_exp2anyreg(fs, &e);
first = e.u.i.info;
last1 = first+1; /* return only this value */
nret = 1; /* return only this value */
}
else {
luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
first = fs->nactloc;
last1 = fs->freereg; /* return all `active' values */
nret = fs->freereg - first; /* return all `active' values */
}
}
}
luaK_codeABC(fs, OP_RETURN, first, last1, 0);
luaK_codeABC(fs, OP_RETURN, first, nret, 0);
fs->freereg = fs->nactloc; /* removes all temp values */
}

24
lvm.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 1.182 2001/06/08 19:00:57 roberto Exp roberto $
** $Id: lvm.c,v 1.183 2001/06/08 19:20:02 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@ -488,37 +488,37 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
}
case OP_TESTEQ: {
lua_assert(GET_OPCODE(*pc) == OP_CJMP);
if (luaO_equalObj(RB(i), RKC(i))) dojump(pc, *pc);
if (luaO_equalObj(ra, RKC(i))) dojump(pc, *pc);
pc++;
break;
}
case OP_TESTNE: {
lua_assert(GET_OPCODE(*pc) == OP_CJMP);
if (!luaO_equalObj(RB(i), RKC(i))) dojump(pc, *pc);
if (!luaO_equalObj(ra, RKC(i))) dojump(pc, *pc);
pc++;
break;
}
case OP_TESTLT: {
lua_assert(GET_OPCODE(*pc) == OP_CJMP);
if (luaV_lessthan(L, RB(i), RKC(i))) dojump(pc, *pc);
if (luaV_lessthan(L, ra, RKC(i))) dojump(pc, *pc);
pc++;
break;
}
case OP_TESTLE: { /* b <= c === !(c<b) */
lua_assert(GET_OPCODE(*pc) == OP_CJMP);
if (!luaV_lessthan(L, RKC(i), RB(i))) dojump(pc, *pc);
if (!luaV_lessthan(L, RKC(i), ra)) dojump(pc, *pc);
pc++;
break;
}
case OP_TESTGT: { /* b > c === (c<b) */
lua_assert(GET_OPCODE(*pc) == OP_CJMP);
if (luaV_lessthan(L, RKC(i), RB(i))) dojump(pc, *pc);
if (luaV_lessthan(L, RKC(i), ra)) dojump(pc, *pc);
pc++;
break;
}
case OP_TESTGE: { /* b >= c === !(b<c) */
lua_assert(GET_OPCODE(*pc) == OP_CJMP);
if (!luaV_lessthan(L, RB(i), RKC(i))) dojump(pc, *pc);
if (!luaV_lessthan(L, ra, RKC(i))) dojump(pc, *pc);
pc++;
break;
}
@ -550,11 +550,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
int c;
int b = GETARG_B(i);
if (b != NO_REG)
L->top = base+b;
L->top = ra+b+1;
luaD_call(L, ra);
c = GETARG_C(i);
if (c != NO_REG) {
while (L->top < base+c) setnilvalue(L->top++);
while (L->top < ra+c) setnilvalue(L->top++);
L->top = base + tf->maxstacksize;
}
break;
@ -562,7 +562,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
case OP_RETURN: {
int b = GETARG_B(i);
if (b != NO_REG)
L->top = base+b;
L->top = ra+b;
return ra;
}
case OP_FORPREP: {
@ -578,10 +578,10 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
/* go through */
}
case OP_FORLOOP: {
if (ttype(ra) != LUA_TNUMBER)
luaD_error(L, l_s("`for' index must be a number"));
runtime_check(L, ttype(ra+1) == LUA_TNUMBER &&
ttype(ra+2) == LUA_TNUMBER);
if (ttype(ra) != LUA_TNUMBER)
luaD_error(L, l_s("`for' index must be a number"));
nvalue(ra) += nvalue(ra+2); /* increment index */
if (nvalue(ra+2) > 0 ?
nvalue(ra) <= nvalue(ra+1) :