summaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2011-09-14 14:40:26 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2011-09-14 14:40:26 -0300
commit500336efd087c02d663797e6d1c256f65e281f05 (patch)
treed530000b29755ee169a9b94bbeb7d5e41b870397 /lparser.c
parent5ea8f108e123317b27b7b4b22209aab19d781605 (diff)
downloadlua-500336efd087c02d663797e6d1c256f65e281f05.tar.gz
lua-500336efd087c02d663797e6d1c256f65e281f05.tar.bz2
lua-500336efd087c02d663797e6d1c256f65e281f05.zip
small bug in if-goto optimization: block must be closed ('leaveblock')
*before* the jump out ('escapelist')
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/lparser.c b/lparser.c
index 56faf1e9..7841c937 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.117 2011/08/25 13:45:24 roberto Exp roberto $ 2** $Id: lparser.c,v 2.118 2011/08/30 16:38:58 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*/
@@ -1376,27 +1376,30 @@ static void test_then_block (LexState *ls, int *escapelist) {
1376 expdesc v; 1376 expdesc v;
1377 int jf; /* instruction to skip 'then' code (if condition is false) */ 1377 int jf; /* instruction to skip 'then' code (if condition is false) */
1378 luaX_next(ls); /* skip IF or ELSEIF */ 1378 luaX_next(ls); /* skip IF or ELSEIF */
1379 enterblock(fs, &bl, 0);
1380 expr(ls, &v); /* read condition */ 1379 expr(ls, &v); /* read condition */
1381 checknext(ls, TK_THEN); 1380 checknext(ls, TK_THEN);
1382 if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) { 1381 if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
1383 luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ 1382 luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
1383 enterblock(fs, &bl, 0); /* must enter block before 'goto' */
1384 gotostat(ls, v.t); /* handle goto/break */ 1384 gotostat(ls, v.t); /* handle goto/break */
1385 if (block_follow(ls, 0)) /* no more code after 'goto'? */ 1385 if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
1386 goto leave; /* that is it */ 1386 leaveblock(fs);
1387 return; /* and that is it */
1388 }
1387 else /* must skip over 'then' part if condition is false */ 1389 else /* must skip over 'then' part if condition is false */
1388 jf = luaK_jump(fs); 1390 jf = luaK_jump(fs);
1389 } 1391 }
1390 else { /* regular case (not goto/break) */ 1392 else { /* regular case (not goto/break) */
1391 luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ 1393 luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */
1394 enterblock(fs, &bl, 0);
1392 jf = v.f; 1395 jf = v.f;
1393 } 1396 }
1394 statlist(ls); /* `then' part */ 1397 statlist(ls); /* `then' part */
1398 leaveblock(fs);
1395 if (ls->t.token == TK_ELSE || 1399 if (ls->t.token == TK_ELSE ||
1396 ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ 1400 ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */
1397 luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ 1401 luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */
1398 luaK_patchtohere(fs, jf); 1402 luaK_patchtohere(fs, jf);
1399 leave: leaveblock(fs);
1400} 1403}
1401 1404
1402 1405