aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-05-27 10:34:57 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-05-27 10:34:57 +0200
commita30ac3790edea8329c199c9c42ff4150cf20c8ba (patch)
treeaea060cc17ac6783389e2561e81b3b74c74ab6ad /src
parent96be015111e2d4b05ae8cb9496b752472e8578a9 (diff)
downloadlanes-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.cpp3
-rw-r--r--src/compat.h8
-rw-r--r--src/debugspew.h9
-rw-r--r--src/intercopycontext.cpp24
-rw-r--r--src/linda.cpp6
-rw-r--r--src/state.cpp45
-rw-r--r--src/tools.cpp4
-rw-r--r--src/uniquekey.h4
-rw-r--r--src/universe.cpp2
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>"]
14LuaType luaG_getmodule(lua_State* L_, char const* name_) 14LuaType 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
52void luaL_requiref(lua_State* L_, const char* modname_, lua_CFunction openf_, int glb_) 51void 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
246LuaType luaG_getmodule(lua_State* L_, char const* name_); 246LuaType 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
38inline 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
38inline auto& DebugSpew(Universe const* const U_) 43inline 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
40DEBUGSPEW_CODE(char const* const DebugSpewIndentScope::debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); 40DEBUGSPEW_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
43static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull }; 43static 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
303void populate_func_lookup_table(lua_State* const L_, int const i_, std::string_view const& name_) 303void 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}