Internalized string "break" kept by the parser

The parser uses "break" as fake label to compile "break" as "goto
break". To avoid producing this string at each use, it keeps it
available in its state.
This commit is contained in:
Roberto Ierusalimschy
2025-05-15 12:43:37 -03:00
parent fded0b4a84
commit 3fb7a77731
3 changed files with 7 additions and 3 deletions

3
llex.c
View File

@@ -190,6 +190,9 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
ls->lastline = 1;
ls->source = source;
ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */
ls->brkn = luaS_newliteral(L, "break"); /* get "break" name */
/* "break" cannot be collected, as it is a reserved word" */
lua_assert(isreserved(ls->brkn));
luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
}

1
llex.h
View File

@@ -75,6 +75,7 @@ typedef struct LexState {
struct Dyndata *dyd; /* dynamic structures used by the parser */
TString *source; /* current source name */
TString *envn; /* environment variable name */
TString *brkn; /* "break" name (used as a label) */
} LexState;

View File

@@ -707,7 +707,7 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
*/
static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
/* breaks are checked when created, cannot be undefined */
lua_assert(!eqstr(gt->name, luaS_newliteral(ls->L, "break")));
lua_assert(!eqstr(gt->name, ls->brkn));
luaK_semerror(ls, "no visible label '%s' for <goto> at line %d",
getstr(gt->name), gt->line);
}
@@ -723,7 +723,7 @@ static void leaveblock (FuncState *fs) {
removevars(fs, bl->nactvar); /* remove block locals */
lua_assert(bl->nactvar == fs->nactvar); /* back to level on entry */
if (bl->isloop == 2) /* has to fix pending breaks? */
createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0);
createlabel(ls, ls->brkn, 0, 0);
solvegotos(fs, bl);
if (bl->previous == NULL) { /* was it the last block? */
if (bl->firstgoto < ls->dyd->gt.n) /* still pending gotos? */
@@ -1497,7 +1497,7 @@ static void breakstat (LexState *ls, int line) {
ok:
bl->isloop = 2; /* signal that block has pending breaks */
luaX_next(ls); /* skip break */
newgotoentry(ls, luaS_newliteral(ls->L, "break"), line);
newgotoentry(ls, ls->brkn, line);
}