From 05e4cce366cccf92ad88f80695efa548fae187de Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Wed, 5 Feb 2025 12:27:02 +0100 Subject: Minor internal code tweaks * mark all eligible classes Final * new TableIndex strong type * buildfixes for HAVE_DEBUGSPEW() * overridden virtual destructors tagged as such --- src/debug.hpp | 2 +- src/debugspew.hpp | 2 +- src/intercopycontext.cpp | 2 +- src/intercopycontext.hpp | 2 +- src/keeper.cpp | 2 +- src/lane.cpp | 4 ++-- src/lane.hpp | 2 +- src/lanes.cpp | 2 +- src/linda.hpp | 4 ++-- src/lindafactory.hpp | 3 ++- src/macros_and_utils.hpp | 2 +- src/nameof.cpp | 6 +++--- src/stackindex.hpp | 5 ++++- src/state.cpp | 2 +- src/tools.cpp | 24 ++++++++++++------------ src/tools.hpp | 5 ++--- src/unique.hpp | 2 +- src/uniquekey.hpp | 2 +- src/universe.hpp | 4 ++-- 19 files changed, 40 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/debug.hpp b/src/debug.hpp index 39d106a..66541c0 100644 --- a/src/debug.hpp +++ b/src/debug.hpp @@ -30,7 +30,7 @@ inline void LUA_ASSERT_IMPL(lua_State* const L_, bool const cond_, std::string_v #define LUA_ASSERT(L_, cond_) LUA_ASSERT_IMPL(L_, (cond_) ? true : false, #cond_) #define LUA_ASSERT_CODE(code_) code_ -class StackChecker +class StackChecker final { private: lua_State* const L; diff --git a/src/debugspew.hpp b/src/debugspew.hpp index 1eb5556..88bdbcc 100644 --- a/src/debugspew.hpp +++ b/src/debugspew.hpp @@ -7,7 +7,7 @@ #if USE_DEBUG_SPEW() -class DebugSpewIndentScope +class DebugSpewIndentScope final { private: Universe* const U{}; diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index fd6b5a5..6b3d282 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp @@ -1279,7 +1279,7 @@ InterCopyResult InterCopyContext::interCopyPackage() const { DEBUGSPEW_CODE(DebugSpew(U) << "InterCopyContext::interCopyPackage()" << std::endl); - class OnExit + class OnExit final { private: lua_State* const L2; diff --git a/src/intercopycontext.hpp b/src/intercopycontext.hpp index 7008919..cc84017 100644 --- a/src/intercopycontext.hpp +++ b/src/intercopycontext.hpp @@ -25,7 +25,7 @@ enum class InterCopyResult DECLARE_UNIQUE_TYPE(CacheIndex, StackIndex); DECLARE_UNIQUE_TYPE(SourceIndex, StackIndex); -class InterCopyContext +class InterCopyContext final { public: Universe* const U; diff --git a/src/keeper.cpp b/src/keeper.cpp index 2d9d800..43f3125 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp @@ -60,7 +60,7 @@ namespace { // ################################################################################################# // the full userdata associated to a given Linda key to store its contents -class KeyUD +class KeyUD final { private: static constexpr UserValueIndex kContentsTableIndex{ 1 }; diff --git a/src/lane.cpp b/src/lane.cpp index 7664dd6..c3f2996 100644 --- a/src/lane.cpp +++ b/src/lane.cpp @@ -188,7 +188,7 @@ static LUAG_FUNC(lane_join) break; default: - DEBUGSPEW_CODE(DebugSpew(nullptr) << "Unknown Lane status: " << static_cast(_lane->status) << std::endl); + DEBUGSPEW_CODE(DebugSpew(nullptr) << "Unknown Lane status: " << static_cast(_lane->status.load(std::memory_order_relaxed)) << std::endl); LUA_ASSERT(L_, false); _ret = 0; } @@ -766,7 +766,7 @@ static void lane_main(Lane* const lane_) // in case of error and if it exists, fetch stack trace from registry and push it lane_->nresults += PushStackTrace(_L, lane_->errorTraceLevel, _rc, StackIndex{ 1 }); // L: retvals|error [trace] - DEBUGSPEW_CODE(DebugSpew(lane_->U) << "Lane " << _L << " body: " << GetErrcodeName(_rc) << " (" << (kCancelError.equals(_L, 1) ? "cancelled" : luaG_typename(_L, 1)) << ")" << std::endl); + DEBUGSPEW_CODE(DebugSpew(lane_->U) << "Lane " << _L << " body: " << GetErrcodeName(_rc) << " (" << (kCancelError.equals(_L, StackIndex{ 1 }) ? "cancelled" : luaG_typename(_L, StackIndex{ 1 })) << ")" << std::endl); // Call finalizers, if the script has set them up. // If the lane is not a coroutine, there is only a regular state, so everything is the same whether we use S or L. // If the lane is a coroutine, this has to be done from the master state (S), not the thread (L), because we can't lua_pcall in a thread state diff --git a/src/lane.hpp b/src/lane.hpp index 595bf4d..4b0acab 100644 --- a/src/lane.hpp +++ b/src/lane.hpp @@ -50,7 +50,7 @@ enum class WakeLane Yes }; -class Lane +class Lane final { public: /* diff --git a/src/lanes.cpp b/src/lanes.cpp index 87f9a90..678540d 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp @@ -286,7 +286,7 @@ LUAG_FUNC(lane_new) raise_luaL_error(L_, "could not create lane: out of memory"); } - class OnExit + class OnExit final { private: lua_State* const L; diff --git a/src/linda.hpp b/src/linda.hpp index 65bca9f..33fc504 100644 --- a/src/linda.hpp +++ b/src/linda.hpp @@ -15,11 +15,11 @@ static constexpr UniqueKey kLindaBatched{ 0xB8234DF772646567ull, "linda.batched" DECLARE_UNIQUE_TYPE(LindaGroup, int); -class Linda +class Linda final : public DeepPrelude // Deep userdata MUST start with this header { public: - class [[nodiscard]] KeeperOperationInProgress + class [[nodiscard]] KeeperOperationInProgress final { private: Linda& linda; diff --git a/src/lindafactory.hpp b/src/lindafactory.hpp index 0921c8f..814f21c 100644 --- a/src/lindafactory.hpp +++ b/src/lindafactory.hpp @@ -4,13 +4,14 @@ // ################################################################################################# -class LindaFactory +class LindaFactory final : public DeepFactory { public: // TODO: I'm not totally happy with having a 'global' variable. Maybe it should be dynamically created and stored somewhere in the universe? static LindaFactory Instance; + ~LindaFactory() override = default; LindaFactory(luaL_Reg const lindaMT_[]) : mLindaMT{ lindaMT_ } { diff --git a/src/macros_and_utils.hpp b/src/macros_and_utils.hpp index 26d47a9..16011f7 100644 --- a/src/macros_and_utils.hpp +++ b/src/macros_and_utils.hpp @@ -53,7 +53,7 @@ typename T::value_type const& OptionalValue(T const& x_, Ts... args_) struct PasskeyToken {}; constexpr PasskeyToken PK{}; template -class Passkey +class Passkey final { private: friend T; diff --git a/src/nameof.cpp b/src/nameof.cpp index 2ae315a..027c703 100644 --- a/src/nameof.cpp +++ b/src/nameof.cpp @@ -33,7 +33,7 @@ THE SOFTWARE. // Return some name helping to identify an object [[nodiscard]] -static int DiscoverObjectNameRecur(lua_State* L_, int shortest_, int depth_) +static int DiscoverObjectNameRecur(lua_State* const L_, int shortest_, TableIndex depth_) { static constexpr StackIndex kWhat{ 1 }; // the object to investigate // L_: o "r" {c} {fqn} ... {?} static constexpr StackIndex kResult{ 2 }; // where the result string is stored @@ -193,13 +193,13 @@ LUAG_FUNC(nameof) lua_rawseti(L_, -2, 1); // L_: o nil {c} {fqn} // this is where we start the search luaG_pushglobaltable(L_); // L_: o nil {c} {fqn} _G - std::ignore = DiscoverObjectNameRecur(L_, std::numeric_limits::max(), 1); + std::ignore = DiscoverObjectNameRecur(L_, std::numeric_limits::max(), TableIndex{ 1 }); if (lua_isnil(L_, 2)) { // try again with registry, just in case... lua_pop(L_, 1); // L_: o nil {c} {fqn} luaG_pushstring(L_, "_R"); // L_: o nil {c} {fqn} "_R" lua_rawseti(L_, -2, 1); // L_: o nil {c} {fqn} lua_pushvalue(L_, kIdxRegistry); // L_: o nil {c} {fqn} _R - std::ignore = DiscoverObjectNameRecur(L_, std::numeric_limits::max(), 1); + std::ignore = DiscoverObjectNameRecur(L_, std::numeric_limits::max(), TableIndex{ 1 }); } lua_pop(L_, 3); // L_: o "result" STACK_CHECK(L_, 1); diff --git a/src/stackindex.hpp b/src/stackindex.hpp index c414ce2..e7c1d8b 100644 --- a/src/stackindex.hpp +++ b/src/stackindex.hpp @@ -5,6 +5,9 @@ DECLARE_UNIQUE_TYPE(StackIndex, int); static_assert(std::is_trivial_v); +DECLARE_UNIQUE_TYPE(TableIndex, int); +static_assert(std::is_trivial_v); + DECLARE_UNIQUE_TYPE(UserValueIndex, int); static_assert(std::is_trivial_v); @@ -12,7 +15,7 @@ DECLARE_UNIQUE_TYPE(UserValueCount, int); static_assert(std::is_trivial_v); DECLARE_UNIQUE_TYPE(UnusedInt, int); -static_assert(std::is_trivial_v); +static_assert(std::is_trivial_v); // ################################################################################################# diff --git a/src/state.cpp b/src/state.cpp index 88f406a..6fabc5f 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -299,7 +299,7 @@ namespace state { lua_pushvalue(_L, -5); // L: {} k v "[" 'k' "] = " tostring v lua_call(_L, 1, 1); // L: {} k v "[" 'k' "] = " 'v' lua_concat(_L, 4); // L: {} k v "[k] = v" - DEBUGSPEW_CODE(DebugSpew(U_) << luaG_tostring(_L, -1) << std::endl); + DEBUGSPEW_CODE(DebugSpew(U_) << luaG_tostring(_L, kIdxTop) << std::endl); lua_pop(_L, 2); // L: {} k } // lua_next() // L: {} lua_pop(_L, 1); // L: diff --git a/src/tools.cpp b/src/tools.cpp index cd64d13..f3be85c 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -47,7 +47,7 @@ static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull }; static constexpr int kWriterReturnCode{ 666 }; [[nodiscard]] -static int dummy_writer([[maybe_unused]] lua_State* L_, [[maybe_unused]] void const* p_, [[maybe_unused]] size_t sz_, [[maybe_unused]] void* ud_) +static int dummy_writer([[maybe_unused]] lua_State* const L_, [[maybe_unused]] void const* p_, [[maybe_unused]] size_t sz_, [[maybe_unused]] void* ud_) { // always fail with this code return kWriterReturnCode; @@ -93,13 +93,13 @@ FuncSubType luaG_getfuncsubtype(lua_State* const L_, StackIndex const i_) namespace tools { // inspired from tconcat() in ltablib.c - std::string_view PushFQN(lua_State* const L_, StackIndex const t_, int const last_) + std::string_view PushFQN(lua_State* const L_, StackIndex const t_, TableIndex const last_) { STACK_CHECK_START_REL(L_, 0); // Lua 5.4 pushes &b as light userdata on the stack. be aware of it... luaL_Buffer _b; luaL_buffinit(L_, &_b); // L_: ... {} ... &b? - int _i{ 1 }; + TableIndex _i{ 1 }; for (; _i < last_; ++_i) { lua_rawgeti(L_, t_, _i); luaL_addvalue(&_b); @@ -127,7 +127,7 @@ namespace tools { * if we already had an entry of type [o] = ..., replace the name if the new one is shorter * pops the processed object from the stack */ -static void update_lookup_entry(lua_State* const L_, StackIndex const ctxBase_, int const depth_) +static void update_lookup_entry(lua_State* const L_, StackIndex const ctxBase_, TableIndex const depth_) { // slot 1 in the stack contains the table that receives everything we found StackIndex const _dest{ ctxBase_ }; @@ -146,7 +146,7 @@ static void update_lookup_entry(lua_State* const L_, StackIndex const ctxBase_, // push name in fqn stack (note that concatenation will crash if name is a not string or a number) lua_pushvalue(L_, -3); // L_: ... {bfc} k o name? k LUA_ASSERT(L_, luaG_type(L_, kIdxTop) == LuaType::NUMBER || luaG_type(L_, kIdxTop) == LuaType::STRING); - int const _deeper{ depth_ + 1 }; + TableIndex const _deeper{ depth_ + 1 }; lua_rawseti(L_, _fqn, _deeper); // L_: ... {bfc} k o name? // generate name std::string_view const _newName{ tools::PushFQN(L_, _fqn, _deeper) }; // L_: ... {bfc} k o name? "f.q.n" @@ -155,10 +155,10 @@ static void update_lookup_entry(lua_State* const L_, StackIndex const ctxBase_, // Also, when Lua is built with compatibility options (such as LUA_COMPAT_ALL), some base libraries register functions under multiple names. // This, with the randomizer, can cause the first generated name of an object to be different on different VMs, which breaks function transfer. // Also, nothing prevents any external module from exposing a given object under several names, so... - // Therefore, when we encounter an object for which a name was previously registered, we need to select the a single name + // Therefore, when we encounter an object for which a name was previously registered, we need to select a single name // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded if (!_prevName.empty() && ((_prevName.size() < _newName.size()) || (_prevName <= _newName))) { - DEBUGSPEW_CODE(DebugSpew(_U) << luaG_typename(L_, -3) << " '" << _newName << "' remains named '" << _prevName << "'" << std::endl); + DEBUGSPEW_CODE(DebugSpew(_U) << luaG_typename(L_, StackIndex{ -3 }) << " '" << _newName << "' remains named '" << _prevName << "'" << std::endl); // the previous name is 'smaller' than the one we just generated: keep it! lua_pop(L_, 3); // L_: ... {bfc} k } else { @@ -172,7 +172,7 @@ static void update_lookup_entry(lua_State* const L_, StackIndex const ctxBase_, } else { lua_remove(L_, -2); // L_: ... {bfc} k o "f.q.n" } - DEBUGSPEW_CODE(DebugSpew(_U) << luaG_typename(L_, -2) << " '" << _newName << "'" << std::endl); + DEBUGSPEW_CODE(DebugSpew(_U) << luaG_typename(L_, StackIndex{ -2 }) << " '" << _newName << "'" << std::endl); // prepare the stack for database feed lua_pushvalue(L_, -1); // L_: ... {bfc} k o "f.q.n" "f.q.n" lua_pushvalue(L_, -3); // L_: ... {bfc} k o "f.q.n" "f.q.n" o @@ -191,7 +191,7 @@ static void update_lookup_entry(lua_State* const L_, StackIndex const ctxBase_, // ################################################################################################# -static void populate_lookup_table_recur(lua_State* const L_, StackIndex const dbIdx_, StackIndex const i_, int const depth_) +static void populate_lookup_table_recur(lua_State* const L_, StackIndex const dbIdx_, StackIndex const i_, TableIndex const depth_) { // slot dbIdx_ contains the lookup database table // slot dbIdx_ + 1 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot i_ @@ -267,10 +267,10 @@ static void populate_lookup_table_recur(lua_State* const L_, StackIndex const db STACK_CHECK(L_, 2); } // now process the tables we encountered at that depth - int const _deeper{ depth_ + 1 }; + TableIndex const _deeper{ depth_ + 1 }; lua_pushnil(L_); // L_: ... {i_} {bfc} nil while (lua_next(L_, _breadthFirstCache) != 0) { // L_: ... {i_} {bfc} k {} - DEBUGSPEW_CODE(std::string_view const _key{ (luaG_type(L_, -2) == LuaType::STRING) ? luaG_tostring(L_, -2) : std::string_view{ "" } }); + DEBUGSPEW_CODE(std::string_view const _key{ (luaG_type(L_, StackIndex{ -2 }) == LuaType::STRING) ? luaG_tostring(L_, StackIndex{ -2 }) : std::string_view{ "" } }); DEBUGSPEW_CODE(DebugSpew(_U) << "table '"<< _key <<"'" << std::endl); DEBUGSPEW_CODE(DebugSpewIndentScope _scope2{ _U }); // un-visit this table in case we do need to process it @@ -334,7 +334,7 @@ namespace tools { lua_pop(L_, 1); // L_: } else if (luaG_type(L_, _in_base) == LuaType::TABLE) { lua_newtable(L_); // L_: {} {fqn} - int _startDepth{ 0 }; + TableIndex _startDepth{ 0 }; if (!_name.empty()) { STACK_CHECK(L_, 2); luaG_pushstring(L_, _name); // L_: {} {fqn} "name" diff --git a/src/tools.hpp b/src/tools.hpp index 77ba5d2..9a62cda 100644 --- a/src/tools.hpp +++ b/src/tools.hpp @@ -13,14 +13,13 @@ enum class LookupMode // ################################################################################################# -enum class FuncSubType +enum class [[nodiscard]] FuncSubType { Bytecode, Native, FastJIT }; -[[nodiscard]] FuncSubType luaG_getfuncsubtype(lua_State* L_, StackIndex i_); // ################################################################################################# @@ -36,6 +35,6 @@ static constexpr RegistryUniqueKey kLookupRegKey{ 0xBF1FC5CF3C6DD47Bull }; // re namespace tools { void PopulateFuncLookupTable(lua_State* L_, StackIndex i_, std::string_view const& name_); [[nodiscard]] - std::string_view PushFQN(lua_State* L_, StackIndex t_, int last_); + std::string_view PushFQN(lua_State* L_, StackIndex t_, TableIndex last_); void SerializeRequire(lua_State* L_); } // namespace tools diff --git a/src/unique.hpp b/src/unique.hpp index aec5610..06a4532 100644 --- a/src/unique.hpp +++ b/src/unique.hpp @@ -78,7 +78,7 @@ class [[nodiscard]] Unique>> using self = Unique; using type = T; using T::T; - explicit Unique(T const& b_) + constexpr explicit Unique(T const& b_) : T{ b_ } { } diff --git a/src/uniquekey.hpp b/src/uniquekey.hpp index 3006b3d..4c9eb58 100644 --- a/src/uniquekey.hpp +++ b/src/uniquekey.hpp @@ -48,7 +48,7 @@ class UniqueKey DECLARE_UNIQUE_TYPE(NArr, int); DECLARE_UNIQUE_TYPE(NRec, int); -class RegistryUniqueKey +class RegistryUniqueKey final : public UniqueKey { public: diff --git a/src/universe.hpp b/src/universe.hpp index d35172d..75604d8 100644 --- a/src/universe.hpp +++ b/src/universe.hpp @@ -16,7 +16,7 @@ class Linda; // ################################################################################################# // mutex-protected allocator for use with Lua states that share a non-threadsafe allocator -class ProtectedAllocator +class ProtectedAllocator final : public lanes::AllocatorDefinition { private: @@ -67,7 +67,7 @@ static constexpr RegistryUniqueKey kUniverseLightRegKey{ 0x48BBE9CEAB0BA04Full } // everything regarding the Lanes universe is stored in that global structure // held as a full userdata in the master Lua state that required it for the first time -class Universe +class Universe final { public: static constexpr char const* kFinally{ "finally" }; // update lanes.lua if the name changes! -- cgit v1.2.3-55-g6feb