diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-27 10:34:57 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-27 10:34:57 +0200 |
commit | a30ac3790edea8329c199c9c42ff4150cf20c8ba (patch) | |
tree | aea060cc17ac6783389e2561e81b3b74c74ab6ad /src | |
parent | 96be015111e2d4b05ae8cb9496b752472e8578a9 (diff) | |
download | lanes-a30ac3790edea8329c199c9c42ff4150cf20c8ba.tar.gz lanes-a30ac3790edea8329c199c9c42ff4150cf20c8ba.tar.bz2 lanes-a30ac3790edea8329c199c9c42ff4150cf20c8ba.zip |
More string_view + improved DEBUGSPEW output
Diffstat (limited to 'src')
-rw-r--r-- | src/compat.cpp | 3 | ||||
-rw-r--r-- | src/compat.h | 8 | ||||
-rw-r--r-- | src/debugspew.h | 9 | ||||
-rw-r--r-- | src/intercopycontext.cpp | 24 | ||||
-rw-r--r-- | src/linda.cpp | 6 | ||||
-rw-r--r-- | src/state.cpp | 45 | ||||
-rw-r--r-- | src/tools.cpp | 4 | ||||
-rw-r--r-- | src/uniquekey.h | 4 | ||||
-rw-r--r-- | src/universe.cpp | 2 |
9 files changed, 68 insertions, 37 deletions
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 @@ | |||
11 | // ################################################################################################# | 11 | // ################################################################################################# |
12 | 12 | ||
13 | // a small helper to obtain a module's table from the registry instead of relying on the presence of _G["<name>"] | 13 | // a small helper to obtain a module's table from the registry instead of relying on the presence of _G["<name>"] |
14 | LuaType luaG_getmodule(lua_State* L_, char const* name_) | 14 | LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_) |
15 | { | 15 | { |
16 | STACK_CHECK_START_REL(L_, 0); | 16 | STACK_CHECK_START_REL(L_, 0); |
17 | LuaType _type{ luaG_getfield(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE) }; // L_: _R._LOADED|nil | 17 | 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_) | |||
46 | return 0; /* false, because did not find table there */ | 46 | return 0; /* false, because did not find table there */ |
47 | } | 47 | } |
48 | } | 48 | } |
49 | |||
50 | // ################################################################################################# | 49 | // ################################################################################################# |
51 | 50 | ||
52 | void luaL_requiref(lua_State* L_, const char* modname_, lua_CFunction openf_, int glb_) | 51 | 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 | |||
133 | 133 | ||
134 | // ################################################################################################# | 134 | // ################################################################################################# |
135 | 135 | ||
136 | [[nodiscard]] inline LuaType luaG_getfield(lua_State* L_, int idx_, char const* k_) | 136 | [[nodiscard]] inline LuaType luaG_getfield(lua_State* L_, int idx_, std::string_view const& k_) |
137 | { | 137 | { |
138 | // starting with Lua 5.3, lua_getfield returns the type of the value it found | 138 | // starting with Lua 5.3, lua_getfield returns the type of the value it found |
139 | #if LUA_VERSION_NUM < 503 | 139 | #if LUA_VERSION_NUM < 503 |
140 | lua_getfield(L_, idx_, k_); | 140 | lua_getfield(L_, idx_, k_.data()); |
141 | return lua_type_as_enum(L_, -1); | 141 | return lua_type_as_enum(L_, -1); |
142 | #else // LUA_VERSION_NUM >= 503 | 142 | #else // LUA_VERSION_NUM >= 503 |
143 | return static_cast<LuaType>(lua_getfield(L_, idx_, k_)); | 143 | return static_cast<LuaType>(lua_getfield(L_, idx_, k_.data())); |
144 | #endif // LUA_VERSION_NUM >= 503 | 144 | #endif // LUA_VERSION_NUM >= 503 |
145 | } | 145 | } |
146 | 146 | ||
@@ -243,7 +243,7 @@ inline constexpr LuaError ToLuaError(int rc_) | |||
243 | 243 | ||
244 | // ################################################################################################# | 244 | // ################################################################################################# |
245 | 245 | ||
246 | LuaType luaG_getmodule(lua_State* L_, char const* name_); | 246 | LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_); |
247 | 247 | ||
248 | // ################################################################################################# | 248 | // ################################################################################################# |
249 | 249 | ||
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 | |||
15 | Universe* const U{}; | 15 | Universe* const U{}; |
16 | 16 | ||
17 | public: | 17 | public: |
18 | static char const* const debugspew_indent; | 18 | static std::string_view const debugspew_indent; |
19 | 19 | ||
20 | DebugSpewIndentScope(Universe* U_) | 20 | DebugSpewIndentScope(Universe* U_) |
21 | : U{ U_ } | 21 | : U{ U_ } |
@@ -35,12 +35,17 @@ class DebugSpewIndentScope | |||
35 | 35 | ||
36 | // ################################################################################################# | 36 | // ################################################################################################# |
37 | 37 | ||
38 | inline std::string_view DebugSpewIndent(Universe const* const U_) | ||
39 | { | ||
40 | return DebugSpewIndentScope::debugspew_indent.substr(0, static_cast<size_t>(U_->debugspewIndentDepth.load(std::memory_order_relaxed))); | ||
41 | } | ||
42 | |||
38 | inline auto& DebugSpew(Universe const* const U_) | 43 | inline auto& DebugSpew(Universe const* const U_) |
39 | { | 44 | { |
40 | if (!U_) { | 45 | if (!U_) { |
41 | return std::cerr; | 46 | return std::cerr; |
42 | } | 47 | } |
43 | return std::cerr << std::string_view{ DebugSpewIndentScope::debugspew_indent, static_cast<size_t>(U_->debugspewIndentDepth.load(std::memory_order_relaxed)) } << " "; | 48 | return std::cerr << DebugSpewIndent(U_) << " "; |
44 | } | 49 | } |
45 | #define DEBUGSPEW_CODE(_code) _code | 50 | #define DEBUGSPEW_CODE(_code) _code |
46 | #define DEBUGSPEW_OR_NOT(a_, b_) a_ | 51 | #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. | |||
29 | #include "debugspew.h" | 29 | #include "debugspew.h" |
30 | #include "deep.h" | 30 | #include "deep.h" |
31 | #include "keeper.h" | 31 | #include "keeper.h" |
32 | #include "linda.h" | ||
32 | #include "universe.h" | 33 | #include "universe.h" |
33 | 34 | ||
34 | // ################################################################################################# | 35 | // ################################################################################################# |
@@ -263,10 +264,10 @@ void InterCopyContext::copy_func() const | |||
263 | for (_n = 0; (_c.name = lua_getupvalue(L1, L1_i, 1 + _n)) != nullptr; ++_n) { // L1: ... _G up[n] | 264 | for (_n = 0; (_c.name = lua_getupvalue(L1, L1_i, 1 + _n)) != nullptr; ++_n) { // L1: ... _G up[n] |
264 | DEBUGSPEW_CODE(DebugSpew(U) << "UPNAME[" << _n << "]: " << _c.name << " -> "); | 265 | DEBUGSPEW_CODE(DebugSpew(U) << "UPNAME[" << _n << "]: " << _c.name << " -> "); |
265 | if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? | 266 | if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? |
266 | DEBUGSPEW_CODE(DebugSpew(U) << "pushing destination global scope" << std::endl); | 267 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "pushing destination global scope" << std::endl); |
267 | lua_pushglobaltable(L2); // L2: ... {cache} ... function <upvalues> | 268 | lua_pushglobaltable(L2); // L2: ... {cache} ... function <upvalues> |
268 | } else { | 269 | } else { |
269 | DEBUGSPEW_CODE(DebugSpew(U) << "copying value" << std::endl); | 270 | DEBUGSPEW_CODE(DebugSpew(nullptr) << "copying value" << std::endl); |
270 | _c.L1_i = SourceIndex{ lua_gettop(L1) }; | 271 | _c.L1_i = SourceIndex{ lua_gettop(L1) }; |
271 | if (!_c.inter_copy_one()) { // L2: ... {cache} ... function <upvalues> | 272 | if (!_c.inter_copy_one()) { // L2: ... {cache} ... function <upvalues> |
272 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); | 273 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); |
@@ -874,13 +875,28 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
874 | [[nodiscard]] bool InterCopyContext::inter_copy_lightuserdata() const | 875 | [[nodiscard]] bool InterCopyContext::inter_copy_lightuserdata() const |
875 | { | 876 | { |
876 | void* const _p{ lua_touserdata(L1, L1_i) }; | 877 | void* const _p{ lua_touserdata(L1, L1_i) }; |
877 | // TODO: recognize and print known UniqueKey names here | 878 | // recognize and print known UniqueKey names here |
878 | DEBUGSPEW_CODE(DebugSpew(nullptr) << _p << std::endl); | 879 | if constexpr (USE_DEBUG_SPEW()) { |
880 | bool _found{ false }; | ||
881 | static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; | ||
882 | for (UniqueKey const& _key : kKeysToCheck) { | ||
883 | if (_key.equals(L1, L1_i)) { | ||
884 | DEBUGSPEW_CODE(DebugSpew(nullptr) << _key.debugName); | ||
885 | _found = true; | ||
886 | break; | ||
887 | } | ||
888 | } | ||
889 | if (!_found) { | ||
890 | DEBUGSPEW_CODE(DebugSpew(nullptr) << _p); | ||
891 | } | ||
892 | } | ||
879 | // when copying a nil sentinel in a non-keeper, write a nil in the destination | 893 | // when copying a nil sentinel in a non-keeper, write a nil in the destination |
880 | if (mode != LookupMode::ToKeeper && kNilSentinel.equals(L1, L1_i)) { | 894 | if (mode != LookupMode::ToKeeper && kNilSentinel.equals(L1, L1_i)) { |
895 | DEBUGSPEW_CODE(DebugSpew(nullptr) << " as nil" << std::endl); | ||
881 | lua_pushnil(L2); | 896 | lua_pushnil(L2); |
882 | } else { | 897 | } else { |
883 | lua_pushlightuserdata(L2, _p); | 898 | lua_pushlightuserdata(L2, _p); |
899 | DEBUGSPEW_CODE(DebugSpew(nullptr) << std::endl); | ||
884 | } | 900 | } |
885 | return true; | 901 | return true; |
886 | } | 902 | } |
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_) | |||
52 | 52 | ||
53 | case LuaType::LIGHTUSERDATA: | 53 | case LuaType::LIGHTUSERDATA: |
54 | static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; | 54 | static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; |
55 | for (UniqueKey const& key : kKeysToCheck) { | 55 | for (UniqueKey const& _key : kKeysToCheck) { |
56 | if (key.equals(L_, _i)) { | 56 | if (_key.equals(L_, _i)) { |
57 | raise_luaL_error(L_, "argument #%d: can't use %s as a key", _i, key.debugName); | 57 | raise_luaL_error(L_, "argument #%d: can't use " STRINGVIEW_FMT " as a key", _i, _key.debugName.size(), _key.debugName.data()); |
58 | break; | 58 | break; |
59 | } | 59 | } |
60 | } | 60 | } |
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. | |||
39 | #include "tools.h" | 39 | #include "tools.h" |
40 | #include "universe.h" | 40 | #include "universe.h" |
41 | 41 | ||
42 | #include <source_location> | ||
43 | |||
42 | // ################################################################################################# | 44 | // ################################################################################################# |
43 | 45 | ||
44 | /*---=== Serialize require ===--- | 46 | /*---=== Serialize require ===--- |
@@ -402,27 +404,36 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) | |||
402 | 404 | ||
403 | STACK_CHECK(_L, 0); | 405 | STACK_CHECK(_L, 0); |
404 | // after all this, register everything we find in our name<->function database | 406 | // after all this, register everything we find in our name<->function database |
405 | lua_pushglobaltable(_L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack | 407 | lua_pushglobaltable(_L); // L: _G |
406 | STACK_CHECK(_L, 1); | ||
407 | populate_func_lookup_table(_L, -1, {}); | 408 | populate_func_lookup_table(_L, -1, {}); |
409 | lua_pop(_L, 1); // L: | ||
410 | STACK_CHECK(_L, 0); | ||
408 | 411 | ||
409 | #if 1 && USE_DEBUG_SPEW() | 412 | if constexpr (USE_DEBUG_SPEW()) { |
410 | // dump the lookup database contents | 413 | DEBUGSPEW_CODE(DebugSpew(U_) << std::source_location::current().function_name() << " LOOKUP DB CONTENTS" << std::endl); |
411 | kLookupRegKey.pushValue(_L); // L: {} | 414 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope2{ U_ }); |
412 | lua_pushnil(_L); // L: {} nil | 415 | // dump the lookup database contents |
413 | while (lua_next(_L, -2)) { // L: {} k v | 416 | kLookupRegKey.pushValue(_L); // L: {} |
414 | lua_getglobal(_L, "print"); // L: {} k v print | 417 | lua_pushnil(_L); // L: {} nil |
415 | int const indent{ U_->debugspewIndentDepth.load(std::memory_order_relaxed) }; | 418 | while (lua_next(_L, -2)) { // L: {} k v |
416 | lua_pushlstring(_L, DebugSpewIndentScope::debugspew_indent, indent); // L: {} k v print " " | 419 | std::ignore = lua_pushstringview(_L, "["); // L: {} k v "[" |
417 | lua_pushvalue(_L, -4); // L: {} k v print " " k | 420 | |
418 | lua_pushvalue(_L, -4); // L: {} k v print " " k v | 421 | lua_getglobal(_L, "tostring"); // L: {} k v "[" tostring |
419 | lua_call(_L, 3, 0); // L: {} k v | 422 | lua_pushvalue(_L, -4); // L: {} k v "[" tostring k |
420 | lua_pop(_L, 1); // L: {} k | 423 | lua_call(_L, 1, 1); // L: {} k v "[" 'k' |
424 | |||
425 | std::ignore = lua_pushstringview(_L, "] = "); // L: {} k v "[" 'k' "] = " | ||
426 | |||
427 | lua_getglobal(_L, "tostring"); // L: {} k v "[" 'k' "] = " tostring | ||
428 | lua_pushvalue(_L, -5); // L: {} k v "[" 'k' "] = " tostring v | ||
429 | lua_call(_L, 1, 1); // L: {} k v "[" 'k' "] = " 'v' | ||
430 | lua_concat(_L, 4); // L: {} k v "[k] = v" | ||
431 | DEBUGSPEW_CODE(DebugSpew(U_) << lua_tostringview(_L, -1) << std::endl); | ||
432 | lua_pop(_L, 2); // L: {} k | ||
433 | } // lua_next() // L: {} | ||
434 | lua_pop(_L, 1); // L: | ||
421 | } | 435 | } |
422 | lua_pop(_L, 1); // L: {} | ||
423 | #endif // USE_DEBUG_SPEW() | ||
424 | 436 | ||
425 | lua_pop(_L, 1); | ||
426 | STACK_CHECK(_L, 0); | 437 | STACK_CHECK(_L, 0); |
427 | return _L; | 438 | return _L; |
428 | } | 439 | } |
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. | |||
37 | #include "debugspew.h" | 37 | #include "debugspew.h" |
38 | #include "universe.h" | 38 | #include "universe.h" |
39 | 39 | ||
40 | DEBUGSPEW_CODE(char const* const DebugSpewIndentScope::debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); | 40 | DEBUGSPEW_CODE(std::string_view const DebugSpewIndentScope::debugspew_indent{ "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+" }); |
41 | 41 | ||
42 | // xxh64 of string "kLookupCacheRegKey" generated at https://www.pelock.com/products/hash-calculator | 42 | // xxh64 of string "kLookupCacheRegKey" generated at https://www.pelock.com/products/hash-calculator |
43 | static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull }; | 43 | static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull }; |
@@ -302,7 +302,7 @@ static void populate_func_lookup_table_recur(lua_State* L_, int dbIdx_, int i_, | |||
302 | // create a "fully.qualified.name" <-> function equivalence database | 302 | // create a "fully.qualified.name" <-> function equivalence database |
303 | void populate_func_lookup_table(lua_State* const L_, int const i_, std::string_view const& name_) | 303 | void populate_func_lookup_table(lua_State* const L_, int const i_, std::string_view const& name_) |
304 | { | 304 | { |
305 | int const _in_base = lua_absindex(L_, i_); | 305 | int const _in_base{ lua_absindex(L_, i_) }; |
306 | DEBUGSPEW_CODE(Universe* _U = universe_get(L_)); | 306 | DEBUGSPEW_CODE(Universe* _U = universe_get(L_)); |
307 | std::string_view _name{ name_.empty() ? std::string_view{} : name_ }; | 307 | std::string_view _name{ name_.empty() ? std::string_view{} : name_ }; |
308 | DEBUGSPEW_CODE(DebugSpew(_U) << L_ << ": populate_func_lookup_table('" << _name << "')" << std::endl); | 308 | 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 | |||
13 | uintptr_t const storage{ 0 }; | 13 | uintptr_t const storage{ 0 }; |
14 | 14 | ||
15 | public: | 15 | public: |
16 | char const* debugName{ nullptr }; | 16 | std::string_view debugName{}; |
17 | 17 | ||
18 | // --------------------------------------------------------------------------------------------- | 18 | // --------------------------------------------------------------------------------------------- |
19 | constexpr explicit UniqueKey(uint64_t val_, char const* debugName_ = nullptr) | 19 | constexpr explicit UniqueKey(uint64_t val_, std::string_view const& debugName_ = {}) |
20 | #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 | 20 | #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 |
21 | : storage{ static_cast<uintptr_t>(val_ & 0x7FFFFFFFFFFFull) } | 21 | : storage{ static_cast<uintptr_t>(val_ & 0x7FFFFFFFFFFFull) } |
22 | #else // LUAJIT_FLAVOR() | 22 | #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 | |||
354 | Lane* _lane{ selfdestructFirst }; | 354 | Lane* _lane{ selfdestructFirst }; |
355 | if (_lane != SELFDESTRUCT_END) { | 355 | if (_lane != SELFDESTRUCT_END) { |
356 | // this causes a leak because we don't call U's destructor (which could be bad if the still running lanes are accessing it) | 356 | // this causes a leak because we don't call U's destructor (which could be bad if the still running lanes are accessing it) |
357 | raise_luaL_error(L_, "Zombie thread " STRINGVIEW_FMT " refuses to die!", _lane->debugName.size(), _lane->debugName.data()); | 357 | raise_luaL_error(L_, "Zombie thread '" STRINGVIEW_FMT "' refuses to die!", _lane->debugName.size(), _lane->debugName.data()); |
358 | } | 358 | } |
359 | } | 359 | } |
360 | } | 360 | } |