diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/util.c | 45 | ||||
-rw-r--r-- | src/util/util.h | 1 |
2 files changed, 46 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; +} 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 <lua.h> +void setup_util(lua_State *L, int honey_tbl); void append_table(lua_State *L, int tbl_a, int tbl_b); #endif |