From 7f6f70853c8a2730fca2e95d5968ad52cf470bda Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy <roberto@inf.puc-rio.br> Date: Wed, 7 Nov 2018 14:42:05 -0200 Subject: To-be-closed variable in 'for' loop separated from the state The variable to be closed in a generic 'for' loop now is the 4th value produced in the loop initialization, instead of being the loop state (the 2nd value produced). That allows a loop to use a state with a '__toclose' metamethod but do not close it. (As an example, 'f:lines()' might use the file 'f' as a state for the loop, but it should not close the file when the loop ends.) --- lvm.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'lvm.c') diff --git a/lvm.c b/lvm.c index 9977bda4..7d5ab9db 100644 --- a/lvm.c +++ b/lvm.c @@ -1654,11 +1654,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmbreak; } vmcase(OP_TFORPREP) { - /* is 'state' a function or has a '__close' metamethod? */ - if (ttisfunction(s2v(ra + 1)) || - !ttisnil(luaT_gettmbyobj(L, s2v(ra + 1), TM_CLOSE))) { + /* is 'toclose' a function or has a '__close' metamethod? */ + if (ttisfunction(s2v(ra + 3)) || + !ttisnil(luaT_gettmbyobj(L, s2v(ra + 3), TM_CLOSE))) { /* create to-be-closed upvalue for it */ - halfProtect(luaF_newtbcupval(L, ra + 1)); + halfProtect(luaF_newtbcupval(L, ra + 3)); } pc += GETARG_Bx(i); i = *(pc++); /* go to next instruction */ @@ -1668,13 +1668,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmcase(OP_TFORCALL) { l_tforcall: /* 'ra' has the iterator function, 'ra + 1' has the state, - and 'ra + 2' has the control variable. The call will use - the stack after these values (starting at 'ra + 3') + 'ra + 2' has the control variable, and 'ra + 3' has the + to-be-closed variable. The call will use the stack after + these values (starting at 'ra + 4') */ /* push function, state, and control variable */ - memcpy(ra + 3, ra, 3 * sizeof(*ra)); - L->top = ra + 6; - Protect(luaD_call(L, ra + 3, GETARG_C(i))); /* do the call */ + memcpy(ra + 4, ra, 3 * sizeof(*ra)); + L->top = ra + 4 + 3; + Protect(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ if (trap) { /* stack may have changed? */ updatebase(ci); /* keep 'base' correct */ ra = RA(i); /* keep 'ra' correct for next instruction */ @@ -1686,8 +1687,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { } vmcase(OP_TFORLOOP) { l_tforloop: - if (!ttisnil(s2v(ra + 1))) { /* continue loop? */ - setobjs2s(L, ra, ra + 1); /* save control variable */ + if (!ttisnil(s2v(ra + 2))) { /* continue loop? */ + setobjs2s(L, ra, ra + 2); /* save control variable */ pc -= GETARG_Bx(i); /* jump back */ } vmbreak; -- cgit v1.2.3-55-g6feb