diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-22 14:44:17 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-22 14:44:17 -0300 |
commit | c85162be276f7bb95416c5ec0ecefd9c24877d67 (patch) | |
tree | e6d55e2b1fa5e7c613f2545f551e877bee33c3e8 | |
parent | bd39db46ed33c09427547c4390aaf2519169de6f (diff) | |
download | lua-c85162be276f7bb95416c5ec0ecefd9c24877d67.tar.gz lua-c85162be276f7bb95416c5ec0ecefd9c24877d67.tar.bz2 lua-c85162be276f7bb95416c5ec0ecefd9c24877d67.zip |
new way to store local-variable information.
-rw-r--r-- | lfunc.c | 23 | ||||
-rw-r--r-- | lgc.c | 7 | ||||
-rw-r--r-- | lobject.h | 10 | ||||
-rw-r--r-- | lparser.c | 63 | ||||
-rw-r--r-- | lparser.h | 7 |
5 files changed, 49 insertions, 61 deletions
@@ -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 | */ |
76 | const char *luaF_getlocalname (const Proto *func, int local_number, int pc) { | 77 | const 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 | ||
@@ -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 | ||
@@ -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 | ||
133 | typedef struct LocVar { | 134 | typedef 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 | ||
@@ -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 | ||
153 | static void luaI_registerlocalvar (LexState *ls, TString *varname, int pc) { | 153 | static 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 | ||
163 | static void new_localvar (LexState *ls, TString *name, int n) { | 161 | static 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 | ||
170 | static void adjustlocalvars (LexState *ls, int nvars) { | 168 | static 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 | ||
180 | static void removelocalvars (LexState *ls, int nvars) { | 175 | static 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) { | |||
270 | static void code_params (LexState *ls, int nparams, int dots) { | 262 | static 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) { | |||
768 | static void block (LexState *ls) { | 759 | static 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 | } |
@@ -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 | ||