From 3fb7a77731e6140674a6b13b73979256bfb95ce3 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 15 May 2025 12:43:37 -0300 Subject: 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. --- llex.c | 3 +++ llex.h | 1 + lparser.c | 6 +++--- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/llex.c b/llex.c index 59d927d4..54e7f343 100644 --- a/llex.c +++ b/llex.c @@ -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 */ } diff --git a/llex.h b/llex.h index 078e4d31..0dba9d60 100644 --- a/llex.h +++ b/llex.h @@ -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; diff --git a/lparser.c b/lparser.c index 27c8a927..29022bfd 100644 --- a/lparser.c +++ b/lparser.c @@ -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 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); } -- cgit v1.2.3-55-g6feb