lua-users home
lua-l archive

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


On 19 February 2017 at 13:24, Martin <eden_martin_fuhrspam@gmx.de> wrote:
> I offer to make values of table "package.loaded" weak to free
> unreachable data at garbage collection cycle.
... snip ...
>   setmetatable(package.loaded, {__mode = 'v'})

I like the idea; though there is the relatively major issue of modules
that don't like being reloaded.

Infact, *most* C modules don't cope well with being reloaded in the
general case.
e.g. a module that registers a metatable with `luaL_setmetatable`
inside of it's `luaopen_` function.
On a reload, this would replace the current metatable in the registry
with a new one.
This would mean that object instances created before the module was
reloaded would not pass luaL_checkudata, even for their own methods!

This fact means that the idea shouldn't be implemented with the
current status-quo for C modules.
But it does bring up the issue I mentioned above, and there *are* ways
to fix it going forward:
Instead of using luaL_checkudata, you can store the metatable as an
upvalue for your C functions, and check that, this has the added
benefit of being *faster*, it also has the benefit of not requiring an
allocation.
A few existing modules do this, e.g. cqueues:
https://github.com/wahern/cqueues/blob/00ad5b9425ba863ed74f3bcbea2049eedcb6c53b/src/cqueues.h#L313

I wonder if future lua versions could encourage this pattern with the
right helpers e.g.
  - A luaL_newlib-like that has an #upvalues argument (like
luaL_setfuncs already does)
  - A luaL_testudata-like that takes an upvalue index to use instead
of a registry key