summaryrefslogtreecommitdiff
path: root/src/util/util.c
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-10-04 15:22:22 -0500
committersanine <sanine.not@pm.me>2022-10-04 15:22:22 -0500
commitff14b4a939511d42aa0ca46ea2139637b74e6e8a (patch)
tree65872a49ad821729d394d6537eee3103862513a2 /src/util/util.c
parent6d96b0e7ea1d98e44647d0bbbba232701a7d557e (diff)
add garbage collector canaries
Diffstat (limited to 'src/util/util.c')
-rw-r--r--src/util/util.c45
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;
+}