aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <b n t DOT g e r m a i n AT g m a i l DOT c o m>2018-10-30 14:18:10 +0100
committerBenoit Germain <b n t DOT g e r m a i n AT g m a i l DOT c o m>2018-10-30 14:18:10 +0100
commitd82bf70e9db3a25ec451b599660f3a837f21caee (patch)
treee9e861252a118c8c66e874fedb93c2a32733aa0f /src
parentea9e8a3af1c2357c454ef18c8136c14a22b8675a (diff)
downloadlanes-d82bf70e9db3a25ec451b599660f3a837f21caee.tar.gz
lanes-d82bf70e9db3a25ec451b599660f3a837f21caee.tar.bz2
lanes-d82bf70e9db3a25ec451b599660f3a837f21caee.zip
Improve LuaJIT-x64 compatibility
Restrict internal "light userdata constants" to 47 significant bits when compiling against LuaJIT-x64
Diffstat (limited to 'src')
-rw-r--r--src/deep.c20
-rw-r--r--src/keeper.c16
-rw-r--r--src/keeper.h4
-rw-r--r--src/lanes.c74
-rw-r--r--src/tools.c7
-rw-r--r--src/uniquekey.h25
-rw-r--r--src/universe.c11
7 files changed, 98 insertions, 59 deletions
diff --git a/src/deep.c b/src/deep.c
index 82350f4..fe7a21f 100644
--- a/src/deep.c
+++ b/src/deep.c
@@ -44,6 +44,7 @@ THE SOFTWARE.
44#include "deep.h" 44#include "deep.h"
45#include "tools.h" 45#include "tools.h"
46#include "universe.h" 46#include "universe.h"
47#include "uniquekey.h"
47 48
48/*-- Metatable copying --*/ 49/*-- Metatable copying --*/
49 50
@@ -59,19 +60,19 @@ THE SOFTWARE.
59/* 60/*
60* Does what the original 'push_registry_subtable' function did, but adds an optional mode argument to it 61* Does what the original 'push_registry_subtable' function did, but adds an optional mode argument to it
61*/ 62*/
62void push_registry_subtable_mode( lua_State* L, void* key_, const char* mode_) 63static void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode_)
63{ 64{
64 STACK_GROW( L, 3); 65 STACK_GROW( L, 3);
65 STACK_CHECK( L); 66 STACK_CHECK( L);
66 67
67 lua_pushlightuserdata( L, key_); // key 68 push_unique_key( L, key_); // key
68 lua_rawget( L, LUA_REGISTRYINDEX); // {}|nil 69 lua_rawget( L, LUA_REGISTRYINDEX); // {}|nil
69 70
70 if( lua_isnil( L, -1)) 71 if( lua_isnil( L, -1))
71 { 72 {
72 lua_pop( L, 1); // 73 lua_pop( L, 1); //
73 lua_newtable( L); // {} 74 lua_newtable( L); // {}
74 lua_pushlightuserdata( L, key_); // {} key 75 push_unique_key( L, key_); // {} key
75 lua_pushvalue( L, -2); // {} key {} 76 lua_pushvalue( L, -2); // {} key {}
76 77
77 // _R[key_] = {} 78 // _R[key_] = {}
@@ -96,7 +97,7 @@ void push_registry_subtable_mode( lua_State* L, void* key_, const char* mode_)
96* Push a registry subtable (keyed by unique 'key_') onto the stack. 97* Push a registry subtable (keyed by unique 'key_') onto the stack.
97* If the subtable does not exist, it is created and chained. 98* If the subtable does not exist, it is created and chained.
98*/ 99*/
99void push_registry_subtable( lua_State* L, void* key_) 100void push_registry_subtable( lua_State* L, UniqueKey key_)
100{ 101{
101 push_registry_subtable_mode( L, key_, NULL); 102 push_registry_subtable_mode( L, key_, NULL);
102} 103}
@@ -121,15 +122,14 @@ void luaG_pushdeepversion( lua_State* L) { (void) lua_pushliteral( L, "ab8743e5-
121* metatable -> idfunc 122* metatable -> idfunc
122* idfunc -> metatable 123* idfunc -> metatable
123*/ 124*/
124// crc64/we of string "DEEP_LOOKUP_KEY" generated at https://www.nitrxgen.net/hashgen/ 125// crc64/we of string "DEEP_LOOKUP_KEY" generated at http://www.nitrxgen.net/hashgen/
125#define DEEP_LOOKUP_KEY ((void*)0x9fb9b4f3f633d83d) 126static DECLARE_CONST_UNIQUE_KEY( DEEP_LOOKUP_KEY, (void*)0x9fb9b4f3f633d83d);
126
127 127
128/* 128/*
129 * The deep proxy cache is a weak valued table listing all deep UD proxies indexed by the deep UD that they are proxying 129 * The deep proxy cache is a weak valued table listing all deep UD proxies indexed by the deep UD that they are proxying
130 * crc64/we of string "DEEP_PROXY_CACHE_KEY" generated at https://www.nitrxgen.net/hashgen/ 130 * crc64/we of string "DEEP_PROXY_CACHE_KEY" generated at http://www.nitrxgen.net/hashgen/
131*/ 131*/
132#define DEEP_PROXY_CACHE_KEY ((void*)0x05773d6fc26be106) 132static DECLARE_CONST_UNIQUE_KEY( DEEP_PROXY_CACHE_KEY, (void*)0x05773d6fc26be106);
133 133
134/* 134/*
135* Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. 135* Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists.
@@ -158,7 +158,7 @@ static void get_deep_lookup( lua_State* L)
158{ 158{
159 STACK_GROW( L, 1); 159 STACK_GROW( L, 1);
160 STACK_CHECK( L); // a 160 STACK_CHECK( L); // a
161 lua_pushlightuserdata( L, DEEP_LOOKUP_KEY); // a DLK 161 push_unique_key( L, DEEP_LOOKUP_KEY); // a DLK
162 lua_rawget( L, LUA_REGISTRYINDEX); // a {} 162 lua_rawget( L, LUA_REGISTRYINDEX); // a {}
163 163
164 if( !lua_isnil( L, -1)) 164 if( !lua_isnil( L, -1))
diff --git a/src/keeper.c b/src/keeper.c
index 907334f..715583b 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -48,6 +48,7 @@
48#include "compat.h" 48#include "compat.h"
49#include "tools.h" 49#include "tools.h"
50#include "universe.h" 50#include "universe.h"
51#include "uniquekey.h"
51 52
52//################################################################################### 53//###################################################################################
53// Keeper implementation 54// Keeper implementation
@@ -160,13 +161,14 @@ static void fifo_pop( lua_State* L, keeper_fifo* fifo_, lua_Integer count_)
160 161
161// in: linda_ud expected at *absolute* stack slot idx 162// in: linda_ud expected at *absolute* stack slot idx
162// out: fifos[ud] 163// out: fifos[ud]
163static void* const fifos_key = (void*) prepare_fifo_access; 164// crc64/we of string "FIFOS_KEY" generated at http://www.nitrxgen.net/hashgen/
165static DECLARE_CONST_UNIQUE_KEY( FIFOS_KEY, 0xdce50bbc351cd465);
164static void push_table( lua_State* L, int idx_) 166static void push_table( lua_State* L, int idx_)
165{ 167{
166 STACK_GROW( L, 4); 168 STACK_GROW( L, 4);
167 STACK_CHECK( L); 169 STACK_CHECK( L);
168 idx_ = lua_absindex( L, idx_); 170 idx_ = lua_absindex( L, idx_);
169 lua_pushlightuserdata( L, fifos_key); // ud fifos_key 171 push_unique_key( L, FIFOS_KEY); // ud fifos_key
170 lua_rawget( L, LUA_REGISTRYINDEX); // ud fifos 172 lua_rawget( L, LUA_REGISTRYINDEX); // ud fifos
171 lua_pushvalue( L, idx_); // ud fifos ud 173 lua_pushvalue( L, idx_); // ud fifos ud
172 lua_rawget( L, -2); // ud fifos fifos[ud] 174 lua_rawget( L, -2); // ud fifos fifos[ud]
@@ -191,7 +193,7 @@ int keeper_push_linda_storage( Universe* U, lua_State* L, void* ptr_, ptrdiff_t
191 if( KL == NULL) return 0; 193 if( KL == NULL) return 0;
192 STACK_GROW( KL, 4); 194 STACK_GROW( KL, 4);
193 STACK_CHECK( KL); 195 STACK_CHECK( KL);
194 lua_pushlightuserdata( KL, fifos_key); // fifos_key 196 push_unique_key( KL, FIFOS_KEY); // fifos_key
195 lua_rawget( KL, LUA_REGISTRYINDEX); // fifos 197 lua_rawget( KL, LUA_REGISTRYINDEX); // fifos
196 lua_pushlightuserdata( KL, ptr_); // fifos ud 198 lua_pushlightuserdata( KL, ptr_); // fifos ud
197 lua_rawget( KL, -2); // fifos storage 199 lua_rawget( KL, -2); // fifos storage
@@ -239,7 +241,7 @@ int keeper_push_linda_storage( Universe* U, lua_State* L, void* ptr_, ptrdiff_t
239int keepercall_clear( lua_State* L) 241int keepercall_clear( lua_State* L)
240{ 242{
241 STACK_GROW( L, 3); 243 STACK_GROW( L, 3);
242 lua_pushlightuserdata( L, fifos_key); // ud fifos_key 244 push_unique_key( L, FIFOS_KEY); // ud fifos_key
243 lua_rawget( L, LUA_REGISTRYINDEX); // ud fifos 245 lua_rawget( L, LUA_REGISTRYINDEX); // ud fifos
244 lua_pushvalue( L, 1); // ud fifos ud 246 lua_pushvalue( L, 1); // ud fifos ud
245 lua_pushnil( L); // ud fifos ud nil 247 lua_pushnil( L); // ud fifos ud nil
@@ -704,7 +706,7 @@ void init_keepers( Universe* U, lua_State* L)
704 lua_setglobal( K, "decoda_name"); // 706 lua_setglobal( K, "decoda_name"); //
705 707
706 // create the fifos table in the keeper state 708 // create the fifos table in the keeper state
707 lua_pushlightuserdata( K, fifos_key); // fifo_key 709 push_unique_key( K, FIFOS_KEY); // fifo_key
708 lua_newtable( K); // fifo_key {} 710 lua_newtable( K); // fifo_key {}
709 lua_rawset( K, LUA_REGISTRYINDEX); // 711 lua_rawset( K, LUA_REGISTRYINDEX); //
710 712
@@ -754,13 +756,13 @@ void keeper_toggle_nil_sentinels( lua_State* L, int val_i_, LookupMode mode_)
754 { 756 {
755 if( lua_isnil( L, i)) 757 if( lua_isnil( L, i))
756 { 758 {
757 lua_pushlightuserdata( L, NIL_SENTINEL); 759 push_unique_key( L, NIL_SENTINEL);
758 lua_replace( L, i); 760 lua_replace( L, i);
759 } 761 }
760 } 762 }
761 else 763 else
762 { 764 {
763 if( lua_touserdata( L, i) == NIL_SENTINEL) 765 if( equal_unique_key( L, i, NIL_SENTINEL))
764 { 766 {
765 lua_pushnil( L); 767 lua_pushnil( L);
766 lua_replace( L, i); 768 lua_replace( L, i);
diff --git a/src/keeper.h b/src/keeper.h
index 06cf3be..37922fb 100644
--- a/src/keeper.h
+++ b/src/keeper.h
@@ -3,6 +3,7 @@
3 3
4#include "lua.h" 4#include "lua.h"
5#include "threading.h" 5#include "threading.h"
6#include "uniquekey.h"
6 7
7// forwards 8// forwards
8struct s_Universe; 9struct s_Universe;
@@ -34,7 +35,8 @@ void keeper_release( Keeper* K);
34void keeper_toggle_nil_sentinels( lua_State* L, int val_i_, LookupMode const mode_); 35void keeper_toggle_nil_sentinels( lua_State* L, int val_i_, LookupMode const mode_);
35int keeper_push_linda_storage( Universe* U, lua_State* L, void* ptr_, ptrdiff_t magic_); 36int keeper_push_linda_storage( Universe* U, lua_State* L, void* ptr_, ptrdiff_t magic_);
36 37
37#define NIL_SENTINEL ((void*)keeper_toggle_nil_sentinels) 38// crc64/we of string "NIL_SENTINEL" generated at http://www.nitrxgen.net/hashgen/
39static DECLARE_CONST_UNIQUE_KEY( NIL_SENTINEL, 0x7eaafa003a1d11a1);
38 40
39typedef lua_CFunction keeper_api_t; 41typedef lua_CFunction keeper_api_t;
40#define KEEPER_API( _op) keepercall_ ## _op 42#define KEEPER_API( _op) keepercall_ ## _op
diff --git a/src/lanes.c b/src/lanes.c
index 0a04d88..5a1f94a 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -93,6 +93,7 @@ THE SOFTWARE.
93#include "tools.h" 93#include "tools.h"
94#include "universe.h" 94#include "universe.h"
95#include "keeper.h" 95#include "keeper.h"
96#include "uniquekey.h"
96 97
97#if !(defined( PLATFORM_XBOX) || defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC)) 98#if !(defined( PLATFORM_XBOX) || defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC))
98# include <sys/time.h> 99# include <sys/time.h>
@@ -193,13 +194,15 @@ typedef struct s_Lane Lane;
193// 194//
194#define lua_toLane( L, i) (*((Lane**) luaL_checkudata( L, i, "Lane"))) 195#define lua_toLane( L, i) (*((Lane**) luaL_checkudata( L, i, "Lane")))
195 196
196#define CANCEL_TEST_KEY ((void*)get_lane_from_registry) // used as registry key 197// crc64/we of string "CANCEL_TEST_KEY" generated at http://www.nitrxgen.net/hashgen/
198static DECLARE_CONST_UNIQUE_KEY( CANCEL_TEST_KEY, 0xe66f5960c57d133a); // used as registry key
199
197static inline Lane* get_lane_from_registry( lua_State* L) 200static inline Lane* get_lane_from_registry( lua_State* L)
198{ 201{
199 Lane* s; 202 Lane* s;
200 STACK_GROW( L, 1); 203 STACK_GROW( L, 1);
201 STACK_CHECK( L); 204 STACK_CHECK( L);
202 lua_pushlightuserdata( L, CANCEL_TEST_KEY); 205 push_unique_key( L, CANCEL_TEST_KEY);
203 lua_rawget( L, LUA_REGISTRYINDEX); 206 lua_rawget( L, LUA_REGISTRYINDEX);
204 s = lua_touserdata( L, -1); // lightuserdata (true 's_lane' pointer) / nil 207 s = lua_touserdata( L, -1); // lightuserdata (true 's_lane' pointer) / nil
205 lua_pop( L, 1); 208 lua_pop( L, 1);
@@ -238,11 +241,13 @@ static inline enum e_cancel_request cancel_test( lua_State* L)
238 return s ? s->cancel_request : CANCEL_NONE; 241 return s ? s->cancel_request : CANCEL_NONE;
239} 242}
240 243
241#define CANCEL_ERROR ((void*)cancel_error) // 'cancel_error' sentinel 244// crc64/we of string "CANCEL_ERROR" generated at http://www.nitrxgen.net/hashgen/
245static DECLARE_CONST_UNIQUE_KEY( CANCEL_ERROR, 0xe97d41626cc97577); // 'cancel_error' sentinel
246
242static int cancel_error( lua_State* L) 247static int cancel_error( lua_State* L)
243{ 248{
244 STACK_GROW( L, 1); 249 STACK_GROW( L, 1);
245 lua_pushlightuserdata( L, CANCEL_ERROR); // special error value 250 push_unique_key( L, CANCEL_ERROR); // special error value
246 return lua_error( L); // doesn't return 251 return lua_error( L); // doesn't return
247} 252}
248 253
@@ -258,7 +263,8 @@ static void cancel_hook( lua_State* L, lua_Debug* ar)
258 263
259#if ERROR_FULL_STACK 264#if ERROR_FULL_STACK
260static int lane_error( lua_State* L); 265static int lane_error( lua_State* L);
261#define STACK_TRACE_KEY ((void*)lane_error) // used as registry key 266// crc64/we of string "STACK_TRACE_KEY" generated at http://www.nitrxgen.net/hashgen/
267static DECLARE_CONST_UNIQUE_KEY( STACK_TRACE_KEY, 0x024d5411677ce879);
262#endif // ERROR_FULL_STACK 268#endif // ERROR_FULL_STACK
263 269
264/* 270/*
@@ -463,7 +469,7 @@ LUAG_FUNC( linda_send)
463 int pushed; 469 int pushed;
464 time_d timeout = -1.0; 470 time_d timeout = -1.0;
465 uint_t key_i = 2; // index of first key, if timeout not there 471 uint_t key_i = 2; // index of first key, if timeout not there
466 void* as_nil_sentinel; // if not NULL, send() will silently send a single nil if nothing is provided 472 bool_t as_nil_sentinel; // if not NULL, send() will silently send a single nil if nothing is provided
467 473
468 if( lua_type( L, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion 474 if( lua_type( L, 2) == LUA_TNUMBER) // we don't want to use lua_isnumber() because of autocoercion
469 { 475 {
@@ -475,8 +481,8 @@ LUAG_FUNC( linda_send)
475 ++ key_i; 481 ++ key_i;
476 } 482 }
477 483
478 as_nil_sentinel = lua_touserdata( L, key_i); 484 as_nil_sentinel = equal_unique_key( L, key_i, NIL_SENTINEL);
479 if( as_nil_sentinel == NIL_SENTINEL) 485 if( as_nil_sentinel)
480 { 486 {
481 // the real key to send data to is after the NIL_SENTINEL marker 487 // the real key to send data to is after the NIL_SENTINEL marker
482 ++ key_i; 488 ++ key_i;
@@ -490,10 +496,10 @@ LUAG_FUNC( linda_send)
490 // make sure there is something to send 496 // make sure there is something to send
491 if( (uint_t)lua_gettop( L) == key_i) 497 if( (uint_t)lua_gettop( L) == key_i)
492 { 498 {
493 if( as_nil_sentinel == NIL_SENTINEL) 499 if( as_nil_sentinel)
494 { 500 {
495 // send a single nil if nothing is provided 501 // send a single nil if nothing is provided
496 lua_pushlightuserdata( L, NIL_SENTINEL); 502 push_unique_key( L, NIL_SENTINEL);
497 } 503 }
498 else 504 else
499 { 505 {
@@ -584,7 +590,7 @@ LUAG_FUNC( linda_send)
584 { 590 {
585 case CANCEL_SOFT: 591 case CANCEL_SOFT:
586 // if user wants to soft-cancel, the call returns lanes.cancel_error 592 // if user wants to soft-cancel, the call returns lanes.cancel_error
587 lua_pushlightuserdata( L, CANCEL_ERROR); 593 push_unique_key( L, CANCEL_ERROR);
588 return 1; 594 return 1;
589 595
590 case CANCEL_HARD: 596 case CANCEL_HARD:
@@ -741,7 +747,7 @@ LUAG_FUNC( linda_receive)
741 { 747 {
742 case CANCEL_SOFT: 748 case CANCEL_SOFT:
743 // if user wants to soft-cancel, the call returns CANCEL_ERROR 749 // if user wants to soft-cancel, the call returns CANCEL_ERROR
744 lua_pushlightuserdata( L, CANCEL_ERROR); 750 push_unique_key( L, CANCEL_ERROR);
745 return 1; 751 return 1;
746 752
747 case CANCEL_HARD: 753 case CANCEL_HARD:
@@ -803,7 +809,7 @@ LUAG_FUNC( linda_set)
803 else // linda is cancelled 809 else // linda is cancelled
804 { 810 {
805 // do nothing and return lanes.cancel_error 811 // do nothing and return lanes.cancel_error
806 lua_pushlightuserdata( L, CANCEL_ERROR); 812 push_unique_key( L, CANCEL_ERROR);
807 pushed = 1; 813 pushed = 1;
808 } 814 }
809 keeper_release( K); 815 keeper_release( K);
@@ -871,7 +877,7 @@ LUAG_FUNC( linda_get)
871 else // linda is cancelled 877 else // linda is cancelled
872 { 878 {
873 // do nothing and return lanes.cancel_error 879 // do nothing and return lanes.cancel_error
874 lua_pushlightuserdata( L, CANCEL_ERROR); 880 push_unique_key( L, CANCEL_ERROR);
875 pushed = 1; 881 pushed = 1;
876 } 882 }
877 keeper_release( K); 883 keeper_release( K);
@@ -922,7 +928,7 @@ LUAG_FUNC( linda_limit)
922 else // linda is cancelled 928 else // linda is cancelled
923 { 929 {
924 // do nothing and return lanes.cancel_error 930 // do nothing and return lanes.cancel_error
925 lua_pushlightuserdata( L, CANCEL_ERROR); 931 push_unique_key( L, CANCEL_ERROR);
926 pushed = 1; 932 pushed = 1;
927 } 933 }
928 keeper_release( K); 934 keeper_release( K);
@@ -1249,7 +1255,7 @@ static void* linda_id( lua_State* L, enum eDeepOp op_)
1249 lua_pushliteral( L, BATCH_SENTINEL); 1255 lua_pushliteral( L, BATCH_SENTINEL);
1250 lua_setfield(L, -2, "batched"); 1256 lua_setfield(L, -2, "batched");
1251 1257
1252 lua_pushlightuserdata( L, NIL_SENTINEL); 1258 push_unique_key( L, NIL_SENTINEL);
1253 lua_setfield(L, -2, "null"); 1259 lua_setfield(L, -2, "null");
1254 1260
1255 luaG_pushdeepversion( L); 1261 luaG_pushdeepversion( L);
@@ -1815,7 +1821,8 @@ LUAG_FUNC( set_singlethreaded)
1815*/ 1821*/
1816#if ERROR_FULL_STACK 1822#if ERROR_FULL_STACK
1817 1823
1818# define EXTENDED_STACK_TRACE_KEY ((void*)LG_set_error_reporting) // used as registry key 1824// crc64/we of string "EXTENDED_STACK_TRACE_REGKEY" generated at http://www.nitrxgen.net/hashgen/
1825static DECLARE_CONST_UNIQUE_KEY( EXTENDED_STACK_TRACE_REGKEY, 0x7a59821071066e49); // used as registry key
1819 1826
1820LUAG_FUNC( set_error_reporting) 1827LUAG_FUNC( set_error_reporting)
1821{ 1828{
@@ -1836,7 +1843,7 @@ LUAG_FUNC( set_error_reporting)
1836 return luaL_error( L, "unsupported error reporting model"); 1843 return luaL_error( L, "unsupported error reporting model");
1837 } 1844 }
1838done: 1845done:
1839 lua_pushlightuserdata( L, EXTENDED_STACK_TRACE_KEY); 1846 push_unique_key( L, EXTENDED_STACK_TRACE_REGKEY);
1840 lua_pushboolean( L, equal); 1847 lua_pushboolean( L, equal);
1841 lua_rawset( L, LUA_REGISTRYINDEX); 1848 lua_rawset( L, LUA_REGISTRYINDEX);
1842 return 0; 1849 return 0;
@@ -1853,13 +1860,13 @@ static int lane_error( lua_State* L)
1853 1860
1854 // Don't do stack survey for cancelled lanes. 1861 // Don't do stack survey for cancelled lanes.
1855 // 1862 //
1856 if( lua_touserdata( L, 1) == CANCEL_ERROR) 1863 if( equal_unique_key( L, 1, CANCEL_ERROR))
1857 { 1864 {
1858 return 1; // just pass on 1865 return 1; // just pass on
1859 } 1866 }
1860 1867
1861 STACK_GROW( L, 3); 1868 STACK_GROW( L, 3);
1862 lua_pushlightuserdata( L, EXTENDED_STACK_TRACE_KEY); // some_error estk 1869 push_unique_key( L, EXTENDED_STACK_TRACE_REGKEY); // some_error estk
1863 lua_rawget( L, LUA_REGISTRYINDEX); // some_error basic|extended 1870 lua_rawget( L, LUA_REGISTRYINDEX); // some_error basic|extended
1864 extended = lua_toboolean( L, -1); 1871 extended = lua_toboolean( L, -1);
1865 lua_pop( L, 1); // some_error 1872 lua_pop( L, 1); // some_error
@@ -1913,7 +1920,7 @@ static int lane_error( lua_State* L)
1913 lua_rawseti( L, -2, (lua_Integer) n); // some_error {} 1920 lua_rawseti( L, -2, (lua_Integer) n); // some_error {}
1914 } 1921 }
1915 1922
1916 lua_pushlightuserdata( L, STACK_TRACE_KEY); // some_error {} stk 1923 push_unique_key( L, STACK_TRACE_KEY); // some_error {} stk
1917 lua_insert( L, -2); // some_error stk {} 1924 lua_insert( L, -2); // some_error stk {}
1918 lua_rawset( L, LUA_REGISTRYINDEX); // some_error 1925 lua_rawset( L, LUA_REGISTRYINDEX); // some_error
1919 1926
@@ -1936,14 +1943,14 @@ static void push_stack_trace( lua_State* L, int rc_, int stk_base_)
1936 { 1943 {
1937 // fetch the call stack table from the registry where the handler stored it 1944 // fetch the call stack table from the registry where the handler stored it
1938 STACK_GROW( L, 1); 1945 STACK_GROW( L, 1);
1939 lua_pushlightuserdata( L, STACK_TRACE_KEY); // err STACK_TRACE_KEY 1946 push_unique_key( L, STACK_TRACE_KEY); // err STACK_TRACE_KEY
1940 // yields nil if no stack was generated (in case of cancellation for example) 1947 // yields nil if no stack was generated (in case of cancellation for example)
1941 lua_rawget( L, LUA_REGISTRYINDEX); // err trace|nil 1948 lua_rawget( L, LUA_REGISTRYINDEX); // err trace|nil
1942 ASSERT_L( lua_gettop( L) == 1 + stk_base_); 1949 ASSERT_L( lua_gettop( L) == 1 + stk_base_);
1943 1950
1944 // For cancellation the error message is CANCEL_ERROR, and a stack trace isn't placed 1951 // For cancellation the error message is CANCEL_ERROR, and a stack trace isn't placed
1945 // For other errors, the message can be whatever was thrown, and we should have a stack trace table 1952 // For other errors, the message can be whatever was thrown, and we should have a stack trace table
1946 ASSERT_L( lua_type( L, 1 + stk_base_) == ((lua_touserdata( L, stk_base_) == CANCEL_ERROR) ? LUA_TNIL : LUA_TTABLE)); 1953 ASSERT_L( lua_type( L, 1 + stk_base_) == (equal_unique_key( L, stk_base_, CANCEL_ERROR) ? LUA_TNIL : LUA_TTABLE));
1947 // Just leaving the stack trace table on the stack is enough to get it through to the master. 1954 // Just leaving the stack trace table on the stack is enough to get it through to the master.
1948 break; 1955 break;
1949 } 1956 }
@@ -1953,18 +1960,19 @@ static void push_stack_trace( lua_State* L, int rc_, int stk_base_)
1953 case LUA_ERRERR: // error while running the error handler (if any, for example an out-of-memory condition) 1960 case LUA_ERRERR: // error while running the error handler (if any, for example an out-of-memory condition)
1954 default: 1961 default:
1955 // we should have a single value which is either a string (the error message) or CANCEL_ERROR 1962 // we should have a single value which is either a string (the error message) or CANCEL_ERROR
1956 ASSERT_L( (lua_gettop( L) == stk_base_) && ((lua_type( L, stk_base_) == LUA_TSTRING) || (lua_touserdata( L, stk_base_) == CANCEL_ERROR))); 1963 ASSERT_L( (lua_gettop( L) == stk_base_) && ((lua_type( L, stk_base_) == LUA_TSTRING) || equal_unique_key( L, stk_base_, CANCEL_ERROR)));
1957 break; 1964 break;
1958 } 1965 }
1959} 1966}
1960 1967
1961LUAG_FUNC( set_debug_threadname) 1968LUAG_FUNC( set_debug_threadname)
1962{ 1969{
1970 DECLARE_CONST_UNIQUE_KEY( hidden_regkey, LG_set_debug_threadname);
1963 // C s_lane structure is a light userdata upvalue 1971 // C s_lane structure is a light userdata upvalue
1964 Lane* s = lua_touserdata( L, lua_upvalueindex( 1)); 1972 Lane* s = lua_touserdata( L, lua_upvalueindex( 1));
1965 luaL_checktype( L, -1, LUA_TSTRING); // "name" 1973 luaL_checktype( L, -1, LUA_TSTRING); // "name"
1966 // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global... 1974 // store a hidden reference in the registry to make sure the string is kept around even if a lane decides to manually change the "decoda_name" global...
1967 lua_pushlightuserdata( L, LG_set_debug_threadname); // "name" lud 1975 push_unique_key( L, hidden_regkey); // "name" lud
1968 lua_pushvalue( L, -2); // "name" lud "name" 1976 lua_pushvalue( L, -2); // "name" lud "name"
1969 lua_rawset( L, LUA_REGISTRYINDEX); // "name" 1977 lua_rawset( L, LUA_REGISTRYINDEX); // "name"
1970 s->debug_name = lua_tostring( L, -1); 1978 s->debug_name = lua_tostring( L, -1);
@@ -2089,7 +2097,7 @@ static THREAD_RETURN_T THREAD_CALLCONV lane_main( void* vs)
2089 // in case of error and if it exists, fetch stack trace from registry and push it 2097 // in case of error and if it exists, fetch stack trace from registry and push it
2090 push_stack_trace( L, rc, 1); // retvals|error [trace] 2098 push_stack_trace( L, rc, 1); // retvals|error [trace]
2091 2099
2092 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "Lane %p body: %s (%s)\n" INDENT_END, L, get_errcode_name( rc), (lua_touserdata( L, 1)==CANCEL_ERROR) ? "cancelled" : lua_typename( L, lua_type( L, 1)))); 2100 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "Lane %p body: %s (%s)\n" INDENT_END, L, get_errcode_name( rc), equal_unique_key( L, 1, CANCEL_ERROR) ? "cancelled" : lua_typename( L, lua_type( L, 1))));
2093 //STACK_DUMP(L); 2101 //STACK_DUMP(L);
2094 // Call finalizers, if the script has set them up. 2102 // Call finalizers, if the script has set them up.
2095 // 2103 //
@@ -2118,7 +2126,7 @@ static THREAD_RETURN_T THREAD_CALLCONV lane_main( void* vs)
2118 { 2126 {
2119 // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them 2127 // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them
2120 2128
2121 enum e_status st = (rc == 0) ? DONE : (lua_touserdata( L, 1) == CANCEL_ERROR) ? CANCELLED : ERROR_ST; 2129 enum e_status st = (rc == 0) ? DONE : equal_unique_key( L, 1, CANCEL_ERROR) ? CANCELLED : ERROR_ST;
2122 2130
2123 // Posix no PTHREAD_TIMEDJOIN: 2131 // Posix no PTHREAD_TIMEDJOIN:
2124 // 'done_lock' protects the -> DONE|ERROR_ST|CANCELLED state change 2132 // 'done_lock' protects the -> DONE|ERROR_ST|CANCELLED state change
@@ -2183,9 +2191,9 @@ LUAG_FUNC( register)
2183 return 0; 2191 return 0;
2184} 2192}
2185 2193
2194// crc64/we of string "GCCB_KEY" generated at http://www.nitrxgen.net/hashgen/
2195static DECLARE_CONST_UNIQUE_KEY( GCCB_KEY, 0xcfb1f046ef074e88);
2186 2196
2187LUAG_FUNC( thread_gc);
2188#define GCCB_KEY (void*)LG_thread_gc
2189//--- 2197//---
2190// lane_ud = lane_new( function 2198// lane_ud = lane_new( function
2191// , [libs_str] 2199// , [libs_str]
@@ -2429,7 +2437,7 @@ LUAG_FUNC( lane_new)
2429 // Store the gc_cb callback in the uservalue 2437 // Store the gc_cb callback in the uservalue
2430 if( gc_cb_idx > 0) 2438 if( gc_cb_idx > 0)
2431 { 2439 {
2432 lua_pushlightuserdata( L, GCCB_KEY); // func libs cancelstep priority globals package required gc_cb lane uv k 2440 push_unique_key( L, GCCB_KEY); // func libs cancelstep priority globals package required gc_cb lane uv k
2433 lua_pushvalue( L, gc_cb_idx); // func libs cancelstep priority globals package required gc_cb lane uv k gc_cb 2441 lua_pushvalue( L, gc_cb_idx); // func libs cancelstep priority globals package required gc_cb lane uv k gc_cb
2434 lua_rawset( L, -3); // func libs cancelstep priority globals package required gc_cb lane uv 2442 lua_rawset( L, -3); // func libs cancelstep priority globals package required gc_cb lane uv
2435 } 2443 }
@@ -2437,7 +2445,7 @@ LUAG_FUNC( lane_new)
2437 lua_setuservalue( L, -2); // func libs cancelstep priority globals package required gc_cb lane 2445 lua_setuservalue( L, -2); // func libs cancelstep priority globals package required gc_cb lane
2438 2446
2439 // Store 's' in the lane's registry, for 'cancel_test()' (even if 'cs'==0 we still do cancel tests at pending send/receive). 2447 // Store 's' in the lane's registry, for 'cancel_test()' (even if 'cs'==0 we still do cancel tests at pending send/receive).
2440 lua_pushlightuserdata( L2, CANCEL_TEST_KEY); // func [... args ...] k 2448 push_unique_key( L2, CANCEL_TEST_KEY); // func [... args ...] k
2441 lua_pushlightuserdata( L2, s); // func [... args ...] k s 2449 lua_pushlightuserdata( L2, s); // func [... args ...] k s
2442 lua_rawset( L2, LUA_REGISTRYINDEX); // func [... args ...] 2450 lua_rawset( L2, LUA_REGISTRYINDEX); // func [... args ...]
2443 2451
@@ -2476,7 +2484,7 @@ LUAG_FUNC( thread_gc)
2476 2484
2477 // if there a gc callback? 2485 // if there a gc callback?
2478 lua_getuservalue( L, 1); // ud uservalue 2486 lua_getuservalue( L, 1); // ud uservalue
2479 lua_pushlightuserdata( L, GCCB_KEY); // ud uservalue __gc 2487 push_unique_key( L, GCCB_KEY); // ud uservalue __gc
2480 lua_rawget( L, -2); // ud uservalue gc_cb|nil 2488 lua_rawget( L, -2); // ud uservalue gc_cb|nil
2481 if( !lua_isnil( L, -1)) 2489 if( !lua_isnil( L, -1))
2482 { 2490 {
@@ -3209,7 +3217,7 @@ LUAG_FUNC( configure)
3209 lua_pushinteger(L, THREAD_PRIO_MAX); // settings M THREAD_PRIO_MAX 3217 lua_pushinteger(L, THREAD_PRIO_MAX); // settings M THREAD_PRIO_MAX
3210 lua_setfield( L, -2, "max_prio"); // settings M 3218 lua_setfield( L, -2, "max_prio"); // settings M
3211 3219
3212 lua_pushlightuserdata( L, CANCEL_ERROR); // settings M CANCEL_ERROR 3220 push_unique_key( L, CANCEL_ERROR); // settings M CANCEL_ERROR
3213 lua_setfield( L, -2, "cancel_error"); // settings M 3221 lua_setfield( L, -2, "cancel_error"); // settings M
3214 3222
3215 // we'll need this every time we transfer some C function from/to this state 3223 // we'll need this every time we transfer some C function from/to this state
diff --git a/src/tools.c b/src/tools.c
index 051e3cc..c13d80d 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -44,6 +44,7 @@ THE SOFTWARE.
44#include "universe.h" 44#include "universe.h"
45#include "keeper.h" 45#include "keeper.h"
46#include "lanes.h" 46#include "lanes.h"
47#include "uniquekey.h"
47 48
48// functions implemented in deep.c 49// functions implemented in deep.c
49extern luaG_IdFunction copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode mode_); 50extern luaG_IdFunction copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode mode_);
@@ -977,7 +978,7 @@ static bool_t lookup_table( lua_State* L2, lua_State* L, uint_t i, LookupMode mo
977static bool_t push_cached_table( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i) 978static bool_t push_cached_table( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i)
978{ 979{
979 bool_t not_found_in_cache; // L2 980 bool_t not_found_in_cache; // L2
980 void* const p = (void*)lua_topointer( L, i); 981 DECLARE_CONST_UNIQUE_KEY( p, lua_topointer( L, i));
981 982
982 ASSERT_L( L2_cache_i != 0); 983 ASSERT_L( L2_cache_i != 0);
983 STACK_GROW( L2, 3); 984 STACK_GROW( L2, 3);
@@ -986,7 +987,7 @@ static bool_t push_cached_table( lua_State* L2, uint_t L2_cache_i, lua_State* L,
986 // We don't need to use the from state ('L') in ID since the life span 987 // We don't need to use the from state ('L') in ID since the life span
987 // is only for the duration of a copy (both states are locked). 988 // is only for the duration of a copy (both states are locked).
988 // push a light userdata uniquely representing the table 989 // push a light userdata uniquely representing the table
989 lua_pushlightuserdata( L2, p); // ... p 990 push_unique_key( L2, p); // ... p
990 991
991 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring( L2, -1)); 992 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring( L2, -1));
992 993
@@ -996,7 +997,7 @@ static bool_t push_cached_table( lua_State* L2, uint_t L2_cache_i, lua_State* L,
996 { 997 {
997 lua_pop( L2, 1); // ... 998 lua_pop( L2, 1); // ...
998 lua_newtable( L2); // ... {} 999 lua_newtable( L2); // ... {}
999 lua_pushlightuserdata( L2, p); // ... {} p 1000 push_unique_key( L2, p); // ... {} p
1000 lua_pushvalue( L2, -2); // ... {} p {} 1001 lua_pushvalue( L2, -2); // ... {} p {}
1001 lua_rawset( L2, L2_cache_i); // ... {} 1002 lua_rawset( L2, L2_cache_i); // ... {}
1002 } 1003 }
diff --git a/src/uniquekey.h b/src/uniquekey.h
new file mode 100644
index 0000000..c90d09a
--- /dev/null
+++ b/src/uniquekey.h
@@ -0,0 +1,25 @@
1#if !defined __LANES_UNIQUEKEY_H__
2#define __LANES_UNIQUEKEY_H__ 1
3
4#include "lualib.h"
5
6// Lua light userdata can hold a pointer.
7struct s_UniqueKey
8{
9 void* value;
10};
11typedef struct s_UniqueKey UniqueKey;
12
13#if defined(LUA_JITLIBNAME) && (defined(__x86_64__) || defined(_M_X64)) // building against LuaJIT headers, light userdata is restricted to 47 significant bits.
14#define MAKE_UNIQUE_KEY( p_) ((void*)(p_) & 0x7fffffffffffull)
15#else // LUA_JITLIBNAME
16#define MAKE_UNIQUE_KEY( p_) ((void*) p_)
17#endif // LUA_JITLIBNAME
18
19#define DECLARE_UNIQUE_KEY( name_) UniqueKey name_
20#define DECLARE_CONST_UNIQUE_KEY( name_, p_) UniqueKey const name_ = { MAKE_UNIQUE_KEY( p_)}
21
22#define push_unique_key( L, key_) lua_pushlightuserdata( L, key_.value)
23#define equal_unique_key( L, i, key_) (lua_touserdata( L, i) == key_.value)
24
25#endif // __LANES_UNIQUEKEY_H__
diff --git a/src/universe.c b/src/universe.c
index 8bcdcfe..ca94930 100644
--- a/src/universe.c
+++ b/src/universe.c
@@ -31,9 +31,10 @@ THE SOFTWARE.
31#include "universe.h" 31#include "universe.h"
32#include "compat.h" 32#include "compat.h"
33#include "macros_and_utils.h" 33#include "macros_and_utils.h"
34#include "uniquekey.h"
34 35
35// crc64/we of string "UNIVERSE_REGKEY" generated at https://www.nitrxgen.net/hashgen/ 36// crc64/we of string "UNIVERSE_REGKEY" generated at http://www.nitrxgen.net/hashgen/
36static void* const UNIVERSE_REGKEY = ((void*)0x9f877b2cf078f17f); 37static DECLARE_UNIQUE_KEY( UNIVERSE_REGKEY, 0x9f877b2cf078f17f);
37 38
38// ################################################################################################ 39// ################################################################################################
39 40
@@ -41,7 +42,7 @@ Universe* universe_create( lua_State* L)
41{ 42{
42 Universe* U = (Universe*) lua_newuserdata( L, sizeof(Universe)); // universe 43 Universe* U = (Universe*) lua_newuserdata( L, sizeof(Universe)); // universe
43 memset( U, 0, sizeof( Universe)); 44 memset( U, 0, sizeof( Universe));
44 lua_pushlightuserdata( L, UNIVERSE_REGKEY); // universe UNIVERSE_REGKEY 45 push_unique_key( L, UNIVERSE_REGKEY); // universe UNIVERSE_REGKEY
45 lua_pushvalue( L, -2); // universe UNIVERSE_REGKEY universe 46 lua_pushvalue( L, -2); // universe UNIVERSE_REGKEY universe
46 lua_rawset( L, LUA_REGISTRYINDEX); // universe 47 lua_rawset( L, LUA_REGISTRYINDEX); // universe
47 return U; 48 return U;
@@ -52,7 +53,7 @@ Universe* universe_create( lua_State* L)
52void universe_store( lua_State* L, Universe* U) 53void universe_store( lua_State* L, Universe* U)
53{ 54{
54 STACK_CHECK( L); 55 STACK_CHECK( L);
55 lua_pushlightuserdata( L, UNIVERSE_REGKEY); 56 push_unique_key( L, UNIVERSE_REGKEY);
56 lua_pushlightuserdata( L, U); 57 lua_pushlightuserdata( L, U);
57 lua_rawset( L, LUA_REGISTRYINDEX); 58 lua_rawset( L, LUA_REGISTRYINDEX);
58 STACK_END( L, 0); 59 STACK_END( L, 0);
@@ -65,7 +66,7 @@ Universe* universe_get( lua_State* L)
65 Universe* universe; 66 Universe* universe;
66 STACK_GROW( L, 2); 67 STACK_GROW( L, 2);
67 STACK_CHECK( L); 68 STACK_CHECK( L);
68 lua_pushlightuserdata( L, UNIVERSE_REGKEY); 69 push_unique_key( L, UNIVERSE_REGKEY);
69 lua_rawget( L, LUA_REGISTRYINDEX); 70 lua_rawget( L, LUA_REGISTRYINDEX);
70 universe = lua_touserdata( L, -1); // NULL if nil 71 universe = lua_touserdata( L, -1); // NULL if nil
71 lua_pop( L, 1); 72 lua_pop( L, 1);