diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-07 11:46:25 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-07 11:46:25 +0200 |
| commit | ee32d4281a5e59ce81d7f38f86a49fa8ff64d2c3 (patch) | |
| tree | 68c0d74ac40c6ee098abf606e3d660a862acf04f /src/intercopycontext.cpp | |
| parent | 35d7a6bb691d7e0564cda324b3d724caf4901545 (diff) | |
| download | lanes-ee32d4281a5e59ce81d7f38f86a49fa8ff64d2c3.tar.gz lanes-ee32d4281a5e59ce81d7f38f86a49fa8ff64d2c3.tar.bz2 lanes-ee32d4281a5e59ce81d7f38f86a49fa8ff64d2c3.zip | |
Boyscouting some luaG_ functions
Diffstat (limited to 'src/intercopycontext.cpp')
| -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); |
