aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c158
1 files changed, 86 insertions, 72 deletions
diff --git a/lparser.c b/lparser.c
index 52486e08..1551cda9 100644
--- a/lparser.c
+++ b/lparser.c
@@ -156,13 +156,6 @@ static void init_exp (expdesc *e, expkind k, int i) {
156} 156}
157 157
158 158
159static void init_var (expdesc *e, expkind k, int i) {
160 e->f = e->t = NO_JUMP;
161 e->k = k;
162 e->u.var.idx = i;
163}
164
165
166static void codestring (LexState *ls, expdesc *e, TString *s) { 159static void codestring (LexState *ls, expdesc *e, TString *s) {
167 init_exp(e, VK, luaK_stringK(ls->fs, s)); 160 init_exp(e, VK, luaK_stringK(ls->fs, s));
168} 161}
@@ -177,16 +170,15 @@ static void codename (LexState *ls, expdesc *e) {
177** Register a new local variable in the active 'Proto' (for debug 170** Register a new local variable in the active 'Proto' (for debug
178** information). 171** information).
179*/ 172*/
180static int registerlocalvar (LexState *ls, TString *varname) { 173static int registerlocalvar (lua_State *L, FuncState *fs, TString *varname) {
181 FuncState *fs = ls->fs;
182 Proto *f = fs->f; 174 Proto *f = fs->f;
183 int oldsize = f->sizelocvars; 175 int oldsize = f->sizelocvars;
184 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, 176 luaM_growvector(L, f->locvars, fs->nlocvars, f->sizelocvars,
185 LocVar, SHRT_MAX, "local variables"); 177 LocVar, SHRT_MAX, "local variables");
186 while (oldsize < f->sizelocvars) 178 while (oldsize < f->sizelocvars)
187 f->locvars[oldsize++].varname = NULL; 179 f->locvars[oldsize++].varname = NULL;
188 f->locvars[fs->nlocvars].varname = varname; 180 f->locvars[fs->nlocvars].varname = varname;
189 luaC_objbarrier(ls->L, f, varname); 181 luaC_objbarrier(L, f, varname);
190 return fs->nlocvars++; 182 return fs->nlocvars++;
191} 183}
192 184
@@ -195,18 +187,19 @@ static int registerlocalvar (LexState *ls, TString *varname) {
195** Create a new local variable with the given 'name'. 187** Create a new local variable with the given 'name'.
196*/ 188*/
197static Vardesc *new_localvar (LexState *ls, TString *name) { 189static Vardesc *new_localvar (LexState *ls, TString *name) {
190 lua_State *L = ls->L;
198 FuncState *fs = ls->fs; 191 FuncState *fs = ls->fs;
199 Dyndata *dyd = ls->dyd; 192 Dyndata *dyd = ls->dyd;
200 Vardesc *var; 193 Vardesc *var;
201 int reg = registerlocalvar(ls, name); 194 int reg = registerlocalvar(L, fs, name);
202 checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, 195 checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
203 MAXVARS, "local variables"); 196 MAXVARS, "local variables");
204 luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, 197 luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1,
205 dyd->actvar.size, Vardesc, MAX_INT, "local variables"); 198 dyd->actvar.size, Vardesc, USHRT_MAX, "local variables");
206 var = &dyd->actvar.arr[dyd->actvar.n++]; 199 var = &dyd->actvar.arr[dyd->actvar.n++];
207 var->idx = cast(short, reg); 200 var->pidx = cast(short, reg);
208 var->ro = 0; 201 var->ro = 0;
209 setnilvalue(&var->val); 202 setnilvalue(var);
210 return var; 203 return var;
211} 204}
212 205
@@ -223,50 +216,47 @@ static Vardesc *getlocalvardesc (FuncState *fs, int i) {
223 return &fs->ls->dyd->actvar.arr[fs->firstlocal + i]; 216 return &fs->ls->dyd->actvar.arr[fs->firstlocal + i];
224} 217}
225 218
219
226/* 220/*
227** Get the debug-information entry for current variable 'i'. 221** Get the debug-information entry for current variable 'i'.
228*/ 222*/
229static LocVar *getlocvar (FuncState *fs, int i) { 223static LocVar *localdebuginfo (FuncState *fs, int i) {
230 int idx = getlocalvardesc(fs, i)->idx; 224 int idx = getlocalvardesc(fs, i)->pidx;
231 lua_assert(idx < fs->nlocvars); 225 lua_assert(idx < fs->nlocvars);
232 return &fs->f->locvars[idx]; 226 return &fs->f->locvars[idx];
233} 227}
234 228
235 229
236/* 230static void init_var (FuncState *fs, expdesc *e, int i) {
237** Return the "variable description" (Vardesc) of a given 231 e->f = e->t = NO_JUMP;
238** local variable and update 'fs' to point to the function 232 e->k = VLOCAL;
239** where that variable was defined. Return NULL if expression 233 e->u.var.vidx = i;
240** is neither a local variable nor an upvalue. 234 e->u.var.sidx = getlocalvardesc(fs, i)->sidx;
241*/
242Vardesc *luaY_getvardesc (FuncState **fs, const expdesc *e) {
243 if (e->k == VLOCAL)
244 return getlocalvardesc(*fs, e->u.var.idx);
245 else if (e->k != VUPVAL)
246 return NULL; /* not a local variable */
247 else { /* upvalue: must go up all levels up to the original local */
248 int idx = e->u.var.idx;
249 for (;;) {
250 Upvaldesc *up = &(*fs)->f->upvalues[idx];
251 *fs = (*fs)->prev; /* must look at the previous level */
252 idx = up->idx; /* at this index */
253 if (*fs == NULL) /* no more levels? (can happen only with _ENV) */
254 return NULL;
255 else if (up->instack) /* got to the original level? */
256 return getlocalvardesc(*fs, idx);
257 /* else repeat for previous level */
258 }
259 }
260} 235}
261 236
262 237
263static void check_readonly (LexState *ls, expdesc *e) { 238static void check_readonly (LexState *ls, expdesc *e) {
264 FuncState *fs = ls->fs; 239 FuncState *fs = ls->fs;
265 Vardesc *vardesc = luaY_getvardesc(&fs, e); 240 TString *varname = NULL; /* to be set if variable is const */
266 if (vardesc && vardesc->ro) { /* is variable local and const? */ 241 switch (e->k) {
242 case VLOCAL: {
243 Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx);
244 if (vardesc->ro)
245 varname = fs->f->locvars[vardesc->pidx].varname;
246 break;
247 }
248 case VUPVAL: {
249 Upvaldesc *up = &fs->f->upvalues[e->u.info];
250 if (up->ro)
251 varname = up->name;
252 break;
253 }
254 default:
255 return; /* other cases cannot be read-only */
256 }
257 if (varname) {
267 const char *msg = luaO_pushfstring(ls->L, 258 const char *msg = luaO_pushfstring(ls->L,
268 "attempt to assign to const variable '%s'", 259 "attempt to assign to const variable '%s'", getstr(varname));
269 getstr(fs->f->locvars[vardesc->idx].varname));
270 luaK_semerror(ls, msg); /* error */ 260 luaK_semerror(ls, msg); /* error */
271 } 261 }
272} 262}
@@ -274,13 +264,15 @@ static void check_readonly (LexState *ls, expdesc *e) {
274 264
275/* 265/*
276** Start the scope for the last 'nvars' created variables. 266** Start the scope for the last 'nvars' created variables.
277** (debug info.)
278*/ 267*/
279static void adjustlocalvars (LexState *ls, int nvars) { 268static void adjustlocalvars (LexState *ls, int nvars) {
280 FuncState *fs = ls->fs; 269 FuncState *fs = ls->fs;
281 fs->nactvar = cast_byte(fs->nactvar + nvars); 270 int i;
282 for (; nvars; nvars--) { 271 for (i = 0; i < nvars; i++) {
283 getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc; 272 int varidx = fs->nactvar++;
273 Vardesc *var = getlocalvardesc(fs, varidx);
274 var->sidx = varidx;
275 fs->f->locvars[var->pidx].startpc = fs->pc;
284 } 276 }
285} 277}
286 278
@@ -292,7 +284,7 @@ static void adjustlocalvars (LexState *ls, int nvars) {
292static void removevars (FuncState *fs, int tolevel) { 284static void removevars (FuncState *fs, int tolevel) {
293 fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); 285 fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
294 while (fs->nactvar > tolevel) 286 while (fs->nactvar > tolevel)
295 getlocvar(fs, --fs->nactvar)->endpc = fs->pc; 287 localdebuginfo(fs, --fs->nactvar)->endpc = fs->pc;
296} 288}
297 289
298 290
@@ -310,7 +302,7 @@ static int searchupvalue (FuncState *fs, TString *name) {
310} 302}
311 303
312 304
313static int newupvalue (FuncState *fs, TString *name, expdesc *v) { 305static Upvaldesc *allocupvalue (FuncState *fs) {
314 Proto *f = fs->f; 306 Proto *f = fs->f;
315 int oldsize = f->sizeupvalues; 307 int oldsize = f->sizeupvalues;
316 checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); 308 checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
@@ -318,11 +310,28 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
318 Upvaldesc, MAXUPVAL, "upvalues"); 310 Upvaldesc, MAXUPVAL, "upvalues");
319 while (oldsize < f->sizeupvalues) 311 while (oldsize < f->sizeupvalues)
320 f->upvalues[oldsize++].name = NULL; 312 f->upvalues[oldsize++].name = NULL;
321 f->upvalues[fs->nups].instack = (v->k == VLOCAL); 313 return &f->upvalues[fs->nups++];
322 f->upvalues[fs->nups].idx = cast_byte(v->u.var.idx); 314}
323 f->upvalues[fs->nups].name = name; 315
324 luaC_objbarrier(fs->ls->L, f, name); 316
325 return fs->nups++; 317static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
318 Upvaldesc *up = allocupvalue(fs);
319 FuncState *prev = fs->prev;
320 if (v->k == VLOCAL) {
321 up->instack = 1;
322 up->idx = v->u.var.sidx;
323 up->ro = getlocalvardesc(prev, v->u.var.vidx)->ro;
324 lua_assert(eqstr(name, localdebuginfo(prev, v->u.var.vidx)->varname));
325 }
326 else {
327 up->instack = 0;
328 up->idx = cast_byte(v->u.info);
329 up->ro = prev->f->upvalues[v->u.info].ro;
330 lua_assert(eqstr(name, prev->f->upvalues[v->u.info].name));
331 }
332 up->name = name;
333 luaC_objbarrier(fs->ls->L, fs->f, name);
334 return fs->nups - 1;
326} 335}
327 336
328 337
@@ -333,7 +342,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
333static int searchvar (FuncState *fs, TString *n) { 342static int searchvar (FuncState *fs, TString *n) {
334 int i; 343 int i;
335 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { 344 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
336 if (eqstr(n, getlocvar(fs, i)->varname)) 345 if (eqstr(n, localdebuginfo(fs, i)->varname))
337 return i; 346 return i;
338 } 347 }
339 return -1; /* not found */ 348 return -1; /* not found */
@@ -364,9 +373,9 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
364 else { 373 else {
365 int v = searchvar(fs, n); /* look up locals at current level */ 374 int v = searchvar(fs, n); /* look up locals at current level */
366 if (v >= 0) { /* found? */ 375 if (v >= 0) { /* found? */
367 init_var(var, VLOCAL, v); /* variable is local */ 376 init_var(fs, var, v); /* variable is local */
368 if (!base) 377 if (!base)
369 markupval(fs, v); /* local will be used as an upval */ 378 markupval(fs, var->u.var.sidx); /* local will be used as an upval */
370 } 379 }
371 else { /* not found as local at current level; try upvalues */ 380 else { /* not found as local at current level; try upvalues */
372 int idx = searchupvalue(fs, n); /* try existing upvalues */ 381 int idx = searchupvalue(fs, n); /* try existing upvalues */
@@ -377,7 +386,7 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
377 /* else was LOCAL or UPVAL */ 386 /* else was LOCAL or UPVAL */
378 idx = newupvalue(fs, n, var); /* will be a new upvalue */ 387 idx = newupvalue(fs, n, var); /* will be a new upvalue */
379 } 388 }
380 init_var(var, VUPVAL, idx); /* new or old upvalue */ 389 init_exp(var, VUPVAL, idx); /* new or old upvalue */
381 } 390 }
382 } 391 }
383} 392}
@@ -440,7 +449,7 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
440** local variable. 449** local variable.
441*/ 450*/
442static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { 451static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) {
443 const char *varname = getstr(getlocvar(ls->fs, gt->nactvar)->varname); 452 const char *varname = getstr(localdebuginfo(ls->fs, gt->nactvar)->varname);
444 const char *msg = "<goto %s> at line %d jumps into the scope of local '%s'"; 453 const char *msg = "<goto %s> at line %d jumps into the scope of local '%s'";
445 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname); 454 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname);
446 luaK_semerror(ls, msg); /* raise the error */ 455 luaK_semerror(ls, msg); /* raise the error */
@@ -1259,20 +1268,20 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1259 for (; lh; lh = lh->prev) { /* check all previous assignments */ 1268 for (; lh; lh = lh->prev) { /* check all previous assignments */
1260 if (vkisindexed(lh->v.k)) { /* assignment to table field? */ 1269 if (vkisindexed(lh->v.k)) { /* assignment to table field? */
1261 if (lh->v.k == VINDEXUP) { /* is table an upvalue? */ 1270 if (lh->v.k == VINDEXUP) { /* is table an upvalue? */
1262 if (v->k == VUPVAL && lh->v.u.ind.t == v->u.var.idx) { 1271 if (v->k == VUPVAL && lh->v.u.ind.t == v->u.info) {
1263 conflict = 1; /* table is the upvalue being assigned now */ 1272 conflict = 1; /* table is the upvalue being assigned now */
1264 lh->v.k = VINDEXSTR; 1273 lh->v.k = VINDEXSTR;
1265 lh->v.u.ind.t = extra; /* assignment will use safe copy */ 1274 lh->v.u.ind.t = extra; /* assignment will use safe copy */
1266 } 1275 }
1267 } 1276 }
1268 else { /* table is a register */ 1277 else { /* table is a register */
1269 if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.idx) { 1278 if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.sidx) {
1270 conflict = 1; /* table is the local being assigned now */ 1279 conflict = 1; /* table is the local being assigned now */
1271 lh->v.u.ind.t = extra; /* assignment will use safe copy */ 1280 lh->v.u.ind.t = extra; /* assignment will use safe copy */
1272 } 1281 }
1273 /* is index the local being assigned? */ 1282 /* is index the local being assigned? */
1274 if (lh->v.k == VINDEXED && v->k == VLOCAL && 1283 if (lh->v.k == VINDEXED && v->k == VLOCAL &&
1275 lh->v.u.ind.idx == v->u.var.idx) { 1284 lh->v.u.ind.idx == v->u.var.sidx) {
1276 conflict = 1; 1285 conflict = 1;
1277 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ 1286 lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
1278 } 1287 }
@@ -1281,14 +1290,16 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1281 } 1290 }
1282 if (conflict) { 1291 if (conflict) {
1283 /* copy upvalue/local value to a temporary (in position 'extra') */ 1292 /* copy upvalue/local value to a temporary (in position 'extra') */
1284 OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; 1293 if (v->k == VLOCAL)
1285 luaK_codeABC(fs, op, extra, v->u.var.idx, 0); 1294 luaK_codeABC(fs, OP_MOVE, extra, v->u.var.sidx, 0);
1295 else
1296 luaK_codeABC(fs, OP_GETUPVAL, extra, v->u.info, 0);
1286 luaK_reserveregs(fs, 1); 1297 luaK_reserveregs(fs, 1);
1287 } 1298 }
1288} 1299}
1289 1300
1290/* 1301/*
1291** Parse and compile a mulitple assignment. The first "variable" 1302** Parse and compile a multiple assignment. The first "variable"
1292** (a 'suffixedexp') was already read by the caller. 1303** (a 'suffixedexp') was already read by the caller.
1293** 1304**
1294** assignment -> suffixedexp restassign 1305** assignment -> suffixedexp restassign
@@ -1652,7 +1663,7 @@ static void localfunc (LexState *ls) {
1652 adjustlocalvars(ls, 1); /* enter its scope */ 1663 adjustlocalvars(ls, 1); /* enter its scope */
1653 body(ls, &b, 0, ls->linenumber); /* function created in next register */ 1664 body(ls, &b, 0, ls->linenumber); /* function created in next register */
1654 /* debug information will only see the variable after this point! */ 1665 /* debug information will only see the variable after this point! */
1655 getlocvar(fs, b.u.info)->startpc = fs->pc; 1666 localdebuginfo(fs, b.u.info)->startpc = fs->pc;
1656} 1667}
1657 1668
1658 1669
@@ -1870,11 +1881,14 @@ static void statement (LexState *ls) {
1870*/ 1881*/
1871static void mainfunc (LexState *ls, FuncState *fs) { 1882static void mainfunc (LexState *ls, FuncState *fs) {
1872 BlockCnt bl; 1883 BlockCnt bl;
1873 expdesc v; 1884 Upvaldesc *env;
1874 open_func(ls, fs, &bl); 1885 open_func(ls, fs, &bl);
1875 setvararg(fs, 0); /* main function is always declared vararg */ 1886 setvararg(fs, 0); /* main function is always declared vararg */
1876 init_var(&v, VLOCAL, 0); /* create and... */ 1887 env = allocupvalue(fs); /* ...set environment upvalue */
1877 newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ 1888 env->instack = 1;
1889 env->idx = 0;
1890 env->ro = 0;
1891 env->name = ls->envn;
1878 luaX_next(ls); /* read first token */ 1892 luaX_next(ls); /* read first token */
1879 statlist(ls); /* parse main body */ 1893 statlist(ls); /* parse main body */
1880 check(ls, TK_EOS); 1894 check(ls, TK_EOS);