diff options
Diffstat (limited to '')
-rw-r--r-- | src/intercopycontext.cpp | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index f00b268..8142b6a 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_tostringview(L1, -1) }; | 103 | std::string_view _fqn{ luaG_tostring(L1, -1) }; |
104 | DEBUGSPEW_CODE(DebugSpew(Universe::Get(L1)) << "function [C] " << _fqn << std::endl); | 104 | DEBUGSPEW_CODE(DebugSpew(Universe::Get(L1)) << "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 ... |
@@ -224,7 +224,7 @@ void InterCopyContext::copy_func() const | |||
224 | } | 224 | } |
225 | 225 | ||
226 | { | 226 | { |
227 | std::string_view const _bytecode{ luaG_tostringview(L1, -1) }; // L1: ... b | 227 | std::string_view const _bytecode{ luaG_tostring(L1, -1) }; // L1: ... b |
228 | LUA_ASSERT(L1, !_bytecode.empty()); | 228 | LUA_ASSERT(L1, !_bytecode.empty()); |
229 | STACK_GROW(L2, 2); | 229 | STACK_GROW(L2, 2); |
230 | // Note: Line numbers seem to be taken precisely from the | 230 | // Note: Line numbers seem to be taken precisely from the |
@@ -313,7 +313,7 @@ void InterCopyContext::lookup_native_func() const | |||
313 | 313 | ||
314 | case LookupMode::ToKeeper: | 314 | case LookupMode::ToKeeper: |
315 | // push a sentinel closure that holds the lookup name as upvalue | 315 | // push a sentinel closure that holds the lookup name as upvalue |
316 | std::ignore = luaG_pushstringview(L2, _fqn); // L1: ... f ... L2: "f.q.n" | 316 | std::ignore = luaG_pushstring(L2, _fqn); // L1: ... f ... L2: "f.q.n" |
317 | lua_pushcclosure(L2, func_lookup_sentinel, 1); // L1: ... f ... L2: f | 317 | lua_pushcclosure(L2, func_lookup_sentinel, 1); // L1: ... f ... L2: f |
318 | break; | 318 | break; |
319 | 319 | ||
@@ -322,7 +322,7 @@ void InterCopyContext::lookup_native_func() const | |||
322 | kLookupRegKey.pushValue(L2); // L1: ... f ... L2: {} | 322 | kLookupRegKey.pushValue(L2); // L1: ... f ... L2: {} |
323 | STACK_CHECK(L2, 1); | 323 | STACK_CHECK(L2, 1); |
324 | LUA_ASSERT(L1, lua_istable(L2, -1)); | 324 | LUA_ASSERT(L1, lua_istable(L2, -1)); |
325 | std::ignore = luaG_pushstringview(L2, _fqn); // L1: ... f ... L2: {} "f.q.n" | 325 | std::ignore = luaG_pushstring(L2, _fqn); // L1: ... f ... L2: {} "f.q.n" |
326 | lua_rawget(L2, -2); // L1: ... f ... L2: {} f | 326 | lua_rawget(L2, -2); // L1: ... f ... L2: {} f |
327 | // nil means we don't know how to transfer stuff: user should do something | 327 | // nil means we don't know how to transfer stuff: user should do something |
328 | // anything other than function or table should not happen! | 328 | // anything other than function or table should not happen! |
@@ -388,7 +388,7 @@ void InterCopyContext::copy_cached_func() const | |||
388 | // push a light userdata uniquely representing the function | 388 | // push a light userdata uniquely representing the function |
389 | lua_pushlightuserdata(L2, _aspointer); // L2: ... {cache} ... p | 389 | lua_pushlightuserdata(L2, _aspointer); // L2: ... {cache} ... p |
390 | 390 | ||
391 | //DEBUGSPEW_CODE(DebugSpew(U) << "<< ID: " << luaG_tostringview(L2, -1) << " >>" << std::endl); | 391 | //DEBUGSPEW_CODE(DebugSpew(U) << "<< ID: " << luaG_tostring(L2, -1) << " >>" << std::endl); |
392 | 392 | ||
393 | lua_pushvalue(L2, -1); // L2: ... {cache} ... p p | 393 | lua_pushvalue(L2, -1); // L2: ... {cache} ... p p |
394 | lua_rawget(L2, L2_cache_i); // L2: ... {cache} ... p function|nil|true | 394 | lua_rawget(L2, L2_cache_i); // L2: ... {cache} ... p function|nil|true |
@@ -433,7 +433,7 @@ void InterCopyContext::copy_cached_func() const | |||
433 | 433 | ||
434 | case LookupMode::ToKeeper: | 434 | case LookupMode::ToKeeper: |
435 | // push a sentinel closure that holds the lookup name as upvalue | 435 | // push a sentinel closure that holds the lookup name as upvalue |
436 | std::ignore = luaG_pushstringview(L2, _fqn); // L1: ... t ... L2: "f.q.n" | 436 | std::ignore = luaG_pushstring(L2, _fqn); // L1: ... t ... L2: "f.q.n" |
437 | lua_pushcclosure(L2, table_lookup_sentinel, 1); // L1: ... t ... L2: f | 437 | lua_pushcclosure(L2, table_lookup_sentinel, 1); // L1: ... t ... L2: f |
438 | break; | 438 | break; |
439 | 439 | ||
@@ -442,7 +442,7 @@ void InterCopyContext::copy_cached_func() const | |||
442 | kLookupRegKey.pushValue(L2); // L1: ... t ... L2: {} | 442 | kLookupRegKey.pushValue(L2); // L1: ... t ... L2: {} |
443 | STACK_CHECK(L2, 1); | 443 | STACK_CHECK(L2, 1); |
444 | LUA_ASSERT(L1, lua_istable(L2, -1)); | 444 | LUA_ASSERT(L1, lua_istable(L2, -1)); |
445 | std::ignore = luaG_pushstringview(L2, _fqn); // L2: {} "f.q.n" | 445 | std::ignore = luaG_pushstring(L2, _fqn); // L2: {} "f.q.n" |
446 | lua_rawget(L2, -2); // L2: {} t | 446 | lua_rawget(L2, -2); // L2: {} t |
447 | // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead) | 447 | // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead) |
448 | // but not when we extract something out of a keeper, as there is nothing to clone! | 448 | // but not when we extract something out of a keeper, as there is nothing to clone! |
@@ -492,7 +492,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
492 | if (U->verboseErrors) { | 492 | if (U->verboseErrors) { |
493 | // for debug purposes, let's try to build a useful name | 493 | // for debug purposes, let's try to build a useful name |
494 | if (luaG_type(L1, _key_i) == LuaType::STRING) { | 494 | if (luaG_type(L1, _key_i) == LuaType::STRING) { |
495 | std::string_view const _key{ luaG_tostringview(L1, _key_i) }; | 495 | std::string_view const _key{ luaG_tostring(L1, _key_i) }; |
496 | size_t const _bufLen{ strlen(name) + _key.size() + 2 }; // +2 for separator dot and terminating 0 | 496 | size_t const _bufLen{ strlen(name) + _key.size() + 2 }; // +2 for separator dot and terminating 0 |
497 | _valPath = static_cast<char*>(alloca(_bufLen)); | 497 | _valPath = static_cast<char*>(alloca(_bufLen)); |
498 | sprintf(_valPath, "%s." STRINGVIEW_FMT, name, (int) _key.size(), _key.data()); | 498 | sprintf(_valPath, "%s." STRINGVIEW_FMT, name, (int) _key.size(), _key.data()); |
@@ -597,7 +597,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
597 | // push a light userdata uniquely representing the table | 597 | // push a light userdata uniquely representing the table |
598 | lua_pushlightuserdata(L2, const_cast<void*>(_p)); // L1: ... t ... L2: ... p | 598 | lua_pushlightuserdata(L2, const_cast<void*>(_p)); // L1: ... t ... L2: ... p |
599 | 599 | ||
600 | //DEBUGSPEW_CODE(DebugSpew(U) << "<< ID: " << luaG_tostringview(L2, -1) << " >>" << std::endl); | 600 | //DEBUGSPEW_CODE(DebugSpew(U) << "<< ID: " << luaG_tostring(L2, -1) << " >>" << std::endl); |
601 | 601 | ||
602 | lua_rawget(L2, L2_cache_i); // L1: ... t ... L2: ... {cached|nil} | 602 | lua_rawget(L2, L2_cache_i); // L1: ... t ... L2: ... {cached|nil} |
603 | bool const _not_found_in_cache{ lua_isnil(L2, -1) }; | 603 | bool const _not_found_in_cache{ lua_isnil(L2, -1) }; |
@@ -723,7 +723,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
723 | // Returns false if not a deep userdata, else true (unless an error occured) | 723 | // Returns false if not a deep userdata, else true (unless an error occured) |
724 | [[nodiscard]] bool InterCopyContext::tryCopyDeep() const | 724 | [[nodiscard]] bool InterCopyContext::tryCopyDeep() const |
725 | { | 725 | { |
726 | DeepFactory* const _factory{ DeepFactory::LookupFactory(L1, L1_i, mode) }; | 726 | DeepFactory* const _factory{ DeepFactory::LookupFactory(L1, L1_i, mode) }; // L1: ... deep ... |
727 | if (_factory == nullptr) { | 727 | if (_factory == nullptr) { |
728 | return false; // not a deep userdata | 728 | return false; // not a deep userdata |
729 | } | 729 | } |
@@ -733,30 +733,31 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
733 | 733 | ||
734 | // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail | 734 | // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail |
735 | int _nuv{ 0 }; | 735 | int _nuv{ 0 }; |
736 | while (lua_getiuservalue(L1, L1_i, _nuv + 1) != LUA_TNONE) { // L1: ... u [uv]* nil | 736 | while (lua_getiuservalue(L1, L1_i, _nuv + 1) != LUA_TNONE) { // L1: ... deep ... [uv]* nil |
737 | ++_nuv; | 737 | ++_nuv; |
738 | } | 738 | } |
739 | // last call returned TNONE and pushed nil, that we don't need | 739 | // last call returned TNONE and pushed nil, that we don't need |
740 | lua_pop(L1, 1); // L1: ... u [uv]* | 740 | lua_pop(L1, 1); // L1: ... deep ... [uv]* |
741 | STACK_CHECK(L1, _nuv); | 741 | STACK_CHECK(L1, _nuv); |
742 | 742 | ||
743 | DeepPrelude* const _u{ *lua_tofulluserdata<DeepPrelude*>(L1, L1_i) }; | 743 | DeepPrelude* const _deep{ *luaG_tofulluserdata<DeepPrelude*>(L1, L1_i) }; |
744 | DeepFactory::PushDeepProxy(L2, _u, _nuv, mode, getErrL()); // L1: ... u [uv]* L2: u | 744 | DeepFactory::PushDeepProxy(L2, _deep, _nuv, mode, getErrL()); // L1: ... deep ... [uv]* L2: deep |
745 | 745 | ||
746 | // transfer all uservalues of the source in the destination | 746 | // transfer all uservalues of the source in the destination |
747 | { | 747 | { |
748 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, name }; | 748 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, name }; |
749 | int const _clone_i{ lua_gettop(L2) }; | 749 | int const _clone_i{ lua_gettop(L2) }; |
750 | // TODO: STACK_GROW(L2, _nuv), and same for L1 above and everywhere we use lua_getiuservalue | ||
750 | while (_nuv) { | 751 | while (_nuv) { |
751 | _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; | 752 | _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; |
752 | if (!_c.inter_copy_one()) { // L1: ... u [uv]* L2: u uv | 753 | if (!_c.inter_copy_one()) { // L1: ... deep ... [uv]* L2: deep uv |
753 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); | 754 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); |
754 | } | 755 | } |
755 | lua_pop(L1, 1); // L1: ... u [uv]* | 756 | lua_pop(L1, 1); // L1: ... deep ... [uv]* |
756 | // this pops the value from the stack | 757 | // this pops the value from the stack |
757 | lua_setiuservalue(L2, _clone_i, _nuv); // L2: u | 758 | lua_setiuservalue(L2, _clone_i, _nuv); // L2: deep |
758 | --_nuv; | 759 | --_nuv; |
759 | } | 760 | } // loop done: no uv remains on L1 stack // L1: ... deep ... |
760 | } | 761 | } |
761 | 762 | ||
762 | STACK_CHECK(L2, 1); | 763 | STACK_CHECK(L2, 1); |
@@ -940,9 +941,9 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
940 | 941 | ||
941 | [[nodiscard]] bool InterCopyContext::inter_copy_string() const | 942 | [[nodiscard]] bool InterCopyContext::inter_copy_string() const |
942 | { | 943 | { |
943 | std::string_view const _s{ luaG_tostringview(L1, L1_i) }; | 944 | std::string_view const _s{ luaG_tostring(L1, L1_i) }; |
944 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "'" << _s << "'" << std::endl); | 945 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "'" << _s << "'" << std::endl); |
945 | std::ignore = luaG_pushstringview(L2, _s); | 946 | std::ignore = luaG_pushstring(L2, _s); |
946 | return true; | 947 | return true; |
947 | } | 948 | } |
948 | 949 | ||
@@ -1188,7 +1189,7 @@ namespace { | |||
1188 | 1189 | ||
1189 | STACK_CHECK_START_REL(L1, 0); | 1190 | STACK_CHECK_START_REL(L1, 0); |
1190 | if (luaG_type(L1, L1_i) != LuaType::TABLE) { | 1191 | if (luaG_type(L1, L1_i) != LuaType::TABLE) { |
1191 | std::string_view const _msg{ luaG_pushstringview(L1, "expected package as table, got a %s", luaL_typename(L1, L1_i)) }; | 1192 | std::string_view const _msg{ luaG_pushstring(L1, "expected package as table, got a %s", luaL_typename(L1, L1_i)) }; |
1192 | STACK_CHECK(L1, 1); | 1193 | STACK_CHECK(L1, 1); |
1193 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later | 1194 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later |
1194 | if (mode == LookupMode::LaneBody) { | 1195 | if (mode == LookupMode::LaneBody) { |
@@ -1224,7 +1225,7 @@ namespace { | |||
1224 | if (_result == InterCopyResult::Success) { | 1225 | if (_result == InterCopyResult::Success) { |
1225 | lua_setfield(L2, -2, _entry.data()); // set package[entry] | 1226 | lua_setfield(L2, -2, _entry.data()); // set package[entry] |
1226 | } else { | 1227 | } else { |
1227 | std::string_view const _msg{ luaG_pushstringview(L1, "failed to copy package.%s", _entry.data()) }; | 1228 | std::string_view const _msg{ luaG_pushstring(L1, "failed to copy package.%s", _entry.data()) }; |
1228 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later | 1229 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later |
1229 | if (mode == LookupMode::LaneBody) { | 1230 | if (mode == LookupMode::LaneBody) { |
1230 | raise_luaL_error(getErrL(), _msg); | 1231 | raise_luaL_error(getErrL(), _msg); |