From 5e621e6251308eb1276f175bf99ab92f15df8d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Vavru=C5=A1a?= <marek.vavrusa@nic.cz> Date: Mon, 15 Jun 2015 22:53:07 +0200 Subject: [PATCH] daemon/bindings: some basic Lua interface to rplan and query --- daemon/bindings/kres.c | 104 ++++++++++++++++++++++++++++++++--------- daemon/bindings/kres.h | 5 ++ daemon/ffimodule.c | 38 +++++++++++---- 3 files changed, 115 insertions(+), 32 deletions(-) diff --git a/daemon/bindings/kres.c b/daemon/bindings/kres.c index 164a18f18..f9d11c162 100644 --- a/daemon/bindings/kres.c +++ b/daemon/bindings/kres.c @@ -17,8 +17,21 @@ #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 @@ -88,45 +101,89 @@ static int pkt_qclass(lua_State *L) 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) \ @@ -146,7 +203,6 @@ static int pkt_meta_get(lua_State *L) int lib_kres(lua_State *L) { static const luaL_Reg lib[] = { - { "packet", pkt_meta_get }, { NULL, NULL } }; /* Create module and register functions */ @@ -162,6 +218,8 @@ int lib_kres(lua_State *L) 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 diff --git a/daemon/bindings/kres.h b/daemon/bindings/kres.h index 39209e03a..d9881e36e 100644 --- a/daemon/bindings/kres.h +++ b/daemon/bindings/kres.h @@ -22,6 +22,11 @@ #include "daemon/bindings.h" +/* Metatable list */ +#define META_PKT "kres.meta_pkt" +#define META_QUERY "kres.meta_query" +#define META_RPLAN "kres.meta_rplan" + /** * Load libkres library. * @param L scriptable diff --git a/daemon/ffimodule.c b/daemon/ffimodule.c index d1482b184..26eed9674 100644 --- a/daemon/ffimodule.c +++ b/daemon/ffimodule.c @@ -17,8 +17,9 @@ #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" @@ -28,6 +29,13 @@ #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; @@ -131,51 +139,61 @@ static int l_ffi_deinit(struct kr_module *module) 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); } @@ -200,7 +218,8 @@ static const knot_layer_api_t* l_ffi_layer(struct kr_module *module) 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); @@ -218,6 +237,7 @@ static const knot_layer_api_t* l_ffi_layer(struct kr_module *module) #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 { \ -- GitLab