From 57ca292c8844e566184e3f7e5c98fa98991684bd Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Fri, 7 Jun 2024 09:51:45 +0200 Subject: Reorganized debug stuff --- src/debug.h | 112 +++++++++++++++++++++++++++++++++++ src/lanesconf.h | 7 +++ src/luaerrors.h | 57 ++++++++++++++++++ src/macros_and_utils.h | 154 +------------------------------------------------ 4 files changed, 179 insertions(+), 151 deletions(-) create mode 100644 src/debug.h create mode 100644 src/luaerrors.h diff --git a/src/debug.h b/src/debug.h new file mode 100644 index 0000000..a0a4b8d --- /dev/null +++ b/src/debug.h @@ -0,0 +1,112 @@ +#pragma once + +#include "lanesconf.h" +#include "luaerrors.h" + +// ################################################################################################# + +#if HAVE_LUA_ASSERT() + +inline void LUA_ASSERT_IMPL(lua_State* L_, bool cond_, char const* file_, int const line_, char const* txt_) +{ + if (!cond_) { + raise_luaL_error(L_, "LUA_ASSERT %s:%d '%s'", file_, line_, txt_); + } +} + +#define LUA_ASSERT(L_, cond_) LUA_ASSERT_IMPL(L_, cond_, __FILE__, __LINE__, #cond_) + +class StackChecker +{ + private: + lua_State* const L; + int oldtop; + + public: + struct Relative + { + int const offset; + + operator int() const { return offset; } + }; + + struct Absolute + { + int const offset; + + operator int() const { return offset; } + }; + + StackChecker(lua_State* const L_, Relative offset_, char const* file_, size_t const line_) + : L{ L_ } + , oldtop{ lua_gettop(L_) - offset_ } + { + if ((offset_ < 0) || (oldtop < 0)) { + assert(false); + raise_luaL_error(L, "STACK INIT ASSERT failed (%d not %d): %s:%llu", lua_gettop(L), offset_, file_, line_); + } + } + + StackChecker(lua_State* const L_, Absolute pos_, char const* file_, size_t const line_) + : L{ L_ } + , oldtop{ 0 } + { + if (lua_gettop(L) != pos_) { + assert(false); + raise_luaL_error(L, "STACK INIT ASSERT failed (%d not %d): %s:%llu", lua_gettop(L), pos_, file_, line_); + } + } + + StackChecker& operator=(StackChecker const& rhs_) + { + assert(L == rhs_.L); + oldtop = rhs_.oldtop; + return *this; + } + + // verify if the distance between the current top and the initial one is what we expect + void check(int expected_, char const* file_, size_t const line_) + { + if (expected_ != LUA_MULTRET) { + int const actual{ lua_gettop(L) - oldtop }; + if (actual != expected_) { + assert(false); + raise_luaL_error(L, "STACK ASSERT failed (%d not %d): %s:%llu", actual, expected_, file_, line_); + } + } + } +}; + +#define STACK_CHECK_START_REL(L, offset_) \ + StackChecker _stackChecker_##L \ + { \ + L, StackChecker::Relative{ offset_ }, __FILE__, __LINE__ \ + } +#define STACK_CHECK_START_ABS(L, offset_) \ + StackChecker _stackChecker_##L \ + { \ + L, StackChecker::Absolute{ offset_ }, __FILE__, __LINE__ \ + } +#define STACK_CHECK_RESET_REL(L, offset_) \ + _stackChecker_##L = StackChecker \ + { \ + L, StackChecker::Relative{ offset_ }, __FILE__, __LINE__ \ + } +#define STACK_CHECK_RESET_ABS(L, offset_) \ + _stackChecker_##L = StackChecker \ + { \ + L, StackChecker::Absolute{ offset_ }, __FILE__, __LINE__ \ + } +#define STACK_CHECK(L, offset_) _stackChecker_##L.check(offset_, __FILE__, __LINE__) + +#else // HAVE_LUA_ASSERT() + +#define LUA_ASSERT(L_, c) nullptr // nothing + +#define STACK_CHECK_START_REL(L_, offset_) +#define STACK_CHECK_START_ABS(L_, offset_) +#define STACK_CHECK_RESET_REL(L_, offset_) +#define STACK_CHECK_RESET_ABS(L_, offset_) +#define STACK_CHECK(L_, offset_) + +#endif // HAVE_LUA_ASSERT() diff --git a/src/lanesconf.h b/src/lanesconf.h index 938d743..f20dfff 100644 --- a/src/lanesconf.h +++ b/src/lanesconf.h @@ -41,5 +41,12 @@ #endif // __cplusplus #endif // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) +// kind of MSVC-specific +#ifdef _DEBUG +#define HAVE_LUA_ASSERT() 1 +#else // NDEBUG +#define HAVE_LUA_ASSERT() 0 +#endif // NDEBUG + #define USE_DEBUG_SPEW() 0 #define HAVE_DECODA_SUPPORT() 0 diff --git a/src/luaerrors.h b/src/luaerrors.h new file mode 100644 index 0000000..9399427 --- /dev/null +++ b/src/luaerrors.h @@ -0,0 +1,57 @@ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +#ifdef __cplusplus +} +#endif // __cplusplus + +#include +#include +#include + +// ################################################################################################# + +// use this instead of Lua's lua_error +[[noreturn]] static inline void raise_lua_error(lua_State* const 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* const L_, std::string_view const& fmt_, ARGS... args_) +{ + std::ignore = luaL_error(L_, fmt_.data(), 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* const L_, int const arg_, std::string_view const& extramsg_) +{ + std::ignore = luaL_argerror(L_, arg_, extramsg_.data()); // doesn't return + assert(false); // we should never get here, but i'm paranoid +} + +// ################################################################################################# + +#if LUA_VERSION_NUM >= 504 +// use this instead of Lua's luaL_typeerror +template +[[noreturn]] static inline void raise_luaL_typeerror(lua_State* const L_, int const arg_, std::string_view const& tname_) +{ + std::ignore = luaL_typeerror(L_, arg_, tname_.data()); // doesn't return + assert(false); // we should never get here, but i'm paranoid +} +#endif // LUA_VERSION_NUM diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h index 926e756..d540cdb 100644 --- a/src/macros_and_utils.h +++ b/src/macros_and_utils.h @@ -11,164 +11,16 @@ extern "C" } #endif // __cplusplus -#include +#include "debug.h" +#include "luaerrors.h" + #include -#include #include using namespace std::chrono_literals; // ################################################################################################# -// use this instead of Lua's lua_error -[[noreturn]] static inline void raise_lua_error(lua_State* const 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* const L_, std::string_view const& fmt_, ARGS... args_) -{ - std::ignore = luaL_error(L_, fmt_.data(), 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* const L_, int const arg_, std::string_view const& extramsg_) -{ - std::ignore = luaL_argerror(L_, arg_, extramsg_.data()); // doesn't return - assert(false); // we should never get here, but i'm paranoid -} - -// ################################################################################################# - -#if LUA_VERSION_NUM >= 504 -// use this instead of Lua's luaL_typeerror -template -[[noreturn]] static inline void raise_luaL_typeerror(lua_State* const L_, int const arg_, std::string_view const& tname_) -{ - std::ignore = luaL_typeerror(L_, arg_, tname_.data()); // doesn't return - assert(false); // we should never get here, but i'm paranoid -} -#endif // LUA_VERSION_NUM - -// ################################################################################################# - -#ifdef NDEBUG - -#define LUA_ASSERT(L_, c) ; // nothing - -#define STACK_CHECK_START_REL(L_, offset_) -#define STACK_CHECK_START_ABS(L_, offset_) -#define STACK_CHECK_RESET_REL(L_, offset_) -#define STACK_CHECK_RESET_ABS(L_, offset_) -#define STACK_CHECK(L_, offset_) - -#else // NDEBUG - -inline void LUA_ASSERT_IMPL(lua_State* L_, bool cond_, char const* file_, int const line_, char const* txt_) -{ - if (!cond_) { - raise_luaL_error(L_, "LUA_ASSERT %s:%d '%s'", file_, line_, txt_); - } -} - -#define LUA_ASSERT(L_, cond_) LUA_ASSERT_IMPL(L_, cond_, __FILE__, __LINE__, #cond_) - -class StackChecker -{ - private: - lua_State* const L; - int oldtop; - - public: - struct Relative - { - int const offset; - - operator int() const { return offset; } - }; - - struct Absolute - { - int const offset; - - operator int() const { return offset; } - }; - - StackChecker(lua_State* const L_, Relative offset_, char const* file_, size_t const line_) - : L{ L_ } - , oldtop{ lua_gettop(L_) - offset_ } - { - if ((offset_ < 0) || (oldtop < 0)) { - assert(false); - raise_luaL_error(L, "STACK INIT ASSERT failed (%d not %d): %s:%llu", lua_gettop(L), offset_, file_, line_); - } - } - - StackChecker(lua_State* const L_, Absolute pos_, char const* file_, size_t const line_) - : L{ L_ } - , oldtop{ 0 } - { - if (lua_gettop(L) != pos_) { - assert(false); - raise_luaL_error(L, "STACK INIT ASSERT failed (%d not %d): %s:%llu", lua_gettop(L), pos_, file_, line_); - } - } - - StackChecker& operator=(StackChecker const& rhs_) - { - assert(L == rhs_.L); - oldtop = rhs_.oldtop; - return *this; - } - - // verify if the distance between the current top and the initial one is what we expect - void check(int expected_, char const* file_, size_t const line_) - { - if (expected_ != LUA_MULTRET) { - int const actual{ lua_gettop(L) - oldtop }; - if (actual != expected_) { - assert(false); - raise_luaL_error(L, "STACK ASSERT failed (%d not %d): %s:%llu", actual, expected_, file_, line_); - } - } - } -}; - -#define STACK_CHECK_START_REL(L, offset_) \ - StackChecker _stackChecker_##L \ - { \ - L, StackChecker::Relative{ offset_ }, __FILE__, __LINE__ \ - } -#define STACK_CHECK_START_ABS(L, offset_) \ - StackChecker _stackChecker_##L \ - { \ - L, StackChecker::Absolute{ offset_ }, __FILE__, __LINE__ \ - } -#define STACK_CHECK_RESET_REL(L, offset_) \ - _stackChecker_##L = StackChecker \ - { \ - L, StackChecker::Relative{ offset_ }, __FILE__, __LINE__ \ - } -#define STACK_CHECK_RESET_ABS(L, offset_) \ - _stackChecker_##L = StackChecker \ - { \ - L, StackChecker::Absolute{ offset_ }, __FILE__, __LINE__ \ - } -#define STACK_CHECK(L, offset_) _stackChecker_##L.check(offset_, __FILE__, __LINE__) - -#endif // NDEBUG - -// ################################################################################################# - inline void STACK_GROW(lua_State* L_, int n_) { if (!lua_checkstack(L_, n_)) { -- cgit v1.2.3-55-g6feb