浏览代码

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.
Roberto Ierusalimschy 2 月之前
父节点
当前提交
3fb7a77731
共有 3 个文件被更改,包括 7 次插入3 次删除
  1. 3 0
      llex.c
  2. 1 0
      llex.h
  3. 3 3
      lparser.c

+ 3 - 0
llex.c

@@ -190,6 +190,9 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
   ls->lastline = 1;
   ls->lastline = 1;
   ls->source = source;
   ls->source = source;
   ls->envn = luaS_newliteral(L, LUA_ENV);  /* get env name */
   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 */
   luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
 }
 }
 
 

+ 1 - 0
llex.h

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

+ 3 - 3
lparser.c

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