lua-users home
lua-l archive

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


Thanks - but these rely on either modifying the lua core or assuming the layout of memory internal to the lua core, neither of which are really portable.

But good to know about LG if no other solution can be found.

On Jun 4, 2009, at 6:11 PM, Robert G. Jakabosky wrote:

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