diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-06-27 15:18:59 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-06-27 15:18:59 -0300 |
| commit | 374773748b6b5890a0b842e6dbb90dfd2213c54c (patch) | |
| tree | 1def1ed93d72e7121010c1def40188f73e5677d4 | |
| parent | 29644366fcd2fa41ffe6387982541ac5dae49e8c (diff) | |
| download | lua-374773748b6b5890a0b842e6dbb90dfd2213c54c.tar.gz lua-374773748b6b5890a0b842e6dbb90dfd2213c54c.tar.bz2 lua-374773748b6b5890a0b842e6dbb90dfd2213c54c.zip | |
back to "one-label-per-block"
| -rw-r--r-- | lparser.c | 33 |
1 files changed, 13 insertions, 20 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 2.110 2011/06/16 16:36:39 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.111 2011/06/20 16:52:48 roberto Exp roberto $ |
| 3 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -367,7 +367,7 @@ static int findlabel (LexState *ls, int g) { | |||
| 367 | /* check labels in current block for a match */ | 367 | /* check labels in current block for a match */ |
| 368 | for (i = bl->firstlabel; i < dyd->label.n; i++) { | 368 | for (i = bl->firstlabel; i < dyd->label.n; i++) { |
| 369 | Labeldesc *lb = &dyd->label.arr[i]; | 369 | Labeldesc *lb = &dyd->label.arr[i]; |
| 370 | if (eqstr(lb->name, gt->name) && lb->pc != -1) { /* correct label? */ | 370 | if (eqstr(lb->name, gt->name)) { /* correct label? */ |
| 371 | if (gt->nactvar > lb->nactvar && | 371 | if (gt->nactvar > lb->nactvar && |
| 372 | (bl->upval || dyd->label.n > bl->firstlabel)) | 372 | (bl->upval || dyd->label.n > bl->firstlabel)) |
| 373 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); | 373 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); |
| @@ -466,12 +466,6 @@ static void undefgoto (LexState *ls, Labeldesc *gt) { | |||
| 466 | } | 466 | } |
| 467 | 467 | ||
| 468 | 468 | ||
| 469 | static void invalidatelabels (Labellist *ll, int level) { | ||
| 470 | for (; level < ll->n; level++) | ||
| 471 | ll->arr[level].pc = -1; /* mark label as out of scope */ | ||
| 472 | } | ||
| 473 | |||
| 474 | |||
| 475 | static void leaveblock (FuncState *fs) { | 469 | static void leaveblock (FuncState *fs) { |
| 476 | BlockCnt *bl = fs->bl; | 470 | BlockCnt *bl = fs->bl; |
| 477 | LexState *ls = fs->ls; | 471 | LexState *ls = fs->ls; |
| @@ -487,7 +481,7 @@ static void leaveblock (FuncState *fs) { | |||
| 487 | removevars(fs, bl->nactvar); | 481 | removevars(fs, bl->nactvar); |
| 488 | lua_assert(bl->nactvar == fs->nactvar); | 482 | lua_assert(bl->nactvar == fs->nactvar); |
| 489 | fs->freereg = fs->nactvar; /* free registers */ | 483 | fs->freereg = fs->nactvar; /* free registers */ |
| 490 | invalidatelabels(&ls->dyd->label, bl->firstlabel); /* remove local labels */ | 484 | ls->dyd->label.n = bl->firstlabel; /* remove local labels */ |
| 491 | if (bl->previous) /* inner block? */ | 485 | if (bl->previous) /* inner block? */ |
| 492 | movegotosout(fs, bl); /* update pending gotos to outer block */ | 486 | movegotosout(fs, bl); /* update pending gotos to outer block */ |
| 493 | else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ | 487 | else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ |
| @@ -532,7 +526,6 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { | |||
| 532 | fs->nlocvars = 0; | 526 | fs->nlocvars = 0; |
| 533 | fs->nactvar = 0; | 527 | fs->nactvar = 0; |
| 534 | fs->firstlocal = ls->dyd->actvar.n; | 528 | fs->firstlocal = ls->dyd->actvar.n; |
| 535 | fs->firstlabel = ls->dyd->label.n; | ||
| 536 | fs->bl = NULL; | 529 | fs->bl = NULL; |
| 537 | f = luaF_newproto(L); | 530 | f = luaF_newproto(L); |
| 538 | fs->f = f; | 531 | fs->f = f; |
| @@ -555,7 +548,6 @@ static void close_func (LexState *ls) { | |||
| 555 | Proto *f = fs->f; | 548 | Proto *f = fs->f; |
| 556 | luaK_ret(fs, 0, 0); /* final return */ | 549 | luaK_ret(fs, 0, 0); /* final return */ |
| 557 | leaveblock(fs); | 550 | leaveblock(fs); |
| 558 | ls->dyd->label.n = fs->firstlabel; /* remove labels */ | ||
| 559 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); | 551 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); |
| 560 | f->sizecode = fs->pc; | 552 | f->sizecode = fs->pc; |
| 561 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); | 553 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); |
| @@ -1193,16 +1185,15 @@ static void gotostat (LexState *ls, TString *label, int line) { | |||
| 1193 | } | 1185 | } |
| 1194 | 1186 | ||
| 1195 | 1187 | ||
| 1196 | /* check for repeated labels on the same function */ | 1188 | /* check for repeated labels on the same block */ |
| 1197 | static void checkrepeated (LexState *ls, FuncState *fs, Labellist *ll, | 1189 | static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { |
| 1198 | TString *label) { | ||
| 1199 | int i; | 1190 | int i; |
| 1200 | for (i = fs->firstlabel; i < ll->n; i++) { | 1191 | for (i = fs->bl->firstlabel; i < ll->n; i++) { |
| 1201 | if (eqstr(label, ll->arr[i].name)) { | 1192 | if (eqstr(label, ll->arr[i].name)) { |
| 1202 | const char *msg = luaO_pushfstring(ls->L, | 1193 | const char *msg = luaO_pushfstring(fs->ls->L, |
| 1203 | "label " LUA_QS " already defined on line %d", | 1194 | "label " LUA_QS " already defined on line %d", |
| 1204 | getstr(label), ll->arr[i].line); | 1195 | getstr(label), ll->arr[i].line); |
| 1205 | semerror(ls, msg); | 1196 | semerror(fs->ls, msg); |
| 1206 | } | 1197 | } |
| 1207 | } | 1198 | } |
| 1208 | } | 1199 | } |
| @@ -1213,7 +1204,7 @@ static void labelstat (LexState *ls, TString *label, int line) { | |||
| 1213 | FuncState *fs = ls->fs; | 1204 | FuncState *fs = ls->fs; |
| 1214 | Labellist *ll = &ls->dyd->label; | 1205 | Labellist *ll = &ls->dyd->label; |
| 1215 | int l; /* index of new label being created */ | 1206 | int l; /* index of new label being created */ |
| 1216 | checkrepeated(ls, fs, ll, label); /* check for repeated labels */ | 1207 | checkrepeated(fs, ll, label); /* check for repeated labels */ |
| 1217 | checknext(ls, TK_DBCOLON); /* skip double colon */ | 1208 | checknext(ls, TK_DBCOLON); /* skip double colon */ |
| 1218 | /* create new entry for this label */ | 1209 | /* create new entry for this label */ |
| 1219 | l = newlabelentry(ls, ll, label, line, fs->pc); | 1210 | l = newlabelentry(ls, ll, label, line, fs->pc); |
| @@ -1607,5 +1598,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |||
| 1607 | L->top--; /* pop name */ | 1598 | L->top--; /* pop name */ |
| 1608 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); | 1599 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); |
| 1609 | return funcstate.f; | 1600 | return funcstate.f; |
| 1601 | /* all scopes should be correctly finished */ | ||
| 1602 | lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); | ||
| 1610 | } | 1603 | } |
| 1611 | 1604 | ||
