From 149d6d6d16b10da9915e3018237405f6fe8749cf Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Fri, 14 Jun 2024 15:23:21 +0200 Subject: More char* -> std::string_view conversions --- src/compat.h | 8 +++ src/intercopycontext.cpp | 40 ++++++------- src/keeper.cpp | 142 ++++++++++++++++++++++++----------------------- src/keeper.h | 4 +- src/linda.cpp | 8 +-- 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_) // ################################################################################################# +inline void luaG_setfield(lua_State* const L_, int const idx_, char const* k_) = delete; +inline void luaG_setfield(lua_State* const L_, int const idx_, std::string_view const& k_) +{ + lua_setfield(L_, idx_, k_.data()); +} + +// ################################################################################################# + inline void luaG_setmetatable(lua_State* const L_, std::string_view const& tname_) { // 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. lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... STACK_CHECK(L1, 0); if (_fqn.empty() && !lua_istable(L1, L1_i)) { // raise an error if we try to send an unknown function (but not for tables) - _fqn = std::string_view{}; // just in case // try to discover the name of the function we want to send kLaneNameRegKey.pushValue(L1); // L1: ... v ... lane_name - char const* _from{ lua_tostring(L1, -1) }; + std::string_view const _from{ luaG_tostring(L1, -1) }; lua_pushcfunction(L1, LG_nameof); // L1: ... v ... lane_name LG_nameof lua_pushvalue(L1, L1_i); // L1: ... v ... lane_name LG_nameof t lua_call(L1, 1, 2); // L1: ... v ... lane_name "type" "name"|nil - char const* _typewhat{ (luaG_type(L1, -2) == LuaType::STRING) ? lua_tostring(L1, -2) : luaL_typename(L1, -2) }; + std::string_view const _typewhat{ (luaG_type(L1, -2) == LuaType::STRING) ? luaG_tostring(L1, -2) : luaG_typename(L1, -2) }; // second return value can be nil if the table was not found // probable reason: the function was removed from the source Lua state before Lanes was required. - char const *_what, *_gotchaA, *_gotchaB; + std::string_view _what, _gotchaA, _gotchaB; if (lua_isnil(L1, -1)) { _gotchaA = " referenced by"; _gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)"; @@ -124,9 +123,9 @@ THE SOFTWARE. } else { _gotchaA = ""; _gotchaB = ""; - _what = (luaG_type(L1, -1) == LuaType::STRING) ? lua_tostring(L1, -1) : luaL_typename(L1, -1); + _what = (luaG_type(L1, -1) == LuaType::STRING) ? luaG_tostring(L1, -1) : luaG_typename(L1, -1); } - raise_luaL_error(L1, "%s%s '%s' not found in %s origin transfer database.%s", _typewhat, _gotchaA, _what, _from ? _from : "main", _gotchaB); + 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()); } STACK_CHECK(L1, 0); return _fqn; @@ -283,12 +282,9 @@ void InterCopyContext::copyFunction() const // Set upvalues (originally set to 'nil' by 'lua_load') for (int const _func_index{ lua_gettop(L2) - _n }; _n > 0; --_n) { - [[maybe_unused]] char const* _upname{ lua_setupvalue(L2, _func_index, _n) }; // L2: ... {cache} ... function - // - // "assigns the value at the top of the stack to the upvalue and returns its name. - // It also pops the value from the stack." - - LUA_ASSERT(L1, _upname); // not having enough slots? + // assign upvalue, popping it from the stack + [[maybe_unused]] std::string_view const _upname{ lua_setupvalue(L2, _func_index, _n) };// L2: ... {cache} ... function + LUA_ASSERT(L1, !_upname.empty()); // not having enough slots? } // once all upvalues have been set we are left // with the function at the top of the stack // L2: ... {cache} ... function @@ -328,19 +324,19 @@ void InterCopyContext::lookupNativeFunction() const // anything other than function or table should not happen! if (!lua_isfunction(L2, -1) && !lua_istable(L2, -1)) { kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name - char const* const _from{ lua_tostring(L1, -1) }; + std::string_view const _from{ luaG_tostring(L1, -1) }; lua_pop(L1, 1); // L1: ... f ... kLaneNameRegKey.pushValue(L2); // L1: ... f ... L2: {} f lane_name - char const* const _to{ lua_tostring(L2, -1) }; + std::string_view const _to{ luaG_tostring(L2, -1) }; lua_pop(L2, 1); // L2: {} f // 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 raise_luaL_error( getErrL(), "%s%s: function '%s' not found in %s destination transfer database.", lua_isnil(L2, -1) ? "" : "INTERNAL ERROR IN ", - _from ? _from : "main", + _from.empty() ? "main" : _from.data(), _fqn.data(), - _to ? _to : "main"); + _to.empty() ? "main" : _to.data()); return; } lua_remove(L2, -2); // L2: f @@ -452,18 +448,18 @@ void InterCopyContext::copyCachedFunction() const return false; } 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 kLaneNameRegKey.pushValue(L1); // L1: ... t ... lane_name - char const* _from{ lua_tostring(L1, -1) }; + std::string_view const _from{ luaG_tostring(L1, -1) }; lua_pop(L1, 1); // L1: ... t ... kLaneNameRegKey.pushValue(L2); // L1: ... t ... L2: {} t lane_name - char const* _to{ lua_tostring(L2, -1) }; + std::string_view const _to{ luaG_tostring(L2, -1) }; lua_pop(L2, 1); // L1: ... t ... L2: {} t raise_luaL_error( getErrL(), "%s: source table '%s' found as %s in %s destination transfer database.", - _from ? _from : "main", - _fqn, + _from.empty() ? "main" : _from.data(), + _fqn.data(), luaG_typename(L2, -1).data(), - _to ? _to : "main"); + _to.empty() ? "main" : _to.data()); } lua_remove(L2, -2); // L1: ... t ... L2: t break; @@ -1260,7 +1256,7 @@ namespace { STACK_CHECK(L1, 0); } if (_result == InterCopyResult::Success) { - lua_setfield(L2, -2, _entry.data()); // set package[entry] + luaG_setfield(L2, -2, _entry); // set package[entry] } else { std::string_view const _msg{ luaG_pushstring(L1, "failed to copy package.%s", _entry.data()) }; // 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 @@ // where key is a key used in the Lua Linda API to exchange data, and KeyUD is a full userdata with a table uservalue // the table uservalue is the actual fifo, where elements are added and removed. +namespace { + // ################################################################################################# // ################################################################################################# // ############################################ KeyUD ############################################## @@ -77,10 +79,10 @@ class KeyUD [[nodiscard]] bool changeLimit(int limit_); [[nodiscard]] static KeyUD* Create(KeeperState K_); [[nodiscard]] static KeyUD* GetPtr(KeeperState K_, int idx_); - void peek(KeeperState K_, int count_); - [[nodiscard]] int pop(KeeperState K_, int minCount_, int maxCount_); - void prepareAccess(KeeperState K_, int idx_); - [[nodiscard]] bool push(KeeperState K_, int count_); + void peek(KeeperState K_, int count_) const; // keepercall_get + [[nodiscard]] int pop(KeeperState K_, int minCount_, int maxCount_); // keepercall_receive[_batched] + void prepareAccess(KeeperState K_, int idx_) const; + [[nodiscard]] bool push(KeeperState K_, int count_); // keepercall_send [[nodiscard]] bool reset(KeeperState K_); }; @@ -126,7 +128,7 @@ KeyUD* KeyUD::GetPtr(KeeperState const K_, int idx_) // out: bool ... // pops the fifo, push bool + as much data as is available (up to the specified count) without consuming it // bool is true if the requested count was served, else false -void KeyUD::peek(KeeperState const K_, int const count_) +void KeyUD::peek(KeeperState const K_, int const count_) const { STACK_CHECK_START_ABS(K_, 1); 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_) // expects 'this' at the specified index // replaces it by its uservalue on the stack (the table holding the fifo values) -void KeyUD::prepareAccess(KeeperState const K_, int const idx_) +void KeyUD::prepareAccess(KeeperState const K_, int const idx_) const { int const _idx{ luaG_absindex(K_, idx_) }; LUA_ASSERT(K_, KeyUD::GetPtr(K_, idx_) == this); @@ -273,68 +275,7 @@ static void PushKeysDB(KeeperState const K_, int const idx_) STACK_CHECK(K_, 1); } -// ################################################################################################# - -// only used by linda:dump() and linda:__towatch() for debugging purposes -int keeper_push_linda_storage(Linda& linda_, DestState L_) -{ - Keeper* const _keeper{ linda_.whichKeeper() }; - KeeperState const _K{ _keeper ? _keeper->K : nullptr }; - if (_K == nullptr) { - return 0; - } - STACK_GROW(_K, 4); - STACK_CHECK_START_REL(_K, 0); - kLindasRegKey.pushValue(_K); // _K: LindasDB L_: - lua_pushlightuserdata(_K, &linda_); // _K: LindasDB linda L_: - lua_rawget(_K, -2); // _K: LindasDB KeysDB L_: - lua_remove(_K, -2); // _K: KeysDB L_: - if (!lua_istable(_K, -1)) { // possible if we didn't send anything through that linda - lua_pop(_K, 1); // _K: L_: - STACK_CHECK(_K, 0); - return 0; - } - // move data from keeper to destination state - STACK_GROW(L_, 5); - STACK_CHECK_START_REL(L_, 0); - lua_newtable(L_); // _K: KeysDB L_: out - InterCopyContext _c{ linda_.U, L_, SourceState{ _K }, {}, {}, {}, LookupMode::FromKeeper, {} }; - lua_pushnil(_K); // _K: KeysDB nil L_: out - while (lua_next(_K, -2)) { // _K: KeysDB key KeyUD L_: out - KeyUD* const _key{ KeyUD::GetPtr(_K, -1) }; - _key->prepareAccess(_K, -1); // _K: KeysDB key fifo L_: out - lua_pushvalue(_K, -2); // _K: KeysDB key fifo key L_: out - if (_c.interMove(1) != InterCopyResult::Success) { // _K: KeysDB key fifo L_: out key - raise_luaL_error(L_, "Internal error reading Keeper contents"); - } - STACK_CHECK(L_, 2); - lua_newtable(L_); // _K: KeysDB key fifo L_: out key keyout - if (_c.interMove(1) != InterCopyResult::Success) { // _K: KeysDB key L_: out key keyout fifo - raise_luaL_error(L_, "Internal error reading Keeper contents"); - } - // keyout.first - lua_pushinteger(L_, _key->first); // _K: KeysDB key L_: out key keyout fifo first - STACK_CHECK(L_, 5); - lua_setfield(L_, -3, "first"); // _K: KeysDB key L_: out key keyout fifo - // keyout.count - lua_pushinteger(L_, _key->count); // _K: KeysDB key L_: out key keyout fifo count - STACK_CHECK(L_, 5); - lua_setfield(L_, -3, "count"); // _K: KeysDB key L_: out key keyout fifo - // keyout.limit - lua_pushinteger(L_, _key->limit); // _K: KeysDB key L_: out key keyout fifo limit - STACK_CHECK(L_, 5); - lua_setfield(L_, -3, "limit"); // _K: KeysDB key L_: out key keyout fifo - // keyout.fifo - lua_setfield(L_, -2, "fifo"); // _K: KeysDB key L_: out key keyout - // out[key] = keyout - lua_rawset(L_, -3); // _K: KeysDB key L_: out - STACK_CHECK(L_, 1); - } // _K: KeysDB L_: out - STACK_CHECK(L_, 1); - lua_pop(_K, 1); // _K: L_: out - STACK_CHECK(_K, 0); - return 1; -} +} // namespace // ################################################################################################# // ################################################################################################# @@ -437,7 +378,7 @@ int keepercall_get(lua_State* const L_) lua_replace(_K, 1); // _K: KeysDB key lua_rawget(_K, 1); // _K: KeysDB KeyUD lua_remove(_K, 1); // _K: KeyUD - KeyUD* const _key{ KeyUD::GetPtr(_K, -1) }; + KeyUD const* const _key{ KeyUD::GetPtr(_K, -1) }; if (_key != nullptr) { _key->peek(_K, _count); // _K: N val... } else { @@ -712,6 +653,69 @@ void Keeper::operator delete[](void* p_, Universe* U_) U_->internalAllocator.free(p_, *static_cast(p_) * sizeof(Keeper) + sizeof(size_t)); } +// ################################################################################################# + +// only used by linda:dump() and linda:__towatch() for debugging purposes +int Keeper::PushLindaStorage(Linda& linda_, DestState const L_) +{ + Keeper* const _keeper{ linda_.whichKeeper() }; + KeeperState const _K{ _keeper ? _keeper->K : nullptr }; + if (_K == nullptr) { + return 0; + } + STACK_GROW(_K, 4); + STACK_CHECK_START_REL(_K, 0); + kLindasRegKey.pushValue(_K); // _K: LindasDB L_: + lua_pushlightuserdata(_K, &linda_); // _K: LindasDB linda L_: + lua_rawget(_K, -2); // _K: LindasDB KeysDB L_: + lua_remove(_K, -2); // _K: KeysDB L_: + if (!lua_istable(_K, -1)) { // possible if we didn't send anything through that linda + lua_pop(_K, 1); // _K: L_: + STACK_CHECK(_K, 0); + return 0; + } + // move data from keeper to destination state + STACK_GROW(L_, 5); + STACK_CHECK_START_REL(L_, 0); + lua_newtable(L_); // _K: KeysDB L_: out + InterCopyContext _c{ linda_.U, L_, SourceState{ _K }, {}, {}, {}, LookupMode::FromKeeper, {} }; + lua_pushnil(_K); // _K: KeysDB nil L_: out + while (lua_next(_K, -2)) { // _K: KeysDB key KeyUD L_: out + KeyUD* const _key{ KeyUD::GetPtr(_K, -1) }; + _key->prepareAccess(_K, -1); // _K: KeysDB key fifo L_: out + lua_pushvalue(_K, -2); // _K: KeysDB key fifo key L_: out + if (_c.interMove(1) != InterCopyResult::Success) { // _K: KeysDB key fifo L_: out key + raise_luaL_error(L_, "Internal error reading Keeper contents"); + } + STACK_CHECK(L_, 2); + lua_newtable(L_); // _K: KeysDB key fifo L_: out key keyout + if (_c.interMove(1) != InterCopyResult::Success) { // _K: KeysDB key L_: out key keyout fifo + raise_luaL_error(L_, "Internal error reading Keeper contents"); + } + // keyout.first + lua_pushinteger(L_, _key->first); // _K: KeysDB key L_: out key keyout fifo first + STACK_CHECK(L_, 5); + lua_setfield(L_, -3, "first"); // _K: KeysDB key L_: out key keyout fifo + // keyout.count + lua_pushinteger(L_, _key->count); // _K: KeysDB key L_: out key keyout fifo count + STACK_CHECK(L_, 5); + lua_setfield(L_, -3, "count"); // _K: KeysDB key L_: out key keyout fifo + // keyout.limit + lua_pushinteger(L_, _key->limit); // _K: KeysDB key L_: out key keyout fifo limit + STACK_CHECK(L_, 5); + lua_setfield(L_, -3, "limit"); // _K: KeysDB key L_: out key keyout fifo + // keyout.fifo + lua_setfield(L_, -2, "fifo"); // _K: KeysDB key L_: out key keyout + // out[key] = keyout + lua_rawset(L_, -3); // _K: KeysDB key L_: out + STACK_CHECK(L_, 1); + } // _K: KeysDB L_: out + STACK_CHECK(L_, 1); + lua_pop(_K, 1); // _K: L_: out + STACK_CHECK(_K, 0); + return 1; +} + // ################################################################################################# // ################################################################################################# // ########################################## Keepers ############################################## 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 Keeper(Keeper const&&) = delete; Keeper& operator=(Keeper const&) = delete; Keeper& operator=(Keeper const&&) = delete; + + [[nodiscard]] static int PushLindaStorage(Linda& linda_, DestState L_); }; // ################################################################################################# @@ -69,8 +71,6 @@ struct Keepers // xxh64 of string "kNilSentinel" generated at https://www.pelock.com/products/hash-calculator static constexpr UniqueKey kNilSentinel{ 0xC457D4EDDB05B5E4ull, "lanes.null" }; -[[nodiscard]] int keeper_push_linda_storage(Linda& linda_, DestState L_); - using keeper_api_t = lua_CFunction; #define KEEPER_API(_op) keepercall_##_op 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 } if (std::holds_alternative(nameVariant)) { char const* const _name{ std::get(nameVariant).data() }; - return std::string_view{ _name, strlen(_name) }; + return std::string_view{ _name }; } return std::string_view{}; } @@ -385,7 +385,7 @@ LUAG_FUNC(linda_dump) { auto _dump = [](lua_State* L_) { Linda* const _linda{ ToLinda(L_, 1) }; - return keeper_push_linda_storage(*_linda, DestState{ L_ }); + return Keeper::PushLindaStorage(*_linda, DestState{ L_ }); }; return Linda::ProtectedCall(L_, _dump); } @@ -777,9 +777,9 @@ LUAG_FUNC(linda_set) // make sure the key is of a valid type (throws an error if not the case) check_key_types(L_, 2, 2); - Keeper* const _keeper{ _linda->whichKeeper() }; KeeperCallResult _pushed; if (_linda->cancelRequest == CancelRequest::None) { + Keeper* const _keeper{ _linda->whichKeeper() }; _pushed = keeper_call(_keeper->K, KEEPER_API(set), L_, _linda, 2); if (_pushed.has_value()) { // no error? LUA_ASSERT(L_, _pushed.value() == 1 && luaG_type(L_, -1) == LuaType::BOOLEAN); @@ -823,7 +823,7 @@ LUAG_FUNC(linda_tostring) LUAG_FUNC(linda_towatch) { Linda* const _linda{ ToLinda(L_, 1) }; - int _pushed{ keeper_push_linda_storage(*_linda, DestState{ L_ }) }; + int _pushed{ Keeper::PushLindaStorage(*_linda, DestState{ L_ }) }; if (_pushed == 0) { // if the linda is empty, don't return nil _pushed = LindaToString(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. // ################################################################################################# -static constexpr char const* kOnStateCreate{ "on_state_create" }; // update lanes.lua if the name changes! +static constexpr std::string_view kOnStateCreate{ "on_state_create" }; // update lanes.lua if the name changes! // ################################################################################################# // ################################################################################################# @@ -185,7 +185,7 @@ namespace state { std::string_view const _stateType{ mode_ == LookupMode::LaneBody ? "lane" : "keeper" }; std::ignore = luaG_pushstring(L_, _stateType); // L_: on_state_create() "" if (lua_pcall(L_, 1, 0, 0) != LUA_OK) { - raise_luaL_error(from_, "%s failed: \"%s\"", kOnStateCreate, lua_isstring(L_, -1) ? lua_tostring(L_, -1) : luaG_typename(L_, -1).data()); + raise_luaL_error(from_, "%s failed: \"%s\"", kOnStateCreate.data(), lua_isstring(L_, -1) ? luaG_tostring(L_, -1).data() : luaG_typename(L_, -1).data()); } STACK_CHECK(L_, 0); } @@ -235,12 +235,12 @@ namespace state { // make sure the function doesn't have upvalues char const* _upname{ lua_getupvalue(L_, -1, 1) }; // L_: settings on_state_create upval? if (_upname != nullptr) { // should be "" for C functions with upvalues if any - raise_luaL_error(L_, "%s shouldn't have upvalues", kOnStateCreate); + raise_luaL_error(L_, "%s shouldn't have upvalues", kOnStateCreate.data()); } // remove this C function from the config table so that it doesn't cause problems // when we transfer the config table in newly created Lua states lua_pushnil(L_); // L_: settings on_state_create nil - lua_setfield(L_, -3, kOnStateCreate); // L_: settings on_state_create + luaG_setfield(L_, -3, kOnStateCreate); // L_: settings on_state_create } else { // optim: store marker saying we have such a function in the config table U_->onStateCreateFunc = reinterpret_cast(InitializeOnStateCreate); -- cgit v1.2.3-55-g6feb