commit 0a1b1acdd36a3ed4e6f1cadf62eec8531a437cbf
parent 79acf5ea6083fe4aebeb24740d25ddf35654944a
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 11 Jun 2001 11:56:20 -0300
details about opcode parameters
Diffstat:
M | lcode.c | | | 19 | +++++++++---------- |
M | ldebug.c | | | 96 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
M | ldebug.h | | | 5 | ++--- |
M | lopcodes.h | | | 24 | ++++++++++++------------ |
M | lparser.c | | | 22 | +++++++++++----------- |
M | lvm.c | | | 24 | ++++++++++++------------ |
6 files changed, 94 insertions(+), 96 deletions(-)
diff --git a/lcode.c b/lcode.c
@@ -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;
}
}
diff --git a/ldebug.c b/ldebug.c
@@ -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 */
};
diff --git a/ldebug.h b/ldebug.h
@@ -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 */
diff --git a/lopcodes.h b/lopcodes.h
@@ -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'
===========================================================================*/
diff --git a/lparser.c b/lparser.c
@@ -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 */
}
diff --git a/lvm.c b/lvm.c
@@ -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) :