diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-11-20 17:51:49 +0100 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-11-20 17:51:49 +0100 |
| commit | 304e4dfabe4555dff4aa72e75b677405fd30d1b3 (patch) | |
| tree | ac934000415b46f784bda25ba671e74b9481573b | |
| parent | 872826ecaca5370e3492385cff3795d995b33ec7 (diff) | |
| download | lanes-304e4dfabe4555dff4aa72e75b677405fd30d1b3.tar.gz lanes-304e4dfabe4555dff4aa72e75b677405fd30d1b3.tar.bz2 lanes-304e4dfabe4555dff4aa72e75b677405fd30d1b3.zip | |
Some [[nodiscard]] boyscouting
| -rw-r--r-- | src/allocator.hpp | 10 | ||||
| -rw-r--r-- | src/cancel.hpp | 10 | ||||
| -rw-r--r-- | src/compat.hpp | 26 | ||||
| -rw-r--r-- | src/deep.hpp | 15 | ||||
| -rw-r--r-- | src/intercopycontext.hpp | 57 | ||||
| -rw-r--r-- | src/keeper.hpp | 44 | ||||
| -rw-r--r-- | src/lane.hpp | 39 | ||||
| -rw-r--r-- | src/linda.hpp | 26 | ||||
| -rw-r--r-- | src/lindafactory.hpp | 6 | ||||
| -rw-r--r-- | src/state.hpp | 7 | ||||
| -rw-r--r-- | src/threading_osx.h | 9 | ||||
| -rw-r--r-- | src/tools.hpp | 8 | ||||
| -rw-r--r-- | src/tracker.hpp | 9 | ||||
| -rw-r--r-- | src/unique.hpp | 6 | ||||
| -rw-r--r-- | src/uniquekey.hpp | 9 | ||||
| -rw-r--r-- | src/universe.hpp | 19 |
16 files changed, 201 insertions, 99 deletions
diff --git a/src/allocator.hpp b/src/allocator.hpp index 4fec044..16db1e6 100644 --- a/src/allocator.hpp +++ b/src/allocator.hpp | |||
| @@ -25,8 +25,10 @@ namespace lanes { | |||
| 25 | 25 | ||
| 26 | public: | 26 | public: |
| 27 | 27 | ||
| 28 | [[nodiscard]] static void* operator new(size_t const size_) noexcept = delete; // can't create one outside of a Lua state | 28 | [[nodiscard]] |
| 29 | [[nodiscard]] static void* operator new(size_t const size_, lua_State* const L_) noexcept { return lua_newuserdatauv(L_, size_, UserValueCount{ 0 }); } | 29 | static void* operator new(size_t const size_) noexcept = delete; // can't create one outside of a Lua state |
| 30 | [[nodiscard]] | ||
| 31 | static void* operator new(size_t const size_, lua_State* const L_) noexcept { return lua_newuserdatauv(L_, size_, UserValueCount{ 0 }); } | ||
| 30 | // always embedded somewhere else or "in-place constructed" as a full userdata | 32 | // always embedded somewhere else or "in-place constructed" as a full userdata |
| 31 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | 33 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception |
| 32 | static void operator delete([[maybe_unused]] void* const p_, [[maybe_unused]] lua_State* const L_) {} | 34 | static void operator delete([[maybe_unused]] void* const p_, [[maybe_unused]] lua_State* const L_) {} |
| @@ -44,6 +46,7 @@ namespace lanes { | |||
| 44 | AllocatorDefinition& operator=(AllocatorDefinition const& rhs_) = default; | 46 | AllocatorDefinition& operator=(AllocatorDefinition const& rhs_) = default; |
| 45 | AllocatorDefinition& operator=(AllocatorDefinition&& rhs_) = default; | 47 | AllocatorDefinition& operator=(AllocatorDefinition&& rhs_) = default; |
| 46 | 48 | ||
| 49 | [[nodiscard]] | ||
| 47 | static AllocatorDefinition& Validated(lua_State* L_, StackIndex idx_); | 50 | static AllocatorDefinition& Validated(lua_State* L_, StackIndex idx_); |
| 48 | 51 | ||
| 49 | void initFrom(lua_State* const L_) | 52 | void initFrom(lua_State* const L_) |
| @@ -58,16 +61,19 @@ namespace lanes { | |||
| 58 | } | 61 | } |
| 59 | } | 62 | } |
| 60 | 63 | ||
| 64 | [[nodiscard]] | ||
| 61 | lua_State* newState() const | 65 | lua_State* newState() const |
| 62 | { | 66 | { |
| 63 | return lua_newstate(allocF, allocUD); | 67 | return lua_newstate(allocF, allocUD); |
| 64 | } | 68 | } |
| 65 | 69 | ||
| 70 | [[nodiscard]] | ||
| 66 | void* alloc(size_t const nsize_) | 71 | void* alloc(size_t const nsize_) |
| 67 | { | 72 | { |
| 68 | return allocF(allocUD, nullptr, 0, nsize_); | 73 | return allocF(allocUD, nullptr, 0, nsize_); |
| 69 | } | 74 | } |
| 70 | 75 | ||
| 76 | [[nodiscard]] | ||
| 71 | void* alloc(void* const ptr_, size_t const osize_, size_t const nsize_) | 77 | void* alloc(void* const ptr_, size_t const osize_, size_t const nsize_) |
| 72 | { | 78 | { |
| 73 | return allocF(allocUD, ptr_, osize_, nsize_); | 79 | return allocF(allocUD, ptr_, osize_, nsize_); |
diff --git a/src/cancel.hpp b/src/cancel.hpp index 7230169..8f4cf07 100644 --- a/src/cancel.hpp +++ b/src/cancel.hpp | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | enum class CancelRequest | 9 | enum class CancelRequest |
| 10 | { | 10 | { |
| 11 | None, // no pending cancel request | 11 | None, // no pending cancel request |
| 12 | // TODO: add a Wake mode: user wants to wake the waiting lindas (in effect resulting in a timeout before the initial operation duration) | ||
| 13 | Soft, // user wants the lane to cancel itself manually on cancel_test() | 12 | Soft, // user wants the lane to cancel itself manually on cancel_test() |
| 14 | Hard // user wants the lane to be interrupted (meaning code won't return from those functions) from inside linda:send/receive calls | 13 | Hard // user wants the lane to be interrupted (meaning code won't return from those functions) from inside linda:send/receive calls |
| 15 | }; | 14 | }; |
| @@ -42,12 +41,15 @@ static constexpr UniqueKey kCancelError{ 0x0630345FEF912746ull, "lanes.cancel_er | |||
| 42 | 41 | ||
| 43 | // ################################################################################################# | 42 | // ################################################################################################# |
| 44 | 43 | ||
| 45 | [[nodiscard]] CancelRequest CheckCancelRequest(lua_State* L_); | 44 | [[nodiscard]] |
| 46 | [[nodiscard]] CancelOp WhichCancelOp(std::string_view const& opString_); | 45 | CancelRequest CheckCancelRequest(lua_State* L_); |
| 46 | [[nodiscard]] | ||
| 47 | CancelOp WhichCancelOp(std::string_view const& opString_); | ||
| 47 | 48 | ||
| 48 | // ################################################################################################# | 49 | // ################################################################################################# |
| 49 | 50 | ||
| 50 | [[noreturn]] static inline void raise_cancel_error(lua_State* const L_) | 51 | [[noreturn]] |
| 52 | static inline void raise_cancel_error(lua_State* const L_) | ||
| 51 | { | 53 | { |
| 52 | STACK_GROW(L_, 1); | 54 | STACK_GROW(L_, 1); |
| 53 | kCancelError.pushKey(L_); // special error value | 55 | kCancelError.pushKey(L_); // special error value |
diff --git a/src/compat.hpp b/src/compat.hpp index 59c8001..f66f703 100644 --- a/src/compat.hpp +++ b/src/compat.hpp | |||
| @@ -115,6 +115,7 @@ enum class LuaError | |||
| 115 | ERRFILE = LUA_ERRFILE | 115 | ERRFILE = LUA_ERRFILE |
| 116 | }; | 116 | }; |
| 117 | 117 | ||
| 118 | [[nodiscard]] | ||
| 118 | inline constexpr LuaError ToLuaError(int const rc_) | 119 | inline constexpr LuaError ToLuaError(int const rc_) |
| 119 | { | 120 | { |
| 120 | assert(rc_ == LUA_OK || rc_ == LUA_YIELD || rc_ == LUA_ERRRUN || rc_ == LUA_ERRSYNTAX || rc_ == LUA_ERRMEM || rc_ == LUA_ERRGCMM || rc_ == LUA_ERRERR || rc_ == LUA_ERRFILE); | 121 | assert(rc_ == LUA_OK || rc_ == LUA_YIELD || rc_ == LUA_ERRRUN || rc_ == LUA_ERRSYNTAX || rc_ == LUA_ERRMEM || rc_ == LUA_ERRGCMM || rc_ == LUA_ERRERR || rc_ == LUA_ERRFILE); |
| @@ -124,6 +125,7 @@ inline constexpr LuaError ToLuaError(int const rc_) | |||
| 124 | // ################################################################################################# | 125 | // ################################################################################################# |
| 125 | 126 | ||
| 126 | // break lexical order for that one because it's needed below | 127 | // break lexical order for that one because it's needed below |
| 128 | [[nodiscard]] | ||
| 127 | inline LuaType luaG_type(lua_State* const L_, StackIndex const idx_) | 129 | inline LuaType luaG_type(lua_State* const L_, StackIndex const idx_) |
| 128 | { | 130 | { |
| 129 | return static_cast<LuaType>(lua_type(L_, idx_)); | 131 | return static_cast<LuaType>(lua_type(L_, idx_)); |
| @@ -139,21 +141,24 @@ inline LuaType luaG_type(lua_State* const L_, StackIndex const idx_) | |||
| 139 | #define STRINGVIEW_FMT "%.*s" | 141 | #define STRINGVIEW_FMT "%.*s" |
| 140 | 142 | ||
| 141 | // a replacement of lua_tolstring | 143 | // a replacement of lua_tolstring |
| 142 | [[nodiscard]] inline std::string_view luaG_tostring(lua_State* const L_, StackIndex const idx_) | 144 | [[nodiscard]] |
| 145 | inline std::string_view luaG_tostring(lua_State* const L_, StackIndex const idx_) | ||
| 143 | { | 146 | { |
| 144 | size_t _len{ 0 }; | 147 | size_t _len{ 0 }; |
| 145 | char const* _str{ lua_tolstring(L_, idx_, &_len) }; | 148 | char const* _str{ lua_tolstring(L_, idx_, &_len) }; |
| 146 | return _str ? std::string_view{ _str, _len } : ""; | 149 | return _str ? std::string_view{ _str, _len } : ""; |
| 147 | } | 150 | } |
| 148 | 151 | ||
| 149 | [[nodiscard]] inline std::string_view luaG_checkstring(lua_State* const L_, StackIndex const idx_) | 152 | [[nodiscard]] |
| 153 | inline std::string_view luaG_checkstring(lua_State* const L_, StackIndex const idx_) | ||
| 150 | { | 154 | { |
| 151 | size_t _len{ 0 }; | 155 | size_t _len{ 0 }; |
| 152 | char const* _str{ luaL_checklstring(L_, idx_, &_len) }; | 156 | char const* _str{ luaL_checklstring(L_, idx_, &_len) }; |
| 153 | return std::string_view{ _str, _len }; | 157 | return std::string_view{ _str, _len }; |
| 154 | } | 158 | } |
| 155 | 159 | ||
| 156 | [[nodiscard]] inline std::string_view luaG_optstring(lua_State* const L_, StackIndex const idx_, std::string_view const& default_) | 160 | [[nodiscard]] |
| 161 | inline std::string_view luaG_optstring(lua_State* const L_, StackIndex const idx_, std::string_view const& default_) | ||
| 157 | { | 162 | { |
| 158 | if (lua_isnoneornil(L_, idx_)) { | 163 | if (lua_isnoneornil(L_, idx_)) { |
| 159 | return default_; | 164 | return default_; |
| @@ -352,7 +357,8 @@ static inline void luaG_newlib(lua_State* const L_, luaL_Reg const (&funcs_)[N]) | |||
| 352 | // ################################################################################################# | 357 | // ################################################################################################# |
| 353 | 358 | ||
| 354 | template <typename T> | 359 | template <typename T> |
| 355 | [[nodiscard]] T* luaG_newuserdatauv(lua_State* L_, UserValueCount nuvalue_) | 360 | [[nodiscard]] |
| 361 | T* luaG_newuserdatauv(lua_State* const L_, UserValueCount const nuvalue_) | ||
| 356 | { | 362 | { |
| 357 | return static_cast<T*>(lua_newuserdatauv(L_, sizeof(T), nuvalue_)); | 363 | return static_cast<T*>(lua_newuserdatauv(L_, sizeof(T), nuvalue_)); |
| 358 | } | 364 | } |
| @@ -394,7 +400,8 @@ inline void luaG_setmetatable(lua_State* const L_, std::string_view const& tname | |||
| 394 | 400 | ||
| 395 | // a small helper to extract a full userdata pointer from the stack in a safe way | 401 | // a small helper to extract a full userdata pointer from the stack in a safe way |
| 396 | template <typename T> | 402 | template <typename T> |
| 397 | [[nodiscard]] T* luaG_tofulluserdata(lua_State* const L_, StackIndex const index_) | 403 | [[nodiscard]] |
| 404 | T* luaG_tofulluserdata(lua_State* const L_, StackIndex const index_) | ||
| 398 | { | 405 | { |
| 399 | LUA_ASSERT(L_, lua_isnil(L_, index_) || lua_type(L_, index_) == LUA_TUSERDATA); | 406 | LUA_ASSERT(L_, lua_isnil(L_, index_) || lua_type(L_, index_) == LUA_TUSERDATA); |
| 400 | return static_cast<T*>(lua_touserdata(L_, index_)); | 407 | return static_cast<T*>(lua_touserdata(L_, index_)); |
| @@ -403,7 +410,8 @@ template <typename T> | |||
| 403 | // ------------------------------------------------------------------------------------------------- | 410 | // ------------------------------------------------------------------------------------------------- |
| 404 | 411 | ||
| 405 | template <typename T> | 412 | template <typename T> |
| 406 | [[nodiscard]] auto luaG_tolightuserdata(lua_State* const L_, StackIndex const index_) | 413 | [[nodiscard]] |
| 414 | auto luaG_tolightuserdata(lua_State* const L_, StackIndex const index_) | ||
| 407 | { | 415 | { |
| 408 | LUA_ASSERT(L_, lua_isnil(L_, index_) || lua_islightuserdata(L_, index_)); | 416 | LUA_ASSERT(L_, lua_isnil(L_, index_) || lua_islightuserdata(L_, index_)); |
| 409 | if constexpr (std::is_pointer_v<T>) { | 417 | if constexpr (std::is_pointer_v<T>) { |
| @@ -415,14 +423,16 @@ template <typename T> | |||
| 415 | 423 | ||
| 416 | // ------------------------------------------------------------------------------------------------- | 424 | // ------------------------------------------------------------------------------------------------- |
| 417 | 425 | ||
| 418 | [[nodiscard]] inline std::string_view luaG_typename(lua_State* const L_, LuaType const t_) | 426 | [[nodiscard]] |
| 427 | inline std::string_view luaG_typename(lua_State* const L_, LuaType const t_) | ||
| 419 | { | 428 | { |
| 420 | return lua_typename(L_, static_cast<int>(t_)); | 429 | return lua_typename(L_, static_cast<int>(t_)); |
| 421 | } | 430 | } |
| 422 | 431 | ||
| 423 | // ------------------------------------------------------------------------------------------------- | 432 | // ------------------------------------------------------------------------------------------------- |
| 424 | 433 | ||
| 425 | [[nodiscard]] inline std::string_view luaG_typename(lua_State* const L_, StackIndex const idx_) | 434 | [[nodiscard]] |
| 435 | inline std::string_view luaG_typename(lua_State* const L_, StackIndex const idx_) | ||
| 426 | { | 436 | { |
| 427 | return luaG_typename(L_, luaG_type(L_, idx_)); | 437 | return luaG_typename(L_, luaG_type(L_, idx_)); |
| 428 | } | 438 | } |
diff --git a/src/deep.hpp b/src/deep.hpp index 3956f71..6fa12b1 100644 --- a/src/deep.hpp +++ b/src/deep.hpp | |||
| @@ -57,8 +57,10 @@ class DeepFactory | |||
| 57 | // NVI: private overrides | 57 | // NVI: private overrides |
| 58 | virtual void createMetatable(lua_State* L_) const = 0; | 58 | virtual void createMetatable(lua_State* L_) const = 0; |
| 59 | virtual void deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const = 0; | 59 | virtual void deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const = 0; |
| 60 | [[nodiscard]] virtual DeepPrelude* newDeepObjectInternal(lua_State* L_) const = 0; | 60 | [[nodiscard]] |
| 61 | [[nodiscard]] virtual std::string_view moduleName() const = 0; | 61 | virtual DeepPrelude* newDeepObjectInternal(lua_State* L_) const = 0; |
| 62 | [[nodiscard]] | ||
| 63 | virtual std::string_view moduleName() const = 0; | ||
| 62 | 64 | ||
| 63 | private: | 65 | private: |
| 64 | void storeDeepLookup(lua_State* L_) const; | 66 | void storeDeepLookup(lua_State* L_) const; |
| @@ -66,11 +68,14 @@ class DeepFactory | |||
| 66 | public: | 68 | public: |
| 67 | // NVI: public interface | 69 | // NVI: public interface |
| 68 | static void DeleteDeepObject(lua_State* L_, DeepPrelude* o_); | 70 | static void DeleteDeepObject(lua_State* L_, DeepPrelude* o_); |
| 69 | [[nodiscard]] static bool IsDeepUserdata(lua_State* const L_, StackIndex const idx_); | 71 | [[nodiscard]] |
| 70 | [[nodiscard]] static DeepFactory* LookupFactory(lua_State* L_, StackIndex index_, LookupMode mode_); | 72 | static bool IsDeepUserdata(lua_State* const L_, StackIndex const idx_); |
| 73 | [[nodiscard]] | ||
| 74 | static DeepFactory* LookupFactory(lua_State* L_, StackIndex index_, LookupMode mode_); | ||
| 71 | static void PushDeepProxy(DestState L_, DeepPrelude* o_, UserValueCount nuv_, LookupMode mode_, lua_State* errL_); | 75 | static void PushDeepProxy(DestState L_, DeepPrelude* o_, UserValueCount nuv_, LookupMode mode_, lua_State* errL_); |
| 72 | void pushDeepUserdata(DestState L_, UserValueCount nuv_) const; | 76 | void pushDeepUserdata(DestState L_, UserValueCount nuv_) const; |
| 73 | [[nodiscard]] DeepPrelude* toDeep(lua_State* L_, StackIndex index_) const; | 77 | [[nodiscard]] |
| 78 | DeepPrelude* toDeep(lua_State* L_, StackIndex index_) const; | ||
| 74 | }; | 79 | }; |
| 75 | 80 | ||
| 76 | // ################################################################################################# | 81 | // ################################################################################################# |
diff --git a/src/intercopycontext.hpp b/src/intercopycontext.hpp index 2b247d2..84d9e70 100644 --- a/src/intercopycontext.hpp +++ b/src/intercopycontext.hpp | |||
| @@ -38,11 +38,13 @@ class InterCopyContext | |||
| 38 | std::string_view name; // that one can change when we reuse the context | 38 | std::string_view name; // that one can change when we reuse the context |
| 39 | 39 | ||
| 40 | private: | 40 | private: |
| 41 | [[nodiscard]] std::string_view findLookupName() const; | 41 | [[nodiscard]] |
| 42 | std::string_view findLookupName() const; | ||
| 42 | // when mode == LookupMode::FromKeeper, L1 is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error | 43 | // when mode == LookupMode::FromKeeper, L1 is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error |
| 43 | // whon mode != LookupMode::FromKeeper, L1 is not a keeper state, therefore L1 is the state where we want to raise the error | 44 | // whon mode != LookupMode::FromKeeper, L1 is not a keeper state, therefore L1 is the state where we want to raise the error |
| 44 | lua_State* getErrL() const { return (mode == LookupMode::FromKeeper) ? L2.value() : L1.value(); } | 45 | lua_State* getErrL() const { return (mode == LookupMode::FromKeeper) ? L2.value() : L1.value(); } |
| 45 | [[nodiscard]] LuaType processConversion() const; | 46 | [[nodiscard]] |
| 47 | LuaType processConversion() const; | ||
| 46 | 48 | ||
| 47 | // for use in copyCachedFunction | 49 | // for use in copyCachedFunction |
| 48 | void copyFunction() const; | 50 | void copyFunction() const; |
| @@ -50,30 +52,47 @@ class InterCopyContext | |||
| 50 | 52 | ||
| 51 | // for use in inter_copy_function | 53 | // for use in inter_copy_function |
| 52 | void copyCachedFunction() const; | 54 | void copyCachedFunction() const; |
| 53 | [[nodiscard]] bool lookupTable() const; | 55 | [[nodiscard]] |
| 56 | bool lookupTable() const; | ||
| 54 | 57 | ||
| 55 | // for use in inter_copy_table | 58 | // for use in inter_copy_table |
| 56 | void interCopyKeyValuePair() const; | 59 | void interCopyKeyValuePair() const; |
| 57 | [[nodiscard]] bool pushCachedMetatable() const; | 60 | [[nodiscard]] |
| 58 | [[nodiscard]] bool pushCachedTable() const; | 61 | bool pushCachedMetatable() const; |
| 62 | [[nodiscard]] | ||
| 63 | bool pushCachedTable() const; | ||
| 59 | 64 | ||
| 60 | // for use in inter_copy_userdata | 65 | // for use in inter_copy_userdata |
| 61 | [[nodiscard]] bool tryCopyClonable() const; | 66 | [[nodiscard]] |
| 62 | [[nodiscard]] bool tryCopyDeep() const; | 67 | bool tryCopyClonable() const; |
| 68 | [[nodiscard]] | ||
| 69 | bool tryCopyDeep() const; | ||
| 63 | 70 | ||
| 64 | // copying a single Lua stack item | 71 | // copying a single Lua stack item |
| 65 | [[nodiscard]] bool interCopyBoolean() const; | 72 | [[nodiscard]] |
| 66 | [[nodiscard]] bool interCopyFunction() const; | 73 | bool interCopyBoolean() const; |
| 67 | [[nodiscard]] bool interCopyLightuserdata() const; | 74 | [[nodiscard]] |
| 68 | [[nodiscard]] bool interCopyNil() const; | 75 | bool interCopyFunction() const; |
| 69 | [[nodiscard]] bool interCopyNumber() const; | 76 | [[nodiscard]] |
| 70 | [[nodiscard]] bool interCopyString() const; | 77 | bool interCopyLightuserdata() const; |
| 71 | [[nodiscard]] bool interCopyTable() const; | 78 | [[nodiscard]] |
| 72 | [[nodiscard]] bool interCopyUserdata() const; | 79 | bool interCopyNil() const; |
| 80 | [[nodiscard]] | ||
| 81 | bool interCopyNumber() const; | ||
| 82 | [[nodiscard]] | ||
| 83 | bool interCopyString() const; | ||
| 84 | [[nodiscard]] | ||
| 85 | bool interCopyTable() const; | ||
| 86 | [[nodiscard]] | ||
| 87 | bool interCopyUserdata() const; | ||
| 73 | 88 | ||
| 74 | public: | 89 | public: |
| 75 | [[nodiscard]] InterCopyResult interCopy(int n_) const; | 90 | [[nodiscard]] |
| 76 | [[nodiscard]] InterCopyResult interCopyOne() const; | 91 | InterCopyResult interCopy(int n_) const; |
| 77 | [[nodiscard]] InterCopyResult interCopyPackage() const; | 92 | [[nodiscard]] |
| 78 | [[nodiscard]] InterCopyResult interMove(int n_) const; | 93 | InterCopyResult interCopyOne() const; |
| 94 | [[nodiscard]] | ||
| 95 | InterCopyResult interCopyPackage() const; | ||
| 96 | [[nodiscard]] | ||
| 97 | InterCopyResult interMove(int n_) const; | ||
| 79 | }; | 98 | }; |
diff --git a/src/keeper.hpp b/src/keeper.hpp index 2354c2e..b77f1a9 100644 --- a/src/keeper.hpp +++ b/src/keeper.hpp | |||
| @@ -18,7 +18,8 @@ struct Keeper | |||
| 18 | std::mutex mutex; | 18 | std::mutex mutex; |
| 19 | KeeperState K{ static_cast<lua_State*>(nullptr) }; | 19 | KeeperState K{ static_cast<lua_State*>(nullptr) }; |
| 20 | 20 | ||
| 21 | [[nodiscard]] static void* operator new[](size_t size_, Universe* U_) noexcept; | 21 | [[nodiscard]] |
| 22 | static void* operator new[](size_t size_, Universe* U_) noexcept; | ||
| 22 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | 23 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception |
| 23 | static void operator delete[](void* p_, Universe* U_); | 24 | static void operator delete[](void* p_, Universe* U_); |
| 24 | 25 | ||
| @@ -31,7 +32,8 @@ struct Keeper | |||
| 31 | Keeper& operator=(Keeper const&) = delete; | 32 | Keeper& operator=(Keeper const&) = delete; |
| 32 | Keeper& operator=(Keeper const&&) = delete; | 33 | Keeper& operator=(Keeper const&&) = delete; |
| 33 | 34 | ||
| 34 | [[nodiscard]] static int PushLindaStorage(Linda& linda_, DestState L_); | 35 | [[nodiscard]] |
| 36 | static int PushLindaStorage(Linda& linda_, DestState L_); | ||
| 35 | }; | 37 | }; |
| 36 | 38 | ||
| 37 | // ################################################################################################# | 39 | // ################################################################################################# |
| @@ -63,13 +65,17 @@ struct Keepers | |||
| 63 | 65 | ||
| 64 | Keepers() = default; | 66 | Keepers() = default; |
| 65 | void close(); | 67 | void close(); |
| 66 | [[nodiscard]] Keeper* getKeeper(KeeperIndex idx_); | 68 | [[nodiscard]] |
| 67 | [[nodiscard]] int getNbKeepers() const; | 69 | Keeper* getKeeper(KeeperIndex idx_); |
| 70 | [[nodiscard]] | ||
| 71 | int getNbKeepers() const; | ||
| 68 | void initialize(Universe& U_, lua_State* L_, size_t nbKeepers_, int gc_threshold_); | 72 | void initialize(Universe& U_, lua_State* L_, size_t nbKeepers_, int gc_threshold_); |
| 69 | }; | 73 | }; |
| 70 | 74 | ||
| 71 | // ################################################################################################# | 75 | // ################################################################################################# |
| 72 | 76 | ||
| 77 | DECLARE_UNIQUE_TYPE(KeeperCallResult, std::optional<int>); | ||
| 78 | |||
| 73 | // xxh64 of string "kNilSentinel" generated at https://www.pelock.com/products/hash-calculator | 79 | // xxh64 of string "kNilSentinel" generated at https://www.pelock.com/products/hash-calculator |
| 74 | static constexpr UniqueKey kNilSentinel{ 0xC457D4EDDB05B5E4ull, "lanes.null" }; | 80 | static constexpr UniqueKey kNilSentinel{ 0xC457D4EDDB05B5E4ull, "lanes.null" }; |
| 75 | 81 | ||
| @@ -77,14 +83,22 @@ using keeper_api_t = lua_CFunction; | |||
| 77 | #define KEEPER_API(_op) keepercall_##_op | 83 | #define KEEPER_API(_op) keepercall_##_op |
| 78 | 84 | ||
| 79 | // lua_Cfunctions to run inside a keeper state | 85 | // lua_Cfunctions to run inside a keeper state |
| 80 | [[nodiscard]] int keepercall_count(lua_State* L_); | 86 | [[nodiscard]] |
| 81 | [[nodiscard]] int keepercall_destruct(lua_State* L_); | 87 | int keepercall_count(lua_State* L_); |
| 82 | [[nodiscard]] int keepercall_get(lua_State* L_); | 88 | [[nodiscard]] |
| 83 | [[nodiscard]] int keepercall_limit(lua_State* L_); | 89 | int keepercall_destruct(lua_State* L_); |
| 84 | [[nodiscard]] int keepercall_receive(lua_State* L_); | 90 | [[nodiscard]] |
| 85 | [[nodiscard]] int keepercall_receive_batched(lua_State* L_); | 91 | int keepercall_get(lua_State* L_); |
| 86 | [[nodiscard]] int keepercall_send(lua_State* L_); | 92 | [[nodiscard]] |
| 87 | [[nodiscard]] int keepercall_set(lua_State* L_); | 93 | int keepercall_limit(lua_State* L_); |
| 88 | 94 | [[nodiscard]] | |
| 89 | DECLARE_UNIQUE_TYPE(KeeperCallResult, std::optional<int>); | 95 | int keepercall_receive(lua_State* L_); |
| 90 | [[nodiscard]] KeeperCallResult keeper_call(KeeperState K_, keeper_api_t func_, lua_State* L_, Linda* linda_, StackIndex starting_index_); | 96 | [[nodiscard]] |
| 97 | int keepercall_receive_batched(lua_State* L_); | ||
| 98 | [[nodiscard]] | ||
| 99 | int keepercall_send(lua_State* L_); | ||
| 100 | [[nodiscard]] | ||
| 101 | int keepercall_set(lua_State* L_); | ||
| 102 | |||
| 103 | [[nodiscard]] | ||
| 104 | KeeperCallResult keeper_call(KeeperState K_, keeper_api_t func_, lua_State* L_, Linda* linda_, StackIndex starting_index_); | ||
diff --git a/src/lane.hpp b/src/lane.hpp index b5be9ab..29bf213 100644 --- a/src/lane.hpp +++ b/src/lane.hpp | |||
| @@ -139,7 +139,8 @@ class Lane | |||
| 139 | 139 | ||
| 140 | ErrorTraceLevel const errorTraceLevel{ Basic }; | 140 | ErrorTraceLevel const errorTraceLevel{ Basic }; |
| 141 | 141 | ||
| 142 | [[nodiscard]] static void* operator new(size_t size_, Universe* U_) noexcept { return U_->internalAllocator.alloc(size_); } | 142 | [[nodiscard]] |
| 143 | static void* operator new(size_t size_, Universe* U_) noexcept { return U_->internalAllocator.alloc(size_); } | ||
| 143 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | 144 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception |
| 144 | static void operator delete(void* p_, Universe* U_) { U_->internalAllocator.free(p_, sizeof(Lane)); } | 145 | static void operator delete(void* p_, Universe* U_) { U_->internalAllocator.free(p_, sizeof(Lane)); } |
| 145 | // this one is for us, to make sure memory is freed by the correct allocator | 146 | // this one is for us, to make sure memory is freed by the correct allocator |
| @@ -156,7 +157,8 @@ class Lane | |||
| 156 | 157 | ||
| 157 | private: | 158 | private: |
| 158 | 159 | ||
| 159 | [[nodiscard]] CancelResult internalCancel(CancelRequest rq_, std::chrono::time_point<std::chrono::steady_clock> until_, WakeLane wakeLane_); | 160 | [[nodiscard]] |
| 161 | CancelResult internalCancel(CancelRequest rq_, std::chrono::time_point<std::chrono::steady_clock> until_, WakeLane wakeLane_); | ||
| 160 | 162 | ||
| 161 | public: | 163 | public: |
| 162 | 164 | ||
| @@ -170,33 +172,43 @@ class Lane | |||
| 170 | nresults = 0; | 172 | nresults = 0; |
| 171 | lua_close(_L); // this collects our coroutine thread at the same time | 173 | lua_close(_L); // this collects our coroutine thread at the same time |
| 172 | } | 174 | } |
| 173 | [[nodiscard]] std::string_view errorTraceLevelString() const; | 175 | [[nodiscard]] |
| 174 | [[nodiscard]] int errorHandlerCount() const noexcept | 176 | std::string_view errorTraceLevelString() const; |
| 177 | [[nodiscard]] | ||
| 178 | int errorHandlerCount() const noexcept | ||
| 175 | { | 179 | { |
| 176 | // don't push a error handler when in coroutine mode, as the first lua_resume wants only the function and its arguments on the stack | 180 | // don't push a error handler when in coroutine mode, as the first lua_resume wants only the function and its arguments on the stack |
| 177 | return ((errorTraceLevel == Lane::Minimal) || isCoroutine()) ? 0 : 1; | 181 | return ((errorTraceLevel == Lane::Minimal) || isCoroutine()) ? 0 : 1; |
| 178 | } | 182 | } |
| 179 | [[nodiscard]] bool isCoroutine() const noexcept { return S != L; } | 183 | [[nodiscard]] |
| 180 | [[nodiscard]] std::string_view getDebugName() const | 184 | bool isCoroutine() const noexcept { return S != L; } |
| 185 | [[nodiscard]] | ||
| 186 | std::string_view getDebugName() const | ||
| 181 | { | 187 | { |
| 182 | std::lock_guard<std::mutex> _guard{ debugNameMutex }; | 188 | std::lock_guard<std::mutex> _guard{ debugNameMutex }; |
| 183 | return debugName; | 189 | return debugName; |
| 184 | } | 190 | } |
| 185 | static int LuaErrorHandler(lua_State* L_); | 191 | static int LuaErrorHandler(lua_State* L_); |
| 186 | [[nodiscard]] int pushErrorHandler() const noexcept { return (errorHandlerCount() == 0) ? 0 : (lua_pushcfunction(L, LuaErrorHandler), 1); } | 192 | [[nodiscard]] |
| 187 | [[nodiscard]] std::string_view pushErrorTraceLevel(lua_State* L_) const; | 193 | int pushErrorHandler() const noexcept { return (errorHandlerCount() == 0) ? 0 : (lua_pushcfunction(L, LuaErrorHandler), 1); } |
| 194 | [[nodiscard]] | ||
| 195 | std::string_view pushErrorTraceLevel(lua_State* L_) const; | ||
| 188 | static void PushMetatable(lua_State* L_); | 196 | static void PushMetatable(lua_State* L_); |
| 189 | void pushStatusString(lua_State* L_) const; | 197 | void pushStatusString(lua_State* L_) const; |
| 190 | void pushIndexedResult(lua_State* L_, int key_) const; | 198 | void pushIndexedResult(lua_State* L_, int key_) const; |
| 191 | void resetResultsStorage(lua_State* L_, StackIndex self_idx_); | 199 | void resetResultsStorage(lua_State* L_, StackIndex self_idx_); |
| 192 | void selfdestructAdd(); | 200 | void selfdestructAdd(); |
| 193 | [[nodiscard]] bool selfdestructRemove(); | 201 | [[nodiscard]] |
| 202 | bool selfdestructRemove(); | ||
| 194 | void securizeDebugName(lua_State* L_); | 203 | void securizeDebugName(lua_State* L_); |
| 195 | void startThread(int priority_); | 204 | void startThread(int priority_); |
| 196 | [[nodiscard]] int storeResults(lua_State* L_); | 205 | [[nodiscard]] |
| 197 | [[nodiscard]] std::string_view threadStatusString() const; | 206 | int storeResults(lua_State* L_); |
| 207 | [[nodiscard]] | ||
| 208 | std::string_view threadStatusString() const; | ||
| 198 | // wait until the lane stops working with its state (either Suspended or Done+) | 209 | // wait until the lane stops working with its state (either Suspended or Done+) |
| 199 | [[nodiscard]] bool waitForCompletion(std::chrono::time_point<std::chrono::steady_clock> until_); | 210 | [[nodiscard]] |
| 211 | bool waitForCompletion(std::chrono::time_point<std::chrono::steady_clock> until_); | ||
| 200 | }; | 212 | }; |
| 201 | 213 | ||
| 202 | // ################################################################################################# | 214 | // ################################################################################################# |
| @@ -205,7 +217,8 @@ class Lane | |||
| 205 | // 'Lane' are malloc/free'd and the handle only carries a pointer. | 217 | // 'Lane' are malloc/free'd and the handle only carries a pointer. |
| 206 | // This is not deep userdata since the handle is not portable among lanes. | 218 | // This is not deep userdata since the handle is not portable among lanes. |
| 207 | // | 219 | // |
| 208 | [[nodiscard]] inline Lane* ToLane(lua_State* const L_, StackIndex const i_) | 220 | [[nodiscard]] |
| 221 | static inline Lane* ToLane(lua_State* const L_, StackIndex const i_) | ||
| 209 | { | 222 | { |
| 210 | return *(static_cast<Lane**>(luaL_checkudata(L_, i_, kLaneMetatableName.data()))); | 223 | return *(static_cast<Lane**>(luaL_checkudata(L_, i_, kLaneMetatableName.data()))); |
| 211 | } | 224 | } |
diff --git a/src/linda.hpp b/src/linda.hpp index 5b5f683..aa63316 100644 --- a/src/linda.hpp +++ b/src/linda.hpp | |||
| @@ -19,7 +19,7 @@ class Linda | |||
| 19 | : public DeepPrelude // Deep userdata MUST start with this header | 19 | : public DeepPrelude // Deep userdata MUST start with this header |
| 20 | { | 20 | { |
| 21 | public: | 21 | public: |
| 22 | class KeeperOperationInProgress | 22 | class [[nodiscard]] KeeperOperationInProgress |
| 23 | { | 23 | { |
| 24 | private: | 24 | private: |
| 25 | Linda& linda; | 25 | Linda& linda; |
| @@ -64,7 +64,8 @@ class Linda | |||
| 64 | Status cancelStatus{ Status::Active }; | 64 | Status cancelStatus{ Status::Active }; |
| 65 | 65 | ||
| 66 | public: | 66 | public: |
| 67 | [[nodiscard]] static void* operator new(size_t size_, Universe* U_) noexcept { return U_->internalAllocator.alloc(size_); } | 67 | [[nodiscard]] |
| 68 | static void* operator new(size_t size_, Universe* U_) noexcept { return U_->internalAllocator.alloc(size_); } | ||
| 68 | // always embedded somewhere else or "in-place constructed" as a full userdata | 69 | // always embedded somewhere else or "in-place constructed" as a full userdata |
| 69 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | 70 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception |
| 70 | static void operator delete(void* p_, Universe* U_) { U_->internalAllocator.free(p_, sizeof(Linda)); } | 71 | static void operator delete(void* p_, Universe* U_) { U_->internalAllocator.free(p_, sizeof(Linda)); } |
| @@ -85,19 +86,26 @@ class Linda | |||
| 85 | void setName(std::string_view const& name_); | 86 | void setName(std::string_view const& name_); |
| 86 | 87 | ||
| 87 | public: | 88 | public: |
| 88 | [[nodiscard]] Keeper* acquireKeeper() const; | 89 | [[nodiscard]] |
| 89 | [[nodiscard]] std::string_view getName() const; | 90 | Keeper* acquireKeeper() const; |
| 90 | [[nodiscard]] bool inKeeperOperation() const { return keeperOperationCount.load(std::memory_order_seq_cst) != 0; } | 91 | [[nodiscard]] |
| 92 | std::string_view getName() const; | ||
| 93 | [[nodiscard]] | ||
| 94 | bool inKeeperOperation() const { return keeperOperationCount.load(std::memory_order_seq_cst) != 0; } | ||
| 91 | template <typename T = uintptr_t> | 95 | template <typename T = uintptr_t> |
| 92 | [[nodiscard]] T obfuscated() const | 96 | [[nodiscard]] |
| 97 | T obfuscated() const | ||
| 93 | { | 98 | { |
| 94 | // xxh64 of string "kObfuscator" generated at https://www.pelock.com/products/hash-calculator | 99 | // xxh64 of string "kObfuscator" generated at https://www.pelock.com/products/hash-calculator |
| 95 | static constexpr UniqueKey kObfuscator{ 0x7B8AA1F99A3BD782ull }; | 100 | static constexpr UniqueKey kObfuscator{ 0x7B8AA1F99A3BD782ull }; |
| 96 | return std::bit_cast<T>(std::bit_cast<uintptr_t>(this) ^ kObfuscator.storage); | 101 | return std::bit_cast<T>(std::bit_cast<uintptr_t>(this) ^ kObfuscator.storage); |
| 97 | }; | 102 | }; |
| 98 | void releaseKeeper(Keeper* keeper_) const; | 103 | void releaseKeeper(Keeper* keeper_) const; |
| 99 | [[nodiscard]] static int ProtectedCall(lua_State* L_, lua_CFunction f_); | 104 | [[nodiscard]] |
| 105 | static int ProtectedCall(lua_State* L_, lua_CFunction f_); | ||
| 100 | void pushCancelString(lua_State* L_) const; | 106 | void pushCancelString(lua_State* L_) const; |
| 101 | [[nodiscard]] KeeperOperationInProgress startKeeperOperation(lua_State* const L_) { return KeeperOperationInProgress{ *this, L_ }; }; | 107 | [[nodiscard]] |
| 102 | [[nodiscard]] Keeper* whichKeeper() const { return U->keepers.getKeeper(keeperIndex); } | 108 | KeeperOperationInProgress startKeeperOperation(lua_State* const L_) { return KeeperOperationInProgress{ *this, L_ }; }; |
| 109 | [[nodiscard]] | ||
| 110 | Keeper* whichKeeper() const { return U->keepers.getKeeper(keeperIndex); } | ||
| 103 | }; | 111 | }; |
diff --git a/src/lindafactory.hpp b/src/lindafactory.hpp index ac42c10..1512e9a 100644 --- a/src/lindafactory.hpp +++ b/src/lindafactory.hpp | |||
| @@ -21,6 +21,8 @@ class LindaFactory | |||
| 21 | 21 | ||
| 22 | void createMetatable(lua_State* L_) const override; | 22 | void createMetatable(lua_State* L_) const override; |
| 23 | void deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const override; | 23 | void deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const override; |
| 24 | [[nodiscard]] std::string_view moduleName() const override; | 24 | [[nodiscard]] |
| 25 | [[nodiscard]] DeepPrelude* newDeepObjectInternal(lua_State* L_) const override; | 25 | std::string_view moduleName() const override; |
| 26 | [[nodiscard]] | ||
| 27 | DeepPrelude* newDeepObjectInternal(lua_State* L_) const override; | ||
| 26 | }; | 28 | }; |
diff --git a/src/state.hpp b/src/state.hpp index 7401fe9..1e1e1f5 100644 --- a/src/state.hpp +++ b/src/state.hpp | |||
| @@ -4,11 +4,12 @@ | |||
| 4 | #include "macros_and_utils.hpp" | 4 | #include "macros_and_utils.hpp" |
| 5 | 5 | ||
| 6 | // forwards | 6 | // forwards |
| 7 | enum class LookupMode; | ||
| 8 | class Universe; | 7 | class Universe; |
| 9 | 8 | ||
| 10 | namespace state { | 9 | namespace state { |
| 11 | [[nodiscard]] lua_State* CreateState(Universe* U_, lua_State* from_, std::string_view const& hint_); | 10 | [[nodiscard]] |
| 12 | [[nodiscard]] lua_State* NewLaneState(Universe* U_, SourceState from_, std::optional<std::string_view> const& libs_); | 11 | lua_State* CreateState(Universe* U_, lua_State* from_, std::string_view const& hint_); |
| 12 | [[nodiscard]] | ||
| 13 | lua_State* NewLaneState(Universe* U_, SourceState from_, std::optional<std::string_view> const& libs_); | ||
| 13 | LUAG_FUNC(supported_libs); | 14 | LUAG_FUNC(supported_libs); |
| 14 | } // namespace state | 15 | } // namespace state |
diff --git a/src/threading_osx.h b/src/threading_osx.h index f4d41e0..c198d6d 100644 --- a/src/threading_osx.h +++ b/src/threading_osx.h | |||
| @@ -17,9 +17,11 @@ struct cpu_set_t | |||
| 17 | 17 | ||
| 18 | static inline void CPU_ZERO(cpu_set_t *cs) { cs->count = 0; } | 18 | static inline void CPU_ZERO(cpu_set_t *cs) { cs->count = 0; } |
| 19 | static inline void CPU_SET(int num, cpu_set_t *cs) { cs->count |= (1 << num); } | 19 | static inline void CPU_SET(int num, cpu_set_t *cs) { cs->count |= (1 << num); } |
| 20 | [[nodiscard]] static inline int CPU_ISSET(int num, cpu_set_t *cs) { return (cs->count & (1 << num)); } | 20 | [[nodiscard]] |
| 21 | static inline int CPU_ISSET(int num, cpu_set_t *cs) { return (cs->count & (1 << num)); } | ||
| 21 | 22 | ||
| 22 | [[nodiscard]] int sched_getaffinity(pid_t pid, size_t cpu_size, cpu_set_t *cpu_set) | 23 | [[nodiscard]] |
| 24 | int sched_getaffinity(pid_t pid, size_t cpu_size, cpu_set_t *cpu_set) | ||
| 23 | { | 25 | { |
| 24 | int32_t core_count = 0; | 26 | int32_t core_count = 0; |
| 25 | size_t len = sizeof(core_count); | 27 | size_t len = sizeof(core_count); |
| @@ -38,7 +40,8 @@ static inline void CPU_SET(int num, cpu_set_t *cs) { cs->count |= (1 << num); } | |||
| 38 | return 0; | 40 | return 0; |
| 39 | } | 41 | } |
| 40 | 42 | ||
| 41 | [[nodiscard]] int pthread_setaffinity_np(pthread_t thread, size_t cpu_size, cpu_set_t *cpu_set) | 43 | [[nodiscard]] |
| 44 | int pthread_setaffinity_np(pthread_t thread, size_t cpu_size, cpu_set_t *cpu_set) | ||
| 42 | { | 45 | { |
| 43 | thread_port_t mach_thread; | 46 | thread_port_t mach_thread; |
| 44 | int core = 0; | 47 | int core = 0; |
diff --git a/src/tools.hpp b/src/tools.hpp index c587500..77ba5d2 100644 --- a/src/tools.hpp +++ b/src/tools.hpp | |||
| @@ -11,6 +11,8 @@ enum class LookupMode | |||
| 11 | FromKeeper // send a function from a keeper state to a lane | 11 | FromKeeper // send a function from a keeper state to a lane |
| 12 | }; | 12 | }; |
| 13 | 13 | ||
| 14 | // ################################################################################################# | ||
| 15 | |||
| 14 | enum class FuncSubType | 16 | enum class FuncSubType |
| 15 | { | 17 | { |
| 16 | Bytecode, | 18 | Bytecode, |
| @@ -18,7 +20,8 @@ enum class FuncSubType | |||
| 18 | FastJIT | 20 | FastJIT |
| 19 | }; | 21 | }; |
| 20 | 22 | ||
| 21 | [[nodiscard]] FuncSubType luaG_getfuncsubtype(lua_State* L_, StackIndex i_); | 23 | [[nodiscard]] |
| 24 | FuncSubType luaG_getfuncsubtype(lua_State* L_, StackIndex i_); | ||
| 22 | 25 | ||
| 23 | // ################################################################################################# | 26 | // ################################################################################################# |
| 24 | 27 | ||
| @@ -32,6 +35,7 @@ static constexpr RegistryUniqueKey kLookupRegKey{ 0xBF1FC5CF3C6DD47Bull }; // re | |||
| 32 | 35 | ||
| 33 | namespace tools { | 36 | namespace tools { |
| 34 | void PopulateFuncLookupTable(lua_State* L_, StackIndex i_, std::string_view const& name_); | 37 | void PopulateFuncLookupTable(lua_State* L_, StackIndex i_, std::string_view const& name_); |
| 35 | [[nodiscard]] std::string_view PushFQN(lua_State* L_, StackIndex t_, int last_); | 38 | [[nodiscard]] |
| 39 | std::string_view PushFQN(lua_State* L_, StackIndex t_, int last_); | ||
| 36 | void SerializeRequire(lua_State* L_); | 40 | void SerializeRequire(lua_State* L_); |
| 37 | } // namespace tools | 41 | } // namespace tools |
diff --git a/src/tracker.hpp b/src/tracker.hpp index c1a38e2..f7dca80 100644 --- a/src/tracker.hpp +++ b/src/tracker.hpp | |||
| @@ -15,12 +15,15 @@ class LaneTracker | |||
| 15 | 15 | ||
| 16 | public: | 16 | public: |
| 17 | void tracking_add(Lane* lane_); | 17 | void tracking_add(Lane* lane_); |
| 18 | [[nodiscard]] bool tracking_remove(Lane* lane_); | 18 | [[nodiscard]] |
| 19 | [[nodiscard]] int pushThreadsTable(lua_State* L_) const; | 19 | bool tracking_remove(Lane* lane_); |
| 20 | [[nodiscard]] | ||
| 21 | int pushThreadsTable(lua_State* L_) const; | ||
| 20 | void activate() { | 22 | void activate() { |
| 21 | trackingFirst = TRACKING_END; | 23 | trackingFirst = TRACKING_END; |
| 22 | } | 24 | } |
| 23 | [[nodiscard]] bool isActive() const { | 25 | [[nodiscard]] |
| 26 | bool isActive() const { | ||
| 24 | return trackingFirst != nullptr; | 27 | return trackingFirst != nullptr; |
| 25 | } | 28 | } |
| 26 | }; | 29 | }; |
diff --git a/src/unique.hpp b/src/unique.hpp index c214dbc..aec5610 100644 --- a/src/unique.hpp +++ b/src/unique.hpp | |||
| @@ -3,8 +3,9 @@ | |||
| 3 | // ################################################################################################# | 3 | // ################################################################################################# |
| 4 | 4 | ||
| 5 | // A unique type generator | 5 | // A unique type generator |
| 6 | // Marking *all* Unique<> types as [[nodiscard]] is maybe overkill, but there is no way of marking a specific instanciation | ||
| 6 | template <typename T, typename TAG, typename specialization = void> | 7 | template <typename T, typename TAG, typename specialization = void> |
| 7 | class Unique | 8 | class [[nodiscard]] Unique |
| 8 | { | 9 | { |
| 9 | private: | 10 | private: |
| 10 | T val; // no default initialization so that std::is_trivial_v<Unique<T>> == true | 11 | T val; // no default initialization so that std::is_trivial_v<Unique<T>> == true |
| @@ -69,7 +70,8 @@ class Unique | |||
| 69 | }; | 70 | }; |
| 70 | 71 | ||
| 71 | template <typename T, typename TAG> | 72 | template <typename T, typename TAG> |
| 72 | class Unique<T, TAG, std::enable_if_t<!std::is_scalar_v<T>>> | 73 | // Marking *all* Unique<> types as [[nodiscard]] is maybe overkill, but there is no way of marking a specific instanciation |
| 74 | class [[nodiscard]] Unique<T, TAG, std::enable_if_t<!std::is_scalar_v<T>>> | ||
| 73 | : public T | 75 | : public T |
| 74 | { | 76 | { |
| 75 | public: | 77 | public: |
diff --git a/src/uniquekey.hpp b/src/uniquekey.hpp index 9041363..a8386a2 100644 --- a/src/uniquekey.hpp +++ b/src/uniquekey.hpp | |||
| @@ -73,7 +73,8 @@ class RegistryUniqueKey | |||
| 73 | } | 73 | } |
| 74 | // --------------------------------------------------------------------------------------------- | 74 | // --------------------------------------------------------------------------------------------- |
| 75 | template <typename T> | 75 | template <typename T> |
| 76 | [[nodiscard]] T* readLightUserDataValue(lua_State* const L_) const | 76 | [[nodiscard]] |
| 77 | T* readLightUserDataValue(lua_State* const L_) const | ||
| 77 | { | 78 | { |
| 78 | STACK_GROW(L_, 1); | 79 | STACK_GROW(L_, 1); |
| 79 | STACK_CHECK_START_REL(L_, 0); | 80 | STACK_CHECK_START_REL(L_, 0); |
| @@ -84,7 +85,8 @@ class RegistryUniqueKey | |||
| 84 | return value; | 85 | return value; |
| 85 | } | 86 | } |
| 86 | // --------------------------------------------------------------------------------------------- | 87 | // --------------------------------------------------------------------------------------------- |
| 87 | [[nodiscard]] bool readBoolValue(lua_State* const L_) const | 88 | [[nodiscard]] |
| 89 | bool readBoolValue(lua_State* const L_) const | ||
| 88 | { | 90 | { |
| 89 | STACK_GROW(L_, 1); | 91 | STACK_GROW(L_, 1); |
| 90 | STACK_CHECK_START_REL(L_, 0); | 92 | STACK_CHECK_START_REL(L_, 0); |
| @@ -96,7 +98,8 @@ class RegistryUniqueKey | |||
| 96 | } | 98 | } |
| 97 | // --------------------------------------------------------------------------------------------- | 99 | // --------------------------------------------------------------------------------------------- |
| 98 | // equivalent to luaL_getsubtable | 100 | // equivalent to luaL_getsubtable |
| 99 | [[nodiscard]] bool getSubTable(lua_State* const L_, NArr const narr_, NRec const nrec_) const | 101 | [[nodiscard]] |
| 102 | bool getSubTable(lua_State* const L_, NArr const narr_, NRec const nrec_) const | ||
| 100 | { | 103 | { |
| 101 | STACK_CHECK_START_REL(L_, 0); | 104 | STACK_CHECK_START_REL(L_, 0); |
| 102 | pushValue(L_); // L_: {}|nil | 105 | pushValue(L_); // L_: {}|nil |
diff --git a/src/universe.hpp b/src/universe.hpp index 77fbb52..fa1e238 100644 --- a/src/universe.hpp +++ b/src/universe.hpp | |||
| @@ -25,7 +25,8 @@ class ProtectedAllocator | |||
| 25 | 25 | ||
| 26 | std::mutex mutex; | 26 | std::mutex mutex; |
| 27 | 27 | ||
| 28 | [[nodiscard]] static void* protected_lua_Alloc(void* ud_, void* ptr_, size_t osize_, size_t nsize_) | 28 | [[nodiscard]] |
| 29 | static void* protected_lua_Alloc(void* ud_, void* ptr_, size_t osize_, size_t nsize_) | ||
| 29 | { | 30 | { |
| 30 | ProtectedAllocator* const allocator{ static_cast<ProtectedAllocator*>(ud_) }; | 31 | ProtectedAllocator* const allocator{ static_cast<ProtectedAllocator*>(ud_) }; |
| 31 | std::lock_guard<std::mutex> guard{ allocator->mutex }; | 32 | std::lock_guard<std::mutex> guard{ allocator->mutex }; |
| @@ -34,7 +35,8 @@ class ProtectedAllocator | |||
| 34 | 35 | ||
| 35 | public: | 36 | public: |
| 36 | // we are not like our base class: we can't be created inside a full userdata (or we would have to install a metatable and __gc handler to destroy ourselves properly) | 37 | // we are not like our base class: we can't be created inside a full userdata (or we would have to install a metatable and __gc handler to destroy ourselves properly) |
| 37 | [[nodiscard]] static void* operator new(size_t size_, lua_State* L_) noexcept = delete; | 38 | [[nodiscard]] |
| 39 | static void* operator new(size_t size_, lua_State* L_) noexcept = delete; | ||
| 38 | static void operator delete(void* p_, lua_State* L_) = delete; | 40 | static void operator delete(void* p_, lua_State* L_) = delete; |
| 39 | 41 | ||
| 40 | AllocatorDefinition makeDefinition() | 42 | AllocatorDefinition makeDefinition() |
| @@ -121,7 +123,8 @@ class Universe | |||
| 121 | std::atomic<int> selfdestructingCount{ 0 }; | 123 | std::atomic<int> selfdestructingCount{ 0 }; |
| 122 | 124 | ||
| 123 | public: | 125 | public: |
| 124 | [[nodiscard]] static void* operator new([[maybe_unused]] size_t size_, lua_State* L_) noexcept { return luaG_newuserdatauv<Universe>(L_, UserValueCount{ 0 }); }; | 126 | [[nodiscard]] |
| 127 | static void* operator new([[maybe_unused]] size_t size_, lua_State* L_) noexcept { return luaG_newuserdatauv<Universe>(L_, UserValueCount{ 0 }); }; | ||
| 125 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | 128 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception |
| 126 | static void operator delete([[maybe_unused]] void* p_, [[maybe_unused]] lua_State* L_) {} // nothing to do, as nothing is allocated independently | 129 | static void operator delete([[maybe_unused]] void* p_, [[maybe_unused]] lua_State* L_) {} // nothing to do, as nothing is allocated independently |
| 127 | 130 | ||
| @@ -134,18 +137,22 @@ class Universe | |||
| 134 | Universe& operator=(Universe&&) = delete; | 137 | Universe& operator=(Universe&&) = delete; |
| 135 | 138 | ||
| 136 | void callOnStateCreate(lua_State* const L_, lua_State* const from_, LookupMode const mode_); | 139 | void callOnStateCreate(lua_State* const L_, lua_State* const from_, LookupMode const mode_); |
| 137 | [[nodiscard]] static Universe* Create(lua_State* L_); | 140 | [[nodiscard]] |
| 138 | [[nodiscard]] static inline Universe* Get(lua_State* L_); | 141 | static Universe* Create(lua_State* L_); |
| 142 | [[nodiscard]] | ||
| 143 | static inline Universe* Get(lua_State* L_); | ||
| 139 | void initializeAllocatorFunction(lua_State* L_); | 144 | void initializeAllocatorFunction(lua_State* L_); |
| 140 | static int InitializeFinalizer(lua_State* L_); | 145 | static int InitializeFinalizer(lua_State* L_); |
| 141 | void initializeOnStateCreate(lua_State* const L_); | 146 | void initializeOnStateCreate(lua_State* const L_); |
| 142 | lanes::AllocatorDefinition resolveAllocator(lua_State* const L_, std::string_view const& hint_) const; | 147 | lanes::AllocatorDefinition resolveAllocator(lua_State* const L_, std::string_view const& hint_) const; |
| 143 | static inline void Store(lua_State* L_, Universe* U_); | 148 | static inline void Store(lua_State* L_, Universe* U_); |
| 144 | [[nodiscard]] bool terminateFreeRunningLanes(lua_Duration shutdownTimeout_, CancelOp op_); | 149 | [[nodiscard]] |
| 150 | bool terminateFreeRunningLanes(lua_Duration shutdownTimeout_, CancelOp op_); | ||
| 145 | }; | 151 | }; |
| 146 | 152 | ||
| 147 | // ################################################################################################# | 153 | // ################################################################################################# |
| 148 | 154 | ||
| 155 | [[nodiscard]] | ||
| 149 | inline Universe* Universe::Get(lua_State* L_) | 156 | inline Universe* Universe::Get(lua_State* L_) |
| 150 | { | 157 | { |
| 151 | STACK_CHECK_START_REL(L_, 0); | 158 | STACK_CHECK_START_REL(L_, 0); |
