diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-29 17:31:45 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-29 17:31:45 +0200 |
commit | a156aaeb07fada043b308409dcffcae1726eec0b (patch) | |
tree | f15a5d60cda30607260d896598ea33f8619af53a /src | |
parent | d47758d58d532a9716ad4fd85cc806704df13735 (diff) | |
download | lanes-a156aaeb07fada043b308409dcffcae1726eec0b.tar.gz lanes-a156aaeb07fada043b308409dcffcae1726eec0b.tar.bz2 lanes-a156aaeb07fada043b308409dcffcae1726eec0b.zip |
Fix clang-tidy issues (most notably Microsoft-specific explicit constructor calls)
Diffstat (limited to 'src')
-rw-r--r-- | src/deep.h | 18 | ||||
-rw-r--r-- | src/intercopycontext.cpp | 5 | ||||
-rw-r--r-- | src/lane.cpp | 2 | ||||
-rw-r--r-- | src/lanes.cpp | 18 | ||||
-rw-r--r-- | src/lanes.lua | 4 | ||||
-rw-r--r-- | src/linda.cpp | 2 | ||||
-rw-r--r-- | src/lindafactory.cpp | 2 | ||||
-rw-r--r-- | src/macros_and_utils.h | 2 | ||||
-rw-r--r-- | src/state.cpp | 4 | ||||
-rw-r--r-- | src/tools.cpp | 10 | ||||
-rw-r--r-- | src/universe.cpp | 40 | ||||
-rw-r--r-- | src/universe.h | 25 |
12 files changed, 70 insertions, 62 deletions
@@ -64,21 +64,21 @@ class DeepFactory | |||
64 | 64 | ||
65 | private: | 65 | private: |
66 | // NVI: private overrides | 66 | // NVI: private overrides |
67 | virtual void createMetatable(lua_State* const L_) const = 0; | 67 | virtual void createMetatable(lua_State* L_) const = 0; |
68 | virtual void deleteDeepObjectInternal(lua_State* const L_, DeepPrelude* const o_) const = 0; | 68 | virtual void deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const = 0; |
69 | [[nodiscard]] virtual DeepPrelude* newDeepObjectInternal(lua_State* const L_) const = 0; | 69 | [[nodiscard]] virtual DeepPrelude* newDeepObjectInternal(lua_State* L_) const = 0; |
70 | [[nodiscard]] virtual std::string_view moduleName() const = 0; | 70 | [[nodiscard]] virtual std::string_view moduleName() const = 0; |
71 | 71 | ||
72 | private: | 72 | private: |
73 | void storeDeepLookup(lua_State* const L_) const; | 73 | void storeDeepLookup(lua_State* L_) const; |
74 | 74 | ||
75 | public: | 75 | public: |
76 | // NVI: public interface | 76 | // NVI: public interface |
77 | static void DeleteDeepObject(lua_State* const L_, DeepPrelude* const o_); | 77 | static void DeleteDeepObject(lua_State* L_, DeepPrelude* o_); |
78 | [[nodiscard]] static DeepFactory* LookupFactory(lua_State* const L_, int const index_, LookupMode const mode_); | 78 | [[nodiscard]] static DeepFactory* LookupFactory(lua_State* L_, int index_, LookupMode mode_); |
79 | static void PushDeepProxy(DestState const L_, DeepPrelude* const o_, int const nuv_, LookupMode const mode_, lua_State* const errL_); | 79 | static void PushDeepProxy(DestState L_, DeepPrelude* o_, int nuv_, LookupMode mode_, lua_State* errL_); |
80 | [[nodiscard]] int pushDeepUserdata(DestState const L_, int const nuv_) const; | 80 | [[nodiscard]] int pushDeepUserdata(DestState L_, int nuv_) const; |
81 | [[nodiscard]] DeepPrelude* toDeep(lua_State* const L_, int const index_) const; | 81 | [[nodiscard]] DeepPrelude* toDeep(lua_State* L_, int index_) const; |
82 | }; | 82 | }; |
83 | 83 | ||
84 | // ################################################################################################# | 84 | // ################################################################################################# |
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. | |||
101 | lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" | 101 | lua_rawget(L1, -2); // L1: ... v ... {} "f.q.n" |
102 | } | 102 | } |
103 | std::string_view _fqn{ lua_tostringview(L1, -1) }; | 103 | std::string_view _fqn{ lua_tostringview(L1, -1) }; |
104 | DEBUGSPEW_CODE(DebugSpew(universe_get(L1)) << "function [C] " << _fqn << std::endl); | 104 | DEBUGSPEW_CODE(DebugSpew(Universe::Get(L1)) << "function [C] " << _fqn << std::endl); |
105 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database | 105 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database |
106 | lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... | 106 | lua_pop(L1, (mode == LookupMode::FromKeeper) ? 1 : 2); // L1: ... v ... |
107 | STACK_CHECK(L1, 0); | 107 | STACK_CHECK(L1, 0); |
@@ -1142,6 +1142,7 @@ namespace { | |||
1142 | break; | 1142 | break; |
1143 | 1143 | ||
1144 | // The following types cannot be copied | 1144 | // The following types cannot be copied |
1145 | case LuaType::NONE: | ||
1145 | case LuaType::CDATA: | 1146 | case LuaType::CDATA: |
1146 | [[fallthrough]]; | 1147 | [[fallthrough]]; |
1147 | case LuaType::THREAD: | 1148 | case LuaType::THREAD: |
@@ -1175,7 +1176,7 @@ namespace { | |||
1175 | OnExit(lua_State* L2_) | 1176 | OnExit(lua_State* L2_) |
1176 | : L2{ L2_ } | 1177 | : L2{ L2_ } |
1177 | , top_L2{ lua_gettop(L2) } | 1178 | , top_L2{ lua_gettop(L2) } |
1178 | DEBUGSPEW_COMMA_PARAM(scope{ universe_get(L2_) }) | 1179 | DEBUGSPEW_COMMA_PARAM(scope{ Universe::Get(L2_) }) |
1179 | { | 1180 | { |
1180 | } | 1181 | } |
1181 | 1182 | ||
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_) | |||
669 | // At this point, the lane function and arguments are on the stack, possibly preceded by the error handler | 669 | // At this point, the lane function and arguments are on the stack, possibly preceded by the error handler |
670 | int const _errorHandlerCount{ lane_->errorTraceLevel == Lane::Minimal ? 0 : 1}; | 670 | int const _errorHandlerCount{ lane_->errorTraceLevel == Lane::Minimal ? 0 : 1}; |
671 | int const _nargs{ lua_gettop(_L) - 1 - _errorHandlerCount }; | 671 | int const _nargs{ lua_gettop(_L) - 1 - _errorHandlerCount }; |
672 | DEBUGSPEW_CODE(Universe* _U = universe_get(_L)); | 672 | DEBUGSPEW_CODE(Universe* _U = Universe::Get(_L)); |
673 | lane_->status = Lane::Running; // Pending -> Running | 673 | lane_->status = Lane::Running; // Pending -> Running |
674 | 674 | ||
675 | PrepareLaneHelpers(lane_); | 675 | 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) | |||
143 | if (_prio < kThreadPrioMin || _prio > kThreadPrioMax) { | 143 | if (_prio < kThreadPrioMin || _prio > kThreadPrioMax) { |
144 | raise_luaL_error(L_, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, _prio); | 144 | raise_luaL_error(L_, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, _prio); |
145 | } | 145 | } |
146 | THREAD_SET_PRIORITY(static_cast<int>(_prio), universe_get(L_)->sudo); | 146 | THREAD_SET_PRIORITY(static_cast<int>(_prio), Universe::Get(L_)->sudo); |
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | 149 | ||
@@ -169,7 +169,7 @@ LUAG_FUNC(require) | |||
169 | { | 169 | { |
170 | std::string_view const _name{ lua_tostringview(L_, 1) }; // L_: "name" ... | 170 | std::string_view const _name{ lua_tostringview(L_, 1) }; // L_: "name" ... |
171 | int const _nargs{ lua_gettop(L_) }; | 171 | int const _nargs{ lua_gettop(L_) }; |
172 | DEBUGSPEW_CODE(Universe * _U{ universe_get(L_) }); | 172 | DEBUGSPEW_CODE(Universe * _U{ Universe::Get(L_) }); |
173 | STACK_CHECK_START_REL(L_, 0); | 173 | STACK_CHECK_START_REL(L_, 0); |
174 | DEBUGSPEW_CODE(DebugSpew(_U) << "lanes.require '" << _name << "' BEGIN" << std::endl); | 174 | DEBUGSPEW_CODE(DebugSpew(_U) << "lanes.require '" << _name << "' BEGIN" << std::endl); |
175 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); | 175 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); |
@@ -194,7 +194,7 @@ LUAG_FUNC(register) | |||
194 | // ignore extra parameters, just in case | 194 | // ignore extra parameters, just in case |
195 | lua_settop(L_, 2); | 195 | lua_settop(L_, 2); |
196 | luaL_argcheck(L_, (_mod_type == LuaType::TABLE) || (_mod_type == LuaType::FUNCTION), 2, "unexpected module type"); | 196 | luaL_argcheck(L_, (_mod_type == LuaType::TABLE) || (_mod_type == LuaType::FUNCTION), 2, "unexpected module type"); |
197 | DEBUGSPEW_CODE(Universe* _U = universe_get(L_)); | 197 | DEBUGSPEW_CODE(Universe* _U = Universe::Get(L_)); |
198 | STACK_CHECK_START_REL(L_, 0); // "name" mod_table | 198 | STACK_CHECK_START_REL(L_, 0); // "name" mod_table |
199 | DEBUGSPEW_CODE(DebugSpew(_U) << "lanes.register '" << _name << "' BEGIN" << std::endl); | 199 | DEBUGSPEW_CODE(DebugSpew(_U) << "lanes.register '" << _name << "' BEGIN" << std::endl); |
200 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); | 200 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); |
@@ -236,7 +236,7 @@ LUAG_FUNC(lane_new) | |||
236 | int const _nargs{ lua_gettop(L_) - kFixedArgsIdx }; | 236 | int const _nargs{ lua_gettop(L_) - kFixedArgsIdx }; |
237 | LUA_ASSERT(L_, _nargs >= 0); | 237 | LUA_ASSERT(L_, _nargs >= 0); |
238 | 238 | ||
239 | Universe* const _U{ universe_get(L_) }; | 239 | Universe* const _U{ Universe::Get(L_) }; |
240 | DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: setup" << std::endl); | 240 | DEBUGSPEW_CODE(DebugSpew(_U) << "lane_new: setup" << std::endl); |
241 | 241 | ||
242 | std::optional<std::string_view> _libs_str{ lua_isnil(L_, kLibsIdx) ? std::nullopt : std::make_optional(lua_tostringview(L_, kLibsIdx)) }; | 242 | std::optional<std::string_view> _libs_str{ lua_isnil(L_, kLibsIdx) ? std::nullopt : std::make_optional(lua_tostringview(L_, kLibsIdx)) }; |
@@ -510,7 +510,7 @@ LUAG_FUNC(lane_new) | |||
510 | // Return a list of all known lanes | 510 | // Return a list of all known lanes |
511 | LUAG_FUNC(threads) | 511 | LUAG_FUNC(threads) |
512 | { | 512 | { |
513 | LaneTracker const& _tracker = universe_get(L_)->tracker; | 513 | LaneTracker const& _tracker = Universe::Get(L_)->tracker; |
514 | return _tracker.pushThreadsTable(L_); | 514 | return _tracker.pushThreadsTable(L_); |
515 | } | 515 | } |
516 | 516 | ||
@@ -616,7 +616,7 @@ LUAG_FUNC(configure) | |||
616 | // start with one-time initializations. | 616 | // start with one-time initializations. |
617 | { | 617 | { |
618 | // C++ guarantees that the static variable initialization is threadsafe. | 618 | // C++ guarantees that the static variable initialization is threadsafe. |
619 | static auto _ = std::invoke( | 619 | [[maybe_unused]] static auto _ = std::invoke( |
620 | []() { | 620 | []() { |
621 | #if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU) | 621 | #if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU) |
622 | chudInitialize(); | 622 | chudInitialize(); |
@@ -625,7 +625,7 @@ LUAG_FUNC(configure) | |||
625 | }); | 625 | }); |
626 | } | 626 | } |
627 | 627 | ||
628 | Universe* _U{ universe_get(L_) }; | 628 | Universe* _U{ Universe::Get(L_) }; |
629 | bool const _from_master_state{ _U == nullptr }; | 629 | bool const _from_master_state{ _U == nullptr }; |
630 | std::string_view const _name{ luaL_checkstringview(L_, lua_upvalueindex(1)) }; | 630 | std::string_view const _name{ luaL_checkstringview(L_, lua_upvalueindex(1)) }; |
631 | LUA_ASSERT(L_, lua_type(L_, 1) == LUA_TTABLE); | 631 | LUA_ASSERT(L_, lua_type(L_, 1) == LUA_TTABLE); |
@@ -637,12 +637,12 @@ LUAG_FUNC(configure) | |||
637 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); | 637 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); |
638 | 638 | ||
639 | if (_U == nullptr) { | 639 | if (_U == nullptr) { |
640 | _U = universe_create(L_); // L_: settings universe | 640 | _U = Universe::Create(L_); // L_: settings universe |
641 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope2{ _U }); | 641 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope2{ _U }); |
642 | lua_createtable(L_, 0, 1); // L_: settings universe {mt} | 642 | lua_createtable(L_, 0, 1); // L_: settings universe {mt} |
643 | std::ignore = luaG_getfield(L_, 1, "shutdown_timeout"); // L_: settings universe {mt} shutdown_timeout | 643 | std::ignore = luaG_getfield(L_, 1, "shutdown_timeout"); // L_: settings universe {mt} shutdown_timeout |
644 | std::ignore = luaG_getfield(L_, 1, "shutdown_mode"); // L_: settings universe {mt} shutdown_timeout shutdown_mode | 644 | std::ignore = luaG_getfield(L_, 1, "shutdown_mode"); // L_: settings universe {mt} shutdown_timeout shutdown_mode |
645 | lua_pushcclosure(L_, universe_gc, 2); // L_: settings universe {mt} universe_gc | 645 | lua_pushcclosure(L_, LG_universe_gc, 2); // L_: settings universe {mt} LG_universe_gc |
646 | lua_setfield(L_, -2, "__gc"); // L_: settings universe {mt} | 646 | lua_setfield(L_, -2, "__gc"); // L_: settings universe {mt} |
647 | lua_setmetatable(L_, -2); // L_: settings universe | 647 | lua_setmetatable(L_, -2); // L_: settings universe |
648 | lua_pop(L_, 1); // L_: settings | 648 | 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 | |||
115 | local param_checkers = | 115 | local param_checkers = |
116 | { | 116 | { |
117 | nb_keepers = function(val_) | 117 | nb_keepers = function(val_) |
118 | -- nb_keepers should be a number > 0 | 118 | -- nb_keepers should be a number in [1,100] (so that nobody tries to run OOM by specifying a huge amount) |
119 | return type(val_) == "number" and val_ > 0 | 119 | return type(val_) == "number" and val_ > 0 and val_ <= 100 |
120 | end, | 120 | end, |
121 | keepers_gc_threshold = function(val_) | 121 | keepers_gc_threshold = function(val_) |
122 | -- keepers_gc_threshold should be a number | 122 | -- 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 <bool OPT> | |||
100 | Linda* const _linda{ static_cast<Linda*>(LindaFactory::Instance.toDeep(L_, idx_)) }; | 100 | Linda* const _linda{ static_cast<Linda*>(LindaFactory::Instance.toDeep(L_, idx_)) }; |
101 | if constexpr (!OPT) { | 101 | if constexpr (!OPT) { |
102 | luaL_argcheck(L_, _linda != nullptr, idx_, "expecting a linda object"); // doesn't return if linda is nullptr | 102 | luaL_argcheck(L_, _linda != nullptr, idx_, "expecting a linda object"); // doesn't return if linda is nullptr |
103 | LUA_ASSERT(L_, _linda->U == universe_get(L_)); | 103 | LUA_ASSERT(L_, _linda->U == Universe::Get(L_)); |
104 | } | 104 | } |
105 | return _linda; | 105 | return _linda; |
106 | } | 106 | } |
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 | |||
126 | 126 | ||
127 | // The deep data is allocated separately of Lua stack; we might no longer be around when last reference to it is being released. | 127 | // The deep data is allocated separately of Lua stack; we might no longer be around when last reference to it is being released. |
128 | // 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 | 128 | // 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 |
129 | Universe* const _U{ universe_get(L_) }; | 129 | Universe* const _U{ Universe::Get(L_) }; |
130 | Linda* const _linda{ new (_U) Linda{ _U, _linda_group, _linda_name } }; | 130 | Linda* const _linda{ new (_U) Linda{ _U, _linda_group, _linda_name } }; |
131 | return _linda; | 131 | return _linda; |
132 | } | 132 | } |
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_) | |||
178 | 178 | ||
179 | // ################################################################################################# | 179 | // ################################################################################################# |
180 | 180 | ||
181 | #define LUAG_FUNC(func_name) [[nodiscard]] int LG_##func_name(lua_State* L_) | 181 | #define LUAG_FUNC(func_name) [[nodiscard]] int LG_##func_name(lua_State* const L_) |
182 | 182 | ||
183 | // ################################################################################################# | 183 | // ################################################################################################# |
184 | 184 | ||
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 { | |||
105 | break; | 105 | break; |
106 | } | 106 | } |
107 | std::string_view const _name{ _entry.name }; | 107 | std::string_view const _name{ _entry.name }; |
108 | DEBUGSPEW_CODE(DebugSpew(universe_get(L_)) << "opening '" << _name << "' library" << std::endl); | 108 | DEBUGSPEW_CODE(DebugSpew(Universe::Get(L_)) << "opening '" << _name << "' library" << std::endl); |
109 | STACK_CHECK_START_REL(L_, 0); | 109 | STACK_CHECK_START_REL(L_, 0); |
110 | // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) | 110 | // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) |
111 | bool const isLanesCore{ _libfunc == require_lanes_core }; // don't want to create a global for "lanes.core" | 111 | bool const isLanesCore{ _libfunc == require_lanes_core }; // don't want to create a global for "lanes.core" |
@@ -273,7 +273,7 @@ namespace state { | |||
273 | 273 | ||
274 | // copy the universe as a light userdata (only the master state holds the full userdata) | 274 | // copy the universe as a light userdata (only the master state holds the full userdata) |
275 | // that way, if Lanes is required in this new state, we'll know we are part of this universe | 275 | // that way, if Lanes is required in this new state, we'll know we are part of this universe |
276 | universe_store(_L, U_); | 276 | Universe::Store(_L, U_); |
277 | STACK_CHECK(_L, 0); | 277 | STACK_CHECK(_L, 0); |
278 | 278 | ||
279 | // we'll need this every time we transfer some C function from/to this state | 279 | // 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_) | |||
133 | // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i | 133 | // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i |
134 | int const _fqn{ ctxBase_ + 1 }; | 134 | int const _fqn{ ctxBase_ + 1 }; |
135 | 135 | ||
136 | DEBUGSPEW_CODE(Universe* const _U{ universe_get(L_) }); | 136 | DEBUGSPEW_CODE(Universe* const _U{ Universe::Get(L_) }); |
137 | DEBUGSPEW_CODE(DebugSpew(_U) << "update_lookup_entry()" << std::endl); | 137 | DEBUGSPEW_CODE(DebugSpew(_U) << "update_lookup_entry()" << std::endl); |
138 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); | 138 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); |
139 | 139 | ||
@@ -200,7 +200,7 @@ static void populate_func_lookup_table_recur(lua_State* L_, int dbIdx_, int i_, | |||
200 | int const _fqn{ dbIdx_ + 1 }; | 200 | int const _fqn{ dbIdx_ + 1 }; |
201 | // slot dbIdx_ + 2 contains a cache that stores all already visited tables to avoid infinite recursion loops | 201 | // slot dbIdx_ + 2 contains a cache that stores all already visited tables to avoid infinite recursion loops |
202 | int const _cache{ dbIdx_ + 2 }; | 202 | int const _cache{ dbIdx_ + 2 }; |
203 | DEBUGSPEW_CODE(Universe* const _U{ universe_get(L_) }); | 203 | DEBUGSPEW_CODE(Universe* const _U{ Universe::Get(L_) }); |
204 | DEBUGSPEW_CODE(DebugSpew(_U) << "populate_func_lookup_table_recur()" << std::endl); | 204 | DEBUGSPEW_CODE(DebugSpew(_U) << "populate_func_lookup_table_recur()" << std::endl); |
205 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); | 205 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); |
206 | 206 | ||
@@ -309,7 +309,7 @@ namespace tools { | |||
309 | void PopulateFuncLookupTable(lua_State* const L_, int const i_, std::string_view const& name_) | 309 | void PopulateFuncLookupTable(lua_State* const L_, int const i_, std::string_view const& name_) |
310 | { | 310 | { |
311 | int const _in_base{ lua_absindex(L_, i_) }; | 311 | int const _in_base{ lua_absindex(L_, i_) }; |
312 | DEBUGSPEW_CODE(Universe* _U = universe_get(L_)); | 312 | DEBUGSPEW_CODE(Universe* _U = Universe::Get(L_)); |
313 | std::string_view _name{ name_.empty() ? std::string_view{} : name_ }; | 313 | std::string_view _name{ name_.empty() ? std::string_view{} : name_ }; |
314 | DEBUGSPEW_CODE(DebugSpew(_U) << L_ << ": PopulateFuncLookupTable('" << _name << "')" << std::endl); | 314 | DEBUGSPEW_CODE(DebugSpew(_U) << L_ << ": PopulateFuncLookupTable('" << _name << "')" << std::endl); |
315 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); | 315 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); |
@@ -380,7 +380,7 @@ namespace tools { | |||
380 | LuaError const _rc{ std::invoke( | 380 | LuaError const _rc{ std::invoke( |
381 | [L = L_, args = _args]() | 381 | [L = L_, args = _args]() |
382 | { | 382 | { |
383 | std::lock_guard _guard{ universe_get(L)->requireMutex }; | 383 | std::lock_guard _guard{ Universe::Get(L)->requireMutex }; |
384 | // starting with Lua 5.4, require may return a second optional value, so we need LUA_MULTRET | 384 | // starting with Lua 5.4, require may return a second optional value, so we need LUA_MULTRET |
385 | return lua_pcall(L, args, LUA_MULTRET, 0 /*errfunc*/); // L_: err|result(s) | 385 | return lua_pcall(L, args, LUA_MULTRET, 0 /*errfunc*/); // L_: err|result(s) |
386 | }) | 386 | }) |
@@ -398,7 +398,7 @@ namespace tools { | |||
398 | 398 | ||
399 | STACK_GROW(L_, 1); | 399 | STACK_GROW(L_, 1); |
400 | STACK_CHECK_START_REL(L_, 0); | 400 | STACK_CHECK_START_REL(L_, 0); |
401 | DEBUGSPEW_CODE(DebugSpew(universe_get(L_)) << "serializing require()" << std::endl); | 401 | DEBUGSPEW_CODE(DebugSpew(Universe::Get(L_)) << "serializing require()" << std::endl); |
402 | 402 | ||
403 | // Check 'require' is there and not already wrapped; if not, do nothing | 403 | // Check 'require' is there and not already wrapped; if not, do nothing |
404 | lua_getglobal(L_, "require"); // L_: _G.require()|nil | 404 | 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. | |||
40 | 40 | ||
41 | // ################################################################################################# | 41 | // ################################################################################################# |
42 | 42 | ||
43 | // xxh64 of string "kUniverseFullRegKey" generated at https://www.pelock.com/products/hash-calculator | ||
44 | static constexpr RegistryUniqueKey kUniverseFullRegKey{ 0x1C2D76870DD9DD9Full }; | ||
45 | |||
46 | // ################################################################################################# | ||
47 | |||
43 | Universe::Universe() | 48 | Universe::Universe() |
44 | { | 49 | { |
45 | //--- | 50 | //--- |
@@ -69,12 +74,12 @@ Universe::Universe() | |||
69 | // ################################################################################################# | 74 | // ################################################################################################# |
70 | 75 | ||
71 | // only called from the master state | 76 | // only called from the master state |
72 | [[nodiscard]] Universe* universe_create(lua_State* L_) | 77 | [[nodiscard]] Universe* Universe::Create(lua_State* const L_) |
73 | { | 78 | { |
74 | LUA_ASSERT(L_, universe_get(L_) == nullptr); | 79 | LUA_ASSERT(L_, Universe::Get(L_) == nullptr); |
75 | Universe* const _U{ lua_newuserdatauv<Universe>(L_, 0) }; // universe | 80 | STACK_CHECK_START_REL(L_, 0); |
76 | _U->Universe::Universe(); | 81 | Universe* const _U{ new (L_) Universe{} }; // L_: universe |
77 | STACK_CHECK_START_REL(L_, 1); | 82 | STACK_CHECK(L_, 1); |
78 | kUniverseFullRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); | 83 | kUniverseFullRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); |
79 | kUniverseLightRegKey.setValue(L_, [U = _U](lua_State* L_) { lua_pushlightuserdata(L_, U); }); | 84 | kUniverseLightRegKey.setValue(L_, [U = _U](lua_State* L_) { lua_pushlightuserdata(L_, U); }); |
80 | STACK_CHECK(L_, 1); | 85 | STACK_CHECK(L_, 1); |
@@ -86,7 +91,7 @@ Universe::Universe() | |||
86 | // ################################################################################################# | 91 | // ################################################################################################# |
87 | 92 | ||
88 | // same as PUC-Lua l_alloc | 93 | // same as PUC-Lua l_alloc |
89 | extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud_, [[maybe_unused]] void* ptr_, [[maybe_unused]] size_t osize_, size_t nsize_) | 94 | [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud_, [[maybe_unused]] void* ptr_, [[maybe_unused]] size_t osize_, size_t nsize_) |
90 | { | 95 | { |
91 | if (nsize_ == 0) { | 96 | if (nsize_ == 0) { |
92 | free(ptr_); | 97 | free(ptr_); |
@@ -98,11 +103,11 @@ extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud_, | |||
98 | 103 | ||
99 | // ################################################################################################# | 104 | // ################################################################################################# |
100 | 105 | ||
101 | [[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L_) | 106 | [[nodiscard]] static int luaG_provide_protected_allocator(lua_State* const L_) |
102 | { | 107 | { |
103 | Universe* const _U{ universe_get(L_) }; | 108 | Universe* const _U{ Universe::Get(L_) }; |
104 | // push a new full userdata on the stack, giving access to the universe's protected allocator | 109 | // push a new full userdata on the stack, giving access to the universe's protected allocator |
105 | [[maybe_unused]] AllocatorDefinition* const def{ new (L_) AllocatorDefinition{ _U->protectedAllocator.makeDefinition() } }; | 110 | [[maybe_unused]] AllocatorDefinition* const _def{ new (L_) AllocatorDefinition{ _U->protectedAllocator.makeDefinition() } }; |
106 | return 1; | 111 | return 1; |
107 | } | 112 | } |
108 | 113 | ||
@@ -149,7 +154,7 @@ void Universe::closeKeepers() | |||
149 | 154 | ||
150 | // called once at the creation of the universe (therefore L_ is the master Lua state everything originates from) | 155 | // called once at the creation of the universe (therefore L_ is the master Lua state everything originates from) |
151 | // Do I need to disable this when compiling for LuaJIT to prevent issues? | 156 | // Do I need to disable this when compiling for LuaJIT to prevent issues? |
152 | void Universe::initializeAllocatorFunction(lua_State* L_) | 157 | void Universe::initializeAllocatorFunction(lua_State* const L_) |
153 | { | 158 | { |
154 | STACK_CHECK_START_REL(L_, 1); // L_: settings | 159 | STACK_CHECK_START_REL(L_, 1); // L_: settings |
155 | if (luaG_getfield(L_, -1, "allocator") != LuaType::NIL) { // L_: settings allocator|nil|"protected" | 160 | if (luaG_getfield(L_, -1, "allocator") != LuaType::NIL) { // L_: settings allocator|nil|"protected" |
@@ -198,7 +203,7 @@ void Universe::initializeAllocatorFunction(lua_State* L_) | |||
198 | // ################################################################################################# | 203 | // ################################################################################################# |
199 | 204 | ||
200 | // should be called ONLY from the state that created the universe | 205 | // should be called ONLY from the state that created the universe |
201 | int Universe::InitializeFinalizer(lua_State* L_) | 206 | int Universe::InitializeFinalizer(lua_State* const L_) |
202 | { | 207 | { |
203 | luaL_argcheck(L_, lua_gettop(L_) <= 1, 1, "too many arguments"); // L_: f? | 208 | luaL_argcheck(L_, lua_gettop(L_) <= 1, 1, "too many arguments"); // L_: f? |
204 | lua_settop(L_, 1); // L_: f|nil | 209 | lua_settop(L_, 1); // L_: f|nil |
@@ -230,7 +235,7 @@ int Universe::InitializeFinalizer(lua_State* L_) | |||
230 | * function never fails. | 235 | * function never fails. |
231 | * settings table is expected at position 1 on the stack | 236 | * settings table is expected at position 1 on the stack |
232 | */ | 237 | */ |
233 | void Universe::initializeKeepers(lua_State* L_) | 238 | void Universe::initializeKeepers(lua_State* const L_) |
234 | { | 239 | { |
235 | LUA_ASSERT(L_, lua_gettop(L_) == 1 && lua_istable(L_, 1)); | 240 | LUA_ASSERT(L_, lua_gettop(L_) == 1 && lua_istable(L_, 1)); |
236 | STACK_CHECK_START_REL(L_, 0); // L_: settings | 241 | STACK_CHECK_START_REL(L_, 0); // L_: settings |
@@ -258,8 +263,9 @@ void Universe::initializeKeepers(lua_State* L_) | |||
258 | keepers->gc_threshold = keepers_gc_threshold; | 263 | keepers->gc_threshold = keepers_gc_threshold; |
259 | keepers->nb_keepers = _nb_keepers; | 264 | keepers->nb_keepers = _nb_keepers; |
260 | 265 | ||
261 | for (int const _i : std::ranges::iota_view{ 0, _nb_keepers }) { | 266 | // we have to manually call the Keeper constructor on the additional array slots |
262 | keepers->keeper_array[_i].Keeper::Keeper(); | 267 | for (int const _i : std::ranges::iota_view{ 1, _nb_keepers }) { |
268 | new (&keepers->keeper_array[_i]) Keeper{}; // placement new | ||
263 | } | 269 | } |
264 | } | 270 | } |
265 | 271 | ||
@@ -279,7 +285,7 @@ void Universe::initializeKeepers(lua_State* L_) | |||
279 | STACK_CHECK_START_ABS(_K, 0); | 285 | STACK_CHECK_START_ABS(_K, 0); |
280 | 286 | ||
281 | // copy the universe pointer in the keeper itself | 287 | // copy the universe pointer in the keeper itself |
282 | universe_store(_K, this); | 288 | Universe::Store(_K, this); |
283 | STACK_CHECK(_K, 0); | 289 | STACK_CHECK(_K, 0); |
284 | 290 | ||
285 | // make sure 'package' is initialized in keeper states, so that we have require() | 291 | // make sure 'package' is initialized in keeper states, so that we have require() |
@@ -325,7 +331,7 @@ void Universe::initializeKeepers(lua_State* L_) | |||
325 | 331 | ||
326 | // ################################################################################################# | 332 | // ################################################################################################# |
327 | 333 | ||
328 | void Universe::terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTimeout_, CancelOp op_) | 334 | void Universe::terminateFreeRunningLanes(lua_State* const L_, lua_Duration const shutdownTimeout_, CancelOp const op_) |
329 | { | 335 | { |
330 | if (selfdestructFirst != SELFDESTRUCT_END) { | 336 | if (selfdestructFirst != SELFDESTRUCT_END) { |
331 | // Signal _all_ still running threads to exit (including the timer thread) | 337 | // Signal _all_ still running threads to exit (including the timer thread) |
@@ -391,7 +397,7 @@ void Universe::terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTim | |||
391 | // ################################################################################################# | 397 | // ################################################################################################# |
392 | 398 | ||
393 | // process end: cancel any still free-running threads | 399 | // process end: cancel any still free-running threads |
394 | int universe_gc(lua_State* L_) | 400 | LUAG_FUNC(universe_gc) |
395 | { | 401 | { |
396 | lua_Duration const _shutdown_timeout{ lua_tonumber(L_, lua_upvalueindex(1)) }; | 402 | lua_Duration const _shutdown_timeout{ lua_tonumber(L_, lua_upvalueindex(1)) }; |
397 | std::string_view const _op_string{ lua_tostringview(L_, lua_upvalueindex(2)) }; | 403 | 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 | |||
108 | 108 | ||
109 | // ################################################################################################# | 109 | // ################################################################################################# |
110 | 110 | ||
111 | // xxh64 of string "kUniverseFullRegKey" generated at https://www.pelock.com/products/hash-calculator | ||
112 | static constexpr RegistryUniqueKey kUniverseFullRegKey{ 0x1C2D76870DD9DD9Full }; | ||
113 | // xxh64 of string "kUniverseLightRegKey" generated at https://www.pelock.com/products/hash-calculator | 111 | // xxh64 of string "kUniverseLightRegKey" generated at https://www.pelock.com/products/hash-calculator |
114 | static constexpr RegistryUniqueKey kUniverseLightRegKey{ 0x48BBE9CEAB0BA04Full }; | 112 | static constexpr RegistryUniqueKey kUniverseLightRegKey{ 0x48BBE9CEAB0BA04Full }; |
115 | 113 | ||
@@ -172,6 +170,11 @@ class Universe | |||
172 | // The terminal desinit sequence should wait for all such processing to terminate before force-killing threads | 170 | // The terminal desinit sequence should wait for all such processing to terminate before force-killing threads |
173 | std::atomic<int> selfdestructingCount{ 0 }; | 171 | std::atomic<int> selfdestructingCount{ 0 }; |
174 | 172 | ||
173 | public: | ||
174 | [[nodiscard]] static void* operator new([[maybe_unused]] size_t size_, lua_State* L_) noexcept { return lua_newuserdatauv<Universe>(L_, 0); }; | ||
175 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | ||
176 | static void operator delete([[maybe_unused]] void* p_, [[maybe_unused]] lua_State* L_) {} // nothing to do, as nothing is allocated independently | ||
177 | |||
175 | Universe(); | 178 | Universe(); |
176 | ~Universe() = default; | 179 | ~Universe() = default; |
177 | // non-copyable, non-movable | 180 | // non-copyable, non-movable |
@@ -181,21 +184,18 @@ class Universe | |||
181 | Universe& operator=(Universe&&) = delete; | 184 | Universe& operator=(Universe&&) = delete; |
182 | 185 | ||
183 | void closeKeepers(); | 186 | void closeKeepers(); |
187 | [[nodiscard]] static Universe* Create(lua_State* L_); | ||
188 | [[nodiscard]] static inline Universe* Get(lua_State* L_); | ||
184 | void initializeAllocatorFunction(lua_State* L_); | 189 | void initializeAllocatorFunction(lua_State* L_); |
185 | static int InitializeFinalizer(lua_State* L_); | 190 | static int InitializeFinalizer(lua_State* L_); |
186 | void initializeKeepers(lua_State* L_); | 191 | void initializeKeepers(lua_State* L_); |
192 | static inline void Store(lua_State* L_, Universe* U_); | ||
187 | void terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTimeout_, CancelOp op_); | 193 | void terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTimeout_, CancelOp op_); |
188 | }; | 194 | }; |
189 | 195 | ||
190 | // ################################################################################################# | 196 | // ################################################################################################# |
191 | 197 | ||
192 | [[nodiscard]] Universe* universe_get(lua_State* L_); | 198 | inline Universe* Universe::Get(lua_State* L_) |
193 | [[nodiscard]] Universe* universe_create(lua_State* L_); | ||
194 | void universe_store(lua_State* L_, Universe* U_); | ||
195 | |||
196 | // ################################################################################################# | ||
197 | |||
198 | [[nodiscard]] inline Universe* universe_get(lua_State* L_) | ||
199 | { | 199 | { |
200 | STACK_CHECK_START_REL(L_, 0); | 200 | STACK_CHECK_START_REL(L_, 0); |
201 | Universe* const _universe{ kUniverseLightRegKey.readLightUserDataValue<Universe>(L_) }; | 201 | Universe* const _universe{ kUniverseLightRegKey.readLightUserDataValue<Universe>(L_) }; |
@@ -205,9 +205,10 @@ void universe_store(lua_State* L_, Universe* U_); | |||
205 | 205 | ||
206 | // ################################################################################################# | 206 | // ################################################################################################# |
207 | 207 | ||
208 | inline void universe_store(lua_State* L_, Universe* U_) | 208 | inline void Universe::Store(lua_State* L_, Universe* U_) |
209 | { | 209 | { |
210 | LUA_ASSERT(L_, !U_ || universe_get(L_) == nullptr); | 210 | // TODO: check if we actually ever call Store with a null universe |
211 | LUA_ASSERT(L_, !U_ || Universe::Get(L_) == nullptr); | ||
211 | STACK_CHECK_START_REL(L_, 0); | 212 | STACK_CHECK_START_REL(L_, 0); |
212 | kUniverseLightRegKey.setValue(L_, [U = U_](lua_State* L_) { U ? lua_pushlightuserdata(L_, U) : lua_pushnil(L_); }); | 213 | kUniverseLightRegKey.setValue(L_, [U = U_](lua_State* L_) { U ? lua_pushlightuserdata(L_, U) : lua_pushnil(L_); }); |
213 | STACK_CHECK(L_, 0); | 214 | STACK_CHECK(L_, 0); |
@@ -215,4 +216,4 @@ inline void universe_store(lua_State* L_, Universe* U_) | |||
215 | 216 | ||
216 | // ################################################################################################# | 217 | // ################################################################################################# |
217 | 218 | ||
218 | int universe_gc(lua_State* L_); | 219 | LUAG_FUNC(universe_gc); |