On Thursday 04, Graham Wakefield wrote:
Hi,
Just wondering if any lua guru can suggest a way I might retrieve the
top-level lua_State pointer in a module's C function.
Given that a lua_State * can be spawned from another with
coroutine.create() or lua_newthread(L), it's not always guaranteed
that the lua_State * pointer you receive in module functions is
always
the same, but the top-level state would always be. Even the lua_State
* received in the luaopen_xxx call might not be the top level (e.g.
require() was called in a coroutine.)
The reason is that I need a unique index with which to call back into
distinct Lua universes, in a situation where several such universes
may coexist (but not interact) in the same application, and
(distinctly) load the same module. I would prefer not to defer this
responsibility to the application itself or require modifications to
Lua itself, as it would reduce the portability of the module in
question.
I hope the question is clear. Any ideas?
Two ideas, one hackish idea, and one non-hackish.
All coroutines/newthreads share the same global_State with the top-
level
lua_State. The top-level lua_State and the global_State are
allocated as one
chunk of memory.
At the top of the lstate.c file is this structure:
typedef struct LG {
lua_State l;
global_State g;
} LG;
So you can get the address of the top-level lua_State with this:
lua_State *top_L = (lua_State *)(G(L) - sizeof(global_State));
Since the LG structure is not exposed in any of the header files, I
would call
this a hack.
Another non-hack option, but requires adding the overhead of an
extra pointer
to each lua_State, would be to redefine the following macros in
luaconf.h
#define LUAI_EXTRASPACE 0
#define luai_userstateopen(L) ((void)L)
#define luai_userstateclose(L) ((void)L)
#define luai_userstatethread(L,L1) ((void)L)
#define luai_userstatefree(L) ((void)L)
#define luai_userstateresume(L,n) ((void)L)
#define luai_userstateyield(L,n) ((void)L)
You can use the extra space that will be allocated be for all
lua_State's to
store a pointer to the top-level lua_State. Then just redefine
luai_userstateopen & luai_userstatethread to copy & initialize that
pointer
to each new state.
--
Robert G. Jakabosky