lua

A copy of the Lua development repository
Log | Files | Refs | README

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:
Mlcode.c | 19+++++++++----------
Mldebug.c | 96++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mldebug.h | 5++---
Mlopcodes.h | 24++++++++++++------------
Mlparser.c | 22+++++++++++-----------
Mlvm.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) :