diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-13 18:00:21 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-13 18:15:46 +0200 |
| commit | 2e27d4153943145f9102d5d56782ad6e20b76182 (patch) | |
| tree | 6b4fb894b4475b3d74bc55e7b7daa5e6761a93c8 /src | |
| parent | 2e61dc33af885974a2a3a3f8a504061abe91bd71 (diff) | |
| download | lanes-2e27d4153943145f9102d5d56782ad6e20b76182.tar.gz lanes-2e27d4153943145f9102d5d56782ad6e20b76182.tar.bz2 lanes-2e27d4153943145f9102d5d56782ad6e20b76182.zip | |
Progressively applying the coding rules
Diffstat (limited to 'src')
| -rw-r--r-- | src/keeper.cpp | 10 | ||||
| -rw-r--r-- | src/keeper.h | 2 | ||||
| -rw-r--r-- | src/lanes.cpp | 662 | ||||
| -rw-r--r-- | src/lanesconf.h | 2 | ||||
| -rw-r--r-- | src/linda.cpp | 464 | ||||
| -rw-r--r-- | src/lindafactory.cpp | 40 | ||||
| -rw-r--r-- | src/macros_and_utils.h | 2 | ||||
| -rw-r--r-- | src/state.cpp | 133 | ||||
| -rw-r--r-- | src/tools.cpp | 124 | ||||
| -rw-r--r-- | src/universe.cpp | 66 |
10 files changed, 751 insertions, 754 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp index 39d2e85..dcfa2ec 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
| @@ -738,9 +738,9 @@ void keeper_toggle_nil_sentinels(lua_State* L_, int start_, LookupMode const mod | |||
| 738 | * | 738 | * |
| 739 | * Returns: number of return values (pushed to 'L'), unset in case of error | 739 | * Returns: number of return values (pushed to 'L'), unset in case of error |
| 740 | */ | 740 | */ |
| 741 | KeeperCallResult keeper_call(Universe* U_, KeeperState K_, keeper_api_t func_, lua_State* L_, void* linda_, int starting_index_) | 741 | KeeperCallResult keeper_call(KeeperState K_, keeper_api_t func_, lua_State* L_, Linda* linda_, int starting_index_) |
| 742 | { | 742 | { |
| 743 | KeeperCallResult _result{}; | 743 | KeeperCallResult _result; |
| 744 | int const _args{ starting_index_ ? (lua_gettop(L_) - starting_index_ + 1) : 0 }; // L: ... args... K_: | 744 | int const _args{ starting_index_ ? (lua_gettop(L_) - starting_index_ + 1) : 0 }; // L: ... args... K_: |
| 745 | int const _top_K{ lua_gettop(K_) }; | 745 | int const _top_K{ lua_gettop(K_) }; |
| 746 | // if we didn't do anything wrong, the keeper stack should be clean | 746 | // if we didn't do anything wrong, the keeper stack should be clean |
| @@ -751,7 +751,7 @@ KeeperCallResult keeper_call(Universe* U_, KeeperState K_, keeper_api_t func_, l | |||
| 751 | lua_pushlightuserdata(K_, linda_); // L: ... args... K_: func_ linda | 751 | lua_pushlightuserdata(K_, linda_); // L: ... args... K_: func_ linda |
| 752 | if ( | 752 | if ( |
| 753 | (_args == 0) || | 753 | (_args == 0) || |
| 754 | (InterCopyContext{ U_, DestState{ K_ }, SourceState{ L_ }, {}, {}, {}, LookupMode::ToKeeper, {} }.inter_copy(_args) == InterCopyResult::Success) | 754 | (InterCopyContext{ linda_->U, DestState{ K_ }, SourceState{ L_ }, {}, {}, {}, LookupMode::ToKeeper, {} }.inter_copy(_args) == InterCopyResult::Success) |
| 755 | ) { // L: ... args... K_: func_ linda args... | 755 | ) { // L: ... args... K_: func_ linda args... |
| 756 | lua_call(K_, 1 + _args, LUA_MULTRET); // L: ... args... K_: result... | 756 | lua_call(K_, 1 + _args, LUA_MULTRET); // L: ... args... K_: result... |
| 757 | int const retvals{ lua_gettop(K_) - _top_K }; | 757 | int const retvals{ lua_gettop(K_) - _top_K }; |
| @@ -761,7 +761,7 @@ KeeperCallResult keeper_call(Universe* U_, KeeperState K_, keeper_api_t func_, l | |||
| 761 | // when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread) | 761 | // when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread) |
| 762 | if ( | 762 | if ( |
| 763 | (retvals == 0) || | 763 | (retvals == 0) || |
| 764 | (InterCopyContext{ U_, DestState{ L_ }, SourceState{ K_ }, {}, {}, {}, LookupMode::FromKeeper, {} }.inter_move(retvals) == InterCopyResult::Success) | 764 | (InterCopyContext{ linda_->U, DestState{ L_ }, SourceState{ K_ }, {}, {}, {}, LookupMode::FromKeeper, {} }.inter_move(retvals) == InterCopyResult::Success) |
| 765 | ) { // L: ... args... result... K_: result... | 765 | ) { // L: ... args... result... K_: result... |
| 766 | _result.emplace(retvals); | 766 | _result.emplace(retvals); |
| 767 | } | 767 | } |
| @@ -772,7 +772,7 @@ KeeperCallResult keeper_call(Universe* U_, KeeperState K_, keeper_api_t func_, l | |||
| 772 | // don't do this for this particular function, as it is only called during Linda destruction, and we don't want to raise an error, ever | 772 | // don't do this for this particular function, as it is only called during Linda destruction, and we don't want to raise an error, ever |
| 773 | if (func_ != KEEPER_API(clear)) [[unlikely]] { | 773 | if (func_ != KEEPER_API(clear)) [[unlikely]] { |
| 774 | // since keeper state GC is stopped, let's run a step once in a while if required | 774 | // since keeper state GC is stopped, let's run a step once in a while if required |
| 775 | int const _gc_threshold{ U_->keepers->gc_threshold }; | 775 | int const _gc_threshold{ linda_->U->keepers->gc_threshold }; |
| 776 | if (_gc_threshold == 0) [[unlikely]] { | 776 | if (_gc_threshold == 0) [[unlikely]] { |
| 777 | lua_gc(K_, LUA_GCSTEP, 0); | 777 | lua_gc(K_, LUA_GCSTEP, 0); |
| 778 | } else if (_gc_threshold > 0) [[likely]] { | 778 | } else if (_gc_threshold > 0) [[likely]] { |
diff --git a/src/keeper.h b/src/keeper.h index 8f30720..ebe2946 100644 --- a/src/keeper.h +++ b/src/keeper.h | |||
| @@ -58,4 +58,4 @@ using keeper_api_t = lua_CFunction; | |||
| 58 | [[nodiscard]] int keepercall_count(lua_State* L_); | 58 | [[nodiscard]] int keepercall_count(lua_State* L_); |
| 59 | 59 | ||
| 60 | using KeeperCallResult = Unique<std::optional<int>>; | 60 | using KeeperCallResult = Unique<std::optional<int>>; |
| 61 | [[nodiscard]] KeeperCallResult keeper_call(Universe* U_, KeeperState K_, keeper_api_t func_, lua_State* L_, void* linda_, int starting_index_); | 61 | [[nodiscard]] KeeperCallResult keeper_call(KeeperState K_, keeper_api_t func_, lua_State* L_, Linda* linda_, int starting_index_); |
diff --git a/src/lanes.cpp b/src/lanes.cpp index ee40ffa..f0ec84c 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
| @@ -116,7 +116,7 @@ THE SOFTWARE. | |||
| 116 | */ | 116 | */ |
| 117 | static void tracking_add(Lane* lane_) | 117 | static void tracking_add(Lane* lane_) |
| 118 | { | 118 | { |
| 119 | std::lock_guard<std::mutex> guard{ lane_->U->trackingMutex }; | 119 | std::lock_guard<std::mutex> _guard{ lane_->U->trackingMutex }; |
| 120 | assert(lane_->tracking_next == nullptr); | 120 | assert(lane_->tracking_next == nullptr); |
| 121 | 121 | ||
| 122 | lane_->tracking_next = lane_->U->trackingFirst; | 122 | lane_->tracking_next = lane_->U->trackingFirst; |
| @@ -130,27 +130,27 @@ static void tracking_add(Lane* lane_) | |||
| 130 | */ | 130 | */ |
| 131 | [[nodiscard]] static bool tracking_remove(Lane* lane_) | 131 | [[nodiscard]] static bool tracking_remove(Lane* lane_) |
| 132 | { | 132 | { |
| 133 | bool found{ false }; | 133 | bool _found{ false }; |
| 134 | std::lock_guard<std::mutex> guard{ lane_->U->trackingMutex }; | 134 | std::lock_guard<std::mutex> _guard{ lane_->U->trackingMutex }; |
| 135 | // Make sure (within the MUTEX) that we actually are in the chain | 135 | // Make sure (within the MUTEX) that we actually are in the chain |
| 136 | // still (at process exit they will remove us from chain and then | 136 | // still (at process exit they will remove us from chain and then |
| 137 | // cancel/kill). | 137 | // cancel/kill). |
| 138 | // | 138 | // |
| 139 | if (lane_->tracking_next != nullptr) { | 139 | if (lane_->tracking_next != nullptr) { |
| 140 | Lane** ref = (Lane**) &lane_->U->trackingFirst; | 140 | Lane** _ref = (Lane**) &lane_->U->trackingFirst; |
| 141 | 141 | ||
| 142 | while (*ref != TRACKING_END) { | 142 | while (*_ref != TRACKING_END) { |
| 143 | if (*ref == lane_) { | 143 | if (*_ref == lane_) { |
| 144 | *ref = lane_->tracking_next; | 144 | *_ref = lane_->tracking_next; |
| 145 | lane_->tracking_next = nullptr; | 145 | lane_->tracking_next = nullptr; |
| 146 | found = true; | 146 | _found = true; |
| 147 | break; | 147 | break; |
| 148 | } | 148 | } |
| 149 | ref = (Lane**) &((*ref)->tracking_next); | 149 | _ref = (Lane**) &((*_ref)->tracking_next); |
| 150 | } | 150 | } |
| 151 | assert(found); | 151 | assert(_found); |
| 152 | } | 152 | } |
| 153 | return found; | 153 | return _found; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | #endif // HAVE_LANE_TRACKING() | 156 | #endif // HAVE_LANE_TRACKING() |
| @@ -172,15 +172,15 @@ Lane::Lane(Universe* U_, lua_State* L_) | |||
| 172 | 172 | ||
| 173 | bool Lane::waitForCompletion(std::chrono::time_point<std::chrono::steady_clock> until_) | 173 | bool Lane::waitForCompletion(std::chrono::time_point<std::chrono::steady_clock> until_) |
| 174 | { | 174 | { |
| 175 | std::unique_lock lock{ doneMutex }; | 175 | std::unique_lock _guard{ doneMutex }; |
| 176 | // std::stop_token token{ thread.get_stop_token() }; | 176 | // std::stop_token token{ thread.get_stop_token() }; |
| 177 | // return doneCondVar.wait_until(lock, token, secs_, [this](){ return status >= Lane::Done; }); | 177 | // return doneCondVar.wait_until(lock, token, secs_, [this](){ return status >= Lane::Done; }); |
| 178 | return doneCondVar.wait_until(lock, until_, [this]() { return status >= Lane::Done; }); | 178 | return doneCondVar.wait_until(_guard, until_, [this]() { return status >= Lane::Done; }); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | // ################################################################################################# | 181 | // ################################################################################################# |
| 182 | 182 | ||
| 183 | static void lane_main(Lane* lane); | 183 | static void lane_main(Lane* lane_); |
| 184 | void Lane::startThread(int priority_) | 184 | void Lane::startThread(int priority_) |
| 185 | { | 185 | { |
| 186 | thread = std::jthread([this]() { lane_main(this); }); | 186 | thread = std::jthread([this]() { lane_main(this); }); |
| @@ -267,9 +267,9 @@ LUAG_FUNC(set_finalizer) | |||
| 267 | // Get the current finalizer table (if any), create one if it doesn't exist | 267 | // Get the current finalizer table (if any), create one if it doesn't exist |
| 268 | std::ignore = kFinalizerRegKey.getSubTable(L_, 1, 0); // L_: finalizer {finalisers} | 268 | std::ignore = kFinalizerRegKey.getSubTable(L_, 1, 0); // L_: finalizer {finalisers} |
| 269 | // must cast to int, not lua_Integer, because LuaJIT signature of lua_rawseti is not the same as PUC-Lua. | 269 | // must cast to int, not lua_Integer, because LuaJIT signature of lua_rawseti is not the same as PUC-Lua. |
| 270 | int const idx{ static_cast<int>(lua_rawlen(L_, -1) + 1) }; | 270 | int const _idx{ static_cast<int>(lua_rawlen(L_, -1) + 1) }; |
| 271 | lua_pushvalue(L_, 1); // L_: finalizer {finalisers} finalizer | 271 | lua_pushvalue(L_, 1); // L_: finalizer {finalisers} finalizer |
| 272 | lua_rawseti(L_, -2, idx); // L_: finalizer {finalisers} | 272 | lua_rawseti(L_, -2, _idx); // L_: finalizer {finalisers} |
| 273 | // no need to adjust the stack, Lua does this for us | 273 | // no need to adjust the stack, Lua does this for us |
| 274 | return 0; | 274 | return 0; |
| 275 | } | 275 | } |
| @@ -337,28 +337,28 @@ static void push_stack_trace(lua_State* L_, int rc_, int stk_base_) | |||
| 337 | 337 | ||
| 338 | STACK_GROW(L_, 5); | 338 | STACK_GROW(L_, 5); |
| 339 | 339 | ||
| 340 | int const finalizers_index{ lua_gettop(L_) }; | 340 | int const _finalizers_index{ lua_gettop(L_) }; |
| 341 | int const err_handler_index{ ERROR_FULL_STACK ? (lua_pushcfunction(L_, lane_error), lua_gettop(L_)) : 0 }; | 341 | int const _err_handler_index{ ERROR_FULL_STACK ? (lua_pushcfunction(L_, lane_error), lua_gettop(L_)) : 0 }; |
| 342 | 342 | ||
| 343 | int rc{ LUA_OK }; | 343 | int rc{ LUA_OK }; |
| 344 | for (int n = static_cast<int>(lua_rawlen(L_, finalizers_index)); n > 0; --n) { | 344 | for (int n = static_cast<int>(lua_rawlen(L_, _finalizers_index)); n > 0; --n) { |
| 345 | int args = 0; | 345 | int args = 0; |
| 346 | lua_pushinteger(L_, n); // L_: ... finalizers lane_error n | 346 | lua_pushinteger(L_, n); // L_: ... finalizers lane_error n |
| 347 | lua_rawget(L_, finalizers_index); // L_: ... finalizers lane_error finalizer | 347 | lua_rawget(L_, _finalizers_index); // L_: ... finalizers lane_error finalizer |
| 348 | LUA_ASSERT(L_, lua_isfunction(L_, -1)); | 348 | LUA_ASSERT(L_, lua_isfunction(L_, -1)); |
| 349 | if (lua_rc_ != LUA_OK) { // we have an error message and an optional stack trace at the bottom of the stack | 349 | if (lua_rc_ != LUA_OK) { // we have an error message and an optional stack trace at the bottom of the stack |
| 350 | LUA_ASSERT(L_, finalizers_index == 2 || finalizers_index == 3); | 350 | LUA_ASSERT(L_, _finalizers_index == 2 || _finalizers_index == 3); |
| 351 | // char const* err_msg = lua_tostring(L_, 1); | 351 | // char const* err_msg = lua_tostring(L_, 1); |
| 352 | lua_pushvalue(L_, 1); // L_: ... finalizers lane_error finalizer err_msg | 352 | lua_pushvalue(L_, 1); // L_: ... finalizers lane_error finalizer err_msg |
| 353 | // note we don't always have a stack trace for example when kCancelError, or when we got an error that doesn't call our handler, such as LUA_ERRMEM | 353 | // note we don't always have a stack trace for example when kCancelError, or when we got an error that doesn't call our handler, such as LUA_ERRMEM |
| 354 | if (finalizers_index == 3) { | 354 | if (_finalizers_index == 3) { |
| 355 | lua_pushvalue(L_, 2); // L_: ... finalizers lane_error finalizer err_msg stack_trace | 355 | lua_pushvalue(L_, 2); // L_: ... finalizers lane_error finalizer err_msg stack_trace |
| 356 | } | 356 | } |
| 357 | args = finalizers_index - 1; | 357 | args = _finalizers_index - 1; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | // if no error from the main body, finalizer doesn't receive any argument, else it gets the error message and optional stack trace | 360 | // if no error from the main body, finalizer doesn't receive any argument, else it gets the error message and optional stack trace |
| 361 | rc = lua_pcall(L_, args, 0, err_handler_index); // L_: ... finalizers lane_error err_msg2? | 361 | rc = lua_pcall(L_, args, 0, _err_handler_index); // L_: ... finalizers lane_error err_msg2? |
| 362 | if (rc != LUA_OK) { | 362 | if (rc != LUA_OK) { |
| 363 | push_stack_trace(L_, rc, lua_gettop(L_)); // L_: ... finalizers lane_error err_msg2? trace | 363 | push_stack_trace(L_, rc, lua_gettop(L_)); // L_: ... finalizers lane_error err_msg2? trace |
| 364 | // If one finalizer fails, don't run the others. Return this | 364 | // If one finalizer fails, don't run the others. Return this |
| @@ -371,7 +371,7 @@ static void push_stack_trace(lua_State* L_, int rc_, int stk_base_) | |||
| 371 | 371 | ||
| 372 | if (rc != LUA_OK) { | 372 | if (rc != LUA_OK) { |
| 373 | // ERROR_FULL_STACK accounts for the presence of lane_error on the stack | 373 | // ERROR_FULL_STACK accounts for the presence of lane_error on the stack |
| 374 | int const nb_err_slots{ lua_gettop(L_) - finalizers_index - ERROR_FULL_STACK }; | 374 | int const nb_err_slots{ lua_gettop(L_) - _finalizers_index - ERROR_FULL_STACK }; |
| 375 | // a finalizer generated an error, this is what we leave of the stack | 375 | // a finalizer generated an error, this is what we leave of the stack |
| 376 | for (int n = nb_err_slots; n > 0; --n) { | 376 | for (int n = nb_err_slots; n > 0; --n) { |
| 377 | lua_replace(L_, n); | 377 | lua_replace(L_, n); |
| @@ -379,7 +379,7 @@ static void push_stack_trace(lua_State* L_, int rc_, int stk_base_) | |||
| 379 | // leave on the stack only the error and optional stack trace produced by the error in the finalizer | 379 | // leave on the stack only the error and optional stack trace produced by the error in the finalizer |
| 380 | lua_settop(L_, nb_err_slots); // L_: ... lane_error trace | 380 | lua_settop(L_, nb_err_slots); // L_: ... lane_error trace |
| 381 | } else { // no error from the finalizers, make sure only the original return values from the lane body remain on the stack | 381 | } else { // no error from the finalizers, make sure only the original return values from the lane body remain on the stack |
| 382 | lua_settop(L_, finalizers_index - 1); | 382 | lua_settop(L_, _finalizers_index - 1); |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | return rc; | 385 | return rc; |
| @@ -395,7 +395,7 @@ static void push_stack_trace(lua_State* L_, int rc_, int stk_base_) | |||
| 395 | */ | 395 | */ |
| 396 | static void selfdestruct_add(Lane* lane_) | 396 | static void selfdestruct_add(Lane* lane_) |
| 397 | { | 397 | { |
| 398 | std::lock_guard<std::mutex> guard{ lane_->U->selfdestructMutex }; | 398 | std::lock_guard<std::mutex> _guard{ lane_->U->selfdestructMutex }; |
| 399 | assert(lane_->selfdestruct_next == nullptr); | 399 | assert(lane_->selfdestruct_next == nullptr); |
| 400 | 400 | ||
| 401 | lane_->selfdestruct_next = lane_->U->selfdestructFirst; | 401 | lane_->selfdestruct_next = lane_->U->selfdestructFirst; |
| @@ -407,29 +407,29 @@ static void selfdestruct_add(Lane* lane_) | |||
| 407 | // A free-running lane has ended; remove it from selfdestruct chain | 407 | // A free-running lane has ended; remove it from selfdestruct chain |
| 408 | [[nodiscard]] static bool selfdestruct_remove(Lane* lane_) | 408 | [[nodiscard]] static bool selfdestruct_remove(Lane* lane_) |
| 409 | { | 409 | { |
| 410 | bool found{ false }; | 410 | bool _found{ false }; |
| 411 | std::lock_guard<std::mutex> guard{ lane_->U->selfdestructMutex }; | 411 | std::lock_guard<std::mutex> _guard{ lane_->U->selfdestructMutex }; |
| 412 | // Make sure (within the MUTEX) that we actually are in the chain | 412 | // Make sure (within the MUTEX) that we actually are in the chain |
| 413 | // still (at process exit they will remove us from chain and then | 413 | // still (at process exit they will remove us from chain and then |
| 414 | // cancel/kill). | 414 | // cancel/kill). |
| 415 | // | 415 | // |
| 416 | if (lane_->selfdestruct_next != nullptr) { | 416 | if (lane_->selfdestruct_next != nullptr) { |
| 417 | Lane* volatile* ref = static_cast<Lane* volatile*>(&lane_->U->selfdestructFirst); | 417 | Lane* volatile* _ref = static_cast<Lane* volatile*>(&lane_->U->selfdestructFirst); |
| 418 | 418 | ||
| 419 | while (*ref != SELFDESTRUCT_END) { | 419 | while (*_ref != SELFDESTRUCT_END) { |
| 420 | if (*ref == lane_) { | 420 | if (*_ref == lane_) { |
| 421 | *ref = lane_->selfdestruct_next; | 421 | *_ref = lane_->selfdestruct_next; |
| 422 | lane_->selfdestruct_next = nullptr; | 422 | lane_->selfdestruct_next = nullptr; |
| 423 | // the terminal shutdown should wait until the lane is done with its lua_close() | 423 | // the terminal shutdown should wait until the lane is done with its lua_close() |
| 424 | lane_->U->selfdestructingCount.fetch_add(1, std::memory_order_release); | 424 | lane_->U->selfdestructingCount.fetch_add(1, std::memory_order_release); |
| 425 | found = true; | 425 | _found = true; |
| 426 | break; | 426 | break; |
| 427 | } | 427 | } |
| 428 | ref = static_cast<Lane* volatile*>(&((*ref)->selfdestruct_next)); | 428 | _ref = static_cast<Lane* volatile*>(&((*_ref)->selfdestruct_next)); |
| 429 | } | 429 | } |
| 430 | assert(found); | 430 | assert(_found); |
| 431 | } | 431 | } |
| 432 | return found; | 432 | return _found; |
| 433 | } | 433 | } |
| 434 | 434 | ||
| 435 | // ################################################################################################# | 435 | // ################################################################################################# |
| @@ -442,11 +442,11 @@ static void selfdestruct_add(Lane* lane_) | |||
| 442 | // | 442 | // |
| 443 | LUAG_FUNC(set_singlethreaded) | 443 | LUAG_FUNC(set_singlethreaded) |
| 444 | { | 444 | { |
| 445 | [[maybe_unused]] lua_Integer const cores{ luaL_optinteger(L_, 1, 1) }; | 445 | [[maybe_unused]] lua_Integer const _cores{ luaL_optinteger(L_, 1, 1) }; |
| 446 | 446 | ||
| 447 | #ifdef PLATFORM_OSX | 447 | #ifdef PLATFORM_OSX |
| 448 | #ifdef _UTILBINDTHREADTOCPU | 448 | #ifdef _UTILBINDTHREADTOCPU |
| 449 | if (cores > 1) { | 449 | if (_cores > 1) { |
| 450 | raise_luaL_error(L_, "Limiting to N>1 cores not possible"); | 450 | raise_luaL_error(L_, "Limiting to N>1 cores not possible"); |
| 451 | } | 451 | } |
| 452 | // requires 'chudInitialize()' | 452 | // requires 'chudInitialize()' |
| @@ -486,15 +486,15 @@ static constexpr RegistryUniqueKey kExtendedStackTraceRegKey{ 0x38147AD48FB426E2 | |||
| 486 | LUAG_FUNC(set_error_reporting) | 486 | LUAG_FUNC(set_error_reporting) |
| 487 | { | 487 | { |
| 488 | luaL_checktype(L_, 1, LUA_TSTRING); | 488 | luaL_checktype(L_, 1, LUA_TSTRING); |
| 489 | char const* mode{ lua_tostring(L_, 1) }; | 489 | char const* _mode{ lua_tostring(L_, 1) }; |
| 490 | lua_pushliteral(L_, "extended"); | 490 | lua_pushliteral(L_, "extended"); |
| 491 | bool const extended{ strcmp(mode, "extended") == 0 }; | 491 | bool const _extended{ strcmp(_mode, "extended") == 0 }; |
| 492 | bool const basic{ strcmp(mode, "basic") == 0 }; | 492 | bool const _basic{ strcmp(_mode, "basic") == 0 }; |
| 493 | if (!extended && !basic) { | 493 | if (!_extended && !_basic) { |
| 494 | raise_luaL_error(L_, "unsupported error reporting model %s", mode); | 494 | raise_luaL_error(L_, "unsupported error reporting model %s", _mode); |
| 495 | } | 495 | } |
| 496 | 496 | ||
| 497 | kExtendedStackTraceRegKey.setValue(L_, [extended](lua_State* L_) { lua_pushboolean(L_, extended ? 1 : 0); }); | 497 | kExtendedStackTraceRegKey.setValue(L_, [extended = _extended](lua_State* L_) { lua_pushboolean(L_, extended ? 1 : 0); }); |
| 498 | return 0; | 498 | return 0; |
| 499 | } | 499 | } |
| 500 | 500 | ||
| @@ -512,7 +512,7 @@ LUAG_FUNC(set_error_reporting) | |||
| 512 | } | 512 | } |
| 513 | 513 | ||
| 514 | STACK_GROW(L_, 3); | 514 | STACK_GROW(L_, 3); |
| 515 | bool const extended{ kExtendedStackTraceRegKey.readBoolValue(L_) }; | 515 | bool const _extended{ kExtendedStackTraceRegKey.readBoolValue(L_) }; |
| 516 | STACK_CHECK(L_, 1); | 516 | STACK_CHECK(L_, 1); |
| 517 | 517 | ||
| 518 | // Place stack trace at 'registry[kStackTraceRegKey]' for the 'lua_pcall()' | 518 | // Place stack trace at 'registry[kStackTraceRegKey]' for the 'lua_pcall()' |
| @@ -531,32 +531,32 @@ LUAG_FUNC(set_error_reporting) | |||
| 531 | // and we don't get '.currentline' for that. It's okay - just keep level | 531 | // and we don't get '.currentline' for that. It's okay - just keep level |
| 532 | // and table index growing separate. --AKa 22-Jan-2009 | 532 | // and table index growing separate. --AKa 22-Jan-2009 |
| 533 | // | 533 | // |
| 534 | lua_Debug ar; | 534 | lua_Debug _ar; |
| 535 | for (int n = 1; lua_getstack(L_, n, &ar); ++n) { | 535 | for (int _n = 1; lua_getstack(L_, _n, &_ar); ++_n) { |
| 536 | lua_getinfo(L_, extended ? "Sln" : "Sl", &ar); | 536 | lua_getinfo(L_, _extended ? "Sln" : "Sl", &_ar); |
| 537 | if (extended) { | 537 | if (_extended) { |
| 538 | lua_newtable(L_); // L_: some_error {} {} | 538 | lua_newtable(L_); // L_: some_error {} {} |
| 539 | 539 | ||
| 540 | lua_pushstring(L_, ar.source); // L_: some_error {} {} source | 540 | lua_pushstring(L_, _ar.source); // L_: some_error {} {} source |
| 541 | lua_setfield(L_, -2, "source"); // L_: some_error {} {} | 541 | lua_setfield(L_, -2, "source"); // L_: some_error {} {} |
| 542 | 542 | ||
| 543 | lua_pushinteger(L_, ar.currentline); // L_: some_error {} {} currentline | 543 | lua_pushinteger(L_, _ar.currentline); // L_: some_error {} {} currentline |
| 544 | lua_setfield(L_, -2, "currentline"); // L_: some_error {} {} | 544 | lua_setfield(L_, -2, "currentline"); // L_: some_error {} {} |
| 545 | 545 | ||
| 546 | lua_pushstring(L_, ar.name); // L_: some_error {} {} name | 546 | lua_pushstring(L_, _ar.name); // L_: some_error {} {} name |
| 547 | lua_setfield(L_, -2, "name"); // L_: some_error {} {} | 547 | lua_setfield(L_, -2, "name"); // L_: some_error {} {} |
| 548 | 548 | ||
| 549 | lua_pushstring(L_, ar.namewhat); // L_: some_error {} {} namewhat | 549 | lua_pushstring(L_, _ar.namewhat); // L_: some_error {} {} namewhat |
| 550 | lua_setfield(L_, -2, "namewhat"); // L_: some_error {} {} | 550 | lua_setfield(L_, -2, "namewhat"); // L_: some_error {} {} |
| 551 | 551 | ||
| 552 | lua_pushstring(L_, ar.what); // L_: some_error {} {} what | 552 | lua_pushstring(L_, _ar.what); // L_: some_error {} {} what |
| 553 | lua_setfield(L_, -2, "what"); // L_: some_error {} {} | 553 | lua_setfield(L_, -2, "what"); // L_: some_error {} {} |
| 554 | } else if (ar.currentline > 0) { | 554 | } else if (_ar.currentline > 0) { |
| 555 | lua_pushfstring(L_, "%s:%d", ar.short_src, ar.currentline); // L_: some_error {} "blah:blah" | 555 | lua_pushfstring(L_, "%s:%d", _ar.short_src, _ar.currentline); // L_: some_error {} "blah:blah" |
| 556 | } else { | 556 | } else { |
| 557 | lua_pushfstring(L_, "%s:?", ar.short_src); // L_: some_error {} "blah" | 557 | lua_pushfstring(L_, "%s:?", _ar.short_src); // L_: some_error {} "blah" |
| 558 | } | 558 | } |
| 559 | lua_rawseti(L_, -2, (lua_Integer) n); // L_: some_error {} | 559 | lua_rawseti(L_, -2, static_cast<lua_Integer>(_n)); // L_: some_error {} |
| 560 | } | 560 | } |
| 561 | 561 | ||
| 562 | // store the stack trace table in the registry | 562 | // store the stack trace table in the registry |
| @@ -572,12 +572,12 @@ LUAG_FUNC(set_error_reporting) | |||
| 572 | void Lane::changeDebugName(int nameIdx_) | 572 | void Lane::changeDebugName(int nameIdx_) |
| 573 | { | 573 | { |
| 574 | // xxh64 of string "debugName" generated at https://www.pelock.com/products/hash-calculator | 574 | // xxh64 of string "debugName" generated at https://www.pelock.com/products/hash-calculator |
| 575 | static constexpr RegistryUniqueKey hidden_regkey{ 0xA194E2645C57F6DDull }; | 575 | static constexpr RegistryUniqueKey kRegKey{ 0xA194E2645C57F6DDull }; |
| 576 | nameIdx_ = lua_absindex(L, nameIdx_); | 576 | nameIdx_ = lua_absindex(L, nameIdx_); |
| 577 | luaL_checktype(L, nameIdx_, LUA_TSTRING); // L: ... "name" ... | 577 | luaL_checktype(L, nameIdx_, LUA_TSTRING); // L: ... "name" ... |
| 578 | STACK_CHECK_START_REL(L, 0); | 578 | STACK_CHECK_START_REL(L, 0); |
| 579 | // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global... | 579 | // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global... |
| 580 | hidden_regkey.setValue(L, [nameIdx = nameIdx_](lua_State* L_) { lua_pushvalue(L_, nameIdx); });// L: ... "name" ... | 580 | kRegKey.setValue(L, [nameIdx = nameIdx_](lua_State* L_) { lua_pushvalue(L_, nameIdx); }); // L: ... "name" ... |
| 581 | // keep a direct pointer on the string | 581 | // keep a direct pointer on the string |
| 582 | debugName = lua_tostring(L, nameIdx_); | 582 | debugName = lua_tostring(L, nameIdx_); |
| 583 | // to see VM name in Decoda debugger Virtual Machine window | 583 | // to see VM name in Decoda debugger Virtual Machine window |
| @@ -594,11 +594,11 @@ void Lane::changeDebugName(int nameIdx_) | |||
| 594 | LUAG_FUNC(set_debug_threadname) | 594 | LUAG_FUNC(set_debug_threadname) |
| 595 | { | 595 | { |
| 596 | // C s_lane structure is a light userdata upvalue | 596 | // C s_lane structure is a light userdata upvalue |
| 597 | Lane* const lane{ lua_tolightuserdata<Lane>(L_, lua_upvalueindex(1)) }; | 597 | Lane* const _lane{ lua_tolightuserdata<Lane>(L_, lua_upvalueindex(1)) }; |
| 598 | LUA_ASSERT(L_, L_ == lane->L); // this function is exported in a lane's state, therefore it is callable only from inside the Lane's state | 598 | LUA_ASSERT(L_, L_ == _lane->L); // this function is exported in a lane's state, therefore it is callable only from inside the Lane's state |
| 599 | lua_settop(L_, 1); | 599 | lua_settop(L_, 1); |
| 600 | STACK_CHECK_START_REL(L_, 0); | 600 | STACK_CHECK_START_REL(L_, 0); |
| 601 | lane->changeDebugName(-1); | 601 | _lane->changeDebugName(-1); |
| 602 | STACK_CHECK(L_, 0); | 602 | STACK_CHECK(L_, 0); |
| 603 | return 0; | 603 | return 0; |
| 604 | } | 604 | } |
| @@ -607,9 +607,9 @@ LUAG_FUNC(set_debug_threadname) | |||
| 607 | 607 | ||
| 608 | LUAG_FUNC(get_debug_threadname) | 608 | LUAG_FUNC(get_debug_threadname) |
| 609 | { | 609 | { |
| 610 | Lane* const lane{ ToLane(L_, 1) }; | 610 | Lane* const _lane{ ToLane(L_, 1) }; |
| 611 | luaL_argcheck(L_, lua_gettop(L_) == 1, 2, "too many arguments"); | 611 | luaL_argcheck(L_, lua_gettop(L_) == 1, 2, "too many arguments"); |
| 612 | lua_pushstring(L_, lane->debugName); | 612 | lua_pushstring(L_, _lane->debugName); |
| 613 | return 1; | 613 | return 1; |
| 614 | } | 614 | } |
| 615 | 615 | ||
| @@ -617,14 +617,14 @@ LUAG_FUNC(get_debug_threadname) | |||
| 617 | 617 | ||
| 618 | LUAG_FUNC(set_thread_priority) | 618 | LUAG_FUNC(set_thread_priority) |
| 619 | { | 619 | { |
| 620 | lua_Integer const prio{ luaL_checkinteger(L_, 1) }; | 620 | lua_Integer const _prio{ luaL_checkinteger(L_, 1) }; |
| 621 | // public Lanes API accepts a generic range -3/+3 | 621 | // public Lanes API accepts a generic range -3/+3 |
| 622 | // that will be remapped into the platform-specific scheduler priority scheme | 622 | // that will be remapped into the platform-specific scheduler priority scheme |
| 623 | // On some platforms, -3 is equivalent to -2 and +3 to +2 | 623 | // On some platforms, -3 is equivalent to -2 and +3 to +2 |
| 624 | if (prio < kThreadPrioMin || prio > kThreadPrioMax) { | 624 | if (_prio < kThreadPrioMin || _prio > kThreadPrioMax) { |
| 625 | raise_luaL_error(L_, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, prio); | 625 | raise_luaL_error(L_, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, _prio); |
| 626 | } | 626 | } |
| 627 | THREAD_SET_PRIORITY(static_cast<int>(prio), universe_get(L_)->sudo); | 627 | THREAD_SET_PRIORITY(static_cast<int>(_prio), universe_get(L_)->sudo); |
| 628 | return 0; | 628 | return 0; |
| 629 | } | 629 | } |
| 630 | 630 | ||
| @@ -632,11 +632,11 @@ LUAG_FUNC(set_thread_priority) | |||
| 632 | 632 | ||
| 633 | LUAG_FUNC(set_thread_affinity) | 633 | LUAG_FUNC(set_thread_affinity) |
| 634 | { | 634 | { |
| 635 | lua_Integer const affinity{ luaL_checkinteger(L_, 1) }; | 635 | lua_Integer const _affinity{ luaL_checkinteger(L_, 1) }; |
| 636 | if (affinity <= 0) { | 636 | if (_affinity <= 0) { |
| 637 | raise_luaL_error(L_, "invalid affinity (%d)", affinity); | 637 | raise_luaL_error(L_, "invalid affinity (%d)", _affinity); |
| 638 | } | 638 | } |
| 639 | THREAD_SET_AFFINITY(static_cast<unsigned int>(affinity)); | 639 | THREAD_SET_AFFINITY(static_cast<unsigned int>(_affinity)); |
| 640 | return 0; | 640 | return 0; |
| 641 | } | 641 | } |
| 642 | 642 | ||
| @@ -662,9 +662,9 @@ static struct errcode_name s_errcodes[] = { | |||
| 662 | }; | 662 | }; |
| 663 | static char const* get_errcode_name(int _code) | 663 | static char const* get_errcode_name(int _code) |
| 664 | { | 664 | { |
| 665 | for (int i{ 0 }; i < 7; ++i) { | 665 | for (errcode_name const& _entry : s_errcodes) { |
| 666 | if (s_errcodes[i].code == _code) { | 666 | if (_entry.code == _code) { |
| 667 | return s_errcodes[i].name; | 667 | return _entry.name; |
| 668 | } | 668 | } |
| 669 | } | 669 | } |
| 670 | return "<nullptr>"; | 670 | return "<nullptr>"; |
| @@ -675,61 +675,61 @@ static char const* get_errcode_name(int _code) | |||
| 675 | 675 | ||
| 676 | static void lane_main(Lane* lane_) | 676 | static void lane_main(Lane* lane_) |
| 677 | { | 677 | { |
| 678 | lua_State* const L{ lane_->L }; | 678 | lua_State* const _L{ lane_->L }; |
| 679 | // wait until the launching thread has finished preparing L | 679 | // wait until the launching thread has finished preparing L |
| 680 | lane_->ready.wait(); | 680 | lane_->ready.wait(); |
| 681 | int rc{ LUA_ERRRUN }; | 681 | int _rc{ LUA_ERRRUN }; |
| 682 | if (lane_->status == Lane::Pending) { // nothing wrong happened during preparation, we can work | 682 | if (lane_->status == Lane::Pending) { // nothing wrong happened during preparation, we can work |
| 683 | // At this point, the lane function and arguments are on the stack | 683 | // At this point, the lane function and arguments are on the stack |
| 684 | int const nargs{ lua_gettop(L) - 1 }; | 684 | int const nargs{ lua_gettop(_L) - 1 }; |
| 685 | DEBUGSPEW_CODE(Universe* U = universe_get(L)); | 685 | DEBUGSPEW_CODE(Universe* U = universe_get(_L)); |
| 686 | lane_->status = Lane::Running; // Pending -> Running | 686 | lane_->status = Lane::Running; // Pending -> Running |
| 687 | 687 | ||
| 688 | // Tie "set_finalizer()" to the state | 688 | // Tie "set_finalizer()" to the state |
| 689 | lua_pushcfunction(L, LG_set_finalizer); | 689 | lua_pushcfunction(_L, LG_set_finalizer); |
| 690 | populate_func_lookup_table(L, -1, "set_finalizer"); | 690 | populate_func_lookup_table(_L, -1, "set_finalizer"); |
| 691 | lua_setglobal(L, "set_finalizer"); | 691 | lua_setglobal(_L, "set_finalizer"); |
| 692 | 692 | ||
| 693 | // Tie "set_debug_threadname()" to the state | 693 | // Tie "set_debug_threadname()" to the state |
| 694 | // But don't register it in the lookup database because of the Lane pointer upvalue | 694 | // But don't register it in the lookup database because of the Lane pointer upvalue |
| 695 | lua_pushlightuserdata(L, lane_); | 695 | lua_pushlightuserdata(_L, lane_); |
| 696 | lua_pushcclosure(L, LG_set_debug_threadname, 1); | 696 | lua_pushcclosure(_L, LG_set_debug_threadname, 1); |
| 697 | lua_setglobal(L, "set_debug_threadname"); | 697 | lua_setglobal(_L, "set_debug_threadname"); |
| 698 | 698 | ||
| 699 | // Tie "cancel_test()" to the state | 699 | // Tie "cancel_test()" to the state |
| 700 | lua_pushcfunction(L, LG_cancel_test); | 700 | lua_pushcfunction(_L, LG_cancel_test); |
| 701 | populate_func_lookup_table(L, -1, "cancel_test"); | 701 | populate_func_lookup_table(_L, -1, "cancel_test"); |
| 702 | lua_setglobal(L, "cancel_test"); | 702 | lua_setglobal(_L, "cancel_test"); |
| 703 | 703 | ||
| 704 | // this could be done in lane_new before the lane body function is pushed on the stack to avoid unnecessary stack slot shifting around | 704 | // this could be done in lane_new before the lane body function is pushed on the stack to avoid unnecessary stack slot shifting around |
| 705 | #if ERROR_FULL_STACK | 705 | #if ERROR_FULL_STACK |
| 706 | // Tie "set_error_reporting()" to the state | 706 | // Tie "set_error_reporting()" to the state |
| 707 | lua_pushcfunction(L, LG_set_error_reporting); | 707 | lua_pushcfunction(_L, LG_set_error_reporting); |
| 708 | populate_func_lookup_table(L, -1, "set_error_reporting"); | 708 | populate_func_lookup_table(_L, -1, "set_error_reporting"); |
| 709 | lua_setglobal(L, "set_error_reporting"); | 709 | lua_setglobal(_L, "set_error_reporting"); |
| 710 | 710 | ||
| 711 | STACK_GROW(L, 1); | 711 | STACK_GROW(_L, 1); |
| 712 | lua_pushcfunction(L, lane_error); // L: func args handler | 712 | lua_pushcfunction(_L, lane_error); // L: func args handler |
| 713 | lua_insert(L, 1); // L: handler func args | 713 | lua_insert(_L, 1); // L: handler func args |
| 714 | #endif // L: ERROR_FULL_STACK | 714 | #endif // L: ERROR_FULL_STACK |
| 715 | 715 | ||
| 716 | rc = lua_pcall(L, nargs, LUA_MULTRET, ERROR_FULL_STACK); // L: retvals|err | 716 | _rc = lua_pcall(_L, nargs, LUA_MULTRET, ERROR_FULL_STACK); // L: retvals|err |
| 717 | 717 | ||
| 718 | #if ERROR_FULL_STACK | 718 | #if ERROR_FULL_STACK |
| 719 | lua_remove(L, 1); // L: retvals|error | 719 | lua_remove(_L, 1); // L: retvals|error |
| 720 | #endif // ERROR_FULL_STACK | 720 | #endif // ERROR_FULL_STACK |
| 721 | 721 | ||
| 722 | // in case of error and if it exists, fetch stack trace from registry and push it | 722 | // in case of error and if it exists, fetch stack trace from registry and push it |
| 723 | push_stack_trace(L, rc, 1); // L: retvals|error [trace] | 723 | push_stack_trace(_L, _rc, 1); // L: retvals|error [trace] |
| 724 | 724 | ||
| 725 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "Lane %p body: %s (%s)\n" INDENT_END(U), L, get_errcode_name(rc), kCancelError.equals(L, 1) ? "cancelled" : lua_typename(L, lua_type(L, 1)))); | 725 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "Lane %p body: %s (%s)\n" INDENT_END(U), _L, get_errcode_name(_rc), kCancelError.equals(_L, 1) ? "cancelled" : lua_typename(_L, lua_type(_L, 1)))); |
| 726 | // Call finalizers, if the script has set them up. | 726 | // Call finalizers, if the script has set them up. |
| 727 | // | 727 | // |
| 728 | int rc2{ run_finalizers(L, rc) }; | 728 | int _rc2{ run_finalizers(_L, _rc) }; |
| 729 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "Lane %p finalizer: %s\n" INDENT_END(U), L, get_errcode_name(rc2))); | 729 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "Lane %p finalizer: %s\n" INDENT_END(U), _L, get_errcode_name(_rc2))); |
| 730 | if (rc2 != LUA_OK) { // Error within a finalizer! | 730 | if (_rc2 != LUA_OK) { // Error within a finalizer! |
| 731 | // the finalizer generated an error, and left its own error message [and stack trace] on the stack | 731 | // the finalizer generated an error, and left its own error message [and stack trace] on the stack |
| 732 | rc = rc2; // we're overruling the earlier script error or normal return | 732 | _rc = _rc2; // we're overruling the earlier script error or normal return |
| 733 | } | 733 | } |
| 734 | lane_->waiting_on = nullptr; // just in case | 734 | lane_->waiting_on = nullptr; // just in case |
| 735 | if (selfdestruct_remove(lane_)) { // check and remove (under lock!) | 735 | if (selfdestruct_remove(lane_)) { // check and remove (under lock!) |
| @@ -750,12 +750,12 @@ static void lane_main(Lane* lane_) | |||
| 750 | if (lane_) { | 750 | if (lane_) { |
| 751 | // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them | 751 | // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them |
| 752 | 752 | ||
| 753 | Lane::Status const st = (rc == LUA_OK) ? Lane::Done : kCancelError.equals(L, 1) ? Lane::Cancelled : Lane::Error; | 753 | Lane::Status const _st = (_rc == LUA_OK) ? Lane::Done : kCancelError.equals(_L, 1) ? Lane::Cancelled : Lane::Error; |
| 754 | 754 | ||
| 755 | { | 755 | { |
| 756 | // 'doneMutex' protects the -> Done|Error|Cancelled state change | 756 | // 'doneMutex' protects the -> Done|Error|Cancelled state change |
| 757 | std::lock_guard lock{ lane_->doneMutex }; | 757 | std::lock_guard lock{ lane_->doneMutex }; |
| 758 | lane_->status = st; | 758 | lane_->status = _st; |
| 759 | lane_->doneCondVar.notify_one(); // wake up master (while 'lane_->doneMutex' is on) | 759 | lane_->doneCondVar.notify_one(); // wake up master (while 'lane_->doneMutex' is on) |
| 760 | } | 760 | } |
| 761 | } | 761 | } |
| @@ -769,17 +769,17 @@ static void lane_main(Lane* lane_) | |||
| 769 | // upvalue[1]: _G.require | 769 | // upvalue[1]: _G.require |
| 770 | LUAG_FUNC(require) | 770 | LUAG_FUNC(require) |
| 771 | { | 771 | { |
| 772 | char const* name = lua_tostring(L_, 1); // L_: "name" ... | 772 | char const* _name{ lua_tostring(L_, 1) }; // L_: "name" ... |
| 773 | int const nargs{ lua_gettop(L_) }; | 773 | int const _nargs{ lua_gettop(L_) }; |
| 774 | DEBUGSPEW_CODE(Universe* U = universe_get(L_)); | 774 | DEBUGSPEW_CODE(Universe * _U{ universe_get(L_) }); |
| 775 | STACK_CHECK_START_REL(L_, 0); | 775 | STACK_CHECK_START_REL(L_, 0); |
| 776 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.require %s BEGIN\n" INDENT_END(U), name)); | 776 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.require %s BEGIN\n" INDENT_END(_U), _name)); |
| 777 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 777 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); |
| 778 | lua_pushvalue(L_, lua_upvalueindex(1)); // L_: "name" ... require | 778 | lua_pushvalue(L_, lua_upvalueindex(1)); // L_: "name" ... require |
| 779 | lua_insert(L_, 1); // L_: require "name" ... | 779 | lua_insert(L_, 1); // L_: require "name" ... |
| 780 | lua_call(L_, nargs, 1); // L_: module | 780 | lua_call(L_, _nargs, 1); // L_: module |
| 781 | populate_func_lookup_table(L_, -1, name); | 781 | populate_func_lookup_table(L_, -1, _name); |
| 782 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.require %s END\n" INDENT_END(U), name)); | 782 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.require %s END\n" INDENT_END(_U), _name)); |
| 783 | STACK_CHECK(L_, 0); | 783 | STACK_CHECK(L_, 0); |
| 784 | return 1; | 784 | return 1; |
| 785 | } | 785 | } |
| @@ -791,17 +791,17 @@ LUAG_FUNC(require) | |||
| 791 | // lanes.register( "modname", module) | 791 | // lanes.register( "modname", module) |
| 792 | LUAG_FUNC(register) | 792 | LUAG_FUNC(register) |
| 793 | { | 793 | { |
| 794 | char const* name = luaL_checkstring(L_, 1); | 794 | char const* _name{ luaL_checkstring(L_, 1) }; |
| 795 | LuaType const mod_type{ lua_type_as_enum(L_, 2) }; | 795 | LuaType const _mod_type{ lua_type_as_enum(L_, 2) }; |
| 796 | // ignore extra parameters, just in case | 796 | // ignore extra parameters, just in case |
| 797 | lua_settop(L_, 2); | 797 | lua_settop(L_, 2); |
| 798 | luaL_argcheck(L_, (mod_type == LuaType::TABLE) || (mod_type == LuaType::FUNCTION), 2, "unexpected module type"); | 798 | luaL_argcheck(L_, (_mod_type == LuaType::TABLE) || (_mod_type == LuaType::FUNCTION), 2, "unexpected module type"); |
| 799 | DEBUGSPEW_CODE(Universe* U = universe_get(L_)); | 799 | DEBUGSPEW_CODE(Universe* U = universe_get(L_)); |
| 800 | STACK_CHECK_START_REL(L_, 0); // "name" mod_table | 800 | STACK_CHECK_START_REL(L_, 0); // "name" mod_table |
| 801 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END(U), name)); | 801 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END(U), _name)); |
| 802 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 802 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
| 803 | populate_func_lookup_table(L_, -1, name); | 803 | populate_func_lookup_table(L_, -1, _name); |
| 804 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s END\n" INDENT_END(U), name)); | 804 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lanes.register %s END\n" INDENT_END(U), _name)); |
| 805 | STACK_CHECK(L_, 0); | 805 | STACK_CHECK(L_, 0); |
| 806 | return 0; | 806 | return 0; |
| 807 | } | 807 | } |
| @@ -827,37 +827,37 @@ static constexpr UniqueKey kLaneGC{ 0x5D6122141727F960ull }; | |||
| 827 | LUAG_FUNC(lane_new) | 827 | LUAG_FUNC(lane_new) |
| 828 | { | 828 | { |
| 829 | // first 8 args: func libs priority globals package required gc_cb name | 829 | // first 8 args: func libs priority globals package required gc_cb name |
| 830 | char const* const libs_str{ lua_tostring(L_, 2) }; | 830 | char const* const _libs_str{ lua_tostring(L_, 2) }; |
| 831 | bool const have_priority{ !lua_isnoneornil(L_, 3) }; | 831 | bool const _have_priority{ !lua_isnoneornil(L_, 3) }; |
| 832 | int const priority{ have_priority ? static_cast<int>(lua_tointeger(L_, 3)) : kThreadPrioDefault }; | 832 | int const _priority{ _have_priority ? static_cast<int>(lua_tointeger(L_, 3)) : kThreadPrioDefault }; |
| 833 | int const globals_idx{ lua_isnoneornil(L_, 4) ? 0 : 4 }; | 833 | int const _globals_idx{ lua_isnoneornil(L_, 4) ? 0 : 4 }; |
| 834 | int const package_idx{ lua_isnoneornil(L_, 5) ? 0 : 5 }; | 834 | int const _package_idx{ lua_isnoneornil(L_, 5) ? 0 : 5 }; |
| 835 | int const required_idx{ lua_isnoneornil(L_, 6) ? 0 : 6 }; | 835 | int const _required_idx{ lua_isnoneornil(L_, 6) ? 0 : 6 }; |
| 836 | int const gc_cb_idx{ lua_isnoneornil(L_, 7) ? 0 : 7 }; | 836 | int const _gc_cb_idx{ lua_isnoneornil(L_, 7) ? 0 : 7 }; |
| 837 | int const name_idx{ lua_isnoneornil(L_, 8) ? 0 : 8 }; | 837 | int const _name_idx{ lua_isnoneornil(L_, 8) ? 0 : 8 }; |
| 838 | 838 | ||
| 839 | static constexpr int kFixedArgsIdx{ 8 }; | 839 | static constexpr int kFixedArgsIdx{ 8 }; |
| 840 | int const nargs{ lua_gettop(L_) - kFixedArgsIdx }; | 840 | int const _nargs{ lua_gettop(L_) - kFixedArgsIdx }; |
| 841 | Universe* const U{ universe_get(L_) }; | 841 | Universe* const _U{ universe_get(L_) }; |
| 842 | LUA_ASSERT(L_, nargs >= 0); | 842 | LUA_ASSERT(L_, _nargs >= 0); |
| 843 | 843 | ||
| 844 | // public Lanes API accepts a generic range -3/+3 | 844 | // public Lanes API accepts a generic range -3/+3 |
| 845 | // that will be remapped into the platform-specific scheduler priority scheme | 845 | // that will be remapped into the platform-specific scheduler priority scheme |
| 846 | // On some platforms, -3 is equivalent to -2 and +3 to +2 | 846 | // On some platforms, -3 is equivalent to -2 and +3 to +2 |
| 847 | if (have_priority && (priority < kThreadPrioMin || priority > kThreadPrioMax)) { | 847 | if (_have_priority && (_priority < kThreadPrioMin || _priority > kThreadPrioMax)) { |
| 848 | raise_luaL_error(L_, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, priority); | 848 | raise_luaL_error(L_, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, _priority); |
| 849 | } | 849 | } |
| 850 | 850 | ||
| 851 | /* --- Create and prepare the sub state --- */ | 851 | /* --- Create and prepare the sub state --- */ |
| 852 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: setup\n" INDENT_END(U))); | 852 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: setup\n" INDENT_END(_U))); |
| 853 | 853 | ||
| 854 | // populate with selected libraries at the same time. | 854 | // populate with selected libraries at the same time. |
| 855 | lua_State* const L2{ luaG_newstate(U, SourceState{ L_ }, libs_str) }; // L_: [8 args] ... L2: | 855 | lua_State* const _L2{ luaG_newstate(_U, SourceState{ L_ }, _libs_str) }; // L_: [8 args] ... L2: |
| 856 | STACK_CHECK_START_REL(L2, 0); | 856 | STACK_CHECK_START_REL(_L2, 0); |
| 857 | 857 | ||
| 858 | // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) | 858 | // 'lane' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) |
| 859 | Lane* const lane{ new (U) Lane{ U, L2 } }; | 859 | Lane* const _lane{ new (_U) Lane{ _U, _L2 } }; |
| 860 | if (lane == nullptr) { | 860 | if (_lane == nullptr) { |
| 861 | raise_luaL_error(L_, "could not create lane: out of memory"); | 861 | raise_luaL_error(L_, "could not create lane: out of memory"); |
| 862 | } | 862 | } |
| 863 | 863 | ||
| @@ -959,135 +959,135 @@ LUAG_FUNC(lane_new) | |||
| 959 | m_lane->ready.count_down(); | 959 | m_lane->ready.count_down(); |
| 960 | m_lane = nullptr; | 960 | m_lane = nullptr; |
| 961 | } | 961 | } |
| 962 | } onExit{ L_, lane, gc_cb_idx, name_idx DEBUGSPEW_COMMA_PARAM(U) }; | 962 | } onExit{ L_, _lane, _gc_cb_idx, _name_idx DEBUGSPEW_COMMA_PARAM(_U) }; |
| 963 | // launch the thread early, it will sync with a std::latch to parallelize OS thread warmup and L2 preparation | 963 | // launch the thread early, it will sync with a std::latch to parallelize OS thread warmup and L2 preparation |
| 964 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: launching thread\n" INDENT_END(U))); | 964 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: launching thread\n" INDENT_END(_U))); |
| 965 | lane->startThread(priority); | 965 | _lane->startThread(_priority); |
| 966 | 966 | ||
| 967 | STACK_GROW(L2, nargs + 3); | 967 | STACK_GROW(_L2, _nargs + 3); |
| 968 | STACK_GROW(L_, 3); | 968 | STACK_GROW(L_, 3); |
| 969 | STACK_CHECK_START_REL(L_, 0); | 969 | STACK_CHECK_START_REL(L_, 0); |
| 970 | 970 | ||
| 971 | // package | 971 | // package |
| 972 | if (package_idx != 0) { | 972 | if (_package_idx != 0) { |
| 973 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: update 'package'\n" INDENT_END(U))); | 973 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: update 'package'\n" INDENT_END(_U))); |
| 974 | // when copying with mode LookupMode::LaneBody, should raise an error in case of problem, not leave it one the stack | 974 | // when copying with mode LookupMode::LaneBody, should raise an error in case of problem, not leave it one the stack |
| 975 | InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, SourceIndex{ package_idx }, {}, {}, {} }; | 975 | InterCopyContext c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, SourceIndex{ _package_idx }, {}, {}, {} }; |
| 976 | [[maybe_unused]] InterCopyResult const ret{ c.inter_copy_package() }; | 976 | [[maybe_unused]] InterCopyResult const ret{ c.inter_copy_package() }; |
| 977 | LUA_ASSERT(L_, ret == InterCopyResult::Success); // either all went well, or we should not even get here | 977 | LUA_ASSERT(L_, ret == InterCopyResult::Success); // either all went well, or we should not even get here |
| 978 | } | 978 | } |
| 979 | 979 | ||
| 980 | // modules to require in the target lane *before* the function is transfered! | 980 | // modules to require in the target lane *before* the function is transfered! |
| 981 | if (required_idx != 0) { | 981 | if (_required_idx != 0) { |
| 982 | int nbRequired = 1; | 982 | int _nbRequired{ 1 }; |
| 983 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: require 'required' list\n" INDENT_END(U))); | 983 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: require 'required' list\n" INDENT_END(_U))); |
| 984 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 984 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ _U }); |
| 985 | // should not happen, was checked in lanes.lua before calling lane_new() | 985 | // should not happen, was checked in lanes.lua before calling lane_new() |
| 986 | if (lua_type(L_, required_idx) != LUA_TTABLE) { | 986 | if (lua_type(L_, _required_idx) != LUA_TTABLE) { |
| 987 | raise_luaL_error(L_, "expected required module list as a table, got %s", luaL_typename(L_, required_idx)); | 987 | raise_luaL_error(L_, "expected required module list as a table, got %s", luaL_typename(L_, _required_idx)); |
| 988 | } | 988 | } |
| 989 | 989 | ||
| 990 | lua_pushnil(L_); // L_: [8 args] args... nil L2: | 990 | lua_pushnil(L_); // L_: [8 args] args... nil L2: |
| 991 | while (lua_next(L_, required_idx) != 0) { // L_: [8 args] args... n "modname" L2: | 991 | while (lua_next(L_, _required_idx) != 0) { // L_: [8 args] args... n "modname" L2: |
| 992 | if (lua_type(L_, -1) != LUA_TSTRING || lua_type(L_, -2) != LUA_TNUMBER || lua_tonumber(L_, -2) != nbRequired) { | 992 | if (lua_type(L_, -1) != LUA_TSTRING || lua_type(L_, -2) != LUA_TNUMBER || lua_tonumber(L_, -2) != _nbRequired) { |
| 993 | raise_luaL_error(L_, "required module list should be a list of strings"); | 993 | raise_luaL_error(L_, "required module list should be a list of strings"); |
| 994 | } else { | 994 | } else { |
| 995 | // require the module in the target state, and populate the lookup table there too | 995 | // require the module in the target state, and populate the lookup table there too |
| 996 | size_t len; | 996 | size_t len; |
| 997 | char const* name = lua_tolstring(L_, -1, &len); | 997 | char const* name = lua_tolstring(L_, -1, &len); |
| 998 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: require '%s'\n" INDENT_END(U), name)); | 998 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: require '%s'\n" INDENT_END(_U), name)); |
| 999 | 999 | ||
| 1000 | // require the module in the target lane | 1000 | // require the module in the target lane |
| 1001 | lua_getglobal(L2, "require"); // L_: [8 args] args... n "modname" L2: require()? | 1001 | lua_getglobal(_L2, "require"); // L_: [8 args] args... n "modname" L2: require()? |
| 1002 | if (lua_isnil(L2, -1)) { | 1002 | if (lua_isnil(_L2, -1)) { |
| 1003 | lua_pop(L2, 1); // L_: [8 args] args... n "modname" L2: | 1003 | lua_pop(_L2, 1); // L_: [8 args] args... n "modname" L2: |
| 1004 | raise_luaL_error(L_, "cannot pre-require modules without loading 'package' library first"); | 1004 | raise_luaL_error(L_, "cannot pre-require modules without loading 'package' library first"); |
| 1005 | } else { | 1005 | } else { |
| 1006 | lua_pushlstring(L2, name, len); // L_: [8 args] args... n "modname" L2: require() name | 1006 | lua_pushlstring(_L2, name, len); // L_: [8 args] args... n "modname" L2: require() name |
| 1007 | if (lua_pcall(L2, 1, 1, 0) != LUA_OK) { // L_: [8 args] args... n "modname" L2: ret/errcode | 1007 | if (lua_pcall(_L2, 1, 1, 0) != LUA_OK) { // L_: [8 args] args... n "modname" L2: ret/errcode |
| 1008 | // propagate error to main state if any | 1008 | // propagate error to main state if any |
| 1009 | InterCopyContext c{ U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} }; | 1009 | InterCopyContext _c{ _U, DestState{ L_ }, SourceState{ _L2 }, {}, {}, {}, {}, {} }; |
| 1010 | std::ignore = c.inter_move(1); // L_: [8 args] args... n "modname" error L2: | 1010 | std::ignore = _c.inter_move(1); // L_: [8 args] args... n "modname" error L2: |
| 1011 | raise_lua_error(L_); | 1011 | raise_lua_error(L_); |
| 1012 | } | 1012 | } |
| 1013 | // here the module was successfully required // L_: [8 args] args... n "modname" L2: ret | 1013 | // here the module was successfully required // L_: [8 args] args... n "modname" L2: ret |
| 1014 | // after requiring the module, register the functions it exported in our name<->function database | 1014 | // after requiring the module, register the functions it exported in our name<->function database |
| 1015 | populate_func_lookup_table(L2, -1, name); | 1015 | populate_func_lookup_table(_L2, -1, name); |
| 1016 | lua_pop(L2, 1); // L_: [8 args] args... n "modname" L2: | 1016 | lua_pop(_L2, 1); // L_: [8 args] args... n "modname" L2: |
| 1017 | } | 1017 | } |
| 1018 | } | 1018 | } |
| 1019 | lua_pop(L_, 1); // L_: func libs priority globals package required gc_cb [... args ...] n | 1019 | lua_pop(L_, 1); // L_: func libs priority globals package required gc_cb [... args ...] n |
| 1020 | ++nbRequired; | 1020 | ++_nbRequired; |
| 1021 | } // L_: [8 args] args... | 1021 | } // L_: [8 args] args... |
| 1022 | } | 1022 | } |
| 1023 | STACK_CHECK(L_, 0); | 1023 | STACK_CHECK(L_, 0); |
| 1024 | STACK_CHECK(L2, 0); // L_: [8 args] args... L2: | 1024 | STACK_CHECK(_L2, 0); // L_: [8 args] args... L2: |
| 1025 | 1025 | ||
| 1026 | // Appending the specified globals to the global environment | 1026 | // Appending the specified globals to the global environment |
| 1027 | // *after* stdlibs have been loaded and modules required, in case we transfer references to native functions they exposed... | 1027 | // *after* stdlibs have been loaded and modules required, in case we transfer references to native functions they exposed... |
| 1028 | // | 1028 | // |
| 1029 | if (globals_idx != 0) { | 1029 | if (_globals_idx != 0) { |
| 1030 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer globals\n" INDENT_END(U))); | 1030 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer globals\n" INDENT_END(_U))); |
| 1031 | if (!lua_istable(L_, globals_idx)) { | 1031 | if (!lua_istable(L_, _globals_idx)) { |
| 1032 | raise_luaL_error(L_, "Expected table, got %s", luaL_typename(L_, globals_idx)); | 1032 | raise_luaL_error(L_, "Expected table, got %s", luaL_typename(L_, _globals_idx)); |
| 1033 | } | 1033 | } |
| 1034 | 1034 | ||
| 1035 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 1035 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); |
| 1036 | lua_pushnil(L_); // L_: [8 args] args... nil L2: | 1036 | lua_pushnil(L_); // L_: [8 args] args... nil L2: |
| 1037 | // Lua 5.2 wants us to push the globals table on the stack | 1037 | // Lua 5.2 wants us to push the globals table on the stack |
| 1038 | InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; | 1038 | InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; |
| 1039 | lua_pushglobaltable(L2); // L_: [8 args] args... nil L2: _G | 1039 | lua_pushglobaltable(_L2); // L_: [8 args] args... nil L2: _G |
| 1040 | while (lua_next(L_, globals_idx)) { // L_: [8 args] args... k v L2: _G | 1040 | while (lua_next(L_, _globals_idx)) { // L_: [8 args] args... k v L2: _G |
| 1041 | std::ignore = c.inter_copy(2); // L_: [8 args] args... k v L2: _G k v | 1041 | std::ignore = _c.inter_copy(2); // L_: [8 args] args... k v L2: _G k v |
| 1042 | // assign it in L2's globals table | 1042 | // assign it in L2's globals table |
| 1043 | lua_rawset(L2, -3); // L_: [8 args] args... k v L2: _G | 1043 | lua_rawset(_L2, -3); // L_: [8 args] args... k v L2: _G |
| 1044 | lua_pop(L_, 1); // L_: [8 args] args... k | 1044 | lua_pop(L_, 1); // L_: [8 args] args... k |
| 1045 | } // L_: [8 args] args... | 1045 | } // L_: [8 args] args... |
| 1046 | lua_pop(L2, 1); // L_: [8 args] args... L2: | 1046 | lua_pop(_L2, 1); // L_: [8 args] args... L2: |
| 1047 | } | 1047 | } |
| 1048 | STACK_CHECK(L_, 0); | 1048 | STACK_CHECK(L_, 0); |
| 1049 | STACK_CHECK(L2, 0); | 1049 | STACK_CHECK(_L2, 0); |
| 1050 | 1050 | ||
| 1051 | // Lane main function | 1051 | // Lane main function |
| 1052 | LuaType const func_type{ lua_type_as_enum(L_, 1) }; | 1052 | LuaType const _func_type{ lua_type_as_enum(L_, 1) }; |
| 1053 | if (func_type == LuaType::FUNCTION) { | 1053 | if (_func_type == LuaType::FUNCTION) { |
| 1054 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END(U))); | 1054 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer lane body\n" INDENT_END(_U))); |
| 1055 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 1055 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); |
| 1056 | lua_pushvalue(L_, 1); // L_: [8 args] args... func L2: | 1056 | lua_pushvalue(L_, 1); // L_: [8 args] args... func L2: |
| 1057 | InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; | 1057 | InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; |
| 1058 | InterCopyResult const res{ c.inter_move(1) }; // L_: [8 args] args... L2: func | 1058 | InterCopyResult const _res{ _c.inter_move(1) }; // L_: [8 args] args... L2: func |
| 1059 | if (res != InterCopyResult::Success) { | 1059 | if (_res != InterCopyResult::Success) { |
| 1060 | raise_luaL_error(L_, "tried to copy unsupported types"); | 1060 | raise_luaL_error(L_, "tried to copy unsupported types"); |
| 1061 | } | 1061 | } |
| 1062 | } else if (func_type == LuaType::STRING) { | 1062 | } else if (_func_type == LuaType::STRING) { |
| 1063 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: compile lane body\n" INDENT_END(U))); | 1063 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: compile lane body\n" INDENT_END(_U))); |
| 1064 | // compile the string | 1064 | // compile the string |
| 1065 | if (luaL_loadstring(L2, lua_tostring(L_, 1)) != 0) { // L_: [8 args] args... L2: func | 1065 | if (luaL_loadstring(_L2, lua_tostring(L_, 1)) != 0) { // L_: [8 args] args... L2: func |
| 1066 | raise_luaL_error(L_, "error when parsing lane function code"); | 1066 | raise_luaL_error(L_, "error when parsing lane function code"); |
| 1067 | } | 1067 | } |
| 1068 | } else { | 1068 | } else { |
| 1069 | raise_luaL_error(L_, "Expected function, got %s", lua_typename(L_, func_type)); | 1069 | raise_luaL_error(L_, "Expected function, got %s", lua_typename(L_, _func_type)); |
| 1070 | } | 1070 | } |
| 1071 | STACK_CHECK(L_, 0); | 1071 | STACK_CHECK(L_, 0); |
| 1072 | STACK_CHECK(L2, 1); | 1072 | STACK_CHECK(_L2, 1); |
| 1073 | LUA_ASSERT(L_, lua_isfunction(L2, 1)); | 1073 | LUA_ASSERT(L_, lua_isfunction(_L2, 1)); |
| 1074 | 1074 | ||
| 1075 | // revive arguments | 1075 | // revive arguments |
| 1076 | if (nargs > 0) { | 1076 | if (_nargs > 0) { |
| 1077 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END(U))); | 1077 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: transfer lane arguments\n" INDENT_END(_U))); |
| 1078 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 1078 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); |
| 1079 | InterCopyContext c{ U, DestState{ L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; | 1079 | InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; |
| 1080 | InterCopyResult const res{ c.inter_move(nargs) }; // L_: [8 args] L2: func args... | 1080 | InterCopyResult const res{ _c.inter_move(_nargs) }; // L_: [8 args] L2: func args... |
| 1081 | if (res != InterCopyResult::Success) { | 1081 | if (res != InterCopyResult::Success) { |
| 1082 | raise_luaL_error(L_, "tried to copy unsupported types"); | 1082 | raise_luaL_error(L_, "tried to copy unsupported types"); |
| 1083 | } | 1083 | } |
| 1084 | } | 1084 | } |
| 1085 | STACK_CHECK(L_, -nargs); | 1085 | STACK_CHECK(L_, -_nargs); |
| 1086 | LUA_ASSERT(L_, lua_gettop(L_) == kFixedArgsIdx); | 1086 | LUA_ASSERT(L_, lua_gettop(L_) == kFixedArgsIdx); |
| 1087 | 1087 | ||
| 1088 | // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). | 1088 | // Store 'lane' in the lane's registry, for 'cancel_test()' (we do cancel tests at pending send/receive). |
| 1089 | kLanePointerRegKey.setValue(L2, [lane](lua_State* L_) { lua_pushlightuserdata(L_, lane); }); // L_: [8 args] L2: func args... | 1089 | kLanePointerRegKey.setValue(_L2, [lane = _lane](lua_State* L_) { lua_pushlightuserdata(L_, lane); });// L_: [8 args] L2: func args... |
| 1090 | STACK_CHECK(L2, 1 + nargs); | 1090 | STACK_CHECK(_L2, 1 + _nargs); |
| 1091 | 1091 | ||
| 1092 | STACK_CHECK_RESET_REL(L_, 0); | 1092 | STACK_CHECK_RESET_REL(L_, 0); |
| 1093 | // all went well, the lane's thread can start working | 1093 | // all went well, the lane's thread can start working |
| @@ -1112,8 +1112,8 @@ LUAG_FUNC(lane_new) | |||
| 1112 | // | 1112 | // |
| 1113 | [[nodiscard]] static int lane_gc(lua_State* L_) | 1113 | [[nodiscard]] static int lane_gc(lua_State* L_) |
| 1114 | { | 1114 | { |
| 1115 | bool have_gc_cb{ false }; | 1115 | bool _have_gc_cb{ false }; |
| 1116 | Lane* const lane{ ToLane(L_, 1) }; // L_: ud | 1116 | Lane* const _lane{ ToLane(L_, 1) }; // L_: ud |
| 1117 | 1117 | ||
| 1118 | // if there a gc callback? | 1118 | // if there a gc callback? |
| 1119 | lua_getiuservalue(L_, 1, 1); // L_: ud uservalue | 1119 | lua_getiuservalue(L_, 1, 1); // L_: ud uservalue |
| @@ -1121,35 +1121,35 @@ LUAG_FUNC(lane_new) | |||
| 1121 | lua_rawget(L_, -2); // L_: ud uservalue gc_cb|nil | 1121 | lua_rawget(L_, -2); // L_: ud uservalue gc_cb|nil |
| 1122 | if (!lua_isnil(L_, -1)) { | 1122 | if (!lua_isnil(L_, -1)) { |
| 1123 | lua_remove(L_, -2); // L_: ud gc_cb|nil | 1123 | lua_remove(L_, -2); // L_: ud gc_cb|nil |
| 1124 | lua_pushstring(L_, lane->debugName); // L_: ud gc_cb name | 1124 | lua_pushstring(L_, _lane->debugName); // L_: ud gc_cb name |
| 1125 | have_gc_cb = true; | 1125 | _have_gc_cb = true; |
| 1126 | } else { | 1126 | } else { |
| 1127 | lua_pop(L_, 2); // L_: ud | 1127 | lua_pop(L_, 2); // L_: ud |
| 1128 | } | 1128 | } |
| 1129 | 1129 | ||
| 1130 | // We can read 'lane->status' without locks, but not wait for it | 1130 | // We can read 'lane->status' without locks, but not wait for it |
| 1131 | if (lane->status < Lane::Done) { | 1131 | if (_lane->status < Lane::Done) { |
| 1132 | // still running: will have to be cleaned up later | 1132 | // still running: will have to be cleaned up later |
| 1133 | selfdestruct_add(lane); | 1133 | selfdestruct_add(_lane); |
| 1134 | assert(lane->selfdestruct_next); | 1134 | assert(_lane->selfdestruct_next); |
| 1135 | if (have_gc_cb) { | 1135 | if (_have_gc_cb) { |
| 1136 | lua_pushliteral(L_, "selfdestruct"); // L_: ud gc_cb name status | 1136 | lua_pushliteral(L_, "selfdestruct"); // L_: ud gc_cb name status |
| 1137 | lua_call(L_, 2, 0); // L_: ud | 1137 | lua_call(L_, 2, 0); // L_: ud |
| 1138 | } | 1138 | } |
| 1139 | return 0; | 1139 | return 0; |
| 1140 | } else if (lane->L) { | 1140 | } else if (_lane->L) { |
| 1141 | // no longer accessing the Lua VM: we can close right now | 1141 | // no longer accessing the Lua VM: we can close right now |
| 1142 | lua_close(lane->L); | 1142 | lua_close(_lane->L); |
| 1143 | lane->L = nullptr; | 1143 | _lane->L = nullptr; |
| 1144 | // just in case, but s will be freed soon so... | 1144 | // just in case, but s will be freed soon so... |
| 1145 | lane->debugName = "<gc>"; | 1145 | _lane->debugName = "<gc>"; |
| 1146 | } | 1146 | } |
| 1147 | 1147 | ||
| 1148 | // Clean up after a (finished) thread | 1148 | // Clean up after a (finished) thread |
| 1149 | delete lane; | 1149 | delete _lane; |
| 1150 | 1150 | ||
| 1151 | // do this after lane cleanup in case the callback triggers an error | 1151 | // do this after lane cleanup in case the callback triggers an error |
| 1152 | if (have_gc_cb) { | 1152 | if (_have_gc_cb) { |
| 1153 | lua_pushliteral(L_, "closed"); // L_: ud gc_cb name status | 1153 | lua_pushliteral(L_, "closed"); // L_: ud gc_cb name status |
| 1154 | lua_call(L_, 2, 0); // L_: ud | 1154 | lua_call(L_, 2, 0); // L_: ud |
| 1155 | } | 1155 | } |
| @@ -1170,7 +1170,7 @@ LUAG_FUNC(lane_new) | |||
| 1170 | // | 1170 | // |
| 1171 | [[nodiscard]] static char const* thread_status_string(Lane::Status status_) | 1171 | [[nodiscard]] static char const* thread_status_string(Lane::Status status_) |
| 1172 | { | 1172 | { |
| 1173 | char const* const str{ | 1173 | char const* const _str{ |
| 1174 | (status_ == Lane::Pending) ? "pending" : | 1174 | (status_ == Lane::Pending) ? "pending" : |
| 1175 | (status_ == Lane::Running) ? "running" : // like in 'co.status()' | 1175 | (status_ == Lane::Running) ? "running" : // like in 'co.status()' |
| 1176 | (status_ == Lane::Waiting) ? "waiting" : | 1176 | (status_ == Lane::Waiting) ? "waiting" : |
| @@ -1179,17 +1179,17 @@ LUAG_FUNC(lane_new) | |||
| 1179 | (status_ == Lane::Cancelled) ? "cancelled" : | 1179 | (status_ == Lane::Cancelled) ? "cancelled" : |
| 1180 | nullptr | 1180 | nullptr |
| 1181 | }; | 1181 | }; |
| 1182 | return str; | 1182 | return _str; |
| 1183 | } | 1183 | } |
| 1184 | 1184 | ||
| 1185 | // ################################################################################################# | 1185 | // ################################################################################################# |
| 1186 | 1186 | ||
| 1187 | void Lane::pushThreadStatus(lua_State* L_) | 1187 | void Lane::pushThreadStatus(lua_State* L_) |
| 1188 | { | 1188 | { |
| 1189 | char const* const str{ thread_status_string(status) }; | 1189 | char const* const _str{ thread_status_string(status) }; |
| 1190 | LUA_ASSERT(L_, str); | 1190 | LUA_ASSERT(L_, _str); |
| 1191 | 1191 | ||
| 1192 | lua_pushstring(L_, str); | 1192 | lua_pushstring(L_, _str); |
| 1193 | } | 1193 | } |
| 1194 | 1194 | ||
| 1195 | // ################################################################################################# | 1195 | // ################################################################################################# |
| @@ -1204,14 +1204,14 @@ void Lane::pushThreadStatus(lua_State* L_) | |||
| 1204 | // | 1204 | // |
| 1205 | LUAG_FUNC(thread_join) | 1205 | LUAG_FUNC(thread_join) |
| 1206 | { | 1206 | { |
| 1207 | Lane* const lane{ ToLane(L_, 1) }; | 1207 | Lane* const _lane{ ToLane(L_, 1) }; |
| 1208 | lua_State* const L2{ lane->L }; | 1208 | lua_State* const _L2{ _lane->L }; |
| 1209 | 1209 | ||
| 1210 | std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; | 1210 | std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; |
| 1211 | if (lua_type(L_, 2) == LUA_TNUMBER) { // we don't want to use lua_isnumber() because of autocoercion | 1211 | if (lua_type(L_, 2) == LUA_TNUMBER) { // we don't want to use lua_isnumber() because of autocoercion |
| 1212 | lua_Duration const duration{ lua_tonumber(L_, 2) }; | 1212 | lua_Duration const duration{ lua_tonumber(L_, 2) }; |
| 1213 | if (duration.count() >= 0.0) { | 1213 | if (duration.count() >= 0.0) { |
| 1214 | until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration); | 1214 | _until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration); |
| 1215 | } else { | 1215 | } else { |
| 1216 | raise_luaL_argerror(L_, 2, "duration cannot be < 0"); | 1216 | raise_luaL_argerror(L_, 2, "duration cannot be < 0"); |
| 1217 | } | 1217 | } |
| @@ -1220,9 +1220,9 @@ LUAG_FUNC(thread_join) | |||
| 1220 | raise_luaL_argerror(L_, 2, "incorrect duration type"); | 1220 | raise_luaL_argerror(L_, 2, "incorrect duration type"); |
| 1221 | } | 1221 | } |
| 1222 | 1222 | ||
| 1223 | bool const done{ !lane->thread.joinable() || lane->waitForCompletion(until) }; | 1223 | bool const done{ !_lane->thread.joinable() || _lane->waitForCompletion(_until) }; |
| 1224 | lua_settop(L_, 1); // L_: lane | 1224 | lua_settop(L_, 1); // L_: lane |
| 1225 | if (!done || !L2) { | 1225 | if (!done || !_L2) { |
| 1226 | lua_pushnil(L_); // L_: lane nil | 1226 | lua_pushnil(L_); // L_: lane nil |
| 1227 | lua_pushliteral(L_, "timeout"); // L_: lane nil "timeout" | 1227 | lua_pushliteral(L_, "timeout"); // L_: lane nil "timeout" |
| 1228 | return 2; | 1228 | return 2; |
| @@ -1231,51 +1231,51 @@ LUAG_FUNC(thread_join) | |||
| 1231 | STACK_CHECK_START_REL(L_, 0); // L_: lane | 1231 | STACK_CHECK_START_REL(L_, 0); // L_: lane |
| 1232 | // Thread is Done/Error/Cancelled; all ours now | 1232 | // Thread is Done/Error/Cancelled; all ours now |
| 1233 | 1233 | ||
| 1234 | int ret{ 0 }; | 1234 | int _ret{ 0 }; |
| 1235 | // debugName is a pointer to string possibly interned in the lane's state, that no longer exists when the state is closed | 1235 | // debugName is a pointer to string possibly interned in the lane's state, that no longer exists when the state is closed |
| 1236 | // so store it in the userdata uservalue at a key that can't possibly collide | 1236 | // so store it in the userdata uservalue at a key that can't possibly collide |
| 1237 | lane->securizeDebugName(L_); | 1237 | _lane->securizeDebugName(L_); |
| 1238 | switch (lane->status) { | 1238 | switch (_lane->status) { |
| 1239 | case Lane::Done: | 1239 | case Lane::Done: |
| 1240 | { | 1240 | { |
| 1241 | int const n{ lua_gettop(L2) }; // whole L2 stack | 1241 | int const _n{ lua_gettop(_L2) }; // whole L2 stack |
| 1242 | if ( | 1242 | if ( |
| 1243 | (n > 0) && | 1243 | (_n > 0) && |
| 1244 | (InterCopyContext{ lane->U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} }.inter_move(n) != InterCopyResult::Success) | 1244 | (InterCopyContext{ _lane->U, DestState{ L_ }, SourceState{ _L2 }, {}, {}, {}, {}, {} }.inter_move(_n) != InterCopyResult::Success) |
| 1245 | ) { // L_: lane results L2: | 1245 | ) { // L_: lane results L2: |
| 1246 | raise_luaL_error(L_, "tried to copy unsupported types"); | 1246 | raise_luaL_error(L_, "tried to copy unsupported types"); |
| 1247 | } | 1247 | } |
| 1248 | ret = n; | 1248 | _ret = _n; |
| 1249 | } | 1249 | } |
| 1250 | break; | 1250 | break; |
| 1251 | 1251 | ||
| 1252 | case Lane::Error: | 1252 | case Lane::Error: |
| 1253 | { | 1253 | { |
| 1254 | int const n{ lua_gettop(L2) }; // L_: lane L2: "err" [trace] | 1254 | int const _n{ lua_gettop(_L2) }; // L_: lane L2: "err" [trace] |
| 1255 | STACK_GROW(L_, 3); | 1255 | STACK_GROW(L_, 3); |
| 1256 | lua_pushnil(L_); // L_: lane nil | 1256 | lua_pushnil(L_); // L_: lane nil |
| 1257 | // even when ERROR_FULL_STACK, if the error is not LUA_ERRRUN, the handler wasn't called, and we only have 1 error message on the stack ... | 1257 | // even when ERROR_FULL_STACK, if the error is not LUA_ERRRUN, the handler wasn't called, and we only have 1 error message on the stack ... |
| 1258 | InterCopyContext c{ lane->U, DestState{ L_ }, SourceState{ L2 }, {}, {}, {}, {}, {} }; | 1258 | InterCopyContext _c{ _lane->U, DestState{ L_ }, SourceState{ _L2 }, {}, {}, {}, {}, {} }; |
| 1259 | if (c.inter_move(n) != InterCopyResult::Success) { // L_: lane nil "err" [trace] L2: | 1259 | if (_c.inter_move(_n) != InterCopyResult::Success) { // L_: lane nil "err" [trace] L2: |
| 1260 | raise_luaL_error(L_, "tried to copy unsupported types: %s", lua_tostring(L_, -n)); | 1260 | raise_luaL_error(L_, "tried to copy unsupported types: %s", lua_tostring(L_, -_n)); |
| 1261 | } | 1261 | } |
| 1262 | ret = 1 + n; | 1262 | _ret = 1 + _n; |
| 1263 | } | 1263 | } |
| 1264 | break; | 1264 | break; |
| 1265 | 1265 | ||
| 1266 | case Lane::Cancelled: | 1266 | case Lane::Cancelled: |
| 1267 | ret = 0; | 1267 | _ret = 0; |
| 1268 | break; | 1268 | break; |
| 1269 | 1269 | ||
| 1270 | default: | 1270 | default: |
| 1271 | DEBUGSPEW_CODE(fprintf(stderr, "Status: %d\n", lane->status)); | 1271 | DEBUGSPEW_CODE(fprintf(stderr, "Status: %d\n", _lane->status)); |
| 1272 | LUA_ASSERT(L_, false); | 1272 | LUA_ASSERT(L_, false); |
| 1273 | ret = 0; | 1273 | _ret = 0; |
| 1274 | } | 1274 | } |
| 1275 | lua_close(L2); | 1275 | lua_close(_L2); |
| 1276 | lane->L = nullptr; | 1276 | _lane->L = nullptr; |
| 1277 | STACK_CHECK(L_, ret); | 1277 | STACK_CHECK(L_, _ret); |
| 1278 | return ret; | 1278 | return _ret; |
| 1279 | } | 1279 | } |
| 1280 | 1280 | ||
| 1281 | // ################################################################################################# | 1281 | // ################################################################################################# |
| @@ -1291,7 +1291,7 @@ LUAG_FUNC(thread_index) | |||
| 1291 | { | 1291 | { |
| 1292 | static constexpr int kSelf{ 1 }; | 1292 | static constexpr int kSelf{ 1 }; |
| 1293 | static constexpr int kKey{ 2 }; | 1293 | static constexpr int kKey{ 2 }; |
| 1294 | Lane* const lane{ ToLane(L_, kSelf) }; | 1294 | Lane* const _lane{ ToLane(L_, kSelf) }; |
| 1295 | LUA_ASSERT(L_, lua_gettop(L_) == 2); | 1295 | LUA_ASSERT(L_, lua_gettop(L_) == 2); |
| 1296 | 1296 | ||
| 1297 | STACK_GROW(L_, 8); // up to 8 positions are needed in case of error propagation | 1297 | STACK_GROW(L_, 8); // up to 8 positions are needed in case of error propagation |
| @@ -1314,9 +1314,9 @@ LUAG_FUNC(thread_index) | |||
| 1314 | // check if we already fetched the values from the thread or not | 1314 | // check if we already fetched the values from the thread or not |
| 1315 | lua_pushinteger(L_, 0); | 1315 | lua_pushinteger(L_, 0); |
| 1316 | lua_rawget(L_, kUsr); | 1316 | lua_rawget(L_, kUsr); |
| 1317 | bool const fetched{ !lua_isnil(L_, -1) }; | 1317 | bool const _fetched{ !lua_isnil(L_, -1) }; |
| 1318 | lua_pop(L_, 1); // back to our 2 args + uservalue on the stack | 1318 | lua_pop(L_, 1); // back to our 2 args + uservalue on the stack |
| 1319 | if (!fetched) { | 1319 | if (!_fetched) { |
| 1320 | lua_pushinteger(L_, 0); | 1320 | lua_pushinteger(L_, 0); |
| 1321 | lua_pushboolean(L_, 1); | 1321 | lua_pushboolean(L_, 1); |
| 1322 | lua_rawset(L_, kUsr); | 1322 | lua_rawset(L_, kUsr); |
| @@ -1324,22 +1324,22 @@ LUAG_FUNC(thread_index) | |||
| 1324 | lua_pushcfunction(L_, LG_thread_join); | 1324 | lua_pushcfunction(L_, LG_thread_join); |
| 1325 | lua_pushvalue(L_, kSelf); | 1325 | lua_pushvalue(L_, kSelf); |
| 1326 | lua_call(L_, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+ | 1326 | lua_call(L_, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+ |
| 1327 | switch (lane->status) { | 1327 | switch (_lane->status) { |
| 1328 | default: | 1328 | default: |
| 1329 | // this is an internal error, we probably never get here | 1329 | // this is an internal error, we probably never get here |
| 1330 | lua_settop(L_, 0); | 1330 | lua_settop(L_, 0); |
| 1331 | lua_pushliteral(L_, "Unexpected status: "); | 1331 | lua_pushliteral(L_, "Unexpected status: "); |
| 1332 | lua_pushstring(L_, thread_status_string(lane->status)); | 1332 | lua_pushstring(L_, thread_status_string(_lane->status)); |
| 1333 | lua_concat(L_, 2); | 1333 | lua_concat(L_, 2); |
| 1334 | raise_lua_error(L_); | 1334 | raise_lua_error(L_); |
| 1335 | [[fallthrough]]; // fall through if we are killed, as we got nil, "killed" on the stack | 1335 | [[fallthrough]]; // fall through if we are killed, as we got nil, "killed" on the stack |
| 1336 | 1336 | ||
| 1337 | case Lane::Done: // got regular return values | 1337 | case Lane::Done: // got regular return values |
| 1338 | { | 1338 | { |
| 1339 | int const nvalues{ lua_gettop(L_) - 3 }; | 1339 | int const _nvalues{ lua_gettop(L_) - 3 }; |
| 1340 | for (int i = nvalues; i > 0; --i) { | 1340 | for (int _i = _nvalues; _i > 0; --_i) { |
| 1341 | // pop the last element of the stack, to store it in the uservalue at its proper index | 1341 | // pop the last element of the stack, to store it in the uservalue at its proper index |
| 1342 | lua_rawseti(L_, kUsr, i); | 1342 | lua_rawseti(L_, kUsr, _i); |
| 1343 | } | 1343 | } |
| 1344 | } | 1344 | } |
| 1345 | break; | 1345 | break; |
| @@ -1361,8 +1361,8 @@ LUAG_FUNC(thread_index) | |||
| 1361 | } | 1361 | } |
| 1362 | } | 1362 | } |
| 1363 | lua_settop(L_, 3); // L_: self KEY ENV | 1363 | lua_settop(L_, 3); // L_: self KEY ENV |
| 1364 | int const key{ static_cast<int>(lua_tointeger(L_, kKey)) }; | 1364 | int const _key{ static_cast<int>(lua_tointeger(L_, kKey)) }; |
| 1365 | if (key != -1) { | 1365 | if (_key != -1) { |
| 1366 | lua_pushnumber(L_, -1); // L_: self KEY ENV -1 | 1366 | lua_pushnumber(L_, -1); // L_: self KEY ENV -1 |
| 1367 | lua_rawget(L_, kUsr); // L_: self KEY ENV "error"|nil | 1367 | lua_rawget(L_, kUsr); // L_: self KEY ENV "error"|nil |
| 1368 | if (!lua_isnil(L_, -1)) { // L_: an error was stored | 1368 | if (!lua_isnil(L_, -1)) { // L_: an error was stored |
| @@ -1388,15 +1388,15 @@ LUAG_FUNC(thread_index) | |||
| 1388 | lua_pop(L_, 1); // L_: self KEY ENV | 1388 | lua_pop(L_, 1); // L_: self KEY ENV |
| 1389 | } | 1389 | } |
| 1390 | } | 1390 | } |
| 1391 | lua_rawgeti(L_, kUsr, key); | 1391 | lua_rawgeti(L_, kUsr, _key); |
| 1392 | } | 1392 | } |
| 1393 | return 1; | 1393 | return 1; |
| 1394 | } | 1394 | } |
| 1395 | if (lua_type(L_, kKey) == LUA_TSTRING) { | 1395 | if (lua_type(L_, kKey) == LUA_TSTRING) { |
| 1396 | char const* const keystr{ lua_tostring(L_, kKey) }; | 1396 | char const* const _keystr{ lua_tostring(L_, kKey) }; |
| 1397 | lua_settop(L_, 2); // keep only our original arguments on the stack | 1397 | lua_settop(L_, 2); // keep only our original arguments on the stack |
| 1398 | if (strcmp(keystr, "status") == 0) { | 1398 | if (strcmp(_keystr, "status") == 0) { |
| 1399 | lane->pushThreadStatus(L_); // push the string representing the status | 1399 | _lane->pushThreadStatus(L_); // push the string representing the status |
| 1400 | return 1; | 1400 | return 1; |
| 1401 | } | 1401 | } |
| 1402 | // return self.metatable[key] | 1402 | // return self.metatable[key] |
| @@ -1405,7 +1405,7 @@ LUAG_FUNC(thread_index) | |||
| 1405 | lua_rawget(L_, -2); // L_: mt value | 1405 | lua_rawget(L_, -2); // L_: mt value |
| 1406 | // only "cancel" and "join" are registered as functions, any other string will raise an error | 1406 | // only "cancel" and "join" are registered as functions, any other string will raise an error |
| 1407 | if (!lua_iscfunction(L_, -1)) { | 1407 | if (!lua_iscfunction(L_, -1)) { |
| 1408 | raise_luaL_error(L_, "can't index a lane with '%s'", keystr); | 1408 | raise_luaL_error(L_, "can't index a lane with '%s'", _keystr); |
| 1409 | } | 1409 | } |
| 1410 | return 1; | 1410 | return 1; |
| 1411 | } | 1411 | } |
| @@ -1428,27 +1428,27 @@ LUAG_FUNC(thread_index) | |||
| 1428 | // Return a list of all known lanes | 1428 | // Return a list of all known lanes |
| 1429 | LUAG_FUNC(threads) | 1429 | LUAG_FUNC(threads) |
| 1430 | { | 1430 | { |
| 1431 | int const top{ lua_gettop(L_) }; | 1431 | int const _top{ lua_gettop(L_) }; |
| 1432 | Universe* const U{ universe_get(L_) }; | 1432 | Universe* const _U{ universe_get(L_) }; |
| 1433 | 1433 | ||
| 1434 | // List _all_ still running threads | 1434 | // List _all_ still running threads |
| 1435 | std::lock_guard<std::mutex> guard{ U->trackingMutex }; | 1435 | std::lock_guard<std::mutex> _guard{ _U->trackingMutex }; |
| 1436 | if (U->trackingFirst && U->trackingFirst != TRACKING_END) { | 1436 | if (_U->trackingFirst && _U->trackingFirst != TRACKING_END) { |
| 1437 | Lane* lane{ U->trackingFirst }; | 1437 | Lane* _lane{ _U->trackingFirst }; |
| 1438 | int index{ 0 }; | 1438 | int _index{ 0 }; |
| 1439 | lua_newtable(L_); // L_: {} | 1439 | lua_newtable(L_); // L_: {} |
| 1440 | while (lane != TRACKING_END) { | 1440 | while (_lane != TRACKING_END) { |
| 1441 | // insert a { name='<name>', status='<status>' } tuple, so that several lanes with the same name can't clobber each other | 1441 | // insert a { name='<name>', status='<status>' } tuple, so that several lanes with the same name can't clobber each other |
| 1442 | lua_createtable(L_, 0, 2); // L_: {} {} | 1442 | lua_createtable(L_, 0, 2); // L_: {} {} |
| 1443 | lua_pushstring(L_, lane->debugName); // L_: {} {} "name" | 1443 | lua_pushstring(L_, _lane->debugName); // L_: {} {} "name" |
| 1444 | lua_setfield(L_, -2, "name"); // L_: {} {} | 1444 | lua_setfield(L_, -2, "name"); // L_: {} {} |
| 1445 | lane->pushThreadStatus(L_); // L_: {} {} "status" | 1445 | _lane->pushThreadStatus(L_); // L_: {} {} "status" |
| 1446 | lua_setfield(L_, -2, "status"); // L_: {} {} | 1446 | lua_setfield(L_, -2, "status"); // L_: {} {} |
| 1447 | lua_rawseti(L_, -2, ++index); // L_: {} | 1447 | lua_rawseti(L_, -2, ++_index); // L_: {} |
| 1448 | lane = lane->tracking_next; | 1448 | _lane = _lane->tracking_next; |
| 1449 | } | 1449 | } |
| 1450 | } | 1450 | } |
| 1451 | return lua_gettop(L_) - top; // L_: 0 or 1 | 1451 | return lua_gettop(L_) - _top; // L_: 0 or 1 |
| 1452 | } | 1452 | } |
| 1453 | #endif // HAVE_LANE_TRACKING() | 1453 | #endif // HAVE_LANE_TRACKING() |
| 1454 | 1454 | ||
| @@ -1464,8 +1464,8 @@ LUAG_FUNC(threads) | |||
| 1464 | */ | 1464 | */ |
| 1465 | LUAG_FUNC(now_secs) | 1465 | LUAG_FUNC(now_secs) |
| 1466 | { | 1466 | { |
| 1467 | auto const now{ std::chrono::system_clock::now() }; | 1467 | auto const _now{ std::chrono::system_clock::now() }; |
| 1468 | lua_Duration duration{ now.time_since_epoch() }; | 1468 | lua_Duration duration{ _now.time_since_epoch() }; |
| 1469 | 1469 | ||
| 1470 | lua_pushnumber(L_, duration.count()); | 1470 | lua_pushnumber(L_, duration.count()); |
| 1471 | return 1; | 1471 | return 1; |
| @@ -1487,38 +1487,38 @@ LUAG_FUNC(wakeup_conv) | |||
| 1487 | // .isdst (daylight saving on/off) | 1487 | // .isdst (daylight saving on/off) |
| 1488 | 1488 | ||
| 1489 | STACK_CHECK_START_REL(L_, 0); | 1489 | STACK_CHECK_START_REL(L_, 0); |
| 1490 | auto readInteger = [L = L_](char const* name_) { | 1490 | auto _readInteger = [L = L_](char const* name_) { |
| 1491 | lua_getfield(L, 1, name_); | 1491 | lua_getfield(L, 1, name_); |
| 1492 | lua_Integer const val{ lua_tointeger(L, -1) }; | 1492 | lua_Integer const val{ lua_tointeger(L, -1) }; |
| 1493 | lua_pop(L, 1); | 1493 | lua_pop(L, 1); |
| 1494 | return static_cast<int>(val); | 1494 | return static_cast<int>(val); |
| 1495 | }; | 1495 | }; |
| 1496 | int const year{ readInteger("year") }; | 1496 | int const _year{ _readInteger("year") }; |
| 1497 | int const month{ readInteger("month") }; | 1497 | int const _month{ _readInteger("month") }; |
| 1498 | int const day{ readInteger("day") }; | 1498 | int const _day{ _readInteger("day") }; |
| 1499 | int const hour{ readInteger("hour") }; | 1499 | int const _hour{ _readInteger("hour") }; |
| 1500 | int const min{ readInteger("min") }; | 1500 | int const _min{ _readInteger("min") }; |
| 1501 | int const sec{ readInteger("sec") }; | 1501 | int const _sec{ _readInteger("sec") }; |
| 1502 | STACK_CHECK(L_, 0); | 1502 | STACK_CHECK(L_, 0); |
| 1503 | 1503 | ||
| 1504 | // If Lua table has '.isdst' we trust that. If it does not, we'll let | 1504 | // If Lua table has '.isdst' we trust that. If it does not, we'll let |
| 1505 | // 'mktime' decide on whether the time is within DST or not (value -1). | 1505 | // 'mktime' decide on whether the time is within DST or not (value -1). |
| 1506 | // | 1506 | // |
| 1507 | lua_getfield(L_, 1, "isdst"); | 1507 | lua_getfield(L_, 1, "isdst"); |
| 1508 | int const isdst{ lua_isboolean(L_, -1) ? lua_toboolean(L_, -1) : -1 }; | 1508 | int const _isdst{ lua_isboolean(L_, -1) ? lua_toboolean(L_, -1) : -1 }; |
| 1509 | lua_pop(L_, 1); | 1509 | lua_pop(L_, 1); |
| 1510 | STACK_CHECK(L_, 0); | 1510 | STACK_CHECK(L_, 0); |
| 1511 | 1511 | ||
| 1512 | std::tm t{}; | 1512 | std::tm _t{}; |
| 1513 | t.tm_year = year - 1900; | 1513 | _t.tm_year = _year - 1900; |
| 1514 | t.tm_mon = month - 1; // 0..11 | 1514 | _t.tm_mon = _month - 1; // 0..11 |
| 1515 | t.tm_mday = day; // 1..31 | 1515 | _t.tm_mday = _day; // 1..31 |
| 1516 | t.tm_hour = hour; // 0..23 | 1516 | _t.tm_hour = _hour; // 0..23 |
| 1517 | t.tm_min = min; // 0..59 | 1517 | _t.tm_min = _min; // 0..59 |
| 1518 | t.tm_sec = sec; // 0..60 | 1518 | _t.tm_sec = _sec; // 0..60 |
| 1519 | t.tm_isdst = isdst; // 0/1/negative | 1519 | _t.tm_isdst = _isdst; // 0/1/negative |
| 1520 | 1520 | ||
| 1521 | lua_pushnumber(L_, static_cast<lua_Number>(std::mktime(&t))); // resolution: 1 second | 1521 | lua_pushnumber(L_, static_cast<lua_Number>(std::mktime(&_t))); // resolution: 1 second |
| 1522 | return 1; | 1522 | return 1; |
| 1523 | } | 1523 | } |
| 1524 | 1524 | ||
| @@ -1527,7 +1527,7 @@ LUAG_FUNC(wakeup_conv) | |||
| 1527 | // ################################################################################################# | 1527 | // ################################################################################################# |
| 1528 | 1528 | ||
| 1529 | // same as PUC-Lua l_alloc | 1529 | // same as PUC-Lua l_alloc |
| 1530 | extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud, [[maybe_unused]] void* ptr_, [[maybe_unused]] size_t osize_, size_t nsize_) | 1530 | extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud_, [[maybe_unused]] void* ptr_, [[maybe_unused]] size_t osize_, size_t nsize_) |
| 1531 | { | 1531 | { |
| 1532 | if (nsize_ == 0) { | 1532 | if (nsize_ == 0) { |
| 1533 | free(ptr_); | 1533 | free(ptr_); |
| @@ -1541,9 +1541,9 @@ extern "C" [[nodiscard]] static void* libc_lua_Alloc([[maybe_unused]] void* ud, | |||
| 1541 | 1541 | ||
| 1542 | [[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L_) | 1542 | [[nodiscard]] static int luaG_provide_protected_allocator(lua_State* L_) |
| 1543 | { | 1543 | { |
| 1544 | Universe* const U{ universe_get(L_) }; | 1544 | Universe* const _U{ universe_get(L_) }; |
| 1545 | // push a new full userdata on the stack, giving access to the universe's protected allocator | 1545 | // push a new full userdata on the stack, giving access to the universe's protected allocator |
| 1546 | [[maybe_unused]] AllocatorDefinition* const def{ new (L_) AllocatorDefinition{ U->protectedAllocator.makeDefinition() } }; | 1546 | [[maybe_unused]] AllocatorDefinition* const def{ new (L_) AllocatorDefinition{ _U->protectedAllocator.makeDefinition() } }; |
| 1547 | return 1; | 1547 | return 1; |
| 1548 | } | 1548 | } |
| 1549 | 1549 | ||
| @@ -1585,8 +1585,8 @@ static void initialize_allocator_function(Universe* U_, lua_State* L_) | |||
| 1585 | 1585 | ||
| 1586 | lua_getfield(L_, -1, "internal_allocator"); // L_: settings "libc"|"allocator" | 1586 | lua_getfield(L_, -1, "internal_allocator"); // L_: settings "libc"|"allocator" |
| 1587 | { | 1587 | { |
| 1588 | char const* allocator = lua_tostring(L_, -1); | 1588 | char const* const _allocator{ lua_tostring(L_, -1) }; |
| 1589 | if (strcmp(allocator, "libc") == 0) { | 1589 | if (strcmp(_allocator, "libc") == 0) { |
| 1590 | U_->internalAllocator = AllocatorDefinition{ libc_lua_Alloc, nullptr }; | 1590 | U_->internalAllocator = AllocatorDefinition{ libc_lua_Alloc, nullptr }; |
| 1591 | } else if (U_->provideAllocator == luaG_provide_protected_allocator) { | 1591 | } else if (U_->provideAllocator == luaG_provide_protected_allocator) { |
| 1592 | // user wants mutex protection on the state's allocator. Use protection for our own allocations too, just in case. | 1592 | // user wants mutex protection on the state's allocator. Use protection for our own allocations too, just in case. |
| @@ -1639,20 +1639,20 @@ LUAG_FUNC(configure) | |||
| 1639 | }); | 1639 | }); |
| 1640 | } | 1640 | } |
| 1641 | 1641 | ||
| 1642 | Universe* U = universe_get(L_); | 1642 | Universe* _U{ universe_get(L_) }; |
| 1643 | bool const from_master_state{ U == nullptr }; | 1643 | bool const _from_master_state{ _U == nullptr }; |
| 1644 | char const* name = luaL_checkstring(L_, lua_upvalueindex(1)); | 1644 | char const* const _name{ luaL_checkstring(L_, lua_upvalueindex(1)) }; |
| 1645 | LUA_ASSERT(L_, lua_type(L_, 1) == LUA_TTABLE); | 1645 | LUA_ASSERT(L_, lua_type(L_, 1) == LUA_TTABLE); |
| 1646 | 1646 | ||
| 1647 | STACK_GROW(L_, 4); | 1647 | STACK_GROW(L_, 4); |
| 1648 | STACK_CHECK_START_ABS(L_, 1); // L_: settings | 1648 | STACK_CHECK_START_ABS(L_, 1); // L_: settings |
| 1649 | 1649 | ||
| 1650 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END(U), L_)); | 1650 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END(_U), L_)); |
| 1651 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 1651 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ _U }); |
| 1652 | 1652 | ||
| 1653 | if (U == nullptr) { | 1653 | if (_U == nullptr) { |
| 1654 | U = universe_create(L_); // L_: settings universe | 1654 | _U = universe_create(L_); // L_: settings universe |
| 1655 | DEBUGSPEW_CODE(DebugSpewIndentScope scope2{ U }); | 1655 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope2{ _U }); |
| 1656 | lua_createtable(L_, 0, 1); // L_: settings universe {mt} | 1656 | lua_createtable(L_, 0, 1); // L_: settings universe {mt} |
| 1657 | lua_getfield(L_, 1, "shutdown_timeout"); // L_: settings universe {mt} shutdown_timeout | 1657 | lua_getfield(L_, 1, "shutdown_timeout"); // L_: settings universe {mt} shutdown_timeout |
| 1658 | lua_getfield(L_, 1, "shutdown_mode"); // L_: settings universe {mt} shutdown_timeout shutdown_mode | 1658 | lua_getfield(L_, 1, "shutdown_mode"); // L_: settings universe {mt} shutdown_timeout shutdown_mode |
| @@ -1661,21 +1661,21 @@ LUAG_FUNC(configure) | |||
| 1661 | lua_setmetatable(L_, -2); // L_: settings universe | 1661 | lua_setmetatable(L_, -2); // L_: settings universe |
| 1662 | lua_pop(L_, 1); // L_: settings | 1662 | lua_pop(L_, 1); // L_: settings |
| 1663 | lua_getfield(L_, 1, "verbose_errors"); // L_: settings verbose_errors | 1663 | lua_getfield(L_, 1, "verbose_errors"); // L_: settings verbose_errors |
| 1664 | U->verboseErrors = lua_toboolean(L_, -1) ? true : false; | 1664 | _U->verboseErrors = lua_toboolean(L_, -1) ? true : false; |
| 1665 | lua_pop(L_, 1); // L_: settings | 1665 | lua_pop(L_, 1); // L_: settings |
| 1666 | lua_getfield(L_, 1, "demote_full_userdata"); // L_: settings demote_full_userdata | 1666 | lua_getfield(L_, 1, "demote_full_userdata"); // L_: settings demote_full_userdata |
| 1667 | U->demoteFullUserdata = lua_toboolean(L_, -1) ? true : false; | 1667 | _U->demoteFullUserdata = lua_toboolean(L_, -1) ? true : false; |
| 1668 | lua_pop(L_, 1); // L_: settings | 1668 | lua_pop(L_, 1); // L_: settings |
| 1669 | #if HAVE_LANE_TRACKING() | 1669 | #if HAVE_LANE_TRACKING() |
| 1670 | lua_getfield(L_, 1, "track_lanes"); // L_: settings track_lanes | 1670 | lua_getfield(L_, 1, "track_lanes"); // L_: settings track_lanes |
| 1671 | U->trackingFirst = lua_toboolean(L_, -1) ? TRACKING_END : nullptr; | 1671 | _U->trackingFirst = lua_toboolean(L_, -1) ? TRACKING_END : nullptr; |
| 1672 | lua_pop(L_, 1); // L_: settings | 1672 | lua_pop(L_, 1); // L_: settings |
| 1673 | #endif // HAVE_LANE_TRACKING() | 1673 | #endif // HAVE_LANE_TRACKING() |
| 1674 | // Linked chains handling | 1674 | // Linked chains handling |
| 1675 | U->selfdestructFirst = SELFDESTRUCT_END; | 1675 | _U->selfdestructFirst = SELFDESTRUCT_END; |
| 1676 | initialize_allocator_function(U, L_); | 1676 | initialize_allocator_function(_U, L_); |
| 1677 | initializeOnStateCreate(U, L_); | 1677 | initializeOnStateCreate(_U, L_); |
| 1678 | init_keepers(U, L_); | 1678 | init_keepers(_U, L_); |
| 1679 | STACK_CHECK(L_, 1); | 1679 | STACK_CHECK(L_, 1); |
| 1680 | 1680 | ||
| 1681 | // Initialize 'timerLinda'; a common Linda object shared by all states | 1681 | // Initialize 'timerLinda'; a common Linda object shared by all states |
| @@ -1685,15 +1685,15 @@ LUAG_FUNC(configure) | |||
| 1685 | STACK_CHECK(L_, 2); | 1685 | STACK_CHECK(L_, 2); |
| 1686 | 1686 | ||
| 1687 | // Proxy userdata contents is only a 'DeepPrelude*' pointer | 1687 | // Proxy userdata contents is only a 'DeepPrelude*' pointer |
| 1688 | U->timerLinda = *lua_tofulluserdata<DeepPrelude*>(L_, -1); | 1688 | _U->timerLinda = *lua_tofulluserdata<DeepPrelude*>(L_, -1); |
| 1689 | // increment refcount so that this linda remains alive as long as the universe exists. | 1689 | // increment refcount so that this linda remains alive as long as the universe exists. |
| 1690 | U->timerLinda->refcount.fetch_add(1, std::memory_order_relaxed); | 1690 | _U->timerLinda->refcount.fetch_add(1, std::memory_order_relaxed); |
| 1691 | lua_pop(L_, 1); // L_: settings | 1691 | lua_pop(L_, 1); // L_: settings |
| 1692 | } | 1692 | } |
| 1693 | STACK_CHECK(L_, 1); | 1693 | STACK_CHECK(L_, 1); |
| 1694 | 1694 | ||
| 1695 | // Serialize calls to 'require' from now on, also in the primary state | 1695 | // Serialize calls to 'require' from now on, also in the primary state |
| 1696 | serialize_require(DEBUGSPEW_PARAM_COMMA(U) L_); | 1696 | serialize_require(DEBUGSPEW_PARAM_COMMA(_U) L_); |
| 1697 | 1697 | ||
| 1698 | // Retrieve main module interface table | 1698 | // Retrieve main module interface table |
| 1699 | lua_pushvalue(L_, lua_upvalueindex(2)); // L_: settings M | 1699 | lua_pushvalue(L_, lua_upvalueindex(2)); // L_: settings M |
| @@ -1704,7 +1704,7 @@ LUAG_FUNC(configure) | |||
| 1704 | luaG_registerlibfuncs(L_, global::sLanesFunctions); | 1704 | luaG_registerlibfuncs(L_, global::sLanesFunctions); |
| 1705 | #if HAVE_LANE_TRACKING() | 1705 | #if HAVE_LANE_TRACKING() |
| 1706 | // register core.threads() only if settings say it should be available | 1706 | // register core.threads() only if settings say it should be available |
| 1707 | if (U->trackingFirst != nullptr) { | 1707 | if (_U->trackingFirst != nullptr) { |
| 1708 | lua_pushcfunction(L_, LG_threads); // L_: settings M LG_threads() | 1708 | lua_pushcfunction(L_, LG_threads); // L_: settings M LG_threads() |
| 1709 | lua_setfield(L_, -2, "threads"); // L_: settings M | 1709 | lua_setfield(L_, -2, "threads"); // L_: settings M |
| 1710 | } | 1710 | } |
| @@ -1712,11 +1712,11 @@ LUAG_FUNC(configure) | |||
| 1712 | STACK_CHECK(L_, 2); | 1712 | STACK_CHECK(L_, 2); |
| 1713 | 1713 | ||
| 1714 | { | 1714 | { |
| 1715 | char const* errmsg{ | 1715 | char const* _errmsg{ |
| 1716 | DeepFactory::PushDeepProxy(DestState{ L_ }, U->timerLinda, 0, LookupMode::LaneBody) | 1716 | DeepFactory::PushDeepProxy(DestState{ L_ }, _U->timerLinda, 0, LookupMode::LaneBody) |
| 1717 | }; // L_: settings M timerLinda | 1717 | }; // L_: settings M timerLinda |
| 1718 | if (errmsg != nullptr) { | 1718 | if (_errmsg != nullptr) { |
| 1719 | raise_luaL_error(L_, errmsg); | 1719 | raise_luaL_error(L_, _errmsg); |
| 1720 | } | 1720 | } |
| 1721 | lua_setfield(L_, -2, "timer_gateway"); // L_: settings M | 1721 | lua_setfield(L_, -2, "timer_gateway"); // L_: settings M |
| 1722 | } | 1722 | } |
| @@ -1780,12 +1780,12 @@ LUAG_FUNC(configure) | |||
| 1780 | // register all native functions found in that module in the transferable functions database | 1780 | // register all native functions found in that module in the transferable functions database |
| 1781 | // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) | 1781 | // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) |
| 1782 | // for example in package.loaded["lanes.core"].* | 1782 | // for example in package.loaded["lanes.core"].* |
| 1783 | populate_func_lookup_table(L_, -1, name); | 1783 | populate_func_lookup_table(L_, -1, _name); |
| 1784 | STACK_CHECK(L_, 2); | 1784 | STACK_CHECK(L_, 2); |
| 1785 | 1785 | ||
| 1786 | // record all existing C/JIT-fast functions | 1786 | // record all existing C/JIT-fast functions |
| 1787 | // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack | 1787 | // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack |
| 1788 | if (from_master_state) { | 1788 | if (_from_master_state) { |
| 1789 | // don't do this when called during the initialization of a new lane, | 1789 | // don't do this when called during the initialization of a new lane, |
| 1790 | // because we will do it after on_state_create() is called, | 1790 | // because we will do it after on_state_create() is called, |
| 1791 | // and we don't want to skip _G because of caching in case globals are created then | 1791 | // and we don't want to skip _G because of caching in case globals are created then |
| @@ -1798,7 +1798,7 @@ LUAG_FUNC(configure) | |||
| 1798 | // set _R[kConfigRegKey] = settings | 1798 | // set _R[kConfigRegKey] = settings |
| 1799 | kConfigRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); | 1799 | kConfigRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); |
| 1800 | STACK_CHECK(L_, 1); | 1800 | STACK_CHECK(L_, 1); |
| 1801 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END(U), L_)); | 1801 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END(_U), L_)); |
| 1802 | // Return the settings table | 1802 | // Return the settings table |
| 1803 | return 1; | 1803 | return 1; |
| 1804 | } | 1804 | } |
| @@ -1809,9 +1809,9 @@ LUAG_FUNC(configure) | |||
| 1809 | #include <signal.h> | 1809 | #include <signal.h> |
| 1810 | #include <conio.h> | 1810 | #include <conio.h> |
| 1811 | 1811 | ||
| 1812 | void signal_handler(int signal) | 1812 | void signal_handler(int signal_) |
| 1813 | { | 1813 | { |
| 1814 | if (signal == SIGABRT) { | 1814 | if (signal_ == SIGABRT) { |
| 1815 | _cprintf("caught abnormal termination!"); | 1815 | _cprintf("caught abnormal termination!"); |
| 1816 | abort(); | 1816 | abort(); |
| 1817 | } | 1817 | } |
| @@ -1830,18 +1830,18 @@ static void EnableCrashingOnCrashes(void) | |||
| 1830 | typedef BOOL(WINAPI * tSetPolicy)(DWORD dwFlags); | 1830 | typedef BOOL(WINAPI * tSetPolicy)(DWORD dwFlags); |
| 1831 | const DWORD EXCEPTION_SWALLOWING = 0x1; | 1831 | const DWORD EXCEPTION_SWALLOWING = 0x1; |
| 1832 | 1832 | ||
| 1833 | HMODULE kernel32 = LoadLibraryA("kernel32.dll"); | 1833 | HMODULE _kernel32 = LoadLibraryA("kernel32.dll"); |
| 1834 | if (kernel32) { | 1834 | if (_kernel32) { |
| 1835 | tGetPolicy pGetPolicy = (tGetPolicy) GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy"); | 1835 | tGetPolicy pGetPolicy = (tGetPolicy) GetProcAddress(_kernel32, "GetProcessUserModeExceptionPolicy"); |
| 1836 | tSetPolicy pSetPolicy = (tSetPolicy) GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy"); | 1836 | tSetPolicy pSetPolicy = (tSetPolicy) GetProcAddress(_kernel32, "SetProcessUserModeExceptionPolicy"); |
| 1837 | if (pGetPolicy && pSetPolicy) { | 1837 | if (pGetPolicy && pSetPolicy) { |
| 1838 | DWORD dwFlags; | 1838 | DWORD _dwFlags; |
| 1839 | if (pGetPolicy(&dwFlags)) { | 1839 | if (pGetPolicy(&_dwFlags)) { |
| 1840 | // Turn off the filter | 1840 | // Turn off the filter |
| 1841 | pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING); | 1841 | pSetPolicy(_dwFlags & ~EXCEPTION_SWALLOWING); |
| 1842 | } | 1842 | } |
| 1843 | } | 1843 | } |
| 1844 | FreeLibrary(kernel32); | 1844 | FreeLibrary(_kernel32); |
| 1845 | } | 1845 | } |
| 1846 | // typedef void (* SignalHandlerPointer)( int); | 1846 | // typedef void (* SignalHandlerPointer)( int); |
| 1847 | /*SignalHandlerPointer previousHandler =*/signal(SIGABRT, signal_handler); | 1847 | /*SignalHandlerPointer previousHandler =*/signal(SIGABRT, signal_handler); |
| @@ -1902,8 +1902,8 @@ LANES_API int luaopen_lanes_core(lua_State* L_) | |||
| 1902 | 1902 | ||
| 1903 | [[nodiscard]] static int default_luaopen_lanes(lua_State* L_) | 1903 | [[nodiscard]] static int default_luaopen_lanes(lua_State* L_) |
| 1904 | { | 1904 | { |
| 1905 | int const rc{ luaL_loadfile(L_, "lanes.lua") || lua_pcall(L_, 0, 1, 0) }; | 1905 | int const _rc{ luaL_loadfile(L_, "lanes.lua") || lua_pcall(L_, 0, 1, 0) }; |
| 1906 | if (rc != LUA_OK) { | 1906 | if (_rc != LUA_OK) { |
| 1907 | raise_luaL_error(L_, "failed to initialize embedded Lanes"); | 1907 | raise_luaL_error(L_, "failed to initialize embedded Lanes"); |
| 1908 | } | 1908 | } |
| 1909 | return 1; | 1909 | return 1; |
diff --git a/src/lanesconf.h b/src/lanesconf.h index 7b4ff93..aae4f5b 100644 --- a/src/lanesconf.h +++ b/src/lanesconf.h | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | // regular class member/method: no prefix, start with a lowercase letter | 23 | // regular class member/method: no prefix, start with a lowercase letter |
| 24 | // function argument: suffix _ | 24 | // function argument: suffix _ |
| 25 | // static function variable: prefix s, followed by an uppercase letter | 25 | // static function variable: prefix s, followed by an uppercase letter |
| 26 | // function local variable: prefix l, followed by an uppercase letter | 26 | // function local variable: prefix _, followed by an uppercase letter |
| 27 | // named lambda capture: no prefix, start with a lowercase letter | 27 | // named lambda capture: no prefix, start with a lowercase letter |
| 28 | 28 | ||
| 29 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 29 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) |
diff --git a/src/linda.cpp b/src/linda.cpp index 07911b3..fedcd01 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
| @@ -59,8 +59,8 @@ Linda::Linda(Universe* U_, LindaGroup group_, char const* name_, size_t len_) | |||
| 59 | Linda::~Linda() | 59 | Linda::~Linda() |
| 60 | { | 60 | { |
| 61 | if (std::holds_alternative<AllocatedName>(nameVariant)) { | 61 | if (std::holds_alternative<AllocatedName>(nameVariant)) { |
| 62 | AllocatedName& name = std::get<AllocatedName>(nameVariant); | 62 | AllocatedName& _name = std::get<AllocatedName>(nameVariant); |
| 63 | U->internalAllocator.free(name.name, name.len); | 63 | U->internalAllocator.free(_name.name, _name.len); |
| 64 | } | 64 | } |
| 65 | } | 65 | } |
| 66 | 66 | ||
| @@ -75,13 +75,13 @@ void Linda::setName(char const* name_, size_t len_) | |||
| 75 | ++len_; // don't forget terminating 0 | 75 | ++len_; // don't forget terminating 0 |
| 76 | if (len_ < kEmbeddedNameLength) { | 76 | if (len_ < kEmbeddedNameLength) { |
| 77 | nameVariant.emplace<EmbeddedName>(); | 77 | nameVariant.emplace<EmbeddedName>(); |
| 78 | char* const name{ std::get<EmbeddedName>(nameVariant).data() }; | 78 | char* const _name{ std::get<EmbeddedName>(nameVariant).data() }; |
| 79 | memcpy(name, name_, len_); | 79 | memcpy(_name, name_, len_); |
| 80 | } else { | 80 | } else { |
| 81 | AllocatedName& name = std::get<AllocatedName>(nameVariant); | 81 | AllocatedName& _name = std::get<AllocatedName>(nameVariant); |
| 82 | name.name = static_cast<char*>(U->internalAllocator.alloc(len_)); | 82 | _name.name = static_cast<char*>(U->internalAllocator.alloc(len_)); |
| 83 | name.len = len_; | 83 | _name.len = len_; |
| 84 | memcpy(name.name, name_, len_); | 84 | memcpy(_name.name, name_, len_); |
| 85 | } | 85 | } |
| 86 | } | 86 | } |
| 87 | 87 | ||
| @@ -90,12 +90,12 @@ void Linda::setName(char const* name_, size_t len_) | |||
| 90 | char const* Linda::getName() const | 90 | char const* Linda::getName() const |
| 91 | { | 91 | { |
| 92 | if (std::holds_alternative<AllocatedName>(nameVariant)) { | 92 | if (std::holds_alternative<AllocatedName>(nameVariant)) { |
| 93 | AllocatedName const& name = std::get<AllocatedName>(nameVariant); | 93 | AllocatedName const& _name = std::get<AllocatedName>(nameVariant); |
| 94 | return name.name; | 94 | return _name.name; |
| 95 | } | 95 | } |
| 96 | if (std::holds_alternative<EmbeddedName>(nameVariant)) { | 96 | if (std::holds_alternative<EmbeddedName>(nameVariant)) { |
| 97 | char const* const name{ std::get<EmbeddedName>(nameVariant).data() }; | 97 | char const* const _name{ std::get<EmbeddedName>(nameVariant).data() }; |
| 98 | return name; | 98 | return _name; |
| 99 | } | 99 | } |
| 100 | return nullptr; | 100 | return nullptr; |
| 101 | } | 101 | } |
| @@ -105,20 +105,20 @@ char const* Linda::getName() const | |||
| 105 | template <bool OPT> | 105 | template <bool OPT> |
| 106 | [[nodiscard]] static inline Linda* ToLinda(lua_State* L_, int idx_) | 106 | [[nodiscard]] static inline Linda* ToLinda(lua_State* L_, int idx_) |
| 107 | { | 107 | { |
| 108 | Linda* const linda{ static_cast<Linda*>(LindaFactory::Instance.toDeep(L_, idx_)) }; | 108 | Linda* const _linda{ static_cast<Linda*>(LindaFactory::Instance.toDeep(L_, idx_)) }; |
| 109 | if constexpr (!OPT) { | 109 | if constexpr (!OPT) { |
| 110 | luaL_argcheck(L_, linda != nullptr, idx_, "expecting a linda object"); // doesn't return if linda is nullptr | 110 | luaL_argcheck(L_, _linda != nullptr, idx_, "expecting a linda object"); // doesn't return if linda is nullptr |
| 111 | LUA_ASSERT(L_, linda->U == universe_get(L_)); | 111 | LUA_ASSERT(L_, _linda->U == universe_get(L_)); |
| 112 | } | 112 | } |
| 113 | return linda; | 113 | return _linda; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | // ################################################################################################# | 116 | // ################################################################################################# |
| 117 | 117 | ||
| 118 | static void check_key_types(lua_State* L_, int start_, int end_) | 118 | static void check_key_types(lua_State* L_, int start_, int end_) |
| 119 | { | 119 | { |
| 120 | for (int i{ start_ }; i <= end_; ++i) { | 120 | for (int _i{ start_ }; _i <= end_; ++_i) { |
| 121 | LuaType const t{ lua_type_as_enum(L_, i) }; | 121 | LuaType const t{ lua_type_as_enum(L_, _i) }; |
| 122 | switch (t) { | 122 | switch (t) { |
| 123 | case LuaType::BOOLEAN: | 123 | case LuaType::BOOLEAN: |
| 124 | case LuaType::NUMBER: | 124 | case LuaType::NUMBER: |
| @@ -128,14 +128,14 @@ static void check_key_types(lua_State* L_, int start_, int end_) | |||
| 128 | case LuaType::LIGHTUSERDATA: | 128 | case LuaType::LIGHTUSERDATA: |
| 129 | static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; | 129 | static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; |
| 130 | for (UniqueKey const& key : kKeysToCheck) { | 130 | for (UniqueKey const& key : kKeysToCheck) { |
| 131 | if (key.equals(L_, i)) { | 131 | if (key.equals(L_, _i)) { |
| 132 | raise_luaL_error(L_, "argument #%d: can't use %s as a key", i, key.debugName); | 132 | raise_luaL_error(L_, "argument #%d: can't use %s as a key", _i, key.debugName); |
| 133 | break; | 133 | break; |
| 134 | } | 134 | } |
| 135 | } | 135 | } |
| 136 | break; | 136 | break; |
| 137 | } | 137 | } |
| 138 | raise_luaL_error(L_, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", i); | 138 | raise_luaL_error(L_, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", _i); |
| 139 | } | 139 | } |
| 140 | } | 140 | } |
| 141 | 141 | ||
| @@ -144,29 +144,29 @@ static void check_key_types(lua_State* L_, int start_, int end_) | |||
| 144 | // used to perform all linda operations that access keepers | 144 | // used to perform all linda operations that access keepers |
| 145 | int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_) | 145 | int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_) |
| 146 | { | 146 | { |
| 147 | Linda* const linda{ ToLinda<false>(L_, 1) }; | 147 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 148 | 148 | ||
| 149 | // acquire the keeper | 149 | // acquire the keeper |
| 150 | Keeper* const K{ linda->acquireKeeper() }; | 150 | Keeper* const _K{ _linda->acquireKeeper() }; |
| 151 | lua_State* const KL{ K ? K->L : nullptr }; | 151 | lua_State* const _KL{ _K ? _K->L : nullptr }; |
| 152 | if (KL == nullptr) | 152 | if (_KL == nullptr) |
| 153 | return 0; | 153 | return 0; |
| 154 | // if we didn't do anything wrong, the keeper stack should be clean | 154 | // if we didn't do anything wrong, the keeper stack should be clean |
| 155 | LUA_ASSERT(L_, lua_gettop(KL) == 0); | 155 | LUA_ASSERT(L_, lua_gettop(_KL) == 0); |
| 156 | 156 | ||
| 157 | // push the function to be called and move it before the arguments | 157 | // push the function to be called and move it before the arguments |
| 158 | lua_pushcfunction(L_, f_); | 158 | lua_pushcfunction(L_, f_); |
| 159 | lua_insert(L_, 1); | 159 | lua_insert(L_, 1); |
| 160 | // do a protected call | 160 | // do a protected call |
| 161 | int const rc{ lua_pcall(L_, lua_gettop(L_) - 1, LUA_MULTRET, 0) }; | 161 | int const _rc{ lua_pcall(L_, lua_gettop(L_) - 1, LUA_MULTRET, 0) }; |
| 162 | // whatever happens, the keeper state stack must be empty when we are done | 162 | // whatever happens, the keeper state stack must be empty when we are done |
| 163 | lua_settop(KL, 0); | 163 | lua_settop(_KL, 0); |
| 164 | 164 | ||
| 165 | // release the keeper | 165 | // release the keeper |
| 166 | linda->releaseKeeper(K); | 166 | _linda->releaseKeeper(_K); |
| 167 | 167 | ||
| 168 | // if there was an error, forward it | 168 | // if there was an error, forward it |
| 169 | if (rc != LUA_OK) { | 169 | if (_rc != LUA_OK) { |
| 170 | raise_lua_error(L_); | 170 | raise_lua_error(L_); |
| 171 | } | 171 | } |
| 172 | // return whatever the actual operation provided | 172 | // return whatever the actual operation provided |
| @@ -186,108 +186,108 @@ int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_) | |||
| 186 | */ | 186 | */ |
| 187 | LUAG_FUNC(linda_send) | 187 | LUAG_FUNC(linda_send) |
| 188 | { | 188 | { |
| 189 | auto send = [](lua_State* L_) { | 189 | auto _send = [](lua_State* L_) { |
| 190 | Linda* const linda{ ToLinda<false>(L_, 1) }; | 190 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 191 | int key_i{ 2 }; // index of first key, if timeout not there | 191 | int _key_i{ 2 }; // index of first key, if timeout not there |
| 192 | 192 | ||
| 193 | std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; | 193 | std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; |
| 194 | if (lua_type(L_, 2) == LUA_TNUMBER) { // we don't want to use lua_isnumber() because of autocoercion | 194 | if (lua_type(L_, 2) == LUA_TNUMBER) { // we don't want to use lua_isnumber() because of autocoercion |
| 195 | lua_Duration const duration{ lua_tonumber(L_, 2) }; | 195 | lua_Duration const _duration{ lua_tonumber(L_, 2) }; |
| 196 | if (duration.count() >= 0.0) { | 196 | if (_duration.count() >= 0.0) { |
| 197 | until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration); | 197 | _until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(_duration); |
| 198 | } else { | 198 | } else { |
| 199 | raise_luaL_argerror(L_, 2, "duration cannot be < 0"); | 199 | raise_luaL_argerror(L_, 2, "duration cannot be < 0"); |
| 200 | } | 200 | } |
| 201 | ++key_i; | 201 | ++_key_i; |
| 202 | } else if (lua_isnil(L_, 2)) { // alternate explicit "infinite timeout" by passing nil before the key | 202 | } else if (lua_isnil(L_, 2)) { // alternate explicit "infinite timeout" by passing nil before the key |
| 203 | ++key_i; | 203 | ++_key_i; |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | // make sure the key is of a valid type | 206 | // make sure the key is of a valid type |
| 207 | check_key_types(L_, key_i, key_i); | 207 | check_key_types(L_, _key_i, _key_i); |
| 208 | 208 | ||
| 209 | STACK_GROW(L_, 1); | 209 | STACK_GROW(L_, 1); |
| 210 | 210 | ||
| 211 | // make sure there is something to send | 211 | // make sure there is something to send |
| 212 | if (lua_gettop(L_) == key_i) { | 212 | if (lua_gettop(L_) == _key_i) { |
| 213 | raise_luaL_error(L_, "no data to send"); | 213 | raise_luaL_error(L_, "no data to send"); |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | // convert nils to some special non-nil sentinel in sent values | 216 | // convert nils to some special non-nil sentinel in sent values |
| 217 | keeper_toggle_nil_sentinels(L_, key_i + 1, LookupMode::ToKeeper); | 217 | keeper_toggle_nil_sentinels(L_, _key_i + 1, LookupMode::ToKeeper); |
| 218 | bool ret{ false }; | 218 | bool _ret{ false }; |
| 219 | CancelRequest cancel{ CancelRequest::None }; | 219 | CancelRequest _cancel{ CancelRequest::None }; |
| 220 | KeeperCallResult pushed; | 220 | KeeperCallResult _pushed; |
| 221 | { | 221 | { |
| 222 | Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L_) }; | 222 | Lane* const _lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L_) }; |
| 223 | Keeper* const K{ linda->whichKeeper() }; | 223 | Keeper* const _K{ _linda->whichKeeper() }; |
| 224 | KeeperState const KL{ K ? K->L : nullptr }; | 224 | KeeperState const _KL{ _K ? _K->L : nullptr }; |
| 225 | if (KL == nullptr) | 225 | if (_KL == nullptr) |
| 226 | return 0; | 226 | return 0; |
| 227 | 227 | ||
| 228 | STACK_CHECK_START_REL(KL, 0); | 228 | STACK_CHECK_START_REL(_KL, 0); |
| 229 | for (bool try_again{ true };;) { | 229 | for (bool _try_again{ true };;) { |
| 230 | if (lane != nullptr) { | 230 | if (_lane != nullptr) { |
| 231 | cancel = lane->cancelRequest; | 231 | _cancel = _lane->cancelRequest; |
| 232 | } | 232 | } |
| 233 | cancel = (cancel != CancelRequest::None) ? cancel : linda->cancelRequest; | 233 | _cancel = (_cancel != CancelRequest::None) ? _cancel : _linda->cancelRequest; |
| 234 | // if user wants to cancel, or looped because of a timeout, the call returns without sending anything | 234 | // if user wants to cancel, or looped because of a timeout, the call returns without sending anything |
| 235 | if (!try_again || cancel != CancelRequest::None) { | 235 | if (!_try_again || _cancel != CancelRequest::None) { |
| 236 | pushed.emplace(0); | 236 | _pushed.emplace(0); |
| 237 | break; | 237 | break; |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | STACK_CHECK(KL, 0); | 240 | STACK_CHECK(_KL, 0); |
| 241 | pushed = keeper_call(linda->U, KL, KEEPER_API(send), L_, linda, key_i); | 241 | _pushed = keeper_call(_KL, KEEPER_API(send), L_, _linda, _key_i); |
| 242 | if (!pushed.has_value()) { | 242 | if (!_pushed.has_value()) { |
| 243 | break; | 243 | break; |
| 244 | } | 244 | } |
| 245 | LUA_ASSERT(L_, pushed.value() == 1); | 245 | LUA_ASSERT(L_, _pushed.value() == 1); |
| 246 | 246 | ||
| 247 | ret = lua_toboolean(L_, -1) ? true : false; | 247 | _ret = lua_toboolean(L_, -1) ? true : false; |
| 248 | lua_pop(L_, 1); | 248 | lua_pop(L_, 1); |
| 249 | 249 | ||
| 250 | if (ret) { | 250 | if (_ret) { |
| 251 | // Wake up ALL waiting threads | 251 | // Wake up ALL waiting threads |
| 252 | linda->writeHappened.notify_all(); | 252 | _linda->writeHappened.notify_all(); |
| 253 | break; | 253 | break; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | // instant timout to bypass the wait syscall | 256 | // instant timout to bypass the wait syscall |
| 257 | if (std::chrono::steady_clock::now() >= until) { | 257 | if (std::chrono::steady_clock::now() >= _until) { |
| 258 | break; /* no wait; instant timeout */ | 258 | break; /* no wait; instant timeout */ |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | // storage limit hit, wait until timeout or signalled that we should try again | 261 | // storage limit hit, wait until timeout or signalled that we should try again |
| 262 | { | 262 | { |
| 263 | Lane::Status prev_status{ Lane::Error }; // prevent 'might be used uninitialized' warnings | 263 | Lane::Status _prev_status{ Lane::Error }; // prevent 'might be used uninitialized' warnings |
| 264 | if (lane != nullptr) { | 264 | if (_lane != nullptr) { |
| 265 | // change status of lane to "waiting" | 265 | // change status of lane to "waiting" |
| 266 | prev_status = lane->status; // Running, most likely | 266 | _prev_status = _lane->status; // Running, most likely |
| 267 | LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case | 267 | LUA_ASSERT(L_, _prev_status == Lane::Running); // but check, just in case |
| 268 | lane->status = Lane::Waiting; | 268 | _lane->status = Lane::Waiting; |
| 269 | LUA_ASSERT(L_, lane->waiting_on == nullptr); | 269 | LUA_ASSERT(L_, _lane->waiting_on == nullptr); |
| 270 | lane->waiting_on = &linda->readHappened; | 270 | _lane->waiting_on = &_linda->readHappened; |
| 271 | } | 271 | } |
| 272 | // could not send because no room: wait until some data was read before trying again, or until timeout is reached | 272 | // could not send because no room: wait until some data was read before trying again, or until timeout is reached |
| 273 | std::unique_lock<std::mutex> keeper_lock{ K->mutex, std::adopt_lock }; | 273 | std::unique_lock<std::mutex> _keeper_lock{ _K->mutex, std::adopt_lock }; |
| 274 | std::cv_status const status{ linda->readHappened.wait_until(keeper_lock, until) }; | 274 | std::cv_status const status{ _linda->readHappened.wait_until(_keeper_lock, _until) }; |
| 275 | keeper_lock.release(); // we don't want to release the lock! | 275 | _keeper_lock.release(); // we don't want to release the lock! |
| 276 | try_again = (status == std::cv_status::no_timeout); // detect spurious wakeups | 276 | _try_again = (status == std::cv_status::no_timeout); // detect spurious wakeups |
| 277 | if (lane != nullptr) { | 277 | if (_lane != nullptr) { |
| 278 | lane->waiting_on = nullptr; | 278 | _lane->waiting_on = nullptr; |
| 279 | lane->status = prev_status; | 279 | _lane->status = _prev_status; |
| 280 | } | 280 | } |
| 281 | } | 281 | } |
| 282 | } | 282 | } |
| 283 | STACK_CHECK(KL, 0); | 283 | STACK_CHECK(_KL, 0); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | if (!pushed.has_value()) { | 286 | if (!_pushed.has_value()) { |
| 287 | raise_luaL_error(L_, "tried to copy unsupported types"); | 287 | raise_luaL_error(L_, "tried to copy unsupported types"); |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | switch (cancel) { | 290 | switch (_cancel) { |
| 291 | case CancelRequest::Soft: | 291 | case CancelRequest::Soft: |
| 292 | // if user wants to soft-cancel, the call returns lanes.cancel_error | 292 | // if user wants to soft-cancel, the call returns lanes.cancel_error |
| 293 | kCancelError.pushKey(L_); | 293 | kCancelError.pushKey(L_); |
| @@ -298,11 +298,11 @@ LUAG_FUNC(linda_send) | |||
| 298 | raise_cancel_error(L_); // raises an error and doesn't return | 298 | raise_cancel_error(L_); // raises an error and doesn't return |
| 299 | 299 | ||
| 300 | default: | 300 | default: |
| 301 | lua_pushboolean(L_, ret); // true (success) or false (timeout) | 301 | lua_pushboolean(L_, _ret); // true (success) or false (timeout) |
| 302 | return 1; | 302 | return 1; |
| 303 | } | 303 | } |
| 304 | }; | 304 | }; |
| 305 | return Linda::ProtectedCall(L_, send); | 305 | return Linda::ProtectedCall(L_, _send); |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | // ################################################################################################# | 308 | // ################################################################################################# |
| @@ -320,122 +320,122 @@ LUAG_FUNC(linda_send) | |||
| 320 | */ | 320 | */ |
| 321 | LUAG_FUNC(linda_receive) | 321 | LUAG_FUNC(linda_receive) |
| 322 | { | 322 | { |
| 323 | auto receive = [](lua_State* L_) { | 323 | auto _receive = [](lua_State* L_) { |
| 324 | Linda* const linda{ ToLinda<false>(L_, 1) }; | 324 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 325 | int key_i{ 2 }; // index of first key, if timeout not there | 325 | int _key_i{ 2 }; // index of first key, if timeout not there |
| 326 | 326 | ||
| 327 | std::chrono::time_point<std::chrono::steady_clock> until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; | 327 | std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::time_point<std::chrono::steady_clock>::max() }; |
| 328 | if (lua_type(L_, 2) == LUA_TNUMBER) { // we don't want to use lua_isnumber() because of autocoercion | 328 | if (lua_type(L_, 2) == LUA_TNUMBER) { // we don't want to use lua_isnumber() because of autocoercion |
| 329 | lua_Duration const duration{ lua_tonumber(L_, 2) }; | 329 | lua_Duration const _duration{ lua_tonumber(L_, 2) }; |
| 330 | if (duration.count() >= 0.0) { | 330 | if (_duration.count() >= 0.0) { |
| 331 | until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(duration); | 331 | _until = std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(_duration); |
| 332 | } else { | 332 | } else { |
| 333 | raise_luaL_argerror(L_, 2, "duration cannot be < 0"); | 333 | raise_luaL_argerror(L_, 2, "duration cannot be < 0"); |
| 334 | } | 334 | } |
| 335 | ++key_i; | 335 | ++_key_i; |
| 336 | } else if (lua_isnil(L_, 2)) { // alternate explicit "infinite timeout" by passing nil before the key | 336 | } else if (lua_isnil(L_, 2)) { // alternate explicit "infinite timeout" by passing nil before the key |
| 337 | ++key_i; | 337 | ++_key_i; |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | keeper_api_t selected_keeper_receive{ nullptr }; | 340 | keeper_api_t _selected_keeper_receive{ nullptr }; |
| 341 | int expected_pushed_min{ 0 }, expected_pushed_max{ 0 }; | 341 | int _expected_pushed_min{ 0 }, _expected_pushed_max{ 0 }; |
| 342 | // are we in batched mode? | 342 | // are we in batched mode? |
| 343 | kLindaBatched.pushKey(L_); | 343 | kLindaBatched.pushKey(L_); |
| 344 | int const is_batched{ lua501_equal(L_, key_i, -1) }; | 344 | int const _is_batched{ lua501_equal(L_, _key_i, -1) }; |
| 345 | lua_pop(L_, 1); | 345 | lua_pop(L_, 1); |
| 346 | if (is_batched) { | 346 | if (_is_batched) { |
| 347 | // no need to pass linda.batched in the keeper state | 347 | // no need to pass linda.batched in the keeper state |
| 348 | ++key_i; | 348 | ++_key_i; |
| 349 | // make sure the keys are of a valid type | 349 | // make sure the keys are of a valid type |
| 350 | check_key_types(L_, key_i, key_i); | 350 | check_key_types(L_, _key_i, _key_i); |
| 351 | // receive multiple values from a single slot | 351 | // receive multiple values from a single slot |
| 352 | selected_keeper_receive = KEEPER_API(receive_batched); | 352 | _selected_keeper_receive = KEEPER_API(receive_batched); |
| 353 | // we expect a user-defined amount of return value | 353 | // we expect a user-defined amount of return value |
| 354 | expected_pushed_min = (int) luaL_checkinteger(L_, key_i + 1); | 354 | _expected_pushed_min = (int) luaL_checkinteger(L_, _key_i + 1); |
| 355 | expected_pushed_max = (int) luaL_optinteger(L_, key_i + 2, expected_pushed_min); | 355 | _expected_pushed_max = (int) luaL_optinteger(L_, _key_i + 2, _expected_pushed_min); |
| 356 | // don't forget to count the key in addition to the values | 356 | // don't forget to count the key in addition to the values |
| 357 | ++expected_pushed_min; | 357 | ++_expected_pushed_min; |
| 358 | ++expected_pushed_max; | 358 | ++_expected_pushed_max; |
| 359 | if (expected_pushed_min > expected_pushed_max) { | 359 | if (_expected_pushed_min > _expected_pushed_max) { |
| 360 | raise_luaL_error(L_, "batched min/max error"); | 360 | raise_luaL_error(L_, "batched min/max error"); |
| 361 | } | 361 | } |
| 362 | } else { | 362 | } else { |
| 363 | // make sure the keys are of a valid type | 363 | // make sure the keys are of a valid type |
| 364 | check_key_types(L_, key_i, lua_gettop(L_)); | 364 | check_key_types(L_, _key_i, lua_gettop(L_)); |
| 365 | // receive a single value, checking multiple slots | 365 | // receive a single value, checking multiple slots |
| 366 | selected_keeper_receive = KEEPER_API(receive); | 366 | _selected_keeper_receive = KEEPER_API(receive); |
| 367 | // we expect a single (value, key) pair of returned values | 367 | // we expect a single (value, key) pair of returned values |
| 368 | expected_pushed_min = expected_pushed_max = 2; | 368 | _expected_pushed_min = _expected_pushed_max = 2; |
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | Lane* const lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L_) }; | 371 | Lane* const _lane{ kLanePointerRegKey.readLightUserDataValue<Lane>(L_) }; |
| 372 | Keeper* const K{ linda->whichKeeper() }; | 372 | Keeper* const _K{ _linda->whichKeeper() }; |
| 373 | KeeperState const KL{ K ? K->L : nullptr }; | 373 | KeeperState const _KL{ _K ? _K->L : nullptr }; |
| 374 | if (KL == nullptr) | 374 | if (_KL == nullptr) |
| 375 | return 0; | 375 | return 0; |
| 376 | 376 | ||
| 377 | CancelRequest cancel{ CancelRequest::None }; | 377 | CancelRequest _cancel{ CancelRequest::None }; |
| 378 | KeeperCallResult pushed; | 378 | KeeperCallResult _pushed; |
| 379 | STACK_CHECK_START_REL(KL, 0); | 379 | STACK_CHECK_START_REL(_KL, 0); |
| 380 | for (bool try_again{ true };;) { | 380 | for (bool _try_again{ true };;) { |
| 381 | if (lane != nullptr) { | 381 | if (_lane != nullptr) { |
| 382 | cancel = lane->cancelRequest; | 382 | _cancel = _lane->cancelRequest; |
| 383 | } | 383 | } |
| 384 | cancel = (cancel != CancelRequest::None) ? cancel : linda->cancelRequest; | 384 | _cancel = (_cancel != CancelRequest::None) ? _cancel : _linda->cancelRequest; |
| 385 | // if user wants to cancel, or looped because of a timeout, the call returns without sending anything | 385 | // if user wants to cancel, or looped because of a timeout, the call returns without sending anything |
| 386 | if (!try_again || cancel != CancelRequest::None) { | 386 | if (!_try_again || _cancel != CancelRequest::None) { |
| 387 | pushed.emplace(0); | 387 | _pushed.emplace(0); |
| 388 | break; | 388 | break; |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | // all arguments of receive() but the first are passed to the keeper's receive function | 391 | // all arguments of receive() but the first are passed to the keeper's receive function |
| 392 | pushed = keeper_call(linda->U, KL, selected_keeper_receive, L_, linda, key_i); | 392 | _pushed = keeper_call(_KL, _selected_keeper_receive, L_, _linda, _key_i); |
| 393 | if (!pushed.has_value()) { | 393 | if (!_pushed.has_value()) { |
| 394 | break; | 394 | break; |
| 395 | } | 395 | } |
| 396 | if (pushed.value() > 0) { | 396 | if (_pushed.value() > 0) { |
| 397 | LUA_ASSERT(L_, pushed.value() >= expected_pushed_min && pushed.value() <= expected_pushed_max); | 397 | LUA_ASSERT(L_, _pushed.value() >= _expected_pushed_min && _pushed.value() <= _expected_pushed_max); |
| 398 | // replace sentinels with real nils | 398 | // replace sentinels with real nils |
| 399 | keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - pushed.value(), LookupMode::FromKeeper); | 399 | keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - _pushed.value(), LookupMode::FromKeeper); |
| 400 | // To be done from within the 'K' locking area | 400 | // To be done from within the 'K' locking area |
| 401 | // | 401 | // |
| 402 | linda->readHappened.notify_all(); | 402 | _linda->readHappened.notify_all(); |
| 403 | break; | 403 | break; |
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | if (std::chrono::steady_clock::now() >= until) { | 406 | if (std::chrono::steady_clock::now() >= _until) { |
| 407 | break; /* instant timeout */ | 407 | break; /* instant timeout */ |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | // nothing received, wait until timeout or signalled that we should try again | 410 | // nothing received, wait until timeout or signalled that we should try again |
| 411 | { | 411 | { |
| 412 | Lane::Status prev_status{ Lane::Error }; // prevent 'might be used uninitialized' warnings | 412 | Lane::Status _prev_status{ Lane::Error }; // prevent 'might be used uninitialized' warnings |
| 413 | if (lane != nullptr) { | 413 | if (_lane != nullptr) { |
| 414 | // change status of lane to "waiting" | 414 | // change status of lane to "waiting" |
| 415 | prev_status = lane->status; // Running, most likely | 415 | _prev_status = _lane->status; // Running, most likely |
| 416 | LUA_ASSERT(L_, prev_status == Lane::Running); // but check, just in case | 416 | LUA_ASSERT(L_, _prev_status == Lane::Running); // but check, just in case |
| 417 | lane->status = Lane::Waiting; | 417 | _lane->status = Lane::Waiting; |
| 418 | LUA_ASSERT(L_, lane->waiting_on == nullptr); | 418 | LUA_ASSERT(L_, _lane->waiting_on == nullptr); |
| 419 | lane->waiting_on = &linda->writeHappened; | 419 | _lane->waiting_on = &_linda->writeHappened; |
| 420 | } | 420 | } |
| 421 | // not enough data to read: wakeup when data was sent, or when timeout is reached | 421 | // not enough data to read: wakeup when data was sent, or when timeout is reached |
| 422 | std::unique_lock<std::mutex> keeper_lock{ K->mutex, std::adopt_lock }; | 422 | std::unique_lock<std::mutex> _keeper_lock{ _K->mutex, std::adopt_lock }; |
| 423 | std::cv_status const status{ linda->writeHappened.wait_until(keeper_lock, until) }; | 423 | std::cv_status const _status{ _linda->writeHappened.wait_until(_keeper_lock, _until) }; |
| 424 | keeper_lock.release(); // we don't want to release the lock! | 424 | _keeper_lock.release(); // we don't want to release the lock! |
| 425 | try_again = (status == std::cv_status::no_timeout); // detect spurious wakeups | 425 | _try_again = (_status == std::cv_status::no_timeout); // detect spurious wakeups |
| 426 | if (lane != nullptr) { | 426 | if (_lane != nullptr) { |
| 427 | lane->waiting_on = nullptr; | 427 | _lane->waiting_on = nullptr; |
| 428 | lane->status = prev_status; | 428 | _lane->status = _prev_status; |
| 429 | } | 429 | } |
| 430 | } | 430 | } |
| 431 | } | 431 | } |
| 432 | STACK_CHECK(KL, 0); | 432 | STACK_CHECK(_KL, 0); |
| 433 | 433 | ||
| 434 | if (!pushed.has_value()) { | 434 | if (!_pushed.has_value()) { |
| 435 | raise_luaL_error(L_, "tried to copy unsupported types"); | 435 | raise_luaL_error(L_, "tried to copy unsupported types"); |
| 436 | } | 436 | } |
| 437 | 437 | ||
| 438 | switch (cancel) { | 438 | switch (_cancel) { |
| 439 | case CancelRequest::Soft: | 439 | case CancelRequest::Soft: |
| 440 | // if user wants to soft-cancel, the call returns kCancelError | 440 | // if user wants to soft-cancel, the call returns kCancelError |
| 441 | kCancelError.pushKey(L_); | 441 | kCancelError.pushKey(L_); |
| @@ -446,10 +446,10 @@ LUAG_FUNC(linda_receive) | |||
| 446 | raise_cancel_error(L_); // raises an error and doesn't return | 446 | raise_cancel_error(L_); // raises an error and doesn't return |
| 447 | 447 | ||
| 448 | default: | 448 | default: |
| 449 | return pushed.value(); | 449 | return _pushed.value(); |
| 450 | } | 450 | } |
| 451 | }; | 451 | }; |
| 452 | return Linda::ProtectedCall(L_, receive); | 452 | return Linda::ProtectedCall(L_, _receive); |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | // ################################################################################################# | 455 | // ################################################################################################# |
| @@ -465,40 +465,40 @@ LUAG_FUNC(linda_receive) | |||
| 465 | LUAG_FUNC(linda_set) | 465 | LUAG_FUNC(linda_set) |
| 466 | { | 466 | { |
| 467 | auto set = [](lua_State* L_) { | 467 | auto set = [](lua_State* L_) { |
| 468 | Linda* const linda{ ToLinda<false>(L_, 1) }; | 468 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 469 | bool const has_value{ lua_gettop(L_) > 2 }; | 469 | bool const _has_value{ lua_gettop(L_) > 2 }; |
| 470 | // make sure the key is of a valid type (throws an error if not the case) | 470 | // make sure the key is of a valid type (throws an error if not the case) |
| 471 | check_key_types(L_, 2, 2); | 471 | check_key_types(L_, 2, 2); |
| 472 | 472 | ||
| 473 | Keeper* const K{ linda->whichKeeper() }; | 473 | Keeper* const _K{ _linda->whichKeeper() }; |
| 474 | KeeperCallResult pushed; | 474 | KeeperCallResult _pushed; |
| 475 | if (linda->cancelRequest == CancelRequest::None) { | 475 | if (_linda->cancelRequest == CancelRequest::None) { |
| 476 | if (has_value) { | 476 | if (_has_value) { |
| 477 | // convert nils to some special non-nil sentinel in sent values | 477 | // convert nils to some special non-nil sentinel in sent values |
| 478 | keeper_toggle_nil_sentinels(L_, 3, LookupMode::ToKeeper); | 478 | keeper_toggle_nil_sentinels(L_, 3, LookupMode::ToKeeper); |
| 479 | } | 479 | } |
| 480 | pushed = keeper_call(linda->U, K->L, KEEPER_API(set), L_, linda, 2); | 480 | _pushed = keeper_call(_K->L, KEEPER_API(set), L_, _linda, 2); |
| 481 | if (pushed.has_value()) { // no error? | 481 | if (_pushed.has_value()) { // no error? |
| 482 | LUA_ASSERT(L_, pushed.value() == 0 || pushed.value() == 1); | 482 | LUA_ASSERT(L_, _pushed.value() == 0 || _pushed.value() == 1); |
| 483 | 483 | ||
| 484 | if (has_value) { | 484 | if (_has_value) { |
| 485 | // we put some data in the slot, tell readers that they should wake | 485 | // we put some data in the slot, tell readers that they should wake |
| 486 | linda->writeHappened.notify_all(); // To be done from within the 'K' locking area | 486 | _linda->writeHappened.notify_all(); // To be done from within the 'K' locking area |
| 487 | } | 487 | } |
| 488 | if (pushed.value() == 1) { | 488 | if (_pushed.value() == 1) { |
| 489 | // the key was full, but it is no longer the case, tell writers they should wake | 489 | // the key was full, but it is no longer the case, tell writers they should wake |
| 490 | LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TBOOLEAN && lua_toboolean(L_, -1) == 1); | 490 | LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TBOOLEAN && lua_toboolean(L_, -1) == 1); |
| 491 | linda->readHappened.notify_all(); // To be done from within the 'K' locking area | 491 | _linda->readHappened.notify_all(); // To be done from within the 'K' locking area |
| 492 | } | 492 | } |
| 493 | } | 493 | } |
| 494 | } else { // linda is cancelled | 494 | } else { // linda is cancelled |
| 495 | // do nothing and return lanes.cancel_error | 495 | // do nothing and return lanes.cancel_error |
| 496 | kCancelError.pushKey(L_); | 496 | kCancelError.pushKey(L_); |
| 497 | pushed.emplace(1); | 497 | _pushed.emplace(1); |
| 498 | } | 498 | } |
| 499 | 499 | ||
| 500 | // must trigger any error after keeper state has been released | 500 | // must trigger any error after keeper state has been released |
| 501 | return OptionalValue(pushed, L_, "tried to copy unsupported types"); | 501 | return OptionalValue(_pushed, L_, "tried to copy unsupported types"); |
| 502 | }; | 502 | }; |
| 503 | return Linda::ProtectedCall(L_, set); | 503 | return Linda::ProtectedCall(L_, set); |
| 504 | } | 504 | } |
| @@ -512,16 +512,16 @@ LUAG_FUNC(linda_set) | |||
| 512 | */ | 512 | */ |
| 513 | LUAG_FUNC(linda_count) | 513 | LUAG_FUNC(linda_count) |
| 514 | { | 514 | { |
| 515 | auto count = [](lua_State* L_) { | 515 | auto _count = [](lua_State* L_) { |
| 516 | Linda* const linda{ ToLinda<false>(L_, 1) }; | 516 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 517 | // make sure the keys are of a valid type | 517 | // make sure the keys are of a valid type |
| 518 | check_key_types(L_, 2, lua_gettop(L_)); | 518 | check_key_types(L_, 2, lua_gettop(L_)); |
| 519 | 519 | ||
| 520 | Keeper* const K{ linda->whichKeeper() }; | 520 | Keeper* const _K{ _linda->whichKeeper() }; |
| 521 | KeeperCallResult const pushed{ keeper_call(linda->U, K->L, KEEPER_API(count), L_, linda, 2) }; | 521 | KeeperCallResult const _pushed{ keeper_call(_K->L, KEEPER_API(count), L_, _linda, 2) }; |
| 522 | return OptionalValue(pushed, L_, "tried to count an invalid key"); | 522 | return OptionalValue(_pushed, L_, "tried to count an invalid key"); |
| 523 | }; | 523 | }; |
| 524 | return Linda::ProtectedCall(L_, count); | 524 | return Linda::ProtectedCall(L_, _count); |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | // ################################################################################################# | 527 | // ################################################################################################# |
| @@ -534,27 +534,27 @@ LUAG_FUNC(linda_count) | |||
| 534 | LUAG_FUNC(linda_get) | 534 | LUAG_FUNC(linda_get) |
| 535 | { | 535 | { |
| 536 | auto get = [](lua_State* L_) { | 536 | auto get = [](lua_State* L_) { |
| 537 | Linda* const linda{ ToLinda<false>(L_, 1) }; | 537 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 538 | lua_Integer const count{ luaL_optinteger(L_, 3, 1) }; | 538 | lua_Integer const _count{ luaL_optinteger(L_, 3, 1) }; |
| 539 | luaL_argcheck(L_, count >= 1, 3, "count should be >= 1"); | 539 | luaL_argcheck(L_, _count >= 1, 3, "count should be >= 1"); |
| 540 | luaL_argcheck(L_, lua_gettop(L_) <= 3, 4, "too many arguments"); | 540 | luaL_argcheck(L_, lua_gettop(L_) <= 3, 4, "too many arguments"); |
| 541 | // make sure the key is of a valid type (throws an error if not the case) | 541 | // make sure the key is of a valid type (throws an error if not the case) |
| 542 | check_key_types(L_, 2, 2); | 542 | check_key_types(L_, 2, 2); |
| 543 | 543 | ||
| 544 | KeeperCallResult pushed; | 544 | KeeperCallResult _pushed; |
| 545 | if (linda->cancelRequest == CancelRequest::None) { | 545 | if (_linda->cancelRequest == CancelRequest::None) { |
| 546 | Keeper* const K{ linda->whichKeeper() }; | 546 | Keeper* const _K{ _linda->whichKeeper() }; |
| 547 | pushed = keeper_call(linda->U, K->L, KEEPER_API(get), L_, linda, 2); | 547 | _pushed = keeper_call(_K->L, KEEPER_API(get), L_, _linda, 2); |
| 548 | if (pushed.value_or(0) > 0) { | 548 | if (_pushed.value_or(0) > 0) { |
| 549 | keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - pushed.value(), LookupMode::FromKeeper); | 549 | keeper_toggle_nil_sentinels(L_, lua_gettop(L_) - _pushed.value(), LookupMode::FromKeeper); |
| 550 | } | 550 | } |
| 551 | } else { // linda is cancelled | 551 | } else { // linda is cancelled |
| 552 | // do nothing and return lanes.cancel_error | 552 | // do nothing and return lanes.cancel_error |
| 553 | kCancelError.pushKey(L_); | 553 | kCancelError.pushKey(L_); |
| 554 | pushed.emplace(1); | 554 | _pushed.emplace(1); |
| 555 | } | 555 | } |
| 556 | // an error can be raised if we attempt to read an unregistered function | 556 | // an error can be raised if we attempt to read an unregistered function |
| 557 | return OptionalValue(pushed, L_, "tried to copy unsupported types"); | 557 | return OptionalValue(_pushed, L_, "tried to copy unsupported types"); |
| 558 | }; | 558 | }; |
| 559 | return Linda::ProtectedCall(L_, get); | 559 | return Linda::ProtectedCall(L_, get); |
| 560 | } | 560 | } |
| @@ -569,8 +569,8 @@ LUAG_FUNC(linda_get) | |||
| 569 | */ | 569 | */ |
| 570 | LUAG_FUNC(linda_limit) | 570 | LUAG_FUNC(linda_limit) |
| 571 | { | 571 | { |
| 572 | auto limit = [](lua_State* L_) { | 572 | auto _limit = [](lua_State* L_) { |
| 573 | Linda* const linda{ ToLinda<false>(L_, 1) }; | 573 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 574 | // make sure we got 3 arguments: the linda, a key and a limit | 574 | // make sure we got 3 arguments: the linda, a key and a limit |
| 575 | luaL_argcheck(L_, lua_gettop(L_) == 3, 2, "wrong number of arguments"); | 575 | luaL_argcheck(L_, lua_gettop(L_) == 3, 2, "wrong number of arguments"); |
| 576 | // make sure we got a numeric limit | 576 | // make sure we got a numeric limit |
| @@ -578,24 +578,24 @@ LUAG_FUNC(linda_limit) | |||
| 578 | // make sure the key is of a valid type | 578 | // make sure the key is of a valid type |
| 579 | check_key_types(L_, 2, 2); | 579 | check_key_types(L_, 2, 2); |
| 580 | 580 | ||
| 581 | KeeperCallResult pushed; | 581 | KeeperCallResult _pushed; |
| 582 | if (linda->cancelRequest == CancelRequest::None) { | 582 | if (_linda->cancelRequest == CancelRequest::None) { |
| 583 | Keeper* const K{ linda->whichKeeper() }; | 583 | Keeper* const _K{ _linda->whichKeeper() }; |
| 584 | pushed = keeper_call(linda->U, K->L, KEEPER_API(limit), L_, linda, 2); | 584 | _pushed = keeper_call(_K->L, KEEPER_API(limit), L_, _linda, 2); |
| 585 | LUA_ASSERT(L_, pushed.has_value() && (pushed.value() == 0 || pushed.value() == 1)); // no error, optional boolean value saying if we should wake blocked writer threads | 585 | LUA_ASSERT(L_, _pushed.has_value() && (_pushed.value() == 0 || _pushed.value() == 1)); // no error, optional boolean value saying if we should wake blocked writer threads |
| 586 | if (pushed.value() == 1) { | 586 | if (_pushed.value() == 1) { |
| 587 | LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TBOOLEAN && lua_toboolean(L_, -1) == 1); | 587 | LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TBOOLEAN && lua_toboolean(L_, -1) == 1); |
| 588 | linda->readHappened.notify_all(); // To be done from within the 'K' locking area | 588 | _linda->readHappened.notify_all(); // To be done from within the 'K' locking area |
| 589 | } | 589 | } |
| 590 | } else { // linda is cancelled | 590 | } else { // linda is cancelled |
| 591 | // do nothing and return lanes.cancel_error | 591 | // do nothing and return lanes.cancel_error |
| 592 | kCancelError.pushKey(L_); | 592 | kCancelError.pushKey(L_); |
| 593 | pushed.emplace(1); | 593 | _pushed.emplace(1); |
| 594 | } | 594 | } |
| 595 | // propagate pushed boolean if any | 595 | // propagate pushed boolean if any |
| 596 | return pushed.value(); | 596 | return _pushed.value(); |
| 597 | }; | 597 | }; |
| 598 | return Linda::ProtectedCall(L_, limit); | 598 | return Linda::ProtectedCall(L_, _limit); |
| 599 | } | 599 | } |
| 600 | 600 | ||
| 601 | // ################################################################################################# | 601 | // ################################################################################################# |
| @@ -607,23 +607,23 @@ LUAG_FUNC(linda_limit) | |||
| 607 | */ | 607 | */ |
| 608 | LUAG_FUNC(linda_cancel) | 608 | LUAG_FUNC(linda_cancel) |
| 609 | { | 609 | { |
| 610 | Linda* const linda{ ToLinda<false>(L_, 1) }; | 610 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 611 | char const* who = luaL_optstring(L_, 2, "both"); | 611 | char const* _who{ luaL_optstring(L_, 2, "both") }; |
| 612 | // make sure we got 3 arguments: the linda, a key and a limit | 612 | // make sure we got 3 arguments: the linda, a key and a limit |
| 613 | luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments"); | 613 | luaL_argcheck(L_, lua_gettop(L_) <= 2, 2, "wrong number of arguments"); |
| 614 | 614 | ||
| 615 | linda->cancelRequest = CancelRequest::Soft; | 615 | _linda->cancelRequest = CancelRequest::Soft; |
| 616 | if (strcmp(who, "both") == 0) { // tell everyone writers to wake up | 616 | if (strcmp(_who, "both") == 0) { // tell everyone writers to wake up |
| 617 | linda->writeHappened.notify_all(); | 617 | _linda->writeHappened.notify_all(); |
| 618 | linda->readHappened.notify_all(); | 618 | _linda->readHappened.notify_all(); |
| 619 | } else if (strcmp(who, "none") == 0) { // reset flag | 619 | } else if (strcmp(_who, "none") == 0) { // reset flag |
| 620 | linda->cancelRequest = CancelRequest::None; | 620 | _linda->cancelRequest = CancelRequest::None; |
| 621 | } else if (strcmp(who, "read") == 0) { // tell blocked readers to wake up | 621 | } else if (strcmp(_who, "read") == 0) { // tell blocked readers to wake up |
| 622 | linda->writeHappened.notify_all(); | 622 | _linda->writeHappened.notify_all(); |
| 623 | } else if (strcmp(who, "write") == 0) { // tell blocked writers to wake up | 623 | } else if (strcmp(_who, "write") == 0) { // tell blocked writers to wake up |
| 624 | linda->readHappened.notify_all(); | 624 | _linda->readHappened.notify_all(); |
| 625 | } else { | 625 | } else { |
| 626 | raise_luaL_error(L_, "unknown wake hint '%s'", who); | 626 | raise_luaL_error(L_, "unknown wake hint '%s'", _who); |
| 627 | } | 627 | } |
| 628 | return 0; | 628 | return 0; |
| 629 | } | 629 | } |
| @@ -642,8 +642,8 @@ LUAG_FUNC(linda_cancel) | |||
| 642 | */ | 642 | */ |
| 643 | LUAG_FUNC(linda_deep) | 643 | LUAG_FUNC(linda_deep) |
| 644 | { | 644 | { |
| 645 | Linda* const linda{ ToLinda<false>(L_, 1) }; | 645 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 646 | lua_pushlightuserdata(L_, linda); // just the address | 646 | lua_pushlightuserdata(L_, _linda); // just the address |
| 647 | return 1; | 647 | return 1; |
| 648 | } | 648 | } |
| 649 | 649 | ||
| @@ -660,15 +660,15 @@ LUAG_FUNC(linda_deep) | |||
| 660 | template <bool OPT> | 660 | template <bool OPT> |
| 661 | [[nodiscard]] static int LindaToString(lua_State* L_, int idx_) | 661 | [[nodiscard]] static int LindaToString(lua_State* L_, int idx_) |
| 662 | { | 662 | { |
| 663 | Linda* const linda{ ToLinda<OPT>(L_, idx_) }; | 663 | Linda* const _linda{ ToLinda<OPT>(L_, idx_) }; |
| 664 | if (linda != nullptr) { | 664 | if (_linda != nullptr) { |
| 665 | char text[128]; | 665 | char _text[128]; |
| 666 | int len; | 666 | int _len; |
| 667 | if (linda->getName()) | 667 | if (_linda->getName()) |
| 668 | len = sprintf(text, "Linda: %.*s", (int) sizeof(text) - 8, linda->getName()); | 668 | _len = sprintf(_text, "Linda: %.*s", (int) sizeof(_text) - 8, _linda->getName()); |
| 669 | else | 669 | else |
| 670 | len = sprintf(text, "Linda: %p", linda); | 670 | _len = sprintf(_text, "Linda: %p", _linda); |
| 671 | lua_pushlstring(L_, text, len); | 671 | lua_pushlstring(L_, _text, _len); |
| 672 | return 1; | 672 | return 1; |
| 673 | } | 673 | } |
| 674 | return 0; | 674 | return 0; |
| @@ -692,17 +692,17 @@ LUAG_FUNC(linda_tostring) | |||
| 692 | */ | 692 | */ |
| 693 | LUAG_FUNC(linda_concat) | 693 | LUAG_FUNC(linda_concat) |
| 694 | { // L_: linda1? linda2? | 694 | { // L_: linda1? linda2? |
| 695 | bool atLeastOneLinda{ false }; | 695 | bool _atLeastOneLinda{ false }; |
| 696 | // Lua semantics enforce that one of the 2 arguments is a Linda, but not necessarily both. | 696 | // Lua semantics enforce that one of the 2 arguments is a Linda, but not necessarily both. |
| 697 | if (LindaToString<true>(L_, 1)) { | 697 | if (LindaToString<true>(L_, 1)) { |
| 698 | atLeastOneLinda = true; | 698 | _atLeastOneLinda = true; |
| 699 | lua_replace(L_, 1); | 699 | lua_replace(L_, 1); |
| 700 | } | 700 | } |
| 701 | if (LindaToString<true>(L_, 2)) { | 701 | if (LindaToString<true>(L_, 2)) { |
| 702 | atLeastOneLinda = true; | 702 | _atLeastOneLinda = true; |
| 703 | lua_replace(L_, 2); | 703 | lua_replace(L_, 2); |
| 704 | } | 704 | } |
| 705 | if (!atLeastOneLinda) { // should not be possible | 705 | if (!_atLeastOneLinda) { // should not be possible |
| 706 | raise_luaL_error(L_, "internal error: linda_concat called on non-Linda"); | 706 | raise_luaL_error(L_, "internal error: linda_concat called on non-Linda"); |
| 707 | } | 707 | } |
| 708 | lua_concat(L_, 2); | 708 | lua_concat(L_, 2); |
| @@ -717,11 +717,11 @@ LUAG_FUNC(linda_concat) | |||
| 717 | */ | 717 | */ |
| 718 | LUAG_FUNC(linda_dump) | 718 | LUAG_FUNC(linda_dump) |
| 719 | { | 719 | { |
| 720 | auto dump = [](lua_State* L_) { | 720 | auto _dump = [](lua_State* L_) { |
| 721 | Linda* const linda{ ToLinda<false>(L_, 1) }; | 721 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 722 | return keeper_push_linda_storage(*linda, DestState{ L_ }); | 722 | return keeper_push_linda_storage(*_linda, DestState{ L_ }); |
| 723 | }; | 723 | }; |
| 724 | return Linda::ProtectedCall(L_, dump); | 724 | return Linda::ProtectedCall(L_, _dump); |
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | // ################################################################################################# | 727 | // ################################################################################################# |
| @@ -732,13 +732,13 @@ LUAG_FUNC(linda_dump) | |||
| 732 | */ | 732 | */ |
| 733 | LUAG_FUNC(linda_towatch) | 733 | LUAG_FUNC(linda_towatch) |
| 734 | { | 734 | { |
| 735 | Linda* const linda{ ToLinda<false>(L_, 1) }; | 735 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 736 | int pushed{ keeper_push_linda_storage(*linda, DestState{ L_ }) }; | 736 | int _pushed{ keeper_push_linda_storage(*_linda, DestState{ L_ }) }; |
| 737 | if (pushed == 0) { | 737 | if (_pushed == 0) { |
| 738 | // if the linda is empty, don't return nil | 738 | // if the linda is empty, don't return nil |
| 739 | pushed = LindaToString<false>(L_, 1); | 739 | _pushed = LindaToString<false>(L_, 1); |
| 740 | } | 740 | } |
| 741 | return pushed; | 741 | return _pushed; |
| 742 | } | 742 | } |
| 743 | 743 | ||
| 744 | // ################################################################################################# | 744 | // ################################################################################################# |
| @@ -773,12 +773,12 @@ namespace global { | |||
| 773 | */ | 773 | */ |
| 774 | LUAG_FUNC(linda) | 774 | LUAG_FUNC(linda) |
| 775 | { | 775 | { |
| 776 | int const top{ lua_gettop(L_) }; | 776 | int const _top{ lua_gettop(L_) }; |
| 777 | luaL_argcheck(L_, top <= 2, top, "too many arguments"); | 777 | luaL_argcheck(L_, _top <= 2, _top, "too many arguments"); |
| 778 | if (top == 1) { | 778 | if (_top == 1) { |
| 779 | LuaType const t{ lua_type_as_enum(L_, 1) }; | 779 | LuaType const _t{ lua_type_as_enum(L_, 1) }; |
| 780 | luaL_argcheck(L_, t == LuaType::STRING || t == LuaType::NUMBER, 1, "wrong parameter (should be a string or a number)"); | 780 | luaL_argcheck(L_, _t == LuaType::STRING || _t == LuaType::NUMBER, 1, "wrong parameter (should be a string or a number)"); |
| 781 | } else if (top == 2) { | 781 | } else if (_top == 2) { |
| 782 | luaL_checktype(L_, 1, LUA_TSTRING); | 782 | luaL_checktype(L_, 1, LUA_TSTRING); |
| 783 | luaL_checktype(L_, 2, LUA_TNUMBER); | 783 | luaL_checktype(L_, 2, LUA_TNUMBER); |
| 784 | } | 784 | } |
diff --git a/src/lindafactory.cpp b/src/lindafactory.cpp index 0ec5a0a..16c653f 100644 --- a/src/lindafactory.cpp +++ b/src/lindafactory.cpp | |||
| @@ -68,25 +68,25 @@ void LindaFactory::createMetatable(lua_State* L_) const | |||
| 68 | 68 | ||
| 69 | void LindaFactory::deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const | 69 | void LindaFactory::deleteDeepObjectInternal(lua_State* L_, DeepPrelude* o_) const |
| 70 | { | 70 | { |
| 71 | Linda* const linda{ static_cast<Linda*>(o_) }; | 71 | Linda* const _linda{ static_cast<Linda*>(o_) }; |
| 72 | LUA_ASSERT(L_, linda); | 72 | LUA_ASSERT(L_, _linda); |
| 73 | Keeper* const myK{ linda->whichKeeper() }; | 73 | Keeper* const _myK{ _linda->whichKeeper() }; |
| 74 | // if collected after the universe, keepers are already destroyed, and there is nothing to clear | 74 | // if collected after the universe, keepers are already destroyed, and there is nothing to clear |
| 75 | if (myK) { | 75 | if (_myK) { |
| 76 | // if collected from my own keeper, we can't acquire/release it | 76 | // if collected from my own keeper, we can't acquire/release it |
| 77 | // because we are already inside a protected area, and trying to do so would deadlock! | 77 | // because we are already inside a protected area, and trying to do so would deadlock! |
| 78 | bool const need_acquire_release{ myK->L != L_ }; | 78 | bool const _need_acquire_release{ _myK->L != L_ }; |
| 79 | // Clean associated structures in the keeper state. | 79 | // Clean associated structures in the keeper state. |
| 80 | Keeper* const K{ need_acquire_release ? linda->acquireKeeper() : myK }; | 80 | Keeper* const _K{ _need_acquire_release ? _linda->acquireKeeper() : _myK }; |
| 81 | // hopefully this won't ever raise an error as we would jump to the closest pcall site while forgetting to release the keeper mutex... | 81 | // hopefully this won't ever raise an error as we would jump to the closest pcall site while forgetting to release the keeper mutex... |
| 82 | [[maybe_unused]] KeeperCallResult const result{ keeper_call(linda->U, K->L, KEEPER_API(clear), L_, linda, 0) }; | 82 | [[maybe_unused]] KeeperCallResult const result{ keeper_call(_K->L, KEEPER_API(clear), L_, _linda, 0) }; |
| 83 | LUA_ASSERT(L_, result.has_value() && result.value() == 0); | 83 | LUA_ASSERT(L_, result.has_value() && result.value() == 0); |
| 84 | if (need_acquire_release) { | 84 | if (_need_acquire_release) { |
| 85 | linda->releaseKeeper(K); | 85 | _linda->releaseKeeper(_K); |
| 86 | } | 86 | } |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | delete linda; // operator delete overload ensures things go as expected | 89 | delete _linda; // operator delete overload ensures things go as expected |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | // ################################################################################################# | 92 | // ################################################################################################# |
| @@ -103,9 +103,9 @@ char const* LindaFactory::moduleName() const | |||
| 103 | 103 | ||
| 104 | DeepPrelude* LindaFactory::newDeepObjectInternal(lua_State* L_) const | 104 | DeepPrelude* LindaFactory::newDeepObjectInternal(lua_State* L_) const |
| 105 | { | 105 | { |
| 106 | size_t name_len{ 0 }; | 106 | size_t _name_len{ 0 }; |
| 107 | char const* linda_name{ nullptr }; | 107 | char const* _linda_name{ nullptr }; |
| 108 | LindaGroup linda_group{ 0 }; | 108 | LindaGroup _linda_group{ 0 }; |
| 109 | // should have a string and/or a number of the stack as parameters (name and group) | 109 | // should have a string and/or a number of the stack as parameters (name and group) |
| 110 | switch (lua_gettop(L_)) { | 110 | switch (lua_gettop(L_)) { |
| 111 | default: // 0 | 111 | default: // 0 |
| @@ -113,21 +113,21 @@ DeepPrelude* LindaFactory::newDeepObjectInternal(lua_State* L_) const | |||
| 113 | 113 | ||
| 114 | case 1: // 1 parameter, either a name or a group | 114 | case 1: // 1 parameter, either a name or a group |
| 115 | if (lua_type(L_, -1) == LUA_TSTRING) { | 115 | if (lua_type(L_, -1) == LUA_TSTRING) { |
| 116 | linda_name = lua_tolstring(L_, -1, &name_len); | 116 | _linda_name = lua_tolstring(L_, -1, &_name_len); |
| 117 | } else { | 117 | } else { |
| 118 | linda_group = LindaGroup{ static_cast<int>(lua_tointeger(L_, -1)) }; | 118 | _linda_group = LindaGroup{ static_cast<int>(lua_tointeger(L_, -1)) }; |
| 119 | } | 119 | } |
| 120 | break; | 120 | break; |
| 121 | 121 | ||
| 122 | case 2: // 2 parameters, a name and group, in that order | 122 | case 2: // 2 parameters, a name and group, in that order |
| 123 | linda_name = lua_tolstring(L_, -2, &name_len); | 123 | _linda_name = lua_tolstring(L_, -2, &_name_len); |
| 124 | linda_group = LindaGroup{ static_cast<int>(lua_tointeger(L_, -1)) }; | 124 | _linda_group = LindaGroup{ static_cast<int>(lua_tointeger(L_, -1)) }; |
| 125 | break; | 125 | break; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | // The deep data is allocated separately of Lua stack; we might no longer be around when last reference to it is being released. | 128 | // The deep data is allocated separately of Lua stack; we might no longer be around when last reference to it is being released. |
| 129 | // 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 | // 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 |
| 130 | Universe* const U{ universe_get(L_) }; | 130 | Universe* const _U{ universe_get(L_) }; |
| 131 | Linda* const linda{ new (U) Linda{ U, linda_group, linda_name, name_len } }; | 131 | Linda* const _linda{ new (_U) Linda{ _U, _linda_group, _linda_name, _name_len } }; |
| 132 | return linda; | 132 | return _linda; |
| 133 | } | 133 | } |
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index a8738a8..aa81db4 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h | |||
| @@ -61,7 +61,7 @@ template <typename... ARGS> | |||
| 61 | 61 | ||
| 62 | // ################################################################################################# | 62 | // ################################################################################################# |
| 63 | 63 | ||
| 64 | #define USE_DEBUG_SPEW() 1 | 64 | #define USE_DEBUG_SPEW() 0 |
| 65 | #if USE_DEBUG_SPEW() | 65 | #if USE_DEBUG_SPEW() |
| 66 | #define INDENT_BEGIN "%.*s " | 66 | #define INDENT_BEGIN "%.*s " |
| 67 | #define INDENT_END(U_) , (U_ ? U_->debugspewIndentDepth.load(std::memory_order_relaxed) : 0), DebugSpewIndentScope::debugspew_indent | 67 | #define INDENT_END(U_) , (U_ ? U_->debugspewIndentDepth.load(std::memory_order_relaxed) : 0), DebugSpewIndentScope::debugspew_indent |
diff --git a/src/state.cpp b/src/state.cpp index 7252885..563fbc2 100644 --- a/src/state.cpp +++ b/src/state.cpp | |||
| @@ -53,9 +53,8 @@ THE SOFTWARE. | |||
| 53 | // | 53 | // |
| 54 | [[nodiscard]] static int luaG_new_require(lua_State* L_) | 54 | [[nodiscard]] static int luaG_new_require(lua_State* L_) |
| 55 | { | 55 | { |
| 56 | int rc; | 56 | int const _args{ lua_gettop(L_) }; // L_: args |
| 57 | int const args = lua_gettop(L_); // L_: args | 57 | Universe* const _U{ universe_get(L_) }; |
| 58 | Universe* U = universe_get(L_); | ||
| 59 | // char const* modname = luaL_checkstring(L_, 1); | 58 | // char const* modname = luaL_checkstring(L_, 1); |
| 60 | 59 | ||
| 61 | STACK_GROW(L_, 1); | 60 | STACK_GROW(L_, 1); |
| @@ -66,18 +65,18 @@ THE SOFTWARE. | |||
| 66 | // Using 'lua_pcall()' to catch errors; otherwise a failing 'require' would | 65 | // Using 'lua_pcall()' to catch errors; otherwise a failing 'require' would |
| 67 | // leave us locked, blocking any future 'require' calls from other lanes. | 66 | // leave us locked, blocking any future 'require' calls from other lanes. |
| 68 | 67 | ||
| 69 | U->requireMutex.lock(); | 68 | _U->requireMutex.lock(); |
| 70 | // starting with Lua 5.4, require may return a second optional value, so we need LUA_MULTRET | 69 | // starting with Lua 5.4, require may return a second optional value, so we need LUA_MULTRET |
| 71 | rc = lua_pcall(L_, args, LUA_MULTRET, 0 /*errfunc*/); // L_: err|result(s) | 70 | int _rc{ lua_pcall(L_, _args, LUA_MULTRET, 0 /*errfunc*/) }; // L_: err|result(s) |
| 72 | U->requireMutex.unlock(); | 71 | _U->requireMutex.unlock(); |
| 73 | 72 | ||
| 74 | // the required module (or an error message) is left on the stack as returned value by original require function | 73 | // the required module (or an error message) is left on the stack as returned value by original require function |
| 75 | 74 | ||
| 76 | if (rc != LUA_OK) { // LUA_ERRRUN / LUA_ERRMEM ? | 75 | if (_rc != LUA_OK) { // LUA_ERRRUN / LUA_ERRMEM ? |
| 77 | raise_lua_error(L_); | 76 | raise_lua_error(L_); |
| 78 | } | 77 | } |
| 79 | // should be 1 for Lua <= 5.3, 1 or 2 starting with Lua 5.4 | 78 | // should be 1 for Lua <= 5.3, 1 or 2 starting with Lua 5.4 |
| 80 | return lua_gettop(L_); // L_: result(s) | 79 | return lua_gettop(L_); // L_: result(s) |
| 81 | } | 80 | } |
| 82 | 81 | ||
| 83 | // ################################################################################################# | 82 | // ################################################################################################# |
| @@ -149,9 +148,7 @@ namespace global | |||
| 149 | { LUA_JITLIBNAME, luaopen_jit }, | 148 | { LUA_JITLIBNAME, luaopen_jit }, |
| 150 | #endif // LUAJIT_FLAVOR() | 149 | #endif // LUAJIT_FLAVOR() |
| 151 | 150 | ||
| 152 | { kLanesCoreLibName, require_lanes_core }, // So that we can open it like any base library (possible since we have access to the init function) | 151 | { kLanesCoreLibName, require_lanes_core } // So that we can open it like any base library (possible since we have access to the init function) |
| 153 | // | ||
| 154 | { nullptr, nullptr } | ||
| 155 | }; | 152 | }; |
| 156 | 153 | ||
| 157 | } // namespace global | 154 | } // namespace global |
| @@ -160,18 +157,18 @@ namespace global | |||
| 160 | 157 | ||
| 161 | static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, char const* name_, size_t len_) | 158 | static void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, char const* name_, size_t len_) |
| 162 | { | 159 | { |
| 163 | for (int i{ 0 }; global::sLibs[i].name; ++i) { | 160 | for (luaL_Reg const& _entry : global::sLibs) { |
| 164 | if (strncmp(name_, global::sLibs[i].name, len_) == 0) { | 161 | if (strncmp(name_, _entry.name, len_) == 0) { |
| 165 | lua_CFunction const libfunc{ global::sLibs[i].func }; | 162 | lua_CFunction const _libfunc{ _entry.func }; |
| 166 | if (!libfunc) { | 163 | if (!_libfunc) { |
| 167 | continue; | 164 | continue; |
| 168 | } | 165 | } |
| 169 | name_ = global::sLibs[i].name; // note that the provided name_ doesn't necessarily ends with '\0', hence len_ | 166 | name_ = _entry.name; // note that the provided name_ doesn't necessarily ends with '\0', hence len_ |
| 170 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END(U_), (int) len_, name_)); | 167 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END(U_), (int) len_, name_)); |
| 171 | STACK_CHECK_START_REL(L_, 0); | 168 | STACK_CHECK_START_REL(L_, 0); |
| 172 | // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) | 169 | // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) |
| 173 | bool const isLanesCore{ libfunc == require_lanes_core }; // don't want to create a global for "lanes.core" | 170 | bool const isLanesCore{ _libfunc == require_lanes_core }; // don't want to create a global for "lanes.core" |
| 174 | luaL_requiref(L_, name_, libfunc, !isLanesCore); // L_: {lib} | 171 | luaL_requiref(L_, name_, _libfunc, !isLanesCore); // L_: {lib} |
| 175 | // lanes.core doesn't declare a global, so scan it here and now | 172 | // lanes.core doesn't declare a global, so scan it here and now |
| 176 | if (isLanesCore) { | 173 | if (isLanesCore) { |
| 177 | populate_func_lookup_table(L_, -1, name_); | 174 | populate_func_lookup_table(L_, -1, name_); |
| @@ -196,7 +193,7 @@ static inline void open1lib(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, c | |||
| 196 | // just like lua_xmove, args are (from, to) | 193 | // just like lua_xmove, args are (from, to) |
| 197 | static void copy_one_time_settings(Universe* U_, SourceState L1_, DestState L2_) | 194 | static void copy_one_time_settings(Universe* U_, SourceState L1_, DestState L2_) |
| 198 | { | 195 | { |
| 199 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U_ }); | 196 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ U_ }); |
| 200 | 197 | ||
| 201 | STACK_GROW(L1_, 2); | 198 | STACK_GROW(L1_, 2); |
| 202 | STACK_CHECK_START_REL(L1_, 0); | 199 | STACK_CHECK_START_REL(L1_, 0); |
| @@ -206,8 +203,8 @@ static void copy_one_time_settings(Universe* U_, SourceState L1_, DestState L2_) | |||
| 206 | 203 | ||
| 207 | kConfigRegKey.pushValue(L1_); // L1_: config | 204 | kConfigRegKey.pushValue(L1_); // L1_: config |
| 208 | // copy settings from from source to destination registry | 205 | // copy settings from from source to destination registry |
| 209 | InterCopyContext c{ U_, L2_, L1_, {}, {}, {}, {}, {} }; | 206 | InterCopyContext _c{ U_, L2_, L1_, {}, {}, {}, {}, {} }; |
| 210 | if (c.inter_move(1) != InterCopyResult::Success) { // L1_: L2_: config | 207 | if (_c.inter_move(1) != InterCopyResult::Success) { // L1_: L2_: config |
| 211 | raise_luaL_error(L1_, "failed to copy settings when loading " kLanesCoreLibName); | 208 | raise_luaL_error(L1_, "failed to copy settings when loading " kLanesCoreLibName); |
| 212 | } | 209 | } |
| 213 | // set L2:_R[kConfigRegKey] = settings | 210 | // set L2:_R[kConfigRegKey] = settings |
| @@ -227,8 +224,8 @@ void initializeOnStateCreate(Universe* U_, lua_State* L_) | |||
| 227 | U_->onStateCreateFunc = lua_tocfunction(L_, -1); // L_: settings on_state_create | 224 | U_->onStateCreateFunc = lua_tocfunction(L_, -1); // L_: settings on_state_create |
| 228 | if (U_->onStateCreateFunc != nullptr) { | 225 | if (U_->onStateCreateFunc != nullptr) { |
| 229 | // make sure the function doesn't have upvalues | 226 | // make sure the function doesn't have upvalues |
| 230 | char const* upname = lua_getupvalue(L_, -1, 1); // L_: settings on_state_create upval? | 227 | char const* _upname{ lua_getupvalue(L_, -1, 1) }; // L_: settings on_state_create upval? |
| 231 | if (upname != nullptr) { // should be "" for C functions with upvalues if any | 228 | if (_upname != nullptr) { // should be "" for C functions with upvalues if any |
| 232 | raise_luaL_error(L_, "on_state_create shouldn't have upvalues"); | 229 | raise_luaL_error(L_, "on_state_create shouldn't have upvalues"); |
| 233 | } | 230 | } |
| 234 | // remove this C function from the config table so that it doesn't cause problems | 231 | // remove this C function from the config table so that it doesn't cause problems |
| @@ -248,29 +245,29 @@ void initializeOnStateCreate(Universe* U_, lua_State* L_) | |||
| 248 | 245 | ||
| 249 | lua_State* create_state([[maybe_unused]] Universe* U_, lua_State* from_) | 246 | lua_State* create_state([[maybe_unused]] Universe* U_, lua_State* from_) |
| 250 | { | 247 | { |
| 251 | lua_State* L; | 248 | lua_State* _L; |
| 252 | #if LUAJIT_FLAVOR() == 64 | 249 | #if LUAJIT_FLAVOR() == 64 |
| 253 | // for some reason, LuaJIT 64 bits does not support creating a state with lua_newstate... | 250 | // for some reason, LuaJIT 64 bits does not support creating a state with lua_newstate... |
| 254 | L = luaL_newstate(); | 251 | _L = luaL_newstate(); |
| 255 | #else // LUAJIT_FLAVOR() == 64 | 252 | #else // LUAJIT_FLAVOR() == 64 |
| 256 | if (U_->provideAllocator != nullptr) { // we have a function we can call to obtain an allocator | 253 | if (U_->provideAllocator != nullptr) { // we have a function we can call to obtain an allocator |
| 257 | lua_pushcclosure(from_, U_->provideAllocator, 0); | 254 | lua_pushcclosure(from_, U_->provideAllocator, 0); |
| 258 | lua_call(from_, 0, 1); | 255 | lua_call(from_, 0, 1); |
| 259 | { | 256 | { |
| 260 | AllocatorDefinition* const def{ lua_tofulluserdata<AllocatorDefinition>(from_, -1) }; | 257 | AllocatorDefinition* const def{ lua_tofulluserdata<AllocatorDefinition>(from_, -1) }; |
| 261 | L = lua_newstate(def->allocF, def->allocUD); | 258 | _L = lua_newstate(def->allocF, def->allocUD); |
| 262 | } | 259 | } |
| 263 | lua_pop(from_, 1); | 260 | lua_pop(from_, 1); |
| 264 | } else { | 261 | } else { |
| 265 | // reuse the allocator provided when the master state was created | 262 | // reuse the allocator provided when the master state was created |
| 266 | L = lua_newstate(U_->protectedAllocator.allocF, U_->protectedAllocator.allocUD); | 263 | _L = lua_newstate(U_->protectedAllocator.allocF, U_->protectedAllocator.allocUD); |
| 267 | } | 264 | } |
| 268 | #endif // LUAJIT_FLAVOR() == 64 | 265 | #endif // LUAJIT_FLAVOR() == 64 |
| 269 | 266 | ||
| 270 | if (L == nullptr) { | 267 | if (_L == nullptr) { |
| 271 | raise_luaL_error(from_, "luaG_newstate() failed while creating state; out of memory"); | 268 | raise_luaL_error(from_, "luaG_newstate() failed while creating state; out of memory"); |
| 272 | } | 269 | } |
| 273 | return L; | 270 | return _L; |
| 274 | } | 271 | } |
| 275 | 272 | ||
| 276 | // ################################################################################################# | 273 | // ################################################################################################# |
| @@ -321,34 +318,34 @@ void callOnStateCreate(Universe* U_, lua_State* L_, lua_State* from_, LookupMode | |||
| 321 | */ | 318 | */ |
| 322 | lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) | 319 | lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) |
| 323 | { | 320 | { |
| 324 | DestState const L{ create_state(U_, from_) }; | 321 | DestState const _L{ create_state(U_, from_) }; |
| 325 | 322 | ||
| 326 | STACK_GROW(L, 2); | 323 | STACK_GROW(_L, 2); |
| 327 | STACK_CHECK_START_ABS(L, 0); | 324 | STACK_CHECK_START_ABS(_L, 0); |
| 328 | 325 | ||
| 329 | // copy the universe as a light userdata (only the master state holds the full userdata) | 326 | // copy the universe as a light userdata (only the master state holds the full userdata) |
| 330 | // that way, if Lanes is required in this new state, we'll know we are part of this universe | 327 | // that way, if Lanes is required in this new state, we'll know we are part of this universe |
| 331 | universe_store(L, U_); | 328 | universe_store(_L, U_); |
| 332 | STACK_CHECK(L, 0); | 329 | STACK_CHECK(_L, 0); |
| 333 | 330 | ||
| 334 | // we'll need this every time we transfer some C function from/to this state | 331 | // we'll need this every time we transfer some C function from/to this state |
| 335 | kLookupRegKey.setValue(L, [](lua_State* L_) { lua_newtable(L_); }); | 332 | kLookupRegKey.setValue(_L, [](lua_State* L_) { lua_newtable(L_); }); |
| 336 | STACK_CHECK(L, 0); | 333 | STACK_CHECK(_L, 0); |
| 337 | 334 | ||
| 338 | // neither libs (not even 'base') nor special init func: we are done | 335 | // neither libs (not even 'base') nor special init func: we are done |
| 339 | if (libs_ == nullptr && U_->onStateCreateFunc == nullptr) { | 336 | if (libs_ == nullptr && U_->onStateCreateFunc == nullptr) { |
| 340 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "luaG_newstate(nullptr)\n" INDENT_END(U_))); | 337 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "luaG_newstate(nullptr)\n" INDENT_END(U_))); |
| 341 | return L; | 338 | return _L; |
| 342 | } | 339 | } |
| 343 | 340 | ||
| 344 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "luaG_newstate()\n" INDENT_END(U_))); | 341 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "luaG_newstate()\n" INDENT_END(U_))); |
| 345 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U_ }); | 342 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U_ }); |
| 346 | 343 | ||
| 347 | // copy settings (for example because it may contain a Lua on_state_create function) | 344 | // copy settings (for example because it may contain a Lua on_state_create function) |
| 348 | copy_one_time_settings(U_, from_, L); | 345 | copy_one_time_settings(U_, from_, _L); |
| 349 | 346 | ||
| 350 | // 'lua.c' stops GC during initialization so perhaps it is a good idea. :) | 347 | // 'lua.c' stops GC during initialization so perhaps it is a good idea. :) |
| 351 | lua_gc(L, LUA_GCSTOP, 0); | 348 | lua_gc(_L, LUA_GCSTOP, 0); |
| 352 | 349 | ||
| 353 | // Anything causes 'base' to be taken in | 350 | // Anything causes 'base' to be taken in |
| 354 | if (libs_ != nullptr) { | 351 | if (libs_ != nullptr) { |
| @@ -356,24 +353,24 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) | |||
| 356 | // as we are called from luaopen_lanes_core() already, and that would deadlock | 353 | // as we are called from luaopen_lanes_core() already, and that would deadlock |
| 357 | if (libs_[0] == '*' && libs_[1] == 0) { | 354 | if (libs_[0] == '*' && libs_[1] == 0) { |
| 358 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END(U_))); | 355 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END(U_))); |
| 359 | luaL_openlibs(L); | 356 | luaL_openlibs(_L); |
| 360 | // don't forget lanes.core for regular lane states | 357 | // don't forget lanes.core for regular lane states |
| 361 | open1lib(DEBUGSPEW_PARAM_COMMA(U_) L, kLanesCoreLibName); | 358 | open1lib(DEBUGSPEW_PARAM_COMMA(U_) _L, kLanesCoreLibName); |
| 362 | libs_ = nullptr; // done with libs | 359 | libs_ = nullptr; // done with libs |
| 363 | } else { | 360 | } else { |
| 364 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening base library\n" INDENT_END(U_))); | 361 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "opening base library\n" INDENT_END(U_))); |
| 365 | #if LUA_VERSION_NUM >= 502 | 362 | #if LUA_VERSION_NUM >= 502 |
| 366 | // open base library the same way as in luaL_openlibs() | 363 | // open base library the same way as in luaL_openlibs() |
| 367 | luaL_requiref(L, "_G", luaopen_base, 1); | 364 | luaL_requiref(_L, "_G", luaopen_base, 1); |
| 368 | lua_pop(L, 1); | 365 | lua_pop(_L, 1); |
| 369 | #else // LUA_VERSION_NUM | 366 | #else // LUA_VERSION_NUM |
| 370 | lua_pushcfunction(L, luaopen_base); | 367 | lua_pushcfunction(_L, luaopen_base); |
| 371 | lua_pushstring(L, ""); | 368 | lua_pushstring(_L, ""); |
| 372 | lua_call(L, 1, 0); | 369 | lua_call(_L, 1, 0); |
| 373 | #endif // LUA_VERSION_NUM | 370 | #endif // LUA_VERSION_NUM |
| 374 | } | 371 | } |
| 375 | } | 372 | } |
| 376 | STACK_CHECK(L, 0); | 373 | STACK_CHECK(_L, 0); |
| 377 | 374 | ||
| 378 | // scan all libraries, open them one by one | 375 | // scan all libraries, open them one by one |
| 379 | if (libs_) { | 376 | if (libs_) { |
| @@ -387,40 +384,40 @@ lua_State* luaG_newstate(Universe* U_, SourceState from_, char const* libs_) | |||
| 387 | while (isalnum(p[len]) || p[len] == '.') | 384 | while (isalnum(p[len]) || p[len] == '.') |
| 388 | ++len; | 385 | ++len; |
| 389 | // open library | 386 | // open library |
| 390 | open1lib(DEBUGSPEW_PARAM_COMMA(U_) L, p, len); | 387 | open1lib(DEBUGSPEW_PARAM_COMMA(U_) _L, p, len); |
| 391 | } | 388 | } |
| 392 | } | 389 | } |
| 393 | lua_gc(L, LUA_GCRESTART, 0); | 390 | lua_gc(_L, LUA_GCRESTART, 0); |
| 394 | 391 | ||
| 395 | serialize_require(DEBUGSPEW_PARAM_COMMA(U_) L); | 392 | serialize_require(DEBUGSPEW_PARAM_COMMA(U_) _L); |
| 396 | 393 | ||
| 397 | // call this after the base libraries are loaded and GC is restarted | 394 | // call this after the base libraries are loaded and GC is restarted |
| 398 | // will raise an error in from_ in case of problem | 395 | // will raise an error in from_ in case of problem |
| 399 | callOnStateCreate(U_, L, from_, LookupMode::LaneBody); | 396 | callOnStateCreate(U_, _L, from_, LookupMode::LaneBody); |
| 400 | 397 | ||
| 401 | STACK_CHECK(L, 0); | 398 | STACK_CHECK(_L, 0); |
| 402 | // after all this, register everything we find in our name<->function database | 399 | // after all this, register everything we find in our name<->function database |
| 403 | lua_pushglobaltable(L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack | 400 | lua_pushglobaltable(_L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack |
| 404 | STACK_CHECK(L, 1); | 401 | STACK_CHECK(_L, 1); |
| 405 | populate_func_lookup_table(L, -1, nullptr); | 402 | populate_func_lookup_table(_L, -1, nullptr); |
| 406 | 403 | ||
| 407 | #if 1 && USE_DEBUG_SPEW() | 404 | #if 1 && USE_DEBUG_SPEW() |
| 408 | // dump the lookup database contents | 405 | // dump the lookup database contents |
| 409 | kLookupRegKey.pushValue(L); // L: {} | 406 | kLookupRegKey.pushValue(_L); // L: {} |
| 410 | lua_pushnil(L); // L: {} nil | 407 | lua_pushnil(_L); // L: {} nil |
| 411 | while (lua_next(L, -2)) { // L: {} k v | 408 | while (lua_next(_L, -2)) { // L: {} k v |
| 412 | lua_getglobal(L, "print"); // L: {} k v print | 409 | lua_getglobal(_L, "print"); // L: {} k v print |
| 413 | int const indent{ U_->debugspewIndentDepth.load(std::memory_order_relaxed) }; | 410 | int const indent{ U_->debugspewIndentDepth.load(std::memory_order_relaxed) }; |
| 414 | lua_pushlstring(L, DebugSpewIndentScope::debugspew_indent, indent); // L: {} k v print " " | 411 | lua_pushlstring(_L, DebugSpewIndentScope::debugspew_indent, indent); // L: {} k v print " " |
| 415 | lua_pushvalue(L, -4); // L: {} k v print " " k | 412 | lua_pushvalue(_L, -4); // L: {} k v print " " k |
| 416 | lua_pushvalue(L, -4); // L: {} k v print " " k v | 413 | lua_pushvalue(_L, -4); // L: {} k v print " " k v |
| 417 | lua_call(L, 3, 0); // L: {} k v | 414 | lua_call(_L, 3, 0); // L: {} k v |
| 418 | lua_pop(L, 1); // L: {} k | 415 | lua_pop(_L, 1); // L: {} k |
| 419 | } | 416 | } |
| 420 | lua_pop(L, 1); // L: {} | 417 | lua_pop(_L, 1); // L: {} |
| 421 | #endif // USE_DEBUG_SPEW() | 418 | #endif // USE_DEBUG_SPEW() |
| 422 | 419 | ||
| 423 | lua_pop(L, 1); | 420 | lua_pop(_L, 1); |
| 424 | STACK_CHECK(L, 0); | 421 | STACK_CHECK(_L, 0); |
| 425 | return L; | 422 | return _L; |
| 426 | } | 423 | } |
diff --git a/src/tools.cpp b/src/tools.cpp index 2623da6..0cfe1ab 100644 --- a/src/tools.cpp +++ b/src/tools.cpp | |||
| @@ -69,16 +69,16 @@ static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull }; | |||
| 69 | return FuncSubType::Native; | 69 | return FuncSubType::Native; |
| 70 | } | 70 | } |
| 71 | { | 71 | { |
| 72 | int mustpush{ 0 }; | 72 | int _mustpush{ 0 }; |
| 73 | if (lua_absindex(L_, _i) != lua_gettop(L_)) { | 73 | if (lua_absindex(L_, _i) != lua_gettop(L_)) { |
| 74 | lua_pushvalue(L_, _i); | 74 | lua_pushvalue(L_, _i); |
| 75 | mustpush = 1; | 75 | _mustpush = 1; |
| 76 | } | 76 | } |
| 77 | // the provided writer fails with code 666 | 77 | // the provided writer fails with code 666 |
| 78 | // therefore, anytime we get 666, this means that lua_dump() attempted a dump | 78 | // therefore, anytime we get 666, this means that lua_dump() attempted a dump |
| 79 | // all other cases mean this is either a C or LuaJIT-fast function | 79 | // all other cases mean this is either a C or LuaJIT-fast function |
| 80 | int const dumpres{ lua504_dump(L_, dummy_writer, nullptr, 0) }; | 80 | int const dumpres{ lua504_dump(L_, dummy_writer, nullptr, 0) }; |
| 81 | lua_pop(L_, mustpush); | 81 | lua_pop(L_, _mustpush); |
| 82 | if (dumpres == 666) { | 82 | if (dumpres == 666) { |
| 83 | return FuncSubType::Bytecode; | 83 | return FuncSubType::Bytecode; |
| 84 | } | 84 | } |
| @@ -91,22 +91,22 @@ static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull }; | |||
| 91 | // inspired from tconcat() in ltablib.c | 91 | // inspired from tconcat() in ltablib.c |
| 92 | [[nodiscard]] static char const* luaG_pushFQN(lua_State* L_, int t_, int last_, size_t* length_) | 92 | [[nodiscard]] static char const* luaG_pushFQN(lua_State* L_, int t_, int last_, size_t* length_) |
| 93 | { | 93 | { |
| 94 | luaL_Buffer b; | 94 | luaL_Buffer _b; |
| 95 | STACK_CHECK_START_REL(L_, 0); | 95 | STACK_CHECK_START_REL(L_, 0); |
| 96 | // Lua 5.4 pushes &b as light userdata on the stack. be aware of it... | 96 | // Lua 5.4 pushes &b as light userdata on the stack. be aware of it... |
| 97 | luaL_buffinit(L_, &b); // L_: ... {} ... &b? | 97 | luaL_buffinit(L_, &_b); // L_: ... {} ... &b? |
| 98 | int i = 1; | 98 | int i = 1; |
| 99 | for (; i < last_; ++i) { | 99 | for (; i < last_; ++i) { |
| 100 | lua_rawgeti(L_, t_, i); | 100 | lua_rawgeti(L_, t_, i); |
| 101 | luaL_addvalue(&b); | 101 | luaL_addvalue(&_b); |
| 102 | luaL_addlstring(&b, "/", 1); | 102 | luaL_addlstring(&_b, "/", 1); |
| 103 | } | 103 | } |
| 104 | if (i == last_) { // add last value (if interval was not empty) | 104 | if (i == last_) { // add last value (if interval was not empty) |
| 105 | lua_rawgeti(L_, t_, i); | 105 | lua_rawgeti(L_, t_, i); |
| 106 | luaL_addvalue(&b); | 106 | luaL_addvalue(&_b); |
| 107 | } | 107 | } |
| 108 | // &b is popped at that point (-> replaced by the result) | 108 | // &b is popped at that point (-> replaced by the result) |
| 109 | luaL_pushresult(&b); // L_: ... {} ... "<result>" | 109 | luaL_pushresult(&_b); // L_: ... {} ... "<result>" |
| 110 | STACK_CHECK(L_, 1); | 110 | STACK_CHECK(L_, 1); |
| 111 | return lua_tolstring(L_, -1, length_); | 111 | return lua_tolstring(L_, -1, length_); |
| 112 | } | 112 | } |
| @@ -124,28 +124,28 @@ static constexpr RegistryUniqueKey kLookupCacheRegKey{ 0x9BF75F84E54B691Bull }; | |||
| 124 | static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, int ctxBase_, int depth_) | 124 | static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L_, int ctxBase_, int depth_) |
| 125 | { | 125 | { |
| 126 | // slot 1 in the stack contains the table that receives everything we found | 126 | // slot 1 in the stack contains the table that receives everything we found |
| 127 | int const dest{ ctxBase_ }; | 127 | int const _dest{ ctxBase_ }; |
| 128 | // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i | 128 | // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i |
| 129 | int const fqn{ ctxBase_ + 1 }; | 129 | int const _fqn{ ctxBase_ + 1 }; |
| 130 | 130 | ||
| 131 | size_t prevNameLength, newNameLength; | 131 | DEBUGSPEW_CODE(char const* _newName); |
| 132 | char const* prevName; | ||
| 133 | DEBUGSPEW_CODE(char const* newName); | ||
| 134 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "update_lookup_entry()\n" INDENT_END(U_))); | 132 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "update_lookup_entry()\n" INDENT_END(U_))); |
| 135 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U_ }); | 133 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U_ }); |
| 136 | 134 | ||
| 137 | STACK_CHECK_START_REL(L_, 0); | 135 | STACK_CHECK_START_REL(L_, 0); |
| 138 | // first, raise an error if the function is already known | 136 | // first, raise an error if the function is already known |
| 139 | lua_pushvalue(L_, -1); // L_: ... {bfc} k o o | 137 | lua_pushvalue(L_, -1); // L_: ... {bfc} k o o |
| 140 | lua_rawget(L_, dest); // L_: ... {bfc} k o name? | 138 | lua_rawget(L_, _dest); // L_: ... {bfc} k o name? |
| 141 | prevName = lua_tolstring(L_, -1, &prevNameLength); // nullptr if we got nil (first encounter of this object) | 139 | size_t _prevNameLength; |
| 140 | char const* const _prevName{ lua_tolstring(L_, -1, &_prevNameLength) }; // nullptr if we got nil (first encounter of this object) | ||
| 142 | // push name in fqn stack (note that concatenation will crash if name is a not string or a number) | 141 | // push name in fqn stack (note that concatenation will crash if name is a not string or a number) |
| 143 | lua_pushvalue(L_, -3); // L_: ... {bfc} k o name? k | 142 | lua_pushvalue(L_, -3); // L_: ... {bfc} k o name? k |
| 144 | LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER || lua_type(L_, -1) == LUA_TSTRING); | 143 | LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER || lua_type(L_, -1) == LUA_TSTRING); |
| 145 | ++depth_; | 144 | ++depth_; |
| 146 | lua_rawseti(L_, fqn, depth_); // L_: ... {bfc} k o name? | 145 | lua_rawseti(L_, _fqn, depth_); // L_: ... {bfc} k o name? |
| 147 | // generate name | 146 | // generate name |
| 148 | DEBUGSPEW_OR_NOT(newName, std::ignore) = luaG_pushFQN(L_, fqn, depth_, &newNameLength); // L_: ... {bfc} k o name? "f.q.n" | 147 | size_t _newNameLength; |
| 148 | DEBUGSPEW_OR_NOT(_newName, std::ignore) = luaG_pushFQN(L_, _fqn, depth_, &_newNameLength); // L_: ... {bfc} k o name? "f.q.n" | ||
| 149 | // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order | 149 | // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order |
| 150 | // on different VMs even when the tables are populated the exact same way. | 150 | // on different VMs even when the tables are populated the exact same way. |
| 151 | // When Lua is built with compatibility options (such as LUA_COMPAT_ALL), | 151 | // When Lua is built with compatibility options (such as LUA_COMPAT_ALL), |
| @@ -155,34 +155,34 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA(Universe* U_) lua_State* L | |||
| 155 | // Also, nothing prevents any external module from exposing a given object under several names, so... | 155 | // Also, nothing prevents any external module from exposing a given object under several names, so... |
| 156 | // Therefore, when we encounter an object for which a name was previously registered, we need to select the names | 156 | // Therefore, when we encounter an object for which a name was previously registered, we need to select the names |
| 157 | // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded | 157 | // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded |
| 158 | if (prevName != nullptr && (prevNameLength < newNameLength || lua_lessthan(L_, -2, -1))) { | 158 | if (_prevName != nullptr && (_prevNameLength < _newNameLength || lua_lessthan(L_, -2, -1))) { |
| 159 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%s '%s' remained named '%s'\n" INDENT_END(U_), lua_typename(L_, lua_type(L_, -3)), newName, prevName)); | 159 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%s '%s' remained named '%s'\n" INDENT_END(U_), lua_typename(L_, lua_type(L_, -3)), _newName, _prevName)); |
| 160 | // the previous name is 'smaller' than the one we just generated: keep it! | 160 | // the previous name is 'smaller' than the one we just generated: keep it! |
| 161 | lua_pop(L_, 3); // L_: ... {bfc} k | 161 | lua_pop(L_, 3); // L_: ... {bfc} k |
| 162 | } else { | 162 | } else { |
| 163 | // the name we generated is either the first one, or a better fit for our purposes | 163 | // the name we generated is either the first one, or a better fit for our purposes |
| 164 | if (prevName) { | 164 | if (_prevName) { |
| 165 | // clear the previous name for the database to avoid clutter | 165 | // clear the previous name for the database to avoid clutter |
| 166 | lua_insert(L_, -2); // L_: ... {bfc} k o "f.q.n" prevName | 166 | lua_insert(L_, -2); // L_: ... {bfc} k o "f.q.n" prevName |
| 167 | // t[prevName] = nil | 167 | // t[prevName] = nil |
| 168 | lua_pushnil(L_); // L_: ... {bfc} k o "f.q.n" prevName nil | 168 | lua_pushnil(L_); // L_: ... {bfc} k o "f.q.n" prevName nil |
| 169 | lua_rawset(L_, dest); // L_: ... {bfc} k o "f.q.n" | 169 | lua_rawset(L_, _dest); // L_: ... {bfc} k o "f.q.n" |
| 170 | } else { | 170 | } else { |
| 171 | lua_remove(L_, -2); // L_: ... {bfc} k o "f.q.n" | 171 | lua_remove(L_, -2); // L_: ... {bfc} k o "f.q.n" |
| 172 | } | 172 | } |
| 173 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%s '%s'\n" INDENT_END(U_), lua_typename(L_, lua_type(L_, -2)), newName)); | 173 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%s '%s'\n" INDENT_END(U_), lua_typename(L_, lua_type(L_, -2)), _newName)); |
| 174 | // prepare the stack for database feed | 174 | // prepare the stack for database feed |
| 175 | lua_pushvalue(L_, -1); // L_: ... {bfc} k o "f.q.n" "f.q.n" | 175 | lua_pushvalue(L_, -1); // L_: ... {bfc} k o "f.q.n" "f.q.n" |
| 176 | lua_pushvalue(L_, -3); // L_: ... {bfc} k o "f.q.n" "f.q.n" o | 176 | lua_pushvalue(L_, -3); // L_: ... {bfc} k o "f.q.n" "f.q.n" o |
| 177 | LUA_ASSERT(L_, lua_rawequal(L_, -1, -4)); | 177 | LUA_ASSERT(L_, lua_rawequal(L_, -1, -4)); |
| 178 | LUA_ASSERT(L_, lua_rawequal(L_, -2, -3)); | 178 | LUA_ASSERT(L_, lua_rawequal(L_, -2, -3)); |
| 179 | // t["f.q.n"] = o | 179 | // t["f.q.n"] = o |
| 180 | lua_rawset(L_, dest); // L_: ... {bfc} k o "f.q.n" | 180 | lua_rawset(L_, _dest); // L_: ... {bfc} k o "f.q.n" |
| 181 | // t[o] = "f.q.n" | 181 | // t[o] = "f.q.n" |
| 182 | lua_rawset(L_, dest); // L_: ... {bfc} k | 182 | lua_rawset(L_, _dest); // L_: ... {bfc} k |
| 183 | // remove table name from fqn stack | 183 | // remove table name from fqn stack |
| 184 | lua_pushnil(L_); // L_: ... {bfc} k nil | 184 | lua_pushnil(L_); // L_: ... {bfc} k nil |
| 185 | lua_rawseti(L_, fqn, depth_); // L_: ... {bfc} k | 185 | lua_rawseti(L_, _fqn, depth_); // L_: ... {bfc} k |
| 186 | } | 186 | } |
| 187 | --depth_; | 187 | --depth_; |
| 188 | STACK_CHECK(L_, -1); | 188 | STACK_CHECK(L_, -1); |
| @@ -194,9 +194,9 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U_) | |||
| 194 | { | 194 | { |
| 195 | // slot dbIdx_ contains the lookup database table | 195 | // slot dbIdx_ contains the lookup database table |
| 196 | // slot dbIdx_ + 1 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot i_ | 196 | // slot dbIdx_ + 1 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot i_ |
| 197 | int const fqn{ dbIdx_ + 1 }; | 197 | int const _fqn{ dbIdx_ + 1 }; |
| 198 | // slot dbIdx_ + 2 contains a cache that stores all already visited tables to avoid infinite recursion loops | 198 | // slot dbIdx_ + 2 contains a cache that stores all already visited tables to avoid infinite recursion loops |
| 199 | int const cache{ dbIdx_ + 2 }; | 199 | int const _cache{ dbIdx_ + 2 }; |
| 200 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "populate_func_lookup_table_recur()\n" INDENT_END(U_))); | 200 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "populate_func_lookup_table_recur()\n" INDENT_END(U_))); |
| 201 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U_ }); | 201 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U_ }); |
| 202 | 202 | ||
| @@ -212,19 +212,19 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U_) | |||
| 212 | 212 | ||
| 213 | // if table is already visited, we are done | 213 | // if table is already visited, we are done |
| 214 | lua_pushvalue(L_, i_); // L_: ... {i_} {} | 214 | lua_pushvalue(L_, i_); // L_: ... {i_} {} |
| 215 | lua_rawget(L_, cache); // L_: ... {i_} nil|n | 215 | lua_rawget(L_, _cache); // L_: ... {i_} nil|n |
| 216 | lua_Integer visit_count{ lua_tointeger(L_, -1) }; // 0 if nil, else n | 216 | lua_Integer _visit_count{ lua_tointeger(L_, -1) }; // 0 if nil, else n |
| 217 | lua_pop(L_, 1); // L_: ... {i_} | 217 | lua_pop(L_, 1); // L_: ... {i_} |
| 218 | STACK_CHECK(L_, 0); | 218 | STACK_CHECK(L_, 0); |
| 219 | if (visit_count > 0) { | 219 | if (_visit_count > 0) { |
| 220 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "already visited\n" INDENT_END(U_))); | 220 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "already visited\n" INDENT_END(U_))); |
| 221 | return; | 221 | return; |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | // remember we visited this table (1-visit count) | 224 | // remember we visited this table (1-visit count) |
| 225 | lua_pushvalue(L_, i_); // L_: ... {i_} {} | 225 | lua_pushvalue(L_, i_); // L_: ... {i_} {} |
| 226 | lua_pushinteger(L_, visit_count + 1); // L_: ... {i_} {} 1 | 226 | lua_pushinteger(L_, _visit_count + 1); // L_: ... {i_} {} 1 |
| 227 | lua_rawset(L_, cache); // L_: ... {i_} | 227 | lua_rawset(L_, _cache); // L_: ... {i_} |
| 228 | STACK_CHECK(L_, 0); | 228 | STACK_CHECK(L_, 0); |
| 229 | 229 | ||
| 230 | // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search) | 230 | // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search) |
| @@ -240,11 +240,11 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U_) | |||
| 240 | // increment visit count to make sure we will actually scan it at this recursive level | 240 | // increment visit count to make sure we will actually scan it at this recursive level |
| 241 | lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} | 241 | lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} |
| 242 | lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} {} | 242 | lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} {} |
| 243 | lua_rawget(L_, cache); // L_: ... {i_} {bfc} k {} {} n? | 243 | lua_rawget(L_, _cache); // L_: ... {i_} {bfc} k {} {} n? |
| 244 | visit_count = lua_tointeger(L_, -1) + 1; // 1 if we got nil, else n+1 | 244 | _visit_count = lua_tointeger(L_, -1) + 1; // 1 if we got nil, else n+1 |
| 245 | lua_pop(L_, 1); // L_: ... {i_} {bfc} k {} {} | 245 | lua_pop(L_, 1); // L_: ... {i_} {bfc} k {} {} |
| 246 | lua_pushinteger(L_, visit_count); // L_: ... {i_} {bfc} k {} {} n | 246 | lua_pushinteger(L_, _visit_count); // L_: ... {i_} {bfc} k {} {} n |
| 247 | lua_rawset(L_, cache); // L_: ... {i_} {bfc} k {} | 247 | lua_rawset(L_, _cache); // L_: ... {i_} {bfc} k {} |
| 248 | // store the table in the breadth-first cache | 248 | // store the table in the breadth-first cache |
| 249 | lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k | 249 | lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k |
| 250 | lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k {} | 250 | lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k {} |
| @@ -269,27 +269,27 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U_) | |||
| 269 | DEBUGSPEW_CODE(DebugSpewIndentScope scope2{ U_ }); | 269 | DEBUGSPEW_CODE(DebugSpewIndentScope scope2{ U_ }); |
| 270 | // un-visit this table in case we do need to process it | 270 | // un-visit this table in case we do need to process it |
| 271 | lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} | 271 | lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} |
| 272 | lua_rawget(L_, cache); // L_: ... {i_} {bfc} k {} n | 272 | lua_rawget(L_, _cache); // L_: ... {i_} {bfc} k {} n |
| 273 | LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER); | 273 | LUA_ASSERT(L_, lua_type(L_, -1) == LUA_TNUMBER); |
| 274 | visit_count = lua_tointeger(L_, -1) - 1; | 274 | _visit_count = lua_tointeger(L_, -1) - 1; |
| 275 | lua_pop(L_, 1); // L_: ... {i_} {bfc} k {} | 275 | lua_pop(L_, 1); // L_: ... {i_} {bfc} k {} |
| 276 | lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} | 276 | lua_pushvalue(L_, -1); // L_: ... {i_} {bfc} k {} {} |
| 277 | if (visit_count > 0) { | 277 | if (_visit_count > 0) { |
| 278 | lua_pushinteger(L_, visit_count); // L_: ... {i_} {bfc} k {} {} n | 278 | lua_pushinteger(L_, _visit_count); // L_: ... {i_} {bfc} k {} {} n |
| 279 | } else { | 279 | } else { |
| 280 | lua_pushnil(L_); // L_: ... {i_} {bfc} k {} {} nil | 280 | lua_pushnil(L_); // L_: ... {i_} {bfc} k {} {} nil |
| 281 | } | 281 | } |
| 282 | lua_rawset(L_, cache); // L_: ... {i_} {bfc} k {} | 282 | lua_rawset(L_, _cache); // L_: ... {i_} {bfc} k {} |
| 283 | // push table name in fqn stack (note that concatenation will crash if name is a not string!) | 283 | // push table name in fqn stack (note that concatenation will crash if name is a not string!) |
| 284 | lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k | 284 | lua_pushvalue(L_, -2); // L_: ... {i_} {bfc} k {} k |
| 285 | lua_rawseti(L_, fqn, depth_); // L_: ... {i_} {bfc} k {} | 285 | lua_rawseti(L_, _fqn, depth_); // L_: ... {i_} {bfc} k {} |
| 286 | populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U_) L_, dbIdx_, lua_gettop(L_), depth_); | 286 | populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U_) L_, dbIdx_, lua_gettop(L_), depth_); |
| 287 | lua_pop(L_, 1); // L_: ... {i_} {bfc} k | 287 | lua_pop(L_, 1); // L_: ... {i_} {bfc} k |
| 288 | STACK_CHECK(L_, 2); | 288 | STACK_CHECK(L_, 2); |
| 289 | } | 289 | } |
| 290 | // remove table name from fqn stack | 290 | // remove table name from fqn stack |
| 291 | lua_pushnil(L_); // L_: ... {i_} {bfc} nil | 291 | lua_pushnil(L_); // L_: ... {i_} {bfc} nil |
| 292 | lua_rawseti(L_, fqn, depth_); // L_: ... {i_} {bfc} | 292 | lua_rawseti(L_, _fqn, depth_); // L_: ... {i_} {bfc} |
| 293 | --depth_; | 293 | --depth_; |
| 294 | // we are done with our cache | 294 | // we are done with our cache |
| 295 | lua_pop(L_, 1); // L_: ... {i_} | 295 | lua_pop(L_, 1); // L_: ... {i_} |
| @@ -302,46 +302,46 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U_) | |||
| 302 | // create a "fully.qualified.name" <-> function equivalence database | 302 | // create a "fully.qualified.name" <-> function equivalence database |
| 303 | void populate_func_lookup_table(lua_State* L_, int i_, char const* name_) | 303 | void populate_func_lookup_table(lua_State* L_, int i_, char const* name_) |
| 304 | { | 304 | { |
| 305 | int const in_base = lua_absindex(L_, i_); | 305 | int const _in_base = lua_absindex(L_, i_); |
| 306 | DEBUGSPEW_CODE(Universe* U = universe_get(L_)); | 306 | DEBUGSPEW_CODE(Universe* _U = universe_get(L_)); |
| 307 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END(U), L_, name_ ? name_ : "nullptr")); | 307 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END(_U), L_, name_ ? name_ : "nullptr")); |
| 308 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); | 308 | DEBUGSPEW_CODE(DebugSpewIndentScope _scope{ _U }); |
| 309 | STACK_GROW(L_, 3); | 309 | STACK_GROW(L_, 3); |
| 310 | STACK_CHECK_START_REL(L_, 0); | 310 | STACK_CHECK_START_REL(L_, 0); |
| 311 | kLookupRegKey.pushValue(L_); // L_: {} | 311 | kLookupRegKey.pushValue(L_); // L_: {} |
| 312 | int const dbIdx{ lua_gettop(L_) }; | 312 | int const _dbIdx{ lua_gettop(L_) }; |
| 313 | STACK_CHECK(L_, 1); | 313 | STACK_CHECK(L_, 1); |
| 314 | LUA_ASSERT(L_, lua_istable(L_, -1)); | 314 | LUA_ASSERT(L_, lua_istable(L_, -1)); |
| 315 | if (lua_type(L_, in_base) == LUA_TFUNCTION) { // for example when a module is a simple function | 315 | if (lua_type(L_, _in_base) == LUA_TFUNCTION) { // for example when a module is a simple function |
| 316 | name_ = name_ ? name_ : "nullptr"; | 316 | name_ = name_ ? name_ : "nullptr"; |
| 317 | lua_pushvalue(L_, in_base); // L_: {} f | 317 | lua_pushvalue(L_, _in_base); // L_: {} f |
| 318 | lua_pushstring(L_, name_); // L_: {} f _name | 318 | lua_pushstring(L_, name_); // L_: {} f _name |
| 319 | lua_rawset(L_, -3); // L_: {} | 319 | lua_rawset(L_, -3); // L_: {} |
| 320 | lua_pushstring(L_, name_); // L_: {} _name | 320 | lua_pushstring(L_, name_); // L_: {} _name |
| 321 | lua_pushvalue(L_, in_base); // L_: {} _name f | 321 | lua_pushvalue(L_, _in_base); // L_: {} _name f |
| 322 | lua_rawset(L_, -3); // L_: {} | 322 | lua_rawset(L_, -3); // L_: {} |
| 323 | lua_pop(L_, 1); // L_: | 323 | lua_pop(L_, 1); // L_: |
| 324 | } else if (lua_type(L_, in_base) == LUA_TTABLE) { | 324 | } else if (lua_type(L_, _in_base) == LUA_TTABLE) { |
| 325 | lua_newtable(L_); // L_: {} {fqn} | 325 | lua_newtable(L_); // L_: {} {fqn} |
| 326 | int startDepth{ 0 }; | 326 | int _startDepth{ 0 }; |
| 327 | if (name_) { | 327 | if (name_) { |
| 328 | STACK_CHECK(L_, 2); | 328 | STACK_CHECK(L_, 2); |
| 329 | lua_pushstring(L_, name_); // L_: {} {fqn} "name" | 329 | lua_pushstring(L_, name_); // L_: {} {fqn} "name" |
| 330 | // generate a name, and if we already had one name, keep whichever is the shorter | 330 | // generate a name, and if we already had one name, keep whichever is the shorter |
| 331 | lua_pushvalue(L_, in_base); // L_: {} {fqn} "name" t | 331 | lua_pushvalue(L_, _in_base); // L_: {} {fqn} "name" t |
| 332 | update_lookup_entry(DEBUGSPEW_PARAM_COMMA(U) L_, dbIdx, startDepth); // L_: {} {fqn} "name" | 332 | update_lookup_entry(DEBUGSPEW_PARAM_COMMA(_U) L_, _dbIdx, _startDepth); // L_: {} {fqn} "name" |
| 333 | // don't forget to store the name at the bottom of the fqn stack | 333 | // don't forget to store the name at the bottom of the fqn stack |
| 334 | lua_rawseti(L_, -2, ++startDepth); // L_: {} {fqn} | 334 | lua_rawseti(L_, -2, ++_startDepth); // L_: {} {fqn} |
| 335 | STACK_CHECK(L_, 2); | 335 | STACK_CHECK(L_, 2); |
| 336 | } | 336 | } |
| 337 | // retrieve the cache, create it if we haven't done it yet | 337 | // retrieve the cache, create it if we haven't done it yet |
| 338 | std::ignore = kLookupCacheRegKey.getSubTable(L_, 0, 0); // L_: {} {fqn} {cache} | 338 | std::ignore = kLookupCacheRegKey.getSubTable(L_, 0, 0); // L_: {} {fqn} {cache} |
| 339 | // process everything we find in that table, filling in lookup data for all functions and tables we see there | 339 | // process everything we find in that table, filling in lookup data for all functions and tables we see there |
| 340 | populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(U) L_, dbIdx, in_base, startDepth); | 340 | populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(_U) L_, _dbIdx, _in_base, _startDepth); |
| 341 | lua_pop(L_, 3); // L_: | 341 | lua_pop(L_, 3); // L_: |
| 342 | } else { | 342 | } else { |
| 343 | lua_pop(L_, 1); // L_: | 343 | lua_pop(L_, 1); // L_: |
| 344 | raise_luaL_error(L_, "unsupported module type %s", lua_typename(L_, lua_type(L_, in_base))); | 344 | raise_luaL_error(L_, "unsupported module type %s", lua_typename(L_, lua_type(L_, _in_base))); |
| 345 | } | 345 | } |
| 346 | STACK_CHECK(L_, 0); | 346 | STACK_CHECK(L_, 0); |
| 347 | } | 347 | } |
| @@ -484,9 +484,9 @@ void populate_func_lookup_table(lua_State* L_, int i_, char const* name_) | |||
| 484 | // "type", "name" = lanes.nameof(o) | 484 | // "type", "name" = lanes.nameof(o) |
| 485 | int luaG_nameof(lua_State* L_) | 485 | int luaG_nameof(lua_State* L_) |
| 486 | { | 486 | { |
| 487 | int const what{ lua_gettop(L_) }; | 487 | int const _what{ lua_gettop(L_) }; |
| 488 | if (what > 1) { | 488 | if (_what > 1) { |
| 489 | raise_luaL_argerror(L_, what, "too many arguments."); | 489 | raise_luaL_argerror(L_, _what, "too many arguments."); |
| 490 | } | 490 | } |
| 491 | 491 | ||
| 492 | // nil, boolean, light userdata, number and string aren't identifiable | 492 | // nil, boolean, light userdata, number and string aren't identifiable |
diff --git a/src/universe.cpp b/src/universe.cpp index a5c28f0..f05cc6f 100644 --- a/src/universe.cpp +++ b/src/universe.cpp | |||
| @@ -68,13 +68,13 @@ Universe::Universe() | |||
| 68 | [[nodiscard]] Universe* universe_create(lua_State* L_) | 68 | [[nodiscard]] Universe* universe_create(lua_State* L_) |
| 69 | { | 69 | { |
| 70 | LUA_ASSERT(L_, universe_get(L_) == nullptr); | 70 | LUA_ASSERT(L_, universe_get(L_) == nullptr); |
| 71 | Universe* const U{ lua_newuserdatauv<Universe>(L_, 0) }; // universe | 71 | Universe* const _U{ lua_newuserdatauv<Universe>(L_, 0) }; // universe |
| 72 | U->Universe::Universe(); | 72 | _U->Universe::Universe(); |
| 73 | STACK_CHECK_START_REL(L_, 1); | 73 | STACK_CHECK_START_REL(L_, 1); |
| 74 | kUniverseFullRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); | 74 | kUniverseFullRegKey.setValue(L_, [](lua_State* L_) { lua_pushvalue(L_, -2); }); |
| 75 | kUniverseLightRegKey.setValue(L_, [U](lua_State* L_) { lua_pushlightuserdata(L_, U); }); | 75 | kUniverseLightRegKey.setValue(L_, [U = _U](lua_State* L_) { lua_pushlightuserdata(L_, U); }); |
| 76 | STACK_CHECK(L_, 1); | 76 | STACK_CHECK(L_, 1); |
| 77 | return U; | 77 | return _U; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | // ################################################################################################# | 80 | // ################################################################################################# |
| @@ -84,22 +84,22 @@ void Universe::terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTim | |||
| 84 | if (selfdestructFirst != SELFDESTRUCT_END) { | 84 | if (selfdestructFirst != SELFDESTRUCT_END) { |
| 85 | // Signal _all_ still running threads to exit (including the timer thread) | 85 | // Signal _all_ still running threads to exit (including the timer thread) |
| 86 | { | 86 | { |
| 87 | std::lock_guard<std::mutex> guard{ selfdestructMutex }; | 87 | std::lock_guard<std::mutex> _guard{ selfdestructMutex }; |
| 88 | Lane* lane{ selfdestructFirst }; | 88 | Lane* _lane{ selfdestructFirst }; |
| 89 | while (lane != SELFDESTRUCT_END) { | 89 | while (_lane != SELFDESTRUCT_END) { |
| 90 | // attempt the requested cancel with a small timeout. | 90 | // attempt the requested cancel with a small timeout. |
| 91 | // if waiting on a linda, they will raise a cancel_error. | 91 | // if waiting on a linda, they will raise a cancel_error. |
| 92 | // if a cancellation hook is desired, it will be installed to try to raise an error | 92 | // if a cancellation hook is desired, it will be installed to try to raise an error |
| 93 | if (lane->thread.joinable()) { | 93 | if (_lane->thread.joinable()) { |
| 94 | std::ignore = thread_cancel(lane, op_, 1, std::chrono::steady_clock::now() + 1us, true); | 94 | std::ignore = thread_cancel(_lane, op_, 1, std::chrono::steady_clock::now() + 1us, true); |
| 95 | } | 95 | } |
| 96 | lane = lane->selfdestruct_next; | 96 | _lane = _lane->selfdestruct_next; |
| 97 | } | 97 | } |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | // When noticing their cancel, the lanes will remove themselves from the selfdestruct chain. | 100 | // When noticing their cancel, the lanes will remove themselves from the selfdestruct chain. |
| 101 | { | 101 | { |
| 102 | std::chrono::time_point<std::chrono::steady_clock> t_until{ std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(shutdownTimeout_) }; | 102 | std::chrono::time_point<std::chrono::steady_clock> _until{ std::chrono::steady_clock::now() + std::chrono::duration_cast<std::chrono::steady_clock::duration>(shutdownTimeout_) }; |
| 103 | 103 | ||
| 104 | while (selfdestructFirst != SELFDESTRUCT_END) { | 104 | while (selfdestructFirst != SELFDESTRUCT_END) { |
| 105 | // give threads time to act on their cancel | 105 | // give threads time to act on their cancel |
| @@ -107,17 +107,17 @@ void Universe::terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTim | |||
| 107 | // count the number of cancelled thread that didn't have the time to act yet | 107 | // count the number of cancelled thread that didn't have the time to act yet |
| 108 | int n{ 0 }; | 108 | int n{ 0 }; |
| 109 | { | 109 | { |
| 110 | std::lock_guard<std::mutex> guard{ selfdestructMutex }; | 110 | std::lock_guard<std::mutex> _guard{ selfdestructMutex }; |
| 111 | Lane* lane{ selfdestructFirst }; | 111 | Lane* _lane{ selfdestructFirst }; |
| 112 | while (lane != SELFDESTRUCT_END) { | 112 | while (_lane != SELFDESTRUCT_END) { |
| 113 | if (lane->cancelRequest != CancelRequest::None) | 113 | if (_lane->cancelRequest != CancelRequest::None) |
| 114 | ++n; | 114 | ++n; |
| 115 | lane = lane->selfdestruct_next; | 115 | _lane = _lane->selfdestruct_next; |
| 116 | } | 116 | } |
| 117 | } | 117 | } |
| 118 | // if timeout elapsed, or we know all threads have acted, stop waiting | 118 | // if timeout elapsed, or we know all threads have acted, stop waiting |
| 119 | std::chrono::time_point<std::chrono::steady_clock> t_now = std::chrono::steady_clock::now(); | 119 | std::chrono::time_point<std::chrono::steady_clock> _now = std::chrono::steady_clock::now(); |
| 120 | if (n == 0 || (t_now >= t_until)) { | 120 | if (n == 0 || (_now >= _until)) { |
| 121 | DEBUGSPEW_CODE(fprintf(stderr, "%d uncancelled lane(s) remain after waiting %fs at process end.\n", n, shutdownTimeout_.count())); | 121 | DEBUGSPEW_CODE(fprintf(stderr, "%d uncancelled lane(s) remain after waiting %fs at process end.\n", n, shutdownTimeout_.count())); |
| 122 | break; | 122 | break; |
| 123 | } | 123 | } |
| @@ -133,11 +133,11 @@ void Universe::terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTim | |||
| 133 | 133 | ||
| 134 | // If after all this, we still have some free-running lanes, it's an external user error, they should have stopped appropriately | 134 | // If after all this, we still have some free-running lanes, it's an external user error, they should have stopped appropriately |
| 135 | { | 135 | { |
| 136 | std::lock_guard<std::mutex> guard{ selfdestructMutex }; | 136 | std::lock_guard<std::mutex> _guard{ selfdestructMutex }; |
| 137 | Lane* lane{ selfdestructFirst }; | 137 | Lane* _lane{ selfdestructFirst }; |
| 138 | if (lane != SELFDESTRUCT_END) { | 138 | if (_lane != SELFDESTRUCT_END) { |
| 139 | // this causes a leak because we don't call U's destructor (which could be bad if the still running lanes are accessing it) | 139 | // this causes a leak because we don't call U's destructor (which could be bad if the still running lanes are accessing it) |
| 140 | raise_luaL_error(L_, "Zombie thread %s refuses to die!", lane->debugName); | 140 | raise_luaL_error(L_, "Zombie thread %s refuses to die!", _lane->debugName); |
| 141 | } | 141 | } |
| 142 | } | 142 | } |
| 143 | } | 143 | } |
| @@ -147,25 +147,25 @@ void Universe::terminateFreeRunningLanes(lua_State* L_, lua_Duration shutdownTim | |||
| 147 | // process end: cancel any still free-running threads | 147 | // process end: cancel any still free-running threads |
| 148 | int universe_gc(lua_State* L_) | 148 | int universe_gc(lua_State* L_) |
| 149 | { | 149 | { |
| 150 | lua_Duration const shutdown_timeout{ lua_tonumber(L_, lua_upvalueindex(1)) }; | 150 | lua_Duration const _shutdown_timeout{ lua_tonumber(L_, lua_upvalueindex(1)) }; |
| 151 | [[maybe_unused]] char const* const op_string{ lua_tostring(L_, lua_upvalueindex(2)) }; | 151 | [[maybe_unused]] char const* const _op_string{ lua_tostring(L_, lua_upvalueindex(2)) }; |
| 152 | Universe* const U{ lua_tofulluserdata<Universe>(L_, 1) }; | 152 | Universe* const _U{ lua_tofulluserdata<Universe>(L_, 1) }; |
| 153 | U->terminateFreeRunningLanes(L_, shutdown_timeout, which_cancel_op(op_string)); | 153 | _U->terminateFreeRunningLanes(L_, _shutdown_timeout, which_cancel_op(_op_string)); |
| 154 | 154 | ||
| 155 | // no need to mutex-protect this as all threads in the universe are gone at that point | 155 | // no need to mutex-protect this as all threads in the universe are gone at that point |
| 156 | if (U->timerLinda != nullptr) { // test in case some early internal error prevented Lanes from creating the deep timer | 156 | if (_U->timerLinda != nullptr) { // test in case some early internal error prevented Lanes from creating the deep timer |
| 157 | [[maybe_unused]] int const prev_ref_count{ U->timerLinda->refcount.fetch_sub(1, std::memory_order_relaxed) }; | 157 | [[maybe_unused]] int const prev_ref_count{ _U->timerLinda->refcount.fetch_sub(1, std::memory_order_relaxed) }; |
| 158 | LUA_ASSERT(L_, prev_ref_count == 1); // this should be the last reference | 158 | LUA_ASSERT(L_, prev_ref_count == 1); // this should be the last reference |
| 159 | DeepFactory::DeleteDeepObject(L_, U->timerLinda); | 159 | DeepFactory::DeleteDeepObject(L_, _U->timerLinda); |
| 160 | U->timerLinda = nullptr; | 160 | _U->timerLinda = nullptr; |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | close_keepers(U); | 163 | close_keepers(_U); |
| 164 | 164 | ||
| 165 | // remove the protected allocator, if any | 165 | // remove the protected allocator, if any |
| 166 | U->protectedAllocator.removeFrom(L_); | 166 | _U->protectedAllocator.removeFrom(L_); |
| 167 | 167 | ||
| 168 | U->Universe::~Universe(); | 168 | _U->Universe::~Universe(); |
| 169 | 169 | ||
| 170 | return 0; | 170 | return 0; |
| 171 | } | 171 | } |
