diff options
Diffstat (limited to 'src/keeper.cpp')
-rw-r--r-- | src/keeper.cpp | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp index 88bd4ff..35b5ea8 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
@@ -52,11 +52,18 @@ | |||
52 | // Keeper implementation | 52 | // Keeper implementation |
53 | // ################################################################################### | 53 | // ################################################################################### |
54 | 54 | ||
55 | struct keeper_fifo | 55 | class keeper_fifo |
56 | { | 56 | { |
57 | public: | ||
58 | |||
57 | int first{ 1 }; | 59 | int first{ 1 }; |
58 | int count{ 0 }; | 60 | int count{ 0 }; |
59 | int limit{ -1 }; | 61 | int limit{ -1 }; |
62 | |||
63 | static void* operator new(size_t size_, lua_State* L) noexcept { return lua_newuserdatauv(L, size_, 1); } | ||
64 | // always embedded somewhere else or "in-place constructed" as a full userdata | ||
65 | // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception | ||
66 | static void operator delete(void* p_, lua_State* L){ ASSERT_L(!"should never be called") }; | ||
60 | }; | 67 | }; |
61 | 68 | ||
62 | static constexpr int CONTENTS_TABLE{ 1 }; | 69 | static constexpr int CONTENTS_TABLE{ 1 }; |
@@ -66,7 +73,7 @@ static constexpr int CONTENTS_TABLE{ 1 }; | |||
66 | // replaces the fifo ud by its uservalue on the stack | 73 | // replaces the fifo ud by its uservalue on the stack |
67 | static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) | 74 | static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) |
68 | { | 75 | { |
69 | keeper_fifo* const fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, idx_)) }; | 76 | keeper_fifo* const fifo{ lua_touserdata<keeper_fifo>(L, idx_) }; |
70 | if (fifo != nullptr) | 77 | if (fifo != nullptr) |
71 | { | 78 | { |
72 | idx_ = lua_absindex(L, idx_); | 79 | idx_ = lua_absindex(L, idx_); |
@@ -84,13 +91,14 @@ static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) | |||
84 | // out: { first = 1, count = 0, limit = -1} | 91 | // out: { first = 1, count = 0, limit = -1} |
85 | static void fifo_new(lua_State* L) | 92 | static void fifo_new(lua_State* L) |
86 | { | 93 | { |
87 | keeper_fifo* fifo; | ||
88 | STACK_GROW(L, 2); | 94 | STACK_GROW(L, 2); |
95 | STACK_CHECK_START_REL(L, 0); | ||
89 | // a fifo full userdata has one uservalue, the table that holds the actual fifo contents | 96 | // a fifo full userdata has one uservalue, the table that holds the actual fifo contents |
90 | fifo = (keeper_fifo*) lua_newuserdatauv(L, sizeof(keeper_fifo), 1); | 97 | [[maybe_unused]] keeper_fifo* const fifo{ new (L) keeper_fifo{} }; |
91 | fifo->keeper_fifo::keeper_fifo(); | 98 | STACK_CHECK(L, 1); |
92 | lua_newtable(L); | 99 | lua_newtable(L); |
93 | lua_setiuservalue(L, -2, CONTENTS_TABLE); | 100 | lua_setiuservalue(L, -2, CONTENTS_TABLE); |
101 | STACK_CHECK(L, 1); | ||
94 | } | 102 | } |
95 | 103 | ||
96 | // ################################################################################################## | 104 | // ################################################################################################## |
@@ -163,13 +171,13 @@ static void fifo_pop( lua_State* L, keeper_fifo* fifo_, int count_) | |||
163 | 171 | ||
164 | // ################################################################################################## | 172 | // ################################################################################################## |
165 | 173 | ||
166 | // in: linda_ud expected at *absolute* stack slot idx | 174 | // in: linda_ud expected at stack slot idx |
167 | // out: fifos[ud] | 175 | // out: fifos[ud] |
168 | // crc64/we of string "FIFOS_KEY" generated at http://www.nitrxgen.net/hashgen/ | 176 | // crc64/we of string "FIFOS_KEY" generated at http://www.nitrxgen.net/hashgen/ |
169 | static constexpr UniqueKey FIFOS_KEY{ 0xdce50bbc351cd465ull }; | 177 | static constexpr UniqueKey FIFOS_KEY{ 0xdce50bbc351cd465ull }; |
170 | static void push_table(lua_State* L, int idx_) | 178 | static void push_table(lua_State* L, int idx_) |
171 | { | 179 | { |
172 | STACK_GROW(L, 4); | 180 | STACK_GROW(L, 5); |
173 | STACK_CHECK_START_REL(L, 0); | 181 | STACK_CHECK_START_REL(L, 0); |
174 | idx_ = lua_absindex(L, idx_); | 182 | idx_ = lua_absindex(L, idx_); |
175 | FIFOS_KEY.query_registry(L); // ud fifos | 183 | FIFOS_KEY.query_registry(L); // ud fifos |
@@ -276,7 +284,7 @@ int keepercall_send(lua_State* L) | |||
276 | lua_rawset(L, -4); // ud key ... fifos fifo | 284 | lua_rawset(L, -4); // ud key ... fifos fifo |
277 | } | 285 | } |
278 | lua_remove(L, -2); // ud key ... fifo | 286 | lua_remove(L, -2); // ud key ... fifo |
279 | keeper_fifo* fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, -1)) }; | 287 | keeper_fifo* fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
280 | if( fifo->limit >= 0 && fifo->count + n > fifo->limit) | 288 | if( fifo->limit >= 0 && fifo->count + n > fifo->limit) |
281 | { | 289 | { |
282 | lua_settop(L, 0); // | 290 | lua_settop(L, 0); // |
@@ -374,12 +382,12 @@ int keepercall_limit(lua_State* L) | |||
374 | lua_pop(L, 1); // fifos key | 382 | lua_pop(L, 1); // fifos key |
375 | lua_pushvalue(L, -1); // fifos key key | 383 | lua_pushvalue(L, -1); // fifos key key |
376 | lua_rawget(L, -3); // fifos key fifo|nil | 384 | lua_rawget(L, -3); // fifos key fifo|nil |
377 | keeper_fifo* fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, -1)) }; | 385 | keeper_fifo* fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
378 | if (fifo == nullptr) | 386 | if (fifo == nullptr) |
379 | { // fifos key nil | 387 | { // fifos key nil |
380 | lua_pop(L, 1); // fifos key | 388 | lua_pop(L, 1); // fifos key |
381 | fifo_new(L); // fifos key fifo | 389 | fifo_new(L); // fifos key fifo |
382 | fifo = static_cast<keeper_fifo*>(lua_touserdata(L, -1)); | 390 | fifo = lua_touserdata<keeper_fifo>(L, -1); |
383 | lua_rawset(L, -3); // fifos | 391 | lua_rawset(L, -3); // fifos |
384 | } | 392 | } |
385 | // remove any clutter on the stack | 393 | // remove any clutter on the stack |
@@ -418,7 +426,7 @@ int keepercall_set(lua_State* L) | |||
418 | lua_pushvalue(L, -1); // fifos key key | 426 | lua_pushvalue(L, -1); // fifos key key |
419 | lua_rawget(L, 1); // fifos key fifo|nil | 427 | lua_rawget(L, 1); // fifos key fifo|nil |
420 | // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! | 428 | // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! |
421 | keeper_fifo* const fifo{ static_cast<keeper_fifo*>(lua_touserdata(L, -1)) }; | 429 | keeper_fifo* const fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
422 | if (fifo != nullptr) // might be nullptr if we set a nonexistent key to nil | 430 | if (fifo != nullptr) // might be nullptr if we set a nonexistent key to nil |
423 | { // fifos key fifo | 431 | { // fifos key fifo |
424 | if (fifo->limit < 0) // fifo limit value is the default (unlimited): we can totally remove it | 432 | if (fifo->limit < 0) // fifo limit value is the default (unlimited): we can totally remove it |
@@ -444,7 +452,7 @@ int keepercall_set(lua_State* L) | |||
444 | int const count{ lua_gettop(L) - 2 }; // number of items we want to store | 452 | int const count{ lua_gettop(L) - 2 }; // number of items we want to store |
445 | lua_pushvalue(L, 2); // fifos key [val [, ...]] key | 453 | lua_pushvalue(L, 2); // fifos key [val [, ...]] key |
446 | lua_rawget(L, 1); // fifos key [val [, ...]] fifo|nil | 454 | lua_rawget(L, 1); // fifos key [val [, ...]] fifo|nil |
447 | keeper_fifo* fifo = static_cast<keeper_fifo*>(lua_touserdata( L, -1)); | 455 | keeper_fifo* fifo{ lua_touserdata<keeper_fifo>(L, -1) }; |
448 | if( fifo == nullptr) // can be nullptr if we store a value at a new key | 456 | if( fifo == nullptr) // can be nullptr if we store a value at a new key |
449 | { // fifos key [val [, ...]] nil | 457 | { // fifos key [val [, ...]] nil |
450 | // no need to wake writers in that case, because a writer can't wait on an inexistent key | 458 | // no need to wake writers in that case, because a writer can't wait on an inexistent key |