lua

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

commit 3b6f8bfbe688fdd0f1c17bd023140804155624f3
parent caf01b5bfa33617b7bb2c40292f74599f6030eba
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Mon, 29 Jan 2001 13:26:18 -0200

simpler implementation of for loops

Diffstat:
Mlcode.c | 13++++++++++++-
Mlcode.h | 3++-
Mlparser.c | 4++--
Mlvm.c | 38+++++++++++++-------------------------
4 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/lcode.c b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.57 2001/01/19 13:20:30 roberto Exp roberto $ +** $Id: lcode.c,v 1.58 2001/01/29 13:14:49 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -59,6 +59,17 @@ static void luaK_fixjump (FuncState *fs, int pc, int dest) { } +/* +** prep-for instructions (OP_FORPREP & OP_LFORPREP) have a negated jump, +** as they simulate the real jump... +*/ +void luaK_fixfor (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest-(pc+1); + SETARG_S(*jmp, -offset); +} + + static int luaK_getjump (FuncState *fs, int pc) { int offset = GETARG_S(fs->f->code[pc]); if (offset == NO_JUMP) /* point to itself represents end of list */ diff --git a/lcode.h b/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.17 2000/11/30 18:50:47 roberto Exp roberto $ +** $Id: lcode.h,v 1.18 2000/12/04 18:33:40 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -53,6 +53,7 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1); int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2); int luaK_jump (FuncState *fs); void luaK_patchlist (FuncState *fs, int list, int target); +void luaK_fixfor (FuncState *fs, int pc, int dest); void luaK_concat (FuncState *fs, int *l1, int l2); void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue); int luaK_getlabel (FuncState *fs); diff --git a/lparser.c b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.125 2001/01/19 13:20:30 roberto Exp roberto $ +** $Id: lparser.c,v 1.126 2001/01/29 13:14:49 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -854,7 +854,7 @@ static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) { adjustlocalvars(ls, nvar); /* scope for control variables */ block(ls); luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); - luaK_patchlist(fs, prep, luaK_getlabel(fs)); + luaK_fixfor(fs, prep, luaK_getlabel(fs)); removelocalvars(ls, nvar); } diff --git a/lvm.c b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.158 2001/01/26 18:43:22 roberto Exp roberto $ +** $Id: lvm.c,v 1.159 2001/01/29 13:02:20 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -330,7 +330,7 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { -#define dojump(pc, i) { int d = GETARG_S(i); pc += d; } +#define dojump(pc, i) ((pc) += GETARG_S(i)) /* ** Executes the given Lua function. Parameters are between [base,top). @@ -615,19 +615,15 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { break; } case OP_FORPREP: { + int jmp = GETARG_S(i); if (tonumber(top-1)) luaD_error(L, "`for' step must be a number"); if (tonumber(top-2)) luaD_error(L, "`for' limit must be a number"); if (tonumber(top-3)) luaD_error(L, "`for' initial value must be a number"); - if (nvalue(top-1) > 0 ? - nvalue(top-3) > nvalue(top-2) : - nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */ - top -= 3; /* remove control variables */ - dojump(pc, i); /* jump to loop end */ - } - break; + pc += -jmp; /* "jump" to loop end (delta is negated here) */ + goto forloop; /* do not increment index */ } case OP_FORLOOP: { lua_assert(ttype(top-1) == LUA_TNUMBER); @@ -635,6 +631,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { if (ttype(top-3) != LUA_TNUMBER) luaD_error(L, "`for' index must be a number"); nvalue(top-3) += nvalue(top-1); /* increment index */ + forloop: if (nvalue(top-1) > 0 ? nvalue(top-3) > nvalue(top-2) : nvalue(top-3) < nvalue(top-2)) @@ -644,24 +641,15 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { break; } case OP_LFORPREP: { - int n; - Hash *t; + int jmp = GETARG_S(i); if (ttype(top-1) != LUA_TTABLE) luaD_error(L, "`for' table must be a table"); - t = hvalue(top-1); - n = luaH_nexti(t, -1); - if (n == -1) { /* `empty' loop? */ - top--; /* remove table */ - dojump(pc, i); /* jump to loop end */ - } - else { - Node *node = node(t, n); - top += 3; /* index,key,value */ - setnvalue(top-3, n); /* index */ - setobj(top-2, key(node)); - setobj(top-1, val(node)); - } - break; + top += 3; /* index,key,value */ + setnvalue(top-3, -1); /* initial index */ + setnilvalue(top-2); + setnilvalue(top-1); + pc += -jmp; /* "jump" to loop end (delta is negated here) */ + /* go through */ } case OP_LFORLOOP: { Hash *t = hvalue(top-4);