]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/ffimodule: avoid ugly casting for slots
authorVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 15 Nov 2018 16:26:32 +0000 (17:26 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 21 Nov 2018 14:33:41 +0000 (15:33 +0100)
Also simplify l_ffi_deinit().

daemon/ffimodule.c
lib/layer.h

index 31a1560f48beb4b5e98733c651cb326208a71162..1cb6b715c2ee887400fe73c1a3b6c13e81b91901 100644 (file)
@@ -38,7 +38,7 @@ enum {
        SLOT_produce,
        SLOT_checkout,
        SLOT_answer_finalize,
-       SLOT_count
+       SLOT_count /* dummy, must be the last */
 };
 #define SLOT_size sizeof(int)
 
@@ -107,13 +107,6 @@ static int l_ffi_init(struct kr_module *module)
        return l_ffi_call(L, 1);
 }
 
-/** @internal Unregister layer callback reference from registry. */
-#define LAYER_UNREGISTER(L, api, name) do { \
-       int *cb_slot = (int *)((char *)api + sizeof(kr_layer_api_t)); \
-       if (cb_slot[SLOT_ ## name] > 0) \
-               luaL_unref(L, LUA_REGISTRYINDEX, cb_slot[SLOT_ ## name]); \
-} while(0)
-
 static int l_ffi_deinit(struct kr_module *module)
 {
        /* Deinit the module in Lua (if possible) */
@@ -122,32 +115,31 @@ static int l_ffi_deinit(struct kr_module *module)
        if (l_ffi_preface(module, "deinit")) {
                ret = l_ffi_call(L, 1);
        }
+       module->lib = NULL;
        /* Free the layer API wrapper (unconst it) */
        kr_layer_api_t* api = module->data;
-       if (api) {
-               LAYER_UNREGISTER(L, api, begin);
-               LAYER_UNREGISTER(L, api, finish);
-               LAYER_UNREGISTER(L, api, consume);
-               LAYER_UNREGISTER(L, api, produce);
-               LAYER_UNREGISTER(L, api, checkout);
-               LAYER_UNREGISTER(L, api, answer_finalize);
-               LAYER_UNREGISTER(L, api, reset);
-               free(api);
+       if (!api) {
+               return ret;
        }
-       module->lib = NULL;
+       /* Unregister layer callback references from registry. */
+       for (int si = 0; si < SLOT_count; ++si) {
+               if (api->cb_slots[si] > 0) {
+                       luaL_unref(L, LUA_REGISTRYINDEX, api->cb_slots[si]);
+               }
+       }
+       free(api);
        return ret;
 }
-#undef LAYER_UNREGISTER
 
 /** @internal Helper for retrieving layer Lua function by name. */
-#define LAYER_FFI_CALL(ctx, slot) \
-       int *cb_slot = (int *)((char *)(ctx)->api + sizeof(kr_layer_api_t)); \
-       if (cb_slot[SLOT_ ## slot] <= 0) { \
+#define LAYER_FFI_CALL(ctx, slot_name) \
+       const int *cb_slot = (ctx)->api->cb_slots + SLOT_ ## slot_name; \
+       if (*cb_slot <= 0) { \
                return ctx->state; \
        } \
        struct kr_module *module = (ctx)->api->data; \
        lua_State *L = module->lib; \
-       lua_rawgeti(L, LUA_REGISTRYINDEX, cb_slot[SLOT_ ## slot]); \
+       lua_rawgeti(L, LUA_REGISTRYINDEX, *cb_slot); \
        lua_pushnumber(L, ctx->state)
 
 static int l_ffi_layer_begin(kr_layer_t *ctx)
@@ -219,11 +211,11 @@ static int l_ffi_layer_answer_finalize(kr_layer_t *ctx)
 /** @internal Conditionally register layer trampoline
   * @warning Expects 'module.layer' to be on top of Lua stack. */
 #define LAYER_REGISTER(L, api, name) do { \
-       int *cb_slot = (int *)((char *)api + sizeof(kr_layer_api_t)); \
+       int *cb_slot = (api)->cb_slots + SLOT_ ## name; \
        lua_getfield((L), -1, #name); \
        if (!lua_isnil((L), -1)) { \
                (api)->name = l_ffi_layer_ ## name; \
-               cb_slot[SLOT_ ## name] = luaL_ref((L), LUA_REGISTRYINDEX); \
+               *cb_slot = luaL_ref((L), LUA_REGISTRYINDEX); \
        } else { \
                lua_pop((L), 1); \
        } \
@@ -234,7 +226,8 @@ static kr_layer_api_t *l_ffi_layer_create(lua_State *L, struct kr_module *module
 {
        /* Fabricate layer API wrapping the Lua functions
         * reserve slots after it for references to Lua callbacks. */
-       const size_t api_length = sizeof(kr_layer_api_t) + (SLOT_count * SLOT_size);
+       const size_t api_length = offsetof(kr_layer_api_t, cb_slots)
+                               + (SLOT_count * SLOT_size);
        kr_layer_api_t *api = malloc(api_length);
        if (api) {
                memset(api, 0, api_length);
index dc69cfcb38a7a7036fda55ac301a9492c8c87687..c3db71c51a18fe91e5e86ef65f3c5ad54c076a59 100644 (file)
@@ -90,6 +90,9 @@ struct kr_layer_api {
 
        /** The module can store anything in here. */
        void *data;
+
+       /** Internal to ./daemon/ffimodule.c. */
+       int cb_slots[];
 };
 
 typedef struct kr_layer_api kr_layer_api_t;