From c85162be276f7bb95416c5ec0ecefd9c24877d67 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 22 Aug 2000 14:44:17 -0300 Subject: [PATCH] new way to store local-variable information. --- lfunc.c | 23 +++++++++----------- lgc.c | 7 +++---- lobject.h | 10 +++++---- lparser.c | 63 ++++++++++++++++++++++++------------------------------- lparser.h | 7 +++---- 5 files changed, 49 insertions(+), 61 deletions(-) diff --git a/lfunc.c b/lfunc.c index 9e8d3a67..579d5e6a 100644 --- a/lfunc.c +++ b/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 1.28 2000/08/08 20:42:07 roberto Exp roberto $ +** $Id: lfunc.c,v 1.29 2000/08/09 19:16:57 roberto Exp roberto $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -43,6 +43,7 @@ Proto *luaF_newproto (lua_State *L) { f->kproto = NULL; f->nkproto = 0; f->locvars = NULL; + f->nlocvars = 0; f->next = L->rootproto; L->rootproto = f; f->marked = 0; @@ -73,19 +74,15 @@ void luaF_freeclosure (lua_State *L, Closure *c) { ** Look for n-th local variable at line `line' in function `func'. ** Returns NULL if not found. */ -const char *luaF_getlocalname (const Proto *func, int local_number, int pc) { - int count = 0; - const char *varname = NULL; - LocVar *lv = func->locvars; - for (; lv->pc != -1 && lv->pc <= pc; lv++) { - if (lv->varname) { /* register */ - if (++count == local_number) - varname = lv->varname->str; +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; inlocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return f->locvars[i].varname->str; } - else /* unregister */ - if (--count < local_number) - varname = NULL; } - return varname; + return NULL; /* not found */ } diff --git a/lgc.c b/lgc.c index 0548fa04..1e26ed51 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.61 2000/08/08 20:42:07 roberto Exp roberto $ +** $Id: lgc.c,v 1.62 2000/08/09 19:16:57 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -42,9 +42,8 @@ static void protomark (Proto *f) { strmark(f->kstr[i]); for (i=0; inkproto; i++) protomark(f->kproto[i]); - for (i=0; f->locvars[i].pc != -1; i++) /* mark local-variable names */ - if (f->locvars[i].varname) - strmark(f->locvars[i].varname); + for (i=0; inlocvars; i++) /* mark local-variable names */ + strmark(f->locvars[i].varname); } } diff --git a/lobject.h b/lobject.h index beb5745d..f2d60760 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 1.72 2000/08/08 18:26:05 roberto Exp roberto $ +** $Id: lobject.h,v 1.73 2000/08/21 14:34:43 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -124,15 +124,17 @@ typedef struct Proto { int marked; /* debug information */ int *lineinfo; /* map from opcodes to source lines */ + int nlocvars; + struct LocVar *locvars; /* information about local variables */ int lineDefined; TString *source; - struct LocVar *locvars; /* ends with line = -1 */ } Proto; typedef struct LocVar { - TString *varname; /* NULL signals end of scope */ - int pc; + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ } LocVar; diff --git a/lparser.c b/lparser.c index 1ae80cfb..673302df 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.108 2000/08/14 17:46:27 roberto Exp roberto $ +** $Id: lparser.c,v 1.109 2000/08/15 13:18:28 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -150,40 +150,32 @@ static int checkname (LexState *ls) { } -static void luaI_registerlocalvar (LexState *ls, TString *varname, int pc) { - FuncState *fs = ls->fs; - Proto *f = fs->f; - luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT); - f->locvars[fs->nvars].varname = varname; - f->locvars[fs->nvars].pc = pc; - fs->nvars++; +static int luaI_registerlocalvar (LexState *ls, TString *varname) { + Proto *f = ls->fs->f; + luaM_growvector(ls->L, f->locvars, f->nlocvars, 1, LocVar, "", MAX_INT); + f->locvars[f->nlocvars].varname = varname; + return f->nlocvars++; } static void new_localvar (LexState *ls, TString *name, int n) { FuncState *fs = ls->fs; - luaX_checklimit(ls, fs->nlocalvar+n+1, MAXLOCALS, "local variables"); - fs->localvar[fs->nlocalvar+n] = name; + luaX_checklimit(ls, fs->nactloc+n+1, MAXLOCALS, "local variables"); + fs->actloc[fs->nactloc+n] = luaI_registerlocalvar(ls, name); } static void adjustlocalvars (LexState *ls, int nvars) { FuncState *fs = ls->fs; - int i; - /* `pc' is first opcode where variable is already active */ - for (i=fs->nlocalvar; inlocalvar+nvars; i++) - luaI_registerlocalvar(ls, fs->localvar[i], fs->pc); - fs->nlocalvar += nvars; + while (nvars--) + fs->f->locvars[fs->actloc[fs->nactloc++]].startpc = fs->pc; } static void removelocalvars (LexState *ls, int nvars) { FuncState *fs = ls->fs; - int i; - /* `pc' is first opcode where variable is already dead */ - for (i=0;ipc); - fs->nlocalvar -= nvars; + while (nvars--) + fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc; } @@ -197,8 +189,8 @@ static int search_local (LexState *ls, TString *n, expdesc *var) { int level = 0; for (fs=ls->fs; fs; fs=fs->prev) { int i; - for (i=fs->nlocalvar-1; i >= 0; i--) { - if (n == fs->localvar[i]) { + for (i=fs->nactloc-1; i >= 0; i--) { + if (n == fs->f->locvars[fs->actloc[i]].varname) { var->k = VLOCAL; var->u.index = i; return level; @@ -270,14 +262,14 @@ static void adjust_mult_assign (LexState *ls, int nvars, int nexps) { static void code_params (LexState *ls, int nparams, int dots) { FuncState *fs = ls->fs; adjustlocalvars(ls, nparams); - luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); - fs->f->numparams = fs->nlocalvar; /* `self' could be there already */ + luaX_checklimit(ls, fs->nactloc, MAXPARAMS, "parameters"); + fs->f->numparams = fs->nactloc; /* `self' could be there already */ fs->f->is_vararg = dots; if (dots) { new_localvarstr(ls, "arg", 0); adjustlocalvars(ls, 1); } - luaK_deltastack(fs, fs->nlocalvar); /* count parameters in the stack */ + luaK_deltastack(fs, fs->nactloc); /* count parameters in the stack */ } @@ -316,7 +308,7 @@ static void open_func (LexState *ls, FuncState *fs) { fs->L = ls->L; ls->fs = fs; fs->stacklevel = 0; - fs->nlocalvar = 0; + fs->nactloc = 0; fs->nupvalues = 0; fs->bl = NULL; fs->f = f; @@ -330,7 +322,6 @@ static void open_func (LexState *ls, FuncState *fs) { f->maxstacksize = 0; f->numparams = 0; /* default for main chunk */ f->is_vararg = 0; /* default for main chunk */ - fs->nvars = 0; } @@ -344,8 +335,8 @@ static void close_func (LexState *ls) { luaM_reallocvector(L, f->kstr, f->nkstr, TString *); luaM_reallocvector(L, f->knum, f->nknum, Number); luaM_reallocvector(L, f->kproto, f->nkproto, Proto *); - luaI_registerlocalvar(ls, NULL, -1); /* flag end of vector */ - luaM_reallocvector(L, f->locvars, fs->nvars, LocVar); + removelocalvars(ls, fs->nactloc); + luaM_reallocvector(L, f->locvars, f->nlocvars, LocVar); luaM_reallocvector(L, f->lineinfo, fs->nlineinfo+1, int); f->lineinfo[fs->nlineinfo] = MAX_INT; /* end flag */ ls->fs = fs->prev; @@ -370,7 +361,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) { /*============================================================*/ -/* GRAMAR RULES */ +/* GRAMMAR RULES */ /*============================================================*/ @@ -768,10 +759,10 @@ static int block_follow (int token) { static void block (LexState *ls) { /* block -> chunk */ FuncState *fs = ls->fs; - int nlocalvar = fs->nlocalvar; + int nactloc = fs->nactloc; chunk(ls); - luaK_adjuststack(fs, fs->nlocalvar - nlocalvar); /* remove local variables */ - removelocalvars(ls, fs->nlocalvar - nlocalvar); + luaK_adjuststack(fs, fs->nactloc - nactloc); /* remove local variables */ + removelocalvars(ls, fs->nactloc - nactloc); } @@ -1009,8 +1000,8 @@ static void retstat (LexState *ls) { next(ls); /* skip RETURN */ if (!block_follow(ls->t.token)) explist1(ls); /* optional return values */ - luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar); - fs->stacklevel = fs->nlocalvar; /* removes all temp values */ + luaK_code1(fs, OP_RETURN, ls->fs->nactloc); + fs->stacklevel = fs->nactloc; /* removes all temp values */ } @@ -1127,7 +1118,7 @@ static void chunk (LexState *ls) { while (!islast && !block_follow(ls->t.token)) { islast = stat(ls); optional(ls, ';'); - LUA_ASSERT(ls->fs->stacklevel == ls->fs->nlocalvar, + LUA_ASSERT(ls->fs->stacklevel == ls->fs->nactloc, "stack size != # local vars"); } } diff --git a/lparser.h b/lparser.h index 258d6fe7..8cfa3180 100644 --- a/lparser.h +++ b/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.21 2000/08/08 18:26:05 roberto Exp roberto $ +** $Id: lparser.h,v 1.22 2000/08/08 20:42:07 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -45,14 +45,13 @@ typedef struct FuncState { int lasttarget; /* `pc' of last `jump target' */ int jlt; /* list of jumps to `lasttarged' */ int stacklevel; /* number of values on activation register */ - int nlocalvar; /* number of active local variables */ + int nactloc; /* number of active local variables */ int nupvalues; /* number of upvalues */ - int nvars; /* number of entries in f->locvars */ int lastline; /* line where last `lineinfo' was generated */ int nlineinfo; /* index of next `lineinfo' to be generated */ struct Breaklabel *bl; /* chain of breakable blocks */ expdesc upvalues[MAXUPVALUES]; /* upvalues */ - TString *localvar[MAXLOCALS]; /* store local variable names */ + int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */ } FuncState;