[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: 5.2 _ENV garbage collection question
- From: Gaspard Bucher <gaspard@...>
- Date: Mon, 27 Jun 2011 16:21:58 +0200
On Mon, Jun 27, 2011 at 3:02 PM, Peter Cawley
<lua@corsix.org> wrote:
On Mon, Jun 27, 2011 at 1:57 PM, Gaspard Bucher <
gaspard@teti.ch> wrote:
> This means that the required script gets the original global _ENV even
> though _LOADED._G has been changed. It can also read the first "foo".
>
> It seems that removing _LOADED._G is not enough to purge "foo"...
That would be because when a chunk is loaded, it is assigned as its
environment the value require"debug".getregistry()[2]. The environment
for your first chunk was from here, so unless changed, your second
chunk gets the same thing from here.
Thanks Moonlit master ! From the sources, index 2 in the registry is:
#define LUA_RIDX_GLOBALS 2
It's nice to know that the environment for loaded chunks comes from there. With this knew knowledge, I tried different scenarios to purge the global environment, and the only solution I found is either to set _ENV before setting "foo" and then removing the environment or to nil "foo":
===================== test4.lua
local print, collectgarbage = print, collectgarbage
local req = require "debug".getregistry()
local gc_mt = {}
function gc_mt.__gc(tbl)
end
foo = {name='foo'}
setmetatable(foo,gc_mt)
_ENV = {}
req[2].foo = nil --- we cannot completely nil the global environment (error in __gc tag method (attempt to call a nil value)...
collectgarbage() --- correctly garbage collects "foo"
print('end')
=====================
Gaspard