diff options
-rw-r--r-- | src/compat.h | 8 | ||||
-rw-r--r-- | src/intercopycontext.cpp | 40 | ||||
-rw-r--r-- | src/keeper.cpp | 142 | ||||
-rw-r--r-- | src/keeper.h | 4 | ||||
-rw-r--r-- | src/linda.cpp | 8 | ||||
-rw-r--r-- | src/state.cpp | 8 |
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 | ||
264 | inline void luaG_setfield(lua_State* const L_, int const idx_, char const* k_) = delete; | ||
265 | inline 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 | |||
264 | inline void luaG_setmetatable(lua_State* const L_, std::string_view const& tname_) | 272 | inline 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 | ||
54 | namespace { | ||
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 |
129 | void KeyUD::peek(KeeperState const K_, int const count_) | 131 | void 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) |
197 | void KeyUD::prepareAccess(KeeperState const K_, int const idx_) | 199 | void 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 | ||
279 | int 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 | ||
659 | int 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 |
70 | static constexpr UniqueKey kNilSentinel{ 0xC457D4EDDB05B5E4ull, "lanes.null" }; | 72 | static constexpr UniqueKey kNilSentinel{ 0xC457D4EDDB05B5E4ull, "lanes.null" }; |
71 | 73 | ||
72 | [[nodiscard]] int keeper_push_linda_storage(Linda& linda_, DestState L_); | ||
73 | |||
74 | using keeper_api_t = lua_CFunction; | 74 | using 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) | |||
823 | LUAG_FUNC(linda_towatch) | 823 | LUAG_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 | ||
45 | static constexpr char const* kOnStateCreate{ "on_state_create" }; // update lanes.lua if the name changes! | 45 | static 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); |