aboutsummaryrefslogtreecommitdiff
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
parentf185c0132e09a5e0a32782c674de75b510f887d8 (diff)
downloadlua-ac65bab25f1eaaf70e1826a6937a74b3a55b521b.tar.gz
lua-ac65bab25f1eaaf70e1826a6937a74b3a55b521b.tar.bz2
lua-ac65bab25f1eaaf70e1826a6937a74b3a55b521b.zip
jumps in 'for' loops don't need to be signed
-rw-r--r--lopcodes.c8
-rw-r--r--lopcodes.h10
-rw-r--r--lparser.c30
-rw-r--r--lvm.c10
4 files changed, 38 insertions, 20 deletions
diff --git a/lopcodes.c b/lopcodes.c
index 163eff60..74195d42 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.58 2017/04/28 20:57:45 roberto Exp roberto $ 2** $Id: lopcodes.c,v 1.59 2017/06/29 15:38:41 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -124,10 +124,10 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
124 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ 124 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
125 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ 125 ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
126 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ 126 ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
127 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ 127 ,opmode(0, 1, OpArgR, OpArgN, iABx) /* OP_FORLOOP */
128 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 128 ,opmode(0, 1, OpArgR, OpArgN, iABx) /* OP_FORPREP */
129 ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ 129 ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */
130 ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ 130 ,opmode(0, 1, OpArgR, OpArgN, iABx) /* OP_TFORLOOP */
131 ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ 131 ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
132 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 132 ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
133 ,opmode(0, 1, OpArgU, OpArgR, iABC) /* OP_VARARG */ 133 ,opmode(0, 1, OpArgU, OpArgR, iABC) /* OP_VARARG */
diff --git a/lopcodes.h b/lopcodes.h
index fb989ac6..f35de02a 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.154 2017/05/08 16:08:01 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.155 2017/06/29 15:38:41 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -229,12 +229,12 @@ OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
229OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ 229OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
230OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ 230OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
231 231
232OP_FORLOOP,/* A sBx R(A)+=R(A+2); 232OP_FORLOOP,/* A Bx R(A)+=R(A+2);
233 if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ 233 if R(A) <?= R(A+1) then { pc-=Bx; R(A+3)=R(A) }*/
234OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ 234OP_FORPREP,/* A Bx R(A)-=R(A+2); pc+=Bx */
235 235
236OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */ 236OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
237OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/ 237OP_TFORLOOP,/* A Bx if R(A+1) ~= nil then { R(A)=R(A+1); pc -= Bx }*/
238 238
239OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ 239OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
240 240
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
diff --git a/lvm.c b/lvm.c
index 18799be7..be4793d1 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.289 2017/06/29 15:38:41 roberto Exp roberto $ 2** $Id: lvm.c,v 2.290 2017/07/07 16:34:32 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -1335,7 +1335,7 @@ void luaV_execute (lua_State *L) {
1335 lua_Integer idx = intop(+, ivalue(s2v(ra)), step); /* increment index */ 1335 lua_Integer idx = intop(+, ivalue(s2v(ra)), step); /* increment index */
1336 lua_Integer limit = ivalue(s2v(ra + 1)); 1336 lua_Integer limit = ivalue(s2v(ra + 1));
1337 if ((0 < step) ? (idx <= limit) : (limit <= idx)) { 1337 if ((0 < step) ? (idx <= limit) : (limit <= idx)) {
1338 pc += GETARG_sBx(i); /* jump back */ 1338 pc -= GETARG_Bx(i); /* jump back */
1339 chgivalue(s2v(ra), idx); /* update internal index... */ 1339 chgivalue(s2v(ra), idx); /* update internal index... */
1340 setivalue(s2v(ra + 3), idx); /* ...and external index */ 1340 setivalue(s2v(ra + 3), idx); /* ...and external index */
1341 } 1341 }
@@ -1347,7 +1347,7 @@ void luaV_execute (lua_State *L) {
1347 idx = luai_numadd(L, idx, step); /* inc. index */ 1347 idx = luai_numadd(L, idx, step); /* inc. index */
1348 if (luai_numlt(0, step) ? luai_numle(idx, limit) 1348 if (luai_numlt(0, step) ? luai_numle(idx, limit)
1349 : luai_numle(limit, idx)) { 1349 : luai_numle(limit, idx)) {
1350 pc += GETARG_sBx(i); /* jump back */ 1350 pc -= GETARG_Bx(i); /* jump back */
1351 chgfltvalue(s2v(ra), idx); /* update internal index... */ 1351 chgfltvalue(s2v(ra), idx); /* update internal index... */
1352 setfltvalue(s2v(ra + 3), idx); /* ...and external index */ 1352 setfltvalue(s2v(ra + 3), idx); /* ...and external index */
1353 } 1353 }
@@ -1381,7 +1381,7 @@ void luaV_execute (lua_State *L) {
1381 luaG_runerror(L, "'for' initial value must be a number"); 1381 luaG_runerror(L, "'for' initial value must be a number");
1382 setfltvalue(init, luai_numsub(L, ninit, nstep)); 1382 setfltvalue(init, luai_numsub(L, ninit, nstep));
1383 } 1383 }
1384 pc += GETARG_sBx(i); 1384 pc += GETARG_Bx(i);
1385 vmbreak; 1385 vmbreak;
1386 } 1386 }
1387 vmcase(OP_TFORCALL) { 1387 vmcase(OP_TFORCALL) {
@@ -1401,7 +1401,7 @@ void luaV_execute (lua_State *L) {
1401 l_tforloop: 1401 l_tforloop:
1402 if (!ttisnil(s2v(ra + 1))) { /* continue loop? */ 1402 if (!ttisnil(s2v(ra + 1))) { /* continue loop? */
1403 setobjs2s(L, ra, ra + 1); /* save control variable */ 1403 setobjs2s(L, ra, ra + 1); /* save control variable */
1404 pc += GETARG_sBx(i); /* jump back */ 1404 pc -= GETARG_Bx(i); /* jump back */
1405 } 1405 }
1406 vmbreak; 1406 vmbreak;
1407 } 1407 }