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 ** Code generator for Lua
** See Copyright Notice in lua.h ** 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) { static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) {
luaK_codeABC(fs, op, NO_REG, B, C); luaK_codeABC(fs, op, A, B, C);
return luaK_codeAsBc(fs, OP_CJMP, 0, NO_JUMP); 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) { void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) {
if (e->k == VCALL) { /* expression is an open function call? */ if (e->k == VCALL) { /* expression is an open function call? */
int a = GETARG_A(getcode(fs, e)); if (nresults == LUA_MULTRET) nresults = NO_REG;
int c = (nresults == LUA_MULTRET) ? NO_REG : a + nresults; SETARG_C(getcode(fs, e), nresults);
SETARG_C(getcode(fs, e), c);
if (nresults == 1) { /* `regular' expression? */ if (nresults == 1) { /* `regular' expression? */
e->k = VNONRELOC; 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) { if (GET_OPCODE(ie) == OP_NOT) {
op = invertoperator(op); op = invertoperator(op);
fs->pc--; /* remove previous OP_NOT */ 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 */ /* else go through */
} }
discharge2anyreg(fs, e); discharge2anyreg(fs, e);
freeexp(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; e1->k = VRELOCABLE;
} }
else { /* jump */ 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; 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 ** Debug Interface
** See Copyright Notice in lua.h ** 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 a = GETARG_A(i);
int b = 0; int b = 0;
int c = 0; int c = 0;
checkreg(pt, a);
switch (getOpMode(op)) { switch (getOpMode(op)) {
case iABC: { case iABC: {
b = GETARG_B(i); b = GETARG_B(i);
@ -370,7 +371,6 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
break; break;
} }
} }
if (testOpMode(op, OpModeAreg)) checkreg(pt, a);
if (testOpMode(op, OpModesetA)) { if (testOpMode(op, OpModesetA)) {
if (a == reg) last = pc; /* change register `a' */ if (a == reg) last = pc; /* change register `a' */
} }
@ -414,20 +414,20 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
break; break;
} }
case OP_CALL: { case OP_CALL: {
if (b == NO_REG) b = pt->maxstacksize; if (b != NO_REG) {
checkreg(pt, a+b);
}
if (c == NO_REG) { if (c == NO_REG) {
check(checkopenop(pt->code[pc+1])); check(checkopenop(pt->code[pc+1]));
c = 1;
} }
check(b > a); else if (c != 0)
checkreg(pt, b-1); checkreg(pt, a+c-1);
checkreg(pt, c-1);
if (reg >= a) last = pc; /* affect all registers above base */ if (reg >= a) last = pc; /* affect all registers above base */
break; break;
} }
case OP_RETURN: { case OP_RETURN: {
if (b == NO_REG) b = pt->maxstacksize; if (b != NO_REG && b != 0)
checkreg(pt, b-1); checkreg(pt, a+b-1);
break; break;
} }
case OP_FORPREP: 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) | \ #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)) ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m))
const lu_byte luaG_opmodes[] = { const lu_byte luaG_opmodes[] = {
/* T A B C sA K mode opcode */ /* T J B C sA K mode opcode */
opmode(0,1,1,0, 1,0,iABC), /* OP_MOVE */ opmode(0,0,1,0, 1,0,iABC), /* OP_MOVE */
opmode(0,1,0,0, 1,1,iABc), /* OP_LOADK */ opmode(0,0,0,0, 1,1,iABc), /* OP_LOADK */
opmode(0,1,0,0, 1,0,iAsBc), /* OP_LOADINT */ opmode(0,0,0,0, 1,0,iAsBc), /* OP_LOADINT */
opmode(0,1,1,0, 1,0,iABC), /* OP_LOADNIL */ opmode(0,0,1,0, 1,0,iABC), /* OP_LOADNIL */
opmode(0,1,0,0, 1,0,iABc), /* OP_LOADUPVAL */ opmode(0,0,0,0, 1,0,iABc), /* OP_LOADUPVAL */
opmode(0,1,0,0, 1,1,iABc), /* OP_GETGLOBAL */ opmode(0,0,0,0, 1,1,iABc), /* OP_GETGLOBAL */
opmode(0,1,1,1, 1,0,iABC), /* OP_GETTABLE */ opmode(0,0,1,1, 1,0,iABC), /* OP_GETTABLE */
opmode(0,1,0,0, 0,1,iABc), /* OP_SETGLOBAL */ opmode(0,0,0,0, 0,1,iABc), /* OP_SETGLOBAL */
opmode(0,1,1,1, 0,0,iABC), /* OP_SETTABLE */ opmode(0,0,1,1, 0,0,iABC), /* OP_SETTABLE */
opmode(0,1,0,0, 1,0,iABc), /* OP_NEWTABLE */ opmode(0,0,0,0, 1,0,iABc), /* OP_NEWTABLE */
opmode(0,1,1,1, 1,0,iABC), /* OP_SELF */ opmode(0,0,1,1, 1,0,iABC), /* OP_SELF */
opmode(0,1,1,1, 1,0,iABC), /* OP_ADD */ opmode(0,0,1,1, 1,0,iABC), /* OP_ADD */
opmode(0,1,1,1, 1,0,iABC), /* OP_SUB */ opmode(0,0,1,1, 1,0,iABC), /* OP_SUB */
opmode(0,1,1,1, 1,0,iABC), /* OP_MUL */ opmode(0,0,1,1, 1,0,iABC), /* OP_MUL */
opmode(0,1,1,1, 1,0,iABC), /* OP_DIV */ opmode(0,0,1,1, 1,0,iABC), /* OP_DIV */
opmode(0,1,1,1, 1,0,iABC), /* OP_POW */ opmode(0,0,1,1, 1,0,iABC), /* OP_POW */
opmode(0,1,1,0, 1,0,iABC), /* OP_UNM */ opmode(0,0,1,0, 1,0,iABC), /* OP_UNM */
opmode(0,1,1,0, 1,0,iABC), /* OP_NOT */ opmode(0,0,1,0, 1,0,iABC), /* OP_NOT */
opmode(0,1,1,1, 1,0,iABC), /* OP_CONCAT */ opmode(0,0,1,1, 1,0,iABC), /* OP_CONCAT */
opmode(0,0,0,0, 0,0,iAsBc), /* OP_JMP */ opmode(0,1,0,0, 0,0,iAsBc), /* OP_JMP */
opmode(0,0,0,0, 0,0,iAsBc), /* OP_CJMP */ opmode(0,1,0,0, 0,0,iAsBc), /* OP_CJMP */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTEQ */ opmode(1,0,0,1, 0,0,iABC), /* OP_TESTEQ */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTNE */ opmode(1,0,0,1, 0,0,iABC), /* OP_TESTNE */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTLT */ opmode(1,0,0,1, 0,0,iABC), /* OP_TESTLT */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTLE */ opmode(1,0,0,1, 0,0,iABC), /* OP_TESTLE */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTGT */ opmode(1,0,0,1, 0,0,iABC), /* OP_TESTGT */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTGE */ opmode(1,0,0,1, 0,0,iABC), /* OP_TESTGE */
opmode(1,1,1,0, 1,0,iABC), /* OP_TESTT */ opmode(1,0,1,0, 1,0,iABC), /* OP_TESTT */
opmode(1,1,1,0, 1,0,iABC), /* OP_TESTF */ opmode(1,0,1,0, 1,0,iABC), /* OP_TESTF */
opmode(0,1,0,0, 1,0,iAsBc), /* OP_NILJMP */ opmode(0,0,0,0, 1,0,iAsBc), /* OP_NILJMP */
opmode(0,1,0,0, 0,0,iABC), /* OP_CALL */ opmode(0,0,0,0, 0,0,iABC), /* OP_CALL */
opmode(0,1,0,0, 0,0,iABC), /* OP_RETURN */ opmode(0,0,0,0, 0,0,iABC), /* OP_RETURN */
opmode(0,1,0,0, 0,0,iAsBc), /* OP_FORPREP */ opmode(0,0,0,0, 0,0,iAsBc), /* OP_FORPREP */
opmode(0,1,0,0, 0,0,iAsBc), /* OP_FORLOOP */ 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_TFORPREP */
opmode(0,1,0,0, 0,0,iAsBc), /* OP_TFORLOOP */ opmode(0,1,0,0, 0,0,iAsBc), /* OP_TFORLOOP */
opmode(0,1,0,0, 0,0,iABc), /* OP_SETLIST */ opmode(0,0,0,0, 0,0,iABc), /* OP_SETLIST */
opmode(0,1,0,0, 0,0,iABc), /* OP_SETLIST0 */ opmode(0,0,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_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 ** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -18,8 +18,7 @@ enum OpMode {iABC, iABc, iAsBc}; /* basic instruction format */
** masks for instruction properties ** masks for instruction properties
*/ */
enum OpModeMask { enum OpModeMask {
OpModeAreg = 2, /* A is a register */ OpModeBreg = 2, /* B is a register */
OpModeBreg, /* B is a register */
OpModeCreg, /* C is a register/constant */ OpModeCreg, /* C is a register/constant */
OpModesetA, /* instruction set register A */ OpModesetA, /* instruction set register A */
OpModeK, /* Bc is a constant */ 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 ** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h ** 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_JMP,/* sBc PC += sBc */
OP_CJMP,/* sBc if test then PC += sBc (see (1)) */ OP_CJMP,/* sBc if test then PC += sBc (see (1)) */
OP_TESTEQ,/* B C test := (R(B) == R/K(C)) */ OP_TESTEQ,/* A C test := (R(A) == R/K(C)) */
OP_TESTNE,/* B C test := (R(B) ~= R/K(C)) */ OP_TESTNE,/* A C test := (R(A) ~= R/K(C)) */
OP_TESTLT,/* B C test := (R(B) < R/K(C)) */ OP_TESTLT,/* A C test := (R(A) < R/K(C)) */
OP_TESTLE,/* B C test := (R(B) <= R/K(C)) */ OP_TESTLE,/* A C test := (R(A) <= R/K(C)) */
OP_TESTGT,/* B C test := (R(B) > R/K(C)) */ OP_TESTGT,/* A C test := (R(A) > R/K(C)) */
OP_TESTGE,/* B C test := (R(B) >= 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_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_TESTF,/* A B test := not R(B); if (test) R(A) := nil */
OP_NILJMP,/* A R(A) := nil; PC++; */ 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_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(B-1) (see (3)) */ OP_RETURN,/* A B return R(A), ... ,R(A+B-1) (see (3)) */
OP_FORPREP,/* A sBc */ OP_FORPREP,/* A sBc */
OP_FORLOOP,/* 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. 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, (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 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". 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 ** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -415,7 +415,7 @@ static int explist1 (LexState *ls, expdesc *v) {
static void funcargs (LexState *ls, expdesc *f) { static void funcargs (LexState *ls, expdesc *f) {
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
expdesc args; expdesc args;
int base, top; int base, nparams;
switch (ls->t.token) { switch (ls->t.token) {
case l_c('('): { /* funcargs -> `(' [ explist1 ] `)' */ case l_c('('): { /* funcargs -> `(' [ explist1 ] `)' */
int line = ls->linenumber; int line = ls->linenumber;
@ -446,13 +446,13 @@ static void funcargs (LexState *ls, expdesc *f) {
lua_assert(f->k == VNONRELOC); lua_assert(f->k == VNONRELOC);
base = f->u.i.info; /* base register for call */ base = f->u.i.info; /* base register for call */
if (args.k == VCALL) if (args.k == VCALL)
top = NO_REG; /* open call */ nparams = NO_REG; /* open call */
else { else {
if (args.k != VVOID) if (args.k != VVOID)
luaK_exp2nextreg(fs, &args); /* close last argument */ 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 fs->freereg = base+1; /* call remove function and arguments and leaves
(unless changed) one result */ (unless changed) one result */
} }
@ -1091,31 +1091,31 @@ static void retstat (LexState *ls) {
/* stat -> RETURN explist */ /* stat -> RETURN explist */
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
expdesc e; expdesc e;
int first, last1; /* registers with returned values */ int first, nret; /* registers with returned values */
next(ls); /* skip RETURN */ next(ls); /* skip RETURN */
if (block_follow(ls->t.token) || ls->t.token == l_c(';')) if (block_follow(ls->t.token) || ls->t.token == l_c(';'))
first = last1 = 0; /* return no values */ first = nret = 0; /* return no values */
else { else {
int n = explist1(ls, &e); /* optional return values */ int n = explist1(ls, &e); /* optional return values */
if (e.k == VCALL) { if (e.k == VCALL) {
luaK_setcallreturns(fs, &e, LUA_MULTRET); luaK_setcallreturns(fs, &e, LUA_MULTRET);
first = fs->nactloc; first = fs->nactloc;
last1 = NO_REG; /* return all values */ nret = NO_REG; /* return all values */
} }
else { else {
if (n == 1) { /* only one value? */ if (n == 1) { /* only one value? */
luaK_exp2anyreg(fs, &e); luaK_exp2anyreg(fs, &e);
first = e.u.i.info; first = e.u.i.info;
last1 = first+1; /* return only this value */ nret = 1; /* return only this value */
} }
else { else {
luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
first = fs->nactloc; 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 */ 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 ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -488,37 +488,37 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
} }
case OP_TESTEQ: { case OP_TESTEQ: {
lua_assert(GET_OPCODE(*pc) == OP_CJMP); 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++; pc++;
break; break;
} }
case OP_TESTNE: { case OP_TESTNE: {
lua_assert(GET_OPCODE(*pc) == OP_CJMP); 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++; pc++;
break; break;
} }
case OP_TESTLT: { case OP_TESTLT: {
lua_assert(GET_OPCODE(*pc) == OP_CJMP); 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++; pc++;
break; break;
} }
case OP_TESTLE: { /* b <= c === !(c<b) */ case OP_TESTLE: { /* b <= c === !(c<b) */
lua_assert(GET_OPCODE(*pc) == OP_CJMP); 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++; pc++;
break; break;
} }
case OP_TESTGT: { /* b > c === (c<b) */ case OP_TESTGT: { /* b > c === (c<b) */
lua_assert(GET_OPCODE(*pc) == OP_CJMP); 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++; pc++;
break; break;
} }
case OP_TESTGE: { /* b >= c === !(b<c) */ case OP_TESTGE: { /* b >= c === !(b<c) */
lua_assert(GET_OPCODE(*pc) == OP_CJMP); 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++; pc++;
break; break;
} }
@ -550,11 +550,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
int c; int c;
int b = GETARG_B(i); int b = GETARG_B(i);
if (b != NO_REG) if (b != NO_REG)
L->top = base+b; L->top = ra+b+1;
luaD_call(L, ra); luaD_call(L, ra);
c = GETARG_C(i); c = GETARG_C(i);
if (c != NO_REG) { 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; L->top = base + tf->maxstacksize;
} }
break; break;
@ -562,7 +562,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
case OP_RETURN: { case OP_RETURN: {
int b = GETARG_B(i); int b = GETARG_B(i);
if (b != NO_REG) if (b != NO_REG)
L->top = base+b; L->top = ra+b;
return ra; return ra;
} }
case OP_FORPREP: { case OP_FORPREP: {
@ -578,10 +578,10 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
/* go through */ /* go through */
} }
case OP_FORLOOP: { 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 && runtime_check(L, ttype(ra+1) == LUA_TNUMBER &&
ttype(ra+2) == 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 */ nvalue(ra) += nvalue(ra+2); /* increment index */
if (nvalue(ra+2) > 0 ? if (nvalue(ra+2) > 0 ?
nvalue(ra) <= nvalue(ra+1) : nvalue(ra) <= nvalue(ra+1) :