aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-10-11 17:02:19 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-10-11 17:02:19 -0300
commit916587508c117decb2f4d70677fa06be18803874 (patch)
tree24f930dcb544c9ddb5a15394537b5d7d8e64169e
parenta5382b763c2faa4c47e55ee0e49889b4c47daac4 (diff)
downloadlua-916587508c117decb2f4d70677fa06be18803874.tar.gz
lua-916587508c117decb2f4d70677fa06be18803874.tar.bz2
lua-916587508c117decb2f4d70677fa06be18803874.zip
parser keeps list of active local variables in a single dynamic array,
therefore saving C stack space
-rw-r--r--ldo.c10
-rw-r--r--llex.h3
-rw-r--r--lparser.c80
-rw-r--r--lparser.h14
-rw-r--r--ltests.c3
-rw-r--r--lua.h4
-rw-r--r--luaconf.h9
7 files changed, 76 insertions, 47 deletions
diff --git a/ldo.c b/ldo.c
index d3c9906d..6affe61f 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.67 2009/09/14 14:30:39 roberto Exp roberto $ 2** $Id: ldo.c,v 2.68 2009/09/28 16:32:50 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -563,6 +563,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
563struct SParser { /* data to `f_parser' */ 563struct SParser { /* data to `f_parser' */
564 ZIO *z; 564 ZIO *z;
565 Mbuffer buff; /* buffer to be used by the scanner */ 565 Mbuffer buff; /* buffer to be used by the scanner */
566 Varlist varl; /* list of local variables (to be used by the parser) */
566 const char *name; 567 const char *name;
567}; 568};
568 569
@@ -573,8 +574,9 @@ static void f_parser (lua_State *L, void *ud) {
573 struct SParser *p = cast(struct SParser *, ud); 574 struct SParser *p = cast(struct SParser *, ud);
574 int c = luaZ_lookahead(p->z); 575 int c = luaZ_lookahead(p->z);
575 luaC_checkGC(L); 576 luaC_checkGC(L);
576 tf = (c == LUA_SIGNATURE[0]) ? luaU_undump(L, p->z, &p->buff, p->name) 577 tf = (c == LUA_SIGNATURE[0])
577 : luaY_parser(L, p->z, &p->buff, p->name); 578 ? luaU_undump(L, p->z, &p->buff, p->name)
579 : luaY_parser(L, p->z, &p->buff, &p->varl, p->name);
578 setptvalue2s(L, L->top, tf); 580 setptvalue2s(L, L->top, tf);
579 incr_top(L); 581 incr_top(L);
580 cl = luaF_newLclosure(L, tf->sizeupvalues, hvalue(gt(L))); 582 cl = luaF_newLclosure(L, tf->sizeupvalues, hvalue(gt(L)));
@@ -589,9 +591,11 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
589 struct SParser p; 591 struct SParser p;
590 int status; 592 int status;
591 p.z = z; p.name = name; 593 p.z = z; p.name = name;
594 p.varl.actvar = NULL; p.varl.nactvar = p.varl.actvarsize = 0;
592 luaZ_initbuffer(L, &p.buff); 595 luaZ_initbuffer(L, &p.buff);
593 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); 596 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
594 luaZ_freebuffer(L, &p.buff); 597 luaZ_freebuffer(L, &p.buff);
598 luaM_freearray(L, p.varl.actvar, p.varl.actvarsize);
595 return status; 599 return status;
596} 600}
597 601
diff --git a/llex.h b/llex.h
index 7c7d2746..3228f0e1 100644
--- a/llex.h
+++ b/llex.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.h,v 1.60 2007/05/11 17:28:56 roberto Exp roberto $ 2** $Id: llex.h,v 1.61 2007/10/25 16:45:47 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -58,6 +58,7 @@ typedef struct LexState {
58 struct lua_State *L; 58 struct lua_State *L;
59 ZIO *z; /* input stream */ 59 ZIO *z; /* input stream */
60 Mbuffer *buff; /* buffer for tokens */ 60 Mbuffer *buff; /* buffer for tokens */
61 struct Varlist *varl; /* list of all active local variables */
61 TString *source; /* current source name */ 62 TString *source; /* current source name */
62 char decpoint; /* locale decimal point */ 63 char decpoint; /* locale decimal point */
63} LexState; 64} LexState;
diff --git a/lparser.c b/lparser.c
index 1ab1cc69..a16de740 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.67 2009/09/28 16:32:50 roberto Exp roberto $ 2** $Id: lparser.c,v 2.68 2009/09/30 15:38:37 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -27,9 +27,14 @@
27 27
28 28
29 29
30/* maximum number of local variables per function (must be smaller
31 than 250, due to the bytecode format) */
32#define MAXVARS 200
33
34
30#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) 35#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
31 36
32#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i].idx]) 37
33 38
34#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) 39#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
35 40
@@ -157,15 +162,26 @@ static int registerlocalvar (LexState *ls, TString *varname) {
157} 162}
158 163
159 164
160#define new_localvarliteral(ls,v,n) \ 165#define new_localvarliteral(ls,v) \
161 new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) 166 new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1))
162 167
163 168
164static void new_localvar (LexState *ls, TString *name, int n) { 169static void new_localvar (LexState *ls, TString *name) {
165 FuncState *fs = ls->fs; 170 FuncState *fs = ls->fs;
171 Varlist *vl = ls->varl;
166 int reg = registerlocalvar(ls, name); 172 int reg = registerlocalvar(ls, name);
167 luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); 173 luaY_checklimit(fs, vl->nactvar + 1 - fs->firstlocal,
168 fs->actvar[fs->nactvar+n].idx = cast(unsigned short, reg); 174 MAXVARS, "local variables");
175 luaM_growvector(ls->L, vl->actvar, vl->nactvar + 1,
176 vl->actvarsize, vardesc, MAX_INT, "local variables");
177 vl->actvar[vl->nactvar++].idx = cast(unsigned short, reg);
178}
179
180
181static LocVar *getlocvar (FuncState *fs, int i) {
182 int idx = fs->ls->varl->actvar[fs->firstlocal + i].idx;
183 lua_assert(idx < fs->nlocvars);
184 return &fs->f->locvars[idx];
169} 185}
170 186
171 187
@@ -173,14 +189,15 @@ static void adjustlocalvars (LexState *ls, int nvars) {
173 FuncState *fs = ls->fs; 189 FuncState *fs = ls->fs;
174 fs->nactvar = cast_byte(fs->nactvar + nvars); 190 fs->nactvar = cast_byte(fs->nactvar + nvars);
175 for (; nvars; nvars--) { 191 for (; nvars; nvars--) {
176 getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; 192 getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc;
177 } 193 }
178} 194}
179 195
180 196
181static void removevars (FuncState *fs, int tolevel) { 197static void removevars (FuncState *fs, int tolevel) {
198 fs->ls->varl->nactvar -= (fs->nactvar - tolevel);
182 while (fs->nactvar > tolevel) 199 while (fs->nactvar > tolevel)
183 getlocvar(fs, --fs->nactvar).endpc = fs->pc; 200 getlocvar(fs, --fs->nactvar)->endpc = fs->pc;
184} 201}
185 202
186 203
@@ -212,7 +229,7 @@ static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
212static int searchvar (FuncState *fs, TString *n) { 229static int searchvar (FuncState *fs, TString *n) {
213 int i; 230 int i;
214 for (i=fs->nactvar-1; i >= 0; i--) { 231 for (i=fs->nactvar-1; i >= 0; i--) {
215 if (n == getlocvar(fs, i).varname) 232 if (n == getlocvar(fs, i)->varname)
216 return i; 233 return i;
217 } 234 }
218 return -1; /* not found */ 235 return -1; /* not found */
@@ -350,6 +367,7 @@ static void open_func (LexState *ls, FuncState *fs) {
350 fs->nups = 0; 367 fs->nups = 0;
351 fs->nlocvars = 0; 368 fs->nlocvars = 0;
352 fs->nactvar = 0; 369 fs->nactvar = 0;
370 fs->firstlocal = ls->varl->nactvar;
353 fs->envreg = NO_REG; 371 fs->envreg = NO_REG;
354 fs->bl = NULL; 372 fs->bl = NULL;
355 fs->h = luaH_new(L); 373 fs->h = luaH_new(L);
@@ -392,13 +410,15 @@ static void close_func (LexState *ls) {
392} 410}
393 411
394 412
395Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { 413Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Varlist *varl,
414 const char *name) {
396 struct LexState lexstate; 415 struct LexState lexstate;
397 struct FuncState funcstate; 416 struct FuncState funcstate;
398 TString *tname = luaS_new(L, name); 417 TString *tname = luaS_new(L, name);
399 setsvalue2s(L, L->top, tname); /* protect name */ 418 setsvalue2s(L, L->top, tname); /* protect name */
400 incr_top(L); 419 incr_top(L);
401 lexstate.buff = buff; 420 lexstate.buff = buff;
421 lexstate.varl = varl;
402 luaX_setinput(L, &lexstate, z, tname); 422 luaX_setinput(L, &lexstate, z, tname);
403 open_func(&lexstate, &funcstate); 423 open_func(&lexstate, &funcstate);
404 funcstate.f->is_vararg = 1; /* main func. is always vararg */ 424 funcstate.f->is_vararg = 1; /* main func. is always vararg */
@@ -565,7 +585,8 @@ static void parlist (LexState *ls) {
565 do { 585 do {
566 switch (ls->t.token) { 586 switch (ls->t.token) {
567 case TK_NAME: { /* param -> NAME */ 587 case TK_NAME: { /* param -> NAME */
568 new_localvar(ls, str_checkname(ls), nparams++); 588 new_localvar(ls, str_checkname(ls));
589 nparams++;
569 break; 590 break;
570 } 591 }
571 case TK_DOTS: { /* param -> `...' */ 592 case TK_DOTS: { /* param -> `...' */
@@ -590,7 +611,7 @@ static void body (LexState *ls, expdesc *e, int needself, int line) {
590 new_fs.f->linedefined = line; 611 new_fs.f->linedefined = line;
591 checknext(ls, '('); 612 checknext(ls, '(');
592 if (needself) { 613 if (needself) {
593 new_localvarliteral(ls, "self", 0); 614 new_localvarliteral(ls, "self");
594 adjustlocalvars(ls, 1); 615 adjustlocalvars(ls, 1);
595 } 616 }
596 parlist(ls); 617 parlist(ls);
@@ -1083,10 +1104,10 @@ static void fornum (LexState *ls, TString *varname, int line) {
1083 /* fornum -> NAME = exp1,exp1[,exp1] forbody */ 1104 /* fornum -> NAME = exp1,exp1[,exp1] forbody */
1084 FuncState *fs = ls->fs; 1105 FuncState *fs = ls->fs;
1085 int base = fs->freereg; 1106 int base = fs->freereg;
1086 new_localvarliteral(ls, "(for index)", 0); 1107 new_localvarliteral(ls, "(for index)");
1087 new_localvarliteral(ls, "(for limit)", 1); 1108 new_localvarliteral(ls, "(for limit)");
1088 new_localvarliteral(ls, "(for step)", 2); 1109 new_localvarliteral(ls, "(for step)");
1089 new_localvar(ls, varname, 3); 1110 new_localvar(ls, varname);
1090 checknext(ls, '='); 1111 checknext(ls, '=');
1091 exp1(ls); /* initial value */ 1112 exp1(ls); /* initial value */
1092 checknext(ls, ','); 1113 checknext(ls, ',');
@@ -1105,17 +1126,19 @@ static void forlist (LexState *ls, TString *indexname) {
1105 /* forlist -> NAME {,NAME} IN explist1 forbody */ 1126 /* forlist -> NAME {,NAME} IN explist1 forbody */
1106 FuncState *fs = ls->fs; 1127 FuncState *fs = ls->fs;
1107 expdesc e; 1128 expdesc e;
1108 int nvars = 0; 1129 int nvars = 4; /* gen, state, control, plus at least one declared var */
1109 int line; 1130 int line;
1110 int base = fs->freereg; 1131 int base = fs->freereg;
1111 /* create control variables */ 1132 /* create control variables */
1112 new_localvarliteral(ls, "(for generator)", nvars++); 1133 new_localvarliteral(ls, "(for generator)");
1113 new_localvarliteral(ls, "(for state)", nvars++); 1134 new_localvarliteral(ls, "(for state)");
1114 new_localvarliteral(ls, "(for control)", nvars++); 1135 new_localvarliteral(ls, "(for control)");
1115 /* create declared variables */ 1136 /* create declared variables */
1116 new_localvar(ls, indexname, nvars++); 1137 new_localvar(ls, indexname);
1117 while (testnext(ls, ',')) 1138 while (testnext(ls, ',')) {
1118 new_localvar(ls, str_checkname(ls), nvars++); 1139 new_localvar(ls, str_checkname(ls));
1140 nvars++;
1141 }
1119 checknext(ls, TK_IN); 1142 checknext(ls, TK_IN);
1120 line = ls->linenumber; 1143 line = ls->linenumber;
1121 adjust_assign(ls, 3, explist1(ls, &e), &e); 1144 adjust_assign(ls, 3, explist1(ls, &e), &e);
@@ -1180,14 +1203,14 @@ static void ifstat (LexState *ls, int line) {
1180static void localfunc (LexState *ls) { 1203static void localfunc (LexState *ls) {
1181 expdesc v, b; 1204 expdesc v, b;
1182 FuncState *fs = ls->fs; 1205 FuncState *fs = ls->fs;
1183 new_localvar(ls, str_checkname(ls), 0); 1206 new_localvar(ls, str_checkname(ls));
1184 init_exp(&v, VLOCAL, fs->freereg); 1207 init_exp(&v, VLOCAL, fs->freereg);
1185 luaK_reserveregs(fs, 1); 1208 luaK_reserveregs(fs, 1);
1186 adjustlocalvars(ls, 1); 1209 adjustlocalvars(ls, 1);
1187 body(ls, &b, 0, ls->linenumber); 1210 body(ls, &b, 0, ls->linenumber);
1188 luaK_storevar(fs, &v, &b); 1211 luaK_storevar(fs, &v, &b);
1189 /* debug information will only see the variable after this point! */ 1212 /* debug information will only see the variable after this point! */
1190 getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; 1213 getlocvar(fs, fs->nactvar - 1)->startpc = fs->pc;
1191} 1214}
1192 1215
1193 1216
@@ -1197,7 +1220,8 @@ static void localstat (LexState *ls) {
1197 int nexps; 1220 int nexps;
1198 expdesc e; 1221 expdesc e;
1199 do { 1222 do {
1200 new_localvar(ls, str_checkname(ls), nvars++); 1223 new_localvar(ls, str_checkname(ls));
1224 nvars++;
1201 } while (testnext(ls, ',')); 1225 } while (testnext(ls, ','));
1202 if (testnext(ls, '=')) 1226 if (testnext(ls, '='))
1203 nexps = explist1(ls, &e); 1227 nexps = explist1(ls, &e);
@@ -1243,7 +1267,7 @@ static void instat (LexState *ls, int line) {
1243 BlockCnt bl; 1267 BlockCnt bl;
1244 luaX_next(ls); /* skip IN */ 1268 luaX_next(ls); /* skip IN */
1245 enterblock(fs, &bl, 0); /* scope for environment variable */ 1269 enterblock(fs, &bl, 0); /* scope for environment variable */
1246 new_localvarliteral(ls, "(environment)", 0); 1270 new_localvarliteral(ls, "(environment)");
1247 fs->envreg = exp1(ls); /* new environment */ 1271 fs->envreg = exp1(ls); /* new environment */
1248 adjustlocalvars(ls, 1); 1272 adjustlocalvars(ls, 1);
1249 checknext(ls, TK_DO); 1273 checknext(ls, TK_DO);
diff --git a/lparser.h b/lparser.h
index 850b787d..4fcdc621 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.59 2009/09/28 16:32:50 roberto Exp roberto $ 2** $Id: lparser.h,v 1.60 2009/09/30 15:38:37 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -51,6 +51,14 @@ typedef struct vardesc {
51} vardesc; 51} vardesc;
52 52
53 53
54/* list of all active local variables */
55typedef struct Varlist {
56 vardesc *actvar;
57 int nactvar;
58 int actvarsize;
59} Varlist;
60
61
54struct BlockCnt; /* defined in lparser.c */ 62struct BlockCnt; /* defined in lparser.c */
55 63
56 64
@@ -68,16 +76,16 @@ typedef struct FuncState {
68 int freereg; /* first free register */ 76 int freereg; /* first free register */
69 int nk; /* number of elements in `k' */ 77 int nk; /* number of elements in `k' */
70 int np; /* number of elements in `p' */ 78 int np; /* number of elements in `p' */
79 int firstlocal; /* index of first local var of this function */
71 short nlocvars; /* number of elements in `locvars' */ 80 short nlocvars; /* number of elements in `locvars' */
72 lu_byte nactvar; /* number of active local variables */ 81 lu_byte nactvar; /* number of active local variables */
73 lu_byte nups; /* number of upvalues */ 82 lu_byte nups; /* number of upvalues */
74 lu_byte envreg; /* register holding current lexical environment */ 83 lu_byte envreg; /* register holding current lexical environment */
75 vardesc actvar[LUAI_MAXVARS]; /* stack of active variables */
76} FuncState; 84} FuncState;
77 85
78 86
79LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 87LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
80 const char *name); 88 Varlist *varl, const char *name);
81 89
82 90
83#endif 91#endif
diff --git a/ltests.c b/ltests.c
index 40a7f965..4fb7a4d2 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.74 2009/09/30 20:49:25 roberto Exp roberto $ 2** $Id: ltests.c,v 2.75 2009/10/05 16:44:33 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -491,7 +491,6 @@ static int get_limits (lua_State *L) {
491 lua_createtable(L, 0, 5); 491 lua_createtable(L, 0, 5);
492 setnameval(L, "BITS_INT", LUAI_BITSINT); 492 setnameval(L, "BITS_INT", LUAI_BITSINT);
493 setnameval(L, "LFPF", LFIELDS_PER_FLUSH); 493 setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
494 setnameval(L, "MAXVARS", LUAI_MAXVARS);
495 setnameval(L, "MAXSTACK", MAXSTACK); 494 setnameval(L, "MAXSTACK", MAXSTACK);
496 setnameval(L, "NUM_OPCODES", NUM_OPCODES); 495 setnameval(L, "NUM_OPCODES", NUM_OPCODES);
497 return 1; 496 return 1;
diff --git a/lua.h b/lua.h
index 478374e3..7492f4a5 100644
--- a/lua.h
+++ b/lua.h
@@ -1,6 +1,6 @@
1/* 1/*
2** $Id: lua.h,v 1.244 2009/09/21 12:09:52 roberto Exp roberto $ 2** $Id: lua.h,v 1.245 2009/10/05 16:44:33 roberto Exp roberto $
3** Lua - An Extensible Extension Language 3** Lua - A Scripting Language
4** Lua.org, PUC-Rio, Brazil (http://www.lua.org) 4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
5** See Copyright Notice at the end of this file 5** See Copyright Notice at the end of this file
6*/ 6*/
diff --git a/luaconf.h b/luaconf.h
index c18681dc..f9cd7283 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: luaconf.h,v 1.109 2009/08/25 19:58:08 roberto Exp roberto $ 2** $Id: luaconf.h,v 1.110 2009/09/28 16:32:50 roberto Exp roberto $
3** Configuration file for Lua 3** Configuration file for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -455,13 +455,6 @@
455 455
456 456
457/* 457/*
458@@ LUAI_MAXVARS is the maximum number of local variables per function
459@* (must be smaller than 250).
460*/
461#define LUAI_MAXVARS 200
462
463
464/*
465@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. 458@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
466*/ 459*/
467#define LUAL_BUFFERSIZE BUFSIZ 460#define LUAL_BUFFERSIZE BUFSIZ