From 6ecd7ee13c329769cfa0461f67c97982f28096b2 Mon Sep 17 00:00:00 2001
From: Mergen Imeev <imeevma@gmail.com>
Date: Sat, 17 Nov 2018 15:37:17 +0300
Subject: [PATCH] box: add method dump_lua to port

New method dump_lua dumps saved in port tuples to Lua stack. It
will allow us to call this method without any other interaction
with port.

Needed for #3505
---
 src/box/lua/call.c  |  1 +
 src/box/lua/misc.cc | 29 ++++++++++++++++-------------
 src/box/port.c      | 10 ++++++++++
 src/box/port.h      |  6 ++++++
 4 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/src/box/lua/call.c b/src/box/lua/call.c
index 1f204269ed..52939ae798 100644
--- a/src/box/lua/call.c
+++ b/src/box/lua/call.c
@@ -424,6 +424,7 @@ port_lua_dump_plain(struct port *port, uint32_t *size);
 static const struct port_vtab port_lua_vtab = {
 	.dump_msgpack = port_lua_dump,
 	.dump_msgpack_16 = port_lua_dump_16,
+	.dump_lua = NULL,
 	.dump_plain = port_lua_dump_plain,
 	.destroy = port_lua_destroy,
 };
diff --git a/src/box/lua/misc.cc b/src/box/lua/misc.cc
index 8bd33aed13..8de7401fa2 100644
--- a/src/box/lua/misc.cc
+++ b/src/box/lua/misc.cc
@@ -56,23 +56,26 @@ lbox_encode_tuple_on_gc(lua_State *L, int idx, size_t *p_len)
 	return (char *) region_join_xc(gc, *p_len);
 }
 
-/* }}} */
-
-/** {{{ Lua/C implementation of index:select(): used only by Vinyl **/
-
-static inline void
-lbox_port_to_table(lua_State *L, struct port *port_base)
+/**
+ * Dump port_tuple content to Lua as a table. Used in box/port.c,
+ * but implemented here to eliminate port.c dependency on Lua.
+ */
+extern "C" void
+port_tuple_dump_lua(struct port *base, struct lua_State *L)
 {
-	struct port_tuple *port = port_tuple(port_base);
+	struct port_tuple *port = port_tuple(base);
 	lua_createtable(L, port->size, 0);
-	struct port_tuple_entry *entry = port->first;
-	for (int i = 0 ; i < port->size; i++) {
-		luaT_pushtuple(L, entry->tuple);
-		lua_rawseti(L, -2, i + 1);
-		entry = entry->next;
+	struct port_tuple_entry *pe = port->first;
+	for (int i = 0; pe != NULL; pe = pe->next) {
+		luaT_pushtuple(L, pe->tuple);
+		lua_rawseti(L, -2, ++i);
 	}
 }
 
+/* }}} */
+
+/** {{{ Lua/C implementation of index:select(): used only by Vinyl **/
+
 static int
 lbox_select(lua_State *L)
 {
@@ -106,7 +109,7 @@ lbox_select(lua_State *L)
 	 * table always crashed the first (can't be fixed with pcall).
 	 * https://github.com/tarantool/tarantool/issues/1182
 	 */
-	lbox_port_to_table(L, &port);
+	port_dump_lua(&port, L);
 	port_destroy(&port);
 	return 1; /* lua table with tuples */
 }
diff --git a/src/box/port.c b/src/box/port.c
index 266cf3dbe6..853d24c5f3 100644
--- a/src/box/port.c
+++ b/src/box/port.c
@@ -121,6 +121,9 @@ port_tuple_dump_msgpack(struct port *base, struct obuf *out)
 	return 1;
 }
 
+extern void
+port_tuple_dump_lua(struct port *base, struct lua_State *L);
+
 void
 port_destroy(struct port *port)
 {
@@ -139,6 +142,12 @@ port_dump_msgpack_16(struct port *port, struct obuf *out)
 	return port->vtab->dump_msgpack_16(port, out);
 }
 
+void
+port_dump_lua(struct port *port, struct lua_State *L)
+{
+	port->vtab->dump_lua(port, L);
+}
+
 const char *
 port_dump_plain(struct port *port, uint32_t *size)
 {
@@ -161,6 +170,7 @@ port_free(void)
 const struct port_vtab port_tuple_vtab = {
 	.dump_msgpack = port_tuple_dump_msgpack,
 	.dump_msgpack_16 = port_tuple_dump_msgpack_16,
+	.dump_lua = port_tuple_dump_lua,
 	.dump_plain = NULL,
 	.destroy = port_tuple_destroy,
 };
diff --git a/src/box/port.h b/src/box/port.h
index 882bb37914..751e44efe5 100644
--- a/src/box/port.h
+++ b/src/box/port.h
@@ -77,6 +77,8 @@ struct port_vtab {
 	 * 1.6 format.
 	 */
 	int (*dump_msgpack_16)(struct port *port, struct obuf *out);
+	/** Dump the content of a port to Lua stack. */
+	void (*dump_lua)(struct port *port, struct lua_State *L);
 	/**
 	 * Dump a port content as a plain text into a buffer,
 	 * allocated inside.
@@ -184,6 +186,10 @@ port_dump_msgpack(struct port *port, struct obuf *out);
 int
 port_dump_msgpack_16(struct port *port, struct obuf *out);
 
+/** Dump port content to Lua stack. */
+void
+port_dump_lua(struct port *port, struct lua_State *L);
+
 /**
  * Dump a port content as a plain text into a buffer,
  * allocated inside.
-- 
GitLab