[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: RE: Can full userdata be put back on the stack?
- From: Benoit Germain <bgermain@...>
- Date: Wed, 11 Dec 2002 16:16:43 +0100
> > some C function in your engine pushes a function (that
> happens to be of C
> > type) on the LUA stack, lua_pcall() it, and this leaves a
> full userdata on
> > the LUA stack as a result, from which you extract the pointer ?
> > If so, I think your full userdata can be collected anytime
> you call LUA
> > again unless you lua_ref() it.
> I'll try to be a bit more accurate:
> 1) Main program M registers the C function A with Lua as
> "func_a", the C
> function B with Lua as "func_b"
> 2) M executes loadbuffer with string "x=func_a()" and pcalls it
> 3) Lua passes control to the C function A which creates a new
> userdata of
> size, sizeof(int) and sets the value to 42. It also saves the
> pointer returned
> by lua_newuserdata in the C variable y.
> 4) Lua assigns the new userdata to Lua variable x and passes
> control back to M.
> 5) M executes loadbuffer with string "z=func_b()" and pcalls it
> 6) Lua passes control to the C function B which pushes the
> value of y (a
> pointer to userdata) on the Lua stack.
> The userdata pointed to by y cannot be garbage collected
> since it is still
> held by Lua variable x.
> 7) Lua assigns the userdata to the Lua variable z.
> 8) After these steps the Lua variables x and y are equal, and
> if passed to
> another C function registered with Lua and are interpreted as
> pointers to ints
> they should contain 42.
> My questions are 1) Is this recommended, or should setp 6
> create a new
> userdata of size sizeof(int) and store 42 in it.
> 2) If it is recommended then what lua_* function do I use to
> push the userdata
> pointer onto the stack. Is it lua_pushlightuserdata since
> that seems to have
> the correct signature.
> You can assume that there is no C program which will change
> the value of a
> userdata. Once it is initialised it will not be changed.
If you want some C function to receive z and change x by accessing the
memory location it points to, you need to do this, because if z is another
full userdata, it is in a different memory location. You could do something
else though: when x is created, store an entry in the registry where y is
the key and x the value: then instead of passing y to func_b, retrieve x
from y in the registry and pass this instead.
This also guarantees that your full userdata will never be collected,
because there is a reference in the registry (unless you store all such
references in a table with weak values, this table being kept in the
> Thank you,
> Steven Murdoch.