aboutsummaryrefslogtreecommitdiff
path: root/src/macros_and_utils.h
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-03-25 10:43:25 +0100
committerBenoit Germain <benoit.germain@ubisoft.com>2024-03-25 10:43:25 +0100
commit0c060e6e4b9f99dc887b5dfebdae76fcde9524f1 (patch)
tree2ba9a1923e3e983375e33aa5f41d9fbc21451832 /src/macros_and_utils.h
parentdad1d5fbf7c7a30caea00694de608c6036789aa5 (diff)
downloadlanes-0c060e6e4b9f99dc887b5dfebdae76fcde9524f1.tar.gz
lanes-0c060e6e4b9f99dc887b5dfebdae76fcde9524f1.tar.bz2
lanes-0c060e6e4b9f99dc887b5dfebdae76fcde9524f1.zip
C++ migration: revamped stack checking macros
Diffstat (limited to 'src/macros_and_utils.h')
-rw-r--r--src/macros_and_utils.h116
1 files changed, 77 insertions, 39 deletions
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h
index 9982693..c549d72 100644
--- a/src/macros_and_utils.h
+++ b/src/macros_and_utils.h
@@ -10,6 +10,8 @@ extern "C" {
10} 10}
11#endif // __cplusplus 11#endif // __cplusplus
12 12
13#include <cassert>
14
13#define USE_DEBUG_SPEW() 0 15#define USE_DEBUG_SPEW() 0
14#if USE_DEBUG_SPEW() 16#if USE_DEBUG_SPEW()
15extern char const* debugspew_indent; 17extern char const* debugspew_indent;
@@ -27,53 +29,89 @@ extern char const* debugspew_indent;
27#ifdef NDEBUG 29#ifdef NDEBUG
28 30
29#define _ASSERT_L(lua,c) //nothing 31#define _ASSERT_L(lua,c) //nothing
30#define STACK_CHECK(L,o) //nothing
31#define STACK_CHECK_ABS(L,o) //nothing
32#define STACK_MID(L,c) //nothing
33#define STACK_END(L,c) //nothing
34#define STACK_DUMP(L) //nothing 32#define STACK_DUMP(L) //nothing
35 33
34#define STACK_CHECK_START_REL(L, offset_)
35#define STACK_CHECK_START_ABS(L, offset_)
36#define STACK_CHECK_RESET_REL(L, offset_)
37#define STACK_CHECK_RESET_ABS(L, offset_)
38#define STACK_CHECK(L, offset_)
39
36#else // NDEBUG 40#else // NDEBUG
37 41
38#define _ASSERT_L( L, cond_) if( (cond_) == 0) { (void) luaL_error( L, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #cond_);} 42#define _ASSERT_L( L, cond_) if( (cond_) == 0) { (void) luaL_error( L, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #cond_);}
43#define STACK_DUMP( L) luaG_dump( L)
44
45class StackChecker
46{
47 private:
48 lua_State* const m_L;
49 int m_oldtop;
50
51 public:
52 struct Relative
53 {
54 int const m_offset;
55
56 operator int() const { return m_offset; }
57 };
58
59 struct Absolute
60 {
61 int const m_offset;
39 62
40#define STACK_CHECK( L, offset_) \ 63 operator int() const { return m_offset; }
41 { \ 64 };
42 int const L##_delta = offset_; \ 65
43 if( (L##_delta < 0) || (lua_gettop( L) < L##_delta)) \ 66 StackChecker(lua_State* const L_, Relative offset_, char const* file_, size_t const line_)
44 { \ 67 : m_L{ L_ }
45 assert( false); \ 68 , m_oldtop{ lua_gettop(L_) - offset_ }
46 (void) luaL_error( L, "STACK INIT ASSERT failed (%d not %d): %s:%d", lua_gettop( L), L##_delta, __FILE__, __LINE__); \ 69 {
47 } \ 70 if ((offset_ < 0) || (m_oldtop < 0))
48 int const L##_oldtop = lua_gettop( L) - L##_delta 71 {
49 72 assert(false);
50#define STACK_CHECK_ABS( L, offset_) \ 73 (void) luaL_error(m_L, "STACK INIT ASSERT failed (%d not %d): %s:%d", lua_gettop(m_L), offset_, file_, line_);
51 { \ 74 }
52 int const L##_pos = offset_; \
53 if( lua_gettop( L) < L##_pos) \
54 { \
55 assert( false); \
56 (void) luaL_error( L, "STACK INIT ASSERT failed (%d not %d): %s:%d", lua_gettop( L), L##_pos, __FILE__, __LINE__); \
57 } \
58 int const L##_oldtop = 0
59
60#define STACK_MID( L, change) \
61 do if( change != LUA_MULTRET) \
62 { \
63 int stack_check_a = lua_gettop( L) - L##_oldtop; \
64 int stack_check_b = (change); \
65 if( stack_check_a != stack_check_b) \
66 { \
67 assert( false); \
68 luaL_error( L, "STACK ASSERT failed (%d not %d): %s:%d", stack_check_a, stack_check_b, __FILE__, __LINE__); \
69 } \
70 } while( 0)
71
72#define STACK_END( L, change) \
73 STACK_MID( L, change); \
74 } 75 }
75 76
76#define STACK_DUMP( L) luaG_dump( L) 77 StackChecker(lua_State* const L_, Absolute pos_, char const* file_, size_t const line_)
78 : m_L{ L_ }
79 , m_oldtop{ 0 }
80 {
81 if (lua_gettop(m_L) != pos_)
82 {
83 assert(false);
84 (void) luaL_error(m_L, "STACK INIT ASSERT failed (%d not %d): %s:%d", lua_gettop(m_L), pos_, file_, line_);
85 }
86 }
87
88 StackChecker& operator=(StackChecker const& rhs_)
89 {
90 assert(m_L == rhs_.m_L);
91 m_oldtop = rhs_.m_oldtop;
92 return *this;
93 }
94
95 // verify if the distance between the current top and the initial one is what we expect
96 void check(int expected_, char const* file_, size_t const line_)
97 {
98 if (expected_ != LUA_MULTRET)
99 {
100 int const actual{ lua_gettop(m_L) - m_oldtop };
101 if (actual != expected_)
102 {
103 assert(false);
104 luaL_error(m_L, "STACK ASSERT failed (%d not %d): %s:%d", actual, expected_, file_, line_);
105 }
106 }
107 }
108};
109
110#define STACK_CHECK_START_REL(L, offset_) StackChecker stackChecker_##L(L, StackChecker::Relative{ offset_ }, __FILE__, __LINE__)
111#define STACK_CHECK_START_ABS(L, offset_) StackChecker stackChecker_##L(L, StackChecker::Absolute{ offset_ }, __FILE__, __LINE__)
112#define STACK_CHECK_RESET_REL(L, offset_) stackChecker_##L = StackChecker{L, StackChecker::Relative{ offset_ }, __FILE__, __LINE__}
113#define STACK_CHECK_RESET_ABS(L, offset_) stackChecker_##L = StackChecker{L, StackChecker::Absolute{ offset_ }, __FILE__, __LINE__}
114#define STACK_CHECK(L, offset_) stackChecker_##L.check(offset_, __FILE__, __LINE__)
77 115
78#endif // NDEBUG 116#endif // NDEBUG
79 117