diff --git a/daemon/ffimodule.c b/daemon/ffimodule.c
index 31a1560f48beb4b5e98733c651cb326208a71162..1cb6b715c2ee887400fe73c1a3b6c13e81b91901 100644
--- a/daemon/ffimodule.c
+++ b/daemon/ffimodule.c
@@ -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);
diff --git a/lib/layer.h b/lib/layer.h
index dc69cfcb38a7a7036fda55ac301a9492c8c87687..c3db71c51a18fe91e5e86ef65f3c5ad54c076a59 100644
--- a/lib/layer.h
+++ b/lib/layer.h
@@ -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;