[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: caching userdata pointers, lua_pushuserdata?
- From: Mark Hamburg <mhamburg@...>
- Date: Mon, 25 Jul 2005 22:30:42 -0700
Technically, this isn't safe. Amongst other things, if the userdata has been
collected, this call corrupts the Lua state.
That being said, I've written this code (though I later took it out).
Someone else also posted essentially the same thing a month or two ago. So,
it's clearly an issue that a lot of people encounter.
The safe way to do this is to maintain a weak table mapping the userdata
pointers as light userdata to the full userdata objects. Pushing then
becomes something like the following:
lua_pushlightuserdata( L, &myUDMapKey );
lua_gettable( L, LUA_REGISTRYINDEX );
lua_pushlightuserdata( L, theUserData );
lua_gettable( L, -2 );
lua_remove( L, -2 );
(I used a light userdata rather than an integer to key the registry because
it's easier to guarantee unique.)
Mark
on 7/25/05 5:45 PM, Kriss at Kriss@XIXs.com wrote:
>
> I was just thinking about tidying up some code and want to do the
> following.
>
> cache a pointer returned from lua_touserdata() on the C side (I am
> already doing this anyway)
>
> at some point later on, push that userdata onto the stack to be used as
> a table look up key, I can guarantee that the userdata will not have
> been GCd at this point. At the moment I am using a unique integer as a
> table key, but it would be simpler to use the userdata instead.
>
> however there is no lua_pushuserdata()
>
> Is it safe just to use a modified version of lua_newuserdata() that
> doesnt allocate any new userdata but takes a previously allocated
> pointer and pushes it on the stack?
>
> EG some untested 5.0 code :)
>
> LUA_API void lua_pushuserdata (lua_State *L, void *data) {
> lua_lock(L);
> luaC_checkGC(L);
> setuvalue(L->top, ((Udata *)(data))-1);
> api_incr_top(L);
> lua_unlock(L);
> }
>
> or is there some more magic surrounding userdata I should be aware of.