lua

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

commit af19d556355b6e79296811cb18fe511f8784b8f1
parent b55fded18c270412e127259a5f28c785620dbf1a
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Mon, 13 May 2002 10:08:38 -0300

generic for also coded to make test at the end of the loop

Diffstat:
Mldebug.c | 10++++------
Mlopcodes.c | 6+++---
Mlopcodes.h | 7+++++--
Mlparser.c | 34++++++++++++++++++++--------------
Mlvm.c | 6++++--
5 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/ldebug.c b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 1.112 2002/05/07 17:36:56 roberto Exp roberto $ +** $Id: ldebug.c,v 1.113 2002/05/09 14:14:34 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -336,6 +336,9 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { check(c < MAXSTACK && b < c); break; } + case OP_TFORLOOP: + checkreg(pt, a+2+c); + /* go through */ case OP_FORLOOP: checkreg(pt, a+2); /* go through */ @@ -347,11 +350,6 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { pc += b; /* do the jump */ break; } - case OP_TFORLOOP: { - checkreg(pt, a+2+c); - check(pc+2 < pt->sizecode); /* check skip */ - break; - } case OP_CALL: { if (b != 0) { checkreg(pt, a+b-1); diff --git a/lopcodes.c b/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.17 2002/04/24 20:07:46 roberto Exp roberto $ +** $Id: lopcodes.c,v 1.18 2002/05/06 15:51:41 roberto Exp roberto $ ** extracted automatically from lopcodes.h by mkprint.lua ** DO NOT EDIT ** See Copyright Notice in lua.h @@ -88,8 +88,8 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(0,0,0,0, 0,0,iABC) /* OP_TAILCALL */ ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */ ,opmode(0,0,0,0, 0,0,iAsBx) /* OP_FORLOOP */ - ,opmode(0,0,0,0, 0,0,iABC) /* OP_TFORLOOP */ - ,opmode(0,0,0,0, 0,0,iABC) /* OP_TFORPREP */ + ,opmode(1,0,0,0, 0,0,iABC) /* OP_TFORLOOP */ + ,opmode(0,0,0,0, 0,0,iAsBx) /* OP_TFORPREP */ ,opmode(0,0,0,0, 0,0,iABx) /* OP_SETLIST */ ,opmode(0,0,0,0, 0,0,iABx) /* OP_SETLISTO */ ,opmode(0,0,0,0, 0,0,iABC) /* OP_CLOSE */ diff --git a/lopcodes.h b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.95 2002/04/24 20:07:46 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.96 2002/05/06 15:51:41 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -170,7 +170,8 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) <?= R(A+1) then PC+= sBx */ OP_TFORLOOP,/* A C R(A+2), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); if R(A+2) ~= nil then pc++ */ -OP_TFORPREP,/* A if type(R(A)) == table then R(A+1):=R(A), R(A):=next */ +OP_TFORPREP,/* A sBx if type(R(A)) == table then R(A+1):=R(A), R(A):=next; + PC += sBx */ OP_SETLIST,/* A Bx R(A)[Bx-Bx%FPF+i] := R(A+i), 1 <= i <= Bx%FPF+1 */ OP_SETLISTO,/* A Bx */ @@ -193,6 +194,8 @@ OP_CLOSURE/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ (2) In OP_RETURN, if (B == 0) then return up to `top' (3) For comparisons, B specifies what conditions the test should accept. + + (4) All `skips' (pc++) assume that next instruction is a jump ===========================================================================*/ diff --git a/lparser.c b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.180 2002/05/10 17:02:32 roberto Exp roberto $ +** $Id: lparser.c,v 1.181 2002/05/10 19:22:11 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -979,15 +979,16 @@ static void whilestat (LexState *ls, int line) { int whileinit, blockinit, expinit; expdesc v; BlockCnt bl; - next(ls); - whileinit = luaK_jump(fs); + next(ls); /* skip WHILE */ + whileinit = luaK_jump(fs); /* jump to condition (which will be moved) */ expinit = luaK_getlabel(fs); - expr(ls, &v); + expr(ls, &v); /* parse condition */ if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */ lineexp = ls->linenumber; luaK_goiffalse(fs, &v); - luaK_dischargejpc(fs); - sizeexp = fs->pc - expinit; + luaK_concat(fs, &v.f, fs->jpc); + fs->jpc = NO_JUMP; + sizeexp = fs->pc - expinit; /* size of expression code */ if (sizeexp > MAXEXPWHILE) luaX_syntaxerror(ls, "while condition too complex"); for (i = 0; i < sizeexp; i++) /* save `exp' code */ @@ -998,14 +999,15 @@ static void whilestat (LexState *ls, int line) { blockinit = luaK_getlabel(fs); block(ls); luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */ + /* move `exp' back to code */ if (v.t != NO_JUMP) v.t += fs->pc - expinit; if (v.f != NO_JUMP) v.f += fs->pc - expinit; for (i=0; i<sizeexp; i++) luaK_code(fs, codeexp[i], lineexp); - luaK_patchlist(fs, v.t, blockinit); - luaK_patchtohere(fs, v.f); check_match(ls, TK_END, TK_WHILE, line); leaveblock(fs); + luaK_patchlist(fs, v.t, blockinit); /* true conditions go back to loop */ + luaK_patchtohere(fs, v.f); /* false conditions finish the loop */ } @@ -1061,8 +1063,8 @@ static void fornum (LexState *ls, TString *varname, int line) { block(ls); luaK_patchtohere(fs, prep-1); endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); + luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ luaK_patchlist(fs, endfor, prep); - fs->f->lineinfo[endfor] = line; /* pretend that `OP_FOR' starts the loop */ } @@ -1070,6 +1072,7 @@ static void forlist (LexState *ls, TString *indexname) { /* forlist -> NAME {,NAME} IN explist1 DO body */ FuncState *fs = ls->fs; expdesc e; + int line; int nvars = 0; int prep; int base = fs->freereg; @@ -1081,16 +1084,19 @@ static void forlist (LexState *ls, TString *indexname) { next(ls); } check(ls, TK_IN); + line = ls->linenumber; adjust_assign(ls, 3, explist1(ls, &e), &e); luaK_reserveregs(fs, nvars - 3); /* registers for other variables */ - luaK_codeABC(fs, OP_TFORPREP, base, 0, 0); - luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); + luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP); adjustlocalvars(ls, nvars); /* scope for all variables */ - prep = luaK_jump(fs); check(ls, TK_DO); + prep = luaK_getlabel(fs); block(ls); - luaK_patchlist(fs, luaK_jump(fs), prep-1); - luaK_patchtohere(fs, prep); + luaK_patchtohere(fs, prep-1); + removevars(fs->ls, fs->nactvar - nvars); /* deactivate locals for next op. */ + luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); + luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ + luaK_patchlist(fs, luaK_jump(fs), prep); } diff --git a/lvm.c b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.229 2002/05/06 15:51:41 roberto Exp roberto $ +** $Id: lvm.c,v 1.230 2002/05/09 14:14:34 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -548,7 +548,8 @@ StkId luaV_execute (lua_State *L) { L->top = ra+5; luaD_call(L, ra+2, GETARG_C(i) + 1); L->top = L->ci->top; - if (ttype(ra+2) != LUA_TNIL) pc++; /* skip jump (keep looping) */ + if (ttype(ra+2) == LUA_TNIL) pc++; /* skip jump (break loop) */ + else dojump(pc, GETARG_sBx(*pc) + 1); /* else jump back */ break; } case OP_TFORPREP: { @@ -557,6 +558,7 @@ StkId luaV_execute (lua_State *L) { setsvalue(ra, luaS_new(L, "next")); luaV_gettable(L, gt(L), ra, ra); } + dojump(pc, GETARG_sBx(i)); break; } case OP_SETLIST: