aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-08-14 15:33:14 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-08-14 15:33:14 -0300
commitac65bab25f1eaaf70e1826a6937a74b3a55b521b (patch)
treea8220432c19dde69af92e720008863f821d1ce96 /lparser.c
parentf185c0132e09a5e0a32782c674de75b510f887d8 (diff)
downloadlua-ac65bab25f1eaaf70e1826a6937a74b3a55b521b.tar.gz
lua-ac65bab25f1eaaf70e1826a6937a74b3a55b521b.tar.bz2
lua-ac65bab25f1eaaf70e1826a6937a74b3a55b521b.zip
jumps in 'for' loops don't need to be signed
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/lparser.c b/lparser.c
index 3df5a958..2eb5581f 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.162 2017/06/29 15:38:41 roberto Exp roberto $ 2** $Id: lparser.c,v 2.163 2017/08/12 13:12:21 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*/
@@ -1307,6 +1307,22 @@ static int exp1 (LexState *ls) {
1307} 1307}
1308 1308
1309 1309
1310/*
1311** Fix for instruction at position 'pc' to jump to 'dest'.
1312** (Jump addresses are relative in Lua). 'back' true means
1313** a back jump.
1314*/
1315static void fixforjump (FuncState *fs, int pc, int dest, int back) {
1316 Instruction *jmp = &fs->f->code[pc];
1317 int offset = dest - (pc + 1);
1318 if (back)
1319 offset = -offset;
1320 if (offset > MAXARG_Bx)
1321 luaX_syntaxerror(fs->ls, "control structure too long");
1322 SETARG_Bx(*jmp, offset);
1323}
1324
1325
1310static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { 1326static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1311 /* forbody -> DO block */ 1327 /* forbody -> DO block */
1312 BlockCnt bl; 1328 BlockCnt bl;
@@ -1314,21 +1330,23 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
1314 int prep, endfor; 1330 int prep, endfor;
1315 adjustlocalvars(ls, 3); /* control variables */ 1331 adjustlocalvars(ls, 3); /* control variables */
1316 checknext(ls, TK_DO); 1332 checknext(ls, TK_DO);
1317 prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); 1333 prep = isnum ? luaK_codeABx(fs, OP_FORPREP, base, 0) : luaK_jump(fs);
1318 enterblock(fs, &bl, 0); /* scope for declared variables */ 1334 enterblock(fs, &bl, 0); /* scope for declared variables */
1319 adjustlocalvars(ls, nvars); 1335 adjustlocalvars(ls, nvars);
1320 luaK_reserveregs(fs, nvars); 1336 luaK_reserveregs(fs, nvars);
1321 block(ls); 1337 block(ls);
1322 leaveblock(fs); /* end of scope for declared variables */ 1338 leaveblock(fs); /* end of scope for declared variables */
1323 luaK_patchtohere(fs, prep); 1339 if (isnum) { /* numeric for? */
1324 if (isnum) /* numeric for? */ 1340 fixforjump(fs, prep, luaK_getlabel(fs), 0);
1325 endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); 1341 endfor = luaK_codeABx(fs, OP_FORLOOP, base, 0);
1342 }
1326 else { /* generic for */ 1343 else { /* generic for */
1344 luaK_patchtohere(fs, prep);
1327 luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); 1345 luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars);
1328 luaK_fixline(fs, line); 1346 luaK_fixline(fs, line);
1329 endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); 1347 endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP);
1330 } 1348 }
1331 luaK_patchlist(fs, endfor, prep + 1); 1349 fixforjump(fs, endfor, prep + 1, 1);
1332 luaK_fixline(fs, line); 1350 luaK_fixline(fs, line);
1333} 1351}
1334 1352