diff options
author | sanine <sanine.not@pm.me> | 2022-10-04 15:22:22 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2022-10-04 15:22:22 -0500 |
commit | ff14b4a939511d42aa0ca46ea2139637b74e6e8a (patch) | |
tree | 65872a49ad821729d394d6537eee3103862513a2 /src/util/util.c | |
parent | 6d96b0e7ea1d98e44647d0bbbba232701a7d557e (diff) |
add garbage collector canaries
Diffstat (limited to 'src/util/util.c')
-rw-r--r-- | src/util/util.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/util/util.c b/src/util/util.c index 84edd27..89e9d38 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1,4 +1,6 @@ #include <lua.h> +#include <lauxlib.h> +#include <honeysuckle.h> void append_table(lua_State *L, int tbl_a, int tbl_b) { @@ -10,3 +12,46 @@ void append_table(lua_State *L, int tbl_a, int tbl_b) lua_pop(L, 1); } } + + +const char *canary_tname = "honey.canary"; + +int gc_canary(lua_State *L); +int gc_canary_collect(lua_State *L); + +void setup_util(lua_State *L, int honey_tbl) +{ + /* create gc_canary metatable */ + luaL_newmetatable(L, canary_tname); + lua_pushcfunction(L, gc_canary_collect); + lua_setfield(L, -2, "__gc"); + lua_pop(L, 1); + + hs_create_table(L, + hs_str_cfunc("gc_canary", gc_canary), + ); + + lua_setfield(L, honey_tbl, "util"); +} + + +int gc_canary(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TFUNCTION); + int ref = luaL_ref(L, LUA_REGISTRYINDEX); + int *canary = lua_newuserdata(L, sizeof(int)); + *canary = ref; + luaL_getmetatable(L, canary_tname); + lua_setmetatable(L, -2); + return 1; +} + + +int gc_canary_collect(lua_State *L) +{ + int *canary = luaL_checkudata(L, 1, canary_tname); + lua_rawgeti(L, LUA_REGISTRYINDEX, *canary); + lua_call(L, 0, 0); + luaL_unref(L, LUA_REGISTRYINDEX, *canary); + return 0; +} |