aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2011-02-14 14:36:34 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2011-02-14 14:36:34 -0200
commitc0a865fa54b3c692af3783bd9470b8c0537b77b4 (patch)
treee641cdb906ae94ca80472333c26772102aff2093 /lparser.c
parent0009ac1f3addb79e3cb4f1f1d12929a975f1f241 (diff)
downloadlua-c0a865fa54b3c692af3783bd9470b8c0537b77b4.tar.gz
lua-c0a865fa54b3c692af3783bd9470b8c0537b77b4.tar.bz2
lua-c0a865fa54b3c692af3783bd9470b8c0537b77b4.zip
error for repeated label + jumps allowed to labels followed by
'no-op' statements
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/lparser.c b/lparser.c
index 6933499e..56cd417a 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.104 2011/02/10 14:50:41 roberto Exp roberto $ 2** $Id: lparser.c,v 2.105 2011/02/14 14:59:28 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*/
@@ -339,8 +339,8 @@ static void enterlevel (LexState *ls) {
339static void closegoto (LexState *ls, int g, Labeldesc *label) { 339static void closegoto (LexState *ls, int g, Labeldesc *label) {
340 int i; 340 int i;
341 FuncState *fs = ls->fs; 341 FuncState *fs = ls->fs;
342 Dyndata *dyd = ls->dyd; 342 Labellist *gl = &ls->dyd->gt;
343 Labeldesc *gt = &dyd->gt.arr[g]; 343 Labeldesc *gt = &gl->arr[g];
344 lua_assert(eqstr(gt->name, label->name)); 344 lua_assert(eqstr(gt->name, label->name));
345 if (gt->nactvar < label->nactvar) { 345 if (gt->nactvar < label->nactvar) {
346 const char *msg = luaO_pushfstring(ls->L, 346 const char *msg = luaO_pushfstring(ls->L,
@@ -350,9 +350,9 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) {
350 } 350 }
351 luaK_patchlist(fs, gt->pc, label->pc); 351 luaK_patchlist(fs, gt->pc, label->pc);
352 /* remove goto from pending list */ 352 /* remove goto from pending list */
353 for (i = g; i < dyd->gt.n - 1; i++) 353 for (i = g; i < gl->n - 1; i++)
354 dyd->gt.arr[i] = dyd->gt.arr[i + 1]; 354 gl->arr[i] = gl->arr[i + 1];
355 dyd->gt.n--; 355 gl->n--;
356} 356}
357 357
358 358
@@ -397,10 +397,10 @@ static int newlabelentry (LexState *ls, Labellist *l, TString *name,
397** block; solves forward jumps 397** block; solves forward jumps
398*/ 398*/
399static void findgotos (LexState *ls, Labeldesc *lb) { 399static void findgotos (LexState *ls, Labeldesc *lb) {
400 Dyndata *dyd = ls->dyd; 400 Labellist *gl = &ls->dyd->gt;
401 int i = ls->fs->bl->firstgoto; 401 int i = ls->fs->bl->firstgoto;
402 while (i < dyd->gt.n) { 402 while (i < gl->n) {
403 if (eqstr(dyd->gt.arr[i].name, lb->name)) 403 if (eqstr(gl->arr[i].name, lb->name))
404 closegoto(ls, i, lb); 404 closegoto(ls, i, lb);
405 else 405 else
406 i++; 406 i++;
@@ -416,11 +416,11 @@ static void findgotos (LexState *ls, Labeldesc *lb) {
416*/ 416*/
417static void movegotosout (FuncState *fs, BlockCnt *bl) { 417static void movegotosout (FuncState *fs, BlockCnt *bl) {
418 int i = bl->firstgoto; 418 int i = bl->firstgoto;
419 Dyndata *dyd = fs->ls->dyd; 419 Labellist *gl = &fs->ls->dyd->gt;
420 /* correct pending gotos to current block and try to close it 420 /* correct pending gotos to current block and try to close it
421 with visible labels */ 421 with visible labels */
422 while (i < dyd->gt.n) { 422 while (i < gl->n) {
423 Labeldesc *gt = &dyd->gt.arr[i]; 423 Labeldesc *gt = &gl->arr[i];
424 if (gt->nactvar > bl->nactvar) { 424 if (gt->nactvar > bl->nactvar) {
425 if (bl->upval) 425 if (bl->upval)
426 luaK_patchclose(fs, gt->pc, bl->nactvar); 426 luaK_patchclose(fs, gt->pc, bl->nactvar);
@@ -1185,21 +1185,31 @@ static void gotostat (LexState *ls, TString *label, int line) {
1185} 1185}
1186 1186
1187 1187
1188static void labelstat (LexState *ls, TString *label) { 1188static void labelstat (LexState *ls, TString *label, int line) {
1189 /* label -> '@' NAME ':' */ 1189 /* label -> '@' NAME ':' */
1190 FuncState *fs = ls->fs; 1190 FuncState *fs = ls->fs;
1191 int l; /* index of new label being created */ 1191 Labellist *ll = &ls->dyd->label;
1192 Labeldesc *lb; 1192 int l, i; /* index of new label being created */
1193 checknext(ls, ':'); 1193 /* check for repeated labels on the same block */
1194 for (i = ls->fs->bl->firstlabel; i < ll->n; i++) {
1195 if (eqstr(label, ll->arr[i].name)) {
1196 const char *msg = luaO_pushfstring(ls->L,
1197 "label " LUA_QS " already defined on line %d",
1198 getstr(label), ll->arr[i].line);
1199 semerror(ls, msg);
1200 }
1201 }
1202 checknext(ls, ':'); /* skip colon */
1194 /* create new entry for this label */ 1203 /* create new entry for this label */
1195 l = newlabelentry(ls, &ls->dyd->label, label, 0, fs->pc); 1204 l = newlabelentry(ls, ll, label, line, fs->pc);
1196 lb = &ls->dyd->label.arr[l]; 1205 /* skip other no-op statements */
1197 while (testnext(ls, ';')) ; /* skip trailing semicolons */ 1206 while (ls->t.token == ';' || ls->t.token == '@')
1198 if (block_follow(ls, 0)) { /* label is last statement in the block? */ 1207 statement(ls);
1208 if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
1199 /* assume that locals are already out of scope */ 1209 /* assume that locals are already out of scope */
1200 lb->nactvar = fs->bl->nactvar; 1210 ll->arr[l].nactvar = fs->bl->nactvar;
1201 } 1211 }
1202 findgotos(ls, lb); 1212 findgotos(ls, &ll->arr[l]);
1203} 1213}
1204 1214
1205 1215
@@ -1476,7 +1486,7 @@ static void retstat (LexState *ls) {
1476 } 1486 }
1477 } 1487 }
1478 luaK_ret(fs, first, nret); 1488 luaK_ret(fs, first, nret);
1479 testnext(ls, ';'); /* skip optional semicollon */ 1489 testnext(ls, ';'); /* skip optional semicolon */
1480} 1490}
1481 1491
1482 1492
@@ -1524,7 +1534,7 @@ static void statement (LexState *ls) {
1524 } 1534 }
1525 case '@': { /* stat -> label */ 1535 case '@': { /* stat -> label */
1526 luaX_next(ls); /* skip '@' */ 1536 luaX_next(ls); /* skip '@' */
1527 labelstat(ls, str_checkname(ls)); 1537 labelstat(ls, str_checkname(ls), line);
1528 break; 1538 break;
1529 } 1539 }
1530 case TK_RETURN: { /* stat -> retstat */ 1540 case TK_RETURN: { /* stat -> retstat */