summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-08-22 14:44:17 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-08-22 14:44:17 -0300
commitc85162be276f7bb95416c5ec0ecefd9c24877d67 (patch)
treee6d55e2b1fa5e7c613f2545f551e877bee33c3e8
parentbd39db46ed33c09427547c4390aaf2519169de6f (diff)
downloadlua-c85162be276f7bb95416c5ec0ecefd9c24877d67.tar.gz
lua-c85162be276f7bb95416c5ec0ecefd9c24877d67.tar.bz2
lua-c85162be276f7bb95416c5ec0ecefd9c24877d67.zip
new way to store local-variable information.
-rw-r--r--lfunc.c23
-rw-r--r--lgc.c7
-rw-r--r--lobject.h10
-rw-r--r--lparser.c63
-rw-r--r--lparser.h7
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 @@
1/* 1/*
2** $Id: lfunc.c,v 1.28 2000/08/08 20:42:07 roberto Exp roberto $ 2** $Id: lfunc.c,v 1.29 2000/08/09 19:16:57 roberto Exp roberto $
3** Auxiliary functions to manipulate prototypes and closures 3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -43,6 +43,7 @@ Proto *luaF_newproto (lua_State *L) {
43 f->kproto = NULL; 43 f->kproto = NULL;
44 f->nkproto = 0; 44 f->nkproto = 0;
45 f->locvars = NULL; 45 f->locvars = NULL;
46 f->nlocvars = 0;
46 f->next = L->rootproto; 47 f->next = L->rootproto;
47 L->rootproto = f; 48 L->rootproto = f;
48 f->marked = 0; 49 f->marked = 0;
@@ -73,19 +74,15 @@ void luaF_freeclosure (lua_State *L, Closure *c) {
73** Look for n-th local variable at line `line' in function `func'. 74** Look for n-th local variable at line `line' in function `func'.
74** Returns NULL if not found. 75** Returns NULL if not found.
75*/ 76*/
76const char *luaF_getlocalname (const Proto *func, int local_number, int pc) { 77const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
77 int count = 0; 78 int i;
78 const char *varname = NULL; 79 for (i = 0; i<f->nlocvars && f->locvars[i].startpc <= pc; i++) {
79 LocVar *lv = func->locvars; 80 if (pc < f->locvars[i].endpc) { /* is variable active? */
80 for (; lv->pc != -1 && lv->pc <= pc; lv++) { 81 local_number--;
81 if (lv->varname) { /* register */ 82 if (local_number == 0)
82 if (++count == local_number) 83 return f->locvars[i].varname->str;
83 varname = lv->varname->str;
84 } 84 }
85 else /* unregister */
86 if (--count < local_number)
87 varname = NULL;
88 } 85 }
89 return varname; 86 return NULL; /* not found */
90} 87}
91 88
diff --git a/lgc.c b/lgc.c
index 0548fa04..1e26ed51 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.61 2000/08/08 20:42:07 roberto Exp roberto $ 2** $Id: lgc.c,v 1.62 2000/08/09 19:16:57 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -42,9 +42,8 @@ static void protomark (Proto *f) {
42 strmark(f->kstr[i]); 42 strmark(f->kstr[i]);
43 for (i=0; i<f->nkproto; i++) 43 for (i=0; i<f->nkproto; i++)
44 protomark(f->kproto[i]); 44 protomark(f->kproto[i]);
45 for (i=0; f->locvars[i].pc != -1; i++) /* mark local-variable names */ 45 for (i=0; i<f->nlocvars; i++) /* mark local-variable names */
46 if (f->locvars[i].varname) 46 strmark(f->locvars[i].varname);
47 strmark(f->locvars[i].varname);
48 } 47 }
49} 48}
50 49
diff --git a/lobject.h b/lobject.h
index beb5745d..f2d60760 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.72 2000/08/08 18:26:05 roberto Exp roberto $ 2** $Id: lobject.h,v 1.73 2000/08/21 14:34:43 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -124,15 +124,17 @@ typedef struct Proto {
124 int marked; 124 int marked;
125 /* debug information */ 125 /* debug information */
126 int *lineinfo; /* map from opcodes to source lines */ 126 int *lineinfo; /* map from opcodes to source lines */
127 int nlocvars;
128 struct LocVar *locvars; /* information about local variables */
127 int lineDefined; 129 int lineDefined;
128 TString *source; 130 TString *source;
129 struct LocVar *locvars; /* ends with line = -1 */
130} Proto; 131} Proto;
131 132
132 133
133typedef struct LocVar { 134typedef struct LocVar {
134 TString *varname; /* NULL signals end of scope */ 135 TString *varname;
135 int pc; 136 int startpc; /* first point where variable is active */
137 int endpc; /* first point where variable is dead */
136} LocVar; 138} LocVar;
137 139
138 140
diff --git a/lparser.c b/lparser.c
index 1ae80cfb..673302df 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.108 2000/08/14 17:46:27 roberto Exp roberto $ 2** $Id: lparser.c,v 1.109 2000/08/15 13:18:28 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -150,40 +150,32 @@ static int checkname (LexState *ls) {
150} 150}
151 151
152 152
153static void luaI_registerlocalvar (LexState *ls, TString *varname, int pc) { 153static int luaI_registerlocalvar (LexState *ls, TString *varname) {
154 FuncState *fs = ls->fs; 154 Proto *f = ls->fs->f;
155 Proto *f = fs->f; 155 luaM_growvector(ls->L, f->locvars, f->nlocvars, 1, LocVar, "", MAX_INT);
156 luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT); 156 f->locvars[f->nlocvars].varname = varname;
157 f->locvars[fs->nvars].varname = varname; 157 return f->nlocvars++;
158 f->locvars[fs->nvars].pc = pc;
159 fs->nvars++;
160} 158}
161 159
162 160
163static void new_localvar (LexState *ls, TString *name, int n) { 161static void new_localvar (LexState *ls, TString *name, int n) {
164 FuncState *fs = ls->fs; 162 FuncState *fs = ls->fs;
165 luaX_checklimit(ls, fs->nlocalvar+n+1, MAXLOCALS, "local variables"); 163 luaX_checklimit(ls, fs->nactloc+n+1, MAXLOCALS, "local variables");
166 fs->localvar[fs->nlocalvar+n] = name; 164 fs->actloc[fs->nactloc+n] = luaI_registerlocalvar(ls, name);
167} 165}
168 166
169 167
170static void adjustlocalvars (LexState *ls, int nvars) { 168static void adjustlocalvars (LexState *ls, int nvars) {
171 FuncState *fs = ls->fs; 169 FuncState *fs = ls->fs;
172 int i; 170 while (nvars--)
173 /* `pc' is first opcode where variable is already active */ 171 fs->f->locvars[fs->actloc[fs->nactloc++]].startpc = fs->pc;
174 for (i=fs->nlocalvar; i<fs->nlocalvar+nvars; i++)
175 luaI_registerlocalvar(ls, fs->localvar[i], fs->pc);
176 fs->nlocalvar += nvars;
177} 172}
178 173
179 174
180static void removelocalvars (LexState *ls, int nvars) { 175static void removelocalvars (LexState *ls, int nvars) {
181 FuncState *fs = ls->fs; 176 FuncState *fs = ls->fs;
182 int i; 177 while (nvars--)
183 /* `pc' is first opcode where variable is already dead */ 178 fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc;
184 for (i=0;i<nvars;i++)
185 luaI_registerlocalvar(ls, NULL, fs->pc);
186 fs->nlocalvar -= nvars;
187} 179}
188 180
189 181
@@ -197,8 +189,8 @@ static int search_local (LexState *ls, TString *n, expdesc *var) {
197 int level = 0; 189 int level = 0;
198 for (fs=ls->fs; fs; fs=fs->prev) { 190 for (fs=ls->fs; fs; fs=fs->prev) {
199 int i; 191 int i;
200 for (i=fs->nlocalvar-1; i >= 0; i--) { 192 for (i=fs->nactloc-1; i >= 0; i--) {
201 if (n == fs->localvar[i]) { 193 if (n == fs->f->locvars[fs->actloc[i]].varname) {
202 var->k = VLOCAL; 194 var->k = VLOCAL;
203 var->u.index = i; 195 var->u.index = i;
204 return level; 196 return level;
@@ -270,14 +262,14 @@ static void adjust_mult_assign (LexState *ls, int nvars, int nexps) {
270static void code_params (LexState *ls, int nparams, int dots) { 262static void code_params (LexState *ls, int nparams, int dots) {
271 FuncState *fs = ls->fs; 263 FuncState *fs = ls->fs;
272 adjustlocalvars(ls, nparams); 264 adjustlocalvars(ls, nparams);
273 luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); 265 luaX_checklimit(ls, fs->nactloc, MAXPARAMS, "parameters");
274 fs->f->numparams = fs->nlocalvar; /* `self' could be there already */ 266 fs->f->numparams = fs->nactloc; /* `self' could be there already */
275 fs->f->is_vararg = dots; 267 fs->f->is_vararg = dots;
276 if (dots) { 268 if (dots) {
277 new_localvarstr(ls, "arg", 0); 269 new_localvarstr(ls, "arg", 0);
278 adjustlocalvars(ls, 1); 270 adjustlocalvars(ls, 1);
279 } 271 }
280 luaK_deltastack(fs, fs->nlocalvar); /* count parameters in the stack */ 272 luaK_deltastack(fs, fs->nactloc); /* count parameters in the stack */
281} 273}
282 274
283 275
@@ -316,7 +308,7 @@ static void open_func (LexState *ls, FuncState *fs) {
316 fs->L = ls->L; 308 fs->L = ls->L;
317 ls->fs = fs; 309 ls->fs = fs;
318 fs->stacklevel = 0; 310 fs->stacklevel = 0;
319 fs->nlocalvar = 0; 311 fs->nactloc = 0;
320 fs->nupvalues = 0; 312 fs->nupvalues = 0;
321 fs->bl = NULL; 313 fs->bl = NULL;
322 fs->f = f; 314 fs->f = f;
@@ -330,7 +322,6 @@ static void open_func (LexState *ls, FuncState *fs) {
330 f->maxstacksize = 0; 322 f->maxstacksize = 0;
331 f->numparams = 0; /* default for main chunk */ 323 f->numparams = 0; /* default for main chunk */
332 f->is_vararg = 0; /* default for main chunk */ 324 f->is_vararg = 0; /* default for main chunk */
333 fs->nvars = 0;
334} 325}
335 326
336 327
@@ -344,8 +335,8 @@ static void close_func (LexState *ls) {
344 luaM_reallocvector(L, f->kstr, f->nkstr, TString *); 335 luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
345 luaM_reallocvector(L, f->knum, f->nknum, Number); 336 luaM_reallocvector(L, f->knum, f->nknum, Number);
346 luaM_reallocvector(L, f->kproto, f->nkproto, Proto *); 337 luaM_reallocvector(L, f->kproto, f->nkproto, Proto *);
347 luaI_registerlocalvar(ls, NULL, -1); /* flag end of vector */ 338 removelocalvars(ls, fs->nactloc);
348 luaM_reallocvector(L, f->locvars, fs->nvars, LocVar); 339 luaM_reallocvector(L, f->locvars, f->nlocvars, LocVar);
349 luaM_reallocvector(L, f->lineinfo, fs->nlineinfo+1, int); 340 luaM_reallocvector(L, f->lineinfo, fs->nlineinfo+1, int);
350 f->lineinfo[fs->nlineinfo] = MAX_INT; /* end flag */ 341 f->lineinfo[fs->nlineinfo] = MAX_INT; /* end flag */
351 ls->fs = fs->prev; 342 ls->fs = fs->prev;
@@ -370,7 +361,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) {
370 361
371 362
372/*============================================================*/ 363/*============================================================*/
373/* GRAMAR RULES */ 364/* GRAMMAR RULES */
374/*============================================================*/ 365/*============================================================*/
375 366
376 367
@@ -768,10 +759,10 @@ static int block_follow (int token) {
768static void block (LexState *ls) { 759static void block (LexState *ls) {
769 /* block -> chunk */ 760 /* block -> chunk */
770 FuncState *fs = ls->fs; 761 FuncState *fs = ls->fs;
771 int nlocalvar = fs->nlocalvar; 762 int nactloc = fs->nactloc;
772 chunk(ls); 763 chunk(ls);
773 luaK_adjuststack(fs, fs->nlocalvar - nlocalvar); /* remove local variables */ 764 luaK_adjuststack(fs, fs->nactloc - nactloc); /* remove local variables */
774 removelocalvars(ls, fs->nlocalvar - nlocalvar); 765 removelocalvars(ls, fs->nactloc - nactloc);
775} 766}
776 767
777 768
@@ -1009,8 +1000,8 @@ static void retstat (LexState *ls) {
1009 next(ls); /* skip RETURN */ 1000 next(ls); /* skip RETURN */
1010 if (!block_follow(ls->t.token)) 1001 if (!block_follow(ls->t.token))
1011 explist1(ls); /* optional return values */ 1002 explist1(ls); /* optional return values */
1012 luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar); 1003 luaK_code1(fs, OP_RETURN, ls->fs->nactloc);
1013 fs->stacklevel = fs->nlocalvar; /* removes all temp values */ 1004 fs->stacklevel = fs->nactloc; /* removes all temp values */
1014} 1005}
1015 1006
1016 1007
@@ -1127,7 +1118,7 @@ static void chunk (LexState *ls) {
1127 while (!islast && !block_follow(ls->t.token)) { 1118 while (!islast && !block_follow(ls->t.token)) {
1128 islast = stat(ls); 1119 islast = stat(ls);
1129 optional(ls, ';'); 1120 optional(ls, ';');
1130 LUA_ASSERT(ls->fs->stacklevel == ls->fs->nlocalvar, 1121 LUA_ASSERT(ls->fs->stacklevel == ls->fs->nactloc,
1131 "stack size != # local vars"); 1122 "stack size != # local vars");
1132 } 1123 }
1133} 1124}
diff --git a/lparser.h b/lparser.h
index 258d6fe7..8cfa3180 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.21 2000/08/08 18:26:05 roberto Exp roberto $ 2** $Id: lparser.h,v 1.22 2000/08/08 20:42:07 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -45,14 +45,13 @@ typedef struct FuncState {
45 int lasttarget; /* `pc' of last `jump target' */ 45 int lasttarget; /* `pc' of last `jump target' */
46 int jlt; /* list of jumps to `lasttarged' */ 46 int jlt; /* list of jumps to `lasttarged' */
47 int stacklevel; /* number of values on activation register */ 47 int stacklevel; /* number of values on activation register */
48 int nlocalvar; /* number of active local variables */ 48 int nactloc; /* number of active local variables */
49 int nupvalues; /* number of upvalues */ 49 int nupvalues; /* number of upvalues */
50 int nvars; /* number of entries in f->locvars */
51 int lastline; /* line where last `lineinfo' was generated */ 50 int lastline; /* line where last `lineinfo' was generated */
52 int nlineinfo; /* index of next `lineinfo' to be generated */ 51 int nlineinfo; /* index of next `lineinfo' to be generated */
53 struct Breaklabel *bl; /* chain of breakable blocks */ 52 struct Breaklabel *bl; /* chain of breakable blocks */
54 expdesc upvalues[MAXUPVALUES]; /* upvalues */ 53 expdesc upvalues[MAXUPVALUES]; /* upvalues */
55 TString *localvar[MAXLOCALS]; /* store local variable names */ 54 int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */
56} FuncState; 55} FuncState;
57 56
58 57