diff options
Diffstat (limited to 'src/lane.cpp')
-rw-r--r-- | src/lane.cpp | 74 |
1 files changed, 37 insertions, 37 deletions
diff --git a/src/lane.cpp b/src/lane.cpp index 4c33afb..57e3454 100644 --- a/src/lane.cpp +++ b/src/lane.cpp | |||
@@ -346,20 +346,20 @@ LUAG_FUNC(thread_index) | |||
346 | // LUA_ERRERR doesn't have the same value | 346 | // LUA_ERRERR doesn't have the same value |
347 | struct errcode_name | 347 | struct errcode_name |
348 | { | 348 | { |
349 | int code; | 349 | LuaError code; |
350 | char const* name; | 350 | char const* name; |
351 | }; | 351 | }; |
352 | 352 | ||
353 | static struct errcode_name s_errcodes[] = { | 353 | static struct errcode_name s_errcodes[] = { |
354 | { LUA_OK, "LUA_OK" }, | 354 | { LuaError::OK, "LUA_OK" }, |
355 | { LUA_YIELD, "LUA_YIELD" }, | 355 | { LuaError::YIELD, "LUA_YIELD" }, |
356 | { LUA_ERRRUN, "LUA_ERRRUN" }, | 356 | { LuaError::ERRRUN, "LUA_ERRRUN" }, |
357 | { LUA_ERRSYNTAX, "LUA_ERRSYNTAX" }, | 357 | { LuaError::ERRSYNTAX, "LUA_ERRSYNTAX" }, |
358 | { LUA_ERRMEM, "LUA_ERRMEM" }, | 358 | { LuaError::ERRMEM, "LUA_ERRMEM" }, |
359 | { LUA_ERRGCMM, "LUA_ERRGCMM" }, | 359 | { LuaError::ERRGCMM, "LUA_ERRGCMM" }, |
360 | { LUA_ERRERR, "LUA_ERRERR" }, | 360 | { LuaError::ERRERR, "LUA_ERRERR" }, |
361 | }; | 361 | }; |
362 | static char const* get_errcode_name(int _code) | 362 | static char const* get_errcode_name(LuaError _code) |
363 | { | 363 | { |
364 | for (errcode_name const& _entry : s_errcodes) { | 364 | for (errcode_name const& _entry : s_errcodes) { |
365 | if (_entry.code == _code) { | 365 | if (_entry.code == _code) { |
@@ -464,14 +464,14 @@ static constexpr RegistryUniqueKey kStackTraceRegKey{ 0x3F327747CACAA904ull }; | |||
464 | // ########################################## Finalizer ############################################ | 464 | // ########################################## Finalizer ############################################ |
465 | // ################################################################################################# | 465 | // ################################################################################################# |
466 | 466 | ||
467 | static void push_stack_trace(lua_State* L_, int rc_, int stk_base_) | 467 | static void push_stack_trace(lua_State* L_, LuaError rc_, int stk_base_) |
468 | { | 468 | { |
469 | // Lua 5.1 error handler is limited to one return value; it stored the stack trace in the registry | 469 | // Lua 5.1 error handler is limited to one return value; it stored the stack trace in the registry |
470 | switch (rc_) { | 470 | switch (rc_) { |
471 | case LUA_OK: // no error, body return values are on the stack | 471 | case LuaError::OK: // no error, body return values are on the stack |
472 | break; | 472 | break; |
473 | 473 | ||
474 | case LUA_ERRRUN: // cancellation or a runtime error | 474 | case LuaError::ERRRUN: // cancellation or a runtime error |
475 | #if ERROR_FULL_STACK // when ERROR_FULL_STACK, we installed a handler | 475 | #if ERROR_FULL_STACK // when ERROR_FULL_STACK, we installed a handler |
476 | { | 476 | { |
477 | STACK_CHECK_START_REL(L_, 0); | 477 | STACK_CHECK_START_REL(L_, 0); |
@@ -491,8 +491,8 @@ static void push_stack_trace(lua_State* L_, int rc_, int stk_base_) | |||
491 | [[fallthrough]]; // fall through if not ERROR_FULL_STACK | 491 | [[fallthrough]]; // fall through if not ERROR_FULL_STACK |
492 | #endif // !ERROR_FULL_STACK | 492 | #endif // !ERROR_FULL_STACK |
493 | 493 | ||
494 | case LUA_ERRMEM: // memory allocation error (handler not called) | 494 | case LuaError::ERRMEM: // memory allocation error (handler not called) |
495 | case LUA_ERRERR: // error while running the error handler (if any, for example an out-of-memory condition) | 495 | case LuaError::ERRERR: // error while running the error handler (if any, for example an out-of-memory condition) |
496 | default: | 496 | default: |
497 | // we should have a single value which is either a string (the error message) or kCancelError | 497 | // we should have a single value which is either a string (the error message) or kCancelError |
498 | LUA_ASSERT(L_, (lua_gettop(L_) == stk_base_) && ((lua_type(L_, stk_base_) == LUA_TSTRING) || kCancelError.equals(L_, stk_base_))); | 498 | LUA_ASSERT(L_, (lua_gettop(L_) == stk_base_) && ((lua_type(L_, stk_base_) == LUA_TSTRING) || kCancelError.equals(L_, stk_base_))); |
@@ -515,12 +515,12 @@ static void push_stack_trace(lua_State* L_, int rc_, int stk_base_) | |||
515 | // TBD: should we add stack trace on failing finalizer, wouldn't be hard.. | 515 | // TBD: should we add stack trace on failing finalizer, wouldn't be hard.. |
516 | // | 516 | // |
517 | 517 | ||
518 | [[nodiscard]] static int run_finalizers(lua_State* L_, int lua_rc_) | 518 | [[nodiscard]] static LuaError run_finalizers(lua_State* L_, LuaError lua_rc_) |
519 | { | 519 | { |
520 | kFinalizerRegKey.pushValue(L_); // L_: ... finalizers? | 520 | kFinalizerRegKey.pushValue(L_); // L_: ... finalizers? |
521 | if (lua_isnil(L_, -1)) { | 521 | if (lua_isnil(L_, -1)) { |
522 | lua_pop(L_, 1); | 522 | lua_pop(L_, 1); |
523 | return 0; // no finalizers | 523 | return LuaError::OK; // no finalizers |
524 | } | 524 | } |
525 | 525 | ||
526 | STACK_GROW(L_, 5); | 526 | STACK_GROW(L_, 5); |
@@ -528,13 +528,13 @@ static void push_stack_trace(lua_State* L_, int rc_, int stk_base_) | |||
528 | int const _finalizers_index{ lua_gettop(L_) }; | 528 | int const _finalizers_index{ lua_gettop(L_) }; |
529 | int const _err_handler_index{ ERROR_FULL_STACK ? (lua_pushcfunction(L_, lane_error), lua_gettop(L_)) : 0 }; | 529 | int const _err_handler_index{ ERROR_FULL_STACK ? (lua_pushcfunction(L_, lane_error), lua_gettop(L_)) : 0 }; |
530 | 530 | ||
531 | int rc{ LUA_OK }; | 531 | LuaError _rc{ LuaError::OK }; |
532 | for (int n = static_cast<int>(lua_rawlen(L_, _finalizers_index)); n > 0; --n) { | 532 | for (int _n = static_cast<int>(lua_rawlen(L_, _finalizers_index)); _n > 0; --_n) { |
533 | int args = 0; | 533 | int _args{ 0 }; |
534 | lua_pushinteger(L_, n); // L_: ... finalizers lane_error n | 534 | lua_pushinteger(L_, _n); // L_: ... finalizers lane_error n |
535 | lua_rawget(L_, _finalizers_index); // L_: ... finalizers lane_error finalizer | 535 | lua_rawget(L_, _finalizers_index); // L_: ... finalizers lane_error finalizer |
536 | LUA_ASSERT(L_, lua_isfunction(L_, -1)); | 536 | LUA_ASSERT(L_, lua_isfunction(L_, -1)); |
537 | if (lua_rc_ != LUA_OK) { // we have an error message and an optional stack trace at the bottom of the stack | 537 | if (lua_rc_ != LuaError::OK) { // we have an error message and an optional stack trace at the bottom of the stack |
538 | LUA_ASSERT(L_, _finalizers_index == 2 || _finalizers_index == 3); | 538 | LUA_ASSERT(L_, _finalizers_index == 2 || _finalizers_index == 3); |
539 | // char const* err_msg = lua_tostring(L_, 1); | 539 | // char const* err_msg = lua_tostring(L_, 1); |
540 | lua_pushvalue(L_, 1); // L_: ... finalizers lane_error finalizer err_msg | 540 | lua_pushvalue(L_, 1); // L_: ... finalizers lane_error finalizer err_msg |
@@ -542,13 +542,13 @@ static void push_stack_trace(lua_State* L_, int rc_, int stk_base_) | |||
542 | if (_finalizers_index == 3) { | 542 | if (_finalizers_index == 3) { |
543 | lua_pushvalue(L_, 2); // L_: ... finalizers lane_error finalizer err_msg stack_trace | 543 | lua_pushvalue(L_, 2); // L_: ... finalizers lane_error finalizer err_msg stack_trace |
544 | } | 544 | } |
545 | args = _finalizers_index - 1; | 545 | _args = _finalizers_index - 1; |
546 | } | 546 | } |
547 | 547 | ||
548 | // if no error from the main body, finalizer doesn't receive any argument, else it gets the error message and optional stack trace | 548 | // if no error from the main body, finalizer doesn't receive any argument, else it gets the error message and optional stack trace |
549 | rc = lua_pcall(L_, args, 0, _err_handler_index); // L_: ... finalizers lane_error err_msg2? | 549 | _rc = ToLuaError(lua_pcall(L_, _args, 0, _err_handler_index)); // L_: ... finalizers lane_error err_msg2? |
550 | if (rc != LUA_OK) { | 550 | if (_rc != LuaError::OK) { |
551 | push_stack_trace(L_, rc, lua_gettop(L_)); // L_: ... finalizers lane_error err_msg2? trace | 551 | push_stack_trace(L_, _rc, lua_gettop(L_)); // L_: ... finalizers lane_error err_msg2? trace |
552 | // If one finalizer fails, don't run the others. Return this | 552 | // If one finalizer fails, don't run the others. Return this |
553 | // as the 'real' error, replacing what we could have had (or not) | 553 | // as the 'real' error, replacing what we could have had (or not) |
554 | // from the actual code. | 554 | // from the actual code. |
@@ -557,20 +557,20 @@ static void push_stack_trace(lua_State* L_, int rc_, int stk_base_) | |||
557 | // no error, proceed to next finalizer // L_: ... finalizers lane_error | 557 | // no error, proceed to next finalizer // L_: ... finalizers lane_error |
558 | } | 558 | } |
559 | 559 | ||
560 | if (rc != LUA_OK) { | 560 | if (_rc != LuaError::OK) { |
561 | // ERROR_FULL_STACK accounts for the presence of lane_error on the stack | 561 | // ERROR_FULL_STACK accounts for the presence of lane_error on the stack |
562 | int const nb_err_slots{ lua_gettop(L_) - _finalizers_index - ERROR_FULL_STACK }; | 562 | int const _nb_err_slots{ lua_gettop(L_) - _finalizers_index - ERROR_FULL_STACK }; |
563 | // a finalizer generated an error, this is what we leave of the stack | 563 | // a finalizer generated an error, this is what we leave of the stack |
564 | for (int n = nb_err_slots; n > 0; --n) { | 564 | for (int _n = _nb_err_slots; _n > 0; --_n) { |
565 | lua_replace(L_, n); | 565 | lua_replace(L_, _n); |
566 | } | 566 | } |
567 | // leave on the stack only the error and optional stack trace produced by the error in the finalizer | 567 | // leave on the stack only the error and optional stack trace produced by the error in the finalizer |
568 | lua_settop(L_, nb_err_slots); // L_: ... lane_error trace | 568 | lua_settop(L_, _nb_err_slots); // L_: ... lane_error trace |
569 | } else { // no error from the finalizers, make sure only the original return values from the lane body remain on the stack | 569 | } else { // no error from the finalizers, make sure only the original return values from the lane body remain on the stack |
570 | lua_settop(L_, _finalizers_index - 1); | 570 | lua_settop(L_, _finalizers_index - 1); |
571 | } | 571 | } |
572 | 572 | ||
573 | return rc; | 573 | return _rc; |
574 | } | 574 | } |
575 | 575 | ||
576 | // ################################################################################################# | 576 | // ################################################################################################# |
@@ -627,7 +627,7 @@ static void lane_main(Lane* lane_) | |||
627 | lua_State* const _L{ lane_->L }; | 627 | lua_State* const _L{ lane_->L }; |
628 | // wait until the launching thread has finished preparing L | 628 | // wait until the launching thread has finished preparing L |
629 | lane_->ready.wait(); | 629 | lane_->ready.wait(); |
630 | int _rc{ LUA_ERRRUN }; | 630 | LuaError _rc{ LuaError::ERRRUN }; |
631 | if (lane_->status == Lane::Pending) { // nothing wrong happened during preparation, we can work | 631 | if (lane_->status == Lane::Pending) { // nothing wrong happened during preparation, we can work |
632 | // At this point, the lane function and arguments are on the stack | 632 | // At this point, the lane function and arguments are on the stack |
633 | int const nargs{ lua_gettop(_L) - 1 }; | 633 | int const nargs{ lua_gettop(_L) - 1 }; |
@@ -662,7 +662,7 @@ static void lane_main(Lane* lane_) | |||
662 | lua_insert(_L, 1); // L: handler func args | 662 | lua_insert(_L, 1); // L: handler func args |
663 | #endif // L: ERROR_FULL_STACK | 663 | #endif // L: ERROR_FULL_STACK |
664 | 664 | ||
665 | _rc = lua_pcall(_L, nargs, LUA_MULTRET, ERROR_FULL_STACK); // L: retvals|err | 665 | _rc = ToLuaError(lua_pcall(_L, nargs, LUA_MULTRET, ERROR_FULL_STACK)); // L: retvals|err |
666 | 666 | ||
667 | #if ERROR_FULL_STACK | 667 | #if ERROR_FULL_STACK |
668 | lua_remove(_L, 1); // L: retvals|error | 668 | lua_remove(_L, 1); // L: retvals|error |
@@ -674,9 +674,9 @@ static void lane_main(Lane* lane_) | |||
674 | 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)))); | 674 | 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)))); |
675 | // Call finalizers, if the script has set them up. | 675 | // Call finalizers, if the script has set them up. |
676 | // | 676 | // |
677 | int _rc2{ run_finalizers(_L, _rc) }; | 677 | LuaError const _rc2{ run_finalizers(_L, _rc) }; |
678 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "Lane %p finalizer: %s\n" INDENT_END(_U), _L, get_errcode_name(_rc2))); | 678 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "Lane %p finalizer: %s\n" INDENT_END(_U), _L, get_errcode_name(_rc2))); |
679 | if (_rc2 != LUA_OK) { // Error within a finalizer! | 679 | if (_rc2 != LuaError::OK) { // Error within a finalizer! |
680 | // the finalizer generated an error, and left its own error message [and stack trace] on the stack | 680 | // the finalizer generated an error, and left its own error message [and stack trace] on the stack |
681 | _rc = _rc2; // we're overruling the earlier script error or normal return | 681 | _rc = _rc2; // we're overruling the earlier script error or normal return |
682 | } | 682 | } |
@@ -699,11 +699,11 @@ static void lane_main(Lane* lane_) | |||
699 | if (lane_) { | 699 | if (lane_) { |
700 | // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them | 700 | // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them |
701 | 701 | ||
702 | Lane::Status const _st = (_rc == LUA_OK) ? Lane::Done : kCancelError.equals(_L, 1) ? Lane::Cancelled : Lane::Error; | 702 | Lane::Status const _st{ (_rc == LuaError::OK) ? Lane::Done : kCancelError.equals(_L, 1) ? Lane::Cancelled : Lane::Error }; |
703 | 703 | ||
704 | { | 704 | { |
705 | // 'doneMutex' protects the -> Done|Error|Cancelled state change | 705 | // 'doneMutex' protects the -> Done|Error|Cancelled state change |
706 | std::lock_guard lock{ lane_->doneMutex }; | 706 | std::lock_guard _guard{ lane_->doneMutex }; |
707 | lane_->status = _st; | 707 | lane_->status = _st; |
708 | lane_->doneCondVar.notify_one(); // wake up master (while 'lane_->doneMutex' is on) | 708 | lane_->doneCondVar.notify_one(); // wake up master (while 'lane_->doneMutex' is on) |
709 | } | 709 | } |