diff options
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 113 |
1 files changed, 76 insertions, 37 deletions
@@ -173,13 +173,13 @@ static void codename (LexState *ls, expdesc *e) { | |||
173 | static int registerlocalvar (lua_State *L, FuncState *fs, TString *varname) { | 173 | static int registerlocalvar (lua_State *L, FuncState *fs, TString *varname) { |
174 | Proto *f = fs->f; | 174 | Proto *f = fs->f; |
175 | int oldsize = f->sizelocvars; | 175 | int oldsize = f->sizelocvars; |
176 | luaM_growvector(L, f->locvars, fs->nlocvars, f->sizelocvars, | 176 | luaM_growvector(L, f->locvars, fs->ndebugvars, f->sizelocvars, |
177 | LocVar, SHRT_MAX, "local variables"); | 177 | LocVar, SHRT_MAX, "local variables"); |
178 | while (oldsize < f->sizelocvars) | 178 | while (oldsize < f->sizelocvars) |
179 | f->locvars[oldsize++].varname = NULL; | 179 | f->locvars[oldsize++].varname = NULL; |
180 | f->locvars[fs->nlocvars].varname = varname; | 180 | f->locvars[fs->ndebugvars].varname = varname; |
181 | luaC_objbarrier(L, f, varname); | 181 | luaC_objbarrier(L, f, varname); |
182 | return fs->nlocvars++; | 182 | return fs->ndebugvars++; |
183 | } | 183 | } |
184 | 184 | ||
185 | 185 | ||
@@ -193,12 +193,13 @@ static Vardesc *new_localvar (LexState *ls, TString *name) { | |||
193 | Vardesc *var; | 193 | Vardesc *var; |
194 | int reg = registerlocalvar(L, fs, name); | 194 | int reg = registerlocalvar(L, fs, name); |
195 | checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, | 195 | checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, |
196 | MAXVARS, "local variables"); | 196 | MAXVARS, "local variables"); |
197 | luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, | 197 | luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, |
198 | dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); | 198 | dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); |
199 | var = &dyd->actvar.arr[dyd->actvar.n++]; | 199 | var = &dyd->actvar.arr[dyd->actvar.n++]; |
200 | var->pidx = cast(short, reg); | 200 | var->pidx = cast(short, reg); |
201 | var->ro = 0; | 201 | var->ro = 0; |
202 | var->name = name; | ||
202 | setnilvalue(var); | 203 | setnilvalue(var); |
203 | return var; | 204 | return var; |
204 | } | 205 | } |
@@ -218,12 +219,41 @@ static Vardesc *getlocalvardesc (FuncState *fs, int i) { | |||
218 | 219 | ||
219 | 220 | ||
220 | /* | 221 | /* |
222 | ** Convert 'nvar' (number of active variables at some point) to | ||
223 | ** number of variables in the stack at that point. | ||
224 | */ | ||
225 | static int stacklevel (FuncState *fs, int nvar) { | ||
226 | while (nvar > 0) { | ||
227 | Vardesc *vd = getlocalvardesc(fs, nvar - 1); | ||
228 | if (vdinstack(vd)) /* is in the stack? */ | ||
229 | return vd->sidx + 1; | ||
230 | else | ||
231 | nvar--; /* try previous variable */ | ||
232 | } | ||
233 | return 0; /* no variables */ | ||
234 | } | ||
235 | |||
236 | |||
237 | /* | ||
238 | ** Return the number of variables in the stack for function 'fs' | ||
239 | */ | ||
240 | int luaY_nvarstack (FuncState *fs) { | ||
241 | return stacklevel(fs, fs->nactvar); | ||
242 | } | ||
243 | |||
244 | |||
245 | /* | ||
221 | ** Get the debug-information entry for current variable 'i'. | 246 | ** Get the debug-information entry for current variable 'i'. |
222 | */ | 247 | */ |
223 | static LocVar *localdebuginfo (FuncState *fs, int i) { | 248 | static LocVar *localdebuginfo (FuncState *fs, int i) { |
224 | int idx = getlocalvardesc(fs, i)->pidx; | 249 | Vardesc *vd = getlocalvardesc(fs, i); |
225 | lua_assert(idx < fs->nlocvars); | 250 | if (!vdinstack(vd)) |
226 | return &fs->f->locvars[idx]; | 251 | return NULL; /* no debug info. for constants */ |
252 | else { | ||
253 | int idx = vd->pidx; | ||
254 | lua_assert(idx < fs->ndebugvars); | ||
255 | return &fs->f->locvars[idx]; | ||
256 | } | ||
227 | } | 257 | } |
228 | 258 | ||
229 | 259 | ||
@@ -242,7 +272,7 @@ static void check_readonly (LexState *ls, expdesc *e) { | |||
242 | case VLOCAL: { | 272 | case VLOCAL: { |
243 | Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx); | 273 | Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx); |
244 | if (vardesc->ro) | 274 | if (vardesc->ro) |
245 | varname = fs->f->locvars[vardesc->pidx].varname; | 275 | varname = vardesc->name; |
246 | break; | 276 | break; |
247 | } | 277 | } |
248 | case VUPVAL: { | 278 | case VUPVAL: { |
@@ -267,11 +297,12 @@ static void check_readonly (LexState *ls, expdesc *e) { | |||
267 | */ | 297 | */ |
268 | static void adjustlocalvars (LexState *ls, int nvars) { | 298 | static void adjustlocalvars (LexState *ls, int nvars) { |
269 | FuncState *fs = ls->fs; | 299 | FuncState *fs = ls->fs; |
300 | int stklevel = luaY_nvarstack(fs); | ||
270 | int i; | 301 | int i; |
271 | for (i = 0; i < nvars; i++) { | 302 | for (i = 0; i < nvars; i++) { |
272 | int varidx = fs->nactvar++; | 303 | int varidx = fs->nactvar++; |
273 | Vardesc *var = getlocalvardesc(fs, varidx); | 304 | Vardesc *var = getlocalvardesc(fs, varidx); |
274 | var->sidx = varidx; | 305 | var->sidx = stklevel++; |
275 | fs->f->locvars[var->pidx].startpc = fs->pc; | 306 | fs->f->locvars[var->pidx].startpc = fs->pc; |
276 | } | 307 | } |
277 | } | 308 | } |
@@ -283,8 +314,11 @@ static void adjustlocalvars (LexState *ls, int nvars) { | |||
283 | */ | 314 | */ |
284 | static void removevars (FuncState *fs, int tolevel) { | 315 | static void removevars (FuncState *fs, int tolevel) { |
285 | fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); | 316 | fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); |
286 | while (fs->nactvar > tolevel) | 317 | while (fs->nactvar > tolevel) { |
287 | localdebuginfo(fs, --fs->nactvar)->endpc = fs->pc; | 318 | LocVar *var = localdebuginfo(fs, --fs->nactvar); |
319 | if (var) /* does it have debug information? */ | ||
320 | var->endpc = fs->pc; | ||
321 | } | ||
288 | } | 322 | } |
289 | 323 | ||
290 | 324 | ||
@@ -321,7 +355,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) { | |||
321 | up->instack = 1; | 355 | up->instack = 1; |
322 | up->idx = v->u.var.sidx; | 356 | up->idx = v->u.var.sidx; |
323 | up->ro = getlocalvardesc(prev, v->u.var.vidx)->ro; | 357 | up->ro = getlocalvardesc(prev, v->u.var.vidx)->ro; |
324 | lua_assert(eqstr(name, localdebuginfo(prev, v->u.var.vidx)->varname)); | 358 | lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->name)); |
325 | } | 359 | } |
326 | else { | 360 | else { |
327 | up->instack = 0; | 361 | up->instack = 0; |
@@ -342,7 +376,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) { | |||
342 | static int searchvar (FuncState *fs, TString *n) { | 376 | static int searchvar (FuncState *fs, TString *n) { |
343 | int i; | 377 | int i; |
344 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { | 378 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { |
345 | if (eqstr(n, localdebuginfo(fs, i)->varname)) | 379 | if (eqstr(n, getlocalvardesc(fs, i)->name)) |
346 | return i; | 380 | return i; |
347 | } | 381 | } |
348 | return -1; /* not found */ | 382 | return -1; /* not found */ |
@@ -375,7 +409,7 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | |||
375 | if (v >= 0) { /* found? */ | 409 | if (v >= 0) { /* found? */ |
376 | init_var(fs, var, v); /* variable is local */ | 410 | init_var(fs, var, v); /* variable is local */ |
377 | if (!base) | 411 | if (!base) |
378 | markupval(fs, var->u.var.sidx); /* local will be used as an upval */ | 412 | markupval(fs, var->u.var.vidx); /* local will be used as an upval */ |
379 | } | 413 | } |
380 | else { /* not found as local at current level; try upvalues */ | 414 | else { /* not found as local at current level; try upvalues */ |
381 | int idx = searchupvalue(fs, n); /* try existing upvalues */ | 415 | int idx = searchupvalue(fs, n); /* try existing upvalues */ |
@@ -449,7 +483,7 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { | |||
449 | ** local variable. | 483 | ** local variable. |
450 | */ | 484 | */ |
451 | static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { | 485 | static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { |
452 | const char *varname = getstr(localdebuginfo(ls->fs, gt->nactvar)->varname); | 486 | const char *varname = getstr(getlocalvardesc(ls->fs, gt->nactvar)->name); |
453 | const char *msg = "<goto %s> at line %d jumps into the scope of local '%s'"; | 487 | const char *msg = "<goto %s> at line %d jumps into the scope of local '%s'"; |
454 | msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname); | 488 | msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname); |
455 | luaK_semerror(ls, msg); /* raise the error */ | 489 | luaK_semerror(ls, msg); /* raise the error */ |
@@ -552,7 +586,7 @@ static int createlabel (LexState *ls, TString *name, int line, | |||
552 | ll->arr[l].nactvar = fs->bl->nactvar; | 586 | ll->arr[l].nactvar = fs->bl->nactvar; |
553 | } | 587 | } |
554 | if (solvegotos(ls, &ll->arr[l])) { /* need close? */ | 588 | if (solvegotos(ls, &ll->arr[l])) { /* need close? */ |
555 | luaK_codeABC(fs, OP_CLOSE, fs->nactvar, 0, 0); | 589 | luaK_codeABC(fs, OP_CLOSE, luaY_nvarstack(fs), 0, 0); |
556 | return 1; | 590 | return 1; |
557 | } | 591 | } |
558 | return 0; | 592 | return 0; |
@@ -568,10 +602,10 @@ static void movegotosout (FuncState *fs, BlockCnt *bl) { | |||
568 | /* correct pending gotos to current block */ | 602 | /* correct pending gotos to current block */ |
569 | for (i = bl->firstgoto; i < gl->n; i++) { /* for each pending goto */ | 603 | for (i = bl->firstgoto; i < gl->n; i++) { /* for each pending goto */ |
570 | Labeldesc *gt = &gl->arr[i]; | 604 | Labeldesc *gt = &gl->arr[i]; |
571 | if (gt->nactvar > bl->nactvar) { /* leaving a variable scope? */ | 605 | /* leaving a variable scope? */ |
572 | gt->nactvar = bl->nactvar; /* update goto level */ | 606 | if (stacklevel(fs, gt->nactvar) > stacklevel(fs, bl->nactvar)) |
573 | gt->close |= bl->upval; /* jump may need a close */ | 607 | gt->close |= bl->upval; /* jump may need a close */ |
574 | } | 608 | gt->nactvar = bl->nactvar; /* update goto level */ |
575 | } | 609 | } |
576 | } | 610 | } |
577 | 611 | ||
@@ -585,7 +619,7 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { | |||
585 | bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc); | 619 | bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc); |
586 | bl->previous = fs->bl; | 620 | bl->previous = fs->bl; |
587 | fs->bl = bl; | 621 | fs->bl = bl; |
588 | lua_assert(fs->freereg == fs->nactvar); | 622 | lua_assert(fs->freereg == luaY_nvarstack(fs)); |
589 | } | 623 | } |
590 | 624 | ||
591 | 625 | ||
@@ -610,14 +644,15 @@ static void leaveblock (FuncState *fs) { | |||
610 | BlockCnt *bl = fs->bl; | 644 | BlockCnt *bl = fs->bl; |
611 | LexState *ls = fs->ls; | 645 | LexState *ls = fs->ls; |
612 | int hasclose = 0; | 646 | int hasclose = 0; |
647 | int stklevel = stacklevel(fs, bl->nactvar); /* level outside the block */ | ||
613 | if (bl->isloop) /* fix pending breaks? */ | 648 | if (bl->isloop) /* fix pending breaks? */ |
614 | hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0); | 649 | hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0); |
615 | if (!hasclose && bl->previous && bl->upval) | 650 | if (!hasclose && bl->previous && bl->upval) |
616 | luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); | 651 | luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0); |
617 | fs->bl = bl->previous; | 652 | fs->bl = bl->previous; |
618 | removevars(fs, bl->nactvar); | 653 | removevars(fs, bl->nactvar); |
619 | lua_assert(bl->nactvar == fs->nactvar); | 654 | lua_assert(bl->nactvar == fs->nactvar); |
620 | fs->freereg = fs->nactvar; /* free registers */ | 655 | fs->freereg = stklevel; /* free registers */ |
621 | ls->dyd->label.n = bl->firstlabel; /* remove local labels */ | 656 | ls->dyd->label.n = bl->firstlabel; /* remove local labels */ |
622 | if (bl->previous) /* inner block? */ | 657 | if (bl->previous) /* inner block? */ |
623 | movegotosout(fs, bl); /* update pending gotos to outer block */ | 658 | movegotosout(fs, bl); /* update pending gotos to outer block */ |
@@ -675,7 +710,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { | |||
675 | fs->nabslineinfo = 0; | 710 | fs->nabslineinfo = 0; |
676 | fs->np = 0; | 711 | fs->np = 0; |
677 | fs->nups = 0; | 712 | fs->nups = 0; |
678 | fs->nlocvars = 0; | 713 | fs->ndebugvars = 0; |
679 | fs->nactvar = 0; | 714 | fs->nactvar = 0; |
680 | fs->needclose = 0; | 715 | fs->needclose = 0; |
681 | fs->firstlocal = ls->dyd->actvar.n; | 716 | fs->firstlocal = ls->dyd->actvar.n; |
@@ -691,7 +726,7 @@ static void close_func (LexState *ls) { | |||
691 | lua_State *L = ls->L; | 726 | lua_State *L = ls->L; |
692 | FuncState *fs = ls->fs; | 727 | FuncState *fs = ls->fs; |
693 | Proto *f = fs->f; | 728 | Proto *f = fs->f; |
694 | luaK_ret(fs, fs->nactvar, 0); /* final return */ | 729 | luaK_ret(fs, luaY_nvarstack(fs), 0); /* final return */ |
695 | leaveblock(fs); | 730 | leaveblock(fs); |
696 | lua_assert(fs->bl == NULL); | 731 | lua_assert(fs->bl == NULL); |
697 | luaK_finish(fs); | 732 | luaK_finish(fs); |
@@ -701,7 +736,7 @@ static void close_func (LexState *ls) { | |||
701 | fs->nabslineinfo, AbsLineInfo); | 736 | fs->nabslineinfo, AbsLineInfo); |
702 | luaM_shrinkvector(L, f->k, f->sizek, fs->nk, TValue); | 737 | luaM_shrinkvector(L, f->k, f->sizek, fs->nk, TValue); |
703 | luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); | 738 | luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); |
704 | luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); | 739 | luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->ndebugvars, LocVar); |
705 | luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); | 740 | luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); |
706 | ls->fs = fs->prev; | 741 | ls->fs = fs->prev; |
707 | luaC_checkGC(L); | 742 | luaC_checkGC(L); |
@@ -1356,8 +1391,9 @@ static void gotostat (LexState *ls) { | |||
1356 | newgotoentry(ls, name, line, luaK_jump(fs)); | 1391 | newgotoentry(ls, name, line, luaK_jump(fs)); |
1357 | else { /* found a label */ | 1392 | else { /* found a label */ |
1358 | /* backward jump; will be resolved here */ | 1393 | /* backward jump; will be resolved here */ |
1359 | if (fs->nactvar > lb->nactvar) /* leaving the scope of some variable? */ | 1394 | int lblevel = stacklevel(fs, lb->nactvar); /* label level */ |
1360 | luaK_codeABC(fs, OP_CLOSE, lb->nactvar, 0, 0); | 1395 | if (luaY_nvarstack(fs) > lblevel) /* leaving the scope of a variable? */ |
1396 | luaK_codeABC(fs, OP_CLOSE, lblevel, 0, 0); | ||
1361 | /* create jump and link it to the label */ | 1397 | /* create jump and link it to the label */ |
1362 | luaK_patchlist(fs, luaK_jump(fs), lb->pc); | 1398 | luaK_patchlist(fs, luaK_jump(fs), lb->pc); |
1363 | } | 1399 | } |
@@ -1432,7 +1468,7 @@ static void repeatstat (LexState *ls, int line) { | |||
1432 | if (bl2.upval) { /* upvalues? */ | 1468 | if (bl2.upval) { /* upvalues? */ |
1433 | int exit = luaK_jump(fs); /* normal exit must jump over fix */ | 1469 | int exit = luaK_jump(fs); /* normal exit must jump over fix */ |
1434 | luaK_patchtohere(fs, condexit); /* repetition must close upvalues */ | 1470 | luaK_patchtohere(fs, condexit); /* repetition must close upvalues */ |
1435 | luaK_codeABC(fs, OP_CLOSE, bl2.nactvar, 0, 0); | 1471 | luaK_codeABC(fs, OP_CLOSE, stacklevel(fs, bl2.nactvar), 0, 0); |
1436 | condexit = luaK_jump(fs); /* repeat after closing upvalues */ | 1472 | condexit = luaK_jump(fs); /* repeat after closing upvalues */ |
1437 | luaK_patchtohere(fs, exit); /* normal exit comes to here */ | 1473 | luaK_patchtohere(fs, exit); /* normal exit comes to here */ |
1438 | } | 1474 | } |
@@ -1532,7 +1568,6 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1532 | /* create control variables */ | 1568 | /* create control variables */ |
1533 | new_localvarliteral(ls, "(for generator)"); | 1569 | new_localvarliteral(ls, "(for generator)"); |
1534 | new_localvarliteral(ls, "(for state)"); | 1570 | new_localvarliteral(ls, "(for state)"); |
1535 | markupval(fs, fs->nactvar); /* state may create an upvalue */ | ||
1536 | new_localvarliteral(ls, "(for control)"); | 1571 | new_localvarliteral(ls, "(for control)"); |
1537 | new_localvarliteral(ls, "(for toclose)"); | 1572 | new_localvarliteral(ls, "(for toclose)"); |
1538 | /* create declared variables */ | 1573 | /* create declared variables */ |
@@ -1545,6 +1580,7 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1545 | line = ls->linenumber; | 1580 | line = ls->linenumber; |
1546 | adjust_assign(ls, 4, explist(ls, &e), &e); | 1581 | adjust_assign(ls, 4, explist(ls, &e), &e); |
1547 | adjustlocalvars(ls, 4); /* control variables */ | 1582 | adjustlocalvars(ls, 4); /* control variables */ |
1583 | markupval(fs, luaY_nvarstack(fs)); /* state may create an upvalue */ | ||
1548 | luaK_checkstack(fs, 3); /* extra space to call generator */ | 1584 | luaK_checkstack(fs, 3); /* extra space to call generator */ |
1549 | forbody(ls, base, line, nvars - 4, 1); | 1585 | forbody(ls, base, line, nvars - 4, 1); |
1550 | } | 1586 | } |
@@ -1587,7 +1623,8 @@ static int issinglejump (LexState *ls, TString **label, int *target) { | |||
1587 | TString *lname = ls->lookahead.seminfo.ts; /* label's id */ | 1623 | TString *lname = ls->lookahead.seminfo.ts; /* label's id */ |
1588 | Labeldesc *lb = findlabel(ls, lname); | 1624 | Labeldesc *lb = findlabel(ls, lname); |
1589 | if (lb) { /* a backward jump? */ | 1625 | if (lb) { /* a backward jump? */ |
1590 | if (ls->fs->nactvar > lb->nactvar) /* needs to close variables? */ | 1626 | /* does it need to close variables? */ |
1627 | if (luaY_nvarstack(ls->fs) > stacklevel(ls->fs, lb->nactvar)) | ||
1591 | return 0; /* not a single jump; cannot optimize */ | 1628 | return 0; /* not a single jump; cannot optimize */ |
1592 | *target = lb->pc; | 1629 | *target = lb->pc; |
1593 | } | 1630 | } |
@@ -1659,11 +1696,12 @@ static void ifstat (LexState *ls, int line) { | |||
1659 | static void localfunc (LexState *ls) { | 1696 | static void localfunc (LexState *ls) { |
1660 | expdesc b; | 1697 | expdesc b; |
1661 | FuncState *fs = ls->fs; | 1698 | FuncState *fs = ls->fs; |
1699 | int fvar = fs->nactvar; /* function's variable index */ | ||
1662 | new_localvar(ls, str_checkname(ls)); /* new local variable */ | 1700 | new_localvar(ls, str_checkname(ls)); /* new local variable */ |
1663 | adjustlocalvars(ls, 1); /* enter its scope */ | 1701 | adjustlocalvars(ls, 1); /* enter its scope */ |
1664 | body(ls, &b, 0, ls->linenumber); /* function created in next register */ | 1702 | body(ls, &b, 0, ls->linenumber); /* function created in next register */ |
1665 | /* debug information will only see the variable after this point! */ | 1703 | /* debug information will only see the variable after this point! */ |
1666 | localdebuginfo(fs, b.u.info)->startpc = fs->pc; | 1704 | localdebuginfo(fs, fvar)->startpc = fs->pc; |
1667 | } | 1705 | } |
1668 | 1706 | ||
1669 | 1707 | ||
@@ -1687,9 +1725,10 @@ static int getlocalattribute (LexState *ls) { | |||
1687 | static void checktoclose (LexState *ls, int toclose) { | 1725 | static void checktoclose (LexState *ls, int toclose) { |
1688 | if (toclose != -1) { /* is there a to-be-closed variable? */ | 1726 | if (toclose != -1) { /* is there a to-be-closed variable? */ |
1689 | FuncState *fs = ls->fs; | 1727 | FuncState *fs = ls->fs; |
1690 | markupval(fs, fs->nactvar + toclose + 1); | 1728 | int level = luaY_nvarstack(fs) + toclose; |
1729 | markupval(fs, level + 1); | ||
1691 | fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */ | 1730 | fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */ |
1692 | luaK_codeABC(fs, OP_TBC, fs->nactvar + toclose, 0, 0); | 1731 | luaK_codeABC(fs, OP_TBC, level, 0, 0); |
1693 | } | 1732 | } |
1694 | } | 1733 | } |
1695 | 1734 | ||
@@ -1773,7 +1812,7 @@ static void retstat (LexState *ls) { | |||
1773 | FuncState *fs = ls->fs; | 1812 | FuncState *fs = ls->fs; |
1774 | expdesc e; | 1813 | expdesc e; |
1775 | int nret; /* number of values being returned */ | 1814 | int nret; /* number of values being returned */ |
1776 | int first = fs->nactvar; /* first slot to be returned */ | 1815 | int first = luaY_nvarstack(fs); /* first slot to be returned */ |
1777 | if (block_follow(ls, 1) || ls->t.token == ';') | 1816 | if (block_follow(ls, 1) || ls->t.token == ';') |
1778 | nret = 0; /* return no values */ | 1817 | nret = 0; /* return no values */ |
1779 | else { | 1818 | else { |
@@ -1782,7 +1821,7 @@ static void retstat (LexState *ls) { | |||
1782 | luaK_setmultret(fs, &e); | 1821 | luaK_setmultret(fs, &e); |
1783 | if (e.k == VCALL && nret == 1 && !fs->bl->insidetbc) { /* tail call? */ | 1822 | if (e.k == VCALL && nret == 1 && !fs->bl->insidetbc) { /* tail call? */ |
1784 | SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL); | 1823 | SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL); |
1785 | lua_assert(GETARG_A(getinstruction(fs,&e)) == fs->nactvar); | 1824 | lua_assert(GETARG_A(getinstruction(fs,&e)) == luaY_nvarstack(fs)); |
1786 | } | 1825 | } |
1787 | nret = LUA_MULTRET; /* return all values */ | 1826 | nret = LUA_MULTRET; /* return all values */ |
1788 | } | 1827 | } |
@@ -1867,8 +1906,8 @@ static void statement (LexState *ls) { | |||
1867 | } | 1906 | } |
1868 | } | 1907 | } |
1869 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && | 1908 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && |
1870 | ls->fs->freereg >= ls->fs->nactvar); | 1909 | ls->fs->freereg >= luaY_nvarstack(ls->fs)); |
1871 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ | 1910 | ls->fs->freereg = luaY_nvarstack(ls->fs); /* free registers */ |
1872 | leavelevel(ls); | 1911 | leavelevel(ls); |
1873 | } | 1912 | } |
1874 | 1913 | ||