diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-10 14:58:31 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-10 14:58:31 -0300 |
commit | be8445d7e4b6122620c428877b51a27d464253d5 (patch) | |
tree | e0160895d105e5a3c20ec65c3196bffa042bd93f | |
parent | 3d296304ef14ac9a6d1fa9357541ddd9bb54722f (diff) | |
download | lua-be8445d7e4b6122620c428877b51a27d464253d5.tar.gz lua-be8445d7e4b6122620c428877b51a27d464253d5.tar.bz2 lua-be8445d7e4b6122620c428877b51a27d464253d5.zip |
Details
In the generic for loop, it is simpler for OP_TFORLOOP to use the
same 'ra' as OP_TFORCALL. Moreover, the internal names of the loop
temporaries "(for ...)" don't need to leak internal details (even
because the numerical for loop doesn't have a fixed role for each of
its temporaries).
-rw-r--r-- | lparser.c | 13 | ||||
-rw-r--r-- | lvm.c | 5 | ||||
-rw-r--r-- | testes/files.lua | 8 |
3 files changed, 13 insertions, 13 deletions
@@ -1527,7 +1527,6 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isgen) { | |||
1527 | if (isgen) { /* generic for? */ | 1527 | if (isgen) { /* generic for? */ |
1528 | luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); | 1528 | luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); |
1529 | luaK_fixline(fs, line); | 1529 | luaK_fixline(fs, line); |
1530 | base += 2; /* base for 'OP_TFORLOOP' (skips function and state) */ | ||
1531 | } | 1530 | } |
1532 | endfor = luaK_codeABx(fs, forloop[isgen], base, 0); | 1531 | endfor = luaK_codeABx(fs, forloop[isgen], base, 0); |
1533 | fixforjump(fs, endfor, prep + 1, 1); | 1532 | fixforjump(fs, endfor, prep + 1, 1); |
@@ -1539,9 +1538,9 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
1539 | /* fornum -> NAME = exp,exp[,exp] forbody */ | 1538 | /* fornum -> NAME = exp,exp[,exp] forbody */ |
1540 | FuncState *fs = ls->fs; | 1539 | FuncState *fs = ls->fs; |
1541 | int base = fs->freereg; | 1540 | int base = fs->freereg; |
1542 | new_localvarliteral(ls, "(for index)"); | 1541 | new_localvarliteral(ls, "(for state)"); |
1543 | new_localvarliteral(ls, "(for limit)"); | 1542 | new_localvarliteral(ls, "(for state)"); |
1544 | new_localvarliteral(ls, "(for step)"); | 1543 | new_localvarliteral(ls, "(for state)"); |
1545 | new_localvar(ls, varname); | 1544 | new_localvar(ls, varname); |
1546 | checknext(ls, '='); | 1545 | checknext(ls, '='); |
1547 | exp1(ls); /* initial value */ | 1546 | exp1(ls); /* initial value */ |
@@ -1566,10 +1565,10 @@ static void forlist (LexState *ls, TString *indexname) { | |||
1566 | int line; | 1565 | int line; |
1567 | int base = fs->freereg; | 1566 | int base = fs->freereg; |
1568 | /* create control variables */ | 1567 | /* create control variables */ |
1569 | new_localvarliteral(ls, "(for generator)"); | ||
1570 | new_localvarliteral(ls, "(for state)"); | 1568 | new_localvarliteral(ls, "(for state)"); |
1571 | new_localvarliteral(ls, "(for control)"); | 1569 | new_localvarliteral(ls, "(for state)"); |
1572 | new_localvarliteral(ls, "(for toclose)"); | 1570 | new_localvarliteral(ls, "(for state)"); |
1571 | new_localvarliteral(ls, "(for state)"); | ||
1573 | /* create declared variables */ | 1572 | /* create declared variables */ |
1574 | new_localvar(ls, indexname); | 1573 | new_localvar(ls, indexname); |
1575 | while (testnext(ls, ',')) { | 1574 | while (testnext(ls, ',')) { |
@@ -1746,14 +1746,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1746 | Protect(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ | 1746 | Protect(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ |
1747 | updatestack(ci); /* stack may have changed */ | 1747 | updatestack(ci); /* stack may have changed */ |
1748 | i = *(pc++); /* go to next instruction */ | 1748 | i = *(pc++); /* go to next instruction */ |
1749 | ra += 2; /* adjust for next instruction */ | ||
1750 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); | 1749 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); |
1751 | goto l_tforloop; | 1750 | goto l_tforloop; |
1752 | } | 1751 | } |
1753 | vmcase(OP_TFORLOOP) { | 1752 | vmcase(OP_TFORLOOP) { |
1754 | l_tforloop: | 1753 | l_tforloop: |
1755 | if (!ttisnil(s2v(ra + 2))) { /* continue loop? */ | 1754 | if (!ttisnil(s2v(ra + 4))) { /* continue loop? */ |
1756 | setobjs2s(L, ra, ra + 2); /* save control variable */ | 1755 | setobjs2s(L, ra + 2, ra + 4); /* save control variable */ |
1757 | pc -= GETARG_Bx(i); /* jump back */ | 1756 | pc -= GETARG_Bx(i); /* jump back */ |
1758 | } | 1757 | } |
1759 | vmbreak; | 1758 | vmbreak; |
diff --git a/testes/files.lua b/testes/files.lua index 54931c14..c8f23d18 100644 --- a/testes/files.lua +++ b/testes/files.lua | |||
@@ -427,10 +427,12 @@ do -- testing closing file in line iteration | |||
427 | -- get the to-be-closed variable from a loop | 427 | -- get the to-be-closed variable from a loop |
428 | local function gettoclose (lv) | 428 | local function gettoclose (lv) |
429 | lv = lv + 1 | 429 | lv = lv + 1 |
430 | for i = 1, math.maxinteger do | 430 | local stvar = 0 -- to-be-closed is 4th state variable in the loop |
431 | for i = 1, 1000 do | ||
431 | local n, v = debug.getlocal(lv, i) | 432 | local n, v = debug.getlocal(lv, i) |
432 | if n == "(for toclose)" then | 433 | if n == "(for state)" then |
433 | return v | 434 | stvar = stvar + 1 |
435 | if stvar == 4 then return v end | ||
434 | end | 436 | end |
435 | end | 437 | end |
436 | end | 438 | end |