[PATCH v3 5/6] box: refactor box_lua_find helper

Kirill Shcherbatov kshcherbatov at tarantool.org
Thu Jun 13 17:08:25 MSK 2019


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.

Refactored function is renamed to luaT_func_find.

Needed for #4182, #1260
---
 src/box/lua/call.c | 54 +++++++++++++++++++++++++---------------------
 1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/src/box/lua/call.c b/src/box/lua/call.c
index 23eb29eb8..90c28a160 100644
--- a/src/box/lua/call.c
+++ b/src/box/lua/call.c
@@ -54,21 +54,19 @@
  * on top of the stack.
  */
 static int
-box_lua_find(lua_State *L, const char *name, const char *name_end)
+luaT_func_find(lua_State *L, const char *name, const char *name_end,
+	       int *count)
 {
 	int index = LUA_GLOBALSINDEX;
-	int objstack = 0;
+	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);
-			luaT_error(L);
-		}
+		if (! lua_istable(L, -1))
+			return -1;
 		start = end + 1; /* next piece of a.b.c */
 		index = lua_gettop(L); /* top of the stack */
 	}
@@ -79,14 +77,11 @@ box_lua_find(lua_State *L, const char *name, const char *name_end)
 		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);
-		}
+			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;
+		objstack = index - top;
 	}
 
 
@@ -95,25 +90,27 @@ box_lua_find(lua_State *L, const char *name, const char *name_end)
 	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);
+		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, 1);
+			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, 1);
-			lua_insert(L, 2);
+			lua_insert(L, top + 1);
+			lua_insert(L, top + 2);
+			lua_pop(L, objstack - 1);
 			objstack = 1;
 		}
-		lua_settop(L, 1 + objstack);
 	}
-	return 1 + objstack;
+	*count = 1 + objstack;
+	return 0;
 }
 
 /**
@@ -129,7 +126,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;
 }
 
 /*
@@ -352,9 +354,13 @@ execute_lua_call(lua_State *L)
 	const char *name = ctx->name;
 	uint32_t name_len = ctx->name_len;
 
-	int oc = 0; /* how many objects are on stack after box_lua_find */
+	/* How many objects are on stack after luaT_func_find. */
+	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). */
 	int top = lua_gettop(L);
-- 
2.21.0




More information about the Tarantool-patches mailing list