diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2025-07-04 14:54:36 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2025-07-04 14:54:36 +0200 |
| commit | 7bddb06461d8f80030b3b86175ec737dbb16ac3b (patch) | |
| tree | 031238469090658f7f20535137edb2620bc77182 /src | |
| parent | 042055968ab0c48faec607889814e38c50c09efa (diff) | |
| download | lanes-7bddb06461d8f80030b3b86175ec737dbb16ac3b.tar.gz lanes-7bddb06461d8f80030b3b86175ec737dbb16ac3b.tar.bz2 lanes-7bddb06461d8f80030b3b86175ec737dbb16ac3b.zip | |
Added Lua 5.5 support
* some unit tests fail/segfault/freeze, but that could be because Lua 5.5 is still in beta yet
Diffstat (limited to 'src')
| -rw-r--r-- | src/allocator.hpp | 2 | ||||
| -rw-r--r-- | src/compat.cpp | 38 | ||||
| -rw-r--r-- | src/compat.hpp | 71 | ||||
| -rw-r--r-- | src/universe.cpp | 2 |
4 files changed, 88 insertions, 25 deletions
diff --git a/src/allocator.hpp b/src/allocator.hpp index ce65a4b..b578f12 100644 --- a/src/allocator.hpp +++ b/src/allocator.hpp | |||
| @@ -66,7 +66,7 @@ namespace lanes { | |||
| 66 | [[nodiscard]] | 66 | [[nodiscard]] |
| 67 | lua_State* newState() const | 67 | lua_State* newState() const |
| 68 | { | 68 | { |
| 69 | return lua_newstate(allocF, allocUD); | 69 | return luaW_newstate(allocF, allocUD, luaL_makeseed(nullptr)); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | [[nodiscard]] | 72 | [[nodiscard]] |
diff --git a/src/compat.cpp b/src/compat.cpp index 08f22ca..c833480 100644 --- a/src/compat.cpp +++ b/src/compat.cpp | |||
| @@ -149,3 +149,41 @@ int lua_setiuservalue(lua_State* const L_, StackIndex const idx_, UserValueIndex | |||
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | #endif // LUA_VERSION_NUM | 151 | #endif // LUA_VERSION_NUM |
| 152 | |||
| 153 | // ################################################################################################# | ||
| 154 | |||
| 155 | #if LUA_VERSION_NUM < 505 | ||
| 156 | |||
| 157 | #include <time.h> | ||
| 158 | |||
| 159 | /* Size for the buffer, in bytes */ | ||
| 160 | #define BUFSEEDB (sizeof(void*) + sizeof(time_t)) | ||
| 161 | |||
| 162 | /* Size for the buffer in int's, rounded up */ | ||
| 163 | #define BUFSEED ((BUFSEEDB + sizeof(int) - 1) / sizeof(int)) | ||
| 164 | |||
| 165 | /* | ||
| 166 | ** Copy the contents of variable 'v' into the buffer pointed by 'b'. | ||
| 167 | ** (The '&b[0]' disguises 'b' to fix an absurd warning from clang.) | ||
| 168 | */ | ||
| 169 | #define addbuff(b, v) (memcpy(&b[0], &(v), sizeof(v)), b += sizeof(v)) | ||
| 170 | |||
| 171 | // Copied from Lua 5.5 lauxlib.c | ||
| 172 | unsigned int luaL_makeseed(lua_State*) | ||
| 173 | { | ||
| 174 | unsigned int buff[BUFSEED]; | ||
| 175 | unsigned int res; | ||
| 176 | unsigned int i; | ||
| 177 | time_t t = time(nullptr); | ||
| 178 | char* b = (char*) buff; | ||
| 179 | addbuff(b, b); /* local variable's address */ | ||
| 180 | addbuff(b, t); /* time */ | ||
| 181 | /* fill (rare but possible) remain of the buffer with zeros */ | ||
| 182 | memset(b, 0, sizeof(buff) - BUFSEEDB); | ||
| 183 | res = buff[0]; | ||
| 184 | for (i = 1; i < BUFSEED; i++) | ||
| 185 | res ^= (res >> 3) + (res << 7) + buff[i]; | ||
| 186 | return res; | ||
| 187 | } | ||
| 188 | |||
| 189 | #endif // LUA_VERSION_NUM < 505 | ||
diff --git a/src/compat.hpp b/src/compat.hpp index 99c468c..49029df 100644 --- a/src/compat.hpp +++ b/src/compat.hpp | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | #endif // LUA_OK | 21 | #endif // LUA_OK |
| 22 | 22 | ||
| 23 | #ifndef LUA_ERRGCMM | 23 | #ifndef LUA_ERRGCMM |
| 24 | #define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1 and Lua 5.4, we don't care about the actual value | 24 | #define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1 and Lua 5.4/5.5, we don't care about the actual value |
| 25 | #endif // LUA_ERRGCMM | 25 | #endif // LUA_ERRGCMM |
| 26 | 26 | ||
| 27 | 27 | ||
| @@ -29,7 +29,7 @@ | |||
| 29 | #define LUA_LOADED_TABLE "_LOADED" // doesn't exist before Lua 5.3 | 29 | #define LUA_LOADED_TABLE "_LOADED" // doesn't exist before Lua 5.3 |
| 30 | #endif // LUA_LOADED_TABLE | 30 | #endif // LUA_LOADED_TABLE |
| 31 | 31 | ||
| 32 | // code is now preferring Lua 5.4 API | 32 | // code is now preferring Lua 5.5 API |
| 33 | 33 | ||
| 34 | // ################################################################################################# | 34 | // ################################################################################################# |
| 35 | 35 | ||
| @@ -76,18 +76,6 @@ int luaL_getsubtable(lua_State* L_, StackIndex idx_, char const* fname_); | |||
| 76 | 76 | ||
| 77 | // ################################################################################################# | 77 | // ################################################################################################# |
| 78 | 78 | ||
| 79 | // wrap Lua 5.3 calls under Lua 5.1 API when it is simpler that way | ||
| 80 | #if LUA_VERSION_NUM == 503 | ||
| 81 | |||
| 82 | inline int luaL_optint(lua_State* L_, int n_, lua_Integer d_) | ||
| 83 | { | ||
| 84 | return static_cast<int>(luaL_optinteger(L_, n_, d_)); | ||
| 85 | } | ||
| 86 | |||
| 87 | #endif // LUA_VERSION_NUM == 503 | ||
| 88 | |||
| 89 | // ################################################################################################# | ||
| 90 | |||
| 91 | #if LUA_VERSION_NUM < 504 | 79 | #if LUA_VERSION_NUM < 504 |
| 92 | 80 | ||
| 93 | void* lua_newuserdatauv(lua_State* L_, size_t sz_, UserValueCount nuvalue_); | 81 | void* lua_newuserdatauv(lua_State* L_, size_t sz_, UserValueCount nuvalue_); |
| @@ -100,15 +88,11 @@ int lua_setiuservalue(lua_State* L_, StackIndex idx_, UserValueIndex n_); | |||
| 100 | 88 | ||
| 101 | // ################################################################################################# | 89 | // ################################################################################################# |
| 102 | 90 | ||
| 103 | // wrap Lua 5.4 calls under Lua 5.1 API when it is simpler that way | 91 | #if LUA_VERSION_NUM < 505 |
| 104 | #if LUA_VERSION_NUM == 504 | ||
| 105 | 92 | ||
| 106 | inline int luaL_optint(lua_State* L_, StackIndex n_, lua_Integer d_) | 93 | unsigned int luaL_makeseed(lua_State*); |
| 107 | { | ||
| 108 | return static_cast<int>(luaL_optinteger(L_, n_, d_)); | ||
| 109 | } | ||
| 110 | 94 | ||
| 111 | #endif // LUA_VERSION_NUM == 504 | 95 | #endif // LUA_VERSION_NUM < 505 |
| 112 | 96 | ||
| 113 | // ################################################################################################# | 97 | // ################################################################################################# |
| 114 | 98 | ||
| @@ -284,6 +268,47 @@ LuaType luaW_getmodule(lua_State* L_, std::string_view const& name_); | |||
| 284 | 268 | ||
| 285 | // ################################################################################################# | 269 | // ################################################################################################# |
| 286 | 270 | ||
| 271 | template <typename LUA_NEWSTATE> | ||
| 272 | concept RequiresOldLuaNewState = requires(LUA_NEWSTATE f_) | ||
| 273 | { | ||
| 274 | { | ||
| 275 | f_(nullptr, 0) | ||
| 276 | } -> std::same_as<lua_State*>; | ||
| 277 | }; | ||
| 278 | |||
| 279 | template <RequiresOldLuaNewState LUA_NEWSTATE> | ||
| 280 | static inline lua_State* WrapLuaNewState(LUA_NEWSTATE const lua_newstate_, lua_Alloc const allocf_, void* const ud_, [[maybe_unused]] unsigned int const seed_) | ||
| 281 | { | ||
| 282 | // until Lua 5.5, lua_newstate has only 2 parameters | ||
| 283 | return lua_newstate_(allocf_, ud_); | ||
| 284 | } | ||
| 285 | |||
| 286 | // ------------------------------------------------------------------------------------------------- | ||
| 287 | |||
| 288 | template <typename LUA_NEWSTATE> | ||
| 289 | concept RequiresNewLuaNewState = requires(LUA_NEWSTATE f_) | ||
| 290 | { | ||
| 291 | { | ||
| 292 | f_(nullptr, nullptr, 0) | ||
| 293 | } -> std::same_as<lua_State*>; | ||
| 294 | }; | ||
| 295 | |||
| 296 | template <RequiresNewLuaNewState LUA_NEWSTATE> | ||
| 297 | static inline lua_State* WrapLuaNewState(LUA_NEWSTATE const lua_newstate_, lua_Alloc const allocf_, void* const ud_, unsigned int const seed_) | ||
| 298 | { | ||
| 299 | // starting with Lua 5.5, lua_newstate has 3 parameters | ||
| 300 | return lua_newstate_(allocf_, ud_, seed_); | ||
| 301 | } | ||
| 302 | |||
| 303 | // ------------------------------------------------------------------------------------------------- | ||
| 304 | |||
| 305 | static inline lua_State* luaW_newstate(lua_Alloc const allocf_, void* const ud_, unsigned int const seed_) | ||
| 306 | { | ||
| 307 | return WrapLuaNewState(lua_newstate, allocf_, ud_, seed_); | ||
| 308 | } | ||
| 309 | |||
| 310 | // ################################################################################################# | ||
| 311 | |||
| 287 | template<typename ENUM> | 312 | template<typename ENUM> |
| 288 | requires std::is_enum_v<ENUM> | 313 | requires std::is_enum_v<ENUM> |
| 289 | [[nodiscard]] | 314 | [[nodiscard]] |
| @@ -364,7 +389,7 @@ template <typename LUA_RAWGET> | |||
| 364 | concept RequiresOldLuaRawget = requires(LUA_RAWGET f_) { { f_(nullptr, 0) } -> std::same_as<void>; }; | 389 | concept RequiresOldLuaRawget = requires(LUA_RAWGET f_) { { f_(nullptr, 0) } -> std::same_as<void>; }; |
| 365 | 390 | ||
| 366 | template <RequiresOldLuaRawget LUA_RAWGET> | 391 | template <RequiresOldLuaRawget LUA_RAWGET> |
| 367 | static inline LuaType WrapLuaRawget(LUA_RAWGET lua_rawget_, lua_State* const L_, StackIndex const idx_) | 392 | static inline LuaType WrapLuaRawget(LUA_RAWGET const lua_rawget_, lua_State* const L_, StackIndex const idx_) |
| 368 | { | 393 | { |
| 369 | // until Lua 5.3, lua_rawget -> void | 394 | // until Lua 5.3, lua_rawget -> void |
| 370 | lua_rawget_(L_, idx_); | 395 | lua_rawget_(L_, idx_); |
| @@ -377,7 +402,7 @@ template <typename LUA_RAWGET> | |||
| 377 | concept RequiresNewLuaRawget = requires(LUA_RAWGET f_) { { f_(nullptr, 0) } -> std::same_as<int>; }; | 402 | concept RequiresNewLuaRawget = requires(LUA_RAWGET f_) { { f_(nullptr, 0) } -> std::same_as<int>; }; |
| 378 | 403 | ||
| 379 | template <RequiresNewLuaRawget LUA_RAWGET> | 404 | template <RequiresNewLuaRawget LUA_RAWGET> |
| 380 | static inline LuaType WrapLuaRawget(LUA_RAWGET lua_rawget_, lua_State* const L_, StackIndex const idx_) | 405 | static inline LuaType WrapLuaRawget(LUA_RAWGET const lua_rawget_, lua_State* const L_, StackIndex const idx_) |
| 381 | { | 406 | { |
| 382 | // starting with Lua 5.3, lua_rawget -> int (the type of the extracted value) | 407 | // starting with Lua 5.3, lua_rawget -> int (the type of the extracted value) |
| 383 | return static_cast<LuaType>(lua_rawget_(L_, idx_)); | 408 | return static_cast<LuaType>(lua_rawget_(L_, idx_)); |
diff --git a/src/universe.cpp b/src/universe.cpp index 044c841..4db036b 100644 --- a/src/universe.cpp +++ b/src/universe.cpp | |||
| @@ -447,7 +447,7 @@ int Universe::UniverseGC(lua_State* const L_) | |||
| 447 | if (!lua_isnil(L_, -1)) { | 447 | if (!lua_isnil(L_, -1)) { |
| 448 | lua_pushboolean(L_, _allLanesTerminated); // L_: U finalizer bool | 448 | lua_pushboolean(L_, _allLanesTerminated); // L_: U finalizer bool |
| 449 | // no protection. Lua rules for errors in finalizers apply normally: | 449 | // no protection. Lua rules for errors in finalizers apply normally: |
| 450 | // Lua 5.4: error is propagated in the warn system | 450 | // Lua 5.4+: error is propagated in the warn system |
| 451 | // older: error is swallowed | 451 | // older: error is swallowed |
| 452 | lua_call(L_, 1, 1); // L_: U msg? | 452 | lua_call(L_, 1, 1); // L_: U msg? |
| 453 | // phew, no error in finalizer, since we reached that point | 453 | // phew, no error in finalizer, since we reached that point |
