An error occurred while fetching folder content.
Alexander Turenko
authored
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 the new `luaT_newmodule()` function. It replaces `luaL_register()` and `luaL_register_module()` to some extent. Here I also start a practice to use `luaL_setfuncs()` instead of `luaL_register(L, NULL, funcs)` for readability purposes. The function is part of Lua 5.2 ([documentation][1]), but it is implemented in LuaJIT. Let's look on examples below. ## How it works now First of all, consider the [documentation][2] 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 in order to implement #7774. Another usage of the function makes it even more confusing: ```c luaL_register(L, NULL, funcs); ``` Does it create a table, fill it with the functions and push 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 `luaL_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 luaL_setfuncs(L, funcs, 0); ``` Add functions into a table on top of the stack. ```c luaL_findtable(L, LUA_GLOBALSINDEX, "foo.bar", 0); luaL_setfuncs(L, funcs, 0); ``` Find/create a table `_G.foo.bar` and add functions to it. Next commits will adopt built-in modules to follow this practice. [1]: https://www.lua.org/manual/5.2/manual.html#luaL_setfuncs [2]: https://www.lua.org/manual/5.1/manual.html#luaL_register Part of #7774 NO_DOC=user visible behavior is unchanged, pure refactoring change NO_TEST=see NO_DOC NO_CHANGELOG=see NO_DOC
Name | Last commit | Last update |
---|