Tarantool development patches archive
 help / color / mirror / Atom feed
From: Kirill Shcherbatov <kshcherbatov@tarantool.org>
To: tarantool-patches@freelists.org, vdavydov.dev@gmail.com
Cc: Kirill Shcherbatov <kshcherbatov@tarantool.org>
Subject: [PATCH v1 1/3] box: refactor box_lua_find helper
Date: Tue, 14 May 2019 16:29:20 +0300	[thread overview]
Message-ID: <c2c8b240772c3883369163511f6792ee5752605b.1557839195.git.kshcherbatov@tarantool.org> (raw)
In-Reply-To: <cover.1557839195.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 refactored to be global in a new header
box/lua/utils.h.

Needed for #4182
---
 src/box/CMakeLists.txt |   1 +
 src/box/lua/call.c     |  82 +++++----------------------------
 src/box/lua/util.c     | 102 +++++++++++++++++++++++++++++++++++++++++
 src/box/lua/util.h     |  59 ++++++++++++++++++++++++
 4 files changed, 174 insertions(+), 70 deletions(-)
 create mode 100644 src/box/lua/util.c
 create mode 100644 src/box/lua/util.h

diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt
index 0864c3433..91cc486c1 100644
--- a/src/box/CMakeLists.txt
+++ b/src/box/CMakeLists.txt
@@ -125,6 +125,7 @@ add_library(box STATIC
     call.c
     merger.c
     ${lua_sources}
+    lua/util.c
     lua/init.c
     lua/call.c
     lua/lua_sql.c
diff --git a/src/box/lua/call.c b/src/box/lua/call.c
index 04020ef6f..1a0fb4df0 100644
--- a/src/box/lua/call.c
+++ b/src/box/lua/call.c
@@ -39,78 +39,12 @@
 #include "box/xrow.h"
 #include "box/port.h"
 #include "box/lua/tuple.h"
+#include "box/lua/util.h"
 #include "small/obuf.h"
 #include "lua_sql.h"
 #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 +58,10 @@ 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)
+		return luaT_error(L);
+	return count;
 }
 
 /*
@@ -292,9 +229,14 @@ 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)
+		return luaT_error(L);
 
 	/* Push the rest of args (a tuple). */
 	const char *args = request->args;
diff --git a/src/box/lua/util.c b/src/box/lua/util.c
new file mode 100644
index 000000000..72bd9ca3f
--- /dev/null
+++ b/src/box/lua/util.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2010-2019, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "box/lua/util.h"
+#include "box/error.h"
+#include "fiber.h"
+#include "lua/msgpack.h"
+
+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)) {
+			diag_set(ClientError, ER_NO_SUCH_PROC,
+				 name_end - name, name);
+			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) )) {
+				diag_set(ClientError, ER_NO_SUCH_PROC,
+					  name_end - name, name);
+				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. */
+		diag_set(ClientError, ER_NO_SUCH_PROC,
+			  name_end - name, name);
+		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;
+}
diff --git a/src/box/lua/util.h b/src/box/lua/util.h
new file mode 100644
index 000000000..d8f29c544
--- /dev/null
+++ b/src/box/lua/util.h
@@ -0,0 +1,59 @@
+#ifndef INCLUDES_TARANTOOL_MOD_BOX_LUA_UTILS_H
+#define INCLUDES_TARANTOOL_MOD_BOX_LUA_UTILS_H
+/*
+ * Copyright 2010-2019, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+struct lua_State;
+
+/**
+ * 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);
+
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* INCLUDES_TARANTOOL_MOD_BOX_LUA_UTILS_H */
-- 
2.21.0

  reply	other threads:[~2019-05-14 13:29 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-14 13:29 [PATCH v1 0/3] box: persistent Lua functions Kirill Shcherbatov
2019-05-14 13:29 ` Kirill Shcherbatov [this message]
2019-05-17 12:33   ` [tarantool-patches] [PATCH v1 1/3] box: refactor box_lua_find helper Kirill Shcherbatov
2019-05-14 13:29 ` [PATCH v1 2/3] schema: extend _func space to persist lua functions Kirill Shcherbatov
2019-05-14 18:21   ` [tarantool-patches] " Konstantin Osipov
2019-05-17 12:33     ` [tarantool-patches] " Kirill Shcherbatov
2019-05-17 15:29       ` Konstantin Osipov
2019-05-14 13:29 ` [PATCH v1 3/3] box: extend box.schema.func with persistent folder Kirill Shcherbatov
2019-05-14 18:24   ` [tarantool-patches] " Konstantin Osipov

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=c2c8b240772c3883369163511f6792ee5752605b.1557839195.git.kshcherbatov@tarantool.org \
    --to=kshcherbatov@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=vdavydov.dev@gmail.com \
    --subject='Re: [PATCH v1 1/3] 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