diff options
Diffstat (limited to 'src/intercopycontext.cpp')
-rw-r--r-- | src/intercopycontext.cpp | 82 |
1 files changed, 42 insertions, 40 deletions
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index e29132d..d21995c 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp | |||
@@ -100,7 +100,7 @@ THE SOFTWARE. | |||
100 | lua_pushvalue(L1, L1_i); // L1: ... v ... {} v | 100 | lua_pushvalue(L1, L1_i); // L1: ... v ... {} v |
101 | lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" | 101 | lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" |
102 | } | 102 | } |
103 | std::string_view _fqn{ luaG_tostring(L1, -1) }; | 103 | std::string_view _fqn{ luaG_tostring(L1, kIdxTop) }; |
104 | DEBUGSPEW_CODE(DebugSpew(U) << "function [C] " << _fqn << std::endl); | 104 | DEBUGSPEW_CODE(DebugSpew(U) << "function [C] " << _fqn << std::endl); |
105 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database | 105 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database |
106 | lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... | 106 | lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... |
@@ -108,11 +108,12 @@ THE SOFTWARE. | |||
108 | if (_fqn.empty() && !lua_istable(L1, L1_i)) { // raise an error if we try to send an unknown function (but not for tables) | 108 | if (_fqn.empty() && !lua_istable(L1, L1_i)) { // raise an error if we try to send an unknown function (but not for tables) |
109 | // try to discover the name of the function we want to send | 109 | // try to discover the name of the function we want to send |
110 | kLaneNameRegKey.pushValue(L1); // L1: ... v ... lane_name | 110 | kLaneNameRegKey.pushValue(L1); // L1: ... v ... lane_name |
111 | std::string_view const _from{ luaG_tostring(L1, -1) }; | 111 | std::string_view const _from{ luaG_tostring(L1, kIdxTop) }; |
112 | lua_pushcfunction(L1, LG_nameof); // L1: ... v ... lane_name LG_nameof | 112 | lua_pushcfunction(L1, LG_nameof); // L1: ... v ... lane_name LG_nameof |
113 | lua_pushvalue(L1, L1_i); // L1: ... v ... lane_name LG_nameof t | 113 | lua_pushvalue(L1, L1_i); // L1: ... v ... lane_name LG_nameof t |
114 | lua_call(L1, 1, 2); // L1: ... v ... lane_name "type" "name"|nil | 114 | lua_call(L1, 1, 2); // L1: ... v ... lane_name "type" "name"|nil |
115 | std::string_view const _typewhat{ (luaG_type(L1, -2) == LuaType::STRING) ? luaG_tostring(L1, -2) : luaG_typename(L1, -2) }; | 115 | StackIndex const _indexTypeWhat{ -2 }; |
116 | std::string_view const _typewhat{ (luaG_type(L1, _indexTypeWhat) == LuaType::STRING) ? luaG_tostring(L1, _indexTypeWhat) : luaG_typename(L1, _indexTypeWhat) }; | ||
116 | // second return value can be nil if the table was not found | 117 | // second return value can be nil if the table was not found |
117 | // probable reason: the function was removed from the source Lua state before Lanes was required. | 118 | // probable reason: the function was removed from the source Lua state before Lanes was required. |
118 | std::string_view _what, _gotchaA, _gotchaB; | 119 | std::string_view _what, _gotchaA, _gotchaB; |
@@ -123,7 +124,8 @@ THE SOFTWARE. | |||
123 | } else { | 124 | } else { |
124 | _gotchaA = ""; | 125 | _gotchaA = ""; |
125 | _gotchaB = ""; | 126 | _gotchaB = ""; |
126 | _what = (luaG_type(L1, -1) == LuaType::STRING) ? luaG_tostring(L1, -1) : luaG_typename(L1, -1); | 127 | StackIndex const _indexWhat{ kIdxTop }; |
128 | _what = (luaG_type(L1, _indexWhat) == LuaType::STRING) ? luaG_tostring(L1, _indexWhat) : luaG_typename(L1, _indexWhat); | ||
127 | } | 129 | } |
128 | raise_luaL_error(L1, "%s%s '%s' not found in %s origin transfer database.%s", _typewhat.data(), _gotchaA.data(), _what.data(), _from.empty() ? "main" : _from.data(), _gotchaB.data()); | 130 | raise_luaL_error(L1, "%s%s '%s' not found in %s origin transfer database.%s", _typewhat.data(), _gotchaA.data(), _what.data(), _from.empty() ? "main" : _from.data(), _gotchaB.data()); |
129 | } | 131 | } |
@@ -139,15 +141,15 @@ THE SOFTWARE. | |||
139 | static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | 141 | static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; |
140 | 142 | ||
141 | // get a unique ID for metatable at [i]. | 143 | // get a unique ID for metatable at [i]. |
142 | [[nodiscard]] static lua_Integer get_mt_id(Universe* U_, lua_State* L_, int idx_) | 144 | [[nodiscard]] static lua_Integer get_mt_id(Universe* U_, lua_State* L_, StackIndex const idx_) |
143 | { | 145 | { |
144 | idx_ = luaG_absindex(L_, idx_); | 146 | StackIndex const _absidx{ luaG_absindex(L_, idx_) }; |
145 | 147 | ||
146 | STACK_GROW(L_, 3); | 148 | STACK_GROW(L_, 3); |
147 | 149 | ||
148 | STACK_CHECK_START_REL(L_, 0); | 150 | STACK_CHECK_START_REL(L_, 0); |
149 | std::ignore = kMtIdRegKey.getSubTable(L_, 0, 0); // L_: ... _R[kMtIdRegKey] | 151 | std::ignore = kMtIdRegKey.getSubTable(L_, 0, 0); // L_: ... _R[kMtIdRegKey] |
150 | lua_pushvalue(L_, idx_); // L_: ... _R[kMtIdRegKey] {mt} | 152 | lua_pushvalue(L_, _absidx); // L_: ... _R[kMtIdRegKey] {mt} |
151 | lua_rawget(L_, -2); // L_: ... _R[kMtIdRegKey] mtk? | 153 | lua_rawget(L_, -2); // L_: ... _R[kMtIdRegKey] mtk? |
152 | 154 | ||
153 | lua_Integer _id{ lua_tointeger(L_, -1) }; // 0 for nil | 155 | lua_Integer _id{ lua_tointeger(L_, -1) }; // 0 for nil |
@@ -158,12 +160,12 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; | |||
158 | _id = U_->nextMetatableId.fetch_add(1, std::memory_order_relaxed); | 160 | _id = U_->nextMetatableId.fetch_add(1, std::memory_order_relaxed); |
159 | 161 | ||
160 | // Create two-way references: id_uint <-> table | 162 | // Create two-way references: id_uint <-> table |
161 | lua_pushvalue(L_, idx_); // L_: ... _R[kMtIdRegKey] {mt} | 163 | lua_pushvalue(L_, _absidx); // L_: ... _R[kMtIdRegKey] {mt} |
162 | lua_pushinteger(L_, _id); // L_: ... _R[kMtIdRegKey] {mt} id | 164 | lua_pushinteger(L_, _id); // L_: ... _R[kMtIdRegKey] {mt} id |
163 | lua_rawset(L_, -3); // L_: ... _R[kMtIdRegKey] | 165 | lua_rawset(L_, -3); // L_: ... _R[kMtIdRegKey] |
164 | 166 | ||
165 | lua_pushinteger(L_, _id); // L_: ... _R[kMtIdRegKey] id | 167 | lua_pushinteger(L_, _id); // L_: ... _R[kMtIdRegKey] id |
166 | lua_pushvalue(L_, idx_); // L_: ... _R[kMtIdRegKey] id {mt} | 168 | lua_pushvalue(L_, _absidx); // L_: ... _R[kMtIdRegKey] id {mt} |
167 | lua_rawset(L_, -3); // L_: ... _R[kMtIdRegKey] | 169 | lua_rawset(L_, -3); // L_: ... _R[kMtIdRegKey] |
168 | } | 170 | } |
169 | lua_pop(L_, 1); // L_: ... | 171 | lua_pop(L_, 1); // L_: ... |
@@ -223,7 +225,7 @@ void InterCopyContext::copyFunction() const | |||
223 | } | 225 | } |
224 | 226 | ||
225 | { | 227 | { |
226 | std::string_view const _bytecode{ luaG_tostring(L1, -1) }; // L1: ... b | 228 | std::string_view const _bytecode{ luaG_tostring(L1, kIdxTop) }; // L1: ... b |
227 | LUA_ASSERT(L1, !_bytecode.empty()); | 229 | LUA_ASSERT(L1, !_bytecode.empty()); |
228 | STACK_GROW(L2, 2); | 230 | STACK_GROW(L2, 2); |
229 | // Note: Line numbers seem to be taken precisely from the | 231 | // Note: Line numbers seem to be taken precisely from the |
@@ -282,7 +284,7 @@ void InterCopyContext::copyFunction() const | |||
282 | STACK_CHECK(L1, 0); | 284 | STACK_CHECK(L1, 0); |
283 | 285 | ||
284 | // Set upvalues (originally set to 'nil' by 'lua_load') | 286 | // Set upvalues (originally set to 'nil' by 'lua_load') |
285 | for (int const _func_index{ lua_gettop(L2) - _n }; _n > 0; --_n) { | 287 | for (StackIndex const _func_index{ lua_gettop(L2) - _n }; _n > 0; --_n) { |
286 | // assign upvalue, popping it from the stack | 288 | // assign upvalue, popping it from the stack |
287 | [[maybe_unused]] std::string_view const _upname{ lua_setupvalue(L2, _func_index, _n) };// L2: ... {cache} ... function | 289 | [[maybe_unused]] std::string_view const _upname{ lua_setupvalue(L2, _func_index, _n) };// L2: ... {cache} ... function |
288 | LUA_ASSERT(L1, !_upname.empty()); // not having enough slots? | 290 | LUA_ASSERT(L1, !_upname.empty()); // not having enough slots? |
@@ -325,10 +327,10 @@ void InterCopyContext::lookupNativeFunction() const | |||
325 | // anything other than function or table should not happen! | 327 | // anything other than function or table should not happen! |
326 | if (!lua_isfunction(L2, -1) && !lua_istable(L2, -1)) { | 328 | if (!lua_isfunction(L2, -1) && !lua_istable(L2, -1)) { |
327 | kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name | 329 | kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name |
328 | std::string_view const _from{ luaG_tostring(L1, -1) }; | 330 | std::string_view const _from{ luaG_tostring(L1, kIdxTop) }; |
329 | lua_pop(L1, 1); // L1: ... f ... | 331 | lua_pop(L1, 1); // L1: ... f ... |
330 | kLaneNameRegKey.pushValue(L2); // L1: ... f ... L2: {} f lane_name | 332 | kLaneNameRegKey.pushValue(L2); // L1: ... f ... L2: {} f lane_name |
331 | std::string_view const _to{ luaG_tostring(L2, -1) }; | 333 | std::string_view const _to{ luaG_tostring(L2, kIdxTop) }; |
332 | lua_pop(L2, 1); // L2: {} f | 334 | lua_pop(L2, 1); // L2: {} f |
333 | raise_luaL_error( | 335 | raise_luaL_error( |
334 | getErrL(), | 336 | getErrL(), |
@@ -433,17 +435,17 @@ void InterCopyContext::copyCachedFunction() const | |||
433 | return false; | 435 | return false; |
434 | } else if (!lua_istable(L2, -1)) { // this can happen if someone decides to replace same already registered item (for a example a standard lib function) with a table | 436 | } else if (!lua_istable(L2, -1)) { // this can happen if someone decides to replace same already registered item (for a example a standard lib function) with a table |
435 | kLaneNameRegKey.pushValue(L1); // L1: ... t ... lane_name | 437 | kLaneNameRegKey.pushValue(L1); // L1: ... t ... lane_name |
436 | std::string_view const _from{ luaG_tostring(L1, -1) }; | 438 | std::string_view const _from{ luaG_tostring(L1, kIdxTop) }; |
437 | lua_pop(L1, 1); // L1: ... t ... | 439 | lua_pop(L1, 1); // L1: ... t ... |
438 | kLaneNameRegKey.pushValue(L2); // L1: ... t ... L2: {} t lane_name | 440 | kLaneNameRegKey.pushValue(L2); // L1: ... t ... L2: {} t lane_name |
439 | std::string_view const _to{ luaG_tostring(L2, -1) }; | 441 | std::string_view const _to{ luaG_tostring(L2, kIdxTop) }; |
440 | lua_pop(L2, 1); // L1: ... t ... L2: {} t | 442 | lua_pop(L2, 1); // L1: ... t ... L2: {} t |
441 | raise_luaL_error( | 443 | raise_luaL_error( |
442 | getErrL(), | 444 | getErrL(), |
443 | "%s: source table '%s' found as %s in %s destination transfer database.", | 445 | "%s: source table '%s' found as %s in %s destination transfer database.", |
444 | _from.empty() ? "main" : _from.data(), | 446 | _from.empty() ? "main" : _from.data(), |
445 | _fqn.data(), | 447 | _fqn.data(), |
446 | luaG_typename(L2, -1).data(), | 448 | luaG_typename(L2, kIdxTop).data(), |
447 | _to.empty() ? "main" : _to.data()); | 449 | _to.empty() ? "main" : _to.data()); |
448 | } | 450 | } |
449 | lua_remove(L2, -2); // L1: ... t ... L2: t | 451 | lua_remove(L2, -2); // L1: ... t ... L2: t |
@@ -490,13 +492,13 @@ void InterCopyContext::interCopyKeyValuePair() const | |||
490 | _valPath = (char*) alloca(name.size() + 32 + 3); // +3 for [] and terminating 0 | 492 | _valPath = (char*) alloca(name.size() + 32 + 3); // +3 for [] and terminating 0 |
491 | sprintf(_valPath, "%s[" LUA_NUMBER_FMT "]", name.data(), key); | 493 | sprintf(_valPath, "%s[" LUA_NUMBER_FMT "]", name.data(), key); |
492 | } else if (luaG_type(L1, _key_i) == LuaType::LIGHTUSERDATA) { | 494 | } else if (luaG_type(L1, _key_i) == LuaType::LIGHTUSERDATA) { |
493 | void* const key{ lua_touserdata(L1, _key_i) }; | 495 | void* const _key{ lua_touserdata(L1, _key_i) }; |
494 | _valPath = (char*) alloca(name.size() + 16 + 5); // +5 for [U:] and terminating 0 | 496 | _valPath = (char*) alloca(name.size() + 16 + 5); // +5 for [U:] and terminating 0 |
495 | sprintf(_valPath, "%s[U:%p]", name.data(), key); | 497 | sprintf(_valPath, "%s[U:%p]", name.data(), _key); |
496 | } else if (luaG_type(L1, _key_i) == LuaType::BOOLEAN) { | 498 | } else if (luaG_type(L1, _key_i) == LuaType::BOOLEAN) { |
497 | int const key{ lua_toboolean(L1, _key_i) }; | 499 | int const _key{ lua_toboolean(L1, _key_i) }; |
498 | _valPath = (char*) alloca(name.size() + 8); // +8 for [], 'false' and terminating 0 | 500 | _valPath = (char*) alloca(name.size() + 8); // +8 for [], 'false' and terminating 0 |
499 | sprintf(_valPath, "%s[%s]", name.data(), key ? "true" : "false"); | 501 | sprintf(_valPath, "%s[%s]", name.data(), _key ? "true" : "false"); |
500 | } | 502 | } |
501 | } | 503 | } |
502 | 504 | ||
@@ -533,7 +535,7 @@ LuaType InterCopyContext::processConversion() const | |||
533 | } | 535 | } |
534 | // we have a metatable // L1: ... mt | 536 | // we have a metatable // L1: ... mt |
535 | static constexpr std::string_view kConvertField{ "__lanesconvert" }; | 537 | static constexpr std::string_view kConvertField{ "__lanesconvert" }; |
536 | LuaType const _converterType{ luaG_getfield(L1, -1, kConvertField) }; // L1: ... mt kConvertField | 538 | LuaType const _converterType{ luaG_getfield(L1, kIdxTop, kConvertField) }; // L1: ... mt kConvertField |
537 | switch (_converterType) { | 539 | switch (_converterType) { |
538 | case LuaType::NIL: | 540 | case LuaType::NIL: |
539 | // no __lanesconvert, nothing to do | 541 | // no __lanesconvert, nothing to do |
@@ -541,7 +543,7 @@ LuaType InterCopyContext::processConversion() const | |||
541 | break; | 543 | break; |
542 | 544 | ||
543 | case LuaType::LIGHTUSERDATA: | 545 | case LuaType::LIGHTUSERDATA: |
544 | if (kNilSentinel.equals(L1, -1)) { | 546 | if (kNilSentinel.equals(L1, kIdxTop)) { |
545 | DEBUGSPEW_CODE(DebugSpew(U) << "converted " << luaG_typename(L1, _val_type) << " to nil" << std::endl); | 547 | DEBUGSPEW_CODE(DebugSpew(U) << "converted " << luaG_typename(L1, _val_type) << " to nil" << std::endl); |
546 | lua_replace(L1, L1_i); // L1: ... mt | 548 | lua_replace(L1, L1_i); // L1: ... mt |
547 | lua_pop(L1, 1); // L1: ... | 549 | lua_pop(L1, 1); // L1: ... |
@@ -553,7 +555,7 @@ LuaType InterCopyContext::processConversion() const | |||
553 | 555 | ||
554 | case LuaType::STRING: | 556 | case LuaType::STRING: |
555 | // kConvertField == "decay" -> replace source value with it's pointer | 557 | // kConvertField == "decay" -> replace source value with it's pointer |
556 | if (std::string_view const _mode{ luaG_tostring(L1, -1) }; _mode == "decay") { | 558 | if (std::string_view const _mode{ luaG_tostring(L1, kIdxTop) }; _mode == "decay") { |
557 | lua_pop(L1, 1); // L1: ... mt | 559 | lua_pop(L1, 1); // L1: ... mt |
558 | lua_pushlightuserdata(L1, const_cast<void*>(lua_topointer(L1, L1_i))); // L1: ... mt decayed | 560 | lua_pushlightuserdata(L1, const_cast<void*>(lua_topointer(L1, L1_i))); // L1: ... mt decayed |
559 | lua_replace(L1, L1_i); // L1: ... mt | 561 | lua_replace(L1, L1_i); // L1: ... mt |
@@ -592,7 +594,7 @@ LuaType InterCopyContext::processConversion() const | |||
592 | } | 594 | } |
593 | STACK_CHECK(L1, 1); | 595 | STACK_CHECK(L1, 1); |
594 | 596 | ||
595 | lua_Integer const _mt_id{ get_mt_id(U, L1, -1) }; // Unique id for the metatable | 597 | lua_Integer const _mt_id{ get_mt_id(U, L1, kIdxTop) }; // Unique id for the metatable |
596 | 598 | ||
597 | STACK_CHECK_START_REL(L2, 0); | 599 | STACK_CHECK_START_REL(L2, 0); |
598 | STACK_GROW(L2, 4); | 600 | STACK_GROW(L2, 4); |
@@ -693,7 +695,7 @@ LuaType InterCopyContext::processConversion() const | |||
693 | } | 695 | } |
694 | 696 | ||
695 | // no __lanesclone? -> not clonable | 697 | // no __lanesclone? -> not clonable |
696 | if (luaG_getfield(L1, -1, "__lanesclone") == LuaType::NIL) { // L1: ... mt nil | 698 | if (luaG_getfield(L1, kIdxTop, "__lanesclone") == LuaType::NIL) { // L1: ... mt nil |
697 | lua_pop(L1, 2); // L1: ... | 699 | lua_pop(L1, 2); // L1: ... |
698 | STACK_CHECK(L1, 0); | 700 | STACK_CHECK(L1, 0); |
699 | return false; | 701 | return false; |
@@ -703,7 +705,7 @@ LuaType InterCopyContext::processConversion() const | |||
703 | 705 | ||
704 | // we need to copy over the uservalues of the userdata as well | 706 | // we need to copy over the uservalues of the userdata as well |
705 | { | 707 | { |
706 | int const _mt{ luaG_absindex(L1, -2) }; // L1: ... mt __lanesclone | 708 | StackIndex const _mt{ luaG_absindex(L1, StackIndex{ -2 }) }; // L1: ... mt __lanesclone |
707 | size_t const userdata_size{ lua_rawlen(L1, _L1_i) }; | 709 | size_t const userdata_size{ lua_rawlen(L1, _L1_i) }; |
708 | // extract all the uservalues, but don't transfer them yet | 710 | // extract all the uservalues, but don't transfer them yet |
709 | int const _nuv{ luaG_getalluservalues(L1, _L1_i) }; // L1: ... mt __lanesclone [uv]* | 711 | int const _nuv{ luaG_getalluservalues(L1, _L1_i) }; // L1: ... mt __lanesclone [uv]* |
@@ -738,13 +740,13 @@ LuaType InterCopyContext::processConversion() const | |||
738 | // assign uservalues | 740 | // assign uservalues |
739 | int _uvi{ _nuv }; | 741 | int _uvi{ _nuv }; |
740 | while (_uvi > 0) { | 742 | while (_uvi > 0) { |
741 | _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; | 743 | _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop) }; |
742 | if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... u uv | 744 | if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... u uv |
743 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); | 745 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); |
744 | } | 746 | } |
745 | lua_pop(L1, 1); // L1: ... mt __lanesclone [uv]* | 747 | lua_pop(L1, 1); // L1: ... mt __lanesclone [uv]* |
746 | // this pops the value from the stack | 748 | // this pops the value from the stack |
747 | lua_setiuservalue(L2, -2, _uvi); // L2: ... u | 749 | lua_setiuservalue(L2, StackIndex{ -2 }, _uvi); // L2: ... u |
748 | --_uvi; | 750 | --_uvi; |
749 | } | 751 | } |
750 | // when we are done, all uservalues are popped from the source stack, and we want only the single transferred value in the destination | 752 | // when we are done, all uservalues are popped from the source stack, and we want only the single transferred value in the destination |
@@ -792,11 +794,11 @@ LuaType InterCopyContext::processConversion() const | |||
792 | // transfer all uservalues of the source in the destination | 794 | // transfer all uservalues of the source in the destination |
793 | { | 795 | { |
794 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, name }; | 796 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, name }; |
795 | int const _clone_i{ lua_gettop(L2) }; | 797 | StackIndex const _clone_i{ lua_gettop(L2) }; |
796 | STACK_GROW(L2, _nuv); | 798 | STACK_GROW(L2, _nuv); |
797 | int _uvi{ _nuv }; | 799 | int _uvi{ _nuv }; |
798 | while (_uvi) { | 800 | while (_uvi) { |
799 | _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; | 801 | _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop) }; |
800 | if (_c.interCopyOne() != InterCopyResult::Success) { // L1: ... deep ... [uv]* L2: deep uv | 802 | if (_c.interCopyOne() != InterCopyResult::Success) { // L1: ... deep ... [uv]* L2: deep uv |
801 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); | 803 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); |
802 | } | 804 | } |
@@ -862,7 +864,7 @@ LuaType InterCopyContext::processConversion() const | |||
862 | _source = lua_touserdata(L1, -1); | 864 | _source = lua_touserdata(L1, -1); |
863 | void* _clone{ nullptr }; | 865 | void* _clone{ nullptr }; |
864 | // get the number of bytes to allocate for the clone | 866 | // get the number of bytes to allocate for the clone |
865 | size_t const userdata_size{ lua_rawlen(L1, -1) }; | 867 | size_t const userdata_size{ lua_rawlen(L1, kIdxTop) }; |
866 | { | 868 | { |
867 | // extract uservalues (don't transfer them yet) | 869 | // extract uservalues (don't transfer them yet) |
868 | int const _nuv{ luaG_getalluservalues(L1, source_i) }; // L1: ... u [uv]* | 870 | int const _nuv{ luaG_getalluservalues(L1, source_i) }; // L1: ... u [uv]* |
@@ -880,13 +882,13 @@ LuaType InterCopyContext::processConversion() const | |||
880 | InterCopyContext _c{ *this }; | 882 | InterCopyContext _c{ *this }; |
881 | int _uvi{ _nuv }; | 883 | int _uvi{ _nuv }; |
882 | while (_uvi > 0) { | 884 | while (_uvi > 0) { |
883 | _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; | 885 | _c.L1_i = SourceIndex{ luaG_absindex(L1, kIdxTop) }; |
884 | if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... mt u uv | 886 | if (_c.interCopyOne() != InterCopyResult::Success) { // L2: ... mt u uv |
885 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); | 887 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); |
886 | } | 888 | } |
887 | lua_pop(L1, 1); // L1: ... u [uv]* | 889 | lua_pop(L1, 1); // L1: ... u [uv]* |
888 | // this pops the value from the stack | 890 | // this pops the value from the stack |
889 | lua_setiuservalue(L2, -2, _uvi); // L2: ... mt u | 891 | lua_setiuservalue(L2, StackIndex{ -2 }, _uvi); // L2: ... mt u |
890 | --_uvi; | 892 | --_uvi; |
891 | } | 893 | } |
892 | // when we are done, all uservalues are popped from the stack, we can pop the source as well | 894 | // when we are done, all uservalues are popped from the stack, we can pop the source as well |
@@ -897,7 +899,7 @@ LuaType InterCopyContext::processConversion() const | |||
897 | // perform the custom cloning part | 899 | // perform the custom cloning part |
898 | lua_insert(L2, -2); // L2: ... u mt | 900 | lua_insert(L2, -2); // L2: ... u mt |
899 | // __lanesclone should always exist because we wouldn't be restoring data from a userdata_clone_sentinel closure to begin with | 901 | // __lanesclone should always exist because we wouldn't be restoring data from a userdata_clone_sentinel closure to begin with |
900 | LuaType const _funcType{ luaG_getfield(L2, -1, "__lanesclone") }; // L2: ... u mt __lanesclone | 902 | LuaType const _funcType{ luaG_getfield(L2, kIdxTop, "__lanesclone") }; // L2: ... u mt __lanesclone |
901 | if (_funcType != LuaType::FUNCTION) { | 903 | if (_funcType != LuaType::FUNCTION) { |
902 | raise_luaL_error(getErrL(), "INTERNAL ERROR: __lanesclone is a %s, not a function", luaG_typename(L2, _funcType).data()); | 904 | raise_luaL_error(getErrL(), "INTERNAL ERROR: __lanesclone is a %s, not a function", luaG_typename(L2, _funcType).data()); |
903 | } | 905 | } |
@@ -1191,7 +1193,7 @@ namespace { | |||
1191 | { | 1193 | { |
1192 | private: | 1194 | private: |
1193 | lua_State* const L2; | 1195 | lua_State* const L2; |
1194 | int const top_L2; | 1196 | StackIndex const top_L2; |
1195 | DEBUGSPEW_CODE(DebugSpewIndentScope scope); | 1197 | DEBUGSPEW_CODE(DebugSpewIndentScope scope); |
1196 | 1198 | ||
1197 | public: | 1199 | public: |
@@ -1246,7 +1248,7 @@ namespace { | |||
1246 | STACK_CHECK(L1, 0); | 1248 | STACK_CHECK(L1, 0); |
1247 | } | 1249 | } |
1248 | if (_result == InterCopyResult::Success) { | 1250 | if (_result == InterCopyResult::Success) { |
1249 | luaG_setfield(L2, -2, _entry); // set package[entry] | 1251 | luaG_setfield(L2, StackIndex{ -2 }, _entry); // set package[entry] |
1250 | } else { | 1252 | } else { |
1251 | std::string_view const _msg{ luaG_pushstring(L1, "failed to copy package.%s", _entry.data()) }; | 1253 | std::string_view const _msg{ luaG_pushstring(L1, "failed to copy package.%s", _entry.data()) }; |
1252 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later | 1254 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later |
@@ -1273,7 +1275,7 @@ namespace { | |||
1273 | DEBUGSPEW_CODE(DebugSpew(U) << "InterCopyContext::interCopy()" << std::endl); | 1275 | DEBUGSPEW_CODE(DebugSpew(U) << "InterCopyContext::interCopy()" << std::endl); |
1274 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ U }); | 1276 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ U }); |
1275 | 1277 | ||
1276 | int const _top_L1{ lua_gettop(L1) }; | 1278 | StackIndex const _top_L1{ lua_gettop(L1) }; |
1277 | int const _available{ (L1_i != 0) ? (_top_L1 - L1_i + 1) : _top_L1 }; | 1279 | int const _available{ (L1_i != 0) ? (_top_L1 - L1_i + 1) : _top_L1 }; |
1278 | if (n_ > _available) { | 1280 | if (n_ > _available) { |
1279 | // requesting to copy more than is available? | 1281 | // requesting to copy more than is available? |
@@ -1289,17 +1291,17 @@ namespace { | |||
1289 | * function entries, avoiding the same entries to be passed on as multiple | 1291 | * function entries, avoiding the same entries to be passed on as multiple |
1290 | * copies. ESSENTIAL i.e. for handling upvalue tables in the right manner! | 1292 | * copies. ESSENTIAL i.e. for handling upvalue tables in the right manner! |
1291 | */ | 1293 | */ |
1292 | int const _top_L2{ lua_gettop(L2) }; // L2: ... | 1294 | StackIndex const _top_L2{ lua_gettop(L2) }; // L2: ... |
1293 | lua_newtable(L2); // L2: ... cache | 1295 | lua_newtable(L2); // L2: ... cache |
1294 | 1296 | ||
1295 | InterCopyContext _c{ U, L2, L1, CacheIndex{ _top_L2 + 1 }, {}, VT::NORMAL, mode, "?" }; | 1297 | InterCopyContext _c{ U, L2, L1, CacheIndex{ _top_L2 + 1 }, {}, VT::NORMAL, mode, "?" }; |
1296 | InterCopyResult _copyok{ InterCopyResult::Success }; | 1298 | InterCopyResult _copyok{ InterCopyResult::Success }; |
1297 | STACK_CHECK_START_REL(L1, 0); | 1299 | STACK_CHECK_START_REL(L1, 0); |
1298 | // if L1_i is specified, start here, else take the _n items off the top of the stack | 1300 | // if L1_i is specified, start here, else take the _n items off the top of the stack |
1299 | for (int _i{ L1_i != 0 ? L1_i : (_top_L1 - n_ + 1) }, _j{ 1 }; _j <= n_; ++_i, ++_j) { | 1301 | for (StackIndex _i{ L1_i != 0 ? L1_i : (_top_L1 - n_ + 1) }, _j{ 1 }; _j <= n_; ++_i, ++_j) { |
1300 | char _tmpBuf[16]; | 1302 | char _tmpBuf[16]; |
1301 | if (U->verboseErrors) { | 1303 | if (U->verboseErrors) { |
1302 | sprintf(_tmpBuf, "arg_%d", _j); | 1304 | sprintf(_tmpBuf, "arg_%d", _j.operator int()); |
1303 | _c.name = _tmpBuf; | 1305 | _c.name = _tmpBuf; |
1304 | } | 1306 | } |
1305 | _c.L1_i = SourceIndex{ _i }; | 1307 | _c.L1_i = SourceIndex{ _i }; |