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?