Created
September 16, 2022 04:48
-
-
Save nicolasnoble/b84ee61c6ca52104d3b9b706d7446df1 to your computer and use it in GitHub Desktop.
Weird Lua garbage collector behavior.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "lua.h" | |
#include "lauxlib.h" | |
#include "lualib.h" | |
static int outergc(lua_State *L) { | |
void * n = lua_touserdata(L, lua_upvalueindex(1)); | |
void * o = lua_touserdata(L, -1); | |
printf("Outer gc called on %p with upvalue = %p\n", o, n); | |
return 0; | |
} | |
static int innergc(lua_State *L) { | |
void * n = lua_touserdata(L, -1); | |
printf("Inner gc called on %p\n", n); | |
return 0; | |
} | |
int main() { | |
lua_State *L = luaL_newstate(); | |
luaL_openlibs(L); | |
lua_checkstack(L, 10); | |
lua_newtable(L); | |
// 1 = {} | |
lua_pushstring(L, "_proxy"); | |
// 1 = {}, 2 = "_proxy" | |
void * o = lua_newuserdata(L, 1); | |
// 1 = {}, 2 = "_proxy", 3 = proxy | |
printf("Created outer object: %p\n", o); | |
lua_newtable(L); | |
// 1 = {}, 2 = "_proxy", 3 = proxy, 4 = {} | |
lua_pushstring(L, "__gc"); | |
// 1 = {}, 2 = "_proxy", 3 = proxy, 4 = {}, 5 = "__gc" | |
void * n = lua_newuserdata(L, 1); | |
// 1 = {}, 2 = "_proxy", 3 = proxy, 4 = {}, 5 = "__gc", 6 = upvalue | |
printf("Created inner object: %p\n", n); | |
lua_newtable(L); | |
// 1 = {}, 2 = "_proxy", 3 = proxy, 4 = {}, 5 = "__gc", 6 = upvalue, 7 = {} | |
lua_pushstring(L, "__gc"); | |
// 1 = {}, 2 = "_proxy", 3 = proxy, 4 = {}, 5 = "__gc", 6 = upvalue, 7 = {}, 8 = "__gc" | |
lua_pushcfunction(L, innergc); | |
// 1 = {}, 2 = "_proxy", 3 = proxy, 4 = {}, 5 = "__gc", 6 = upvalue, 7 = {}, 8 = "__gc", 9 = innergc | |
lua_settable(L, 7); | |
// 1 = {}, 2 = "_proxy", 3 = proxy, 4 = {}, 5 = "__gc", 6 = upvalue, 7 = {__gc = innergc} | |
lua_setmetatable(L, -1); | |
// 1 = {}, 2 = "_proxy", 3 = proxy, 4 = {}, 5 = "__gc", 6 = upvalue_with_gc | |
lua_pushcclosure(L, outergc, 1); | |
// 1 = {}, 2 = "_proxy", 3 = proxy, 4 = {}, 5 = "__gc", 6 = outergc_with_upvalue_with_gc | |
lua_settable(L, 4); | |
// 1 = {}, 2 = "_proxy", 3 = proxy, 4 = { __gc = outergc_with_upvalue_with_gc } | |
lua_setmetatable(L, 3); | |
// 1 = {}, 2 = "_proxy", 3 = proxy_with_gc | |
lua_settable(L, 1); | |
// 1 = { _proxy = proxy_with_gc } | |
lua_pop(L, 1); | |
// empty stack | |
lua_gc(L, LUA_GCCOLLECT, 0); | |
printf("Closing...\n"); | |
lua_close(L); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment