diff options
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 64 |
1 files changed, 36 insertions, 28 deletions
@@ -212,27 +212,28 @@ static int new_localvar (LexState *ls, TString *name) { | |||
212 | 212 | ||
213 | 213 | ||
214 | /* | 214 | /* |
215 | ** Return the "variable description" (Vardesc) of a given | 215 | ** Return the "variable description" (Vardesc) of a given variable. |
216 | ** variable | 216 | ** (Unless noted otherwise, all variables are referred to by their |
217 | ** compiler indices.) | ||
217 | */ | 218 | */ |
218 | static Vardesc *getlocalvardesc (FuncState *fs, int i) { | 219 | static Vardesc *getlocalvardesc (FuncState *fs, int vidx) { |
219 | return &fs->ls->dyd->actvar.arr[fs->firstlocal + i]; | 220 | return &fs->ls->dyd->actvar.arr[fs->firstlocal + vidx]; |
220 | } | 221 | } |
221 | 222 | ||
222 | 223 | ||
223 | /* | 224 | /* |
224 | ** Convert 'nvar' (number of active variables at some point) to | 225 | ** Convert 'nvar', a compiler index level, to it corresponding |
225 | ** number of variables in the stack at that point. | 226 | ** stack index level. For that, search for the highest variable |
227 | ** below that level that is in the stack and uses its stack | ||
228 | ** index ('sidx'). | ||
226 | */ | 229 | */ |
227 | static int stacklevel (FuncState *fs, int nvar) { | 230 | static int stacklevel (FuncState *fs, int nvar) { |
228 | while (nvar > 0) { | 231 | while (nvar-- > 0) { |
229 | Vardesc *vd = getlocalvardesc(fs, nvar - 1); | 232 | Vardesc *vd = getlocalvardesc(fs, nvar); /* get variable */ |
230 | if (vd->vd.kind != RDKCTC) /* is in the stack? */ | 233 | if (vd->vd.kind != RDKCTC) /* is in the stack? */ |
231 | return vd->vd.sidx + 1; | 234 | return vd->vd.sidx + 1; |
232 | else | ||
233 | nvar--; /* try previous variable */ | ||
234 | } | 235 | } |
235 | return 0; /* no variables */ | 236 | return 0; /* no variables in the stack */ |
236 | } | 237 | } |
237 | 238 | ||
238 | 239 | ||
@@ -245,10 +246,10 @@ int luaY_nvarstack (FuncState *fs) { | |||
245 | 246 | ||
246 | 247 | ||
247 | /* | 248 | /* |
248 | ** Get the debug-information entry for current variable 'i'. | 249 | ** Get the debug-information entry for current variable 'vidx'. |
249 | */ | 250 | */ |
250 | static LocVar *localdebuginfo (FuncState *fs, int i) { | 251 | static LocVar *localdebuginfo (FuncState *fs, int vidx) { |
251 | Vardesc *vd = getlocalvardesc(fs, i); | 252 | Vardesc *vd = getlocalvardesc(fs, vidx); |
252 | if (vd->vd.kind == RDKCTC) | 253 | if (vd->vd.kind == RDKCTC) |
253 | return NULL; /* no debug info. for constants */ | 254 | return NULL; /* no debug info. for constants */ |
254 | else { | 255 | else { |
@@ -259,14 +260,20 @@ static LocVar *localdebuginfo (FuncState *fs, int i) { | |||
259 | } | 260 | } |
260 | 261 | ||
261 | 262 | ||
262 | static void init_var (FuncState *fs, expdesc *e, int i) { | 263 | /* |
264 | ** Create an expression representing variable 'vidx' | ||
265 | */ | ||
266 | static void init_var (FuncState *fs, expdesc *e, int vidx) { | ||
263 | e->f = e->t = NO_JUMP; | 267 | e->f = e->t = NO_JUMP; |
264 | e->k = VLOCAL; | 268 | e->k = VLOCAL; |
265 | e->u.var.vidx = i; | 269 | e->u.var.vidx = vidx; |
266 | e->u.var.sidx = getlocalvardesc(fs, i)->vd.sidx; | 270 | e->u.var.sidx = getlocalvardesc(fs, vidx)->vd.sidx; |
267 | } | 271 | } |
268 | 272 | ||
269 | 273 | ||
274 | /* | ||
275 | ** Raises an error if variable described by 'e' is read only | ||
276 | */ | ||
270 | static void check_readonly (LexState *ls, expdesc *e) { | 277 | static void check_readonly (LexState *ls, expdesc *e) { |
271 | FuncState *fs = ls->fs; | 278 | FuncState *fs = ls->fs; |
272 | TString *varname = NULL; /* to be set if variable is const */ | 279 | TString *varname = NULL; /* to be set if variable is const */ |
@@ -306,8 +313,8 @@ static void adjustlocalvars (LexState *ls, int nvars) { | |||
306 | int stklevel = luaY_nvarstack(fs); | 313 | int stklevel = luaY_nvarstack(fs); |
307 | int i; | 314 | int i; |
308 | for (i = 0; i < nvars; i++) { | 315 | for (i = 0; i < nvars; i++) { |
309 | int varidx = fs->nactvar++; | 316 | int vidx = fs->nactvar++; |
310 | Vardesc *var = getlocalvardesc(fs, varidx); | 317 | Vardesc *var = getlocalvardesc(fs, vidx); |
311 | var->vd.sidx = stklevel++; | 318 | var->vd.sidx = stklevel++; |
312 | var->vd.pidx = registerlocalvar(ls, fs, var->vd.name); | 319 | var->vd.pidx = registerlocalvar(ls, fs, var->vd.name); |
313 | } | 320 | } |
@@ -377,7 +384,8 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) { | |||
377 | 384 | ||
378 | /* | 385 | /* |
379 | ** Look for an active local variable with the name 'n' in the | 386 | ** Look for an active local variable with the name 'n' in the |
380 | ** function 'fs'. | 387 | ** function 'fs'. If found, initialize 'var' with it and return |
388 | ** its expression kind; otherwise return -1. | ||
381 | */ | 389 | */ |
382 | static int searchvar (FuncState *fs, TString *n, expdesc *var) { | 390 | static int searchvar (FuncState *fs, TString *n, expdesc *var) { |
383 | int i; | 391 | int i; |
@@ -1592,7 +1600,7 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1592 | line = ls->linenumber; | 1600 | line = ls->linenumber; |
1593 | adjust_assign(ls, 4, explist(ls, &e), &e); | 1601 | adjust_assign(ls, 4, explist(ls, &e), &e); |
1594 | adjustlocalvars(ls, 4); /* control variables */ | 1602 | adjustlocalvars(ls, 4); /* control variables */ |
1595 | markupval(fs, luaY_nvarstack(fs)); /* state may create an upvalue */ | 1603 | markupval(fs, fs->nactvar); /* last control var. must be closed */ |
1596 | luaK_checkstack(fs, 3); /* extra space to call generator */ | 1604 | luaK_checkstack(fs, 3); /* extra space to call generator */ |
1597 | forbody(ls, base, line, nvars - 4, 1); | 1605 | forbody(ls, base, line, nvars - 4, 1); |
1598 | } | 1606 | } |
@@ -1730,7 +1738,7 @@ static int getlocalattribute (LexState *ls) { | |||
1730 | luaK_semerror(ls, | 1738 | luaK_semerror(ls, |
1731 | luaO_pushfstring(ls->L, "unknown attribute '%s'", attr)); | 1739 | luaO_pushfstring(ls->L, "unknown attribute '%s'", attr)); |
1732 | } | 1740 | } |
1733 | return VDKREG; | 1741 | return VDKREG; /* regular variable */ |
1734 | } | 1742 | } |
1735 | 1743 | ||
1736 | 1744 | ||
@@ -1739,7 +1747,7 @@ static void checktoclose (LexState *ls, int level) { | |||
1739 | FuncState *fs = ls->fs; | 1747 | FuncState *fs = ls->fs; |
1740 | markupval(fs, level + 1); | 1748 | markupval(fs, level + 1); |
1741 | fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */ | 1749 | fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */ |
1742 | luaK_codeABC(fs, OP_TBC, level, 0, 0); | 1750 | luaK_codeABC(fs, OP_TBC, stacklevel(fs, level), 0, 0); |
1743 | } | 1751 | } |
1744 | } | 1752 | } |
1745 | 1753 | ||
@@ -1749,18 +1757,18 @@ static void localstat (LexState *ls) { | |||
1749 | FuncState *fs = ls->fs; | 1757 | FuncState *fs = ls->fs; |
1750 | int toclose = -1; /* index of to-be-closed variable (if any) */ | 1758 | int toclose = -1; /* index of to-be-closed variable (if any) */ |
1751 | Vardesc *var; /* last variable */ | 1759 | Vardesc *var; /* last variable */ |
1752 | int ivar, kind; /* index and kind of last variable */ | 1760 | int vidx, kind; /* index and kind of last variable */ |
1753 | int nvars = 0; | 1761 | int nvars = 0; |
1754 | int nexps; | 1762 | int nexps; |
1755 | expdesc e; | 1763 | expdesc e; |
1756 | do { | 1764 | do { |
1757 | ivar = new_localvar(ls, str_checkname(ls)); | 1765 | vidx = new_localvar(ls, str_checkname(ls)); |
1758 | kind = getlocalattribute(ls); | 1766 | kind = getlocalattribute(ls); |
1759 | getlocalvardesc(fs, ivar)->vd.kind = kind; | 1767 | getlocalvardesc(fs, vidx)->vd.kind = kind; |
1760 | if (kind == RDKTOCLOSE) { /* to-be-closed? */ | 1768 | if (kind == RDKTOCLOSE) { /* to-be-closed? */ |
1761 | if (toclose != -1) /* one already present? */ | 1769 | if (toclose != -1) /* one already present? */ |
1762 | luaK_semerror(ls, "multiple to-be-closed variables in local list"); | 1770 | luaK_semerror(ls, "multiple to-be-closed variables in local list"); |
1763 | toclose = luaY_nvarstack(fs) + nvars; | 1771 | toclose = fs->nactvar + nvars; |
1764 | } | 1772 | } |
1765 | nvars++; | 1773 | nvars++; |
1766 | } while (testnext(ls, ',')); | 1774 | } while (testnext(ls, ',')); |
@@ -1770,7 +1778,7 @@ static void localstat (LexState *ls) { | |||
1770 | e.k = VVOID; | 1778 | e.k = VVOID; |
1771 | nexps = 0; | 1779 | nexps = 0; |
1772 | } | 1780 | } |
1773 | var = getlocalvardesc(fs, ivar); /* get last variable */ | 1781 | var = getlocalvardesc(fs, vidx); /* get last variable */ |
1774 | if (nvars == nexps && /* no adjustments? */ | 1782 | if (nvars == nexps && /* no adjustments? */ |
1775 | var->vd.kind == RDKCONST && /* last variable is const? */ | 1783 | var->vd.kind == RDKCONST && /* last variable is const? */ |
1776 | luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */ | 1784 | luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */ |