From a30ac3790edea8329c199c9c42ff4150cf20c8ba Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Mon, 27 May 2024 10:34:57 +0200 Subject: More string_view + improved DEBUGSPEW output --- src/compat.cpp | 3 +-- src/compat.h | 8 ++++---- src/debugspew.h | 9 +++++++-- src/intercopycontext.cpp | 24 ++++++++++++++++++++---- src/linda.cpp | 6 +++--- src/state.cpp | 45 ++++++++++++++++++++++++++++----------------- src/tools.cpp | 4 ++-- src/uniquekey.h | 4 ++-- src/universe.cpp | 2 +- 9 files changed, 68 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/compat.cpp b/src/compat.cpp index efc2ffd..66fa3d5 100644 --- a/src/compat.cpp +++ b/src/compat.cpp @@ -11,7 +11,7 @@ // ################################################################################################# // a small helper to obtain a module's table from the registry instead of relying on the presence of _G[""] -LuaType luaG_getmodule(lua_State* L_, char const* name_) +LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_) { STACK_CHECK_START_REL(L_, 0); LuaType _type{ luaG_getfield(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE) }; // L_: _R._LOADED|nil @@ -46,7 +46,6 @@ int luaL_getsubtable(lua_State* L_, int idx_, const char* fname_) return 0; /* false, because did not find table there */ } } - // ################################################################################################# void luaL_requiref(lua_State* L_, const char* modname_, lua_CFunction openf_, int glb_) diff --git a/src/compat.h b/src/compat.h index e080749..139e606 100644 --- a/src/compat.h +++ b/src/compat.h @@ -133,14 +133,14 @@ inline int lua504_dump(lua_State* L_, lua_Writer writer_, void* data_, [[maybe_u // ################################################################################################# -[[nodiscard]] inline LuaType luaG_getfield(lua_State* L_, int idx_, char const* k_) +[[nodiscard]] inline LuaType luaG_getfield(lua_State* L_, int idx_, std::string_view const& k_) { // starting with Lua 5.3, lua_getfield returns the type of the value it found #if LUA_VERSION_NUM < 503 - lua_getfield(L_, idx_, k_); + lua_getfield(L_, idx_, k_.data()); return lua_type_as_enum(L_, -1); #else // LUA_VERSION_NUM >= 503 - return static_cast(lua_getfield(L_, idx_, k_)); + return static_cast(lua_getfield(L_, idx_, k_.data())); #endif // LUA_VERSION_NUM >= 503 } @@ -243,7 +243,7 @@ inline constexpr LuaError ToLuaError(int rc_) // ################################################################################################# -LuaType luaG_getmodule(lua_State* L_, char const* name_); +LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_); // ################################################################################################# diff --git a/src/debugspew.h b/src/debugspew.h index 216f617..ccebc0a 100644 --- a/src/debugspew.h +++ b/src/debugspew.h @@ -15,7 +15,7 @@ class DebugSpewIndentScope Universe* const U{}; public: - static char const* const debugspew_indent; + static std::string_view const debugspew_indent; DebugSpewIndentScope(Universe* U_) : U{ U_ } @@ -35,12 +35,17 @@ class DebugSpewIndentScope // ################################################################################################# +inline std::string_view DebugSpewIndent(Universe const* const U_) +{ + return DebugSpewIndentScope::debugspew_indent.substr(0, static_cast(U_->debugspewIndentDepth.load(std::memory_order_relaxed))); +} + inline auto& DebugSpew(Universe const* const U_) { if (!U_) { return std::cerr; } - return std::cerr << std::string_view{ DebugSpewIndentScope::debugspew_indent, static_cast(U_->debugspewIndentDepth.load(std::memory_order_relaxed)) } << " "; + return std::cerr << DebugSpewIndent(U_) << " "; } #define DEBUGSPEW_CODE(_code) _code #define DEBUGSPEW_OR_NOT(a_, b_) a_ diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index 6684f3f..67e4e03 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp @@ -29,6 +29,7 @@ THE SOFTWARE. #include "debugspew.h" #include "deep.h" #include "keeper.h" +#include "linda.h" #include "universe.h" // ################################################################################################# @@ -263,10 +264,10 @@ void InterCopyContext::copy_func() const for (_n = 0; (_c.name = lua_getupvalue(L1, L1_i, 1 + _n)) != nullptr; ++_n) { // L1: ... _G up[n] DEBUGSPEW_CODE(DebugSpew(U) << "UPNAME[" << _n << "]: " << _c.name << " -> "); if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? - DEBUGSPEW_CODE(DebugSpew(U) << "pushing destination global scope" << std::endl); + DEBUGSPEW_CODE(DebugSpew(nullptr) << "pushing destination global scope" << std::endl); lua_pushglobaltable(L2); // L2: ... {cache} ... function } else { - DEBUGSPEW_CODE(DebugSpew(U) << "copying value" << std::endl); + DEBUGSPEW_CODE(DebugSpew(nullptr) << "copying value" << std::endl); _c.L1_i = SourceIndex{ lua_gettop(L1) }; if (!_c.inter_copy_one()) { // L2: ... {cache} ... function raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); @@ -874,13 +875,28 @@ void InterCopyContext::inter_copy_keyvaluepair() const [[nodiscard]] bool InterCopyContext::inter_copy_lightuserdata() const { void* const _p{ lua_touserdata(L1, L1_i) }; - // TODO: recognize and print known UniqueKey names here - DEBUGSPEW_CODE(DebugSpew(nullptr) << _p << std::endl); + // recognize and print known UniqueKey names here + if constexpr (USE_DEBUG_SPEW()) { + bool _found{ false }; + static constexpr std::array, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; + for (UniqueKey const& _key : kKeysToCheck) { + if (_key.equals(L1, L1_i)) { + DEBUGSPEW_CODE(DebugSpew(nullptr) << _key.debugName); + _found = true; + break; + } + } + if (!_found) { + DEBUGSPEW_CODE(DebugSpew(nullptr) << _p); + } + } // when copying a nil sentinel in a non-keeper, write a nil in the destination if (mode != LookupMode::ToKeeper && kNilSentinel.equals(L1, L1_i)) { + DEBUGSPEW_CODE(DebugSpew(nullptr) << " as nil" << std::endl); lua_pushnil(L2); } else { lua_pushlightuserdata(L2, _p); + DEBUGSPEW_CODE(DebugSpew(nullptr) << std::endl); } return true; } diff --git a/src/linda.cpp b/src/linda.cpp index 1040cd6..a5db50a 100644 --- a/src/linda.cpp +++ b/src/linda.cpp @@ -52,9 +52,9 @@ static void check_key_types(lua_State* L_, int start_, int end_) case LuaType::LIGHTUSERDATA: static constexpr std::array, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; - for (UniqueKey const& key : kKeysToCheck) { - if (key.equals(L_, _i)) { - raise_luaL_error(L_, "argument #%d: can't use %s as a key", _i, key.debugName); + for (UniqueKey const& _key : kKeysToCheck) { + if (_key.equals(L_, _i)) { + raise_luaL_error(L_, "argument #%d: can't use " STRINGVIEW_FMT " as a key", _i, _key.debugName.size(), _key.debugName.data()); break; } } diff --git a/src/state.cpp b/src/state.cpp index 73c94f0..68569bd 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -39,6 +39,8 @@ THE SOFTWARE. #include "tools.h" #include "universe.h" +#include + // ################################################################################################# /*---=== Serialize require ===--- @@ -402,27 +404,36 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) STACK_CHECK(_L, 0); // after all this, register everything we find in our name<->function database - lua_pushglobaltable(_L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack - STACK_CHECK(_L, 1); + lua_pushglobaltable(_L); // L: _G populate_func_lookup_table(_L, -1, {}); + lua_pop(_L, 1); // L: + STACK_CHECK(_L, 0); -#if 1 && USE_DEBUG_SPEW() - // dump the lookup database contents - kLookupRegKey.pushValue(_L); // L: {} - lua_pushnil(_L); // L: {} nil - while (lua_next(_L, -2)) { // L: {} k v - lua_getglobal(_L, "print"); // L: {} k v print - int const indent{ U_->debugspewIndentDepth.load(std::memory_order_relaxed) }; - lua_pushlstring(_L, DebugSpewIndentScope::debugspew_indent, indent); // L: {} k v print " " - lua_pushvalue(_L, -4); // L: {} k v print " " k - lua_pushvalue(_L, -4); // L: {} k v print " " k v - lua_call(_L, 3, 0); // L: {} k v - lua_pop(_L, 1); // L: {} k + if constexpr (USE_DEBUG_SPEW()) { + DEBUGSPEW_CODE(DebugSpew(U_) << std::source_location::current().function_name() << " LOOKUP DB CONTENTS" << std::endl); + DEBUGSPEW_CODE(DebugSpewIndentScope _scope2{ U_ }); + // dump the lookup database contents + kLookupRegKey.pushValue(_L); // L: {} + lua_pushnil(_L); // L: {} nil + while (lua_next(_L, -2)) { // L: {} k v + std::ignore = lua_pushstringview(_L, "["); // L: {} k v "[" + + lua_getglobal(_L, "tostring"); // L: {} k v "[" tostring + lua_pushvalue(_L, -4); // L: {} k v "[" tostring k + lua_call(_L, 1, 1); // L: {} k v "[" 'k' + + std::ignore = lua_pushstringview(_L, "] = "); // L: {} k v "[" 'k' "] = " + + lua_getglobal(_L, "tostring"); // L: {} k v "[" 'k' "] = " tostring + 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_) << lua_tostringview(_L, -1) << std::endl); + lua_pop(_L, 2); // L: {} k + } // lua_next() // L: {} + lua_pop(_L, 1); // L: } - lua_pop(_L, 1); // L: {} -#endif // USE_DEBUG_SPEW() - lua_pop(_L, 1); STACK_CHECK(_L, 0); return _L; } diff --git a/src/tools.cpp b/src/tools.cpp index 1d778ef..adb30b0 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -37,7 +37,7 @@ THE SOFTWARE. #include "debugspew.h" #include "universe.h" -DEBUGSPEW_CODE(char const* const DebugSpewIndentScope::debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); +DEBUGSPEW_CODE(std::string_view const DebugSpewIndentScope::debugspew_indent{ "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+" }); // xxh64 of string "kLookupCacheRegKey" generated at https://www.pelock.com/products/hash-calculator static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull }; @@ -302,7 +302,7 @@ static void populate_func_lookup_table_recur(lua_State* L_, int dbIdx_, int i_, // create a "fully.qualified.name" <-> function equivalence database void populate_func_lookup_table(lua_State* const L_, int const i_, std::string_view const& name_) { - int const _in_base = lua_absindex(L_, i_); + int const _in_base{ lua_absindex(L_, i_) }; DEBUGSPEW_CODE(Universe* _U = universe_get(L_)); std::string_view _name{ name_.empty() ? std::string_view{} : name_ }; DEBUGSPEW_CODE(DebugSpew(_U) << L_ << ": populate_func_lookup_table('" << _name << "')" << std::endl); diff --git a/src/uniquekey.h b/src/uniquekey.h index 67b3279..9981bb8 100644 --- a/src/uniquekey.h +++ b/src/uniquekey.h @@ -13,10 +13,10 @@ class UniqueKey uintptr_t const storage{ 0 }; public: - char const* debugName{ nullptr }; + std::string_view debugName{}; // --------------------------------------------------------------------------------------------- - constexpr explicit UniqueKey(uint64_t val_, char const* debugName_ = nullptr) + constexpr explicit UniqueKey(uint64_t val_, std::string_view const& debugName_ = {}) #if LUAJIT_FLAVOR() == 64 // building against LuaJIT headers for 64 bits, light userdata is restricted to 47 significant bits, because LuaJIT uses the other bits for internal optimizations : storage{ static_cast(val_ & 0x7FFFFFFFFFFFull) } #else // LUAJIT_FLAVOR() diff --git a/src/universe.cpp b/src/universe.cpp index cdb3d72..3d1645f 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -354,7 +354,7 @@ void Universe::terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTim Lane* _lane{ selfdestructFirst }; if (_lane != SELFDESTRUCT_END) { // this causes a leak because we don't call U's destructor (which could be bad if the still running lanes are accessing it) - raise_luaL_error(L_, "Zombie thread " STRINGVIEW_FMT " refuses to die!", _lane->debugName.size(), _lane->debugName.data()); + raise_luaL_error(L_, "Zombie thread '" STRINGVIEW_FMT "' refuses to die!", _lane->debugName.size(), _lane->debugName.data()); } } } -- cgit v1.2.3-55-g6feb