aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cancel.h6
-rw-r--r--src/deep.cpp6
-rw-r--r--src/deep.h11
-rw-r--r--src/keeper.cpp6
-rw-r--r--src/keeper.h2
-rw-r--r--src/lanes.cpp25
-rw-r--r--src/linda.cpp18
-rw-r--r--src/macros_and_utils.h4
-rw-r--r--src/tools.cpp12
-rw-r--r--src/tools.h4
-rw-r--r--src/uniquekey.h43
-rw-r--r--src/universe.cpp2
-rw-r--r--src/universe.h3
13 files changed, 80 insertions, 62 deletions
diff --git a/src/cancel.h b/src/cancel.h
index e5dfe23..c1bee4e 100644
--- a/src/cancel.h
+++ b/src/cancel.h
@@ -46,17 +46,17 @@ typedef enum
46} CancelOp; 46} CancelOp;
47 47
48// crc64/we of string "CANCEL_ERROR" generated at http://www.nitrxgen.net/hashgen/ 48// crc64/we of string "CANCEL_ERROR" generated at http://www.nitrxgen.net/hashgen/
49static DECLARE_CONST_UNIQUE_KEY(CANCEL_ERROR, 0xe97d41626cc97577); // 'cancel_error' sentinel 49static constexpr UniqueKey CANCEL_ERROR{ 0xe97d41626cc97577ull }; // 'cancel_error' sentinel
50 50
51// crc64/we of string "CANCEL_TEST_KEY" generated at http://www.nitrxgen.net/hashgen/ 51// crc64/we of string "CANCEL_TEST_KEY" generated at http://www.nitrxgen.net/hashgen/
52static DECLARE_CONST_UNIQUE_KEY(CANCEL_TEST_KEY, 0xe66f5960c57d133a); // used as registry key 52static constexpr UniqueKey CANCEL_TEST_KEY{ 0xe66f5960c57d133aull }; // used as registry key
53 53
54cancel_result thread_cancel( lua_State* L, Lane* s, CancelOp op_, double secs_, bool force_, double waitkill_timeout_); 54cancel_result thread_cancel( lua_State* L, Lane* s, CancelOp op_, double secs_, bool force_, double waitkill_timeout_);
55 55
56static inline int cancel_error( lua_State* L) 56static inline int cancel_error( lua_State* L)
57{ 57{
58 STACK_GROW( L, 1); 58 STACK_GROW( L, 1);
59 push_unique_key( L, CANCEL_ERROR); // special error value 59 CANCEL_ERROR.push(L); // special error value
60 return lua_error( L); // doesn't return 60 return lua_error( L); // doesn't return
61} 61}
62 62
diff --git a/src/deep.cpp b/src/deep.cpp
index 897dc63..c0aa25b 100644
--- a/src/deep.cpp
+++ b/src/deep.cpp
@@ -59,13 +59,13 @@ THE SOFTWARE.
59* idfunc -> metatable 59* idfunc -> metatable
60*/ 60*/
61// crc64/we of string "DEEP_LOOKUP_KEY" generated at http://www.nitrxgen.net/hashgen/ 61// crc64/we of string "DEEP_LOOKUP_KEY" generated at http://www.nitrxgen.net/hashgen/
62static DECLARE_CONST_UNIQUE_KEY( DEEP_LOOKUP_KEY, 0x9fb9b4f3f633d83d); 62static constexpr UniqueKey DEEP_LOOKUP_KEY{ 0x9fb9b4f3f633d83dull };
63 63
64/* 64/*
65 * The deep proxy cache is a weak valued table listing all deep UD proxies indexed by the deep UD that they are proxying 65 * The deep proxy cache is a weak valued table listing all deep UD proxies indexed by the deep UD that they are proxying
66 * crc64/we of string "DEEP_PROXY_CACHE_KEY" generated at http://www.nitrxgen.net/hashgen/ 66 * crc64/we of string "DEEP_PROXY_CACHE_KEY" generated at http://www.nitrxgen.net/hashgen/
67*/ 67*/
68static DECLARE_CONST_UNIQUE_KEY( DEEP_PROXY_CACHE_KEY, 0x05773d6fc26be106); 68static constexpr UniqueKey DEEP_PROXY_CACHE_KEY{ 0x05773d6fc26be106ull };
69 69
70/* 70/*
71* Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. 71* Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists.
@@ -390,7 +390,7 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc, int nuv_)
390 { 390 {
391 return luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)"); 391 return luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)");
392 } 392 }
393 if( prelude->magic.value != DEEP_VERSION.value) 393 if( prelude->magic != DEEP_VERSION)
394 { 394 {
395 // just in case, don't leak the newly allocated deep userdata object 395 // just in case, don't leak the newly allocated deep userdata object
396 lua_pushlightuserdata( L, prelude); 396 lua_pushlightuserdata( L, prelude);
diff --git a/src/deep.h b/src/deep.h
index 728aa2a..d8a1772 100644
--- a/src/deep.h
+++ b/src/deep.h
@@ -42,18 +42,17 @@ typedef void* (*luaG_IdFunction)( lua_State* L, DeepOp op_);
42// ################################################################################################ 42// ################################################################################################
43 43
44// fnv164 of string "DEEP_VERSION_2" generated at https://www.pelock.com/products/hash-calculator 44// fnv164 of string "DEEP_VERSION_2" generated at https://www.pelock.com/products/hash-calculator
45static DECLARE_CONST_UNIQUE_KEY( DEEP_VERSION, 0xB4B0119C10642B29); 45static constexpr UniqueKey DEEP_VERSION{ 0xB4B0119C10642B29ull };
46 46
47// should be used as header for full userdata 47// should be used as header for full userdata
48struct s_DeepPrelude 48struct DeepPrelude
49{ 49{
50 DECLARE_UNIQUE_KEY( magic); // must be filled by the Deep userdata idfunc that allocates it on eDO_new operation 50 UniqueKey const magic{ DEEP_VERSION };
51 // when stored in a keeper state, the full userdata doesn't have a metatable, so we need direct access to the idfunc 51 // when stored in a keeper state, the full userdata doesn't have a metatable, so we need direct access to the idfunc
52 luaG_IdFunction idfunc; 52 luaG_IdFunction idfunc { nullptr };
53 // data is destroyed when refcount is 0 53 // data is destroyed when refcount is 0
54 volatile int refcount; 54 volatile int refcount{ 0 };
55}; 55};
56typedef struct s_DeepPrelude DeepPrelude;
57 56
58char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, int nuv_, LookupMode mode_); 57char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, int nuv_, LookupMode mode_);
59void free_deep_prelude( lua_State* L, DeepPrelude* prelude_); 58void free_deep_prelude( lua_State* L, DeepPrelude* prelude_);
diff --git a/src/keeper.cpp b/src/keeper.cpp
index 1e344f2..697fe71 100644
--- a/src/keeper.cpp
+++ b/src/keeper.cpp
@@ -166,7 +166,7 @@ static void fifo_pop( lua_State* L, keeper_fifo* fifo_, lua_Integer count_)
166// in: linda_ud expected at *absolute* stack slot idx 166// in: linda_ud expected at *absolute* stack slot idx
167// out: fifos[ud] 167// out: fifos[ud]
168// crc64/we of string "FIFOS_KEY" generated at http://www.nitrxgen.net/hashgen/ 168// crc64/we of string "FIFOS_KEY" generated at http://www.nitrxgen.net/hashgen/
169static DECLARE_CONST_UNIQUE_KEY( FIFOS_KEY, 0xdce50bbc351cd465); 169static constexpr UniqueKey FIFOS_KEY{ 0xdce50bbc351cd465ull };
170static void push_table( lua_State* L, int idx_) 170static void push_table( lua_State* L, int idx_)
171{ 171{
172 STACK_GROW( L, 4); 172 STACK_GROW( L, 4);
@@ -769,13 +769,13 @@ void keeper_toggle_nil_sentinels( lua_State* L, int val_i_, LookupMode const mod
769 { 769 {
770 if( lua_isnil( L, i)) 770 if( lua_isnil( L, i))
771 { 771 {
772 push_unique_key( L, NIL_SENTINEL); 772 NIL_SENTINEL.push(L);
773 lua_replace( L, i); 773 lua_replace( L, i);
774 } 774 }
775 } 775 }
776 else 776 else
777 { 777 {
778 if( equal_unique_key( L, i, NIL_SENTINEL)) 778 if (NIL_SENTINEL.equals(L, i))
779 { 779 {
780 lua_pushnil( L); 780 lua_pushnil( L);
781 lua_replace( L, i); 781 lua_replace( L, i);
diff --git a/src/keeper.h b/src/keeper.h
index 33118be..4cf3605 100644
--- a/src/keeper.h
+++ b/src/keeper.h
@@ -43,7 +43,7 @@ void keeper_toggle_nil_sentinels( lua_State* L, int val_i_, LookupMode const mod
43int keeper_push_linda_storage( Universe* U, lua_State* L, void* ptr_, ptrdiff_t magic_); 43int keeper_push_linda_storage( Universe* U, lua_State* L, void* ptr_, ptrdiff_t magic_);
44 44
45// crc64/we of string "NIL_SENTINEL" generated at http://www.nitrxgen.net/hashgen/ 45// crc64/we of string "NIL_SENTINEL" generated at http://www.nitrxgen.net/hashgen/
46static DECLARE_CONST_UNIQUE_KEY( NIL_SENTINEL, 0x7eaafa003a1d11a1); 46static constexpr UniqueKey NIL_SENTINEL{ 0x7eaafa003a1d11a1ull };
47 47
48typedef lua_CFunction keeper_api_t; 48typedef lua_CFunction keeper_api_t;
49#define KEEPER_API( _op) keepercall_ ## _op 49#define KEEPER_API( _op) keepercall_ ## _op
diff --git a/src/lanes.cpp b/src/lanes.cpp
index fa69656..126f65c 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -128,7 +128,7 @@ static void securize_debug_threadname( lua_State* L, Lane* s)
128#if ERROR_FULL_STACK 128#if ERROR_FULL_STACK
129static int lane_error( lua_State* L); 129static int lane_error( lua_State* L);
130// crc64/we of string "STACKTRACE_REGKEY" generated at http://www.nitrxgen.net/hashgen/ 130// crc64/we of string "STACKTRACE_REGKEY" generated at http://www.nitrxgen.net/hashgen/
131static DECLARE_CONST_UNIQUE_KEY( STACKTRACE_REGKEY, 0x534af7d3226a429f); 131static constexpr UniqueKey STACKTRACE_REGKEY{ 0x534af7d3226a429full };
132#endif // ERROR_FULL_STACK 132#endif // ERROR_FULL_STACK
133 133
134/* 134/*
@@ -140,7 +140,7 @@ static DECLARE_CONST_UNIQUE_KEY( STACKTRACE_REGKEY, 0x534af7d3226a429f);
140* anyways complicate that approach. 140* anyways complicate that approach.
141*/ 141*/
142// crc64/we of string "FINALIZER_REGKEY" generated at http://www.nitrxgen.net/hashgen/ 142// crc64/we of string "FINALIZER_REGKEY" generated at http://www.nitrxgen.net/hashgen/
143static DECLARE_CONST_UNIQUE_KEY( FINALIZER_REGKEY, 0x188fccb8bf348e09); 143static constexpr UniqueKey FINALIZER_REGKEY{ 0x188fccb8bf348e09ull };
144 144
145struct s_Linda; 145struct s_Linda;
146 146
@@ -649,7 +649,7 @@ LUAG_FUNC( set_singlethreaded)
649#if ERROR_FULL_STACK 649#if ERROR_FULL_STACK
650 650
651// crc64/we of string "EXTENDED_STACKTRACE_REGKEY" generated at http://www.nitrxgen.net/hashgen/ 651// crc64/we of string "EXTENDED_STACKTRACE_REGKEY" generated at http://www.nitrxgen.net/hashgen/
652static DECLARE_CONST_UNIQUE_KEY( EXTENDED_STACKTRACE_REGKEY, 0x2357c69a7c92c936); // used as registry key 652static constexpr UniqueKey EXTENDED_STACKTRACE_REGKEY{ 0x2357c69a7c92c936ull }; // used as registry key
653 653
654LUAG_FUNC( set_error_reporting) 654LUAG_FUNC( set_error_reporting)
655{ 655{
@@ -683,7 +683,7 @@ static int lane_error( lua_State* L)
683 683
684 // Don't do stack survey for cancelled lanes. 684 // Don't do stack survey for cancelled lanes.
685 // 685 //
686 if( equal_unique_key( L, 1, CANCEL_ERROR)) 686 if (CANCEL_ERROR.equals(L, 1))
687 { 687 {
688 return 1; // just pass on 688 return 1; // just pass on
689 } 689 }
@@ -769,7 +769,7 @@ static void push_stack_trace( lua_State* L, int rc_, int stk_base_)
769 769
770 // For cancellation the error message is CANCEL_ERROR, and a stack trace isn't placed 770 // For cancellation the error message is CANCEL_ERROR, and a stack trace isn't placed
771 // For other errors, the message can be whatever was thrown, and we should have a stack trace table 771 // For other errors, the message can be whatever was thrown, and we should have a stack trace table
772 ASSERT_L( lua_type( L, 1 + stk_base_) == (equal_unique_key( L, stk_base_, CANCEL_ERROR) ? LUA_TNIL : LUA_TTABLE)); 772 ASSERT_L(lua_type(L, 1 + stk_base_) == (CANCEL_ERROR.equals(L, stk_base_) ? LUA_TNIL : LUA_TTABLE));
773 // Just leaving the stack trace table on the stack is enough to get it through to the master. 773 // Just leaving the stack trace table on the stack is enough to get it through to the master.
774 break; 774 break;
775 } 775 }
@@ -779,14 +779,15 @@ static void push_stack_trace( lua_State* L, int rc_, int stk_base_)
779 case LUA_ERRERR: // error while running the error handler (if any, for example an out-of-memory condition) 779 case LUA_ERRERR: // error while running the error handler (if any, for example an out-of-memory condition)
780 default: 780 default:
781 // we should have a single value which is either a string (the error message) or CANCEL_ERROR 781 // we should have a single value which is either a string (the error message) or CANCEL_ERROR
782 ASSERT_L( (lua_gettop( L) == stk_base_) && ((lua_type( L, stk_base_) == LUA_TSTRING) || equal_unique_key( L, stk_base_, CANCEL_ERROR))); 782 ASSERT_L((lua_gettop(L) == stk_base_) && ((lua_type(L, stk_base_) == LUA_TSTRING) || CANCEL_ERROR.equals(L, stk_base_)));
783 break; 783 break;
784 } 784 }
785} 785}
786 786
787LUAG_FUNC( set_debug_threadname) 787LUAG_FUNC( set_debug_threadname)
788{ 788{
789 DECLARE_CONST_UNIQUE_KEY( hidden_regkey, LG_set_debug_threadname); 789 // fnv164 of string "debug_threadname" generated at https://www.pelock.com/products/hash-calculator
790 constexpr UniqueKey hidden_regkey{ 0x79C0669AAAE04440ull };
790 // C s_lane structure is a light userdata upvalue 791 // C s_lane structure is a light userdata upvalue
791 Lane* s = (Lane*) lua_touserdata( L, lua_upvalueindex( 1)); 792 Lane* s = (Lane*) lua_touserdata( L, lua_upvalueindex( 1));
792 luaL_checktype( L, -1, LUA_TSTRING); // "name" 793 luaL_checktype( L, -1, LUA_TSTRING); // "name"
@@ -959,7 +960,7 @@ static THREAD_RETURN_T THREAD_CALLCONV lane_main( void* vs)
959 { 960 {
960 // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them 961 // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them
961 962
962 enum e_status st = (rc == 0) ? DONE : equal_unique_key( L, 1, CANCEL_ERROR) ? CANCELLED : ERROR_ST; 963 enum e_status st = (rc == 0) ? DONE : CANCEL_ERROR.equals(L, 1) ? CANCELLED : ERROR_ST;
963 964
964 // Posix no PTHREAD_TIMEDJOIN: 965 // Posix no PTHREAD_TIMEDJOIN:
965 // 'done_lock' protects the -> DONE|ERROR_ST|CANCELLED state change 966 // 'done_lock' protects the -> DONE|ERROR_ST|CANCELLED state change
@@ -1024,7 +1025,7 @@ LUAG_FUNC( register)
1024} 1025}
1025 1026
1026// crc64/we of string "GCCB_KEY" generated at http://www.nitrxgen.net/hashgen/ 1027// crc64/we of string "GCCB_KEY" generated at http://www.nitrxgen.net/hashgen/
1027static DECLARE_CONST_UNIQUE_KEY( GCCB_KEY, 0xcfb1f046ef074e88); 1028static constexpr UniqueKey GCCB_KEY{ 0xcfb1f046ef074e88ull };
1028 1029
1029//--- 1030//---
1030// lane_ud = lane_new( function 1031// lane_ud = lane_new( function
@@ -1267,7 +1268,7 @@ LUAG_FUNC( lane_new)
1267 // Store the gc_cb callback in the uservalue 1268 // Store the gc_cb callback in the uservalue
1268 if( gc_cb_idx > 0) 1269 if( gc_cb_idx > 0)
1269 { 1270 {
1270 push_unique_key( L, GCCB_KEY); // func libs priority globals package required gc_cb lane uv k 1271 GCCB_KEY.push(L); // func libs priority globals package required gc_cb lane uv k
1271 lua_pushvalue( L, gc_cb_idx); // func libs priority globals package required gc_cb lane uv k gc_cb 1272 lua_pushvalue( L, gc_cb_idx); // func libs priority globals package required gc_cb lane uv k gc_cb
1272 lua_rawset( L, -3); // func libs priority globals package required gc_cb lane uv 1273 lua_rawset( L, -3); // func libs priority globals package required gc_cb lane uv
1273 } 1274 }
@@ -1307,7 +1308,7 @@ LUAG_FUNC( thread_gc)
1307 1308
1308 // if there a gc callback? 1309 // if there a gc callback?
1309 lua_getiuservalue( L, 1, 1); // ud uservalue 1310 lua_getiuservalue( L, 1, 1); // ud uservalue
1310 push_unique_key( L, GCCB_KEY); // ud uservalue __gc 1311 GCCB_KEY.push(L); // ud uservalue __gc
1311 lua_rawget( L, -2); // ud uservalue gc_cb|nil 1312 lua_rawget( L, -2); // ud uservalue gc_cb|nil
1312 if( !lua_isnil( L, -1)) 1313 if( !lua_isnil( L, -1))
1313 { 1314 {
@@ -1986,7 +1987,7 @@ LUAG_FUNC( configure)
1986 lua_pushinteger(L, THREAD_PRIO_MAX); // settings M THREAD_PRIO_MAX 1987 lua_pushinteger(L, THREAD_PRIO_MAX); // settings M THREAD_PRIO_MAX
1987 lua_setfield( L, -2, "max_prio"); // settings M 1988 lua_setfield( L, -2, "max_prio"); // settings M
1988 1989
1989 push_unique_key( L, CANCEL_ERROR); // settings M CANCEL_ERROR 1990 CANCEL_ERROR.push(L); // settings M CANCEL_ERROR
1990 lua_setfield( L, -2, "cancel_error"); // settings M 1991 lua_setfield( L, -2, "cancel_error"); // settings M
1991 1992
1992 STACK_MID( L, 2); // reference stack contains only the function argument 'settings' 1993 STACK_MID( L, 2); // reference stack contains only the function argument 'settings'
diff --git a/src/linda.cpp b/src/linda.cpp
index fa27871..4cc356a 100644
--- a/src/linda.cpp
+++ b/src/linda.cpp
@@ -137,7 +137,7 @@ LUAG_FUNC( linda_send)
137 ++ key_i; 137 ++ key_i;
138 } 138 }
139 139
140 bool const as_nil_sentinel{ equal_unique_key(L, key_i, NIL_SENTINEL) };// if not nullptr, send() will silently send a single nil if nothing is provided 140 bool const as_nil_sentinel{ NIL_SENTINEL.equals(L, key_i) }; // if not nullptr, send() will silently send a single nil if nothing is provided
141 if( as_nil_sentinel) 141 if( as_nil_sentinel)
142 { 142 {
143 // the real key to send data to is after the NIL_SENTINEL marker 143 // the real key to send data to is after the NIL_SENTINEL marker
@@ -155,7 +155,7 @@ LUAG_FUNC( linda_send)
155 if( as_nil_sentinel) 155 if( as_nil_sentinel)
156 { 156 {
157 // send a single nil if nothing is provided 157 // send a single nil if nothing is provided
158 push_unique_key( L, NIL_SENTINEL); 158 NIL_SENTINEL.push(L);
159 } 159 }
160 else 160 else
161 { 161 {
@@ -243,7 +243,7 @@ LUAG_FUNC( linda_send)
243 { 243 {
244 case CANCEL_SOFT: 244 case CANCEL_SOFT:
245 // if user wants to soft-cancel, the call returns lanes.cancel_error 245 // if user wants to soft-cancel, the call returns lanes.cancel_error
246 push_unique_key( L, CANCEL_ERROR); 246 CANCEL_ERROR.push(L);
247 return 1; 247 return 1;
248 248
249 case CANCEL_HARD: 249 case CANCEL_HARD:
@@ -397,7 +397,7 @@ LUAG_FUNC( linda_receive)
397 { 397 {
398 case CANCEL_SOFT: 398 case CANCEL_SOFT:
399 // if user wants to soft-cancel, the call returns CANCEL_ERROR 399 // if user wants to soft-cancel, the call returns CANCEL_ERROR
400 push_unique_key( L, CANCEL_ERROR); 400 CANCEL_ERROR.push(L);
401 return 1; 401 return 1;
402 402
403 case CANCEL_HARD: 403 case CANCEL_HARD:
@@ -458,7 +458,7 @@ LUAG_FUNC( linda_set)
458 else // linda is cancelled 458 else // linda is cancelled
459 { 459 {
460 // do nothing and return lanes.cancel_error 460 // do nothing and return lanes.cancel_error
461 push_unique_key( L, CANCEL_ERROR); 461 CANCEL_ERROR.push(L);
462 pushed = 1; 462 pushed = 1;
463 } 463 }
464 } 464 }
@@ -522,7 +522,7 @@ LUAG_FUNC( linda_get)
522 else // linda is cancelled 522 else // linda is cancelled
523 { 523 {
524 // do nothing and return lanes.cancel_error 524 // do nothing and return lanes.cancel_error
525 push_unique_key( L, CANCEL_ERROR); 525 CANCEL_ERROR.push(L);
526 pushed = 1; 526 pushed = 1;
527 } 527 }
528 // an error can be raised if we attempt to read an unregistered function 528 // an error can be raised if we attempt to read an unregistered function
@@ -570,7 +570,7 @@ LUAG_FUNC( linda_limit)
570 else // linda is cancelled 570 else // linda is cancelled
571 { 571 {
572 // do nothing and return lanes.cancel_error 572 // do nothing and return lanes.cancel_error
573 push_unique_key( L, CANCEL_ERROR); 573 CANCEL_ERROR.push(L);
574 pushed = 1; 574 pushed = 1;
575 } 575 }
576 } 576 }
@@ -798,7 +798,7 @@ static void* linda_id( lua_State* L, DeepOp op_)
798 } 798 }
799 if( s) 799 if( s)
800 { 800 {
801 s->prelude.magic.value = DEEP_VERSION.value; 801 s->prelude.DeepPrelude::DeepPrelude();
802 SIGNAL_INIT( &s->read_happened); 802 SIGNAL_INIT( &s->read_happened);
803 SIGNAL_INIT( &s->write_happened); 803 SIGNAL_INIT( &s->write_happened);
804 s->U = universe_get( L); 804 s->U = universe_get( L);
@@ -901,7 +901,7 @@ static void* linda_id( lua_State* L, DeepOp op_)
901 lua_pushliteral( L, BATCH_SENTINEL); 901 lua_pushliteral( L, BATCH_SENTINEL);
902 lua_setfield( L, -2, "batched"); 902 lua_setfield( L, -2, "batched");
903 903
904 push_unique_key( L, NIL_SENTINEL); 904 NIL_SENTINEL.push(L);
905 lua_setfield( L, -2, "null"); 905 lua_setfield( L, -2, "null");
906 906
907 STACK_END( L, 1); 907 STACK_END( L, 1);
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h
index 8a4ffb3..ae93e97 100644
--- a/src/macros_and_utils.h
+++ b/src/macros_and_utils.h
@@ -83,14 +83,14 @@ extern char const* debugspew_indent;
83// non-string keyed registry access 83// non-string keyed registry access
84#define REGISTRY_SET( L, key_, value_) \ 84#define REGISTRY_SET( L, key_, value_) \
85{ \ 85{ \
86 push_unique_key( L, key_); \ 86 key_.push(L); \
87 value_; \ 87 value_; \
88 lua_rawset( L, LUA_REGISTRYINDEX); \ 88 lua_rawset( L, LUA_REGISTRYINDEX); \
89} 89}
90 90
91#define REGISTRY_GET( L, key_) \ 91#define REGISTRY_GET( L, key_) \
92{ \ 92{ \
93 push_unique_key( L, key_); \ 93 key_.push(L); \
94 lua_rawget( L, LUA_REGISTRYINDEX); \ 94 lua_rawget( L, LUA_REGISTRYINDEX); \
95} 95}
96 96
diff --git a/src/tools.cpp b/src/tools.cpp
index e6ebdba..ac2cf75 100644
--- a/src/tools.cpp
+++ b/src/tools.cpp
@@ -328,7 +328,7 @@ static lua_CFunction luaG_tocfunction( lua_State *L, int _i, FuncSubType *_out)
328} 328}
329 329
330// crc64/we of string "LOOKUPCACHE_REGKEY" generated at http://www.nitrxgen.net/hashgen/ 330// crc64/we of string "LOOKUPCACHE_REGKEY" generated at http://www.nitrxgen.net/hashgen/
331static DECLARE_CONST_UNIQUE_KEY( LOOKUPCACHE_REGKEY, 0x837a68dfc6fcb716); 331static constexpr UniqueKey LOOKUPCACHE_REGKEY{ 0x837a68dfc6fcb716ull };
332 332
333// inspired from tconcat() in ltablib.c 333// inspired from tconcat() in ltablib.c
334static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length) 334static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length)
@@ -627,7 +627,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
627/*---=== Inter-state copying ===---*/ 627/*---=== Inter-state copying ===---*/
628 628
629// crc64/we of string "REG_MTID" generated at http://www.nitrxgen.net/hashgen/ 629// crc64/we of string "REG_MTID" generated at http://www.nitrxgen.net/hashgen/
630static DECLARE_CONST_UNIQUE_KEY( REG_MTID, 0x2e68f9b4751584dc); 630static constexpr UniqueKey REG_MTID{ 0x2e68f9b4751584dcull };
631 631
632/* 632/*
633* Get a unique ID for metatable at [i]. 633* Get a unique ID for metatable at [i].
@@ -845,7 +845,7 @@ static bool lookup_table( lua_State* L2, lua_State* L, uint_t i, LookupMode mode
845static bool push_cached_table( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i) 845static bool push_cached_table( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i)
846{ 846{
847 bool not_found_in_cache; // L2 847 bool not_found_in_cache; // L2
848 DECLARE_CONST_UNIQUE_KEY( p, lua_topointer( L, i)); 848 void const* p{ lua_topointer(L, i) };
849 849
850 ASSERT_L( L2_cache_i != 0); 850 ASSERT_L( L2_cache_i != 0);
851 STACK_GROW( L2, 3); 851 STACK_GROW( L2, 3);
@@ -854,7 +854,7 @@ static bool push_cached_table( lua_State* L2, uint_t L2_cache_i, lua_State* L, u
854 // We don't need to use the from state ('L') in ID since the life span 854 // We don't need to use the from state ('L') in ID since the life span
855 // is only for the duration of a copy (both states are locked). 855 // is only for the duration of a copy (both states are locked).
856 // push a light userdata uniquely representing the table 856 // push a light userdata uniquely representing the table
857 push_unique_key( L2, p); // ... p 857 lua_pushlightuserdata(L2, const_cast<void*>(p)); // ... p
858 858
859 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring( L2, -1)); 859 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring( L2, -1));
860 860
@@ -864,7 +864,7 @@ static bool push_cached_table( lua_State* L2, uint_t L2_cache_i, lua_State* L, u
864 { 864 {
865 lua_pop( L2, 1); // ... 865 lua_pop( L2, 1); // ...
866 lua_newtable( L2); // ... {} 866 lua_newtable( L2); // ... {}
867 push_unique_key( L2, p); // ... {} p 867 lua_pushlightuserdata(L2, const_cast<void*>(p)); // ... {} p
868 lua_pushvalue( L2, -2); // ... {} p {} 868 lua_pushvalue( L2, -2); // ... {} p {}
869 lua_rawset( L2, L2_cache_i); // ... {} 869 lua_rawset( L2, L2_cache_i); // ... {}
870 } 870 }
@@ -1508,7 +1508,7 @@ static void inter_copy_keyvaluepair( Universe* U, lua_State* L2, uint_t L2_cache
1508* The clone cache is a weak valued table listing all clones, indexed by their userdatapointer 1508* The clone cache is a weak valued table listing all clones, indexed by their userdatapointer
1509* fnv164 of string "CLONABLES_CACHE_KEY" generated at https://www.pelock.com/products/hash-calculator 1509* fnv164 of string "CLONABLES_CACHE_KEY" generated at https://www.pelock.com/products/hash-calculator
1510*/ 1510*/
1511static DECLARE_CONST_UNIQUE_KEY( CLONABLES_CACHE_KEY, 0xD04EE018B3DEE8F5); 1511static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull };
1512 1512
1513static bool copyclone( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t source_i_, LookupMode mode_, char const* upName_) 1513static bool copyclone( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t source_i_, LookupMode mode_, char const* upName_)
1514{ 1514{
diff --git a/src/tools.h b/src/tools.h
index 9214d85..928a149 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -47,7 +47,7 @@ void cleanup_allocator_function( Universe* U, lua_State* L);
47// ################################################################################################ 47// ################################################################################################
48 48
49// crc64/we of string "CONFIG_REGKEY" generated at http://www.nitrxgen.net/hashgen/ 49// crc64/we of string "CONFIG_REGKEY" generated at http://www.nitrxgen.net/hashgen/
50static DECLARE_CONST_UNIQUE_KEY( CONFIG_REGKEY, 0x31cd24894eae8624); // 'cancel_error' sentinel 50static constexpr UniqueKey CONFIG_REGKEY{ 0x31cd24894eae8624ull }; // registry key to access the configuration
51 51
52// crc64/we of string "LOOKUP_REGKEY" generated at http://www.nitrxgen.net/hashgen/ 52// crc64/we of string "LOOKUP_REGKEY" generated at http://www.nitrxgen.net/hashgen/
53static DECLARE_CONST_UNIQUE_KEY( LOOKUP_REGKEY, 0x5051ed67ee7b51a1); // 'cancel_error' sentinel 53static constexpr UniqueKey LOOKUP_REGKEY{ 0x5051ed67ee7b51a1ull }; // registry key to access the lookup database
diff --git a/src/uniquekey.h b/src/uniquekey.h
index f219ab1..fb98628 100644
--- a/src/uniquekey.h
+++ b/src/uniquekey.h
@@ -2,21 +2,40 @@
2 2
3#include "compat.h" 3#include "compat.h"
4 4
5// Lua light userdata can hold a pointer. 5class UniqueKey
6struct s_UniqueKey
7{ 6{
8 void* value; 7 private:
9}; 8
10typedef struct s_UniqueKey UniqueKey; 9 uintptr_t m_storage;
10
11 public:
11 12
13 constexpr UniqueKey(uintptr_t val_)
12#if LUAJIT_FLAVOR() == 64 // building against LuaJIT headers for 64 bits, light userdata is restricted to 47 significant bits, because LuaJIT uses the other bits for internal optimizations 14#if LUAJIT_FLAVOR() == 64 // building against LuaJIT headers for 64 bits, light userdata is restricted to 47 significant bits, because LuaJIT uses the other bits for internal optimizations
13#define MAKE_UNIQUE_KEY( p_) ((void*)((ptrdiff_t)(p_) & 0x7fffffffffffull)) 15 : m_storage{ val_ & 0x7fffffffffffull }
14#else // LUAJIT_FLAVOR() 16#else // LUAJIT_FLAVOR()
15#define MAKE_UNIQUE_KEY( p_) ((void*)(ptrdiff_t)(p_)) 17 : m_storage{ val_ }
16#endif // LUAJIT_FLAVOR() 18#endif // LUAJIT_FLAVOR()
19 {
20 }
21 constexpr UniqueKey(UniqueKey const& rhs_) = default;
22 constexpr bool operator!=(UniqueKey const& rhs_) const
23 {
24 return m_storage != rhs_.m_storage;
25 }
26 constexpr bool operator==(UniqueKey const& rhs_) const
27 {
28 return m_storage == rhs_.m_storage;
29 }
17 30
18#define DECLARE_UNIQUE_KEY( name_) UniqueKey name_ 31 void push(lua_State* const L) const
19#define DECLARE_CONST_UNIQUE_KEY( name_, p_) UniqueKey const name_ = { MAKE_UNIQUE_KEY( p_)} 32 {
20 33 // unfortunately, converting a scalar to a pointer must go through a C cast
21#define push_unique_key( L, key_) lua_pushlightuserdata( L, key_.value) 34 lua_pushlightuserdata(L, (void*) m_storage);
22#define equal_unique_key( L, i, key_) (lua_touserdata( L, i) == key_.value) 35 }
36 bool equals(lua_State* const L, int i) const
37 {
38 // unfortunately, converting a scalar to a pointer must go through a C cast
39 return lua_touserdata(L, i) == (void*) m_storage;
40 }
41};
diff --git a/src/universe.cpp b/src/universe.cpp
index d5cc9e2..a31189c 100644
--- a/src/universe.cpp
+++ b/src/universe.cpp
@@ -37,7 +37,7 @@ THE SOFTWARE.
37#include "uniquekey.h" 37#include "uniquekey.h"
38 38
39// crc64/we of string "UNIVERSE_REGKEY" generated at http://www.nitrxgen.net/hashgen/ 39// crc64/we of string "UNIVERSE_REGKEY" generated at http://www.nitrxgen.net/hashgen/
40static DECLARE_CONST_UNIQUE_KEY( UNIVERSE_REGKEY, 0x9f877b2cf078f17f); 40static constexpr UniqueKey UNIVERSE_REGKEY{ 0x9f877b2cf078f17full };
41 41
42// ################################################################################################ 42// ################################################################################################
43 43
diff --git a/src/universe.h b/src/universe.h
index 77b3ea5..0599302 100644
--- a/src/universe.h
+++ b/src/universe.h
@@ -12,8 +12,7 @@ extern "C" {
12#include "macros_and_utils.h" 12#include "macros_and_utils.h"
13 13
14// forwards 14// forwards
15struct s_DeepPrelude; 15struct DeepPrelude;
16typedef struct s_DeepPrelude DeepPrelude;
17struct s_Keepers; 16struct s_Keepers;
18typedef struct s_Keepers Keepers; 17typedef struct s_Keepers Keepers;
19struct s_Lane; 18struct s_Lane;