lua-users home
lua-l archive

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


Hello Christian,

On Wed, Jan 6, 2010 at 8:17 AM, Christian Tellefsen
<christian.tellefsen@funcom.com> wrote:
> Hi,
>
> I have a question about the Lua registry, environment, and threads. I have
> the following code:
>
> int Test(lua_State * L )
> {
> Âlua_getglobal(L, "print");
> Âlua_getglobal(L, "a");
> Âlua_pcall(L, 1, 0, 0);
>
> Âreturn 0;
> }
>
> int main (void) {
> Âint error;
> Âlua_State * L = lua_open(); Â /* opens Lua */
> ÂluaL_openlibs(L);
>
> Âlua_pushnumber(L, 0); Â// In the global environment, a = 0
> Âlua_setglobal(L, "a");
>
> Â// Create a thread with its own environment.
> Âlua_State * L1 = lua_newthread(L);
>
> Âlua_pushthread(L1); Â Â Â Â Â Â Â Â Â// thread
> Âlua_newtable(L1); Â Â Â Â Â Â Â Â Â Â// thread, t
> Âlua_pushvalue(L1, LUA_GLOBALSINDEX); // thread, t, _G
> Âlua_setfield(L1, -2, "__index"); Â Â // thread, t
> Âlua_pushvalue(L1, -1); Â Â Â Â Â Â Â // thread, t, t
> Âlua_setmetatable(L1, -2); Â Â Â Â Â Â// thread, t
> Âlua_setfenv(L1, -2); Â Â Â Â Â Â Â Â // thread
>
> Âlua_pushnumber(L1, 1); Â// In the thread environment, a = 1
> Âlua_setglobal(L1, "a");
>
> Âlua_pop(L1, 1); Â Â Â Â Â Â Â Â Â Â Â// -
>
> Â// Put the C function in the registry, and retrieve it and call it from the
> root and the child thread.
> Âlua_pushcfunction(L, &Test);
> Âint r0 = luaL_ref(L, LUA_REGISTRYINDEX);
>
> Âlua_rawgeti(L, LUA_REGISTRYINDEX, r0);
> Âlua_pcall(L, 0, 0, 0);
>
> Âlua_rawgeti(L1, LUA_REGISTRYINDEX, r0);
> Âlua_pcall(L1, 0, 0, 0);
>
> Â// Load the buffer and store it in registry, and retrieve it and call it
> from the root and the child thread.
> Âconst char * txt = "print(a)";
> ÂluaL_loadbuffer(L, txt, strlen(txt), "x");
>
> Âint r1 = luaL_ref(L, LUA_REGISTRYINDEX);
>
> Âlua_rawgeti(L, LUA_REGISTRYINDEX, r1);
> Âlua_pcall(L, 0, 0, 0);
>
> Âlua_rawgeti(L1, LUA_REGISTRYINDEX, r1);
> Âlua_pcall(L1, 0, 0, 0);
> }
>
> This prints:
>
> 0
> 1
> 0
> 0
>
> So, as far as I can tell, the C function will print out the 'a' in the
> thread's environment, but the identical Lua function loaded through
> luaL_loadbuffer() will always print out the 'a' in the global environment.
>
> Does anyone know why this gives a different result? And is there any way I
> can get the second case to work in the same way as the first one, that is,
> print the 'a' in the thread's environment?

Lua functions do not use the thread environment. Instead, Lua
functions use the function environment for all global accesses. Lua C
functions, by convention, (for better or worse) use the thread
environment (LUA_GLOBALSINDEX) instead of an environment index
(LUA_ENVIRONINDEX). Your Lua function inherits the environment of the
thread it was created in. In your example, that is the main thread
environment (a = 0).

HTH,

-- 
-Patrick Donnelly

"Let all men know thee, but no man know thee thoroughly: Men freely
ford that see the shallows."

- Benjamin Franklin