aboutsummaryrefslogtreecommitdiff
path: root/src/intercopycontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/intercopycontext.cpp89
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
312void InterCopyContext::lookup_native_func() const 313void 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);