lua-users home
lua-l archive

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

On Mon, Sep 2, 2013 at 7:59 PM, Tim Hill <> wrote:

On Sep 2, 2013, at 3:19 PM, Hao Wu <> wrote:

Hi Tim,

Would you explain a little bit more of how you play the trick? I would assume you compare the allocating size with the internal state object to see whether it's a state objects or other objects? but how do you get the state size in the first place? It is probably not reliable either right (what if one of userdata collides?)


There isn't really a "trick" as such. Remember my requirement: When Lua code calls a C function, it gets a Lua_State* as an argument so that it can access the Lua stack. In my case, I wanted to associate a main Lua_State with additional C application state.

Now, Lua_newstate() allows you to specify a custom memory allocator, and as a convenience for this allocator, Lua lets you also pass into the Lua_newstate() API an arbitrary pointer (void*) named ud. It stores this in the global (shared between all Lua_State structs) state, and allows you to recover it with lua_getallocf(). So basically I can store a unique void* for each main Lua_State* and recover it whenever a C function is called from Lua.

Of course, the pointer is aimed at helping the custom allocator, but there is nothing to stop you putting whatever you want in the void* pointer, and in my case we simply set it to the wrapper structure that includes the Lua_State* pointer.

I see. I thought you needed to wrap every lua_State including the coroutines. 
It's a bit messy, in that you have to have a custom allocator, and cannot use LuaL_newstate(), but otherwise is fine. I find it better than the EXTRASPACE trick since that is (a) undocumented, (b) hidden inside the Lua implementation and © not compatible with LuaJIT.

I checked this too, but still, the EXTRASPACE needs to recompile the source, which is probably not the decent solution.

Thanks for your explanation!