Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lua: add built-in module registration function
This commit starts a series, which refactors built-in module registration mechanisms. The series aims several goals: * Offer a standard tarantool specific way to register a built-in module. It allows to change the registration process for all built-in modules at once. * Make the API of such functions simple and clean. * Eliminate known problems of the existing approach to register built-in modules. This particular commit offers two new functions: * luaT_setfuncs() * luaT_newmodule() The former replaces `luaL_register(L, NULL, funcs)`. The latter replaces `luaL_register()` and `luaL_register_module()` to some extent. Let's look on examples below. ## How it works now First of all, consider the [documentation][1] about the `luaL_register()` function. Then look on the examples. ```c luaL_register(L, "foo.bar", funcs); ``` Creates a table `package.loaded['foo.bar']` and `_G.foo.bar` (if neither of them exists), fill it with the functions and pushes it to the stack. What is not ok: * Pollutes `_G`. * `package.loaded` is written flat, but `_G` is written deeply. * No control over (un)intended module rewritting. It also worth to note that we can't change this function, because it is part of the Lua API. So we need another function for our registration process. Another usage of the function makes it even more confusing: ```c luaL_register(L, NULL, funcs); ``` Does it creates a table, fills it with the functions and pushes it to the stack? No. Unlike other usages, it fills a table on the top of the stack with the functions and leaves it on the stack. And it actually has no relation to module registration. There is tarantool specific function `luaL_register_module()`, which looks as an attempt to solve some of the problems. ```c luaL_register_module(L, "foo.bar", funcs); ``` It doesn't touch `_G` and, surprisingly, changes how a module is written to `package.loaded`. The call creates a table (or finds it) in `package.loaded.foo.bar`, fills it with the functions and pushes to the stack. *This* function writes `package.loaded` deeply. It leaves us with `luaL_register()` for assigning `_G.foo.bar` (with pollution of `package.loaded`). It leaves us with `lua_register()` for setting functions into a table on the stack (with confusing name in this context and confusing contract). And we has no a function to just assign `package.loaded[modname]` without the deep tables creation and with appropriate checks. ## How it will work ```c luaT_newmodule(L, "foo.bar", funcs); ``` Create a table, set it to `package.loaded['foo.bar']` and push into the stack. Assert that the table doesn't exist. ```c luaT_setfuncs(L, funcs); ``` Add functions into a table on top of the stack. ```c luaL_findtable(L, LUA_GLOBALSINDEX, "foo.bar", 0); luaT_setfuncs(L, funcs); ``` Find/create a table `_G.foo.bar` and add functions to it. [1]: https://www.lua.org/manual/5.1/manual.html#luaL_register Part of tarantool#7774 NO_DOC=user visible behavior is unchanged, pure refactoring change NO_TEST=see NO_DOC NO_CHANGELOG=see NO_DOC
- Loading branch information