lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

On Tue, Oct 20, 2020 at 11:28 PM 孙世龙 sunshilong <> wrote:
> >The loop keeps a reference of the value passed to 'pairs' which disappears when the goto statement executes.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Not after the statement executed?

The effect of a "goto" that exits a block like this is twofold:
- any explicit or implicit local variables that go out of scope are
destroyed. The objects that they refer to are not destroyed (but any
"__close" methods are called).
- the program continues at the target label.

The way this works: the Lua 5.4 interpreter translates the "goto
BEGIN" into two VM instructions:
JMP -22

"CLOSE 0" destroys all local variables, in this case the 3 loop
variables containing the "next" function, the value of "list" when the
loop was entered, and the current value of "k". This happens after
"collectgarbage" is called, so the previous value of "list" is still
reachable. This causes the delay.

When exactly all this happens is not all that relevant, it has not
happened before the goto is executed, and by the time the loop is
entered again it has. If the Lua compiler was sufficiently "clever" it
could even conclude that the 3 loop variables are no longer needed
right after "list = v" and destroy them right there.

In general you should not rely on the timing of the call to "__gc"
because it may change between Lua versions. A change would be legal
because the exact behavior is not specified in the spec. Because
"__gc" is called at an unknown point in the execution of your program
its use is a bit dangerous, it's best not to change anything outside
of the object about to be collected.