aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compat.h8
-rw-r--r--src/intercopycontext.cpp40
-rw-r--r--src/keeper.cpp142
-rw-r--r--src/keeper.h4
-rw-r--r--src/linda.cpp8
-rw-r--r--src/state.cpp8
6 files changed, 109 insertions, 101 deletions
diff --git a/src/compat.h b/src/compat.h
index bcea225..714556e 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -261,6 +261,14 @@ inline void luaG_pushglobaltable(lua_State* const L_)
261 261
262// ################################################################################################# 262// #################################################################################################
263 263
264inline void luaG_setfield(lua_State* const L_, int const idx_, char const* k_) = delete;
265inline void luaG_setfield(lua_State* const L_, int const idx_, std::string_view const& k_)
266{
267 lua_setfield(L_, idx_, k_.data());
268}
269
270// #################################################################################################
271
264inline void luaG_setmetatable(lua_State* const L_, std::string_view const& tname_) 272inline void luaG_setmetatable(lua_State* const L_, std::string_view const& tname_)
265{ 273{
266 // fake externs to make clang happy... 274 // fake externs to make clang happy...
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp
index 1ccef80..e56b9fd 100644
--- a/src/intercopycontext.cpp
+++ b/src/intercopycontext.cpp
@@ -106,17 +106,16 @@ THE SOFTWARE.
106 lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... 106 lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ...
107 STACK_CHECK(L1, 0); 107 STACK_CHECK(L1, 0);
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 _fqn = std::string_view{}; // just in case
110 // 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
111 kLaneNameRegKey.pushValue(L1); // L1: ... v ... lane_name 110 kLaneNameRegKey.pushValue(L1); // L1: ... v ... lane_name
112 char const* _from{ lua_tostring(L1, -1) }; 111 std::string_view const _from{ luaG_tostring(L1, -1) };
113 lua_pushcfunction(L1, LG_nameof); // L1: ... v ... lane_name LG_nameof 112 lua_pushcfunction(L1, LG_nameof); // L1: ... v ... lane_name LG_nameof
114 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
115 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
116 char const* _typewhat{ (luaG_type(L1, -2) == LuaType::STRING) ? lua_tostring(L1, -2) : luaL_typename(L1, -2) }; 115 std::string_view const _typewhat{ (luaG_type(L1, -2) == LuaType::STRING) ? luaG_tostring(L1, -2) : luaG_typename(L1, -2) };
117 // second return value can be nil if the table was not found 116 // second return value can be nil if the table was not found
118 // probable reason: the function was removed from the source Lua state before Lanes was required. 117 // probable reason: the function was removed from the source Lua state before Lanes was required.
119 char const *_what, *_gotchaA, *_gotchaB; 118 std::string_view _what, _gotchaA, _gotchaB;
120 if (lua_isnil(L1, -1)) { 119 if (lua_isnil(L1, -1)) {
121 _gotchaA = " referenced by"; 120 _gotchaA = " referenced by";
122 _gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; 121 _gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)";
@@ -124,9 +123,9 @@ THE SOFTWARE.
124 } else { 123 } else {
125 _gotchaA = ""; 124 _gotchaA = "";
126 _gotchaB = ""; 125 _gotchaB = "";
127 _what = (luaG_type(L1, -1) == LuaType::STRING) ? lua_tostring(L1, -1) : luaL_typename(L1, -1); 126 _what = (luaG_type(L1, -1) == LuaType::STRING) ? luaG_tostring(L1, -1) : luaG_typename(L1, -1);
128 } 127 }
129 raise_luaL_error(L1, "%s%s '%s' not found in %s origin transfer database.%s", _typewhat, _gotchaA, _what, _from ? _from : "main", _gotchaB); 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 } 129 }
131 STACK_CHECK(L1, 0); 130 STACK_CHECK(L1, 0);
132 return _fqn; 131 return _fqn;
@@ -283,12 +282,9 @@ void InterCopyContext::copyFunction() const
283 282
284 // Set upvalues (originally set to 'nil' by 'lua_load') 283 // Set upvalues (originally set to 'nil' by 'lua_load')
285 for (int const _func_index{ lua_gettop(L2) - _n }; _n > 0; --_n) { 284 for (int const _func_index{ lua_gettop(L2) - _n }; _n > 0; --_n) {
286 [[maybe_unused]] char const* _upname{ lua_setupvalue(L2, _func_index, _n) }; // L2: ... {cache} ... function 285 // assign upvalue, popping it from the stack
287 // 286 [[maybe_unused]] std::string_view const _upname{ lua_setupvalue(L2, _func_index, _n) };// L2: ... {cache} ... function
288 // "assigns the value at the top of the stack to the upvalue and returns its name. 287 LUA_ASSERT(L1, !_upname.empty()); // not having enough slots?
289 // It also pops the value from the stack."
290
291 LUA_ASSERT(L1, _upname); // not having enough slots?
292 } 288 }
293 // once all upvalues have been set we are left 289 // once all upvalues have been set we are left
294 // with the function at the top of the stack // L2: ... {cache} ... function 290 // with the function at the top of the stack // L2: ... {cache} ... function
@@ -328,19 +324,19 @@ void InterCopyContext::lookupNativeFunction() const
328 // anything other than function or table should not happen! 324 // anything other than function or table should not happen!
329 if (!lua_isfunction(L2, -1) && !lua_istable(L2, -1)) { 325 if (!lua_isfunction(L2, -1) && !lua_istable(L2, -1)) {
330 kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name 326 kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name
331 char const* const _from{ lua_tostring(L1, -1) }; 327 std::string_view const _from{ luaG_tostring(L1, -1) };
332 lua_pop(L1, 1); // L1: ... f ... 328 lua_pop(L1, 1); // L1: ... f ...
333 kLaneNameRegKey.pushValue(L2); // L1: ... f ... L2: {} f lane_name 329 kLaneNameRegKey.pushValue(L2); // L1: ... f ... L2: {} f lane_name
334 char const* const _to{ lua_tostring(L2, -1) }; 330 std::string_view const _to{ luaG_tostring(L2, -1) };
335 lua_pop(L2, 1); // L2: {} f 331 lua_pop(L2, 1); // L2: {} f
336 // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error 332 // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error
337 raise_luaL_error( 333 raise_luaL_error(
338 getErrL(), 334 getErrL(),
339 "%s%s: function '%s' not found in %s destination transfer database.", 335 "%s%s: function '%s' not found in %s destination transfer database.",
340 lua_isnil(L2, -1) ? "" : "INTERNAL ERROR IN ", 336 lua_isnil(L2, -1) ? "" : "INTERNAL ERROR IN ",
341 _from ? _from : "main", 337 _from.empty() ? "main" : _from.data(),
342 _fqn.data(), 338 _fqn.data(),
343 _to ? _to : "main"); 339 _to.empty() ? "main" : _to.data());
344 return; 340 return;
345 } 341 }
346 lua_remove(L2, -2); // L2: f 342 lua_remove(L2, -2); // L2: f
@@ -452,18 +448,18 @@ void InterCopyContext::copyCachedFunction() const
452 return false; 448 return false;
453 } 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 449 } 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
454 kLaneNameRegKey.pushValue(L1); // L1: ... t ... lane_name 450 kLaneNameRegKey.pushValue(L1); // L1: ... t ... lane_name
455 char const* _from{ lua_tostring(L1, -1) }; 451 std::string_view const _from{ luaG_tostring(L1, -1) };
456 lua_pop(L1, 1); // L1: ... t ... 452 lua_pop(L1, 1); // L1: ... t ...
457 kLaneNameRegKey.pushValue(L2); // L1: ... t ... L2: {} t lane_name 453 kLaneNameRegKey.pushValue(L2); // L1: ... t ... L2: {} t lane_name
458 char const* _to{ lua_tostring(L2, -1) }; 454 std::string_view const _to{ luaG_tostring(L2, -1) };
459 lua_pop(L2, 1); // L1: ... t ... L2: {} t 455 lua_pop(L2, 1); // L1: ... t ... L2: {} t
460 raise_luaL_error( 456 raise_luaL_error(
461 getErrL(), 457 getErrL(),
462 "%s: source table '%s' found as %s in %s destination transfer database.", 458 "%s: source table '%s' found as %s in %s destination transfer database.",
463 _from ? _from : "main", 459 _from.empty() ? "main" : _from.data(),
464 _fqn, 460 _fqn.data(),
465 luaG_typename(L2, -1).data(), 461 luaG_typename(L2, -1).data(),
466 _to ? _to : "main"); 462 _to.empty() ? "main" : _to.data());
467 } 463 }
468 lua_remove(L2, -2); // L1: ... t ... L2: t 464 lua_remove(L2, -2); // L1: ... t ... L2: t
469 break; 465 break;
@@ -1260,7 +1256,7 @@ namespace {
1260 STACK_CHECK(L1, 0); 1256 STACK_CHECK(L1, 0);
1261 } 1257 }
1262 if (_result == InterCopyResult::Success) { 1258 if (_result == InterCopyResult::Success) {
1263 lua_setfield(L2, -2, _entry.data()); // set package[entry] 1259 luaG_setfield(L2, -2, _entry); // set package[entry]
1264 } else { 1260 } else {
1265 std::string_view const _msg{ luaG_pushstring(L1, "failed to copy package.%s", _entry.data()) }; 1261 std::string_view const _msg{ luaG_pushstring(L1, "failed to copy package.%s", _entry.data()) };
1266 // raise the error when copying from lane to lane, else just leave it on the stack to be raised later 1262 // raise the error when copying from lane to lane, else just leave it on the stack to be raised later
diff --git a/src/keeper.cpp b/src/keeper.cpp
index 4175d84..6aeea45 100644
--- a/src/keeper.cpp
+++ b/src/keeper.cpp
@@ -51,6 +51,8 @@
51// where key is a key used in the Lua Linda API to exchange data, and KeyUD is a full userdata with a table uservalue 51// where key is a key used in the Lua Linda API to exchange data, and KeyUD is a full userdata with a table uservalue
52// the table uservalue is the actual fifo, where elements are added and removed. 52// the table uservalue is the actual fifo, where elements are added and removed.
53 53
54namespace {
55
54// ################################################################################################# 56// #################################################################################################
55// ################################################################################################# 57// #################################################################################################
56// ############################################ KeyUD ############################################## 58// ############################################ KeyUD ##############################################
@@ -77,10 +79,10 @@ class KeyUD
77 [[nodiscard]] bool changeLimit(int limit_); 79 [[nodiscard]] bool changeLimit(int limit_);
78 [[nodiscard]] static KeyUD* Create(KeeperState K_); 80 [[nodiscard]] static KeyUD* Create(KeeperState K_);
79 [[nodiscard]] static KeyUD* GetPtr(KeeperState K_, int idx_); 81 [[nodiscard]] static KeyUD* GetPtr(KeeperState K_, int idx_);
80 void peek(KeeperState K_, int count_); 82 void peek(KeeperState K_, int count_) const; // keepercall_get
81 [[nodiscard]] int pop(KeeperState K_, int minCount_, int maxCount_); 83 [[nodiscard]] int pop(KeeperState K_, int minCount_, int maxCount_); // keepercall_receive[_batched]
82 void prepareAccess(KeeperState K_, int idx_); 84 void prepareAccess(KeeperState K_, int idx_) const;
83 [[nodiscard]] bool push(KeeperState K_, int count_); 85 [[nodiscard]] bool push(KeeperState K_, int count_); // keepercall_send
84 [[nodiscard]] bool reset(KeeperState K_); 86 [[nodiscard]] bool reset(KeeperState K_);
85}; 87};
86 88
@@ -126,7 +128,7 @@ KeyUD* KeyUD::GetPtr(KeeperState const K_, int idx_)
126// out: bool ... 128// out: bool ...
127// pops the fifo, push bool + as much data as is available (up to the specified count) without consuming it 129// pops the fifo, push bool + as much data as is available (up to the specified count) without consuming it
128// bool is true if the requested count was served, else false 130// bool is true if the requested count was served, else false
129void KeyUD::peek(KeeperState const K_, int const count_) 131void KeyUD::peek(KeeperState const K_, int const count_) const
130{ 132{
131 STACK_CHECK_START_ABS(K_, 1); 133 STACK_CHECK_START_ABS(K_, 1);
132 LUA_ASSERT(K_, KeyUD::GetPtr(K_, -1) == this); // K_: KeyUD 134 LUA_ASSERT(K_, KeyUD::GetPtr(K_, -1) == this); // K_: KeyUD
@@ -194,7 +196,7 @@ int KeyUD::pop(KeeperState const K_, int const minCount_, int const maxCount_)
194 196
195// expects 'this' at the specified index 197// expects 'this' at the specified index
196// replaces it by its uservalue on the stack (the table holding the fifo values) 198// replaces it by its uservalue on the stack (the table holding the fifo values)
197void KeyUD::prepareAccess(KeeperState const K_, int const idx_) 199void KeyUD::prepareAccess(KeeperState const K_, int const idx_) const
198{ 200{
199 int const _idx{ luaG_absindex(K_, idx_) }; 201 int const _idx{ luaG_absindex(K_, idx_) };
200 LUA_ASSERT(K_, KeyUD::GetPtr(K_, idx_) == this); 202 LUA_ASSERT(K_, KeyUD::GetPtr(K_, idx_) == this);
@@ -273,68 +275,7 @@ static void PushKeysDB(KeeperState const K_, int const idx_)
273 STACK_CHECK(K_, 1); 275 STACK_CHECK(K_, 1);
274} 276}
275 277
276// ################################################################################################# 278} // namespace
277
278// only used by linda:dump() and linda:__towatch() for debugging purposes
279int keeper_push_linda_storage(Linda& linda_, DestState L_)
280{
281 Keeper* const _keeper{ linda_.whichKeeper() };
282 KeeperState const _K{ _keeper ? _keeper->K : nullptr };
283 if (_K == nullptr) {
284 return 0;
285 }
286 STACK_GROW(_K, 4);
287 STACK_CHECK_START_REL(_K, 0);
288 kLindasRegKey.pushValue(_K); // _K: LindasDB L_:
289 lua_pushlightuserdata(_K, &linda_); // _K: LindasDB linda L_:
290 lua_rawget(_K, -2); // _K: LindasDB KeysDB L_:
291 lua_remove(_K, -2); // _K: KeysDB L_:
292 if (!lua_istable(_K, -1)) { // possible if we didn't send anything through that linda
293 lua_pop(_K, 1); // _K: L_:
294 STACK_CHECK(_K, 0);
295 return 0;
296 }
297 // move data from keeper to destination state
298 STACK_GROW(L_, 5);
299 STACK_CHECK_START_REL(L_, 0);
300 lua_newtable(L_); // _K: KeysDB L_: out
301 InterCopyContext _c{ linda_.U, L_, SourceState{ _K }, {}, {}, {}, LookupMode::FromKeeper, {} };
302 lua_pushnil(_K); // _K: KeysDB nil L_: out
303 while (lua_next(_K, -2)) { // _K: KeysDB key KeyUD L_: out
304 KeyUD* const _key{ KeyUD::GetPtr(_K, -1) };
305 _key->prepareAccess(_K, -1); // _K: KeysDB key fifo L_: out
306 lua_pushvalue(_K, -2); // _K: KeysDB key fifo key L_: out
307 if (_c.interMove(1) != InterCopyResult::Success) { // _K: KeysDB key fifo L_: out key
308 raise_luaL_error(L_, "Internal error reading Keeper contents");
309 }
310 STACK_CHECK(L_, 2);
311 lua_newtable(L_); // _K: KeysDB key fifo L_: out key keyout
312 if (_c.interMove(1) != InterCopyResult::Success) { // _K: KeysDB key L_: out key keyout fifo
313 raise_luaL_error(L_, "Internal error reading Keeper contents");
314 }
315 // keyout.first
316 lua_pushinteger(L_, _key->first); // _K: KeysDB key L_: out key keyout fifo first
317 STACK_CHECK(L_, 5);
318 lua_setfield(L_, -3, "first"); // _K: KeysDB key L_: out key keyout fifo
319 // keyout.count
320 lua_pushinteger(L_, _key->count); // _K: KeysDB key L_: out key keyout fifo count
321 STACK_CHECK(L_, 5);
322 lua_setfield(L_, -3, "count"); // _K: KeysDB key L_: out key keyout fifo
323 // keyout.limit
324 lua_pushinteger(L_, _key->limit); // _K: KeysDB key L_: out key keyout fifo limit
325 STACK_CHECK(L_, 5);
326 lua_setfield(L_, -3, "limit"); // _K: KeysDB key L_: out key keyout fifo
327 // keyout.fifo
328 lua_setfield(L_, -2, "fifo"); // _K: KeysDB key L_: out key keyout
329 // out[key] = keyout
330 lua_rawset(L_, -3); // _K: KeysDB key L_: out
331 STACK_CHECK(L_, 1);
332 } // _K: KeysDB L_: out
333 STACK_CHECK(L_, 1);
334 lua_pop(_K, 1); // _K: L_: out
335 STACK_CHECK(_K, 0);
336 return 1;
337}
338 279
339// ################################################################################################# 280// #################################################################################################
340// ################################################################################################# 281// #################################################################################################
@@ -437,7 +378,7 @@ int keepercall_get(lua_State* const L_)
437 lua_replace(_K, 1); // _K: KeysDB key 378 lua_replace(_K, 1); // _K: KeysDB key
438 lua_rawget(_K, 1); // _K: KeysDB KeyUD 379 lua_rawget(_K, 1); // _K: KeysDB KeyUD
439 lua_remove(_K, 1); // _K: KeyUD 380 lua_remove(_K, 1); // _K: KeyUD
440 KeyUD* const _key{ KeyUD::GetPtr(_K, -1) }; 381 KeyUD const* const _key{ KeyUD::GetPtr(_K, -1) };
441 if (_key != nullptr) { 382 if (_key != nullptr) {
442 _key->peek(_K, _count); // _K: N val... 383 _key->peek(_K, _count); // _K: N val...
443 } else { 384 } else {
@@ -713,6 +654,69 @@ void Keeper::operator delete[](void* p_, Universe* U_)
713} 654}
714 655
715// ################################################################################################# 656// #################################################################################################
657
658// only used by linda:dump() and linda:__towatch() for debugging purposes
659int Keeper::PushLindaStorage(Linda& linda_, DestState const L_)
660{
661 Keeper* const _keeper{ linda_.whichKeeper() };
662 KeeperState const _K{ _keeper ? _keeper->K : nullptr };
663 if (_K == nullptr) {
664 return 0;
665 }
666 STACK_GROW(_K, 4);
667 STACK_CHECK_START_REL(_K, 0);
668 kLindasRegKey.pushValue(_K); // _K: LindasDB L_:
669 lua_pushlightuserdata(_K, &linda_); // _K: LindasDB linda L_:
670 lua_rawget(_K, -2); // _K: LindasDB KeysDB L_:
671 lua_remove(_K, -2); // _K: KeysDB L_:
672 if (!lua_istable(_K, -1)) { // possible if we didn't send anything through that linda
673 lua_pop(_K, 1); // _K: L_:
674 STACK_CHECK(_K, 0);
675 return 0;
676 }
677 // move data from keeper to destination state
678 STACK_GROW(L_, 5);
679 STACK_CHECK_START_REL(L_, 0);
680 lua_newtable(L_); // _K: KeysDB L_: out
681 InterCopyContext _c{ linda_.U, L_, SourceState{ _K }, {}, {}, {}, LookupMode::FromKeeper, {} };
682 lua_pushnil(_K); // _K: KeysDB nil L_: out
683 while (lua_next(_K, -2)) { // _K: KeysDB key KeyUD L_: out
684 KeyUD* const _key{ KeyUD::GetPtr(_K, -1) };
685 _key->prepareAccess(_K, -1); // _K: KeysDB key fifo L_: out
686 lua_pushvalue(_K, -2); // _K: KeysDB key fifo key L_: out
687 if (_c.interMove(1) != InterCopyResult::Success) { // _K: KeysDB key fifo L_: out key
688 raise_luaL_error(L_, "Internal error reading Keeper contents");
689 }
690 STACK_CHECK(L_, 2);
691 lua_newtable(L_); // _K: KeysDB key fifo L_: out key keyout
692 if (_c.interMove(1) != InterCopyResult::Success) { // _K: KeysDB key L_: out key keyout fifo
693 raise_luaL_error(L_, "Internal error reading Keeper contents");
694 }
695 // keyout.first
696 lua_pushinteger(L_, _key->first); // _K: KeysDB key L_: out key keyout fifo first
697 STACK_CHECK(L_, 5);
698 lua_setfield(L_, -3, "first"); // _K: KeysDB key L_: out key keyout fifo
699 // keyout.count
700 lua_pushinteger(L_, _key->count); // _K: KeysDB key L_: out key keyout fifo count
701 STACK_CHECK(L_, 5);
702 lua_setfield(L_, -3, "count"); // _K: KeysDB key L_: out key keyout fifo
703 // keyout.limit
704 lua_pushinteger(L_, _key->limit); // _K: KeysDB key L_: out key keyout fifo limit
705 STACK_CHECK(L_, 5);
706 lua_setfield(L_, -3, "limit"); // _K: KeysDB key L_: out key keyout fifo
707 // keyout.fifo
708 lua_setfield(L_, -2, "fifo"); // _K: KeysDB key L_: out key keyout
709 // out[key] = keyout
710 lua_rawset(L_, -3); // _K: KeysDB key L_: out
711 STACK_CHECK(L_, 1);
712 } // _K: KeysDB L_: out
713 STACK_CHECK(L_, 1);
714 lua_pop(_K, 1); // _K: L_: out
715 STACK_CHECK(_K, 0);
716 return 1;
717}
718
719// #################################################################################################
716// ################################################################################################# 720// #################################################################################################
717// ########################################## Keepers ############################################## 721// ########################################## Keepers ##############################################
718// ################################################################################################# 722// #################################################################################################
diff --git a/src/keeper.h b/src/keeper.h
index 1a194e8..102d006 100644
--- a/src/keeper.h
+++ b/src/keeper.h
@@ -28,6 +28,8 @@ struct Keeper
28 Keeper(Keeper const&&) = delete; 28 Keeper(Keeper const&&) = delete;
29 Keeper& operator=(Keeper const&) = delete; 29 Keeper& operator=(Keeper const&) = delete;
30 Keeper& operator=(Keeper const&&) = delete; 30 Keeper& operator=(Keeper const&&) = delete;
31
32 [[nodiscard]] static int PushLindaStorage(Linda& linda_, DestState L_);
31}; 33};
32 34
33// ################################################################################################# 35// #################################################################################################
@@ -69,8 +71,6 @@ struct Keepers
69// xxh64 of string "kNilSentinel" generated at https://www.pelock.com/products/hash-calculator 71// xxh64 of string "kNilSentinel" generated at https://www.pelock.com/products/hash-calculator
70static constexpr UniqueKey kNilSentinel{ 0xC457D4EDDB05B5E4ull, "lanes.null" }; 72static constexpr UniqueKey kNilSentinel{ 0xC457D4EDDB05B5E4ull, "lanes.null" };
71 73
72[[nodiscard]] int keeper_push_linda_storage(Linda& linda_, DestState L_);
73
74using keeper_api_t = lua_CFunction; 74using keeper_api_t = lua_CFunction;
75#define KEEPER_API(_op) keepercall_##_op 75#define KEEPER_API(_op) keepercall_##_op
76 76
diff --git a/src/linda.cpp b/src/linda.cpp
index 316e917..3c04bae 100644
--- a/src/linda.cpp
+++ b/src/linda.cpp
@@ -162,7 +162,7 @@ std::string_view Linda::getName() const
162 } 162 }
163 if (std::holds_alternative<EmbeddedName>(nameVariant)) { 163 if (std::holds_alternative<EmbeddedName>(nameVariant)) {
164 char const* const _name{ std::get<EmbeddedName>(nameVariant).data() }; 164 char const* const _name{ std::get<EmbeddedName>(nameVariant).data() };
165 return std::string_view{ _name, strlen(_name) }; 165 return std::string_view{ _name };
166 } 166 }
167 return std::string_view{}; 167 return std::string_view{};
168} 168}
@@ -385,7 +385,7 @@ LUAG_FUNC(linda_dump)
385{ 385{
386 auto _dump = [](lua_State* L_) { 386 auto _dump = [](lua_State* L_) {
387 Linda* const _linda{ ToLinda<false>(L_, 1) }; 387 Linda* const _linda{ ToLinda<false>(L_, 1) };
388 return keeper_push_linda_storage(*_linda, DestState{ L_ }); 388 return Keeper::PushLindaStorage(*_linda, DestState{ L_ });
389 }; 389 };
390 return Linda::ProtectedCall(L_, _dump); 390 return Linda::ProtectedCall(L_, _dump);
391} 391}
@@ -777,9 +777,9 @@ LUAG_FUNC(linda_set)
777 // make sure the key is of a valid type (throws an error if not the case) 777 // make sure the key is of a valid type (throws an error if not the case)
778 check_key_types(L_, 2, 2); 778 check_key_types(L_, 2, 2);
779 779
780 Keeper* const _keeper{ _linda->whichKeeper() };
781 KeeperCallResult _pushed; 780 KeeperCallResult _pushed;
782 if (_linda->cancelRequest == CancelRequest::None) { 781 if (_linda->cancelRequest == CancelRequest::None) {
782 Keeper* const _keeper{ _linda->whichKeeper() };
783 _pushed = keeper_call(_keeper->K, KEEPER_API(set), L_, _linda, 2); 783 _pushed = keeper_call(_keeper->K, KEEPER_API(set), L_, _linda, 2);
784 if (_pushed.has_value()) { // no error? 784 if (_pushed.has_value()) { // no error?
785 LUA_ASSERT(L_, _pushed.value() == 1 && luaG_type(L_, -1) == LuaType::BOOLEAN); 785 LUA_ASSERT(L_, _pushed.value() == 1 && luaG_type(L_, -1) == LuaType::BOOLEAN);
@@ -823,7 +823,7 @@ LUAG_FUNC(linda_tostring)
823LUAG_FUNC(linda_towatch) 823LUAG_FUNC(linda_towatch)
824{ 824{
825 Linda* const _linda{ ToLinda<false>(L_, 1) }; 825 Linda* const _linda{ ToLinda<false>(L_, 1) };
826 int _pushed{ keeper_push_linda_storage(*_linda, DestState{ L_ }) }; 826 int _pushed{ Keeper::PushLindaStorage(*_linda, DestState{ L_ }) };
827 if (_pushed == 0) { 827 if (_pushed == 0) {
828 // if the linda is empty, don't return nil 828 // if the linda is empty, don't return nil
829 _pushed = LindaToString<false>(L_, 1); 829 _pushed = LindaToString<false>(L_, 1);
diff --git a/src/state.cpp b/src/state.cpp
index 96f7268..6d27256 100644
--- a/src/state.cpp
+++ b/src/state.cpp
@@ -42,7 +42,7 @@ THE SOFTWARE.
42 42
43// ################################################################################################# 43// #################################################################################################
44 44
45static constexpr char const* kOnStateCreate{ "on_state_create" }; // update lanes.lua if the name changes! 45static constexpr std::string_view kOnStateCreate{ "on_state_create" }; // update lanes.lua if the name changes!
46 46
47// ################################################################################################# 47// #################################################################################################
48// ################################################################################################# 48// #################################################################################################
@@ -185,7 +185,7 @@ namespace state {
185 std::string_view const _stateType{ mode_ == LookupMode::LaneBody ? "lane" : "keeper" }; 185 std::string_view const _stateType{ mode_ == LookupMode::LaneBody ? "lane" : "keeper" };
186 std::ignore = luaG_pushstring(L_, _stateType); // L_: on_state_create() "<type>" 186 std::ignore = luaG_pushstring(L_, _stateType); // L_: on_state_create() "<type>"
187 if (lua_pcall(L_, 1, 0, 0) != LUA_OK) { 187 if (lua_pcall(L_, 1, 0, 0) != LUA_OK) {
188 raise_luaL_error(from_, "%s failed: \"%s\"", kOnStateCreate, lua_isstring(L_, -1) ? lua_tostring(L_, -1) : luaG_typename(L_, -1).data()); 188 raise_luaL_error(from_, "%s failed: \"%s\"", kOnStateCreate.data(), lua_isstring(L_, -1) ? luaG_tostring(L_, -1).data() : luaG_typename(L_, -1).data());
189 } 189 }
190 STACK_CHECK(L_, 0); 190 STACK_CHECK(L_, 0);
191 } 191 }
@@ -235,12 +235,12 @@ namespace state {
235 // make sure the function doesn't have upvalues 235 // make sure the function doesn't have upvalues
236 char const* _upname{ lua_getupvalue(L_, -1, 1) }; // L_: settings on_state_create upval? 236 char const* _upname{ lua_getupvalue(L_, -1, 1) }; // L_: settings on_state_create upval?
237 if (_upname != nullptr) { // should be "" for C functions with upvalues if any 237 if (_upname != nullptr) { // should be "" for C functions with upvalues if any
238 raise_luaL_error(L_, "%s shouldn't have upvalues", kOnStateCreate); 238 raise_luaL_error(L_, "%s shouldn't have upvalues", kOnStateCreate.data());
239 } 239 }
240 // remove this C function from the config table so that it doesn't cause problems 240 // remove this C function from the config table so that it doesn't cause problems
241 // when we transfer the config table in newly created Lua states 241 // when we transfer the config table in newly created Lua states
242 lua_pushnil(L_); // L_: settings on_state_create nil 242 lua_pushnil(L_); // L_: settings on_state_create nil
243 lua_setfield(L_, -3, kOnStateCreate); // L_: settings on_state_create 243 luaG_setfield(L_, -3, kOnStateCreate); // L_: settings on_state_create
244 } else { 244 } else {
245 // optim: store marker saying we have such a function in the config table 245 // optim: store marker saying we have such a function in the config table
246 U_->onStateCreateFunc = reinterpret_cast<lua_CFunction>(InitializeOnStateCreate); 246 U_->onStateCreateFunc = reinterpret_cast<lua_CFunction>(InitializeOnStateCreate);