return ret;
}
+kr_layer_t kr_layer_t_static;
+
/** @internal Helper for calling a layer Lua function by e.g. SLOT_begin. */
static int l_ffi_call_layer(kr_layer_t *ctx, int slot_ix)
{
lua_State *L = the_worker->engine->L;
lua_rawgeti(L, LUA_REGISTRYINDEX, wrap_slot);
lua_rawgeti(L, LUA_REGISTRYINDEX, cb_slot);
- lua_pushpointer(L, ctx);
- const int ret = l_ffi_call_mod(L, 2);
+ /* We pass the content of *ctx via a global structure to avoid
+ * lua (full) userdata, as that's relatively expensive (GC-allocated).
+ * Performance: copying isn't ideal, but it's not visible in profiles. */
+ memcpy(&kr_layer_t_static, ctx, sizeof(*ctx));
+ const int ret = l_ffi_call_mod(L, 1);
/* The return codes are mixed at this point. We need to return KR_STATE_* */
return ret < 0 ? KR_STATE_FAIL : ret;
}
#pragma once
+#include "lib/defines.h"
+#include "lib/layer.h"
+#include <lua.h>
+struct engine;
+struct kr_module;
+
/**
* Register Lua module as a FFI module.
* This fabricates a standard module interface,
int ffimodule_init(lua_State *L);
void ffimodule_deinit(lua_State *L);
+/** Static storage for faster passing of layer function parameters to lua callbacks.
+ *
+ * We don't need to declare it in a header, but let's give it visibility. */
+KR_EXPORT kr_layer_t kr_layer_t_static;
+
void *lib;
void *data;
};
-
+kr_layer_t kr_layer_t_static;
typedef int32_t (*kr_stale_cb)(int32_t ttl, const knot_dname_t *owner, uint16_t type,
const struct kr_query *qry);
struct kr_module
EOF
+# a static variable; the line might not be simple to generate
+printf "kr_layer_t kr_layer_t_static;"
+
printf "
typedef int32_t (*kr_stale_cb)(int32_t ttl, const knot_dname_t *owner, uint16_t type,
const struct kr_query *qry);
})
end
+local layer_ctx = ffi.C.kr_layer_t_static
-- Utilities internal for lua layer glue; see ../ffimodule.c
-modules_ffi_layer_wrap1 = function (layer_cb, ctx_udata)
- local ctx = ffi.cast('kr_layer_t **', ctx_udata)[0]
- return layer_cb(ctx.state, ctx.req)
+modules_ffi_layer_wrap1 = function (layer_cb)
+ return layer_cb(layer_ctx.state, layer_ctx.req)
end
-modules_ffi_layer_wrap2 = function (layer_cb, ctx_udata)
- local ctx = ffi.cast('kr_layer_t **', ctx_udata)[0]
- return layer_cb(ctx.state, ctx.req, ctx.pkt)
+modules_ffi_layer_wrap2 = function (layer_cb)
+ return layer_cb(layer_ctx.state, layer_ctx.req, layer_ctx.pkt)
end
-modules_ffi_layer_wrap_checkout = function (layer_cb, ctx_udata)
- local ctx = ffi.cast('kr_layer_t **', ctx_udata)[0]
- return layer_cb(ctx.state, ctx.req, ctx.pkt, ctx.dst, ctx.is_stream)
+modules_ffi_layer_wrap_checkout = function (layer_cb)
+ return layer_cb(layer_ctx.state, layer_ctx.req, layer_ctx.pkt,
+ layer_ctx.dst, layer_ctx.is_stream)
end
modules_ffi_wrap_modcb = function (cb, kr_module_ud) -- this one isn't for layer
local kr_module = ffi.cast('struct kr_module **', kr_module_ud)[0]