aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-12-02 11:53:09 +0100
committerBenoit Germain <benoit.germain@ubisoft.com>2024-12-02 11:53:09 +0100
commitca7657e24549acb8a2dd45fa81c309b5bf9f61ee (patch)
tree0124afa9a67d5f9d64fdbad4724bc715b7b502fb /src
parent0728e80bc2d3f5609f19b76f2bcf10412ce029b4 (diff)
downloadlanes-ca7657e24549acb8a2dd45fa81c309b5bf9f61ee.tar.gz
lanes-ca7657e24549acb8a2dd45fa81c309b5bf9f61ee.tar.bz2
lanes-ca7657e24549acb8a2dd45fa81c309b5bf9f61ee.zip
Data transfer supports registered non-deep full userdata
Diffstat (limited to 'src')
-rw-r--r--src/intercopycontext.cpp98
-rw-r--r--src/intercopycontext.hpp2
-rw-r--r--src/tools.cpp29
3 files changed, 103 insertions, 26 deletions
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp
index 568e4cb..1be4c53 100644
--- a/src/intercopycontext.cpp
+++ b/src/intercopycontext.cpp
@@ -55,7 +55,7 @@ static int buf_writer(lua_State* L_, void const* b_, size_t size_, void* ud_)
55 55
56// function sentinel used to transfer native functions from/to keeper states 56// function sentinel used to transfer native functions from/to keeper states
57[[nodiscard]] 57[[nodiscard]]
58static int func_lookup_sentinel(lua_State* L_) 58static int func_lookup_sentinel(lua_State* const L_)
59{ 59{
60 raise_luaL_error(L_, "function lookup sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1))); 60 raise_luaL_error(L_, "function lookup sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1)));
61} 61}
@@ -64,7 +64,7 @@ static int func_lookup_sentinel(lua_State* L_)
64 64
65// function sentinel used to transfer native table from/to keeper states 65// function sentinel used to transfer native table from/to keeper states
66[[nodiscard]] 66[[nodiscard]]
67static int table_lookup_sentinel(lua_State* L_) 67static int table_lookup_sentinel(lua_State* const L_)
68{ 68{
69 raise_luaL_error(L_, "table lookup sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1))); 69 raise_luaL_error(L_, "table lookup sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1)));
70} 70}
@@ -73,23 +73,32 @@ static int table_lookup_sentinel(lua_State* L_)
73 73
74// function sentinel used to transfer cloned full userdata from/to keeper states 74// function sentinel used to transfer cloned full userdata from/to keeper states
75[[nodiscard]] 75[[nodiscard]]
76static int userdata_clone_sentinel(lua_State* L_) 76static int userdata_clone_sentinel(lua_State* const L_)
77{ 77{
78 raise_luaL_error(L_, "userdata clone sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1))); 78 raise_luaL_error(L_, "userdata clone sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1)));
79} 79}
80 80
81// ################################################################################################# 81// #################################################################################################
82 82
83// retrieve the name of a function/table in the lookup database 83// function sentinel used to transfer native table from/to keeper states
84[[nodiscard]]
85static int userdata_lookup_sentinel(lua_State* const L_)
86{
87 raise_luaL_error(L_, "userdata lookup sentinel for %s, should never be called", lua_tostring(L_, lua_upvalueindex(1)));
88}
89
90// #################################################################################################
91
92// retrieve the name of a function/table/userdata in the lookup database
84[[nodiscard]] 93[[nodiscard]]
85std::string_view InterCopyContext::findLookupName() const 94std::string_view InterCopyContext::findLookupName() const
86{ 95{
87 LUA_ASSERT(L1, lua_isfunction(L1, L1_i) || lua_istable(L1, L1_i)); // L1: ... v ... 96 LUA_ASSERT(L1, lua_isfunction(L1, L1_i) || lua_istable(L1, L1_i) || luaG_type(L1, L1_i) == LuaType::USERDATA);
88 STACK_CHECK_START_REL(L1, 0); 97 STACK_CHECK_START_REL(L1, 0); // L1: ... v ...
89 STACK_GROW(L1, 3); // up to 3 slots are necessary on error 98 STACK_GROW(L1, 3); // up to 3 slots are necessary on error
90 if (mode == LookupMode::FromKeeper) { 99 if (mode == LookupMode::FromKeeper) {
91 lua_CFunction const _f{ lua_tocfunction(L1, L1_i) }; // should *always* be one of the function sentinels 100 lua_CFunction const _f{ lua_tocfunction(L1, L1_i) }; // should *always* be one of the sentinel functions
92 if (_f == func_lookup_sentinel || _f == table_lookup_sentinel || _f == userdata_clone_sentinel) { 101 if (_f == func_lookup_sentinel || _f == table_lookup_sentinel || _f == userdata_clone_sentinel || _f == userdata_lookup_sentinel) {
93 lua_getupvalue(L1, L1_i, 1); // L1: ... v ... "f.q.n" 102 lua_getupvalue(L1, L1_i, 1); // L1: ... v ... "f.q.n"
94 } else { 103 } else {
95 // if this is not a sentinel, this is some user-created table we wanted to lookup 104 // if this is not a sentinel, this is some user-created table we wanted to lookup
@@ -110,8 +119,8 @@ std::string_view InterCopyContext::findLookupName() const
110 // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database 119 // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database
111 lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... 120 lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ...
112 STACK_CHECK(L1, 0); 121 STACK_CHECK(L1, 0);
113 if (_fqn.empty() && !lua_istable(L1, L1_i)) { // raise an error if we try to send an unknown function (but not for tables) 122 if (_fqn.empty() && !lua_istable(L1, L1_i)) { // raise an error if we try to send an unknown function/userdata (but not for tables)
114 // try to discover the name of the function we want to send 123 // try to discover the name of the function/userdata we want to send
115 kLaneNameRegKey.pushValue(L1); // L1: ... v ... lane_name 124 kLaneNameRegKey.pushValue(L1); // L1: ... v ... lane_name
116 std::string_view const _from{ luaG_tostring(L1, kIdxTop) }; 125 std::string_view const _from{ luaG_tostring(L1, kIdxTop) };
117 lua_pushcfunction(L1, LG_nameof); // L1: ... v ... lane_name LG_nameof 126 lua_pushcfunction(L1, LG_nameof); // L1: ... v ... lane_name LG_nameof
@@ -331,7 +340,8 @@ void InterCopyContext::lookupNativeFunction() const
331 lua_rawget(L2, -2); // L1: ... f ... L2: {} f 340 lua_rawget(L2, -2); // L1: ... f ... L2: {} f
332 // nil means we don't know how to transfer stuff: user should do something 341 // nil means we don't know how to transfer stuff: user should do something
333 // anything other than function or table should not happen! 342 // anything other than function or table should not happen!
334 if (!lua_isfunction(L2, -1) && !lua_istable(L2, -1)) { 343 LuaType const _objType{ luaG_type(L2, kIdxTop) };
344 if (_objType != LuaType::FUNCTION && _objType != LuaType::TABLE && _objType != LuaType::USERDATA) {
335 kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name 345 kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name
336 std::string_view const _from{ luaG_tostring(L1, kIdxTop) }; 346 std::string_view const _from{ luaG_tostring(L1, kIdxTop) };
337 lua_pop(L1, 1); // L1: ... f ... 347 lua_pop(L1, 1); // L1: ... f ...
@@ -340,9 +350,10 @@ void InterCopyContext::lookupNativeFunction() const
340 lua_pop(L2, 1); // L2: {} f 350 lua_pop(L2, 1); // L2: {} f
341 raise_luaL_error( 351 raise_luaL_error(
342 getErrL(), 352 getErrL(),
343 "%s%s: function '%s' not found in %s destination transfer database.", 353 "%s%s: %s '%s' not found in %s destination transfer database.",
344 lua_isnil(L2, -1) ? "" : "INTERNAL ERROR IN ", 354 lua_isnil(L2, -1) ? "" : "INTERNAL ERROR IN ",
345 _from.empty() ? "main" : _from.data(), 355 _from.empty() ? "main" : _from.data(),
356 luaG_typename(L2, _objType),
346 _fqn.data(), 357 _fqn.data(),
347 _to.empty() ? "main" : _to.data()); 358 _to.empty() ? "main" : _to.data());
348 return; 359 return;
@@ -397,8 +408,8 @@ void InterCopyContext::copyCachedFunction() const
397 LUA_ASSERT(L1, lua_isfunction(L2, -1)); 408 LUA_ASSERT(L1, lua_isfunction(L2, -1));
398 } else { // function is native/LuaJIT: no need to cache 409 } else { // function is native/LuaJIT: no need to cache
399 lookupNativeFunction(); // L2: ... {cache} ... function 410 lookupNativeFunction(); // L2: ... {cache} ... function
400 // if the function was in fact a lookup sentinel, we can either get a function or a table here 411 // if the function was in fact a lookup sentinel, we can either get a function, table or full userdata here
401 LUA_ASSERT(L1, lua_isfunction(L2, -1) || lua_istable(L2, -1)); 412 LUA_ASSERT(L1, lua_isfunction(L2, kIdxTop) || lua_istable(L2, kIdxTop) || luaG_type(L2, kIdxTop) == LuaType::USERDATA);
402 } 413 }
403} 414}
404 415
@@ -678,6 +689,59 @@ bool InterCopyContext::pushCachedTable() const
678 689
679// ################################################################################################# 690// #################################################################################################
680 691
692// Push a looked-up full userdata.
693[[nodiscard]]
694bool InterCopyContext::lookupUserdata() const
695{
696 // get the name of the userdata we want to send
697 std::string_view const _fqn{ findLookupName() };
698 // push the equivalent userdata in the destination's stack, retrieved from the lookup table
699 STACK_CHECK_START_REL(L2, 0);
700 STACK_GROW(L2, 3); // up to 3 slots are necessary on error
701 switch (mode) {
702 default: // shouldn't happen, in theory...
703 raise_luaL_error(getErrL(), "internal error: unknown lookup mode");
704 break;
705
706 case LookupMode::ToKeeper:
707 // push a sentinel closure that holds the lookup name as upvalue
708 luaG_pushstring(L2, _fqn); // L1: ... f ... L2: "f.q.n"
709 lua_pushcclosure(L2, userdata_lookup_sentinel, 1); // L1: ... f ... L2: f
710 break;
711
712 case LookupMode::LaneBody:
713 case LookupMode::FromKeeper:
714 kLookupRegKey.pushValue(L2); // L1: ... f ... L2: {}
715 STACK_CHECK(L2, 1);
716 LUA_ASSERT(L1, lua_istable(L2, -1));
717 luaG_pushstring(L2, _fqn); // L1: ... f ... L2: {} "f.q.n"
718 lua_rawget(L2, -2); // L1: ... f ... L2: {} f
719 // nil means we don't know how to transfer stuff: user should do something
720 // anything other than function or table should not happen!
721 if (!lua_isfunction(L2, -1) && !lua_istable(L2, -1)) {
722 kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name
723 std::string_view const _from{ luaG_tostring(L1, kIdxTop) };
724 lua_pop(L1, 1); // L1: ... f ...
725 kLaneNameRegKey.pushValue(L2); // L1: ... f ... L2: {} f lane_name
726 std::string_view const _to{ luaG_tostring(L2, kIdxTop) };
727 lua_pop(L2, 1); // L2: {} f
728 raise_luaL_error(
729 getErrL(),
730 "%s%s: userdata '%s' not found in %s destination transfer database.",
731 lua_isnil(L2, -1) ? "" : "INTERNAL ERROR IN ",
732 _from.empty() ? "main" : _from.data(),
733 _fqn.data(),
734 _to.empty() ? "main" : _to.data());
735 }
736 lua_remove(L2, -2); // L2: f
737 break;
738 }
739 STACK_CHECK(L2, 1);
740 return true;
741}
742
743// #################################################################################################
744
681[[nodiscard]] 745[[nodiscard]]
682bool InterCopyContext::tryCopyClonable() const 746bool InterCopyContext::tryCopyClonable() const
683{ 747{
@@ -1099,6 +1163,12 @@ bool InterCopyContext::interCopyUserdata() const
1099 return true; 1163 return true;
1100 } 1164 }
1101 1165
1166 // Last, let's try to see if this userdata is special (aka is it some userdata that we registered in our lookup databases during module registration?)
1167 if (lookupUserdata()) {
1168 LUA_ASSERT(L1, luaG_type(L2, kIdxTop) == LuaType::USERDATA || (lua_tocfunction(L2, kIdxTop) == userdata_lookup_sentinel)); // from lookup data. can also be userdata_lookup_sentinel if this is a userdata we know
1169 return true;
1170 }
1171
1102 raise_luaL_error(getErrL(), "can't copy non-deep full userdata across lanes"); 1172 raise_luaL_error(getErrL(), "can't copy non-deep full userdata across lanes");
1103} 1173}
1104 1174
diff --git a/src/intercopycontext.hpp b/src/intercopycontext.hpp
index 84d9e70..7008919 100644
--- a/src/intercopycontext.hpp
+++ b/src/intercopycontext.hpp
@@ -64,6 +64,8 @@ class InterCopyContext
64 64
65 // for use in inter_copy_userdata 65 // for use in inter_copy_userdata
66 [[nodiscard]] 66 [[nodiscard]]
67 bool lookupUserdata() const;
68 [[nodiscard]]
67 bool tryCopyClonable() const; 69 bool tryCopyClonable() const;
68 [[nodiscard]] 70 [[nodiscard]]
69 bool tryCopyDeep() const; 71 bool tryCopyDeep() const;
diff --git a/src/tools.cpp b/src/tools.cpp
index 827c4a4..cd64d13 100644
--- a/src/tools.cpp
+++ b/src/tools.cpp
@@ -123,7 +123,7 @@ namespace tools {
123 * receives 2 arguments: a name k and an object o 123 * receives 2 arguments: a name k and an object o
124 * add two entries ["fully.qualified.name"] = o 124 * add two entries ["fully.qualified.name"] = o
125 * and [o] = "fully.qualified.name" 125 * and [o] = "fully.qualified.name"
126 * where <o> is either a table or a function 126 * where <o> is either a table, a function, or a full userdata
127 * if we already had an entry of type [o] = ..., replace the name if the new one is shorter 127 * if we already had an entry of type [o] = ..., replace the name if the new one is shorter
128 * pops the processed object from the stack 128 * pops the processed object from the stack
129 */ 129 */
@@ -191,7 +191,7 @@ static void update_lookup_entry(lua_State* const L_, StackIndex const ctxBase_,
191 191
192// ################################################################################################# 192// #################################################################################################
193 193
194static void populate_func_lookup_table_recur(lua_State* const L_, StackIndex const dbIdx_, StackIndex const i_, int const depth_) 194static void populate_lookup_table_recur(lua_State* const L_, StackIndex const dbIdx_, StackIndex const i_, int const depth_)
195{ 195{
196 // slot dbIdx_ contains the lookup database table 196 // slot dbIdx_ contains the lookup database table
197 // slot dbIdx_ + 1 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot i_ 197 // slot dbIdx_ + 1 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot i_
@@ -199,7 +199,7 @@ static void populate_func_lookup_table_recur(lua_State* const L_, StackIndex con
199 // slot dbIdx_ + 2 contains a cache that stores all already visited tables to avoid infinite recursion loops 199 // slot dbIdx_ + 2 contains a cache that stores all already visited tables to avoid infinite recursion loops
200 StackIndex const _cache{ dbIdx_ + 2 }; 200 StackIndex const _cache{ dbIdx_ + 2 };
201 DEBUGSPEW_CODE(Universe* const _U{ Universe::Get(L_) }); 201 DEBUGSPEW_CODE(Universe* const _U{ Universe::Get(L_) });
202 DEBUGSPEW_CODE(DebugSpew(_U) << "populate_func_lookup_table_recur()" << std::endl); 202 DEBUGSPEW_CODE(DebugSpew(_U) << "populate_lookup_table_recur()" << std::endl);
203 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); 203 DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U });
204 204
205 STACK_GROW(L_, 6); 205 STACK_GROW(L_, 6);
@@ -231,14 +231,14 @@ static void populate_func_lookup_table_recur(lua_State* const L_, StackIndex con
231 231
232 // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search) 232 // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search)
233 lua_newtable(L_); // L_: ... {i_} {bfc} 233 lua_newtable(L_); // L_: ... {i_} {bfc}
234 int const breadthFirstCache{ lua_gettop(L_) }; 234 StackIndex const _breadthFirstCache{ lua_gettop(L_) };
235 // iterate over all entries in the processed table 235 // iterate over all entries in the processed table
236 lua_pushnil(L_); // L_: ... {i_} {bfc} nil 236 lua_pushnil(L_); // L_: ... {i_} {bfc} nil
237 while (lua_next(L_, i_) != 0) { // L_: ... {i_} {bfc} k v 237 while (lua_next(L_, i_) != 0) { // L_: ... {i_} {bfc} k v
238 // just for debug, not actually needed 238 // just for debug, not actually needed
239 // std::string_view const _key{ (luaG_type(L_, -2) == LuaType::STRING) ? luaG_tostring(L_, -2) : "not a string" }; 239 // std::string_view const _key{ (luaG_type(L_, -2) == LuaType::STRING) ? luaG_tostring(L_, -2) : "not a string" };
240 // subtable: process it recursively 240 // subtable: process it recursively
241 if (lua_istable(L_, -1)) { // L_: ... {i_} {bfc} k {} 241 if (lua_istable(L_, kIdxTop)) { // L_: ... {i_} {bfc} k {}
242 // increment visit count to make sure we will actually scan it at this recursive level 242 // increment visit count to make sure we will actually scan it at this recursive level
243 lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} 243 lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {}
244 lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} {} 244 lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} {}
@@ -250,22 +250,26 @@ static void populate_func_lookup_table_recur(lua_State* const L_, StackIndex con
250 // store the table in the breadth-first cache 250 // store the table in the breadth-first cache
251 lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k 251 lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k
252 lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k {} 252 lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k {}
253 lua_rawset(L_, breadthFirstCache); // L_: ... {i_} {bfc} k {} 253 lua_rawset(L_, _breadthFirstCache); // L_: ... {i_} {bfc} k {}
254 // generate a name, and if we already had one name, keep whichever is the shorter 254 // generate a name, and if we already had one name, keep whichever is the shorter
255 update_lookup_entry(L_, dbIdx_, depth_); // L_: ... {i_} {bfc} k 255 update_lookup_entry(L_, dbIdx_, depth_); // L_: ... {i_} {bfc} k
256 } else if (lua_isfunction(L_, -1) && (luaG_getfuncsubtype(L_, kIdxTop) != FuncSubType::Bytecode)) { 256 } else if (lua_isfunction(L_, kIdxTop) && (luaG_getfuncsubtype(L_, kIdxTop) != FuncSubType::Bytecode)) {
257 // generate a name, and if we already had one name, keep whichever is the shorter 257 // generate a name, and if we already had one name, keep whichever is the shorter
258 // this pops the function from the stack 258 // this pops the function from the stack
259 update_lookup_entry(L_, dbIdx_, depth_); // L_: ... {i_} {bfc} k 259 update_lookup_entry(L_, dbIdx_, depth_); // L_: ... {i_} {bfc} k
260 } else if (luaG_type(L_, kIdxTop) == LuaType::USERDATA) {
261 // generate a name, and if we already had one name, keep whichever is the shorter
262 // this pops the userdata from the stack
263 update_lookup_entry(L_, dbIdx_, depth_); // L_: ... {i_} {bfc} k
260 } else { 264 } else {
261 lua_pop(L_, 1); // L_: ... {i_} {bfc} k 265 lua_pop(L_, 1); // L_: ... {i_} {bfc} k
262 } 266 }
263 STACK_CHECK(L_, 2); 267 STACK_CHECK(L_, 2);
264 } 268 }
265 // now process the tables we encountered at that depth 269 // now process the tables we encountered at that depth
266 int const _deeper{ depth_ + 1 }; 270 int const _deeper{ depth_ + 1 };
267 lua_pushnil(L_); // L_: ... {i_} {bfc} nil 271 lua_pushnil(L_); // L_: ... {i_} {bfc} nil
268 while (lua_next(L_, breadthFirstCache) != 0) { // L_: ... {i_} {bfc} k {} 272 while (lua_next(L_, _breadthFirstCache) != 0) { // L_: ... {i_} {bfc} k {}
269 DEBUGSPEW_CODE(std::string_view const _key{ (luaG_type(L_, -2) == LuaType::STRING) ? luaG_tostring(L_, -2) : std::string_view{ "<not a string>" } }); 273 DEBUGSPEW_CODE(std::string_view const _key{ (luaG_type(L_, -2) == LuaType::STRING) ? luaG_tostring(L_, -2) : std::string_view{ "<not a string>" } });
270 DEBUGSPEW_CODE(DebugSpew(_U) << "table '"<< _key <<"'" << std::endl); 274 DEBUGSPEW_CODE(DebugSpew(_U) << "table '"<< _key <<"'" << std::endl);
271 DEBUGSPEW_CODE(DebugSpewIndentScope _scope2{ _U }); 275 DEBUGSPEW_CODE(DebugSpewIndentScope _scope2{ _U });
@@ -285,7 +289,7 @@ static void populate_func_lookup_table_recur(lua_State* const L_, StackIndex con
285 // push table name in fqn stack (note that concatenation will crash if name is a not string!) 289 // push table name in fqn stack (note that concatenation will crash if name is a not string!)
286 lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k 290 lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k
287 lua_rawseti(L_, _fqn, _deeper); // L_: ... {i_} {bfc} k {} 291 lua_rawseti(L_, _fqn, _deeper); // L_: ... {i_} {bfc} k {}
288 populate_func_lookup_table_recur(L_, dbIdx_, StackIndex{ lua_gettop(L_) }, _deeper); 292 populate_lookup_table_recur(L_, dbIdx_, StackIndex{ lua_gettop(L_) }, _deeper);
289 lua_pop(L_, 1); // L_: ... {i_} {bfc} k 293 lua_pop(L_, 1); // L_: ... {i_} {bfc} k
290 STACK_CHECK(L_, 2); 294 STACK_CHECK(L_, 2);
291 } 295 }
@@ -316,7 +320,8 @@ namespace tools {
316 StackIndex const _dbIdx{ lua_gettop(L_) }; 320 StackIndex const _dbIdx{ lua_gettop(L_) };
317 STACK_CHECK(L_, 1); 321 STACK_CHECK(L_, 1);
318 LUA_ASSERT(L_, lua_istable(L_, -1)); 322 LUA_ASSERT(L_, lua_istable(L_, -1));
319 if (luaG_type(L_, _in_base) == LuaType::FUNCTION) { // for example when a module is a simple function 323 LuaType const _moduleType{ luaG_type(L_, _in_base) };
324 if ((_moduleType == LuaType::FUNCTION) || (_moduleType == LuaType::USERDATA)) { // for example when a module is a simple function
320 if (_name.empty()) { 325 if (_name.empty()) {
321 _name = "nullptr"; 326 _name = "nullptr";
322 } 327 }
@@ -343,7 +348,7 @@ namespace tools {
343 // retrieve the cache, create it if we haven't done it yet 348 // retrieve the cache, create it if we haven't done it yet
344 std::ignore = kLookupCacheRegKey.getSubTable(L_, NArr{ 0 }, NRec{ 0 }); // L_: {} {fqn} {cache} 349 std::ignore = kLookupCacheRegKey.getSubTable(L_, NArr{ 0 }, NRec{ 0 }); // L_: {} {fqn} {cache}
345 // process everything we find in that table, filling in lookup data for all functions and tables we see there 350 // process everything we find in that table, filling in lookup data for all functions and tables we see there
346 populate_func_lookup_table_recur(L_, _dbIdx, _in_base, _startDepth); 351 populate_lookup_table_recur(L_, _dbIdx, _in_base, _startDepth);
347 lua_pop(L_, 3); // L_: 352 lua_pop(L_, 3); // L_:
348 } else { 353 } else {
349 lua_pop(L_, 1); // L_: 354 lua_pop(L_, 1); // L_: