From a156aaeb07fada043b308409dcffcae1726eec0b Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Wed, 29 May 2024 17:31:45 +0200 Subject: Fix clang-tidy issues (most notably Microsoft-specific explicit constructor calls) --- src/deep.h | 18 +++++++++--------- src/intercopycontext.cpp | 5 +++-- src/lane.cpp | 2 +- src/lanes.cpp | 18 +++++++++--------- src/lanes.lua | 4 ++-- src/linda.cpp | 2 +- src/lindafactory.cpp | 2 +- src/macros_and_utils.h | 2 +- src/state.cpp | 4 ++-- src/tools.cpp | 10 +++++----- src/universe.cpp | 40 +++++++++++++++++++++++----------------- src/universe.h | 25 +++++++++++++------------ tests/keeper.lua | 2 +- 13 files changed, 71 insertions(+), 63 deletions(-) diff --git a/src/deep.h b/src/deep.h index 17d3491..1710aba 100644 --- a/src/deep.h +++ b/src/deep.h @@ -64,21 +64,21 @@ class DeepFactory private: // NVI: private overrides - virtual void createMetatable(lua_State* const L_) const = 0; - virtual void deleteDeepObjectInternal(lua_State* const L_, DeepPrelude* const o_) const = 0; - [[nodiscard]] virtual DeepPrelude* newDeepObjectInternal(lua_State* const L_) const = 0; + virtual void createMetatable(lua_State* L_) const = 0; + virtual void deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const = 0; + [[nodiscard]] virtual DeepPrelude* newDeepObjectInternal(lua_State* L_) const = 0; [[nodiscard]] virtual std::string_view moduleName() const = 0; private: - void storeDeepLookup(lua_State* const L_) const; + void storeDeepLookup(lua_State* L_) const; public: // NVI: public interface - static void DeleteDeepObject(lua_State* const L_, DeepPrelude* const o_); - [[nodiscard]] static DeepFactory* LookupFactory(lua_State* const L_, int const index_, LookupMode const mode_); - static void PushDeepProxy(DestState const L_, DeepPrelude* const o_, int const nuv_, LookupMode const mode_, lua_State* const errL_); - [[nodiscard]] int pushDeepUserdata(DestState const L_, int const nuv_) const; - [[nodiscard]] DeepPrelude* toDeep(lua_State* const L_, int const index_) const; + static void DeleteDeepObject(lua_State* L_, DeepPrelude* o_); + [[nodiscard]] static DeepFactory* LookupFactory(lua_State* L_, int index_, LookupMode mode_); + static void PushDeepProxy(DestState L_, DeepPrelude* o_, int nuv_, LookupMode mode_, lua_State* errL_); + [[nodiscard]] int pushDeepUserdata(DestState L_, int nuv_) const; + [[nodiscard]] DeepPrelude* toDeep(lua_State* L_, int index_) const; }; // ################################################################################################# diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index eddb309..3557c7b 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp @@ -101,7 +101,7 @@ THE SOFTWARE. lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" } std::string_view _fqn{ lua_tostringview(L1, -1) }; - DEBUGSPEW_CODE(DebugSpew(universe_get(L1)) << "function [C] " << _fqn << std::endl); + DEBUGSPEW_CODE(DebugSpew(Universe::Get(L1)) << "function [C] " << _fqn << std::endl); // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... STACK_CHECK(L1, 0); @@ -1142,6 +1142,7 @@ namespace { break; // The following types cannot be copied + case LuaType::NONE: case LuaType::CDATA: [[fallthrough]]; case LuaType::THREAD: @@ -1175,7 +1176,7 @@ namespace { OnExit(lua_State* L2_) : L2{ L2_ } , top_L2{ lua_gettop(L2) } - DEBUGSPEW_COMMA_PARAM(scope{ universe_get(L2_) }) + DEBUGSPEW_COMMA_PARAM(scope{ Universe::Get(L2_) }) { } diff --git a/src/lane.cpp b/src/lane.cpp index eef9e6e..22147f1 100644 --- a/src/lane.cpp +++ b/src/lane.cpp @@ -669,7 +669,7 @@ static void lane_main(Lane* lane_) // At this point, the lane function and arguments are on the stack, possibly preceded by the error handler int const _errorHandlerCount{ lane_->errorTraceLevel == Lane::Minimal ? 0 : 1}; int const _nargs{ lua_gettop(_L) - 1 - _errorHandlerCount }; - DEBUGSPEW_CODE(Universe* _U = universe_get(_L)); + DEBUGSPEW_CODE(Universe* _U = Universe::Get(_L)); lane_->status = Lane::Running; // Pending -> Running PrepareLaneHelpers(lane_); diff --git a/src/lanes.cpp b/src/lanes.cpp index 9fc7fc9..b74e9ec 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp @@ -143,7 +143,7 @@ LUAG_FUNC(set_thread_priority) if (_prio < kThreadPrioMin || _prio > kThreadPrioMax) { raise_luaL_error(L_, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, _prio); } - THREAD_SET_PRIORITY(static_cast(_prio), universe_get(L_)->sudo); + THREAD_SET_PRIORITY(static_cast(_prio), Universe::Get(L_)->sudo); return 0; } @@ -169,7 +169,7 @@ LUAG_FUNC(require) { std::string_view const _name{ lua_tostringview(L_, 1) }; // L_: "name" ... int const _nargs{ lua_gettop(L_) }; - DEBUGSPEW_CODE(Universe * _U{ universe_get(L_) }); + DEBUGSPEW_CODE(Universe * _U{ Universe::Get(L_) }); STACK_CHECK_START_REL(L_, 0); DEBUGSPEW_CODE(DebugSpew(_U) << "lanes.require '" << _name << "' BEGIN" << std::endl); DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); @@ -194,7 +194,7 @@ LUAG_FUNC(register) // ignore extra parameters, just in case lua_settop(L_, 2); luaL_argcheck(L_, (_mod_type == LuaType::TABLE) || (_mod_type == LuaType::FUNCTION), 2, "unexpected module type"); - DEBUGSPEW_CODE(Universe* _U = universe_get(L_)); + DEBUGSPEW_CODE(Universe* _U = Universe::Get(L_)); STACK_CHECK_START_REL(L_, 0); // "name" mod_table DEBUGSPEW_CODE(DebugSpew(_U) << "lanes.register '" << _name << "' BEGIN" << std::endl); DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); @@ -236,7 +236,7 @@ LUAG_FUNC(lane_new) int const _nargs{ lua_gettop(L_) - kFixedArgsIdx }; LUA_ASSERT(L_, _nargs >= 0); - Universe* const _U{ universe_get(L_) }; + Universe* const _U{ Universe::Get(L_) }; DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: setup" << std::endl); std::optional _libs_str{ lua_isnil(L_, kLibsIdx) ? std::nullopt : std::make_optional(lua_tostringview(L_, kLibsIdx)) }; @@ -510,7 +510,7 @@ LUAG_FUNC(lane_new) // Return a list of all known lanes LUAG_FUNC(threads) { - LaneTracker const& _tracker = universe_get(L_)->tracker; + LaneTracker const& _tracker = Universe::Get(L_)->tracker; return _tracker.pushThreadsTable(L_); } @@ -616,7 +616,7 @@ LUAG_FUNC(configure) // start with one-time initializations. { // C++ guarantees that the static variable initialization is threadsafe. - static auto _ = std::invoke( + [[maybe_unused]] static auto _ = std::invoke( []() { #if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU) chudInitialize(); @@ -625,7 +625,7 @@ LUAG_FUNC(configure) }); } - Universe* _U{ universe_get(L_) }; + Universe* _U{ Universe::Get(L_) }; bool const _from_master_state{ _U == nullptr }; std::string_view const _name{ luaL_checkstringview(L_, lua_upvalueindex(1)) }; LUA_ASSERT(L_, lua_type(L_, 1) == LUA_TTABLE); @@ -637,12 +637,12 @@ LUAG_FUNC(configure) DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); if (_U == nullptr) { - _U = universe_create(L_); // L_: settings universe + _U = Universe::Create(L_); // L_: settings universe DEBUGSPEW_CODE(DebugSpewIndentScope _scope2{ _U }); lua_createtable(L_, 0, 1); // L_: settings universe {mt} std::ignore = luaG_getfield(L_, 1, "shutdown_timeout"); // L_: settings universe {mt} shutdown_timeout std::ignore = luaG_getfield(L_, 1, "shutdown_mode"); // L_: settings universe {mt} shutdown_timeout shutdown_mode - lua_pushcclosure(L_, universe_gc, 2); // L_: settings universe {mt} universe_gc + lua_pushcclosure(L_, LG_universe_gc, 2); // L_: settings universe {mt} LG_universe_gc lua_setfield(L_, -2, "__gc"); // L_: settings universe {mt} lua_setmetatable(L_, -2); // L_: settings universe lua_pop(L_, 1); // L_: settings diff --git a/src/lanes.lua b/src/lanes.lua index 982de98..e7763b1 100644 --- a/src/lanes.lua +++ b/src/lanes.lua @@ -115,8 +115,8 @@ end local param_checkers = { nb_keepers = function(val_) - -- nb_keepers should be a number > 0 - return type(val_) == "number" and val_ > 0 + -- nb_keepers should be a number in [1,100] (so that nobody tries to run OOM by specifying a huge amount) + return type(val_) == "number" and val_ > 0 and val_ <= 100 end, keepers_gc_threshold = function(val_) -- keepers_gc_threshold should be a number diff --git a/src/linda.cpp b/src/linda.cpp index 8d09903..76cd347 100644 --- a/src/linda.cpp +++ b/src/linda.cpp @@ -100,7 +100,7 @@ template Linda* const _linda{ static_cast(LindaFactory::Instance.toDeep(L_, idx_)) }; if constexpr (!OPT) { luaL_argcheck(L_, _linda != nullptr, idx_, "expecting a linda object"); // doesn't return if linda is nullptr - LUA_ASSERT(L_, _linda->U == universe_get(L_)); + LUA_ASSERT(L_, _linda->U == Universe::Get(L_)); } return _linda; } diff --git a/src/lindafactory.cpp b/src/lindafactory.cpp index 890cc96..6d26852 100644 --- a/src/lindafactory.cpp +++ b/src/lindafactory.cpp @@ -126,7 +126,7 @@ DeepPrelude* LindaFactory::newDeepObjectInternal(lua_State* L_) const // The deep data is allocated separately of Lua stack; we might no longer be around when last reference to it is being released. // One can use any memory allocation scheme. Just don't use L's allocF because we don't know which state will get the honor of GCing the linda - Universe* const _U{ universe_get(L_) }; + Universe* const _U{ Universe::Get(L_) }; Linda* const _linda{ new (_U) Linda{ _U, _linda_group, _linda_name } }; return _linda; } diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index 1427ef1..7bb0d2a 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h @@ -178,7 +178,7 @@ inline void STACK_GROW(lua_State* L_, int n_) // ################################################################################################# -#define LUAG_FUNC(func_name) [[nodiscard]] int LG_##func_name(lua_State* L_) +#define LUAG_FUNC(func_name) [[nodiscard]] int LG_##func_name(lua_State* const L_) // ################################################################################################# diff --git a/src/state.cpp b/src/state.cpp index 5589c30..7585132 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -105,7 +105,7 @@ namespace { break; } std::string_view const _name{ _entry.name }; - DEBUGSPEW_CODE(DebugSpew(universe_get(L_)) << "opening '" << _name << "' library" << std::endl); + DEBUGSPEW_CODE(DebugSpew(Universe::Get(L_)) << "opening '" << _name << "' library" << std::endl); STACK_CHECK_START_REL(L_, 0); // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) bool const isLanesCore{ _libfunc == require_lanes_core }; // don't want to create a global for "lanes.core" @@ -273,7 +273,7 @@ namespace state { // copy the universe as a light userdata (only the master state holds the full userdata) // that way, if Lanes is required in this new state, we'll know we are part of this universe - universe_store(_L, U_); + Universe::Store(_L, U_); STACK_CHECK(_L, 0); // we'll need this every time we transfer some C function from/to this state diff --git a/src/tools.cpp b/src/tools.cpp index e9114e0..94e941d 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -133,7 +133,7 @@ static void update_lookup_entry(lua_State* L_, int ctxBase_, int depth_) // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i int const _fqn{ ctxBase_ + 1 }; - DEBUGSPEW_CODE(Universe* const _U{ universe_get(L_) }); + DEBUGSPEW_CODE(Universe* const _U{ Universe::Get(L_) }); DEBUGSPEW_CODE(DebugSpew(_U) << "update_lookup_entry()" << std::endl); DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); @@ -200,7 +200,7 @@ static void populate_func_lookup_table_recur(lua_State* L_, int dbIdx_, int i_, int const _fqn{ dbIdx_ + 1 }; // slot dbIdx_ + 2 contains a cache that stores all already visited tables to avoid infinite recursion loops int const _cache{ dbIdx_ + 2 }; - DEBUGSPEW_CODE(Universe* const _U{ universe_get(L_) }); + DEBUGSPEW_CODE(Universe* const _U{ Universe::Get(L_) }); DEBUGSPEW_CODE(DebugSpew(_U) << "populate_func_lookup_table_recur()" << std::endl); DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); @@ -309,7 +309,7 @@ namespace tools { void PopulateFuncLookupTable(lua_State* const L_, int const i_, std::string_view const& name_) { int const _in_base{ lua_absindex(L_, i_) }; - DEBUGSPEW_CODE(Universe* _U = universe_get(L_)); + DEBUGSPEW_CODE(Universe* _U = Universe::Get(L_)); std::string_view _name{ name_.empty() ? std::string_view{} : name_ }; DEBUGSPEW_CODE(DebugSpew(_U) << L_ << ": PopulateFuncLookupTable('" << _name << "')" << std::endl); DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); @@ -380,7 +380,7 @@ namespace tools { LuaError const _rc{ std::invoke( [L = L_, args = _args]() { - std::lock_guard _guard{ universe_get(L)->requireMutex }; + std::lock_guard _guard{ Universe::Get(L)->requireMutex }; // starting with Lua 5.4, require may return a second optional value, so we need LUA_MULTRET return lua_pcall(L, args, LUA_MULTRET, 0 /*errfunc*/); // L_: err|result(s) }) @@ -398,7 +398,7 @@ namespace tools { STACK_GROW(L_, 1); STACK_CHECK_START_REL(L_, 0); - DEBUGSPEW_CODE(DebugSpew(universe_get(L_)) << "serializing require()" << std::endl); + DEBUGSPEW_CODE(DebugSpew(Universe::Get(L_)) << "serializing require()" << std::endl); // Check 'require' is there and not already wrapped; if not, do nothing lua_getglobal(L_, "require"); // L_: _G.require()|nil diff --git a/src/universe.cpp b/src/universe.cpp index 77f799b..55c3e69 100644 --- a/src/universe.cpp +++ b/src/universe.cpp @@ -40,6 +40,11 @@ THE SOFTWARE. // ################################################################################################# +// xxh64 of string "kUniverseFullRegKey" generated at https://www.pelock.com/products/hash-calculator +static constexpr RegistryUniqueKey kUniverseFullRegKey{ 0x1C2D76870DD9DD9Full }; + +// ################################################################################################# + Universe::Universe() { //--- @@ -69,12 +74,12 @@ Universe::Universe() // ################################################################################################# // only called from the master state -[[nodiscard]] Universe* universe_create(lua_State* L_) +[[nodiscard]] Universe* Universe::Create(lua_State* const L_) { - LUA_ASSERT(L_, universe_get(L_) == nullptr); - Universe* const _U{ lua_newuserdatauv(L_, 0) }; // universe - _U->Universe::Universe(); - STACK_CHECK_START_REL(L_, 1); + LUA_ASSERT(L_, Universe::Get(L_) == nullptr); + STACK_CHECK_START_REL(L_, 0); + Universe* const _U{ new (L_) Universe{} }; // L_: universe + STACK_CHECK(L_, 1); kUniverseFullRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); kUniverseLightRegKey.setValue(L_, [U = _U](lua_State* L_) { lua_pushlightuserdata(L_, U); }); STACK_CHECK(L_, 1); @@ -86,7 +91,7 @@ Universe::Universe() // ################################################################################################# // same as PUC-Lua l_alloc -extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud_, [[maybe_unused]] void* ptr_, [[maybe_unused]] size_t osize_, size_t nsize_) +[[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud_, [[maybe_unused]] void* ptr_, [[maybe_unused]] size_t osize_, size_t nsize_) { if (nsize_ == 0) { free(ptr_); @@ -98,11 +103,11 @@ extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud_, // ################################################################################################# -[[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L_) +[[nodiscard]] static int luaG_provide_protected_allocator(lua_State* const L_) { - Universe* const _U{ universe_get(L_) }; + Universe* const _U{ Universe::Get(L_) }; // push a new full userdata on the stack, giving access to the universe's protected allocator - [[maybe_unused]] AllocatorDefinition* const def{ new (L_) AllocatorDefinition{ _U->protectedAllocator.makeDefinition() } }; + [[maybe_unused]] AllocatorDefinition* const _def{ new (L_) AllocatorDefinition{ _U->protectedAllocator.makeDefinition() } }; return 1; } @@ -149,7 +154,7 @@ void Universe::closeKeepers() // called once at the creation of the universe (therefore L_ is the master Lua state everything originates from) // Do I need to disable this when compiling for LuaJIT to prevent issues? -void Universe::initializeAllocatorFunction(lua_State* L_) +void Universe::initializeAllocatorFunction(lua_State* const L_) { STACK_CHECK_START_REL(L_, 1); // L_: settings if (luaG_getfield(L_, -1, "allocator") != LuaType::NIL) { // L_: settings allocator|nil|"protected" @@ -198,7 +203,7 @@ void Universe::initializeAllocatorFunction(lua_State* L_) // ################################################################################################# // should be called ONLY from the state that created the universe -int Universe::InitializeFinalizer(lua_State* L_) +int Universe::InitializeFinalizer(lua_State* const L_) { luaL_argcheck(L_, lua_gettop(L_) <= 1, 1, "too many arguments"); // L_: f? lua_settop(L_, 1); // L_: f|nil @@ -230,7 +235,7 @@ int Universe::InitializeFinalizer(lua_State* L_) * function never fails. * settings table is expected at position 1 on the stack */ -void Universe::initializeKeepers(lua_State* L_) +void Universe::initializeKeepers(lua_State* const L_) { LUA_ASSERT(L_, lua_gettop(L_) == 1 && lua_istable(L_, 1)); STACK_CHECK_START_REL(L_, 0); // L_: settings @@ -258,8 +263,9 @@ void Universe::initializeKeepers(lua_State* L_) keepers->gc_threshold = keepers_gc_threshold; keepers->nb_keepers = _nb_keepers; - for (int const _i : std::ranges::iota_view{ 0, _nb_keepers }) { - keepers->keeper_array[_i].Keeper::Keeper(); + // we have to manually call the Keeper constructor on the additional array slots + for (int const _i : std::ranges::iota_view{ 1, _nb_keepers }) { + new (&keepers->keeper_array[_i]) Keeper{}; // placement new } } @@ -279,7 +285,7 @@ void Universe::initializeKeepers(lua_State* L_) STACK_CHECK_START_ABS(_K, 0); // copy the universe pointer in the keeper itself - universe_store(_K, this); + Universe::Store(_K, this); STACK_CHECK(_K, 0); // make sure 'package' is initialized in keeper states, so that we have require() @@ -325,7 +331,7 @@ void Universe::initializeKeepers(lua_State* L_) // ################################################################################################# -void Universe::terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTimeout_, CancelOp op_) +void Universe::terminateFreeRunningLanes(lua_State* const L_, lua_Duration const shutdownTimeout_, CancelOp const op_) { if (selfdestructFirst != SELFDESTRUCT_END) { // Signal _all_ still running threads to exit (including the timer thread) @@ -391,7 +397,7 @@ void Universe::terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTim // ################################################################################################# // process end: cancel any still free-running threads -int universe_gc(lua_State* L_) +LUAG_FUNC(universe_gc) { lua_Duration const _shutdown_timeout{ lua_tonumber(L_, lua_upvalueindex(1)) }; std::string_view const _op_string{ lua_tostringview(L_, lua_upvalueindex(2)) }; diff --git a/src/universe.h b/src/universe.h index 4be6a9a..7624fed 100644 --- a/src/universe.h +++ b/src/universe.h @@ -108,8 +108,6 @@ class ProtectedAllocator // ################################################################################################# -// xxh64 of string "kUniverseFullRegKey" generated at https://www.pelock.com/products/hash-calculator -static constexpr RegistryUniqueKey kUniverseFullRegKey{ 0x1C2D76870DD9DD9Full }; // xxh64 of string "kUniverseLightRegKey" generated at https://www.pelock.com/products/hash-calculator static constexpr RegistryUniqueKey kUniverseLightRegKey{ 0x48BBE9CEAB0BA04Full }; @@ -172,6 +170,11 @@ class Universe // The terminal desinit sequence should wait for all such processing to terminate before force-killing threads std::atomic selfdestructingCount{ 0 }; + public: + [[nodiscard]] static void* operator new([[maybe_unused]] size_t size_, lua_State* L_) noexcept { return lua_newuserdatauv(L_, 0); }; + // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception + static void operator delete([[maybe_unused]] void* p_, [[maybe_unused]] lua_State* L_) {} // nothing to do, as nothing is allocated independently + Universe(); ~Universe() = default; // non-copyable, non-movable @@ -181,21 +184,18 @@ class Universe Universe& operator=(Universe&&) = delete; void closeKeepers(); + [[nodiscard]] static Universe* Create(lua_State* L_); + [[nodiscard]] static inline Universe* Get(lua_State* L_); void initializeAllocatorFunction(lua_State* L_); static int InitializeFinalizer(lua_State* L_); void initializeKeepers(lua_State* L_); + static inline void Store(lua_State* L_, Universe* U_); void terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTimeout_, CancelOp op_); }; // ################################################################################################# -[[nodiscard]] Universe* universe_get(lua_State* L_); -[[nodiscard]] Universe* universe_create(lua_State* L_); -void universe_store(lua_State* L_, Universe* U_); - -// ################################################################################################# - -[[nodiscard]] inline Universe* universe_get(lua_State* L_) +inline Universe* Universe::Get(lua_State* L_) { STACK_CHECK_START_REL(L_, 0); Universe* const _universe{ kUniverseLightRegKey.readLightUserDataValue(L_) }; @@ -205,9 +205,10 @@ void universe_store(lua_State* L_, Universe* U_); // ################################################################################################# -inline void universe_store(lua_State* L_, Universe* U_) +inline void Universe::Store(lua_State* L_, Universe* U_) { - LUA_ASSERT(L_, !U_ || universe_get(L_) == nullptr); + // TODO: check if we actually ever call Store with a null universe + LUA_ASSERT(L_, !U_ || Universe::Get(L_) == nullptr); STACK_CHECK_START_REL(L_, 0); kUniverseLightRegKey.setValue(L_, [U = U_](lua_State* L_) { U ? lua_pushlightuserdata(L_, U) : lua_pushnil(L_); }); STACK_CHECK(L_, 0); @@ -215,4 +216,4 @@ inline void universe_store(lua_State* L_, Universe* U_) // ################################################################################################# -int universe_gc(lua_State* L_); +LUAG_FUNC(universe_gc); diff --git a/tests/keeper.lua b/tests/keeper.lua index e485018..e758b54 100644 --- a/tests/keeper.lua +++ b/tests/keeper.lua @@ -3,7 +3,7 @@ -- -- Test program for Lua Lanes -- - +-- TODO: there is a random crash when nb_keepers > 1. Will have to investigate local lanes = require "lanes".configure{ with_timers = false, nb_keepers = 1, keepers_gc_threshold = 500} do -- cgit v1.2.3-55-g6feb