aboutsummaryrefslogtreecommitdiff
path: root/src/keeper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/keeper.cpp')
-rw-r--r--src/keeper.cpp32
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
55struct keeper_fifo 55class 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
62static constexpr int CONTENTS_TABLE{ 1 }; 69static 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
67static keeper_fifo* prepare_fifo_access(lua_State* L, int idx_) 74static 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}
85static void fifo_new(lua_State* L) 92static 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/
169static constexpr UniqueKey FIFOS_KEY{ 0xdce50bbc351cd465ull }; 177static constexpr UniqueKey FIFOS_KEY{ 0xdce50bbc351cd465ull };
170static void push_table(lua_State* L, int idx_) 178static 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