| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: lparser.c,v 1.13 2023/04/17 19:17:49 nikita Exp $ */ | | 1 | /* $NetBSD: lparser.c,v 1.14 2023/04/17 20:07:32 nikita Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | ** Id: lparser.c | | 4 | ** Id: lparser.c |
5 | ** Lua Parser | | 5 | ** Lua Parser |
6 | ** See Copyright Notice in lua.h | | 6 | ** See Copyright Notice in lua.h |
7 | */ | | 7 | */ |
8 | | | 8 | |
9 | #define lparser_c | | 9 | #define lparser_c |
10 | #define LUA_CORE | | 10 | #define LUA_CORE |
11 | | | 11 | |
12 | #include "lprefix.h" | | 12 | #include "lprefix.h" |
13 | | | 13 | |
14 | | | 14 | |
| @@ -668,39 +668,39 @@ static l_noret undefgoto (LexState *ls, | | | @@ -668,39 +668,39 @@ static l_noret undefgoto (LexState *ls, |
668 | else { | | 668 | else { |
669 | msg = "no visible label '%s' for <goto> at line %d"; | | 669 | msg = "no visible label '%s' for <goto> at line %d"; |
670 | msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); | | 670 | msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); |
671 | } | | 671 | } |
672 | luaK_semerror(ls, msg); | | 672 | luaK_semerror(ls, msg); |
673 | } | | 673 | } |
674 | | | 674 | |
675 | | | 675 | |
676 | static void leaveblock (FuncState *fs) { | | 676 | static void leaveblock (FuncState *fs) { |
677 | BlockCnt *bl = fs->bl; | | 677 | BlockCnt *bl = fs->bl; |
678 | LexState *ls = fs->ls; | | 678 | LexState *ls = fs->ls; |
679 | int hasclose = 0; | | 679 | int hasclose = 0; |
680 | int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */ | | 680 | int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */ |
681 | if (bl->isloop) /* fix pending breaks? */ | | 681 | removevars(fs, bl->nactvar); /* remove block locals */ |
| | | 682 | lua_assert(bl->nactvar == fs->nactvar); /* back to level on entry */ |
| | | 683 | if (bl->isloop) /* has to fix pending breaks? */ |
682 | hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0); | | 684 | hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0); |
683 | if (!hasclose && bl->previous && bl->upval) | | 685 | if (!hasclose && bl->previous && bl->upval) /* still need a 'close'? */ |
684 | luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0); | | 686 | luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0); |
685 | fs->bl = bl->previous; | | | |
686 | removevars(fs, bl->nactvar); | | | |
687 | lua_assert(bl->nactvar == fs->nactvar); | | | |
688 | fs->freereg = stklevel; /* free registers */ | | 687 | fs->freereg = stklevel; /* free registers */ |
689 | ls->dyd->label.n = bl->firstlabel; /* remove local labels */ | | 688 | ls->dyd->label.n = bl->firstlabel; /* remove local labels */ |
690 | if (bl->previous) /* inner block? */ | | 689 | fs->bl = bl->previous; /* current block now is previous one */ |
691 | movegotosout(fs, bl); /* update pending gotos to outer block */ | | 690 | if (bl->previous) /* was it a nested block? */ |
| | | 691 | movegotosout(fs, bl); /* update pending gotos to enclosing block */ |
692 | else { | | 692 | else { |
693 | if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ | | 693 | if (bl->firstgoto < ls->dyd->gt.n) /* still pending gotos? */ |
694 | undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ | | 694 | undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ |
695 | } | | 695 | } |
696 | } | | 696 | } |
697 | | | 697 | |
698 | | | 698 | |
699 | /* | | 699 | /* |
700 | ** adds a new prototype into list of prototypes | | 700 | ** adds a new prototype into list of prototypes |
701 | */ | | 701 | */ |
702 | static Proto *addprototype (LexState *ls) { | | 702 | static Proto *addprototype (LexState *ls) { |
703 | Proto *clp; | | 703 | Proto *clp; |
704 | lua_State *L = ls->L; | | 704 | lua_State *L = ls->L; |
705 | FuncState *fs = ls->fs; | | 705 | FuncState *fs = ls->fs; |
706 | Proto *f = fs->f; /* prototype of current function */ | | 706 | Proto *f = fs->f; /* prototype of current function */ |