#include "daemon/bindings/kres.h"
#include "daemon/bindings.h"
-/* Metatable list */
-#define META_PKT "kres.meta_pkt"
+/** @internal Register metatable. */
+#define META_REGISTER(L, funcs, name) \
+ luaL_newmetatable((L), (name)); \
+ luaL_setfuncs((L), (funcs), 0); \
+ lua_pushvalue((L), -1); \
+ lua_setfield((L), -2, "__index"); \
+ lua_pop((L), 1);
+
+/** @internal Shortcut for dname conversion. */
+static inline void lua_pushdname(lua_State *L, const knot_dname_t *name)
+{
+ char dname_str[KNOT_DNAME_MAXLEN];
+ knot_dname_to_str(dname_str, name, sizeof(dname_str));
+ lua_pushstring(L, dname_str);
+}
/*
* Packet interface
static int pkt_qname(lua_State *L)
{
knot_pkt_t *pkt = lua_touserdata(L, 1);
- const knot_dname_t *dname = knot_pkt_qname(pkt);
- char dname_str[KNOT_DNAME_MAXLEN];
- knot_dname_to_str(dname_str, dname, sizeof(dname_str));
- lua_pushstring(L, dname_str);
+ lua_pushdname(L, knot_pkt_qname(pkt));
return 1;
}
#warning TODO: record interfaces
-static int pkt_meta_set(lua_State *L)
+static int pkt_meta_register(lua_State *L)
{
- static const luaL_Reg pkt_wrap[] = {
- { "flag", pkt_flag},
- { "rcode", pkt_rcode},
- { "opcode", pkt_opcode},
- { "qtype", pkt_qtype },
+ static const luaL_Reg wrap[] = {
+ { "flag", pkt_flag },
+ { "rcode", pkt_rcode },
+ { "opcode", pkt_opcode },
+ { "qtype", pkt_qtype },
{ "qclass", pkt_qclass },
- { "qname", pkt_qname },
+ { "qname", pkt_qname },
{ NULL, NULL }
};
- luaL_newmetatable(L, META_PKT);
- luaL_setfuncs(L, pkt_wrap, 0);
- lua_pushvalue(L, -1);
- lua_setfield(L, -2, "__index");
- lua_pop(L, 1);
+ META_REGISTER (L, wrap, META_PKT);
return 0;
}
-static int pkt_meta_get(lua_State *L)
+/**
+ * Query interface.
+ */
+
+static int query_qtype(lua_State *L)
{
- luaL_getmetatable(L, META_PKT);
- lua_setmetatable(L, -2);
+ struct kr_query *qry = lua_touserdata(L, 1);
+ lua_pushnumber(L, qry->stype);
return 1;
}
+static int query_qclass(lua_State *L)
+{
+ struct kr_query *qry = lua_touserdata(L, 1);
+ lua_pushnumber(L, qry->sclass);
+ return 1;
+}
+
+static int query_qname(lua_State *L)
+{
+ struct kr_query *qry = lua_touserdata(L, 1);
+ lua_pushdname(L, qry->sname);
+ return 1;
+}
+
+static int query_meta_register(lua_State *L)
+{
+ static const luaL_Reg wrap[] = {
+ { "qtype", query_qtype },
+ { "qclass", query_qclass },
+ { "qname", query_qname },
+ { NULL, NULL }
+ };
+ META_REGISTER (L, wrap, META_QUERY);
+ return 0;
+}
+
/**
* Resolution context interface.
*/
+static int rplan_query(lua_State *L)
+{
+ struct kr_rplan *rplan = lua_touserdata(L, 1);
+ lua_pushlightuserdata(L, kr_rplan_current(rplan));
+ luaL_getmetatable(L, META_QUERY);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+static int rplan_meta_register(lua_State *L)
+{
+ static const luaL_Reg wrap[] = {
+ { "query", rplan_query },
+ // { "pending", rplan_pending },
+ // { "resolved", rplan_resolved },
+ { NULL, NULL }
+ };
+ META_REGISTER (L, wrap, META_RPLAN);
+ return 0;
+}
+
#warning TODO: context interface, rplan
#define WRAP_NUMBER(L, name, val) \
int lib_kres(lua_State *L)
{
static const luaL_Reg lib[] = {
- { "packet", pkt_meta_get },
{ NULL, NULL }
};
/* Create module and register functions */
WRAP_LUT(L, "opcode", knot_opcode_names);
WRAP_LUT(L, "wire", wire_flag_names);
/* Register metatables */
- pkt_meta_set(L);
+ pkt_meta_register(L);
+ query_meta_register(L);
+ rplan_meta_register(L);
return 1;
}
\ No newline at end of file
#include <uv.h>
#include "daemon/engine.h"
-#include "daemon/bindings.h"
#include "daemon/ffimodule.h"
+#include "daemon/bindings.h"
+#include "daemon/bindings/kres.h"
#include "lib/module.h"
#include "lib/layer.h"
#define l_resume(L, argc) lua_resume((L), (argc))
#endif
+/** @internal Set metatable on the object on stack. */
+static void set_metatable(lua_State *L, const char *tname)
+{
+ luaL_getmetatable(L, tname);
+ lua_setmetatable(L, -2);
+}
+
/** @internal Helper for retrieving the right function entrypoint. */
static inline lua_State *l_ffi_preface(struct kr_module *module, const char *call) {
lua_State *L = module->lib;
lua_pop(L, 1); \
return ctx->state; \
} \
- lua_pushnumber(L, ctx->state);
+ lua_pushnumber(L, ctx->state)
+
+/** @internal Push rplan and metatable. */
+#define LAYER_PUSH_RPLAN(ctx) do { \
+ struct kr_request *req = (ctx)->data; \
+ lua_pushlightuserdata(L, &req->rplan); \
+ set_metatable(L, META_RPLAN); \
+} while (0)
static int l_ffi_layer_begin(knot_layer_t *ctx, void *module_param)
{
+ ctx->data = module_param;
LAYER_FFI_CALL(ctx, "begin");
lua_pushlightuserdata(L, module_param);
- ctx->data = module_param;
return l_ffi_call(L, 2);
}
static int l_ffi_layer_reset(knot_layer_t *ctx)
{
LAYER_FFI_CALL(ctx, "reset");
- lua_pushlightuserdata(L, ctx->data);
+ LAYER_PUSH_RPLAN(ctx);
return l_ffi_call(L, 2);
}
static int l_ffi_layer_finish(knot_layer_t *ctx)
{
LAYER_FFI_CALL(ctx, "finish");
- lua_pushlightuserdata(L, ctx->data);
+ LAYER_PUSH_RPLAN(ctx);
return l_ffi_call(L, 2);
}
static int l_ffi_layer_consume(knot_layer_t *ctx, knot_pkt_t *pkt)
{
LAYER_FFI_CALL(ctx, "consume");
- lua_pushlightuserdata(L, ctx->data);
+ LAYER_PUSH_RPLAN(ctx);
lua_pushlightuserdata(L, pkt);
+ set_metatable(L, META_PKT);
return l_ffi_call(L, 3);
}
static int l_ffi_layer_produce(knot_layer_t *ctx, knot_pkt_t *pkt)
{
LAYER_FFI_CALL(ctx, "produce");
- lua_pushlightuserdata(L, ctx->data);
+ LAYER_PUSH_RPLAN(ctx);
lua_pushlightuserdata(L, pkt);
+ set_metatable(L, META_PKT);
return l_ffi_call(L, 3);
}
static int l_ffi_layer_fail(knot_layer_t *ctx, knot_pkt_t *pkt)
{
LAYER_FFI_CALL(ctx, "fail");
- lua_pushlightuserdata(L, ctx->data);
+ LAYER_PUSH_RPLAN(ctx);
lua_pushlightuserdata(L, pkt);
+ set_metatable(L, META_PKT);
return l_ffi_call(L, 3);
}
api = malloc(sizeof(*api));
if (api) {
memset(api, 0, sizeof(*api));
- LAYER_REGISTER(L, api, begin);
+ /* Begin is always set, as it initializes layer baton. */
+ api->begin = l_ffi_layer_begin;
LAYER_REGISTER(L, api, finish);
LAYER_REGISTER(L, api, consume);
LAYER_REGISTER(L, api, produce);
#undef LAYER_REGISTER
#undef LAYER_FFI_CALL
+#undef LAYER_PUSH_RPLAN
/** @internal Helper macro for function presence check. */
#define REGISTER_FFI_CALL(L, attr, name, cb) do { \