From af19d556355b6e79296811cb18fe511f8784b8f1 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 13 May 2002 10:09:00 -0300 Subject: generic for also coded to make test at the end of the loop --- ldebug.c | 10 ++++------ lopcodes.c | 6 +++--- lopcodes.h | 7 +++++-- lparser.c | 34 ++++++++++++++++++++-------------- lvm.c | 6 ++++-- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/ldebug.c b/ldebug.c index 59c74731..82c636bf 100644 --- 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 index 8c8332c5..bf0e617a 100644 --- 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 index 79dae70c..fbdec4cf 100644 --- 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) 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; if->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 index a9045eef..ac0cca9d 100644 --- 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: -- cgit v1.2.3-55-g6feb