lua-users home
lua-l archive

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


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?

Cheers,
Christian Tellefsen
Funcom