aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-04-30 16:13:30 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-04-30 16:13:30 +0200
commit261a42021e44e1d3c3cfb3fc6576d3d269241c93 (patch)
tree61bf8bbf0bb334e18f4a36e5f58badd809e6bade /src
parent92ea4d16a274b4a7db0206fd74891a555f6501c9 (diff)
downloadlanes-261a42021e44e1d3c3cfb3fc6576d3d269241c93.tar.gz
lanes-261a42021e44e1d3c3cfb3fc6576d3d269241c93.tar.bz2
lanes-261a42021e44e1d3c3cfb3fc6576d3d269241c93.zip
Progressively applying the coding rules
Diffstat (limited to 'src')
-rw-r--r--src/deep.cpp64
-rw-r--r--src/deep.h1
-rw-r--r--src/tools.cpp171
-rw-r--r--src/tools.h5
4 files changed, 112 insertions, 129 deletions
diff --git a/src/deep.cpp b/src/deep.cpp
index 11e1ea7..6358745 100644
--- a/src/deep.cpp
+++ b/src/deep.cpp
@@ -66,28 +66,30 @@ static constexpr RegistryUniqueKey kDeepProxyCacheRegKey{ 0xEBCD49AE1A3DD35Eull
66 * Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. 66 * Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists.
67 * Pops the both values off the stack. 67 * Pops the both values off the stack.
68 */ 68 */
69static void set_deep_lookup(lua_State* L_) 69void DeepFactory::storeDeepLookup(lua_State* L_) const
70{ 70{
71 // the deep metatable is at the top of the stack // L_: mt
71 STACK_GROW(L_, 3); 72 STACK_GROW(L_, 3);
72 STACK_CHECK_START_REL(L_, 2); // L_: a b 73 STACK_CHECK_START_REL(L_, 0); // L_: mt
73 push_registry_subtable(L_, kDeepLookupRegKey); // L_: a b {} 74 push_registry_subtable(L_, kDeepLookupRegKey); // L_: mt {}
74 STACK_CHECK(L_, 3); 75 lua_pushvalue(L_, -2); // L_: mt {} mt
75 lua_insert(L_, -3); // L_: {} a b 76 lua_pushlightuserdata(L_, std::bit_cast<void*>(this)); // L_: mt {} mt factory
76 lua_pushvalue(L_, -1); // L_: {} a b b 77 lua_rawset(L_, -3); // L_: mt {}
77 lua_pushvalue(L_, -3); // L_: {} a b b a 78 STACK_CHECK(L_, 1);
78 lua_rawset(L_, -5); // L_: {} a b 79
79 lua_rawset(L_, -3); // L_: {} 80 lua_pushlightuserdata(L_, std::bit_cast<void*>(this)); // L_: mt {} factory
80 lua_pop(L_, 1); // L_: 81 lua_pushvalue(L_, -3); // L_: mt {} factory mt
82 lua_rawset(L_, -3); // L_: mt {}
83 STACK_CHECK(L_, 1);
84
85 lua_pop(L_, 1); // L_: mt
81 STACK_CHECK(L_, 0); 86 STACK_CHECK(L_, 0);
82} 87}
83 88
84// ################################################################################################# 89// #################################################################################################
85 90
86/* 91// Pops the key (metatable or factory) off the stack, and replaces with the deep lookup value (factory/metatable/nil).
87 * Pops the key (metatable or factory) off the stack, and replaces with the 92static void LookupDeep(lua_State* L_)
88 * deep lookup value (factory/metatable/nil).
89 */
90static void get_deep_lookup(lua_State* L_)
91{ 93{
92 STACK_GROW(L_, 1); 94 STACK_GROW(L_, 1);
93 STACK_CHECK_START_REL(L_, 1); // L_: a 95 STACK_CHECK_START_REL(L_, 1); // L_: a
@@ -102,11 +104,8 @@ static void get_deep_lookup(lua_State* L_)
102 104
103// ################################################################################################# 105// #################################################################################################
104 106
105/* 107// Return the registered factory for 'index' (deep userdata proxy), or nullptr if 'index' is not a deep userdata proxy.
106 * Return the registered factory for 'index' (deep userdata proxy), 108[[nodiscard]] static inline DeepFactory* LookupFactory(lua_State* L_, int index_, LookupMode mode_)
107 * or nullptr if 'index' is not a deep userdata proxy.
108 */
109[[nodiscard]] static inline DeepFactory* get_factory(lua_State* L_, int index_, LookupMode mode_)
110{ 109{
111 // when looking inside a keeper, we are 100% sure the object is a deep userdata 110 // when looking inside a keeper, we are 100% sure the object is a deep userdata
112 if (mode_ == LookupMode::FromKeeper) { 111 if (mode_ == LookupMode::FromKeeper) {
@@ -125,7 +124,7 @@ static void get_deep_lookup(lua_State* L_)
125 } 124 }
126 125
127 // replace metatable with the factory pointer, if it is actually a deep userdata 126 // replace metatable with the factory pointer, if it is actually a deep userdata
128 get_deep_lookup(L_); // L_: deep ... factory|nil 127 LookupDeep(L_); // L_: deep ... factory|nil
129 128
130 DeepFactory* const ret{ lua_tolightuserdata<DeepFactory>(L_, -1) }; // nullptr if not a userdata 129 DeepFactory* const ret{ lua_tolightuserdata<DeepFactory>(L_, -1) }; // nullptr if not a userdata
131 lua_pop(L_, 1); 130 lua_pop(L_, 1);
@@ -211,7 +210,7 @@ char const* DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_, int
211 // Get/create metatable for 'factory' (in this state) 210 // Get/create metatable for 'factory' (in this state)
212 DeepFactory& factory = prelude_->m_factory; 211 DeepFactory& factory = prelude_->m_factory;
213 lua_pushlightuserdata(L_, std::bit_cast<void*>(&factory)); // L_: DPC proxy factory 212 lua_pushlightuserdata(L_, std::bit_cast<void*>(&factory)); // L_: DPC proxy factory
214 get_deep_lookup(L_); // L_: DPC proxy metatable? 213 LookupDeep(L_); // L_: DPC proxy metatable|nil
215 214
216 if (lua_isnil(L_, -1)) { // No metatable yet. 215 if (lua_isnil(L_, -1)) { // No metatable yet.
217 lua_pop(L_, 1); // L_: DPC proxy 216 lua_pop(L_, 1); // L_: DPC proxy
@@ -240,12 +239,10 @@ char const* DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_, int
240 // Add our own '__gc' method wrapping the original 239 // Add our own '__gc' method wrapping the original
241 lua_pushcclosure(L_, deep_userdata_gc, 1); // DPC proxy metatable deep_userdata_gc 240 lua_pushcclosure(L_, deep_userdata_gc, 1); // DPC proxy metatable deep_userdata_gc
242 } 241 }
243 lua_setfield(L_, -2, "__gc"); // DPC proxy metatable 242 lua_setfield(L_, -2, "__gc"); // L_: DPC proxy metatable
244 243
245 // Memorize for later rounds 244 // Memorize for later rounds
246 lua_pushvalue(L_, -1); // L_: DPC proxy metatable metatable 245 factory.storeDeepLookup(L_);
247 lua_pushlightuserdata(L_, std::bit_cast<void*>(&factory)); // L_: DPC proxy metatable metatable factory
248 set_deep_lookup(L_); // L_: DPC proxy metatable
249 246
250 // 2 - cause the target state to require the module that exported the factory 247 // 2 - cause the target state to require the module that exported the factory
251 if (char const* const modname{ factory.moduleName() }; modname) { // we actually got a module name 248 if (char const* const modname{ factory.moduleName() }; modname) { // we actually got a module name
@@ -361,7 +358,7 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index_) const
361{ 358{
362 STACK_CHECK_START_REL(L_, 0); 359 STACK_CHECK_START_REL(L_, 0);
363 // ensure it is actually a deep userdata we created 360 // ensure it is actually a deep userdata we created
364 if (get_factory(L_, index_, LookupMode::LaneBody) != this) { 361 if (LookupFactory(L_, index_, LookupMode::LaneBody) != this) {
365 return nullptr; // no metatable, or wrong kind 362 return nullptr; // no metatable, or wrong kind
366 } 363 }
367 STACK_CHECK(L_, 0); 364 STACK_CHECK(L_, 0);
@@ -372,16 +369,11 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index_) const
372 369
373// ################################################################################################# 370// #################################################################################################
374 371
375/* 372// Copy deep userdata between two separate Lua states (from L1 to L2)
376 * Copy deep userdata between two separate Lua states (from L1 to L2) 373// Returns false if not a deep userdata, else true (unless an error occured)
377 * 374[[nodiscard]] bool InterCopyContext::tryCopyDeep() const
378 * Returns:
379 * the id function of the copied value, or nullptr for non-deep userdata
380 * (not copied)
381 */
382[[nodiscard]] bool InterCopyContext::copyDeep() const
383{ 375{
384 DeepFactory* const factory{ get_factory(L1, L1_i, mode) }; 376 DeepFactory* const factory{ LookupFactory(L1, L1_i, mode) };
385 if (factory == nullptr) { 377 if (factory == nullptr) {
386 return false; // not a deep userdata 378 return false; // not a deep userdata
387 } 379 }
diff --git a/src/deep.h b/src/deep.h
index 6f6e99d..6f4e64d 100644
--- a/src/deep.h
+++ b/src/deep.h
@@ -66,6 +66,7 @@ class DeepFactory
66 DeepFactory& operator=(DeepFactory const&&) = delete; 66 DeepFactory& operator=(DeepFactory const&&) = delete;
67 67
68 private: 68 private:
69 void storeDeepLookup(lua_State* L_) const;
69 // NVI: private overrides 70 // NVI: private overrides
70 [[nodiscard]] virtual DeepPrelude* newDeepObjectInternal(lua_State* L_) const = 0; 71 [[nodiscard]] virtual DeepPrelude* newDeepObjectInternal(lua_State* L_) const = 0;
71 virtual void deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const = 0; 72 virtual void deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const = 0;
diff --git a/src/tools.cpp b/src/tools.cpp
index 63bb323..f4fbf46 100644
--- a/src/tools.cpp
+++ b/src/tools.cpp
@@ -245,12 +245,12 @@ FuncSubType luaG_getfuncsubtype(lua_State* L_, int _i)
245 * if we already had an entry of type [o] = ..., replace the name if the new one is shorter 245 * if we already had an entry of type [o] = ..., replace the name if the new one is shorter
246 * pops the processed object from the stack 246 * pops the processed object from the stack
247 */ 247 */
248static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, int _ctx_base, int _depth) 248static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, int ctxBase_, int depth_)
249{ 249{
250 // slot 1 in the stack contains the table that receives everything we found 250 // slot 1 in the stack contains the table that receives everything we found
251 int const dest{ _ctx_base }; 251 int const dest{ ctxBase_ };
252 // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i 252 // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i
253 int const fqn{ _ctx_base + 1 }; 253 int const fqn{ ctxBase_ + 1 };
254 254
255 size_t prevNameLength, newNameLength; 255 size_t prevNameLength, newNameLength;
256 char const* prevName; 256 char const* prevName;
@@ -266,10 +266,10 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L
266 // push name in fqn stack (note that concatenation will crash if name is a not string or a number) 266 // push name in fqn stack (note that concatenation will crash if name is a not string or a number)
267 lua_pushvalue(L_, -3); // L_: ... {bfc} k o name? k 267 lua_pushvalue(L_, -3); // L_: ... {bfc} k o name? k
268 LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER || lua_type(L_, -1) == LUA_TSTRING); 268 LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER || lua_type(L_, -1) == LUA_TSTRING);
269 ++_depth; 269 ++depth_;
270 lua_rawseti(L_, fqn, _depth); // L_: ... {bfc} k o name? 270 lua_rawseti(L_, fqn, depth_); // L_: ... {bfc} k o name?
271 // generate name 271 // generate name
272 DEBUGSPEW_OR_NOT(newName, std::ignore) = luaG_pushFQN(L_, fqn, _depth, &newNameLength); // L_: ... {bfc} k o name? "f.q.n" 272 DEBUGSPEW_OR_NOT(newName, std::ignore) = luaG_pushFQN(L_, fqn, depth_, &newNameLength); // L_: ... {bfc} k o name? "f.q.n"
273 // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order 273 // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order
274 // on different VMs even when the tables are populated the exact same way. 274 // on different VMs even when the tables are populated the exact same way.
275 // When Lua is built with compatibility options (such as LUA_COMPAT_ALL), 275 // When Lua is built with compatibility options (such as LUA_COMPAT_ALL),
@@ -306,9 +306,9 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L
306 lua_rawset(L_, dest); // L_: ... {bfc} k 306 lua_rawset(L_, dest); // L_: ... {bfc} k
307 // remove table name from fqn stack 307 // remove table name from fqn stack
308 lua_pushnil(L_); // L_: ... {bfc} k nil 308 lua_pushnil(L_); // L_: ... {bfc} k nil
309 lua_rawseti(L_, fqn, _depth); // L_: ... {bfc} k 309 lua_rawseti(L_, fqn, depth_); // L_: ... {bfc} k
310 } 310 }
311 --_depth; 311 --depth_;
312 STACK_CHECK(L_, -1); 312 STACK_CHECK(L_, -1);
313} 313}
314 314
@@ -486,15 +486,15 @@ void populate_func_lookup_table(lua_State* L_, int i_, char const* name_)
486static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; 486static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
487 487
488// get a unique ID for metatable at [i]. 488// get a unique ID for metatable at [i].
489[[nodiscard]] static lua_Integer get_mt_id(Universe* U_, lua_State* L_, int i) 489[[nodiscard]] static lua_Integer get_mt_id(Universe* U_, lua_State* L_, int idx_)
490{ 490{
491 i = lua_absindex(L_, i); 491 idx_ = lua_absindex(L_, idx_);
492 492
493 STACK_GROW(L_, 3); 493 STACK_GROW(L_, 3);
494 494
495 STACK_CHECK_START_REL(L_, 0); 495 STACK_CHECK_START_REL(L_, 0);
496 push_registry_subtable(L_, kMtIdRegKey); // L_: ... _R[kMtIdRegKey] 496 push_registry_subtable(L_, kMtIdRegKey); // L_: ... _R[kMtIdRegKey]
497 lua_pushvalue(L_, i); // L_: ... _R[kMtIdRegKey] {mt} 497 lua_pushvalue(L_, idx_); // L_: ... _R[kMtIdRegKey] {mt}
498 lua_rawget(L_, -2); // L_: ... _R[kMtIdRegKey] mtk? 498 lua_rawget(L_, -2); // L_: ... _R[kMtIdRegKey] mtk?
499 499
500 lua_Integer id{ lua_tointeger(L_, -1) }; // 0 for nil 500 lua_Integer id{ lua_tointeger(L_, -1) }; // 0 for nil
@@ -505,12 +505,12 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
505 id = U_->next_mt_id.fetch_add(1, std::memory_order_relaxed); 505 id = U_->next_mt_id.fetch_add(1, std::memory_order_relaxed);
506 506
507 // Create two-way references: id_uint <-> table 507 // Create two-way references: id_uint <-> table
508 lua_pushvalue(L_, i); // L_: ... _R[kMtIdRegKey] {mt} 508 lua_pushvalue(L_, idx_); // L_: ... _R[kMtIdRegKey] {mt}
509 lua_pushinteger(L_, id); // L_: ... _R[kMtIdRegKey] {mt} id 509 lua_pushinteger(L_, id); // L_: ... _R[kMtIdRegKey] {mt} id
510 lua_rawset(L_, -3); // L_: ... _R[kMtIdRegKey] 510 lua_rawset(L_, -3); // L_: ... _R[kMtIdRegKey]
511 511
512 lua_pushinteger(L_, id); // L_: ... _R[kMtIdRegKey] id 512 lua_pushinteger(L_, id); // L_: ... _R[kMtIdRegKey] id
513 lua_pushvalue(L_, i); // L_: ... _R[kMtIdRegKey] id {mt} 513 lua_pushvalue(L_, idx_); // L_: ... _R[kMtIdRegKey] id {mt}
514 lua_rawset(L_, -3); // L_: ... _R[kMtIdRegKey] 514 lua_rawset(L_, -3); // L_: ... _R[kMtIdRegKey]
515 } 515 }
516 lua_pop(L_, 1); // L_: ... 516 lua_pop(L_, 1); // L_: ...
@@ -548,13 +548,11 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
548// retrieve the name of a function/table in the lookup database 548// retrieve the name of a function/table in the lookup database
549[[nodiscard]] static char const* find_lookup_name(lua_State* L_, int i_, LookupMode mode_, char const* upName_, size_t* len_) 549[[nodiscard]] static char const* find_lookup_name(lua_State* L_, int i_, LookupMode mode_, char const* upName_, size_t* len_)
550{ 550{
551 DEBUGSPEW_CODE(Universe* const U = universe_get(L_));
552 char const* fqn;
553 LUA_ASSERT(L_, lua_isfunction(L_, i_) || lua_istable(L_, i_)); // L_: ... v ... 551 LUA_ASSERT(L_, lua_isfunction(L_, i_) || lua_istable(L_, i_)); // L_: ... v ...
554 STACK_CHECK_START_REL(L_, 0); 552 STACK_CHECK_START_REL(L_, 0);
555 STACK_GROW(L_, 3); // up to 3 slots are necessary on error 553 STACK_GROW(L_, 3); // up to 3 slots are necessary on error
556 if (mode_ == LookupMode::FromKeeper) { 554 if (mode_ == LookupMode::FromKeeper) {
557 lua_CFunction f = lua_tocfunction(L_, i_); // should *always* be func_lookup_sentinel or table_lookup_sentinel! 555 lua_CFunction f = lua_tocfunction(L_, i_); // should *always* be one of the function sentinels
558 if (f == func_lookup_sentinel || f == table_lookup_sentinel || f == userdata_clone_sentinel) { 556 if (f == func_lookup_sentinel || f == table_lookup_sentinel || f == userdata_clone_sentinel) {
559 lua_getupvalue(L_, i_, 1); // L_: ... v ... "f.q.n" 557 lua_getupvalue(L_, i_, 1); // L_: ... v ... "f.q.n"
560 } else { 558 } else {
@@ -571,22 +569,24 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
571 lua_pushvalue(L_, i_); // L_: ... v ... {} v 569 lua_pushvalue(L_, i_); // L_: ... v ... {} v
572 lua_rawget(L_, -2); // L_: ... v ... {} "f.q.n" 570 lua_rawget(L_, -2); // L_: ... v ... {} "f.q.n"
573 } 571 }
574 fqn = lua_tolstring(L_, -1, len_); 572 char const* fqn{ lua_tolstring(L_, -1, len_) };
573 DEBUGSPEW_CODE(Universe* const U = universe_get(L_));
575 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END(U), fqn)); 574 DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END(U), fqn));
576 // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database 575 // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database
577 lua_pop(L_, (mode_ == LookupMode::FromKeeper) ? 1 : 2); // L_: ... v ... 576 lua_pop(L_, (mode_ == LookupMode::FromKeeper) ? 1 : 2); // L_: ... v ...
578 STACK_CHECK(L_, 0); 577 STACK_CHECK(L_, 0);
579 if (nullptr == fqn && !lua_istable(L_, i_)) { // raise an error if we try to send an unknown function (but not for tables) 578 if (nullptr == fqn && !lua_istable(L_, i_)) { // raise an error if we try to send an unknown function (but not for tables)
580 char const *from, *typewhat, *what, *gotchaA, *gotchaB; 579 *len_ = 0; // just in case
581 // try to discover the name of the function we want to send 580 // try to discover the name of the function we want to send
582 lua_getglobal(L_, "decoda_name"); // L_: ... v ... decoda_name 581 lua_getglobal(L_, "decoda_name"); // L_: ... v ... decoda_name
583 from = lua_tostring(L_, -1); 582 char const* from{ lua_tostring(L_, -1) };
584 lua_pushcfunction(L_, luaG_nameof); // L_: ... v ... decoda_name luaG_nameof 583 lua_pushcfunction(L_, luaG_nameof); // L_: ... v ... decoda_name luaG_nameof
585 lua_pushvalue(L_, i_); // L_: ... v ... decoda_name luaG_nameof t 584 lua_pushvalue(L_, i_); // L_: ... v ... decoda_name luaG_nameof t
586 lua_call(L_, 1, 2); // L_: ... v ... decoda_name "type" "name"|nil 585 lua_call(L_, 1, 2); // L_: ... v ... decoda_name "type" "name"|nil
587 typewhat = (lua_type(L_, -2) == LUA_TSTRING) ? lua_tostring(L_, -2) : luaL_typename(L_, -2); 586 char const* typewhat{ (lua_type(L_, -2) == LUA_TSTRING) ? lua_tostring(L_, -2) : luaL_typename(L_, -2) };
588 // second return value can be nil if the table was not found 587 // second return value can be nil if the table was not found
589 // probable reason: the function was removed from the source Lua state before Lanes was required. 588 // probable reason: the function was removed from the source Lua state before Lanes was required.
589 char const *what, *gotchaA, *gotchaB;
590 if (lua_isnil(L_, -1)) { 590 if (lua_isnil(L_, -1)) {
591 gotchaA = " referenced by"; 591 gotchaA = " referenced by";
592 gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; 592 gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)";
@@ -597,8 +597,6 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
597 what = (lua_type(L_, -1) == LUA_TSTRING) ? lua_tostring(L_, -1) : luaL_typename(L_, -1); 597 what = (lua_type(L_, -1) == LUA_TSTRING) ? lua_tostring(L_, -1) : luaL_typename(L_, -1);
598 } 598 }
599 raise_luaL_error(L_, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); 599 raise_luaL_error(L_, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB);
600 *len_ = 0;
601 return nullptr;
602 } 600 }
603 STACK_CHECK(L_, 0); 601 STACK_CHECK(L_, 0);
604 return fqn; 602 return fqn;
@@ -668,19 +666,13 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
668 666
669// ################################################################################################# 667// #################################################################################################
670 668
671/* 669// Check if we've already copied the same table from 'L1', and reuse the old copy. This allows table upvalues shared by multiple
672 * Check if we've already copied the same table from 'L1_', and 670// local functions to point to the same table, also in the target.
673 * reuse the old copy. This allows table upvalues shared by multiple 671// Always pushes a table to 'L2'.
674 * local functions to point to the same table, also in the target. 672// Returns true if the table was cached (no need to fill it!); false if it's a virgin.
675 * 673[[nodiscard]] bool InterCopyContext::push_cached_table() const
676 * Always pushes a table to 'L2_'.
677 *
678 * Returns true if the table was cached (no need to fill it!); false if
679 * it's a virgin.
680 */
681[[nodiscard]] static bool push_cached_table(DestState L2, CacheIndex L2_cache_i, SourceState L1, SourceIndex i)
682{ 674{
683 void const* p{ lua_topointer(L1, i) }; 675 void const* p{ lua_topointer(L1, L1_i) };
684 676
685 LUA_ASSERT(L1, L2_cache_i != 0); 677 LUA_ASSERT(L1, L2_cache_i != 0);
686 STACK_GROW(L2, 3); 678 STACK_GROW(L2, 3);
@@ -689,19 +681,19 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
689 // We don't need to use the from state ('L1') in ID since the life span 681 // We don't need to use the from state ('L1') in ID since the life span
690 // is only for the duration of a copy (both states are locked). 682 // is only for the duration of a copy (both states are locked).
691 // push a light userdata uniquely representing the table 683 // push a light userdata uniquely representing the table
692 lua_pushlightuserdata(L2, const_cast<void*>(p)); // L2: ... p 684 lua_pushlightuserdata(L2, const_cast<void*>(p)); // L1: ... t ... L2: ... p
693 685
694 // fprintf(stderr, "<< ID: %s >>\n", lua_tostring(L2, -1)); 686 // fprintf(stderr, "<< ID: %s >>\n", lua_tostring(L2, -1));
695 687
696 lua_rawget(L2, L2_cache_i); // L2: ... {cached|nil} 688 lua_rawget(L2, L2_cache_i); // L1: ... t ... L2: ... {cached|nil}
697 bool const not_found_in_cache{ lua_isnil(L2, -1) }; 689 bool const not_found_in_cache{ lua_isnil(L2, -1) };
698 if (not_found_in_cache) { 690 if (not_found_in_cache) {
699 // create a new entry in the cache 691 // create a new entry in the cache
700 lua_pop(L2, 1); // L2: ... 692 lua_pop(L2, 1); // L1: ... t ... L2: ...
701 lua_newtable(L2); // L2: ... {} 693 lua_newtable(L2); // L1: ... t ... L2: ... {}
702 lua_pushlightuserdata(L2, const_cast<void*>(p)); // L2: ... {} p 694 lua_pushlightuserdata(L2, const_cast<void*>(p)); // L1: ... t ... L2: ... {} p
703 lua_pushvalue(L2, -2); // L2: ... {} p {} 695 lua_pushvalue(L2, -2); // L1: ... t ... L2: ... {} p {}
704 lua_rawset(L2, L2_cache_i); // L2: ... {} 696 lua_rawset(L2, L2_cache_i); // L1: ... t ... L2: ... {}
705 } 697 }
706 STACK_CHECK(L2, 1); 698 STACK_CHECK(L2, 1);
707 LUA_ASSERT(L1, lua_istable(L2, -1)); 699 LUA_ASSERT(L1, lua_istable(L2, -1));
@@ -711,12 +703,12 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
711// ################################################################################################# 703// #################################################################################################
712 704
713// Return some name helping to identify an object 705// Return some name helping to identify an object
714[[nodiscard]] static int discover_object_name_recur(lua_State* L_, int shortest_, int depth_) 706[[nodiscard]] static int DiscoverObjectNameRecur(lua_State* L_, int shortest_, int depth_)
715{ 707{
716 int const what = 1; // L_: o "r" {c} {fqn} ... {?} 708 static constexpr int kWhat{ 1 }; // the object to investigate // L_: o "r" {c} {fqn} ... {?}
717 int const result = 2; 709 static constexpr int kResult{ 2 }; // where the result string is stored
718 int const cache = 3; 710 static constexpr int kCache{ 3 }; // a cache
719 int const fqn = 4; 711 static constexpr int kFQN{ 4 }; // the name compositing stack
720 // no need to scan this table if the name we will discover is longer than one we already know 712 // no need to scan this table if the name we will discover is longer than one we already know
721 if (shortest_ <= depth_ + 1) { 713 if (shortest_ <= depth_ + 1) {
722 return shortest_; 714 return shortest_;
@@ -725,7 +717,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
725 STACK_CHECK_START_REL(L_, 0); 717 STACK_CHECK_START_REL(L_, 0);
726 // stack top contains the table to search in 718 // stack top contains the table to search in
727 lua_pushvalue(L_, -1); // L_: o "r" {c} {fqn} ... {?} {?} 719 lua_pushvalue(L_, -1); // L_: o "r" {c} {fqn} ... {?} {?}
728 lua_rawget(L_, cache); // L_: o "r" {c} {fqn} ... {?} nil/1 720 lua_rawget(L_, kCache); // L_: o "r" {c} {fqn} ... {?} nil/1
729 // if table is already visited, we are done 721 // if table is already visited, we are done
730 if (!lua_isnil(L_, -1)) { 722 if (!lua_isnil(L_, -1)) {
731 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?} 723 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?}
@@ -735,7 +727,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
735 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?} 727 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?}
736 lua_pushvalue(L_, -1); // L_: o "r" {c} {fqn} ... {?} {?} 728 lua_pushvalue(L_, -1); // L_: o "r" {c} {fqn} ... {?} {?}
737 lua_pushinteger(L_, 1); // L_: o "r" {c} {fqn} ... {?} {?} 1 729 lua_pushinteger(L_, 1); // L_: o "r" {c} {fqn} ... {?} {?} 1
738 lua_rawset(L_, cache); // L_: o "r" {c} {fqn} ... {?} 730 lua_rawset(L_, kCache); // L_: o "r" {c} {fqn} ... {?}
739 // scan table contents 731 // scan table contents
740 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} nil 732 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} nil
741 while (lua_next(L_, -2)) { // L_: o "r" {c} {fqn} ... {?} k v 733 while (lua_next(L_, -2)) { // L_: o "r" {c} {fqn} ... {?} k v
@@ -745,14 +737,14 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
745 // append key name to fqn stack 737 // append key name to fqn stack
746 ++depth_; 738 ++depth_;
747 lua_pushvalue(L_, -2); // L_: o "r" {c} {fqn} ... {?} k v k 739 lua_pushvalue(L_, -2); // L_: o "r" {c} {fqn} ... {?} k v k
748 lua_rawseti(L_, fqn, depth_); // L_: o "r" {c} {fqn} ... {?} k v 740 lua_rawseti(L_, kFQN, depth_); // L_: o "r" {c} {fqn} ... {?} k v
749 if (lua_rawequal(L_, -1, what)) { // is it what we are looking for? 741 if (lua_rawequal(L_, -1, kWhat)) { // is it what we are looking for?
750 STACK_CHECK(L_, 2); 742 STACK_CHECK(L_, 2);
751 // update shortest name 743 // update shortest name
752 if (depth_ < shortest_) { 744 if (depth_ < shortest_) {
753 shortest_ = depth_; 745 shortest_ = depth_;
754 std::ignore = luaG_pushFQN(L_, fqn, depth_, nullptr); // L_: o "r" {c} {fqn} ... {?} k v "fqn" 746 std::ignore = luaG_pushFQN(L_, kFQN, depth_, nullptr); // L_: o "r" {c} {fqn} ... {?} k v "fqn"
755 lua_replace(L_, result); // L_: o "r" {c} {fqn} ... {?} k v 747 lua_replace(L_, kResult); // L_: o "r" {c} {fqn} ... {?} k v
756 } 748 }
757 // no need to search further at this level 749 // no need to search further at this level
758 lua_pop(L_, 2); // L_: o "r" {c} {fqn} ... {?} 750 lua_pop(L_, 2); // L_: o "r" {c} {fqn} ... {?}
@@ -765,16 +757,16 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
765 757
766 case LUA_TTABLE: // L_: o "r" {c} {fqn} ... {?} k {} 758 case LUA_TTABLE: // L_: o "r" {c} {fqn} ... {?} k {}
767 STACK_CHECK(L_, 2); 759 STACK_CHECK(L_, 2);
768 shortest_ = discover_object_name_recur(L_, shortest_, depth_); 760 shortest_ = DiscoverObjectNameRecur(L_, shortest_, depth_);
769 // search in the table's metatable too 761 // search in the table's metatable too
770 if (lua_getmetatable(L_, -1)) { // L_: o "r" {c} {fqn} ... {?} k {} {mt} 762 if (lua_getmetatable(L_, -1)) { // L_: o "r" {c} {fqn} ... {?} k {} {mt}
771 if (lua_istable(L_, -1)) { 763 if (lua_istable(L_, -1)) {
772 ++depth_; 764 ++depth_;
773 lua_pushliteral(L_, "__metatable"); // L_: o "r" {c} {fqn} ... {?} k {} {mt} "__metatable" 765 lua_pushliteral(L_, "__metatable"); // L_: o "r" {c} {fqn} ... {?} k {} {mt} "__metatable"
774 lua_rawseti(L_, fqn, depth_); // L_: o "r" {c} {fqn} ... {?} k {} {mt} 766 lua_rawseti(L_, kFQN, depth_); // L_: o "r" {c} {fqn} ... {?} k {} {mt}
775 shortest_ = discover_object_name_recur(L_, shortest_, depth_); 767 shortest_ = DiscoverObjectNameRecur(L_, shortest_, depth_);
776 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} k {} {mt} nil 768 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} k {} {mt} nil
777 lua_rawseti(L_, fqn, depth_); // L_: o "r" {c} {fqn} ... {?} k {} {mt} 769 lua_rawseti(L_, kFQN, depth_); // L_: o "r" {c} {fqn} ... {?} k {} {mt}
778 --depth_; 770 --depth_;
779 } 771 }
780 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?} k {} 772 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?} k {}
@@ -793,10 +785,10 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
793 if (lua_istable(L_, -1)) { 785 if (lua_istable(L_, -1)) {
794 ++depth_; 786 ++depth_;
795 lua_pushliteral(L_, "__metatable"); // L_: o "r" {c} {fqn} ... {?} k U {mt} "__metatable" 787 lua_pushliteral(L_, "__metatable"); // L_: o "r" {c} {fqn} ... {?} k U {mt} "__metatable"
796 lua_rawseti(L_, fqn, depth_); // L_: o "r" {c} {fqn} ... {?} k U {mt} 788 lua_rawseti(L_, kFQN, depth_); // L_: o "r" {c} {fqn} ... {?} k U {mt}
797 shortest_ = discover_object_name_recur(L_, shortest_, depth_); 789 shortest_ = DiscoverObjectNameRecur(L_, shortest_, depth_);
798 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} k U {mt} nil 790 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} k U {mt} nil
799 lua_rawseti(L_, fqn, depth_); // L_: o "r" {c} {fqn} ... {?} k U {mt} 791 lua_rawseti(L_, kFQN, depth_); // L_: o "r" {c} {fqn} ... {?} k U {mt}
800 --depth_; 792 --depth_;
801 } 793 }
802 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?} k U 794 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?} k U
@@ -809,10 +801,10 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
809 if (lua_istable(L_, -1)) { // if it is a table, look inside 801 if (lua_istable(L_, -1)) { // if it is a table, look inside
810 ++depth_; 802 ++depth_;
811 lua_pushliteral(L_, "uservalue"); // L_: o "r" {c} {fqn} ... {?} k v {u} "uservalue" 803 lua_pushliteral(L_, "uservalue"); // L_: o "r" {c} {fqn} ... {?} k v {u} "uservalue"
812 lua_rawseti(L_, fqn, depth_); // L_: o "r" {c} {fqn} ... {?} k v {u} 804 lua_rawseti(L_, kFQN, depth_); // L_: o "r" {c} {fqn} ... {?} k v {u}
813 shortest_ = discover_object_name_recur(L_, shortest_, depth_); 805 shortest_ = DiscoverObjectNameRecur(L_, shortest_, depth_);
814 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} k v {u} nil 806 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} k v {u} nil
815 lua_rawseti(L_, fqn, depth_); // L_: o "r" {c} {fqn} ... {?} k v {u} 807 lua_rawseti(L_, kFQN, depth_); // L_: o "r" {c} {fqn} ... {?} k v {u}
816 --depth_; 808 --depth_;
817 } 809 }
818 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?} k U 810 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?} k U
@@ -828,7 +820,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
828 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?} k 820 lua_pop(L_, 1); // L_: o "r" {c} {fqn} ... {?} k
829 // remove name from fqn stack 821 // remove name from fqn stack
830 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} k nil 822 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} k nil
831 lua_rawseti(L_, fqn, depth_); // L_: o "r" {c} {fqn} ... {?} k 823 lua_rawseti(L_, kFQN, depth_); // L_: o "r" {c} {fqn} ... {?} k
832 STACK_CHECK(L_, 1); 824 STACK_CHECK(L_, 1);
833 --depth_; 825 --depth_;
834 } // L_: o "r" {c} {fqn} ... {?} 826 } // L_: o "r" {c} {fqn} ... {?}
@@ -836,14 +828,14 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull };
836 // remove the visited table from the cache, in case a shorter path to the searched object exists 828 // remove the visited table from the cache, in case a shorter path to the searched object exists
837 lua_pushvalue(L_, -1); // L_: o "r" {c} {fqn} ... {?} {?} 829 lua_pushvalue(L_, -1); // L_: o "r" {c} {fqn} ... {?} {?}
838 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} {?} nil 830 lua_pushnil(L_); // L_: o "r" {c} {fqn} ... {?} {?} nil
839 lua_rawset(L_, cache); // L_: o "r" {c} {fqn} ... {?} 831 lua_rawset(L_, kCache); // L_: o "r" {c} {fqn} ... {?}
840 STACK_CHECK(L_, 0); 832 STACK_CHECK(L_, 0);
841 return shortest_; 833 return shortest_;
842} 834}
843 835
844// ################################################################################################# 836// #################################################################################################
845 837
846// "type", "name" = lanes.nameof( o) 838// "type", "name" = lanes.nameof(o)
847int luaG_nameof(lua_State* L_) 839int luaG_nameof(lua_State* L_)
848{ 840{
849 int const what{ lua_gettop(L_) }; 841 int const what{ lua_gettop(L_) };
@@ -863,20 +855,21 @@ int luaG_nameof(lua_State* L_)
863 // this slot will contain the shortest name we found when we are done 855 // this slot will contain the shortest name we found when we are done
864 lua_pushnil(L_); // L_: o nil 856 lua_pushnil(L_); // L_: o nil
865 // push a cache that will contain all already visited tables 857 // push a cache that will contain all already visited tables
866 lua_newtable(L_); // o nil {c} 858 lua_newtable(L_); // L_: o nil {c}
867 // push a table whose contents are strings that, when concatenated, produce unique name 859 // push a table whose contents are strings that, when concatenated, produce unique name
868 lua_newtable(L_); // L_: o nil {c} {fqn} 860 lua_newtable(L_); // L_: o nil {c} {fqn}
861 // {fqn}[1] = "_G"
869 lua_pushliteral(L_, "_G"); // L_: o nil {c} {fqn} "_G" 862 lua_pushliteral(L_, "_G"); // L_: o nil {c} {fqn} "_G"
870 lua_rawseti(L_, -2, 1); // L_: o nil {c} {fqn} 863 lua_rawseti(L_, -2, 1); // L_: o nil {c} {fqn}
871 // this is where we start the search 864 // this is where we start the search
872 lua_pushglobaltable(L_); // L_: o nil {c} {fqn} _G 865 lua_pushglobaltable(L_); // L_: o nil {c} {fqn} _G
873 std::ignore = discover_object_name_recur(L_, 6666, 1); 866 std::ignore = DiscoverObjectNameRecur(L_, 6666, 1);
874 if (lua_isnil(L_, 2)) { // try again with registry, just in case... 867 if (lua_isnil(L_, 2)) { // try again with registry, just in case...
875 lua_pop(L_, 1); // L_: o nil {c} {fqn} 868 lua_pop(L_, 1); // L_: o nil {c} {fqn}
876 lua_pushliteral(L_, "_R"); // L_: o nil {c} {fqn} "_R" 869 lua_pushliteral(L_, "_R"); // L_: o nil {c} {fqn} "_R"
877 lua_rawseti(L_, -2, 1); // L_: o nil {c} {fqn} 870 lua_rawseti(L_, -2, 1); // L_: o nil {c} {fqn}
878 lua_pushvalue(L_, LUA_REGISTRYINDEX); // L_: o nil {c} {fqn} _R 871 lua_pushvalue(L_, LUA_REGISTRYINDEX); // L_: o nil {c} {fqn} _R
879 (void) discover_object_name_recur(L_, 6666, 1); 872 std::ignore = DiscoverObjectNameRecur(L_, 6666, 1);
880 } 873 }
881 lua_pop(L_, 3); // L_: o "result" 874 lua_pop(L_, 3); // L_: o "result"
882 STACK_CHECK(L_, 1); 875 STACK_CHECK(L_, 1);
@@ -892,7 +885,7 @@ void InterCopyContext::lookup_native_func() const
892{ 885{
893 // get the name of the function we want to send 886 // get the name of the function we want to send
894 size_t len; 887 size_t len;
895 char const* fqn = find_lookup_name(L1, L1_i, mode, name, &len); 888 char const* const fqn{ find_lookup_name(L1, L1_i, mode, name, &len) };
896 // push the equivalent function in the destination's stack, retrieved from the lookup table 889 // push the equivalent function in the destination's stack, retrieved from the lookup table
897 STACK_CHECK_START_REL(L2, 0); 890 STACK_CHECK_START_REL(L2, 0);
898 STACK_GROW(L2, 3); // up to 3 slots are necessary on error 891 STACK_GROW(L2, 3); // up to 3 slots are necessary on error
@@ -917,12 +910,11 @@ void InterCopyContext::lookup_native_func() const
917 // nil means we don't know how to transfer stuff: user should do something 910 // nil means we don't know how to transfer stuff: user should do something
918 // anything other than function or table should not happen! 911 // anything other than function or table should not happen!
919 if (!lua_isfunction(L2, -1) && !lua_istable(L2, -1)) { 912 if (!lua_isfunction(L2, -1) && !lua_istable(L2, -1)) {
920 char const *from, *to;
921 lua_getglobal(L1, "decoda_name"); // L1: ... f ... decoda_name 913 lua_getglobal(L1, "decoda_name"); // L1: ... f ... decoda_name
922 from = lua_tostring(L1, -1); 914 char const* const from{ lua_tostring(L1, -1) };
923 lua_pop(L1, 1); // L1: ... f ... 915 lua_pop(L1, 1); // L1: ... f ...
924 lua_getglobal(L2, "decoda_name"); // L1: ... f ... L2: {} f decoda_name 916 lua_getglobal(L2, "decoda_name"); // L1: ... f ... L2: {} f decoda_name
925 to = lua_tostring(L2, -1); 917 char const* const to{ lua_tostring(L2, -1) };
926 lua_pop(L2, 1); // L2: {} f 918 lua_pop(L2, 1); // L2: {} f
927 // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error 919 // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error
928 raise_luaL_error( 920 raise_luaL_error(
@@ -985,13 +977,13 @@ static char const* vt_names[] = {
985// we have to do it that way because we can't unbalance the stack between buffer operations 977// we have to do it that way because we can't unbalance the stack between buffer operations
986// namely, this means we can't push a function on top of the stack *after* we initialize the buffer! 978// namely, this means we can't push a function on top of the stack *after* we initialize the buffer!
987// luckily, this also works with earlier Lua versions 979// luckily, this also works with earlier Lua versions
988[[nodiscard]] static int buf_writer(lua_State* L_, void const* b, size_t size, void* ud) 980[[nodiscard]] static int buf_writer(lua_State* L_, void const* b_, size_t size_, void* ud_)
989{ 981{
990 luaL_Buffer* B = (luaL_Buffer*) ud; 982 luaL_Buffer* const B{ static_cast<luaL_Buffer*>(ud_) };
991 if (!B->L) { 983 if (!B->L) {
992 luaL_buffinit(L_, B); 984 luaL_buffinit(L_, B);
993 } 985 }
994 luaL_addlstring(B, (char const*) b, size); 986 luaL_addlstring(B, static_cast<char const*>(b_), size_);
995 return 0; 987 return 0;
996} 988}
997 989
@@ -1118,18 +1110,16 @@ void InterCopyContext::copy_func() const
1118 STACK_CHECK(L1, 0); 1110 STACK_CHECK(L1, 0);
1119 1111
1120 // Set upvalues (originally set to 'nil' by 'lua_load') 1112 // Set upvalues (originally set to 'nil' by 'lua_load')
1121 { 1113 for (int const func_index{ lua_gettop(L2) - n }; n > 0; --n) {
1122 for (int const func_index{ lua_gettop(L2) - n }; n > 0; --n) { 1114 char const* rc{ lua_setupvalue(L2, func_index, n) }; // L2: ... {cache} ... function
1123 char const* rc{ lua_setupvalue(L2, func_index, n) }; // L2: ... {cache} ... function 1115 //
1124 // 1116 // "assigns the value at the top of the stack to the upvalue and returns its name.
1125 // "assigns the value at the top of the stack to the upvalue and returns its name. 1117 // It also pops the value from the stack."
1126 // It also pops the value from the stack."
1127 1118
1128 LUA_ASSERT(L1, rc); // not having enough slots? 1119 LUA_ASSERT(L1, rc); // not having enough slots?
1129 }
1130 // once all upvalues have been set we are left
1131 // with the function at the top of the stack // L2: ... {cache} ... function
1132 } 1120 }
1121 // once all upvalues have been set we are left
1122 // with the function at the top of the stack // L2: ... {cache} ... function
1133 } 1123 }
1134 STACK_CHECK(L1, 0); 1124 STACK_CHECK(L1, 0);
1135} 1125}
@@ -1152,9 +1142,8 @@ void InterCopyContext::copy_cached_func() const
1152 // 1142 //
1153 STACK_CHECK_START_REL(L2, 0); 1143 STACK_CHECK_START_REL(L2, 0);
1154 1144
1155 // We don't need to use the from state ('L') in ID since the life span 1145 // We don't need to use the from state ('L1') in ID since the life span
1156 // is only for the duration of a copy (both states are locked). 1146 // is only for the duration of a copy (both states are locked).
1157 //
1158 1147
1159 // push a light userdata uniquely representing the function 1148 // push a light userdata uniquely representing the function
1160 lua_pushlightuserdata(L2, aspointer); // L2: ... {cache} ... p 1149 lua_pushlightuserdata(L2, aspointer); // L2: ... {cache} ... p
@@ -1294,7 +1283,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1294 1283
1295// ################################################################################################# 1284// #################################################################################################
1296 1285
1297[[nodiscard]] bool InterCopyContext::copyClonable() const 1286[[nodiscard]] bool InterCopyContext::tryCopyClonable() const
1298{ 1287{
1299 SourceIndex const L1_i{ lua_absindex(L1, this->L1_i) }; 1288 SourceIndex const L1_i{ lua_absindex(L1, this->L1_i) };
1300 void* const source{ lua_touserdata(L1, L1_i) }; 1289 void* const source{ lua_touserdata(L1, L1_i) };
@@ -1407,7 +1396,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1407 } 1396 }
1408 1397
1409 // try clonable userdata first 1398 // try clonable userdata first
1410 if (copyClonable()) { 1399 if (tryCopyClonable()) {
1411 STACK_CHECK(L1, 0); 1400 STACK_CHECK(L1, 0);
1412 STACK_CHECK(L2, 1); 1401 STACK_CHECK(L2, 1);
1413 return true; 1402 return true;
@@ -1418,7 +1407,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1418 1407
1419 // Allow only deep userdata entities to be copied across 1408 // Allow only deep userdata entities to be copied across
1420 DEBUGSPEW_CODE(fprintf(stderr, "USERDATA\n")); 1409 DEBUGSPEW_CODE(fprintf(stderr, "USERDATA\n"));
1421 if (copyDeep()) { 1410 if (tryCopyDeep()) {
1422 STACK_CHECK(L1, 0); 1411 STACK_CHECK(L1, 0);
1423 STACK_CHECK(L2, 1); 1412 STACK_CHECK(L2, 1);
1424 return true; 1413 return true;
@@ -1564,7 +1553,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const
1564 * Note: Even metatables need to go through this test; to detect 1553 * Note: Even metatables need to go through this test; to detect
1565 * loops such as those in required module tables (getmetatable(lanes).lanes == lanes) 1554 * loops such as those in required module tables (getmetatable(lanes).lanes == lanes)
1566 */ 1555 */
1567 if (push_cached_table(L2, L2_cache_i, L1, L1_i)) { 1556 if (push_cached_table()) {
1568 LUA_ASSERT(L1, lua_istable(L2, -1)); // from cache 1557 LUA_ASSERT(L1, lua_istable(L2, -1)); // from cache
1569 return true; 1558 return true;
1570 } 1559 }
diff --git a/src/tools.h b/src/tools.h
index b22e4dd..f5fdabc 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -53,10 +53,11 @@ class InterCopyContext
53 // for use in inter_copy_table 53 // for use in inter_copy_table
54 void inter_copy_keyvaluepair() const; 54 void inter_copy_keyvaluepair() const;
55 [[nodiscard]] bool push_cached_metatable() const; 55 [[nodiscard]] bool push_cached_metatable() const;
56 [[nodiscard]] bool push_cached_table() const;
56 57
57 // for use in inter_copy_userdata 58 // for use in inter_copy_userdata
58 [[nodiscard]] bool copyClonable() const; 59 [[nodiscard]] bool tryCopyClonable() const;
59 [[nodiscard]] bool copyDeep() const; 60 [[nodiscard]] bool tryCopyDeep() const;
60 61
61 // copying a single Lua stack item 62 // copying a single Lua stack item
62 [[nodiscard]] bool inter_copy_boolean() const; 63 [[nodiscard]] bool inter_copy_boolean() const;