You call lua_pop()
to remove items from the Lua stack. For simple functions, this can be entirely unnecessary since the core will clean up the stack as part of handling the return values.
For more complex functions, and especially for C code that is calling into Lua, you will often need to pop things from the stack to prevent the stack from growing indefinitely.
The lua_getglobal()
function adds one item to the stack when called, which is either nil
if the global doesn't exist or the value of the named global variable. Having a copy of that value on the stack protects it from the garbage collector as long as it is there. That value needs to remain on the stack as long as it is in use by the C code that retrieved it, because if the global were modified, the copy on the stack might be the only remaining reference.
So the general patterns for using a global are something like these:
void doMyEvent(lua_State *L) {
lua_getglobal(L, "MyEvent");
lua_call(L, 0, 0); /* pops the function and 0 parameters, pushes 0 results */
}
double getGlobalDouble(lua_State *L, const char *name) {
double d;
lua_getglobal(L,name);
d = lua_tonumber(L,1); /* extracts the value, leaves stack unchanged */
lua_pop(L,1); /* pop the value to leave stack balanced */
return d;
}
char *copyGlobalString(lua_State *L, const char *name) {
char *s = NULL;
lua_getglobal(L,name);
if (!lua_isnil(L,-1))
s = strdup(lua_tostring(L,-1));
lua_pop(L,1);
return s;
}
In the last example, I am careful to copy the content of the string because the pointer returned by lua_tostring()
is only guaranteed to be valid as long as the value remains on the stack. The requires that a caller of copyGlobalString()
is responsible for calling free()
later.
Note too that recent editions of the Lua manual include a notation along with each function that identifies the number of stack entries consumed, and the number pushed. This helps avoid unexpected stack growth.