瀏覽代碼

new way to store local-variable information.

Roberto Ierusalimschy 25 年之前
父節點
當前提交
c85162be27
共有 5 個文件被更改,包括 49 次插入61 次删除
  1. 10 13
      lfunc.c
  2. 3 4
      lgc.c
  3. 6 4
      lobject.h
  4. 27 36
      lparser.c
  5. 3 4
      lparser.h

+ 10 - 13
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; i<f->nlocvars && 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 */
 }
 

+ 3 - 4
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; i<f->nkproto; 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; i<f->nlocvars; i++)  /* mark local-variable names */
+      strmark(f->locvars[i].varname);
   }
 }
 

+ 6 - 4
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;
 
 

+ 27 - 36
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; i<fs->nlocalvar+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;i<nvars;i++)
-    luaI_registerlocalvar(ls, NULL, fs->pc);
-  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");
   }
 }

+ 3 - 4
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;