From ff14b4a939511d42aa0ca46ea2139637b74e6e8a Mon Sep 17 00:00:00 2001 From: sanine Date: Tue, 4 Oct 2022 15:22:22 -0500 Subject: add garbage collector canaries --- src/util/util.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/util/util.h | 1 + 2 files changed, 46 insertions(+) (limited to 'src/util') 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 +#include +#include 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; +} diff --git a/src/util/util.h b/src/util/util.h index 3ef4e0b..231bcc9 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -3,6 +3,7 @@ #include +void setup_util(lua_State *L, int honey_tbl); void append_table(lua_State *L, int tbl_a, int tbl_b); #endif -- cgit v1.2.1