lua-users home
lua-l archive

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

I'm trying to figure out how the lua gc works..

>From the manual:

"A light userdata represents a pointer. It is a value (like a number):
You do not create it, it has no metatables, it is not collected (as it
was never created). A light userdata is equal to "any" light userdata
with the same C address."

"A full userdata represents a block of memory. It is an object (like a
table): You must create it, it can have its own metatable, and you can
detect when it is being collected. A full userdata is only equal to
itself (under raw equality)."

Hmmm. Generally it seems: for lightuserdata, it seems safe for a 
pointer to static memory and nothing else. More precisely,
to make sure there are no references to it, you'd
have to delete the lua_State object (of an interpreter
using it) before deleting it. Conversely, the creator
would have to keep it around when the lua interpreter
it was passed to remained in existence.

For fulluserdata, you can put a pointer in it,
and the GC will invoke a callback when Lua finds
the fulluserdata object unreachable. This would
allow you to reflect that back to your native
memory manager.

In neither case does it seem you can just pass
Lua a pointer -- for light data, Lua doesn't reflect
reachability, for full data, you have to allocate
sizeof(pointer) and store the pointer (an extra

BTW: my GC doesn't allow this either .. I'm just trying
to figure out how to make them play together. 

I think you can think about this without knowing my GC, 
by considering getting two Lua interpreters to share data.

OK, I haven't found the following facility,
although it may be thre and I missed it:
how does one mark an object as a root?

This is necessary, so that even if an object is
unreachable, it isn't collected. It is marked
as a root, because someone *else* is using it.

For example: Lua interpreter #1 creates some object,
and passes it to #2. #1 must mark the object as a root.
It also uses sets the finalisation callback in #2,
so when it is unreachable in #2, the #2 finaliser
will 'unmark' the object as a root, so #1 can 
now collect it.

If this is done with full user data, it generalises
to arbitrary sharing, at the cost of one extra
level of indirection every time the object crosses
an interpreter boundary. 

It isn't clear how to make this seamless (transparent),
for any GC (not just Lua's or mine).

It also isn't clear what happens in Lua if you unravel
the full user data one level, and get the other interpreters
object out of it: which functions will work with this data
without triggering faulty GC operations? to be clear --
we'd be working with an object that is the correct structure
for a Lua object, and may even have been created by a 
lua API call .. but is used with a 'different' lua_State*
than it was created with.

The difficulty is that such an object, being a pointer,
may be put on the Lua stack .. then there is a reference
to it we don't know about .. OTOH Lua might know about it,
examining the stack, and incorrectly do something to
it .. such as try to do a mark or sweep on it .. 

John Skaller,
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language