lua-users home
lua-l archive

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

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_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