This commit is contained in:
Roberto Ierusalimschy 2001-06-08 09:29:27 -03:00
parent ba11831d35
commit 0267168675
4 changed files with 71 additions and 79 deletions

12
lcode.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lcode.c,v 1.70 2001/06/06 18:00:19 roberto Exp roberto $ ** $Id: lcode.c,v 1.71 2001/06/07 15:01:21 roberto Exp roberto $
** Code generator for Lua ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -144,6 +144,12 @@ static int need_value (FuncState *fs, int list, OpCode op) {
} }
static void patchtestreg (Instruction *i, int reg) {
if (reg == NO_REG) reg = GETARG_B(*i);
SETARG_A(*i, reg);
}
static void luaK_patchlistaux (FuncState *fs, int list, static void luaK_patchlistaux (FuncState *fs, int list,
int ttarget, int treg, int ftarget, int freg, int dtarget) { int ttarget, int treg, int ftarget, int freg, int dtarget) {
while (list != NO_JUMP) { while (list != NO_JUMP) {
@ -151,12 +157,12 @@ static void luaK_patchlistaux (FuncState *fs, int list,
Instruction *i = getjumpcontrol(fs, list); Instruction *i = getjumpcontrol(fs, list);
switch (GET_OPCODE(*i)) { switch (GET_OPCODE(*i)) {
case OP_TESTT: { case OP_TESTT: {
SETARG_A(*i, treg); patchtestreg(i, treg);
luaK_fixjump(fs, list, ttarget); luaK_fixjump(fs, list, ttarget);
break; break;
} }
case OP_TESTF: { case OP_TESTF: {
SETARG_A(*i, freg); patchtestreg(i, freg);
luaK_fixjump(fs, list, ftarget); luaK_fixjump(fs, list, ftarget);
break; break;
} }

View File

@ -1,5 +1,5 @@
/* /*
** $Id: ldebug.c,v 1.78 2001/06/06 17:50:36 roberto Exp roberto $ ** $Id: ldebug.c,v 1.79 2001/06/07 14:44:51 roberto Exp roberto $
** Debug Interface ** Debug Interface
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -409,12 +409,6 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
pc += b; /* do the jump */ pc += b; /* do the jump */
break; break;
} }
case OP_TESTT:
case OP_TESTF: {
if (a != NO_REG)
checkreg(pt, a);
break;
}
case OP_NILJMP: { case OP_NILJMP: {
check(pc+2 < pt->sizecode); /* check its jump */ check(pc+2 < pt->sizecode); /* check its jump */
break; break;
@ -605,8 +599,8 @@ const lu_byte luaG_opmodes[] = {
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTLE */ 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_TESTGT */
opmode(1,0,1,1, 0,0,iABC), /* OP_TESTGE */ opmode(1,0,1,1, 0,0,iABC), /* OP_TESTGE */
opmode(1,0,1,0, 1,0,iABC), /* OP_TESTT */ opmode(1,1,1,0, 1,0,iABC), /* OP_TESTT */
opmode(1,0,1,0, 1,0,iABC), /* OP_TESTF */ 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, 1,0,iAsBc), /* OP_NILJMP */
opmode(0,1,0,0, 0,0,iABC), /* OP_CALL */ 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,iABC), /* OP_RETURN */

View File

@ -1,5 +1,5 @@
/* /*
** $Id: lparser.c,v 1.144 2001/06/05 19:27:32 roberto Exp roberto $ ** $Id: lparser.c,v 1.145 2001/06/07 14:44:51 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
*/ */
@ -492,16 +492,20 @@ static void recfield (LexState *ls, expdesc *t) {
} }
static int anotherfield (LexState *ls) {
if (ls->t.token != l_c(',')) return 0;
next(ls); /* skip the comma */
return (ls->t.token != l_c(';') && ls->t.token != l_c('}'));
}
static int recfields (LexState *ls, expdesc *t) { static int recfields (LexState *ls, expdesc *t) {
/* recfields -> recfield { `,' recfield } [`,'] */ /* recfields -> recfield { `,' recfield } [`,'] */
int n = 1; /* at least one element */ int n = 0;
recfield(ls, t); do { /* at least one element */
while (ls->t.token == l_c(',')) {
next(ls);
if (ls->t.token == l_c(';') || ls->t.token == l_c('}')) break;
recfield(ls, t); recfield(ls, t);
n++; n++;
} } while (anotherfield(ls));
return n; return n;
} }
@ -514,13 +518,12 @@ static int listfields (LexState *ls, expdesc *t) {
int reg; int reg;
reg = fs->freereg; reg = fs->freereg;
expr(ls, &v); expr(ls, &v);
while (ls->t.token == l_c(',') && while (anotherfield(ls)) {
(next(ls), (ls->t.token != l_c(';') && ls->t.token != l_c('}')))) {
luaK_exp2nextreg(fs, &v); luaK_exp2nextreg(fs, &v);
luaX_checklimit(ls, n, MAXARG_Bc, luaX_checklimit(ls, n, MAXARG_Bc,
l_s("`item groups' in a list initializer")); l_s("`item groups' in a list initializer"));
if (n%LFIELDS_PER_FLUSH == 0) { if (n%LFIELDS_PER_FLUSH == 0) {
luaK_codeABc(fs, OP_SETLIST, t->u.i.info, n-1); luaK_codeABc(fs, OP_SETLIST, t->u.i.info, n-1); /* flush */
fs->freereg = reg; /* free registers */ fs->freereg = reg; /* free registers */
} }
expr(ls, &v); expr(ls, &v);

103
lvm.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lvm.c,v 1.179 2001/06/05 18:17:01 roberto Exp roberto $ ** $Id: lvm.c,v 1.180 2001/06/05 19:27:32 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -346,9 +346,9 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
TObject tempb, tempc; \ TObject tempb, tempc; \
if ((ttype(b) == LUA_TNUMBER || (b = luaV_tonumber(b, &tempb)) != NULL) && \ if ((ttype(b) == LUA_TNUMBER || (b = luaV_tonumber(b, &tempb)) != NULL) && \
(ttype(c) == LUA_TNUMBER || (c = luaV_tonumber(c, &tempc)) != NULL)) { \ (ttype(c) == LUA_TNUMBER || (c = luaV_tonumber(c, &tempc)) != NULL)) { \
setnvalue(RA(i), nvalue(b) op nvalue(c)); \ setnvalue(ra, nvalue(b) op nvalue(c)); \
} else \ } else \
call_arith(L, RB(i), RKC(i), RA(i), optm); \ call_arith(L, RB(i), RKC(i), ra, optm); \
} }
@ -375,59 +375,57 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
/* main loop of interpreter */ /* main loop of interpreter */
for (;;) { for (;;) {
const Instruction i = *pc++; const Instruction i = *pc++;
const StkId ra = RA(i);
if (linehook) if (linehook)
traceexec(L, linehook); traceexec(L, linehook);
switch (GET_OPCODE(i)) { switch (GET_OPCODE(i)) {
case OP_MOVE: { case OP_MOVE: {
setobj(RA(i), RB(i)); setobj(ra, RB(i));
break; break;
} }
case OP_LOADK: { case OP_LOADK: {
setobj(RA(i), KBc(i)); setobj(ra, KBc(i));
break; break;
} }
case OP_LOADINT: { case OP_LOADINT: {
setnvalue(RA(i), (lua_Number)GETARG_sBc(i)); setnvalue(ra, (lua_Number)GETARG_sBc(i));
break; break;
} }
case OP_LOADUPVAL: { case OP_LOADUPVAL: {
setobj(RA(i), cl->upvalue+GETARG_Bc(i)); setobj(ra, cl->upvalue+GETARG_Bc(i));
break; break;
} }
case OP_LOADNIL: { case OP_LOADNIL: {
TObject *ra = RA(i);
TObject *rb = RB(i); TObject *rb = RB(i);
do { do {
setnilvalue(ra++); setnilvalue(rb--);
} while (ra <= rb); } while (rb >= ra);
break; break;
} }
case OP_GETGLOBAL: { case OP_GETGLOBAL: {
lua_assert(ttype(KBc(i)) == LUA_TSTRING); lua_assert(ttype(KBc(i)) == LUA_TSTRING);
luaV_getglobal(L, tsvalue(KBc(i)), RA(i)); luaV_getglobal(L, tsvalue(KBc(i)), ra);
break; break;
} }
case OP_GETTABLE: { case OP_GETTABLE: {
luaV_gettable(L, RB(i), RKC(i), RA(i)); luaV_gettable(L, RB(i), RKC(i), ra);
break; break;
} }
case OP_SETGLOBAL: { case OP_SETGLOBAL: {
lua_assert(ttype(KBc(i)) == LUA_TSTRING); lua_assert(ttype(KBc(i)) == LUA_TSTRING);
luaV_setglobal(L, tsvalue(KBc(i)), RA(i)); luaV_setglobal(L, tsvalue(KBc(i)), ra);
break; break;
} }
case OP_SETTABLE: { case OP_SETTABLE: {
luaV_settable(L, RB(i), RKC(i), RA(i)); luaV_settable(L, RB(i), RKC(i), ra);
break; break;
} }
case OP_NEWTABLE: { case OP_NEWTABLE: {
StkId ra = RA(i);
sethvalue(ra, luaH_new(L, GETARG_Bc(i))); sethvalue(ra, luaH_new(L, GETARG_Bc(i)));
luaV_checkGC(L, ra+1); luaV_checkGC(L, ra+1);
break; break;
} }
case OP_SELF: { case OP_SELF: {
StkId ra = RA(i);
StkId rb = RB(i); StkId rb = RB(i);
setobj(ra+1, rb); setobj(ra+1, rb);
luaV_gettable(L, rb, RKC(i), ra); luaV_gettable(L, rb, RKC(i), ra);
@ -450,12 +448,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
break; break;
} }
case OP_POW: { case OP_POW: {
call_arith(L, RB(i), RKC(i), RA(i), TM_POW); call_arith(L, RB(i), RKC(i), ra, TM_POW);
break; break;
} }
case OP_UNM: { case OP_UNM: {
const TObject *rb = RB(i); const TObject *rb = RB(i);
StkId ra = RA(i);
if (ttype(rb) == LUA_TNUMBER || (rb=luaV_tonumber(rb, ra)) != NULL) { if (ttype(rb) == LUA_TNUMBER || (rb=luaV_tonumber(rb, ra)) != NULL) {
setnvalue(ra, -nvalue(rb)); setnvalue(ra, -nvalue(rb));
} }
@ -468,9 +465,9 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
} }
case OP_NOT: { case OP_NOT: {
if (ttype(RB(i)) == LUA_TNIL) { if (ttype(RB(i)) == LUA_TNIL) {
setnvalue(RA(i), 1); setnvalue(ra, 1);
} else { } else {
setnilvalue(RA(i)); setnilvalue(ra);
} }
break; break;
} }
@ -478,7 +475,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
StkId top = RC(i)+1; StkId top = RC(i)+1;
StkId rb = RB(i); StkId rb = RB(i);
luaV_strconc(L, top-rb, top); luaV_strconc(L, top-rb, top);
setobj(RA(i), rb); setobj(ra, rb);
break; break;
} }
case OP_CJMP: case OP_CJMP:
@ -526,8 +523,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
StkId rb = RB(i); StkId rb = RB(i);
lua_assert(GET_OPCODE(*pc) == OP_CJMP); lua_assert(GET_OPCODE(*pc) == OP_CJMP);
if (ttype(rb) != LUA_TNIL) { if (ttype(rb) != LUA_TNIL) {
int a = GETARG_A(i); setobj(ra, rb);
if (a != NO_REG) setobj(base+a, rb);
dojump(pc, *pc); dojump(pc, *pc);
} }
pc++; pc++;
@ -536,15 +532,14 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
case OP_TESTF: { case OP_TESTF: {
lua_assert(GET_OPCODE(*pc) == OP_CJMP); lua_assert(GET_OPCODE(*pc) == OP_CJMP);
if (ttype(RB(i)) == LUA_TNIL) { if (ttype(RB(i)) == LUA_TNIL) {
int a = GETARG_A(i); setnilvalue(ra);
if (a != NO_REG) setnilvalue(base+a);
dojump(pc, *pc); dojump(pc, *pc);
} }
pc++; pc++;
break; break;
} }
case OP_NILJMP: { case OP_NILJMP: {
setnilvalue(RA(i)); setnilvalue(ra);
pc++; pc++;
break; break;
} }
@ -555,9 +550,9 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
L->top = base+b; L->top = base+b;
nres = GETARG_C(i); nres = GETARG_C(i);
if (nres == NO_REG) nres = LUA_MULTRET; if (nres == NO_REG) nres = LUA_MULTRET;
luaD_call(L, RA(i), nres); luaD_call(L, ra, nres);
if (nres != LUA_MULTRET) { if (nres != LUA_MULTRET) {
lua_assert(L->top == RA(i)+nres); lua_assert(L->top == ra+nres);
L->top = base+tf->maxstacksize; L->top = base+tf->maxstacksize;
} }
break; break;
@ -566,59 +561,55 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
int b = GETARG_B(i); int b = GETARG_B(i);
if (b != NO_REG) if (b != NO_REG)
L->top = base+b; L->top = base+b;
return RA(i); return ra;
} }
case OP_FORPREP: { case OP_FORPREP: {
int jmp = GETARG_sBc(i); int jmp = GETARG_sBc(i);
StkId breg = RA(i); if (luaV_tonumber(ra, ra) == NULL)
if (luaV_tonumber(breg, breg) == NULL)
luaD_error(L, l_s("`for' initial value must be a number")); luaD_error(L, l_s("`for' initial value must be a number"));
if (luaV_tonumber(breg+1, breg+1) == NULL) if (luaV_tonumber(ra+1, ra+1) == NULL)
luaD_error(L, l_s("`for' limit must be a number")); luaD_error(L, l_s("`for' limit must be a number"));
if (luaV_tonumber(breg+2, breg+2) == NULL) if (luaV_tonumber(ra+2, ra+2) == NULL)
luaD_error(L, l_s("`for' step must be a number")); luaD_error(L, l_s("`for' step must be a number"));
pc += -jmp; /* `jump' to loop end (delta is negated here) */ pc += -jmp; /* `jump' to loop end (delta is negated here) */
nvalue(breg) -= nvalue(breg+2);/* decrement index (to be incremented) */ nvalue(ra) -= nvalue(ra+2);/* decrement index (to be incremented) */
/* go through */ /* go through */
} }
case OP_FORLOOP: { case OP_FORLOOP: {
StkId breg = RA(i); if (ttype(ra) != LUA_TNUMBER)
if (ttype(breg) != LUA_TNUMBER)
luaD_error(L, l_s("`for' index must be a number")); luaD_error(L, l_s("`for' index must be a number"));
runtime_check(L, ttype(breg+1) == LUA_TNUMBER && runtime_check(L, ttype(ra+1) == LUA_TNUMBER &&
ttype(breg+2) == LUA_TNUMBER); ttype(ra+2) == LUA_TNUMBER);
nvalue(breg) += nvalue(breg+2); /* increment index */ nvalue(ra) += nvalue(ra+2); /* increment index */
if (nvalue(breg+2) > 0 ? if (nvalue(ra+2) > 0 ?
nvalue(breg) <= nvalue(breg+1) : nvalue(ra) <= nvalue(ra+1) :
nvalue(breg) >= nvalue(breg+1)) nvalue(ra) >= nvalue(ra+1))
dojump(pc, i); /* repeat loop */ dojump(pc, i); /* repeat loop */
break; break;
} }
case OP_TFORPREP: { case OP_TFORPREP: {
int jmp = GETARG_sBc(i); int jmp = GETARG_sBc(i);
StkId breg = RA(i); if (ttype(ra) != LUA_TTABLE)
if (ttype(breg) != LUA_TTABLE)
luaD_error(L, l_s("`for' table must be a table")); luaD_error(L, l_s("`for' table must be a table"));
setnvalue(breg+1, -1); /* initial index */ setnvalue(ra+1, -1); /* initial index */
setnilvalue(breg+2); setnilvalue(ra+2);
setnilvalue(breg+3); setnilvalue(ra+3);
pc += -jmp; /* `jump' to loop end (delta is negated here) */ pc += -jmp; /* `jump' to loop end (delta is negated here) */
/* go through */ /* go through */
} }
case OP_TFORLOOP: { case OP_TFORLOOP: {
StkId breg = RA(i);
Hash *t; Hash *t;
int n; int n;
runtime_check(L, ttype(breg) == LUA_TTABLE); runtime_check(L, ttype(ra) == LUA_TTABLE);
runtime_check(L, ttype(breg+1) == LUA_TNUMBER); runtime_check(L, ttype(ra+1) == LUA_TNUMBER);
t = hvalue(breg); t = hvalue(ra);
n = (int)nvalue(breg+1); n = (int)nvalue(ra+1);
n = luaH_nexti(t, n); n = luaH_nexti(t, n);
if (n != -1) { /* repeat loop? */ if (n != -1) { /* repeat loop? */
Node *node = node(t, n); Node *node = node(t, n);
setnvalue(breg+1, n); /* index */ setnvalue(ra+1, n); /* index */
setkey2obj(breg+2, node); setkey2obj(ra+2, node);
setobj(breg+3, val(node)); setobj(ra+3, val(node));
dojump(pc, i); /* repeat loop */ dojump(pc, i); /* repeat loop */
} }
break; break;
@ -628,7 +619,6 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
int bc; int bc;
int n; int n;
Hash *h; Hash *h;
StkId ra = RA(i);
runtime_check(L, ttype(ra) == LUA_TTABLE); runtime_check(L, ttype(ra) == LUA_TTABLE);
h = hvalue(ra); h = hvalue(ra);
bc = GETARG_Bc(i); bc = GETARG_Bc(i);
@ -644,7 +634,6 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
case OP_CLOSURE: { case OP_CLOSURE: {
Proto *p = tf->kproto[GETARG_Bc(i)]; Proto *p = tf->kproto[GETARG_Bc(i)];
int nup = p->nupvalues; int nup = p->nupvalues;
StkId ra = RA(i);
luaV_checkGC(L, ra+nup); luaV_checkGC(L, ra+nup);
L->top = ra+nup; L->top = ra+nup;
luaV_Lclosure(L, p, nup); luaV_Lclosure(L, p, nup);