aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-12-22 13:52:53 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2022-12-22 13:52:53 -0300
commit7d4c7ae2af686df4a9f3cc0c6110986d886d55e6 (patch)
tree19c504432ef6a8631749783fda1b6622296a5a72 /lvm.c
parent873588dc5f04bfc37006c3dc6ceb9a495ea503f2 (diff)
downloadlua-7d4c7ae2af686df4a9f3cc0c6110986d886d55e6.tar.gz
lua-7d4c7ae2af686df4a9f3cc0c6110986d886d55e6.tar.bz2
lua-7d4c7ae2af686df4a9f3cc0c6110986d886d55e6.zip
Changes in opcodes for generic 'for'
Again, as the control variable is read only, the code doesn't need to keep an internal copy of it.
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/lvm.c b/lvm.c
index bdfef434..8ab8753d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1806,26 +1806,38 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1806 vmbreak; 1806 vmbreak;
1807 } 1807 }
1808 vmcase(OP_TFORPREP) { 1808 vmcase(OP_TFORPREP) {
1809 /* before: 'ra' has the iterator function, 'ra + 1' has the state,
1810 'ra + 2' has the initial value for the control variable, and
1811 'ra + 3' has the closing variable. This opcode then swaps the
1812 control and the closing variables and marks the closing variable
1813 as to-be-closed.
1814 */
1809 StkId ra = RA(i); 1815 StkId ra = RA(i);
1810 /* create to-be-closed upvalue (if needed) */ 1816 TValue temp; /* to swap control and closing variables */
1811 halfProtect(luaF_newtbcupval(L, ra + 3)); 1817 setobj(L, &temp, s2v(ra + 3));
1812 pc += GETARG_Bx(i); 1818 setobjs2s(L, ra + 3, ra + 2);
1813 i = *(pc++); /* go to next instruction */ 1819 setobj2s(L, ra + 2, &temp);
1820 /* create to-be-closed upvalue (if closing var. is not nil) */
1821 halfProtect(luaF_newtbcupval(L, ra + 2));
1822 pc += GETARG_Bx(i); /* go to end of the loop */
1823 i = *(pc++); /* fetch next instruction */
1814 lua_assert(GET_OPCODE(i) == OP_TFORCALL && ra == RA(i)); 1824 lua_assert(GET_OPCODE(i) == OP_TFORCALL && ra == RA(i));
1815 goto l_tforcall; 1825 goto l_tforcall;
1816 } 1826 }
1817 vmcase(OP_TFORCALL) { 1827 vmcase(OP_TFORCALL) {
1818 l_tforcall: { 1828 l_tforcall: {
1819 StkId ra = RA(i);
1820 /* 'ra' has the iterator function, 'ra + 1' has the state, 1829 /* 'ra' has the iterator function, 'ra + 1' has the state,
1821 'ra + 2' has the control variable, and 'ra + 3' has the 1830 'ra + 2' has the closing variable, and 'ra + 3' has the control
1822 to-be-closed variable. The call will use the stack after 1831 variable. The call will use the stack starting at 'ra + 3',
1823 these values (starting at 'ra + 4') 1832 so that it preserves the first three values, and the first
1833 return will be the new value for the control variable.
1824 */ 1834 */
1825 /* push function, state, and control variable */ 1835 StkId ra = RA(i);
1826 memcpy(ra + 4, ra, 3 * sizeof(*ra)); 1836 setobjs2s(L, ra + 5, ra + 3); /* copy the control variable */
1827 L->top.p = ra + 4 + 3; 1837 setobjs2s(L, ra + 4, ra + 1); /* copy state */
1828 ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ 1838 setobjs2s(L, ra + 3, ra); /* copy function */
1839 L->top.p = ra + 3 + 3;
1840 ProtectNT(luaD_call(L, ra + 3, GETARG_C(i))); /* do the call */
1829 updatestack(ci); /* stack may have changed */ 1841 updatestack(ci); /* stack may have changed */
1830 i = *(pc++); /* go to next instruction */ 1842 i = *(pc++); /* go to next instruction */
1831 lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); 1843 lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i));
@@ -1834,10 +1846,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1834 vmcase(OP_TFORLOOP) { 1846 vmcase(OP_TFORLOOP) {
1835 l_tforloop: { 1847 l_tforloop: {
1836 StkId ra = RA(i); 1848 StkId ra = RA(i);
1837 if (!ttisnil(s2v(ra + 4))) { /* continue loop? */ 1849 if (!ttisnil(s2v(ra + 3))) /* continue loop? */
1838 setobjs2s(L, ra + 2, ra + 4); /* save control variable */
1839 pc -= GETARG_Bx(i); /* jump back */ 1850 pc -= GETARG_Bx(i); /* jump back */
1840 }
1841 vmbreak; 1851 vmbreak;
1842 }} 1852 }}
1843 vmcase(OP_SETLIST) { 1853 vmcase(OP_SETLIST) {