diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-26 17:46:00 +0100 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-03-26 17:46:00 +0100 |
| commit | f214d35df5f09e7026dafd8553e83cc6ea21cbde (patch) | |
| tree | 2bd19bfddf4949183fe0e84ca58940fd6a6aa918 /src | |
| parent | 2eeb245b98bd702379aa92d888f7b7d21d1193b8 (diff) | |
| download | lanes-f214d35df5f09e7026dafd8553e83cc6ea21cbde.tar.gz lanes-f214d35df5f09e7026dafd8553e83cc6ea21cbde.tar.bz2 lanes-f214d35df5f09e7026dafd8553e83cc6ea21cbde.zip | |
C++ migration: templated lua_touserdata
Diffstat (limited to 'src')
| -rw-r--r-- | src/deep.cpp | 14 | ||||
| -rw-r--r-- | src/keeper.cpp | 32 | ||||
| -rw-r--r-- | src/lanes.cpp | 6 | ||||
| -rw-r--r-- | src/lanes_private.h | 2 | ||||
| -rw-r--r-- | src/linda.cpp | 2 | ||||
| -rw-r--r-- | src/macros_and_utils.h | 7 | ||||
| -rw-r--r-- | src/state.cpp | 2 | ||||
| -rw-r--r-- | src/universe.cpp | 2 | ||||
| -rw-r--r-- | src/universe.h | 2 |
9 files changed, 41 insertions, 28 deletions
diff --git a/src/deep.cpp b/src/deep.cpp index dd682e4..f091d4d 100644 --- a/src/deep.cpp +++ b/src/deep.cpp | |||
| @@ -113,7 +113,7 @@ static inline luaG_IdFunction* get_idfunc( lua_State* L, int index, LookupMode m | |||
| 113 | // when looking inside a keeper, we are 100% sure the object is a deep userdata | 113 | // when looking inside a keeper, we are 100% sure the object is a deep userdata |
| 114 | if( mode_ == eLM_FromKeeper) | 114 | if( mode_ == eLM_FromKeeper) |
| 115 | { | 115 | { |
| 116 | DeepPrelude** proxy = (DeepPrelude**) lua_touserdata( L, index); | 116 | DeepPrelude** const proxy{ lua_touserdata<DeepPrelude*>(L, index) }; |
| 117 | // we can (and must) cast and fetch the internally stored idfunc | 117 | // we can (and must) cast and fetch the internally stored idfunc |
| 118 | return (*proxy)->idfunc; | 118 | return (*proxy)->idfunc; |
| 119 | } | 119 | } |
| @@ -133,7 +133,7 @@ static inline luaG_IdFunction* get_idfunc( lua_State* L, int index, LookupMode m | |||
| 133 | // replace metatable with the idfunc pointer, if it is actually a deep userdata | 133 | // replace metatable with the idfunc pointer, if it is actually a deep userdata |
| 134 | get_deep_lookup( L); // deep ... idfunc|nil | 134 | get_deep_lookup( L); // deep ... idfunc|nil |
| 135 | 135 | ||
| 136 | luaG_IdFunction* const ret{ static_cast<luaG_IdFunction*>(lua_touserdata(L, -1)) }; // nullptr if not a userdata | 136 | luaG_IdFunction* const ret{ lua_touserdata<luaG_IdFunction>(L, -1) }; // nullptr if not a userdata |
| 137 | lua_pop( L, 1); | 137 | lua_pop( L, 1); |
| 138 | STACK_CHECK( L, 0); | 138 | STACK_CHECK( L, 0); |
| 139 | return ret; | 139 | return ret; |
| @@ -161,7 +161,7 @@ void free_deep_prelude( lua_State* L, DeepPrelude* prelude_) | |||
| 161 | */ | 161 | */ |
| 162 | static int deep_userdata_gc( lua_State* L) | 162 | static int deep_userdata_gc( lua_State* L) |
| 163 | { | 163 | { |
| 164 | DeepPrelude** proxy = (DeepPrelude**) lua_touserdata( L, 1); | 164 | DeepPrelude** const proxy{ lua_touserdata<DeepPrelude*>(L, 1) }; |
| 165 | DeepPrelude* p = *proxy; | 165 | DeepPrelude* p = *proxy; |
| 166 | 166 | ||
| 167 | // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded | 167 | // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded |
| @@ -418,17 +418,15 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction* idfunc, int nuv_) | |||
| 418 | */ | 418 | */ |
| 419 | void* luaG_todeep( lua_State* L, luaG_IdFunction* idfunc, int index) | 419 | void* luaG_todeep( lua_State* L, luaG_IdFunction* idfunc, int index) |
| 420 | { | 420 | { |
| 421 | DeepPrelude** proxy; | ||
| 422 | |||
| 423 | STACK_CHECK_START_REL(L, 0); | 421 | STACK_CHECK_START_REL(L, 0); |
| 424 | // ensure it is actually a deep userdata | 422 | // ensure it is actually a deep userdata |
| 425 | if( get_idfunc( L, index, eLM_LaneBody) != idfunc) | 423 | if( get_idfunc( L, index, eLM_LaneBody) != idfunc) |
| 426 | { | 424 | { |
| 427 | return nullptr; // no metatable, or wrong kind | 425 | return nullptr; // no metatable, or wrong kind |
| 428 | } | 426 | } |
| 427 | STACK_CHECK(L, 0); | ||
| 429 | 428 | ||
| 430 | proxy = (DeepPrelude**) lua_touserdata( L, index); | 429 | DeepPrelude** const proxy{ lua_touserdata<DeepPrelude*>(L, index) }; |
| 431 | STACK_CHECK( L, 0); | ||
| 432 | 430 | ||
| 433 | return *proxy; | 431 | return *proxy; |
| 434 | } | 432 | } |
| @@ -464,7 +462,7 @@ bool copydeep(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, L | |||
| 464 | lua_pop( L, 1); // ... u [uv]* | 462 | lua_pop( L, 1); // ... u [uv]* |
| 465 | STACK_CHECK( L, nuv); | 463 | STACK_CHECK( L, nuv); |
| 466 | 464 | ||
| 467 | errmsg = push_deep_proxy(L2, *(DeepPrelude**) lua_touserdata( L, i), nuv, mode_); // u | 465 | errmsg = push_deep_proxy(L2, *lua_touserdata<DeepPrelude*>(L, i), nuv, mode_); // u |
| 468 | 466 | ||
| 469 | // transfer all uservalues of the source in the destination | 467 | // transfer all uservalues of the source in the destination |
| 470 | { | 468 | { |
diff --git a/src/keeper.cpp b/src/keeper.cpp index 88bd4ff..35b5ea8 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
| @@ -52,11 +52,18 @@ | |||
| 52 | // Keeper implementation | 52 | // Keeper implementation |
| 53 | // ################################################################################### | 53 | // ################################################################################### |
| 54 | 54 | ||
| 55 | struct keeper_fifo | 55 | class keeper_fifo |
| 56 | { | 56 | { |
| 57 | public: | ||
| 58 | |||
| 57 | int first{ 1 }; | 59 | int first{ 1 }; |
| 58 | int count{ 0 }; | 60 | int count{ 0 }; |
| 59 | int limit{ -1 }; | 61 | int limit{ -1 }; |
| 62 | |||
| 63 | static void* operator new(size_t size_, lua_State* L) noexcept { return lua_newuserdatauv(L, size_, 1); } | ||
| 64 | // always embedded somewhere else or "in-place constructed" as a full userdata | ||
| 65 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | ||
| 66 | static void operator delete(void* p_, lua_State* L){ ASSERT_L(!"should never be called") }; | ||
| 60 | }; | 67 | }; |
| 61 | 68 | ||
| 62 | static constexpr int CONTENTS_TABLE{ 1 }; | 69 | static constexpr int CONTENTS_TABLE{ 1 }; |
| @@ -66,7 +73,7 @@ static constexpr int CONTENTS_TABLE{ 1 }; | |||
| 66 | // replaces the fifo ud by its uservalue on the stack | 73 | // replaces the fifo ud by its uservalue on the stack |
| 67 | static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) | 74 | static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) |
| 68 | { | 75 | { |
| 69 | keeper_fifo* const fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, idx_)) }; | 76 | keeper_fifo* const fifo{ lua_touserdata<keeper_fifo>(L, idx_) }; |
| 70 | if (fifo != nullptr) | 77 | if (fifo != nullptr) |
| 71 | { | 78 | { |
| 72 | idx_ = lua_absindex(L, idx_); | 79 | idx_ = lua_absindex(L, idx_); |
| @@ -84,13 +91,14 @@ static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) | |||
| 84 | // out: { first = 1, count = 0, limit = -1} | 91 | // out: { first = 1, count = 0, limit = -1} |
| 85 | static void fifo_new(lua_State* L) | 92 | static void fifo_new(lua_State* L) |
| 86 | { | 93 | { |
| 87 | keeper_fifo* fifo; | ||
| 88 | STACK_GROW(L, 2); | 94 | STACK_GROW(L, 2); |
| 95 | STACK_CHECK_START_REL(L, 0); | ||
| 89 | // a fifo full userdata has one uservalue, the table that holds the actual fifo contents | 96 | // a fifo full userdata has one uservalue, the table that holds the actual fifo contents |
| 90 | fifo = (keeper_fifo*) lua_newuserdatauv(L, sizeof(keeper_fifo), 1); | 97 | [[maybe_unused]] keeper_fifo* const fifo{ new (L) keeper_fifo{} }; |
| 91 | fifo->keeper_fifo::keeper_fifo(); | 98 | STACK_CHECK(L, 1); |
| 92 | lua_newtable(L); | 99 | lua_newtable(L); |
| 93 | lua_setiuservalue(L, -2, CONTENTS_TABLE); | 100 | lua_setiuservalue(L, -2, CONTENTS_TABLE); |
| 101 | STACK_CHECK(L, 1); | ||
| 94 | } | 102 | } |
| 95 | 103 | ||
| 96 | // ################################################################################################## | 104 | // ################################################################################################## |
| @@ -163,13 +171,13 @@ static void fifo_pop( lua_State* L, keeper_fifo* fifo_, int count_) | |||
| 163 | 171 | ||
| 164 | // ################################################################################################## | 172 | // ################################################################################################## |
| 165 | 173 | ||
| 166 | // in: linda_ud expected at *absolute* stack slot idx | 174 | // in: linda_ud expected at stack slot idx |
| 167 | // out: fifos[ud] | 175 | // out: fifos[ud] |
| 168 | // crc64/we of string "FIFOS_KEY" generated at http://www.nitrxgen.net/hashgen/ | 176 | // crc64/we of string "FIFOS_KEY" generated at http://www.nitrxgen.net/hashgen/ |
| 169 | static constexpr UniqueKey FIFOS_KEY{ 0xdce50bbc351cd465ull }; | 177 | static constexpr UniqueKey FIFOS_KEY{ 0xdce50bbc351cd465ull }; |
| 170 | static void push_table(lua_State* L, int idx_) | 178 | static void push_table(lua_State* L, int idx_) |
| 171 | { | 179 | { |
| 172 | STACK_GROW(L, 4); | 180 | STACK_GROW(L, 5); |
| 173 | STACK_CHECK_START_REL(L, 0); | 181 | STACK_CHECK_START_REL(L, 0); |
| 174 | idx_ = lua_absindex(L, idx_); | 182 | idx_ = lua_absindex(L, idx_); |
| 175 | FIFOS_KEY.query_registry(L); // ud fifos | 183 | FIFOS_KEY.query_registry(L); // ud fifos |
| @@ -276,7 +284,7 @@ int keepercall_send(lua_State* L) | |||
| 276 | lua_rawset(L, -4); // ud key ... fifos fifo | 284 | lua_rawset(L, -4); // ud key ... fifos fifo |
| 277 | } | 285 | } |
| 278 | lua_remove(L, -2); // ud key ... fifo | 286 | lua_remove(L, -2); // ud key ... fifo |
| 279 | keeper_fifo* fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, -1)) }; | 287 | keeper_fifo* fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
| 280 | if( fifo->limit >= 0 && fifo->count + n > fifo->limit) | 288 | if( fifo->limit >= 0 && fifo->count + n > fifo->limit) |
| 281 | { | 289 | { |
| 282 | lua_settop(L, 0); // | 290 | lua_settop(L, 0); // |
| @@ -374,12 +382,12 @@ int keepercall_limit(lua_State* L) | |||
| 374 | lua_pop(L, 1); // fifos key | 382 | lua_pop(L, 1); // fifos key |
| 375 | lua_pushvalue(L, -1); // fifos key key | 383 | lua_pushvalue(L, -1); // fifos key key |
| 376 | lua_rawget(L, -3); // fifos key fifo|nil | 384 | lua_rawget(L, -3); // fifos key fifo|nil |
| 377 | keeper_fifo* fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, -1)) }; | 385 | keeper_fifo* fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
| 378 | if (fifo == nullptr) | 386 | if (fifo == nullptr) |
| 379 | { // fifos key nil | 387 | { // fifos key nil |
| 380 | lua_pop(L, 1); // fifos key | 388 | lua_pop(L, 1); // fifos key |
| 381 | fifo_new(L); // fifos key fifo | 389 | fifo_new(L); // fifos key fifo |
| 382 | fifo = static_cast<keeper_fifo*>(lua_touserdata(L, -1)); | 390 | fifo = lua_touserdata<keeper_fifo>(L, -1); |
| 383 | lua_rawset(L, -3); // fifos | 391 | lua_rawset(L, -3); // fifos |
| 384 | } | 392 | } |
| 385 | // remove any clutter on the stack | 393 | // remove any clutter on the stack |
| @@ -418,7 +426,7 @@ int keepercall_set(lua_State* L) | |||
| 418 | lua_pushvalue(L, -1); // fifos key key | 426 | lua_pushvalue(L, -1); // fifos key key |
| 419 | lua_rawget(L, 1); // fifos key fifo|nil | 427 | lua_rawget(L, 1); // fifos key fifo|nil |
| 420 | // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! | 428 | // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! |
| 421 | keeper_fifo* const fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, -1)) }; | 429 | keeper_fifo* const fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
| 422 | if (fifo != nullptr) // might be nullptr if we set a nonexistent key to nil | 430 | if (fifo != nullptr) // might be nullptr if we set a nonexistent key to nil |
| 423 | { // fifos key fifo | 431 | { // fifos key fifo |
| 424 | if (fifo->limit < 0) // fifo limit value is the default (unlimited): we can totally remove it | 432 | if (fifo->limit < 0) // fifo limit value is the default (unlimited): we can totally remove it |
| @@ -444,7 +452,7 @@ int keepercall_set(lua_State* L) | |||
| 444 | int const count{ lua_gettop(L) - 2 }; // number of items we want to store | 452 | int const count{ lua_gettop(L) - 2 }; // number of items we want to store |
| 445 | lua_pushvalue(L, 2); // fifos key [val [, ...]] key | 453 | lua_pushvalue(L, 2); // fifos key [val [, ...]] key |
| 446 | lua_rawget(L, 1); // fifos key [val [, ...]] fifo|nil | 454 | lua_rawget(L, 1); // fifos key [val [, ...]] fifo|nil |
| 447 | keeper_fifo* fifo = static_cast<keeper_fifo*>(lua_touserdata( L, -1)); | 455 | keeper_fifo* fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
| 448 | if( fifo == nullptr) // can be nullptr if we store a value at a new key | 456 | if( fifo == nullptr) // can be nullptr if we store a value at a new key |
| 449 | { // fifos key [val [, ...]] nil | 457 | { // fifos key [val [, ...]] nil |
| 450 | // no need to wake writers in that case, because a writer can't wait on an inexistent key | 458 | // no need to wake writers in that case, because a writer can't wait on an inexistent key |
diff --git a/src/lanes.cpp b/src/lanes.cpp index 5945a1a..6b3542b 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
| @@ -442,7 +442,7 @@ static bool selfdestruct_remove( Lane* s) | |||
| 442 | */ | 442 | */ |
| 443 | static int selfdestruct_gc( lua_State* L) | 443 | static int selfdestruct_gc( lua_State* L) |
| 444 | { | 444 | { |
| 445 | Universe* U = (Universe*) lua_touserdata( L, 1); | 445 | Universe* const U{ lua_touserdata<Universe>(L, 1) }; |
| 446 | 446 | ||
| 447 | while( U->selfdestruct_first != SELFDESTRUCT_END) // true at most once! | 447 | while( U->selfdestruct_first != SELFDESTRUCT_END) // true at most once! |
| 448 | { | 448 | { |
| @@ -781,7 +781,7 @@ LUAG_FUNC( set_debug_threadname) | |||
| 781 | // fnv164 of string "debug_threadname" generated at https://www.pelock.com/products/hash-calculator | 781 | // fnv164 of string "debug_threadname" generated at https://www.pelock.com/products/hash-calculator |
| 782 | constexpr UniqueKey hidden_regkey{ 0x79C0669AAAE04440ull }; | 782 | constexpr UniqueKey hidden_regkey{ 0x79C0669AAAE04440ull }; |
| 783 | // C s_lane structure is a light userdata upvalue | 783 | // C s_lane structure is a light userdata upvalue |
| 784 | Lane* s = (Lane*) lua_touserdata( L, lua_upvalueindex( 1)); | 784 | Lane* const s{ lua_touserdata<Lane>(L, lua_upvalueindex(1)) }; |
| 785 | luaL_checktype( L, -1, LUA_TSTRING); // "name" | 785 | luaL_checktype( L, -1, LUA_TSTRING); // "name" |
| 786 | lua_settop( L, 1); | 786 | lua_settop( L, 1); |
| 787 | STACK_CHECK_START_ABS( L, 1); | 787 | STACK_CHECK_START_ABS( L, 1); |
| @@ -1887,7 +1887,7 @@ LUAG_FUNC( configure) | |||
| 1887 | STACK_CHECK( L, 2); | 1887 | STACK_CHECK( L, 2); |
| 1888 | 1888 | ||
| 1889 | // Proxy userdata contents is only a 'DeepPrelude*' pointer | 1889 | // Proxy userdata contents is only a 'DeepPrelude*' pointer |
| 1890 | U->timer_deep = *(DeepPrelude**) lua_touserdata( L, -1); | 1890 | U->timer_deep = *lua_touserdata<DeepPrelude*>(L, -1); |
| 1891 | // increment refcount so that this linda remains alive as long as the universe exists. | 1891 | // increment refcount so that this linda remains alive as long as the universe exists. |
| 1892 | U->timer_deep->m_refcount.fetch_add(1, std::memory_order_relaxed); | 1892 | U->timer_deep->m_refcount.fetch_add(1, std::memory_order_relaxed); |
| 1893 | lua_pop( L, 1); // settings | 1893 | lua_pop( L, 1); // settings |
diff --git a/src/lanes_private.h b/src/lanes_private.h index b8d26d3..839a51f 100644 --- a/src/lanes_private.h +++ b/src/lanes_private.h | |||
| @@ -83,7 +83,7 @@ static inline Lane* get_lane_from_registry( lua_State* L) | |||
| 83 | STACK_GROW( L, 1); | 83 | STACK_GROW( L, 1); |
| 84 | STACK_CHECK_START_REL(L, 0); | 84 | STACK_CHECK_START_REL(L, 0); |
| 85 | CANCEL_TEST_KEY.query_registry(L); | 85 | CANCEL_TEST_KEY.query_registry(L); |
| 86 | Lane* const s = static_cast<Lane*>(lua_touserdata(L, -1)); // lightuserdata (true 's_lane' pointer) / nil | 86 | Lane* const s{ lua_touserdata<Lane>(L, -1) }; // lightuserdata (true 's_lane' pointer) / nil |
| 87 | lua_pop( L, 1); | 87 | lua_pop( L, 1); |
| 88 | STACK_CHECK( L, 0); | 88 | STACK_CHECK( L, 0); |
| 89 | return s; | 89 | return s; |
diff --git a/src/linda.cpp b/src/linda.cpp index eb2349e..7e346d8 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
| @@ -808,7 +808,7 @@ static void* linda_id( lua_State* L, DeepOp op_) | |||
| 808 | 808 | ||
| 809 | case eDO_delete: | 809 | case eDO_delete: |
| 810 | { | 810 | { |
| 811 | struct s_Linda* linda = (struct s_Linda*) lua_touserdata( L, 1); | 811 | struct s_Linda* const linda{ lua_touserdata<struct s_Linda>(L, 1) }; |
| 812 | ASSERT_L( linda); | 812 | ASSERT_L( linda); |
| 813 | 813 | ||
| 814 | // Clean associated structures in the keeper state. | 814 | // Clean associated structures in the keeper state. |
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index c549d72..370cbed 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h | |||
| @@ -124,3 +124,10 @@ inline void STACK_GROW(lua_State* L, int n_) | |||
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | #define LUAG_FUNC( func_name) int LG_##func_name( lua_State* L) | 126 | #define LUAG_FUNC( func_name) int LG_##func_name( lua_State* L) |
| 127 | |||
| 128 | // a small helper to extract a userdata pointer from the stack | ||
| 129 | template<typename T> | ||
| 130 | T* lua_touserdata(lua_State* L, int index_) | ||
| 131 | { | ||
| 132 | return static_cast<T*>(lua_touserdata(L, index_)); | ||
| 133 | } | ||
diff --git a/src/state.cpp b/src/state.cpp index 7bdaec9..b46a145 100644 --- a/src/state.cpp +++ b/src/state.cpp | |||
| @@ -259,7 +259,7 @@ lua_State* create_state( Universe* U, lua_State* from_) | |||
| 259 | lua_pushcclosure( from_, U->provide_allocator, 0); | 259 | lua_pushcclosure( from_, U->provide_allocator, 0); |
| 260 | lua_call( from_, 0, 1); | 260 | lua_call( from_, 0, 1); |
| 261 | { | 261 | { |
| 262 | AllocatorDefinition* const def = (AllocatorDefinition*) lua_touserdata( from_, -1); | 262 | AllocatorDefinition* const def{ lua_touserdata<AllocatorDefinition>(from_, -1) }; |
| 263 | L = lua_newstate( def->m_allocF, def->m_allocUD); | 263 | L = lua_newstate( def->m_allocF, def->m_allocUD); |
| 264 | } | 264 | } |
| 265 | lua_pop( from_, 1); | 265 | lua_pop( from_, 1); |
diff --git a/src/universe.cpp b/src/universe.cpp index 4dd956d..095f000 100644 --- a/src/universe.cpp +++ b/src/universe.cpp | |||
| @@ -67,7 +67,7 @@ Universe* universe_get(lua_State* L) | |||
| 67 | STACK_GROW(L, 2); | 67 | STACK_GROW(L, 2); |
| 68 | STACK_CHECK_START_REL(L, 0); | 68 | STACK_CHECK_START_REL(L, 0); |
| 69 | UNIVERSE_REGKEY.query_registry(L); | 69 | UNIVERSE_REGKEY.query_registry(L); |
| 70 | Universe* const universe = static_cast<Universe*>(lua_touserdata(L, -1)); // nullptr if nil | 70 | Universe* const universe{ lua_touserdata<Universe>(L, -1) }; // nullptr if nil |
| 71 | lua_pop(L, 1); | 71 | lua_pop(L, 1); |
| 72 | STACK_CHECK(L, 0); | 72 | STACK_CHECK(L, 0); |
| 73 | return universe; | 73 | return universe; |
diff --git a/src/universe.h b/src/universe.h index bb3ebdd..04c92ca 100644 --- a/src/universe.h +++ b/src/universe.h | |||
| @@ -142,7 +142,7 @@ struct Universe | |||
| 142 | 142 | ||
| 143 | // Initialized by 'init_once_LOCKED()': the deep userdata Linda object | 143 | // Initialized by 'init_once_LOCKED()': the deep userdata Linda object |
| 144 | // used for timers (each lane will get a proxy to this) | 144 | // used for timers (each lane will get a proxy to this) |
| 145 | volatile DeepPrelude* timer_deep{ nullptr }; // = nullptr | 145 | DeepPrelude* timer_deep{ nullptr }; |
| 146 | 146 | ||
| 147 | #if HAVE_LANE_TRACKING() | 147 | #if HAVE_LANE_TRACKING() |
| 148 | std::mutex tracking_cs; | 148 | std::mutex tracking_cs; |
