diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-20 11:48:41 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-20 11:48:41 +0200 |
| commit | 0ec260c12ee6a37e763bc60ef587dbd891136e76 (patch) | |
| tree | 26a738c47f8a4c264546feb5bccb507b3330456a /src/intercopycontext.cpp | |
| parent | 08040747494fe7839d2ab049e37f8e23fb8141b4 (diff) | |
| download | lanes-0ec260c12ee6a37e763bc60ef587dbd891136e76.tar.gz lanes-0ec260c12ee6a37e763bc60ef587dbd891136e76.tar.bz2 lanes-0ec260c12ee6a37e763bc60ef587dbd891136e76.zip | |
Start using string_view
Diffstat (limited to 'src/intercopycontext.cpp')
| -rw-r--r-- | src/intercopycontext.cpp | 89 |
1 files changed, 44 insertions, 45 deletions
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index e2e3d31..2f83400 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp | |||
| @@ -73,60 +73,61 @@ THE SOFTWARE. | |||
| 73 | // ################################################################################################# | 73 | // ################################################################################################# |
| 74 | 74 | ||
| 75 | // retrieve the name of a function/table in the lookup database | 75 | // retrieve the name of a function/table in the lookup database |
| 76 | [[nodiscard]] static char const* find_lookup_name(lua_State* L_, int i_, LookupMode mode_, char const* upName_, size_t* len_) | 76 | [[nodiscard]] std::string_view InterCopyContext::findLookupName() const |
| 77 | { | 77 | { |
| 78 | LUA_ASSERT(L_, lua_isfunction(L_, i_) || lua_istable(L_, i_)); // L_: ... v ... | 78 | LUA_ASSERT(L1, lua_isfunction(L1, L1_i) || lua_istable(L1, L1_i)); // L1: ... v ... |
| 79 | STACK_CHECK_START_REL(L_, 0); | 79 | STACK_CHECK_START_REL(L1, 0); |
| 80 | STACK_GROW(L_, 3); // up to 3 slots are necessary on error | 80 | STACK_GROW(L1, 3); // up to 3 slots are necessary on error |
| 81 | if (mode_ == LookupMode::FromKeeper) { | 81 | if (mode == LookupMode::FromKeeper) { |
| 82 | lua_CFunction const _f{ lua_tocfunction(L_, i_) }; // should *always* be one of the function sentinels | 82 | lua_CFunction const _f{ lua_tocfunction(L1, L1_i) }; // should *always* be one of the function sentinels |
| 83 | if (_f == func_lookup_sentinel || _f == table_lookup_sentinel || _f == userdata_clone_sentinel) { | 83 | if (_f == func_lookup_sentinel || _f == table_lookup_sentinel || _f == userdata_clone_sentinel) { |
| 84 | lua_getupvalue(L_, i_, 1); // L_: ... v ... "f.q.n" | 84 | lua_getupvalue(L1, L1_i, 1); // L1: ... v ... "f.q.n" |
| 85 | } else { | 85 | } else { |
| 86 | // if this is not a sentinel, this is some user-created table we wanted to lookup | 86 | // if this is not a sentinel, this is some user-created table we wanted to lookup |
| 87 | LUA_ASSERT(L_, nullptr == _f && lua_istable(L_, i_)); | 87 | LUA_ASSERT(L1, nullptr == _f && lua_istable(L1, L1_i)); |
| 88 | // push anything that will convert to nullptr string | 88 | // push anything that will convert to nullptr string |
| 89 | lua_pushnil(L_); // L_: ... v ... nil | 89 | lua_pushnil(L1); // L1: ... v ... nil |
| 90 | } | 90 | } |
| 91 | } else { | 91 | } else { |
| 92 | // fetch the name from the source state's lookup table | 92 | // fetch the name from the source state's lookup table |
| 93 | kLookupRegKey.pushValue(L_); // L_: ... v ... {} | 93 | kLookupRegKey.pushValue(L1); // L1: ... v ... {} |
| 94 | STACK_CHECK(L_, 1); | 94 | STACK_CHECK(L1, 1); |
| 95 | LUA_ASSERT(L_, lua_istable(L_, -1)); | 95 | LUA_ASSERT(L1, lua_istable(L1, -1)); |
| 96 | lua_pushvalue(L_, i_); // L_: ... v ... {} v | 96 | lua_pushvalue(L1, L1_i); // L1: ... v ... {} v |
| 97 | lua_rawget(L_, -2); // L_: ... v ... {} "f.q.n" | 97 | lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" |
| 98 | } | 98 | } |
| 99 | char const* _fqn{ lua_tolstring(L_, -1, len_) }; | 99 | size_t _len{ 0 }; |
| 100 | DEBUGSPEW_CODE(Universe* const _U = universe_get(L_)); | 100 | char const* _fqn{ lua_tolstring(L1, -1, &_len) }; |
| 101 | DEBUGSPEW_CODE(Universe* const _U = universe_get(L1)); | ||
| 101 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END(_U), _fqn)); | 102 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END(_U), _fqn)); |
| 102 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database | 103 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database |
| 103 | lua_pop(L_, (mode_ == LookupMode::FromKeeper) ? 1 : 2); // L_: ... v ... | 104 | lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... |
| 104 | STACK_CHECK(L_, 0); | 105 | STACK_CHECK(L1, 0); |
| 105 | if (nullptr == _fqn && !lua_istable(L_, i_)) { // raise an error if we try to send an unknown function (but not for tables) | 106 | if (nullptr == _fqn && !lua_istable(L1, L1_i)) { // raise an error if we try to send an unknown function (but not for tables) |
| 106 | *len_ = 0; // just in case | 107 | _len = 0; // just in case |
| 107 | // try to discover the name of the function we want to send | 108 | // try to discover the name of the function we want to send |
| 108 | lua_getglobal(L_, "decoda_name"); // L_: ... v ... decoda_name | 109 | lua_getglobal(L1, "decoda_name"); // L1: ... v ... decoda_name |
| 109 | char const* from{ lua_tostring(L_, -1) }; | 110 | char const* from{ lua_tostring(L1, -1) }; |
| 110 | lua_pushcfunction(L_, luaG_nameof); // L_: ... v ... decoda_name luaG_nameof | 111 | lua_pushcfunction(L1, luaG_nameof); // L1: ... v ... decoda_name luaG_nameof |
| 111 | lua_pushvalue(L_, i_); // L_: ... v ... decoda_name luaG_nameof t | 112 | lua_pushvalue(L1, L1_i); // L1: ... v ... decoda_name luaG_nameof t |
| 112 | lua_call(L_, 1, 2); // L_: ... v ... decoda_name "type" "name"|nil | 113 | lua_call(L1, 1, 2); // L1: ... v ... decoda_name "type" "name"|nil |
| 113 | char const* typewhat{ (lua_type(L_, -2) == LUA_TSTRING) ? lua_tostring(L_, -2) : luaL_typename(L_, -2) }; | 114 | char const* typewhat{ (lua_type(L1, -2) == LUA_TSTRING) ? lua_tostring(L1, -2) : luaL_typename(L1, -2) }; |
| 114 | // second return value can be nil if the table was not found | 115 | // second return value can be nil if the table was not found |
| 115 | // probable reason: the function was removed from the source Lua state before Lanes was required. | 116 | // probable reason: the function was removed from the source Lua state before Lanes was required. |
| 116 | char const *what, *gotchaA, *gotchaB; | 117 | char const *what, *gotchaA, *gotchaB; |
| 117 | if (lua_isnil(L_, -1)) { | 118 | if (lua_isnil(L1, -1)) { |
| 118 | gotchaA = " referenced by"; | 119 | gotchaA = " referenced by"; |
| 119 | gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; | 120 | gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; |
| 120 | what = upName_; | 121 | what = name; |
| 121 | } else { | 122 | } else { |
| 122 | gotchaA = ""; | 123 | gotchaA = ""; |
| 123 | gotchaB = ""; | 124 | gotchaB = ""; |
| 124 | what = (lua_type(L_, -1) == LUA_TSTRING) ? lua_tostring(L_, -1) : luaL_typename(L_, -1); | 125 | what = (lua_type(L1, -1) == LUA_TSTRING) ? lua_tostring(L1, -1) : luaL_typename(L1, -1); |
| 125 | } | 126 | } |
| 126 | raise_luaL_error(L_, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); | 127 | raise_luaL_error(L1, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); |
| 127 | } | 128 | } |
| 128 | STACK_CHECK(L_, 0); | 129 | STACK_CHECK(L1, 0); |
| 129 | return _fqn; | 130 | return std::string_view{ _fqn, _len }; |
| 130 | } | 131 | } |
| 131 | 132 | ||
| 132 | // ################################################################################################# | 133 | // ################################################################################################# |
| @@ -312,8 +313,7 @@ void InterCopyContext::copy_func() const | |||
| 312 | void InterCopyContext::lookup_native_func() const | 313 | void InterCopyContext::lookup_native_func() const |
| 313 | { | 314 | { |
| 314 | // get the name of the function we want to send | 315 | // get the name of the function we want to send |
| 315 | size_t _len; | 316 | std::string_view const _fqn{ findLookupName() }; |
| 316 | char const* const _fqn{ find_lookup_name(L1, L1_i, mode, name, &_len) }; | ||
| 317 | // push the equivalent function in the destination's stack, retrieved from the lookup table | 317 | // push the equivalent function in the destination's stack, retrieved from the lookup table |
| 318 | STACK_CHECK_START_REL(L2, 0); | 318 | STACK_CHECK_START_REL(L2, 0); |
| 319 | STACK_GROW(L2, 3); // up to 3 slots are necessary on error | 319 | STACK_GROW(L2, 3); // up to 3 slots are necessary on error |
| @@ -324,7 +324,7 @@ void InterCopyContext::lookup_native_func() const | |||
| 324 | 324 | ||
| 325 | case LookupMode::ToKeeper: | 325 | case LookupMode::ToKeeper: |
| 326 | // push a sentinel closure that holds the lookup name as upvalue | 326 | // push a sentinel closure that holds the lookup name as upvalue |
| 327 | lua_pushlstring(L2, _fqn, _len); // L1: ... f ... L2: "f.q.n" | 327 | lua_pushlstring(L2, _fqn.data(), _fqn.size()); // L1: ... f ... L2: "f.q.n" |
| 328 | lua_pushcclosure(L2, func_lookup_sentinel, 1); // L1: ... f ... L2: f | 328 | lua_pushcclosure(L2, func_lookup_sentinel, 1); // L1: ... f ... L2: f |
| 329 | break; | 329 | break; |
| 330 | 330 | ||
| @@ -333,7 +333,7 @@ void InterCopyContext::lookup_native_func() const | |||
| 333 | kLookupRegKey.pushValue(L2); // L1: ... f ... L2: {} | 333 | kLookupRegKey.pushValue(L2); // L1: ... f ... L2: {} |
| 334 | STACK_CHECK(L2, 1); | 334 | STACK_CHECK(L2, 1); |
| 335 | LUA_ASSERT(L1, lua_istable(L2, -1)); | 335 | LUA_ASSERT(L1, lua_istable(L2, -1)); |
| 336 | lua_pushlstring(L2, _fqn, _len); // L1: ... f ... L2: {} "f.q.n" | 336 | lua_pushlstring(L2, _fqn.data(), _fqn.size()); // L1: ... f ... L2: {} "f.q.n" |
| 337 | lua_rawget(L2, -2); // L1: ... f ... L2: {} f | 337 | lua_rawget(L2, -2); // L1: ... f ... L2: {} f |
| 338 | // nil means we don't know how to transfer stuff: user should do something | 338 | // nil means we don't know how to transfer stuff: user should do something |
| 339 | // anything other than function or table should not happen! | 339 | // anything other than function or table should not happen! |
| @@ -413,7 +413,7 @@ void InterCopyContext::copy_cached_func() const | |||
| 413 | // pushes a copy of the func, stores a reference in the cache | 413 | // pushes a copy of the func, stores a reference in the cache |
| 414 | copy_func(); // L2: ... {cache} ... function | 414 | copy_func(); // L2: ... {cache} ... function |
| 415 | } else { // found function in the cache | 415 | } else { // found function in the cache |
| 416 | lua_remove(L2, -2); // L2: ... {cache} ... function | 416 | lua_remove(L2, -2); // L2: ... {cache} ... function |
| 417 | } | 417 | } |
| 418 | STACK_CHECK(L2, 1); | 418 | STACK_CHECK(L2, 1); |
| 419 | LUA_ASSERT(L1, lua_isfunction(L2, -1)); | 419 | LUA_ASSERT(L1, lua_isfunction(L2, -1)); |
| @@ -430,9 +430,8 @@ void InterCopyContext::copy_cached_func() const | |||
| 430 | [[nodiscard]] bool InterCopyContext::lookup_table() const | 430 | [[nodiscard]] bool InterCopyContext::lookup_table() const |
| 431 | { | 431 | { |
| 432 | // get the name of the table we want to send | 432 | // get the name of the table we want to send |
| 433 | size_t _len; | 433 | std::string_view const _fqn{ findLookupName() }; |
| 434 | char const* const _fqn{ find_lookup_name(L1, L1_i, mode, name, &_len) }; | 434 | if (_fqn.empty()) { // name not found, it is some user-created table |
| 435 | if (nullptr == _fqn) { // name not found, it is some user-created table | ||
| 436 | return false; | 435 | return false; |
| 437 | } | 436 | } |
| 438 | // push the equivalent table in the destination's stack, retrieved from the lookup table | 437 | // push the equivalent table in the destination's stack, retrieved from the lookup table |
| @@ -445,7 +444,7 @@ void InterCopyContext::copy_cached_func() const | |||
| 445 | 444 | ||
| 446 | case LookupMode::ToKeeper: | 445 | case LookupMode::ToKeeper: |
| 447 | // push a sentinel closure that holds the lookup name as upvalue | 446 | // push a sentinel closure that holds the lookup name as upvalue |
| 448 | lua_pushlstring(L2, _fqn, _len); // L1: ... t ... L2: "f.q.n" | 447 | lua_pushlstring(L2, _fqn.data(), _fqn.size()); // L1: ... t ... L2: "f.q.n" |
| 449 | lua_pushcclosure(L2, table_lookup_sentinel, 1); // L1: ... t ... L2: f | 448 | lua_pushcclosure(L2, table_lookup_sentinel, 1); // L1: ... t ... L2: f |
| 450 | break; | 449 | break; |
| 451 | 450 | ||
| @@ -454,12 +453,12 @@ void InterCopyContext::copy_cached_func() const | |||
| 454 | kLookupRegKey.pushValue(L2); // L1: ... t ... L2: {} | 453 | kLookupRegKey.pushValue(L2); // L1: ... t ... L2: {} |
| 455 | STACK_CHECK(L2, 1); | 454 | STACK_CHECK(L2, 1); |
| 456 | LUA_ASSERT(L1, lua_istable(L2, -1)); | 455 | LUA_ASSERT(L1, lua_istable(L2, -1)); |
| 457 | lua_pushlstring(L2, _fqn, _len); // L2: {} "f.q.n" | 456 | lua_pushlstring(L2, _fqn.data(), _fqn.size()); // L2: {} "f.q.n" |
| 458 | lua_rawget(L2, -2); // L2: {} t | 457 | lua_rawget(L2, -2); // L2: {} t |
| 459 | // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead) | 458 | // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead) |
| 460 | // but not when we extract something out of a keeper, as there is nothing to clone! | 459 | // but not when we extract something out of a keeper, as there is nothing to clone! |
| 461 | if (lua_isnil(L2, -1) && mode == LookupMode::LaneBody) { | 460 | if (lua_isnil(L2, -1) && mode == LookupMode::LaneBody) { |
| 462 | lua_pop(L2, 2); // L1: ... t ... L2: | 461 | lua_pop(L2, 2); // L1: ... t ... L2: |
| 463 | STACK_CHECK(L2, 0); | 462 | STACK_CHECK(L2, 0); |
| 464 | return false; | 463 | return false; |
| 465 | } 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 | 464 | } 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 |
| @@ -932,7 +931,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
| 932 | 931 | ||
| 933 | [[nodiscard]] bool InterCopyContext::inter_copy_string() const | 932 | [[nodiscard]] bool InterCopyContext::inter_copy_string() const |
| 934 | { | 933 | { |
| 935 | size_t _len; | 934 | size_t _len{ 0 }; |
| 936 | char const* const _s{ lua_tolstring(L1, L1_i, &_len) }; | 935 | char const* const _s{ lua_tolstring(L1, L1_i, &_len) }; |
| 937 | DEBUGSPEW_CODE(fprintf(stderr, "'%s'\n", _s)); | 936 | DEBUGSPEW_CODE(fprintf(stderr, "'%s'\n", _s)); |
| 938 | lua_pushlstring(L2, _s, _len); | 937 | lua_pushlstring(L2, _s, _len); |
