From 4a2705af8a9a6b55cf848d53f8330447138a19c4 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Fri, 26 Apr 2024 17:15:12 +0200 Subject: C++ migration: wrap all Lua error raising API functions in a [[noreturn]] raise_... equivalent --- deep_test/deep_test.cpp | 6 ++--- src/cancel.cpp | 8 +++---- src/cancel.h | 2 +- src/deep.cpp | 12 +++++----- src/keeper.cpp | 10 ++++---- src/lanes.cpp | 48 ++++++++++++++++++------------------- src/linda.cpp | 16 ++++++------- src/macros_and_utils.h | 64 +++++++++++++++++++++++++++++++++++++++---------- src/state.cpp | 8 +++---- src/tools.cpp | 50 +++++++++++++++++++------------------- 10 files changed, 131 insertions(+), 93 deletions(-) diff --git a/deep_test/deep_test.cpp b/deep_test/deep_test.cpp index 1931e6d..77ecefb 100644 --- a/deep_test/deep_test.cpp +++ b/deep_test/deep_test.cpp @@ -178,20 +178,20 @@ struct MyClonableUserdata // this is all we need to make a userdata lanes-clonable. no dependency on Lanes code. [[nodiscard]] static int clonable_lanesclone(lua_State* L) { - switch( lua_gettop( L)) + switch( lua_gettop(L)) { case 3: { MyClonableUserdata* self = static_cast(lua_touserdata(L, 1)); MyClonableUserdata* from = static_cast(lua_touserdata(L, 2)); - size_t len = lua_tointeger( L, 3); + size_t len = lua_tointeger(L, 3); assert( len == sizeof(MyClonableUserdata)); *self = *from; } return 0; default: - (void) luaL_error( L, "Lanes called clonable_lanesclone with unexpected parameters"); + raise_luaL_error(L, "Lanes called clonable_lanesclone with unexpected parameters"); } return 0; } diff --git a/src/cancel.cpp b/src/cancel.cpp index 0ec5eb5..cff1443 100644 --- a/src/cancel.cpp +++ b/src/cancel.cpp @@ -213,7 +213,7 @@ CancelOp which_cancel_op(char const* op_string_) lua_remove(L, idx_); // argument is processed, remove it if (op == CancelOp::Invalid) { - luaL_error(L, "invalid hook option %s", str); // doesn't return + raise_luaL_error(L, "invalid hook option %s", str); } return op; } @@ -235,7 +235,7 @@ LUAG_FUNC(thread_cancel) lua_remove(L, 2); // argument is processed, remove it if (hook_count < 1) { - return luaL_error(L, "hook count cannot be < 1"); // doesn't return + raise_luaL_error(L, "hook count cannot be < 1"); } } @@ -246,7 +246,7 @@ LUAG_FUNC(thread_cancel) lua_remove(L, 2); // argument is processed, remove it if (wait_timeout.count() < 0.0) { - return luaL_error(L, "cancel timeout cannot be < 0"); // doesn't return + raise_luaL_error(L, "cancel timeout cannot be < 0"); } } // we wake by default in "hard" mode (remember that hook is hard too), but this can be turned off if desired @@ -255,7 +255,7 @@ LUAG_FUNC(thread_cancel) { if (!lua_isboolean(L, 2)) { - return luaL_error(L, "wake_lindas parameter is not a boolean"); // doesn't return + raise_luaL_error(L, "wake_lindas parameter is not a boolean"); } wake_lane = lua_toboolean(L, 2); lua_remove(L, 2); // argument is processed, remove it diff --git a/src/cancel.h b/src/cancel.h index d5c3f7b..bbc7787 100644 --- a/src/cancel.h +++ b/src/cancel.h @@ -54,7 +54,7 @@ static constexpr UniqueKey kCancelError{ 0x0630345FEF912746ull, "lanes.cancel_er { STACK_GROW(L, 1); kCancelError.pushKey(L); // special error value - raise_lua_error(L); // doesn't return + raise_lua_error(L); } // ################################################################################################# diff --git a/src/deep.cpp b/src/deep.cpp index d7efe68..5a62000 100644 --- a/src/deep.cpp +++ b/src/deep.cpp @@ -351,14 +351,14 @@ int DeepFactory::pushDeepUserdata(DestState L, int nuv_) const DeepPrelude* const prelude{ newDeepObjectInternal(L) }; if (prelude == nullptr) { - return luaL_error( L, "DeepFactory::newDeepObjectInternal failed to create deep userdata (out of memory)"); + raise_luaL_error(L, "DeepFactory::newDeepObjectInternal failed to create deep userdata (out of memory)"); } if (prelude->m_magic != kDeepVersion) { // just in case, don't leak the newly allocated deep userdata object deleteDeepObjectInternal(L, prelude); - return luaL_error( L, "Bad Deep Factory: kDeepVersion is incorrect, rebuild your implementation with the latest deep implementation"); + raise_luaL_error(L, "Bad Deep Factory: kDeepVersion is incorrect, rebuild your implementation with the latest deep implementation"); } LUA_ASSERT(L, prelude->m_refcount.load(std::memory_order_relaxed) == 0); // 'DeepFactory::PushDeepProxy' will lift it to 1 @@ -368,13 +368,13 @@ int DeepFactory::pushDeepUserdata(DestState L, int nuv_) const { // just in case, don't leak the newly allocated deep userdata object deleteDeepObjectInternal(L, prelude); - return luaL_error(L, "Bad DeepFactory::newDeepObjectInternal overload: should not push anything on the stack"); + raise_luaL_error(L, "Bad DeepFactory::newDeepObjectInternal overload: should not push anything on the stack"); } char const* const errmsg{ DeepFactory::PushDeepProxy(L, prelude, nuv_, LookupMode::LaneBody) }; // proxy if (errmsg != nullptr) { - return luaL_error( L, errmsg); + raise_luaL_error(L, errmsg); } STACK_CHECK( L, 1); return 1; @@ -443,7 +443,7 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L, int index) const c.L1_i = SourceIndex{ lua_absindex(L1, -1) }; if (!c.inter_copy_one()) // u uv { - luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); // doesn't return + raise_luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); } lua_pop(L1, 1); // ... u [uv]* // this pops the value from the stack @@ -459,7 +459,7 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L, int index) const { // raise the error in the proper state (not the keeper) lua_State* const errL{ (mode == LookupMode::FromKeeper) ? L2 : L1 }; - luaL_error(errL, errmsg); // doesn't return + raise_luaL_error(errL, errmsg); } return true; } \ No newline at end of file diff --git a/src/keeper.cpp b/src/keeper.cpp index 682d70d..51f6388 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp @@ -660,7 +660,7 @@ void init_keepers(Universe* U, lua_State* L) lua_pop(L, 1); // settings if (nb_keepers < 1) { - luaL_error(L, "Bad number of keepers (%d)", nb_keepers); // doesn't return + raise_luaL_error(L, "Bad number of keepers (%d)", nb_keepers); } STACK_CHECK(L, 0); @@ -675,7 +675,7 @@ void init_keepers(Universe* U, lua_State* L) U->keepers = static_cast(U->internal_allocator.alloc(bytes)); if (U->keepers == nullptr) { - luaL_error(L, "init_keepers() failed while creating keeper array; out of memory"); // doesn't return + raise_luaL_error(L, "init_keepers() failed while creating keeper array; out of memory"); } U->keepers->Keepers::Keepers(); U->keepers->gc_threshold = keepers_gc_threshold; @@ -692,7 +692,7 @@ void init_keepers(Universe* U, lua_State* L) KeeperState const K{ create_state(U, L) }; if (K == nullptr) { - luaL_error(L, "init_keepers() failed while creating keeper states; out of memory"); // doesn't return + raise_luaL_error(L, "init_keepers() failed while creating keeper states; out of memory"); } U->keepers->keeper_array[i].L = K; @@ -829,7 +829,7 @@ KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t func_, lua { // func_ linda args... lua_call(K, 1 + args, LUA_MULTRET); // result... int const retvals{ lua_gettop(K) - top_K }; - // note that this can raise a luaL_error while the keeper state (and its mutex) is acquired + // note that this can raise a lua error while the keeper state (and its mutex) is acquired // this may interrupt a lane, causing the destruction of the underlying OS thread // after this, another lane making use of this keeper can get an error code from the mutex-locking function // when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread) @@ -862,7 +862,7 @@ KeeperCallResult keeper_call(Universe* U, KeeperState K, keeper_api_t func_, lua int const gc_usage_after{ lua_gc(K, LUA_GCCOUNT, 0) }; if (gc_usage_after > gc_threshold) [[unlikely]] { - luaL_error(L, "Keeper GC threshold is too low, need at least %d", gc_usage_after); + raise_luaL_error(L, "Keeper GC threshold is too low, need at least %d", gc_usage_after); } } } diff --git a/src/lanes.cpp b/src/lanes.cpp index d907fcd..e150eea 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp @@ -556,7 +556,7 @@ static void selfdestruct_add(Lane* lane_) if (lane != SELFDESTRUCT_END) { // this causes a leak because we don't call U's destructor (which could be bad if the still running lanes are accessing it) - luaL_error(L, "Zombie thread %s refuses to die!", lane->debug_name); // doesn't return + raise_luaL_error(L, "Zombie thread %s refuses to die!", lane->debug_name); } } @@ -600,16 +600,16 @@ LUAG_FUNC( set_singlethreaded) #ifdef _UTILBINDTHREADTOCPU if (cores > 1) { - return luaL_error(L, "Limiting to N>1 cores not possible"); + raise_luaL_error(L, "Limiting to N>1 cores not possible"); } // requires 'chudInitialize()' utilBindThreadToCPU(0); // # of CPU to run on (we cannot limit to 2..N CPUs?) return 0; #else - return luaL_error(L, "Not available: compile with _UTILBINDTHREADTOCPU"); + raise_luaL_error(L, "Not available: compile with _UTILBINDTHREADTOCPU"); #endif #else - return luaL_error(L, "not implemented"); + raise_luaL_error(L, "not implemented"); #endif } @@ -645,7 +645,7 @@ LUAG_FUNC( set_error_reporting) bool const basic{ strcmp(mode, "basic") == 0 }; if (!extended && !basic) { - return luaL_error(L, "unsupported error reporting model %s", mode); + raise_luaL_error(L, "unsupported error reporting model %s", mode); } kExtendedStackTraceRegKey.setValue(L, [extended](lua_State* L) { lua_pushboolean(L, extended ? 1 : 0); }); @@ -769,7 +769,7 @@ LUAG_FUNC(set_thread_priority) // On some platforms, -3 is equivalent to -2 and +3 to +2 if (prio < kThreadPrioMin || prio > kThreadPrioMax) { - return luaL_error(L, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, prio); + raise_luaL_error(L, "priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, prio); } THREAD_SET_PRIORITY(static_cast(prio), universe_get(L)->m_sudo); return 0; @@ -782,7 +782,7 @@ LUAG_FUNC(set_thread_affinity) lua_Integer const affinity{ luaL_checkinteger(L, 1) }; if (affinity <= 0) { - return luaL_error(L, "invalid affinity (%d)", affinity); + raise_luaL_error(L, "invalid affinity (%d)", affinity); } THREAD_SET_AFFINITY( static_cast(affinity)); return 0; @@ -994,7 +994,7 @@ LUAG_FUNC(lane_new) // On some platforms, -3 is equivalent to -2 and +3 to +2 if (have_priority && (priority < kThreadPrioMin || priority > kThreadPrioMax)) { - return luaL_error(L, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, priority); + raise_luaL_error(L, "Priority out of range: %d..+%d (%d)", kThreadPrioMin, kThreadPrioMax, priority); } /* --- Create and prepare the sub state --- */ @@ -1007,7 +1007,7 @@ LUAG_FUNC(lane_new) Lane* const lane{ new (U) Lane{ U, L2 } }; if (lane == nullptr) { - return luaL_error(L, "could not create lane: out of memory"); + raise_luaL_error(L, "could not create lane: out of memory"); } class OnExit @@ -1125,7 +1125,7 @@ LUAG_FUNC(lane_new) // should not happen, was checked in lanes.lua before calling lane_new() if (lua_type(L, required_idx) != LUA_TTABLE) { - luaL_error(L, "expected required module list as a table, got %s", luaL_typename(L, required_idx)); // doesn't return + raise_luaL_error(L, "expected required module list as a table, got %s", luaL_typename(L, required_idx)); } lua_pushnil(L); // func libs priority globals package required gc_cb [... args ...] nil @@ -1133,7 +1133,7 @@ LUAG_FUNC(lane_new) { if (lua_type(L, -1) != LUA_TSTRING || lua_type(L, -2) != LUA_TNUMBER || lua_tonumber(L, -2) != nbRequired) { - luaL_error(L, "required module list should be a list of strings"); // doesn't return + raise_luaL_error(L, "required module list should be a list of strings"); } else { @@ -1147,7 +1147,7 @@ LUAG_FUNC(lane_new) if (lua_isnil( L2, -1)) { lua_pop( L2, 1); // - luaL_error(L, "cannot pre-require modules without loading 'package' library first"); // doesn't return + raise_luaL_error(L, "cannot pre-require modules without loading 'package' library first"); } else { @@ -1179,7 +1179,7 @@ LUAG_FUNC(lane_new) DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lane_new: transfer globals\n" INDENT_END)); if (!lua_istable(L, globals_idx)) { - luaL_error(L, "Expected table, got %s", luaL_typename(L, globals_idx)); // doesn't return + raise_luaL_error(L, "Expected table, got %s", luaL_typename(L, globals_idx)); } DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); @@ -1210,7 +1210,7 @@ LUAG_FUNC(lane_new) InterCopyResult const res{ c.inter_move(1) }; // func libs priority globals package required gc_cb [... args ...] // func if (res != InterCopyResult::Success) { - luaL_error(L, "tried to copy unsupported types"); // doesn't return + raise_luaL_error(L, "tried to copy unsupported types"); } } else if (func_type == LuaType::STRING) @@ -1219,12 +1219,12 @@ LUAG_FUNC(lane_new) // compile the string if (luaL_loadstring(L2, lua_tostring(L, 1)) != 0) // func { - luaL_error(L, "error when parsing lane function code"); // doesn't return + raise_luaL_error(L, "error when parsing lane function code"); } } else { - luaL_error(L, "Expected function, got %s", lua_typename(L, func_type)); // doesn't return + raise_luaL_error(L, "Expected function, got %s", lua_typename(L, func_type)); } STACK_CHECK(L, 0); STACK_CHECK(L2, 1); @@ -1239,7 +1239,7 @@ LUAG_FUNC(lane_new) InterCopyResult const res{ c.inter_move(nargs) }; // func libs priority globals package required gc_cb // func [... args ...] if (res != InterCopyResult::Success) { - luaL_error(L, "tried to copy unsupported types"); // doesn't return + raise_luaL_error(L, "tried to copy unsupported types"); } } STACK_CHECK(L, -nargs); @@ -1405,7 +1405,7 @@ LUAG_FUNC(thread_join) (InterCopyContext{ U, DestState{ L }, SourceState{ L2 }, {}, {}, {}, {}, {} }.inter_move(n) != InterCopyResult::Success) ) { - luaL_error(L, "tried to copy unsupported types"); // doesn't return + raise_luaL_error(L, "tried to copy unsupported types"); } ret = n; } @@ -1420,7 +1420,7 @@ LUAG_FUNC(thread_join) InterCopyContext c{ U, DestState{ L }, SourceState{ L2 }, {}, {}, {}, {}, {} }; if (c.inter_move(n) != InterCopyResult::Success) // nil "err" [trace] { - luaL_error(L, "tried to copy unsupported types: %s", lua_tostring(L, -n)); // doesn't return + raise_luaL_error(L, "tried to copy unsupported types: %s", lua_tostring(L, -n)); } ret = 1 + n; } @@ -1580,7 +1580,7 @@ LUAG_FUNC(thread_index) // only "cancel" and "join" are registered as functions, any other string will raise an error if (!lua_iscfunction(L, -1)) { - luaL_error(L, "can't index a lane with '%s'", keystr); // doesn't return + raise_luaL_error(L, "can't index a lane with '%s'", keystr); } return 1; } @@ -1818,7 +1818,7 @@ LUAG_FUNC(configure) char const* errmsg{ DeepFactory::PushDeepProxy(DestState{ L }, U->timer_deep, 0, LookupMode::LaneBody) }; // settings M timer_deep if (errmsg != nullptr) { - return luaL_error(L, errmsg); + raise_luaL_error(L, errmsg); } lua_setfield(L, -2, "timer_gateway"); // settings M } @@ -1975,10 +1975,10 @@ LANES_API int luaopen_lanes_core( lua_State* L) lua_getglobal(L, "jit"); // {jit?} #if LUAJIT_FLAVOR() == 0 if (!lua_isnil(L, -1)) - return luaL_error(L, "Lanes is built for PUC-Lua, don't run from LuaJIT"); + raise_luaL_error(L, "Lanes is built for PUC-Lua, don't run from LuaJIT"); #else if (lua_isnil(L, -1)) - return luaL_error(L, "Lanes is built for LuaJIT, don't run from PUC-Lua"); + raise_luaL_error(L, "Lanes is built for LuaJIT, don't run from PUC-Lua"); #endif lua_pop(L, 1); // STACK_CHECK(L, 0); @@ -2012,7 +2012,7 @@ LANES_API int luaopen_lanes_core( lua_State* L) int const rc{ luaL_loadfile(L, "lanes.lua") || lua_pcall(L, 0, 1, 0) }; if (rc != LUA_OK) { - return luaL_error(L, "failed to initialize embedded Lanes"); + raise_luaL_error(L, "failed to initialize embedded Lanes"); } return 1; } diff --git a/src/linda.cpp b/src/linda.cpp index bc931ac..67a97c2 100644 --- a/src/linda.cpp +++ b/src/linda.cpp @@ -146,14 +146,14 @@ static void check_key_types(lua_State* L, int start_, int end_) { if (key.equals(L, i)) { - luaL_error(L, "argument #%d: can't use %s as a key", i, key.m_debugName); // doesn't return + raise_luaL_error(L, "argument #%d: can't use %s as a key", i, key.m_debugName); break; } } } break; } - luaL_error(L, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", i); // doesn't return + raise_luaL_error(L, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", i); } } @@ -247,7 +247,7 @@ LUAG_FUNC(linda_send) } else { - return luaL_error(L, "no data to send"); + raise_luaL_error(L, "no data to send"); } } @@ -331,7 +331,7 @@ LUAG_FUNC(linda_send) if (!pushed.has_value()) { - luaL_error(L, "tried to copy unsupported types"); // doesn't return + raise_luaL_error(L, "tried to copy unsupported types"); } switch (cancel) @@ -410,7 +410,7 @@ LUAG_FUNC(linda_receive) ++expected_pushed_max; if (expected_pushed_min > expected_pushed_max) { - return luaL_error(L, "batched min/max error"); + raise_luaL_error(L, "batched min/max error"); } } else @@ -496,7 +496,7 @@ LUAG_FUNC(linda_receive) if (!pushed.has_value()) { - return luaL_error(L, "tried to copy unsupported types"); + raise_luaL_error(L, "tried to copy unsupported types"); } switch (cancel) @@ -716,7 +716,7 @@ LUAG_FUNC(linda_cancel) } else { - return luaL_error(L, "unknown wake hint '%s'", who); + raise_luaL_error(L, "unknown wake hint '%s'", who); } return 0; } @@ -798,7 +798,7 @@ LUAG_FUNC(linda_concat) } if (!atLeastOneLinda) // should not be possible { - return luaL_error(L, "internal error: linda_concat called on non-Linda"); + raise_luaL_error(L, "internal error: linda_concat called on non-Linda"); } lua_concat(L, 2); return 1; diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index 068ff26..9bc71e1 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h @@ -17,6 +17,47 @@ extern "C" { using namespace std::chrono_literals; +// ################################################################################################# + +// use this instead of Lua's lua_error +[[noreturn]] static inline void raise_lua_error(lua_State* L_) +{ + std::ignore = lua_error(L_); // doesn't return + assert(false); // we should never get here, but i'm paranoid +} + +// ################################################################################################# + +// use this instead of Lua's luaL_error +template +[[noreturn]] static inline void raise_luaL_error(lua_State* L_, char const* fmt_, ARGS... args_) +{ + std::ignore = luaL_error(L_, fmt_, std::forward(args_)...); // doesn't return + assert(false); // we should never get here, but i'm paranoid +} + +// ################################################################################################# + +// use this instead of Lua's luaL_argerror +template +[[noreturn]] static inline void raise_luaL_argerror(lua_State* L_, int arg_, char const* extramsg_) +{ + std::ignore = luaL_argerror(L_, arg_, extramsg_); // doesn't return + assert(false); // we should never get here, but i'm paranoid +} + +// ################################################################################################# + +// use this instead of Lua's luaL_typeerror +template +[[noreturn]] static inline void raise_luaL_typeerror(lua_State* L_, int arg_, char const* tname_) +{ + std::ignore = luaL_typeerror(L_, arg_, tname_); // doesn't return + assert(false); // we should never get here, but i'm paranoid +} + +// ################################################################################################# + #define USE_DEBUG_SPEW() 0 #if USE_DEBUG_SPEW() #define INDENT_BEGIN "%.*s " @@ -48,7 +89,7 @@ inline void LUA_ASSERT_IMPL(lua_State* L_, bool cond_, char const* file_, size_t { if (!cond_) { - luaL_error(L_, "LUA_ASSERT %s:%llu '%s'", file_, line_, txt_); // doesn't return + raise_luaL_error(L_, "LUA_ASSERT %s:%llu '%s'", file_, line_, txt_); } } @@ -82,7 +123,7 @@ class StackChecker if ((offset_ < 0) || (m_oldtop < 0)) { assert(false); - luaL_error(m_L, "STACK INIT ASSERT failed (%d not %d): %s:%llu", lua_gettop(m_L), offset_, file_, line_); // doesn't return + raise_luaL_error(m_L, "STACK INIT ASSERT failed (%d not %d): %s:%llu", lua_gettop(m_L), offset_, file_, line_); } } @@ -93,7 +134,7 @@ class StackChecker if (lua_gettop(m_L) != pos_) { assert(false); - luaL_error(m_L, "STACK INIT ASSERT failed (%d not %d): %s:%llu", lua_gettop(m_L), pos_, file_, line_); // doesn't return + raise_luaL_error(m_L, "STACK INIT ASSERT failed (%d not %d): %s:%llu", lua_gettop(m_L), pos_, file_, line_); } } @@ -113,7 +154,7 @@ class StackChecker if (actual != expected_) { assert(false); - luaL_error(m_L, "STACK ASSERT failed (%d not %d): %s:%llu", actual, expected_, file_, line_); // doesn't return + raise_luaL_error(m_L, "STACK ASSERT failed (%d not %d): %s:%llu", actual, expected_, file_, line_); } } } @@ -127,14 +168,18 @@ class StackChecker #endif // NDEBUG +// ################################################################################################# + inline void STACK_GROW(lua_State* L, int n_) { if (!lua_checkstack(L, n_)) { - luaL_error(L, "Cannot grow stack!"); // doesn't return + raise_luaL_error(L, "Cannot grow stack!"); } } +// ################################################################################################# + #define LUAG_FUNC(func_name) [[nodiscard]] int LG_##func_name(lua_State* L) // ################################################################################################# @@ -169,13 +214,6 @@ template // ################################################################################################# -// use this instead of Lua's lua_error if possible -[[noreturn]] static inline void raise_lua_error(lua_State* L) -{ - std::ignore = lua_error(L); // doesn't return - assert(false); // we should never get here, but i'm paranoid -} - using lua_Duration = std::chrono::template duration; // ################################################################################################# @@ -222,7 +260,7 @@ typename T::value_type const& OptionalValue(T const& x_, Ts... args_) { if (!x_.has_value()) { - luaL_error(std::forward(args_)...); // doesn't return + raise_luaL_error(std::forward(args_)...); } return x_.value(); } diff --git a/src/state.cpp b/src/state.cpp index 379b63e..9898812 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -205,7 +205,7 @@ static void copy_one_time_settings(Universe* U, SourceState L1, DestState L2) InterCopyContext c{ U, L2, L1, {}, {}, {}, {}, {} }; if (c.inter_move(1) != InterCopyResult::Success) // // config { - luaL_error(L1, "failed to copy settings when loading lanes.core"); // doesn't return + raise_luaL_error(L1, "failed to copy settings when loading lanes.core"); } // set L2:_R[kConfigRegKey] = settings kConfigRegKey.setValue(L2, [](lua_State* L) { lua_insert(L, -2); }); // config @@ -229,7 +229,7 @@ void initialize_on_state_create( Universe* U, lua_State* L) char const* upname = lua_getupvalue(L, -1, 1); // settings on_state_create upval? if (upname != nullptr) // should be "" for C functions with upvalues if any { - (void) luaL_error(L, "on_state_create shouldn't have upvalues"); + raise_luaL_error(L, "on_state_create shouldn't have upvalues"); } // remove this C function from the config table so that it doesn't cause problems // when we transfer the config table in newly created Lua states @@ -274,7 +274,7 @@ lua_State* create_state(Universe* U, lua_State* from_) if (L == nullptr) { - luaL_error(from_, "luaG_newstate() failed while creating state; out of memory"); // doesn't return + raise_luaL_error(from_, "luaG_newstate() failed while creating state; out of memory"); } return L; } @@ -310,7 +310,7 @@ void call_on_state_create(Universe* U, lua_State* L, lua_State* from_, LookupMod // capture error and raise it in caller state if (lua_pcall(L, 0, 0, 0) != LUA_OK) { - luaL_error(from_, "on_state_create failed: \"%s\"", lua_isstring(L, -1) ? lua_tostring(L, -1) : lua_typename(L, lua_type(L, -1))); + raise_luaL_error(from_, "on_state_create failed: \"%s\"", lua_isstring(L, -1) ? lua_tostring(L, -1) : lua_typename(L, lua_type(L, -1))); } STACK_CHECK(L, 0); } diff --git a/src/tools.cpp b/src/tools.cpp index aa8f927..2497ba7 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -130,7 +130,7 @@ void initialize_allocator_function(Universe* U, lua_State* L) char const* upname = lua_getupvalue(L, -1, 1); // settings allocator upval? if (upname != nullptr) // should be "" for C functions with upvalues if any { - (void) luaL_error(L, "config.allocator() shouldn't have upvalues"); + raise_luaL_error(L, "config.allocator() shouldn't have upvalues"); } // remove this C function from the config table so that it doesn't cause problems // when we transfer the config table in newly created Lua states @@ -525,7 +525,7 @@ void populate_func_lookup_table(lua_State* L, int i_, char const* name_) else { lua_pop(L, 1); // - luaL_error(L, "unsupported module type %s", lua_typename(L, lua_type(L, in_base))); // doesn't return + raise_luaL_error(L, "unsupported module type %s", lua_typename(L, lua_type(L, in_base))); } STACK_CHECK(L, 0); } @@ -579,7 +579,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; // function sentinel used to transfer native functions from/to keeper states [[nodiscard]] static int func_lookup_sentinel(lua_State* L) { - return luaL_error(L, "function lookup sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); + raise_luaL_error(L, "function lookup sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); } // ################################################################################################# @@ -587,7 +587,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; // function sentinel used to transfer native table from/to keeper states [[nodiscard]] static int table_lookup_sentinel(lua_State* L) { - return luaL_error(L, "table lookup sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); + raise_luaL_error(L, "table lookup sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); } // ################################################################################################# @@ -595,7 +595,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; // function sentinel used to transfer cloned full userdata from/to keeper states [[nodiscard]] static int userdata_clone_sentinel(lua_State* L) { - return luaL_error(L, "userdata clone sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); + raise_luaL_error(L, "userdata clone sentinel for %s, should never be called", lua_tostring(L, lua_upvalueindex(1))); } // ################################################################################################# @@ -663,7 +663,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; gotchaB = ""; what = (lua_type( L, -1) == LUA_TSTRING) ? lua_tostring( L, -1) : luaL_typename( L, -1); } - (void) luaL_error( L, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); + raise_luaL_error(L, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB); *len_ = 0; return nullptr; } @@ -689,7 +689,7 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; switch (mode) { default: // shouldn't happen, in theory... - luaL_error(L1, "internal error: unknown lookup mode"); // doesn't return + raise_luaL_error(L1, "internal error: unknown lookup mode"); break; case LookupMode::ToKeeper: @@ -723,13 +723,13 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; to = lua_tostring(L2, -1); lua_pop(L2, 1); // {} t // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error - luaL_error( + raise_luaL_error( (mode == LookupMode::FromKeeper) ? L2 : L1 , "INTERNAL ERROR IN %s: table '%s' not found in %s destination transfer database." , from ? from : "main" , fqn , to ? to : "main" - ); // doesn't return + ); return false; } lua_remove(L2, -2); // t @@ -936,10 +936,10 @@ static constexpr RegistryUniqueKey kMtIdRegKey{ 0xA8895DCF4EC3FE3Cull }; */ int luaG_nameof( lua_State* L) { - int what = lua_gettop( L); + int const what{ lua_gettop(L) }; if (what > 1) { - luaL_argerror( L, what, "too many arguments."); + raise_luaL_argerror( L, what, "too many arguments."); } // nil, boolean, light userdata, number and string aren't identifiable @@ -994,7 +994,7 @@ void InterCopyContext::lookup_native_func() const switch (mode) { default: // shouldn't happen, in theory... - luaL_error(L1, "internal error: unknown lookup mode"); // doesn't return + raise_luaL_error(L1, "internal error: unknown lookup mode"); break; case LookupMode::ToKeeper: @@ -1022,7 +1022,7 @@ void InterCopyContext::lookup_native_func() const to = lua_tostring(L2, -1); lua_pop(L2, 1); // {} f // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error - (void) luaL_error( + raise_luaL_error( (mode == LookupMode::FromKeeper) ? L2 : L1 , "%s%s: function '%s' not found in %s destination transfer database." , lua_isnil(L2, -1) ? "" : "INTERNAL ERROR IN " @@ -1127,7 +1127,7 @@ void InterCopyContext::copy_func() const B.L = nullptr; if (lua504_dump(L1, buf_writer, &B, 0) != 0) { - luaL_error(L1, "internal error: function dump failed."); // doesn't return + raise_luaL_error(L1, "internal error: function dump failed."); } // pushes dumped string on 'L1' @@ -1173,7 +1173,7 @@ void InterCopyContext::copy_func() const // "Otherwise, it pushes an error message" // STACK_GROW(L1, 1); - luaL_error(L1, "%s: %s", name, lua_tostring(L2, -1)); // doesn't return + raise_luaL_error(L1, "%s: %s", name, lua_tostring(L2, -1)); } // remove the dumped string lua_pop(L1, 1); // ... @@ -1217,7 +1217,7 @@ void InterCopyContext::copy_func() const c.L1_i = SourceIndex{ lua_gettop(L1) }; if (!c.inter_copy_one()) // ... {cache} ... function { - luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); // doesn't return + raise_luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); } } lua_pop(L1, 1); // ... _G @@ -1335,7 +1335,7 @@ void InterCopyContext::copy_cached_func() const InterCopyContext const c{ U, L2, L1, L2_cache_i, SourceIndex{ lua_gettop(L1) }, VT::METATABLE, mode, name }; if (!c.inter_copy_one()) // _R[kMtIdRegKey] mt? { - luaL_error(L1, "Error copying a metatable"); // doesn't return + raise_luaL_error(L1, "Error copying a metatable"); } STACK_CHECK(L2, 2); // _R[kMtIdRegKey] mt @@ -1371,7 +1371,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const { return; // we could raise an error instead of ignoring the table entry, like so: - //luaL_error(L1, "Unable to copy %s key '%s' because of value is of type '%s'", (vt == VT::NORMAL) ? "table" : "metatable", name, luaL_typename(L1, key_i)); // doesn't return + //raise_luaL_error(L1, "Unable to copy %s key '%s' because of value is of type '%s'", (vt == VT::NORMAL) ? "table" : "metatable", name, luaL_typename(L1, key_i)); // maybe offer this possibility as a global configuration option, or a linda setting, or as a parameter of the call causing the transfer? } @@ -1426,7 +1426,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const } else { - luaL_error(L1, "Unable to copy %s entry '%s' because of value is of type '%s'", (vt == VT::NORMAL) ? "table" : "metatable", valPath, luaL_typename(L1, val_i)); + raise_luaL_error(L1, "Unable to copy %s entry '%s' because of value is of type '%s'", (vt == VT::NORMAL) ? "table" : "metatable", valPath, luaL_typename(L1, val_i)); } } @@ -1504,7 +1504,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const } else { - luaL_error(L1, "Error copying a metatable"); // doesn't return + raise_luaL_error(L1, "Error copying a metatable"); } // first, add the entry in the cache (at this point it is either the actual userdata or the keeper sentinel lua_pushlightuserdata( L2, source); // ... u source @@ -1521,7 +1521,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const c.L1_i = SourceIndex{ lua_absindex(L1, -1) }; if (!c.inter_copy_one()) // ... u uv { - luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); // doesn't return + raise_luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); } lua_pop(L1, 1); // ... mt __lanesclone [uv]* // this pops the value from the stack @@ -1591,7 +1591,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const } else // raise an error { - luaL_error(L1, "can't copy non-deep full userdata across lanes"); // doesn't return + raise_luaL_error(L1, "can't copy non-deep full userdata across lanes"); } STACK_CHECK(L2, 1); @@ -1667,7 +1667,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const c.L1_i = SourceIndex{ lua_absindex(L1, -1) }; if (!c.inter_copy_one()) // ... mt u uv { - luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); // doesn't return + raise_luaL_error(L1, "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); } lua_pop(L1, 1); // ... u [uv]* // this pops the value from the stack @@ -2010,7 +2010,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const // raise the error when copying from lane to lane, else just leave it on the stack to be raised later if (mode == LookupMode::LaneBody) { - lua_error(L1); // doesn't return + raise_lua_error(L1); } return InterCopyResult::Error; } @@ -2057,7 +2057,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const // raise the error when copying from lane to lane, else just leave it on the stack to be raised later if (mode == LookupMode::LaneBody) { - lua_error(L1); // doesn't return + raise_lua_error(L1); } lua_pop(L1, 1); break; -- cgit v1.2.3-55-g6feb