/** @internal Retrieve C layer api wrapper. */ static const knot_layer_api_t* l_ffi_layer(struct kr_module *module) { lua_State *L = module->lib; lua_rawgeti(L, LUA_REGISTRYINDEX, (intptr_t)module->data); lua_getfield(L, -1, "_layer_capi"); knot_layer_api_t *api = lua_touserdata(L, -1); lua_pop(L, 1); if (!api) { /* Fabricate layer API wrapping the Lua functions */ api = malloc(sizeof(*api)); if (api) { memset(api, 0, sizeof(*api)); /* 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); LAYER_REGISTER(L, api, reset); LAYER_REGISTER(L, api, fail); api->data = module; } /* Store the api in the registry. */ lua_pushlightuserdata(L, api); lua_setfield(L, -2, "_layer_capi"); } lua_pop(L, 1); /* Clear module table */ return api; }
/** @internal Create C layer api wrapper. */ static knot_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(knot_layer_api_t) + (SLOT_count * SLOT_size); knot_layer_api_t *api = malloc(api_length); if (api) { memset(api, 0, api_length); LAYER_REGISTER(L, api, begin); LAYER_REGISTER(L, api, finish); LAYER_REGISTER(L, api, consume); LAYER_REGISTER(L, api, produce); LAYER_REGISTER(L, api, reset); /* Begin is always set, as it initializes layer baton. */ api->begin = l_ffi_layer_begin; api->data = module; } return api; }