From: Kirill Shcherbatov <kshcherbatov@tarantool.org> To: tarantool-patches@freelists.org, vdavydov.dev@gmail.com Cc: Kirill Shcherbatov <kshcherbatov@tarantool.org> Subject: [PATCH v2 1/9] box: refactor box_lua_find helper Date: Thu, 6 Jun 2019 15:03:57 +0300 [thread overview] Message-ID: <9f896499624289da849eebccd076f3029353ae8d.1559822429.git.kshcherbatov@tarantool.org> (raw) In-Reply-To: <cover.1559822429.git.kshcherbatov@tarantool.org> The box_lua_find routine used to work with an empty stack only. It is unacceptable in following patches because this helper need to be reused in following patches for environment table construction. The definition also is moved to lua/utils.h. Needed for #4182, #1260 --- src/box/lua/call.c | 85 ++++++++-------------------------------------- src/lua/utils.c | 59 ++++++++++++++++++++++++++++++++ src/lua/utils.h | 11 ++++++ 3 files changed, 85 insertions(+), 70 deletions(-) diff --git a/src/box/lua/call.c b/src/box/lua/call.c index 04020ef6f..c729778c4 100644 --- a/src/box/lua/call.c +++ b/src/box/lua/call.c @@ -44,73 +44,6 @@ #include "trivia/util.h" #include "mpstream.h" -/** - * A helper to find a Lua function by name and put it - * on top of the stack. - */ -static int -box_lua_find(lua_State *L, const char *name, const char *name_end) -{ - int index = LUA_GLOBALSINDEX; - int objstack = 0; - const char *start = name, *end; - - while ((end = (const char *) memchr(start, '.', name_end - start))) { - lua_checkstack(L, 3); - lua_pushlstring(L, start, end - start); - lua_gettable(L, index); - if (! lua_istable(L, -1)) { - diag_set(ClientError, ER_NO_SUCH_PROC, - name_end - name, name); - luaT_error(L); - } - start = end + 1; /* next piece of a.b.c */ - index = lua_gettop(L); /* top of the stack */ - } - - /* box.something:method */ - if ((end = (const char *) memchr(start, ':', name_end - start))) { - lua_checkstack(L, 3); - lua_pushlstring(L, start, end - start); - lua_gettable(L, index); - if (! (lua_istable(L, -1) || - lua_islightuserdata(L, -1) || lua_isuserdata(L, -1) )) { - diag_set(ClientError, ER_NO_SUCH_PROC, - name_end - name, name); - luaT_error(L); - } - start = end + 1; /* next piece of a.b.c */ - index = lua_gettop(L); /* top of the stack */ - objstack = index; - } - - - lua_pushlstring(L, start, name_end - start); - lua_gettable(L, index); - if (!lua_isfunction(L, -1) && !lua_istable(L, -1)) { - /* lua_call or lua_gettable would raise a type error - * for us, but our own message is more verbose. */ - diag_set(ClientError, ER_NO_SUCH_PROC, - name_end - name, name); - luaT_error(L); - } - /* setting stack that it would contain only - * the function pointer. */ - if (index != LUA_GLOBALSINDEX) { - if (objstack == 0) { /* no object, only a function */ - lua_replace(L, 1); - } else if (objstack == 1) { /* just two values, swap them */ - lua_insert(L, -2); - } else { /* long path */ - lua_insert(L, 1); - lua_insert(L, 2); - objstack = 1; - } - lua_settop(L, 1 + objstack); - } - return 1 + objstack; -} - /** * A helper to find lua stored procedures for box.call. * box.call iteslf is pure Lua, to avoid issues @@ -124,7 +57,12 @@ lbox_call_loadproc(struct lua_State *L) const char *name; size_t name_len; name = lua_tolstring(L, 1, &name_len); - return box_lua_find(L, name, name + name_len); + int count; + if (luaT_func_find(L, name, name + name_len, &count) != 0) { + diag_set(ClientError, ER_NO_SUCH_PROC, name_len, name); + return luaT_error(L); + } + return count; } /* @@ -292,9 +230,16 @@ execute_lua_call(lua_State *L) const char *name = request->name; uint32_t name_len = mp_decode_strl(&name); - int oc = 0; /* how many objects are on stack after box_lua_find */ + /* + * How many objects are on stack after + * luaT_func_find call. + */ + int oc = 0; /* Try to find a function by name in Lua */ - oc = box_lua_find(L, name, name + name_len); + if (luaT_func_find(L, name, name + name_len, &oc) != 0) { + diag_set(ClientError, ER_NO_SUCH_PROC, name_len, name); + return luaT_error(L); + } /* Push the rest of args (a tuple). */ const char *args = request->args; diff --git a/src/lua/utils.c b/src/lua/utils.c index 01a0cd894..27ff6b396 100644 --- a/src/lua/utils.c +++ b/src/lua/utils.c @@ -1189,6 +1189,65 @@ void luaL_iterator_delete(struct luaL_iterator *it) /* }}} */ +int +luaT_func_find(struct lua_State *L, const char *name, const char *name_end, + int *count) +{ + int index = LUA_GLOBALSINDEX; + int objstack = 0, top = lua_gettop(L); + const char *start = name, *end; + + while ((end = (const char *) memchr(start, '.', name_end - start))) { + lua_checkstack(L, 3); + lua_pushlstring(L, start, end - start); + lua_gettable(L, index); + if (! lua_istable(L, -1)) + return -1; + start = end + 1; /* next piece of a.b.c */ + index = lua_gettop(L); /* top of the stack */ + } + + /* box.something:method */ + if ((end = (const char *) memchr(start, ':', name_end - start))) { + lua_checkstack(L, 3); + lua_pushlstring(L, start, end - start); + lua_gettable(L, index); + if (! (lua_istable(L, -1) || + lua_islightuserdata(L, -1) || lua_isuserdata(L, -1) )) + return -1; + start = end + 1; /* next piece of a.b.c */ + index = lua_gettop(L); /* top of the stack */ + objstack = index - top; + } + + lua_pushlstring(L, start, name_end - start); + lua_gettable(L, index); + if (!lua_isfunction(L, -1) && !lua_istable(L, -1)) { + /* lua_call or lua_gettable would raise a type error + * for us, but our own message is more verbose. */ + return -1; + } + + /* setting stack that it would contain only + * the function pointer. */ + if (index != LUA_GLOBALSINDEX) { + if (objstack == 0) { /* no object, only a function */ + lua_replace(L, top + 1); + lua_pop(L, lua_gettop(L) - top - 1); + } else if (objstack == 1) { /* just two values, swap them */ + lua_insert(L, -2); + lua_pop(L, lua_gettop(L) - top - 2); + } else { /* long path */ + lua_insert(L, top + 1); + lua_insert(L, top + 2); + lua_pop(L, objstack - 1); + objstack = 1; + } + } + *count = 1 + objstack; + return 0; +} + int tarantool_lua_utils_init(struct lua_State *L) { diff --git a/src/lua/utils.h b/src/lua/utils.h index 943840ec0..81e936bee 100644 --- a/src/lua/utils.h +++ b/src/lua/utils.h @@ -592,6 +592,17 @@ void luaL_iterator_delete(struct luaL_iterator *it); /* }}} */ +/** + * A helper to find a Lua function by name and put it + * on top of the stack. + * Returns 0 in case of succsess and -1 otherwise; in case of + * success also uses count[out] argument to return the how many + * objects are pushed on to stack. + */ +int +luaT_func_find(struct lua_State *L, const char *name, const char *name_end, + int *count); + int tarantool_lua_utils_init(struct lua_State *L); -- 2.21.0
next prev parent reply other threads:[~2019-06-06 12:03 UTC|newest] Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-06-06 12:03 [PATCH v2 0/9] box: rework functions machinery Kirill Shcherbatov 2019-06-06 12:03 ` Kirill Shcherbatov [this message] 2019-06-10 9:17 ` [PATCH v2 1/9] box: refactor box_lua_find helper Vladimir Davydov 2019-06-06 12:03 ` [PATCH v2 2/9] box: move box_module_reload routine to func.c Kirill Shcherbatov 2019-06-10 9:19 ` Vladimir Davydov 2019-06-06 12:03 ` [PATCH v2 3/9] box: rework func cache update machinery Kirill Shcherbatov 2019-06-10 9:44 ` Vladimir Davydov 2019-06-06 12:04 ` [PATCH v2 4/9] box: rework func object as a function frontend Kirill Shcherbatov 2019-06-10 10:32 ` Vladimir Davydov 2019-06-06 12:04 ` [PATCH v2 5/9] schema: rework _func system space format Kirill Shcherbatov 2019-06-10 12:10 ` Vladimir Davydov 2019-06-06 12:04 ` [PATCH v2 6/9] box: load persistent Lua functions on creation Kirill Shcherbatov 2019-06-10 12:19 ` Vladimir Davydov 2019-06-06 12:04 ` [PATCH v2 7/9] box: sandbox option for persistent functions Kirill Shcherbatov 2019-06-10 14:06 ` Vladimir Davydov 2019-06-10 14:15 ` [tarantool-patches] " Kirill Shcherbatov 2019-06-10 14:41 ` Vladimir Davydov 2019-06-06 12:04 ` [PATCH v2 8/9] box: implement lua_port dump to region and to Lua Kirill Shcherbatov 2019-06-10 14:24 ` Vladimir Davydov 2019-06-06 12:04 ` [PATCH v2 9/9] box: export _func functions with box.func folder Kirill Shcherbatov 2019-06-10 15:18 ` Vladimir Davydov 2019-06-10 9:14 ` [PATCH v2 0/9] box: rework functions machinery Vladimir Davydov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=9f896499624289da849eebccd076f3029353ae8d.1559822429.git.kshcherbatov@tarantool.org \ --to=kshcherbatov@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=vdavydov.dev@gmail.com \ --subject='Re: [PATCH v2 1/9] box: refactor box_lua_find helper' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox