diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-30 16:13:30 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-30 16:13:30 +0200 |
commit | 261a42021e44e1d3c3cfb3fc6576d3d269241c93 (patch) | |
tree | 61bf8bbf0bb334e18f4a36e5f58badd809e6bade /src | |
parent | 92ea4d16a274b4a7db0206fd74891a555f6501c9 (diff) | |
download | lanes-261a42021e44e1d3c3cfb3fc6576d3d269241c93.tar.gz lanes-261a42021e44e1d3c3cfb3fc6576d3d269241c93.tar.bz2 lanes-261a42021e44e1d3c3cfb3fc6576d3d269241c93.zip |
Progressively applying the coding rules
Diffstat (limited to 'src')
-rw-r--r-- | src/deep.cpp | 64 | ||||
-rw-r--r-- | src/deep.h | 1 | ||||
-rw-r--r-- | src/tools.cpp | 171 | ||||
-rw-r--r-- | src/tools.h | 5 |
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 | */ |
69 | static void set_deep_lookup(lua_State* L_) | 69 | void 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 | 92 | static void LookupDeep(lua_State* L_) |
88 | * deep lookup value (factory/metatable/nil). | ||
89 | */ | ||
90 | static 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 | } |
@@ -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 | */ |
248 | static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, int _ctx_base, int _depth) | 248 | static 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_) | |||
486 | static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | 486 | static 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) |
847 | int luaG_nameof(lua_State* L_) | 839 | int 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; |