aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2018-11-19 09:16:49 +0100
committerBenoit Germain <bnt.germain@gmail.com>2018-11-19 09:16:49 +0100
commit7b4f59c5ebc84e426e2876906b24d7dd73342f07 (patch)
treef05748fc2d75c43c25865be01677271fff5d86e4 /src
parent01f83215a2ad235fbf306f591c6c0547b1bb7047 (diff)
downloadlanes-7b4f59c5ebc84e426e2876906b24d7dd73342f07.tar.gz
lanes-7b4f59c5ebc84e426e2876906b24d7dd73342f07.tar.bz2
lanes-7b4f59c5ebc84e426e2876906b24d7dd73342f07.zip
Internal code tweaks
* Registry access code utility macros * CONFIG_REGKEY and LOOKUP_REGKEY are now lightuserdata instead of strings * Stack checking debug macros improvements
Diffstat (limited to 'src')
-rw-r--r--src/deep.c39
-rw-r--r--src/keeper.c34
-rw-r--r--src/lanes.c62
-rw-r--r--src/lanes_private.h5
-rw-r--r--src/linda.c9
-rw-r--r--src/macros_and_utils.h68
-rw-r--r--src/tools.c107
-rw-r--r--src/tools.h11
-rw-r--r--src/universe.c25
9 files changed, 202 insertions, 158 deletions
diff --git a/src/deep.c b/src/deep.c
index c351bf7..a486a72 100644
--- a/src/deep.c
+++ b/src/deep.c
@@ -33,6 +33,7 @@ THE SOFTWARE.
33*/ 33*/
34 34
35#include <stdio.h> 35#include <stdio.h>
36#include <assert.h>
36#include <string.h> 37#include <string.h>
37#include <ctype.h> 38#include <ctype.h>
38#include <stdlib.h> 39#include <stdlib.h>
@@ -63,20 +64,18 @@ THE SOFTWARE.
63static void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode_) 64static void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode_)
64{ 65{
65 STACK_GROW( L, 3); 66 STACK_GROW( L, 3);
66 STACK_CHECK( L); 67 STACK_CHECK( L, 0);
67 68
68 push_unique_key( L, key_); // key 69 REGISTRY_GET( L, key_); // {}|nil
69 lua_rawget( L, LUA_REGISTRYINDEX); // {}|nil 70 STACK_MID( L, 1);
70 71
71 if( lua_isnil( L, -1)) 72 if( lua_isnil( L, -1))
72 { 73 {
73 lua_pop( L, 1); // 74 lua_pop( L, 1); //
74 lua_newtable( L); // {} 75 lua_newtable( L); // {}
75 push_unique_key( L, key_); // {} key
76 lua_pushvalue( L, -2); // {} key {}
77
78 // _R[key_] = {} 76 // _R[key_] = {}
79 lua_rawset( L, LUA_REGISTRYINDEX); // {} 77 REGISTRY_SET( L, key_, lua_pushvalue( L, -2)); // {}
78 STACK_MID( L, 1);
80 79
81 // Set its metatable if requested 80 // Set its metatable if requested
82 if( mode_) 81 if( mode_)
@@ -128,16 +127,16 @@ static DECLARE_CONST_UNIQUE_KEY( DEEP_PROXY_CACHE_KEY, 0x05773d6fc26be106);
128static void set_deep_lookup( lua_State* L) 127static void set_deep_lookup( lua_State* L)
129{ 128{
130 STACK_GROW( L, 3); 129 STACK_GROW( L, 3);
131 STACK_CHECK( L); // a b 130 STACK_CHECK( L, 2); // a b
132 push_registry_subtable( L, DEEP_LOOKUP_KEY); // a b {} 131 push_registry_subtable( L, DEEP_LOOKUP_KEY); // a b {}
133 STACK_MID( L, 1); 132 STACK_MID( L, 3);
134 lua_insert( L, -3); // {} a b 133 lua_insert( L, -3); // {} a b
135 lua_pushvalue( L, -1); // {} a b b 134 lua_pushvalue( L, -1); // {} a b b
136 lua_pushvalue( L,-3); // {} a b b a 135 lua_pushvalue( L,-3); // {} a b b a
137 lua_rawset( L, -5); // {} a b 136 lua_rawset( L, -5); // {} a b
138 lua_rawset( L, -3); // {} 137 lua_rawset( L, -3); // {}
139 lua_pop( L, 1); // 138 lua_pop( L, 1); //
140 STACK_END( L, -2); 139 STACK_END( L, 0);
141} 140}
142 141
143/* 142/*
@@ -147,17 +146,15 @@ static void set_deep_lookup( lua_State* L)
147static void get_deep_lookup( lua_State* L) 146static void get_deep_lookup( lua_State* L)
148{ 147{
149 STACK_GROW( L, 1); 148 STACK_GROW( L, 1);
150 STACK_CHECK( L); // a 149 STACK_CHECK( L, 1); // a
151 push_unique_key( L, DEEP_LOOKUP_KEY); // a DLK 150 REGISTRY_GET( L, DEEP_LOOKUP_KEY); // a {}
152 lua_rawget( L, LUA_REGISTRYINDEX); // a {}
153
154 if( !lua_isnil( L, -1)) 151 if( !lua_isnil( L, -1))
155 { 152 {
156 lua_insert( L, -2); // {} a 153 lua_insert( L, -2); // {} a
157 lua_rawget( L, -2); // {} b 154 lua_rawget( L, -2); // {} b
158 } 155 }
159 lua_remove( L, -2); // a|b 156 lua_remove( L, -2); // a|b
160 STACK_END( L, 0); 157 STACK_END( L, 1);
161} 158}
162 159
163/* 160/*
@@ -180,7 +177,7 @@ static inline luaG_IdFunction get_idfunc( lua_State* L, int index, LookupMode mo
180 // of course, we could just trust the caller, but we won't 177 // of course, we could just trust the caller, but we won't
181 luaG_IdFunction ret; 178 luaG_IdFunction ret;
182 STACK_GROW( L, 1); 179 STACK_GROW( L, 1);
183 STACK_CHECK( L); 180 STACK_CHECK( L, 0);
184 181
185 if( !lua_getmetatable( L, index)) // deep ... metatable? 182 if( !lua_getmetatable( L, index)) // deep ... metatable?
186 { 183 {
@@ -284,7 +281,7 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, Lo
284 if( U) MUTEX_UNLOCK( &U->deep_lock); 281 if( U) MUTEX_UNLOCK( &U->deep_lock);
285 282
286 STACK_GROW( L, 7); 283 STACK_GROW( L, 7);
287 STACK_CHECK( L); 284 STACK_CHECK( L, 0);
288 285
289 proxy = lua_newuserdata( L, sizeof(DeepPrelude*)); // DPC proxy 286 proxy = lua_newuserdata( L, sizeof(DeepPrelude*)); // DPC proxy
290 ASSERT_L( proxy); 287 ASSERT_L( proxy);
@@ -318,7 +315,7 @@ char const* push_deep_proxy( Universe* U, lua_State* L, DeepPrelude* prelude, Lo
318 lua_newtable( L); // DPC proxy metatable 315 lua_newtable( L); // DPC proxy metatable
319 lua_pushnil( L); // DPC proxy metatable nil 316 lua_pushnil( L); // DPC proxy metatable nil
320 } 317 }
321 if (lua_isnil(L, -1)) 318 if( lua_isnil( L, -1))
322 { 319 {
323 // Add our own '__gc' method 320 // Add our own '__gc' method
324 lua_pop( L, 1); // DPC proxy metatable 321 lua_pop( L, 1); // DPC proxy metatable
@@ -438,9 +435,9 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc)
438 char const* errmsg; 435 char const* errmsg;
439 436
440 STACK_GROW( L, 1); 437 STACK_GROW( L, 1);
441 STACK_CHECK( L); 438 STACK_CHECK( L, 0);
442 { 439 {
443 int oldtop = lua_gettop( L); 440 int const oldtop = lua_gettop( L);
444 DeepPrelude* prelude = idfunc( L, eDO_new); 441 DeepPrelude* prelude = idfunc( L, eDO_new);
445 if( prelude == NULL) 442 if( prelude == NULL)
446 { 443 {
@@ -484,7 +481,7 @@ void* luaG_todeep( lua_State* L, luaG_IdFunction idfunc, int index)
484{ 481{
485 DeepPrelude** proxy; 482 DeepPrelude** proxy;
486 483
487 STACK_CHECK( L); 484 STACK_CHECK( L, 0);
488 // ensure it is actually a deep userdata 485 // ensure it is actually a deep userdata
489 if( get_idfunc( L, index, eLM_LaneBody) != idfunc) 486 if( get_idfunc( L, index, eLM_LaneBody) != idfunc)
490 { 487 {
diff --git a/src/keeper.c b/src/keeper.c
index 0471cb7..ae3e2a8 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -166,10 +166,9 @@ static DECLARE_CONST_UNIQUE_KEY( FIFOS_KEY, 0xdce50bbc351cd465);
166static void push_table( lua_State* L, int idx_) 166static void push_table( lua_State* L, int idx_)
167{ 167{
168 STACK_GROW( L, 4); 168 STACK_GROW( L, 4);
169 STACK_CHECK( L); 169 STACK_CHECK( L, 0);
170 idx_ = lua_absindex( L, idx_); 170 idx_ = lua_absindex( L, idx_);
171 push_unique_key( L, FIFOS_KEY); // ud fifos_key 171 REGISTRY_GET( L, FIFOS_KEY); // ud fifos
172 lua_rawget( L, LUA_REGISTRYINDEX); // ud fifos
173 lua_pushvalue( L, idx_); // ud fifos ud 172 lua_pushvalue( L, idx_); // ud fifos ud
174 lua_rawget( L, -2); // ud fifos fifos[ud] 173 lua_rawget( L, -2); // ud fifos fifos[ud]
175 STACK_MID( L, 2); 174 STACK_MID( L, 2);
@@ -192,9 +191,8 @@ int keeper_push_linda_storage( Universe* U, lua_State* L, void* ptr_, ptrdiff_t
192 lua_State* const KL = K ? K->L : NULL; 191 lua_State* const KL = K ? K->L : NULL;
193 if( KL == NULL) return 0; 192 if( KL == NULL) return 0;
194 STACK_GROW( KL, 4); 193 STACK_GROW( KL, 4);
195 STACK_CHECK( KL); 194 STACK_CHECK( KL, 0);
196 push_unique_key( KL, FIFOS_KEY); // fifos_key 195 REGISTRY_GET( KL, FIFOS_KEY); // fifos
197 lua_rawget( KL, LUA_REGISTRYINDEX); // fifos
198 lua_pushlightuserdata( KL, ptr_); // fifos ud 196 lua_pushlightuserdata( KL, ptr_); // fifos ud
199 lua_rawget( KL, -2); // fifos storage 197 lua_rawget( KL, -2); // fifos storage
200 lua_remove( KL, -2); // storage 198 lua_remove( KL, -2); // storage
@@ -207,7 +205,7 @@ int keeper_push_linda_storage( Universe* U, lua_State* L, void* ptr_, ptrdiff_t
207 // move data from keeper to destination state KEEPER MAIN 205 // move data from keeper to destination state KEEPER MAIN
208 lua_pushnil( KL); // storage nil 206 lua_pushnil( KL); // storage nil
209 STACK_GROW( L, 5); 207 STACK_GROW( L, 5);
210 STACK_CHECK( L); 208 STACK_CHECK( L, 0);
211 lua_newtable( L); // out 209 lua_newtable( L); // out
212 while( lua_next( KL, -2)) // storage key fifo 210 while( lua_next( KL, -2)) // storage key fifo
213 { 211 {
@@ -240,12 +238,13 @@ int keeper_push_linda_storage( Universe* U, lua_State* L, void* ptr_, ptrdiff_t
240int keepercall_clear( lua_State* L) 238int keepercall_clear( lua_State* L)
241{ 239{
242 STACK_GROW( L, 3); 240 STACK_GROW( L, 3);
243 push_unique_key( L, FIFOS_KEY); // ud fifos_key 241 STACK_CHECK( L, 0);
244 lua_rawget( L, LUA_REGISTRYINDEX); // ud fifos 242 REGISTRY_GET( L, FIFOS_KEY); // ud fifos
245 lua_pushvalue( L, 1); // ud fifos ud 243 lua_pushvalue( L, 1); // ud fifos ud
246 lua_pushnil( L); // ud fifos ud nil 244 lua_pushnil( L); // ud fifos ud nil
247 lua_rawset( L, -3); // ud fifos 245 lua_rawset( L, -3); // ud fifos
248 lua_pop( L, 1); // ud 246 lua_pop( L, 1); // ud
247 STACK_END( L, 0);
249 return 0; 248 return 0;
250} 249}
251 250
@@ -634,11 +633,14 @@ void init_keepers( Universe* U, lua_State* L)
634 void* allocUD; 633 void* allocUD;
635 lua_Alloc allocF = lua_getallocf( L, &allocUD); 634 lua_Alloc allocF = lua_getallocf( L, &allocUD);
636 635
637 STACK_CHECK( L); // L K 636 STACK_CHECK( L, 0); // L K
638 lua_getfield( L, 1, "nb_keepers"); // nb_keepers 637 lua_getfield( L, 1, "nb_keepers"); // nb_keepers
639 nb_keepers = (int) lua_tointeger( L, -1); 638 nb_keepers = (int) lua_tointeger( L, -1);
640 lua_pop( L, 1); // 639 lua_pop( L, 1); //
641 assert( nb_keepers >= 1); 640 if( nb_keepers < 1)
641 {
642 (void) luaL_error( L, "Bad number of keepers (%d)", nb_keepers);
643 }
642 644
643 // Keepers contains an array of 1 s_Keeper, adjust for the actual number of keeper states 645 // Keepers contains an array of 1 s_Keeper, adjust for the actual number of keeper states
644 { 646 {
@@ -654,6 +656,7 @@ void init_keepers( Universe* U, lua_State* L)
654 } 656 }
655 for( i = 0; i < nb_keepers; ++ i) // keepersUD 657 for( i = 0; i < nb_keepers; ++ i) // keepersUD
656 { 658 {
659 // note that we will leak K if we raise an error later
657 lua_State* K = PROPAGATE_ALLOCF_ALLOC(); 660 lua_State* K = PROPAGATE_ALLOCF_ALLOC();
658 if( K == NULL) 661 if( K == NULL)
659 { 662 {
@@ -667,10 +670,12 @@ void init_keepers( Universe* U, lua_State* L)
667 // therefore, we need a recursive mutex. 670 // therefore, we need a recursive mutex.
668 MUTEX_RECURSIVE_INIT( &U->keepers->keeper_array[i].keeper_cs); 671 MUTEX_RECURSIVE_INIT( &U->keepers->keeper_array[i].keeper_cs);
669 672
673 STACK_CHECK( K, 0);
674
670 // copy the universe pointer in the keeper itself 675 // copy the universe pointer in the keeper itself
671 universe_store( K, U); 676 universe_store( K, U);
677 STACK_MID( K, 0);
672 678
673 STACK_CHECK( K);
674 // make sure 'package' is initialized in keeper states, so that we have require() 679 // make sure 'package' is initialized in keeper states, so that we have require()
675 // this because this is needed when transferring deep userdata object 680 // this because this is needed when transferring deep userdata object
676 luaL_requiref( K, "package", luaopen_package, 1); // package 681 luaL_requiref( K, "package", luaopen_package, 1); // package
@@ -705,10 +710,7 @@ void init_keepers( Universe* U, lua_State* L)
705 lua_setglobal( K, "decoda_name"); // 710 lua_setglobal( K, "decoda_name"); //
706 711
707 // create the fifos table in the keeper state 712 // create the fifos table in the keeper state
708 push_unique_key( K, FIFOS_KEY); // fifo_key 713 REGISTRY_SET( K, FIFOS_KEY, lua_newtable( K));
709 lua_newtable( K); // fifo_key {}
710 lua_rawset( K, LUA_REGISTRYINDEX); //
711
712 STACK_END( K, 0); 714 STACK_END( K, 0);
713 } 715 }
714 STACK_END( L, 0); 716 STACK_END( L, 0);
diff --git a/src/lanes.c b/src/lanes.c
index 037e44f..ae29af2 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -114,7 +114,7 @@ THE SOFTWARE.
114// intern the debug name in the specified lua state so that the pointer remains valid when the lane's state is closed 114// intern the debug name in the specified lua state so that the pointer remains valid when the lane's state is closed
115static void securize_debug_threadname( lua_State* L, Lane* s) 115static void securize_debug_threadname( lua_State* L, Lane* s)
116{ 116{
117 STACK_CHECK( L); 117 STACK_CHECK( L, 0);
118 STACK_GROW( L, 3); 118 STACK_GROW( L, 3);
119 lua_getuservalue( L, 1); 119 lua_getuservalue( L, 1);
120 lua_newtable( L); 120 lua_newtable( L);
@@ -196,10 +196,9 @@ struct s_Linda;
196static bool_t push_registry_table( lua_State* L, UniqueKey key, bool_t create) 196static bool_t push_registry_table( lua_State* L, UniqueKey key, bool_t create)
197{ 197{
198 STACK_GROW( L, 3); 198 STACK_GROW( L, 3);
199 STACK_CHECK( L); 199 STACK_CHECK( L, 0);
200 push_unique_key( L, key); // key
201 lua_rawget( L, LUA_REGISTRYINDEX); // t?
202 200
201 REGISTRY_GET( L, key); // ?
203 if( lua_isnil( L, -1)) // nil? 202 if( lua_isnil( L, -1)) // nil?
204 { 203 {
205 lua_pop( L, 1); // 204 lua_pop( L, 1); //
@@ -1179,7 +1178,7 @@ LUAG_FUNC( require)
1179 char const* name = lua_tostring( L, 1); 1178 char const* name = lua_tostring( L, 1);
1180 int const nargs = lua_gettop( L); 1179 int const nargs = lua_gettop( L);
1181 DEBUGSPEW_CODE( Universe* U = universe_get( L)); 1180 DEBUGSPEW_CODE( Universe* U = universe_get( L));
1182 STACK_CHECK( L); 1181 STACK_CHECK( L, 0);
1183 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.require %s BEGIN\n" INDENT_END, name)); 1182 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.require %s BEGIN\n" INDENT_END, name));
1184 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1183 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1185 lua_pushvalue( L, lua_upvalueindex(1)); // "name" require 1184 lua_pushvalue( L, lua_upvalueindex(1)); // "name" require
@@ -1204,7 +1203,7 @@ LUAG_FUNC( register)
1204 lua_settop( L, 2); 1203 lua_settop( L, 2);
1205 luaL_argcheck( L, (mod_type == LUA_TTABLE) || (mod_type == LUA_TFUNCTION), 2, "unexpected module type"); 1204 luaL_argcheck( L, (mod_type == LUA_TTABLE) || (mod_type == LUA_TFUNCTION), 2, "unexpected module type");
1206 DEBUGSPEW_CODE( Universe* U = universe_get( L)); 1205 DEBUGSPEW_CODE( Universe* U = universe_get( L));
1207 STACK_CHECK( L); // "name" mod_table 1206 STACK_CHECK( L, 0); // "name" mod_table
1208 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name)); 1207 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "lanes.register %s BEGIN\n" INDENT_END, name));
1209 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1208 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1210 populate_func_lookup_table( L, -1, name); 1209 populate_func_lookup_table( L, -1, name);
@@ -1265,10 +1264,10 @@ LUAG_FUNC( lane_new)
1265 L2 = luaG_newstate( U, L, libs_str); // L // L2 1264 L2 = luaG_newstate( U, L, libs_str); // L // L2
1266 1265
1267 STACK_GROW( L2, nargs + 3); // 1266 STACK_GROW( L2, nargs + 3); //
1268 STACK_CHECK( L2); 1267 STACK_CHECK( L2, 0);
1269 1268
1270 STACK_GROW( L, 3); // func libs cancelstep priority globals package required gc_cb [... args ...] 1269 STACK_GROW( L, 3); // func libs cancelstep priority globals package required gc_cb [... args ...]
1271 STACK_CHECK( L); 1270 STACK_CHECK( L, 0);
1272 1271
1273 // give a default "Lua" name to the thread to see VM name in Decoda debugger 1272 // give a default "Lua" name to the thread to see VM name in Decoda debugger
1274 lua_pushfstring( L2, "Lane #%p", L2); // "..." 1273 lua_pushfstring( L2, "Lane #%p", L2); // "..."
@@ -1409,7 +1408,7 @@ LUAG_FUNC( lane_new)
1409 } 1408 }
1410 STACK_END( L, -nargs); 1409 STACK_END( L, -nargs);
1411 ASSERT_L( lua_gettop( L) == FIXED_ARGS); 1410 ASSERT_L( lua_gettop( L) == FIXED_ARGS);
1412 STACK_CHECK( L); 1411 STACK_CHECK( L, 0);
1413 STACK_MID( L2, 1 + nargs); 1412 STACK_MID( L2, 1 + nargs);
1414 1413
1415 // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread) 1414 // 's' is allocated from heap, not Lua, since its life span may surpass the handle's (if free running thread)
@@ -1463,9 +1462,7 @@ LUAG_FUNC( lane_new)
1463 lua_setuservalue( L, -2); // func libs cancelstep priority globals package required gc_cb lane 1462 lua_setuservalue( L, -2); // func libs cancelstep priority globals package required gc_cb lane
1464 1463
1465 // Store 's' in the lane's registry, for 'cancel_test()' (even if 'cs'==0 we still do cancel tests at pending send/receive). 1464 // Store 's' in the lane's registry, for 'cancel_test()' (even if 'cs'==0 we still do cancel tests at pending send/receive).
1466 push_unique_key( L2, CANCEL_TEST_KEY); // func [... args ...] k 1465 REGISTRY_SET( L2, CANCEL_TEST_KEY, lua_pushlightuserdata( L2, s)); // func [... args ...]
1467 lua_pushlightuserdata( L2, s); // func [... args ...] k s
1468 lua_rawset( L2, LUA_REGISTRYINDEX); // func [... args ...]
1469 1466
1470 if( cancelstep_idx) 1467 if( cancelstep_idx)
1471 { 1468 {
@@ -1679,7 +1676,7 @@ LUAG_FUNC( thread_join)
1679 return 2; 1676 return 2;
1680 } 1677 }
1681 1678
1682 STACK_CHECK( L); 1679 STACK_CHECK( L, 0);
1683 // Thread is DONE/ERROR_ST/CANCELLED; all ours now 1680 // Thread is DONE/ERROR_ST/CANCELLED; all ours now
1684 1681
1685 if( s->mstatus == KILLED) // OS thread was killed if thread_cancel was forced 1682 if( s->mstatus == KILLED) // OS thread was killed if thread_cancel was forced
@@ -1961,7 +1958,7 @@ LUAG_FUNC( wakeup_conv )
1961 // .yday (day of the year) 1958 // .yday (day of the year)
1962 // .isdst (daylight saving on/off) 1959 // .isdst (daylight saving on/off)
1963 1960
1964 STACK_CHECK( L); 1961 STACK_CHECK( L, 0);
1965 lua_getfield( L, 1, "year" ); year= (int)lua_tointeger(L,-1); lua_pop(L,1); 1962 lua_getfield( L, 1, "year" ); year= (int)lua_tointeger(L,-1); lua_pop(L,1);
1966 lua_getfield( L, 1, "month" ); month= (int)lua_tointeger(L,-1); lua_pop(L,1); 1963 lua_getfield( L, 1, "month" ); month= (int)lua_tointeger(L,-1); lua_pop(L,1);
1967 lua_getfield( L, 1, "day" ); day= (int)lua_tointeger(L,-1); lua_pop(L,1); 1964 lua_getfield( L, 1, "day" ); day= (int)lua_tointeger(L,-1); lua_pop(L,1);
@@ -1975,7 +1972,7 @@ LUAG_FUNC( wakeup_conv )
1975 lua_getfield( L, 1, "isdst" ); 1972 lua_getfield( L, 1, "isdst" );
1976 isdst= lua_isboolean(L,-1) ? lua_toboolean(L,-1) : -1; 1973 isdst= lua_isboolean(L,-1) ? lua_toboolean(L,-1) : -1;
1977 lua_pop(L,1); 1974 lua_pop(L,1);
1978 STACK_END( L, 0); 1975 STACK_END( L, 0);
1979 1976
1980 t.tm_year= year-1900; 1977 t.tm_year= year-1900;
1981 t.tm_mon= month-1; // 0..11 1978 t.tm_mon= month-1; // 0..11
@@ -2101,7 +2098,7 @@ LUAG_FUNC( configure)
2101#endif // THREADAPI == THREADAPI_PTHREAD 2098#endif // THREADAPI == THREADAPI_PTHREAD
2102 2099
2103 STACK_GROW( L, 4); 2100 STACK_GROW( L, 4);
2104 STACK_CHECK( L); 2101 STACK_CHECK_ABS( L, 1); // settings
2105 2102
2106 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END, L)); 2103 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() BEGIN\n" INDENT_END, L));
2107 DEBUGSPEW_CODE( if( U) ++ U->debugspew_indent_depth); 2104 DEBUGSPEW_CODE( if( U) ++ U->debugspew_indent_depth);
@@ -2121,7 +2118,7 @@ LUAG_FUNC( configure)
2121 } 2118 }
2122 } 2119 }
2123 lua_pop( L, 1); // settings 2120 lua_pop( L, 1); // settings
2124 STACK_MID( L, 0); 2121 STACK_MID( L, 1);
2125 2122
2126 // grab or create the universe 2123 // grab or create the universe
2127 if( U == NULL) 2124 if( U == NULL)
@@ -2155,13 +2152,13 @@ LUAG_FUNC( configure)
2155 U->selfdestruct_first = SELFDESTRUCT_END; 2152 U->selfdestruct_first = SELFDESTRUCT_END;
2156 initialize_on_state_create( U, L); 2153 initialize_on_state_create( U, L);
2157 init_keepers( U, L); 2154 init_keepers( U, L);
2158 STACK_MID( L, 0); 2155 STACK_MID( L, 1);
2159 2156
2160 // Initialize 'timer_deep'; a common Linda object shared by all states 2157 // Initialize 'timer_deep'; a common Linda object shared by all states
2161 lua_pushcfunction( L, LG_linda); // settings lanes.linda 2158 lua_pushcfunction( L, LG_linda); // settings lanes.linda
2162 lua_pushliteral( L, "lanes-timer"); // settings lanes.linda "lanes-timer" 2159 lua_pushliteral( L, "lanes-timer"); // settings lanes.linda "lanes-timer"
2163 lua_call( L, 1, 1); // settings linda 2160 lua_call( L, 1, 1); // settings linda
2164 STACK_MID( L, 1); 2161 STACK_MID( L, 2);
2165 2162
2166 // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer 2163 // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer
2167 U->timer_deep = *(DeepPrelude**) lua_touserdata( L, -1); 2164 U->timer_deep = *(DeepPrelude**) lua_touserdata( L, -1);
@@ -2169,7 +2166,7 @@ LUAG_FUNC( configure)
2169 ++ U->timer_deep->refcount; 2166 ++ U->timer_deep->refcount;
2170 lua_pop( L, 1); // settings 2167 lua_pop( L, 1); // settings
2171 } 2168 }
2172 STACK_MID( L, 0); 2169 STACK_MID( L, 1);
2173 2170
2174 // Serialize calls to 'require' from now on, also in the primary state 2171 // Serialize calls to 'require' from now on, also in the primary state
2175 serialize_require( DEBUGSPEW_PARAM_COMMA( U) L); 2172 serialize_require( DEBUGSPEW_PARAM_COMMA( U) L);
@@ -2189,7 +2186,7 @@ LUAG_FUNC( configure)
2189 lua_setfield( L, -2, "threads"); // settings M 2186 lua_setfield( L, -2, "threads"); // settings M
2190 } 2187 }
2191#endif // HAVE_LANE_TRACKING 2188#endif // HAVE_LANE_TRACKING
2192 STACK_MID( L, 1); 2189 STACK_MID( L, 2);
2193 2190
2194 { 2191 {
2195 char const* errmsg; 2192 char const* errmsg;
@@ -2200,7 +2197,7 @@ LUAG_FUNC( configure)
2200 } 2197 }
2201 lua_setfield( L, -2, "timer_gateway"); // settings M 2198 lua_setfield( L, -2, "timer_gateway"); // settings M
2202 } 2199 }
2203 STACK_MID( L, 1); 2200 STACK_MID( L, 2);
2204 2201
2205 // prepare the metatable for threads 2202 // prepare the metatable for threads
2206 // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname } 2203 // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname }
@@ -2244,9 +2241,10 @@ LUAG_FUNC( configure)
2244 push_unique_key( L, CANCEL_ERROR); // settings M CANCEL_ERROR 2241 push_unique_key( L, CANCEL_ERROR); // settings M CANCEL_ERROR
2245 lua_setfield( L, -2, "cancel_error"); // settings M 2242 lua_setfield( L, -2, "cancel_error"); // settings M
2246 2243
2244 STACK_MID( L, 2); // reference stack contains only the function argument 'settings'
2247 // we'll need this every time we transfer some C function from/to this state 2245 // we'll need this every time we transfer some C function from/to this state
2248 lua_newtable( L); 2246 REGISTRY_SET( L, LOOKUP_REGKEY, lua_newtable( L));
2249 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); 2247 STACK_MID( L, 2);
2250 2248
2251 // register all native functions found in that module in the transferable functions database 2249 // register all native functions found in that module in the transferable functions database
2252 // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) 2250 // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names)
@@ -2264,11 +2262,11 @@ LUAG_FUNC( configure)
2264 populate_func_lookup_table( L, -1, NULL); 2262 populate_func_lookup_table( L, -1, NULL);
2265 lua_pop( L, 1); // settings M 2263 lua_pop( L, 1); // settings M
2266 } 2264 }
2267 // set _R[CONFIG_REGKEY] = settings 2265 lua_pop( L, 1); // settings
2268 lua_pushvalue( L, -2); // settings M settings 2266
2269 lua_setfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); // settings M 2267 // set _R[CONFIG_REGKEY] = settings
2270 lua_pop( L, 1); // settings 2268 REGISTRY_SET( L, CONFIG_REGKEY, lua_pushvalue( L, -2)); // -2 because CONFIG_REGKEY is pushed before the value itself
2271 STACK_END( L, 0); 2269 STACK_END( L, 1);
2272 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L)); 2270 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L));
2273 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 2271 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
2274 // Return the settings table 2272 // Return the settings table
@@ -2331,7 +2329,7 @@ int LANES_API luaopen_lanes_core( lua_State* L)
2331#endif // defined PLATFORM_WIN32 && !defined NDEBUG 2329#endif // defined PLATFORM_WIN32 && !defined NDEBUG
2332 2330
2333 STACK_GROW( L, 4); 2331 STACK_GROW( L, 4);
2334 STACK_CHECK( L); 2332 STACK_CHECK( L, 0);
2335 2333
2336 // Create main module interface table 2334 // Create main module interface table
2337 // we only have 1 closure, which must be called to configure Lanes 2335 // we only have 1 closure, which must be called to configure Lanes
@@ -2339,7 +2337,7 @@ int LANES_API luaopen_lanes_core( lua_State* L)
2339 lua_pushvalue( L, 1); // M "lanes.core" 2337 lua_pushvalue( L, 1); // M "lanes.core"
2340 lua_pushvalue( L, -2); // M "lanes.core" M 2338 lua_pushvalue( L, -2); // M "lanes.core" M
2341 lua_pushcclosure( L, LG_configure, 2); // M LG_configure() 2339 lua_pushcclosure( L, LG_configure, 2); // M LG_configure()
2342 lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); // M LG_configure() settings 2340 REGISTRY_GET( L, CONFIG_REGKEY); // M LG_configure() settings
2343 if( !lua_isnil( L, -1)) // this is not the first require "lanes.core": call configure() immediately 2341 if( !lua_isnil( L, -1)) // this is not the first require "lanes.core": call configure() immediately
2344 { 2342 {
2345 lua_pushvalue( L, -1); // M LG_configure() settings settings 2343 lua_pushvalue( L, -1); // M LG_configure() settings settings
@@ -2370,7 +2368,7 @@ static int default_luaopen_lanes( lua_State* L)
2370// call this instead of luaopen_lanes_core() when embedding Lua and Lanes in a custom application 2368// call this instead of luaopen_lanes_core() when embedding Lua and Lanes in a custom application
2371void LANES_API luaopen_lanes_embedded( lua_State* L, lua_CFunction _luaopen_lanes) 2369void LANES_API luaopen_lanes_embedded( lua_State* L, lua_CFunction _luaopen_lanes)
2372{ 2370{
2373 STACK_CHECK( L); 2371 STACK_CHECK( L, 0);
2374 // pre-require lanes.core so that when lanes.lua calls require "lanes.core" it finds it is already loaded 2372 // pre-require lanes.core so that when lanes.lua calls require "lanes.core" it finds it is already loaded
2375 luaL_requiref( L, "lanes.core", luaopen_lanes_core, 0); // ... lanes.core 2373 luaL_requiref( L, "lanes.core", luaopen_lanes_core, 0); // ... lanes.core
2376 lua_pop( L, 1); // ... 2374 lua_pop( L, 1); // ...
diff --git a/src/lanes_private.h b/src/lanes_private.h
index 1adfa31..16c178d 100644
--- a/src/lanes_private.h
+++ b/src/lanes_private.h
@@ -96,9 +96,8 @@ static inline Lane* get_lane_from_registry( lua_State* L)
96{ 96{
97 Lane* s; 97 Lane* s;
98 STACK_GROW( L, 1); 98 STACK_GROW( L, 1);
99 STACK_CHECK( L); 99 STACK_CHECK( L, 0);
100 push_unique_key( L, CANCEL_TEST_KEY); 100 REGISTRY_GET( L, CANCEL_TEST_KEY);
101 lua_rawget( L, LUA_REGISTRYINDEX);
102 s = lua_touserdata( L, -1); // lightuserdata (true 's_lane' pointer) / nil 101 s = lua_touserdata( L, -1); // lightuserdata (true 's_lane' pointer) / nil
103 lua_pop( L, 1); 102 lua_pop( L, 1);
104 STACK_END( L, 0); 103 STACK_END( L, 0);
diff --git a/src/linda.c b/src/linda.c
index ee60ebc..4d1fa9f 100644
--- a/src/linda.c
+++ b/src/linda.c
@@ -31,6 +31,7 @@ THE SOFTWARE.
31*/ 31*/
32 32
33#include <stdlib.h> 33#include <stdlib.h>
34#include <assert.h>
34 35
35#include "threading.h" 36#include "threading.h"
36#include "compat.h" 37#include "compat.h"
@@ -171,7 +172,7 @@ LUAG_FUNC( linda_send)
171 Keeper* K = which_keeper( linda->U->keepers, LINDA_KEEPER_HASHSEED( linda)); 172 Keeper* K = which_keeper( linda->U->keepers, LINDA_KEEPER_HASHSEED( linda));
172 lua_State* KL = K ? K->L : NULL; // need to do this for 'STACK_CHECK' 173 lua_State* KL = K ? K->L : NULL; // need to do this for 'STACK_CHECK'
173 if( KL == NULL) return 0; 174 if( KL == NULL) return 0;
174 STACK_CHECK( KL); 175 STACK_CHECK( KL, 0);
175 for( ;;) 176 for( ;;)
176 { 177 {
177 if( s != NULL) 178 if( s != NULL)
@@ -832,7 +833,7 @@ static void* linda_id( lua_State* L, DeepOp op_)
832 case eDO_metatable: 833 case eDO_metatable:
833 { 834 {
834 835
835 STACK_CHECK( L); 836 STACK_CHECK( L, 0);
836 lua_newtable( L); 837 lua_newtable( L);
837 // metatable is its own index 838 // metatable is its own index
838 lua_pushvalue( L, -1); 839 lua_pushvalue( L, -1);
@@ -892,10 +893,10 @@ static void* linda_id( lua_State* L, DeepOp op_)
892 893
893 // some constants 894 // some constants
894 lua_pushliteral( L, BATCH_SENTINEL); 895 lua_pushliteral( L, BATCH_SENTINEL);
895 lua_setfield(L, -2, "batched"); 896 lua_setfield( L, -2, "batched");
896 897
897 push_unique_key( L, NIL_SENTINEL); 898 push_unique_key( L, NIL_SENTINEL);
898 lua_setfield(L, -2, "null"); 899 lua_setfield( L, -2, "null");
899 900
900 STACK_END( L, 1); 901 STACK_END( L, 1);
901 return NULL; 902 return NULL;
diff --git a/src/macros_and_utils.h b/src/macros_and_utils.h
index 550fc0a..acbe690 100644
--- a/src/macros_and_utils.h
+++ b/src/macros_and_utils.h
@@ -46,26 +46,52 @@ extern char const* debugspew_indent;
46 46
47#ifdef NDEBUG 47#ifdef NDEBUG
48 48
49#define _ASSERT_L(lua,c) /*nothing*/ 49#define _ASSERT_L(lua,c) //nothing
50#define STACK_CHECK(L) /*nothing*/ 50#define STACK_CHECK(L,o) //nothing
51#define STACK_MID(L,c) /*nothing*/ 51#define STACK_CHECK_ABS(L,o) //nothing
52#define STACK_END(L,c) /*nothing*/ 52#define STACK_MID(L,c) //nothing
53#define STACK_DUMP(L) /*nothing*/ 53#define STACK_END(L,c) //nothing
54#define STACK_DUMP(L) //nothing
54 55
55#else // NDEBUG 56#else // NDEBUG
56 57
57#define _ASSERT_L( L, cond_) if( (cond_) == 0) { (void) luaL_error( L, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #cond_);} 58#define _ASSERT_L( L, cond_) if( (cond_) == 0) { (void) luaL_error( L, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #cond_);}
58 59
59#define STACK_CHECK(L) { int const _oldtop_##L = lua_gettop( L) 60#define STACK_CHECK( L, offset_) \
60#define STACK_MID(L,change) \
61 do \
62 { \ 61 { \
63 int stack_check_a = lua_gettop( L) - _oldtop_##L; \ 62 int const L##_delta = offset_; \
64 int stack_check_b = (change); \ 63 if( (L##_delta < 0) || (lua_gettop( L) < L##_delta)) \
65 if( stack_check_a != stack_check_b) \ 64 { \
66 luaL_error( L, "STACK ASSERT failed (%d not %d): %s:%d", stack_check_a, stack_check_b, __FILE__, __LINE__ ); \ 65 assert( FALSE); \
67 } while( 0) 66 (void) luaL_error( L, "STACK INIT ASSERT failed (%d not %d): %s:%d", lua_gettop( L), L##_delta, __FILE__, __LINE__); \
68#define STACK_END(L,change) STACK_MID(L,change); } 67 } \
68 int const L##_oldtop = lua_gettop( L) - L##_delta
69
70#define STACK_CHECK_ABS( L, offset_) \
71 { \
72 int const L##_pos = offset_; \
73 if( lua_gettop( L) < L##_pos) \
74 { \
75 assert( FALSE); \
76 (void) luaL_error( L, "STACK INIT ASSERT failed (%d not %d): %s:%d", lua_gettop( L), L##_pos, __FILE__, __LINE__); \
77 } \
78 int const L##_oldtop = 0
79
80#define STACK_MID( L, change) \
81 do \
82 { \
83 int stack_check_a = lua_gettop( L) - L##_oldtop; \
84 int stack_check_b = (change); \
85 if( stack_check_a != stack_check_b) \
86 { \
87 assert( FALSE); \
88 luaL_error( L, "STACK ASSERT failed (%d not %d): %s:%d", stack_check_a, stack_check_b, __FILE__, __LINE__); \
89 } \
90 } while( 0)
91
92#define STACK_END( L, change) \
93 STACK_MID( L, change); \
94 }
69 95
70#define STACK_DUMP( L) luaG_dump( L) 96#define STACK_DUMP( L) luaG_dump( L)
71 97
@@ -75,4 +101,18 @@ extern char const* debugspew_indent;
75 101
76#define STACK_GROW( L, n) do { if (!lua_checkstack(L,(int)(n))) luaL_error( L, "Cannot grow stack!" ); } while( 0) 102#define STACK_GROW( L, n) do { if (!lua_checkstack(L,(int)(n))) luaL_error( L, "Cannot grow stack!" ); } while( 0)
77 103
104// non-string keyed registry access
105#define REGISTRY_SET( L, key_, value_) \
106{ \
107 push_unique_key( L, key_); \
108 value_; \
109 lua_rawset( L, LUA_REGISTRYINDEX); \
110}
111
112#define REGISTRY_GET( L, key_) \
113{ \
114 push_unique_key( L, key_); \
115 lua_rawget( L, LUA_REGISTRYINDEX); \
116}
117
78#endif // MACROS_AND_UTILS_H 118#endif // MACROS_AND_UTILS_H
diff --git a/src/tools.c b/src/tools.c
index 6f71dd8..e54e0c0 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -32,6 +32,7 @@ THE SOFTWARE.
32*/ 32*/
33 33
34#include <stdio.h> 34#include <stdio.h>
35#include <assert.h>
35#include <string.h> 36#include <string.h>
36#include <ctype.h> 37#include <ctype.h>
37#include <stdlib.h> 38#include <stdlib.h>
@@ -50,14 +51,11 @@ THE SOFTWARE.
50extern bool_t copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode mode_); 51extern bool_t copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode mode_);
51extern void push_registry_subtable( lua_State* L, void* key_); 52extern void push_registry_subtable( lua_State* L, void* key_);
52 53
53char const* const CONFIG_REGKEY = "ee932492-a654-4506-9da8-f16540bdb5d4";
54char const* const LOOKUP_REGKEY = "ddea37aa-50c7-4d3f-8e0b-fb7a9d62bac5";
55
56DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); 54DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+");
57 55
58 56
59/*---=== luaG_dump ===---*/ 57/*---=== luaG_dump ===---*/
60 58#ifdef _DEBUG
61void luaG_dump( lua_State* L) 59void luaG_dump( lua_State* L)
62{ 60{
63 int top = lua_gettop( L); 61 int top = lua_gettop( L);
@@ -79,7 +77,7 @@ void luaG_dump( lua_State* L)
79 // Note: this requires 'tostring()' to be defined. If it is NOT, 77 // Note: this requires 'tostring()' to be defined. If it is NOT,
80 // enable it for more debugging. 78 // enable it for more debugging.
81 // 79 //
82 STACK_CHECK( L); 80 STACK_CHECK( L, 0);
83 STACK_GROW( L, 2); 81 STACK_GROW( L, 2);
84 82
85 lua_getglobal( L, "tostring"); 83 lua_getglobal( L, "tostring");
@@ -105,10 +103,11 @@ void luaG_dump( lua_State* L)
105 } 103 }
106 fprintf( stderr, "\n"); 104 fprintf( stderr, "\n");
107} 105}
106#endif // _DEBUG
108 107
109void initialize_on_state_create( Universe* U, lua_State* L) 108void initialize_on_state_create( Universe* U, lua_State* L)
110{ 109{
111 STACK_CHECK( L); 110 STACK_CHECK( L, 0);
112 lua_getfield( L, -1, "on_state_create"); // settings on_state_create|nil 111 lua_getfield( L, -1, "on_state_create"); // settings on_state_create|nil
113 if( !lua_isnil( L, -1)) 112 if( !lua_isnil( L, -1))
114 { 113 {
@@ -142,14 +141,19 @@ void initialize_on_state_create( Universe* U, lua_State* L)
142// just like lua_xmove, args are (from, to) 141// just like lua_xmove, args are (from, to)
143static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2) 142static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2)
144{ 143{
145 STACK_GROW( L, 1); 144 STACK_GROW( L, 2);
145 STACK_CHECK( L, 0);
146 STACK_CHECK( L2, 0);
147 REGISTRY_GET( L, CONFIG_REGKEY); // config
146 // copy settings from from source to destination registry 148 // copy settings from from source to destination registry
147 lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); 149 if( luaG_inter_move( U, L, L2, 1, eLM_LaneBody) < 0) // // config
148 if( luaG_inter_move( U, L, L2, 1, eLM_LaneBody) < 0) // error?
149 { 150 {
150 (void) luaL_error( L, "failed to copy settings when loading lanes.core"); 151 (void) luaL_error( L, "failed to copy settings when loading lanes.core");
151 } 152 }
152 lua_setfield( L2, LUA_REGISTRYINDEX, CONFIG_REGKEY); 153 // set L2:_R[CONFIG_REGKEY] = settings
154 REGISTRY_SET( L2, CONFIG_REGKEY, lua_insert( L2, -2)); //
155 STACK_END( L2, 0);
156 STACK_END( L, 0);
153} 157}
154 158
155 159
@@ -212,7 +216,7 @@ static void open1lib( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L, char con
212 { 216 {
213 bool_t const isLanesCore = (libfunc == require_lanes_core) ? TRUE : FALSE; // don't want to create a global for "lanes.core" 217 bool_t const isLanesCore = (libfunc == require_lanes_core) ? TRUE : FALSE; // don't want to create a global for "lanes.core"
214 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, (int) len_, name_)); 218 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, (int) len_, name_));
215 STACK_CHECK( L); 219 STACK_CHECK( L, 0);
216 // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) 220 // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack)
217 luaL_requiref( L, name_, libfunc, !isLanesCore); 221 luaL_requiref( L, name_, libfunc, !isLanesCore);
218 // lanes.core doesn't declare a global, so scan it here and now 222 // lanes.core doesn't declare a global, so scan it here and now
@@ -301,7 +305,7 @@ static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length)
301{ 305{
302 int i = 1; 306 int i = 1;
303 luaL_Buffer b; 307 luaL_Buffer b;
304 STACK_CHECK( L); 308 STACK_CHECK( L, 0);
305 luaL_buffinit( L, &b); 309 luaL_buffinit( L, &b);
306 for( ; i < last; ++ i) 310 for( ; i < last; ++ i)
307 { 311 {
@@ -339,7 +343,7 @@ static void update_lookup_entry( lua_State* L, int _ctx_base, int _depth)
339 DEBUGSPEW_CODE( char const *newName); 343 DEBUGSPEW_CODE( char const *newName);
340 DEBUGSPEW_CODE( Universe* U = universe_get( L)); 344 DEBUGSPEW_CODE( Universe* U = universe_get( L));
341 345
342 STACK_CHECK( L); 346 STACK_CHECK( L, 0);
343 // first, raise an error if the function is already known 347 // first, raise an error if the function is already known
344 lua_pushvalue( L, -1); // ... {bfc} k o o 348 lua_pushvalue( L, -1); // ... {bfc} k o o
345 lua_rawget( L, dest); // ... {bfc} k o name? 349 lua_rawget( L, dest); // ... {bfc} k o name?
@@ -412,7 +416,7 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _
412 416
413 STACK_GROW( L, 6); 417 STACK_GROW( L, 6);
414 // slot _i contains a table where we search for functions (or a full userdata with a metatable) 418 // slot _i contains a table where we search for functions (or a full userdata with a metatable)
415 STACK_CHECK( L); // ... {_i} 419 STACK_CHECK( L, 0); // ... {_i}
416 420
417 // if object is a userdata, replace it by its metatable 421 // if object is a userdata, replace it by its metatable
418 if( lua_type( L, _i) == LUA_TUSERDATA) 422 if( lua_type( L, _i) == LUA_TUSERDATA)
@@ -530,8 +534,9 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
530 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "NULL")); 534 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "NULL"));
531 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 535 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
532 STACK_GROW( L, 3); 536 STACK_GROW( L, 3);
533 STACK_CHECK( L); 537 STACK_CHECK( L, 0);
534 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {} 538 REGISTRY_GET( L, LOOKUP_REGKEY); // {}
539 STACK_MID( L, 1);
535 ASSERT_L( lua_istable( L, -1)); 540 ASSERT_L( lua_istable( L, -1));
536 if( lua_type( L, in_base) == LUA_TFUNCTION) // for example when a module is a simple function 541 if( lua_type( L, in_base) == LUA_TFUNCTION) // for example when a module is a simple function
537 { 542 {
@@ -585,12 +590,12 @@ void call_on_state_create( Universe* U, lua_State* L, lua_State* from_, LookupMo
585{ 590{
586 if( U->on_state_create_func != NULL) 591 if( U->on_state_create_func != NULL)
587 { 592 {
588 STACK_CHECK( L); 593 STACK_CHECK( L, 0);
589 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); 594 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END));
590 if( U->on_state_create_func != (lua_CFunction) initialize_on_state_create) 595 if( U->on_state_create_func != (lua_CFunction) initialize_on_state_create)
591 { 596 {
592 // C function: recreate a closure in the new state, bypassing the lookup scheme 597 // C function: recreate a closure in the new state, bypassing the lookup scheme
593 lua_pushcfunction( L, U->on_state_create_func); 598 lua_pushcfunction( L, U->on_state_create_func); // on_state_create()
594 } 599 }
595 else // Lua function located in the config table, copied when we opened "lanes.core" 600 else // Lua function located in the config table, copied when we opened "lanes.core"
596 { 601 {
@@ -600,10 +605,12 @@ void call_on_state_create( Universe* U, lua_State* L, lua_State* from_, LookupMo
600 // this doesn't count as an error though 605 // this doesn't count as an error though
601 return; 606 return;
602 } 607 }
603 lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); 608 REGISTRY_GET( L, CONFIG_REGKEY); // {}
604 lua_getfield( L, -1, "on_state_create"); 609 STACK_MID( L, 1);
605 lua_remove( L, -2); 610 lua_getfield( L, -1, "on_state_create"); // {} on_state_create()
611 lua_remove( L, -2); // on_state_create()
606 } 612 }
613 STACK_MID( L, 1);
607 // capture error and raise it in caller state 614 // capture error and raise it in caller state
608 if( lua_pcall( L, 0, 0, 0) != LUA_OK) 615 if( lua_pcall( L, 0, 0, 0) != LUA_OK)
609 { 616 {
@@ -640,16 +647,16 @@ lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_)
640 } 647 }
641 648
642 STACK_GROW( L, 2); 649 STACK_GROW( L, 2);
650 STACK_CHECK_ABS( L, 0);
643 651
644 // copy the universe as a light userdata (only the master state holds the full userdata) 652 // copy the universe as a light userdata (only the master state holds the full userdata)
645 // that way, if Lanes is required in this new state, we'll know we are part of this universe 653 // that way, if Lanes is required in this new state, we'll know we are part of this universe
646 universe_store( L, U); 654 universe_store( L, U);
647 655 STACK_MID( L, 0);
648 STACK_CHECK( L);
649 656
650 // we'll need this every time we transfer some C function from/to this state 657 // we'll need this every time we transfer some C function from/to this state
651 lua_newtable( L); 658 REGISTRY_SET( L, LOOKUP_REGKEY, lua_newtable( L));
652 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); 659 STACK_MID( L, 0);
653 660
654 // neither libs (not even 'base') nor special init func: we are done 661 // neither libs (not even 'base') nor special init func: we are done
655 if( libs_ == NULL && U->on_state_create_func == NULL) 662 if( libs_ == NULL && U->on_state_create_func == NULL)
@@ -724,7 +731,7 @@ lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_)
724 // will raise an error in from_ in case of problem 731 // will raise an error in from_ in case of problem
725 call_on_state_create( U, L, from_, eLM_LaneBody); 732 call_on_state_create( U, L, from_, eLM_LaneBody);
726 733
727 STACK_CHECK( L); 734 STACK_CHECK( L, 0);
728 // after all this, register everything we find in our name<->function database 735 // after all this, register everything we find in our name<->function database
729 lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack 736 lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack
730 populate_func_lookup_table( L, -1, NULL); 737 populate_func_lookup_table( L, -1, NULL);
@@ -769,7 +776,7 @@ static uint_t get_mt_id( Universe* U, lua_State* L, int i)
769 776
770 STACK_GROW( L, 3); 777 STACK_GROW( L, 3);
771 778
772 STACK_CHECK( L); 779 STACK_CHECK( L, 0);
773 push_registry_subtable( L, REG_MTID); 780 push_registry_subtable( L, REG_MTID);
774 lua_pushvalue( L, i); 781 lua_pushvalue( L, i);
775 lua_rawget( L, -2); 782 lua_rawget( L, -2);
@@ -839,7 +846,7 @@ static char const* find_lookup_name( lua_State* L, uint_t i, LookupMode mode_, c
839 DEBUGSPEW_CODE( Universe* const U = universe_get( L)); 846 DEBUGSPEW_CODE( Universe* const U = universe_get( L));
840 char const* fqn; 847 char const* fqn;
841 ASSERT_L( lua_isfunction( L, i) || lua_istable( L, i)); // ... v ... 848 ASSERT_L( lua_isfunction( L, i) || lua_istable( L, i)); // ... v ...
842 STACK_CHECK( L); 849 STACK_CHECK( L, 0);
843 STACK_GROW( L, 3); // up to 3 slots are necessary on error 850 STACK_GROW( L, 3); // up to 3 slots are necessary on error
844 if( mode_ == eLM_FromKeeper) 851 if( mode_ == eLM_FromKeeper)
845 { 852 {
@@ -859,7 +866,8 @@ static char const* find_lookup_name( lua_State* L, uint_t i, LookupMode mode_, c
859 else 866 else
860 { 867 {
861 // fetch the name from the source state's lookup table 868 // fetch the name from the source state's lookup table
862 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // ... v ... {} 869 REGISTRY_GET( L, LOOKUP_REGKEY); // ... v ... {}
870 STACK_MID( L, 1);
863 ASSERT_L( lua_istable( L, -1)); 871 ASSERT_L( lua_istable( L, -1));
864 lua_pushvalue( L, i); // ... v ... {} v 872 lua_pushvalue( L, i); // ... v ... {} v
865 lua_rawget( L, -2); // ... v ... {} "f.q.n" 873 lua_rawget( L, -2); // ... v ... {} "f.q.n"
@@ -915,7 +923,7 @@ static bool_t lookup_table( lua_State* L2, lua_State* L, uint_t i, LookupMode mo
915 return FALSE; 923 return FALSE;
916 } 924 }
917 // push the equivalent table in the destination's stack, retrieved from the lookup table 925 // push the equivalent table in the destination's stack, retrieved from the lookup table
918 STACK_CHECK( L2); // L // L2 926 STACK_CHECK( L2, 0); // L // L2
919 STACK_GROW( L2, 3); // up to 3 slots are necessary on error 927 STACK_GROW( L2, 3); // up to 3 slots are necessary on error
920 switch( mode_) 928 switch( mode_)
921 { 929 {
@@ -931,7 +939,8 @@ static bool_t lookup_table( lua_State* L2, lua_State* L, uint_t i, LookupMode mo
931 939
932 case eLM_LaneBody: 940 case eLM_LaneBody:
933 case eLM_FromKeeper: 941 case eLM_FromKeeper:
934 lua_getfield( L2, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {} 942 REGISTRY_GET( L2, LOOKUP_REGKEY); // {}
943 STACK_MID( L2, 1);
935 ASSERT_L( lua_istable( L2, -1)); 944 ASSERT_L( lua_istable( L2, -1));
936 lua_pushlstring( L2, fqn, len); // {} "f.q.n" 945 lua_pushlstring( L2, fqn, len); // {} "f.q.n"
937 lua_rawget( L2, -2); // {} t 946 lua_rawget( L2, -2); // {} t
@@ -987,7 +996,7 @@ static bool_t push_cached_table( lua_State* L2, uint_t L2_cache_i, lua_State* L,
987 996
988 ASSERT_L( L2_cache_i != 0); 997 ASSERT_L( L2_cache_i != 0);
989 STACK_GROW( L2, 3); 998 STACK_GROW( L2, 3);
990 STACK_CHECK( L2); 999 STACK_CHECK( L2, 0);
991 1000
992 // We don't need to use the from state ('L') in ID since the life span 1001 // We don't need to use the from state ('L') in ID since the life span
993 // is only for the duration of a copy (both states are locked). 1002 // is only for the duration of a copy (both states are locked).
@@ -1027,7 +1036,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
1027 return shortest_; 1036 return shortest_;
1028 } 1037 }
1029 STACK_GROW( L, 3); 1038 STACK_GROW( L, 3);
1030 STACK_CHECK( L); 1039 STACK_CHECK( L, 0);
1031 // stack top contains the table to search in 1040 // stack top contains the table to search in
1032 lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} 1041 lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?}
1033 lua_rawget( L, cache); // o "r" {c} {fqn} ... {?} nil/1 1042 lua_rawget( L, cache); // o "r" {c} {fqn} ... {?} nil/1
@@ -1170,7 +1179,7 @@ int luaG_nameof( lua_State* L)
1170 } 1179 }
1171 1180
1172 STACK_GROW( L, 4); 1181 STACK_GROW( L, 4);
1173 STACK_CHECK( L); 1182 STACK_CHECK( L, 0);
1174 // this slot will contain the shortest name we found when we are done 1183 // this slot will contain the shortest name we found when we are done
1175 lua_pushnil( L); // o nil 1184 lua_pushnil( L); // o nil
1176 // push a cache that will contain all already visited tables 1185 // push a cache that will contain all already visited tables
@@ -1207,7 +1216,7 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, LookupMod
1207 size_t len; 1216 size_t len;
1208 char const* fqn = find_lookup_name( L, i, mode_, upName_, &len); 1217 char const* fqn = find_lookup_name( L, i, mode_, upName_, &len);
1209 // push the equivalent function in the destination's stack, retrieved from the lookup table 1218 // push the equivalent function in the destination's stack, retrieved from the lookup table
1210 STACK_CHECK( L2); // L // L2 1219 STACK_CHECK( L2, 0); // L // L2
1211 STACK_GROW( L2, 3); // up to 3 slots are necessary on error 1220 STACK_GROW( L2, 3); // up to 3 slots are necessary on error
1212 switch( mode_) 1221 switch( mode_)
1213 { 1222 {
@@ -1223,7 +1232,8 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, LookupMod
1223 1232
1224 case eLM_LaneBody: 1233 case eLM_LaneBody:
1225 case eLM_FromKeeper: 1234 case eLM_FromKeeper:
1226 lua_getfield( L2, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {} 1235 REGISTRY_GET( L2, LOOKUP_REGKEY); // {}
1236 STACK_MID( L2, 1);
1227 ASSERT_L( lua_istable( L2, -1)); 1237 ASSERT_L( lua_istable( L2, -1));
1228 lua_pushlstring( L2, fqn, len); // {} "f.q.n" 1238 lua_pushlstring( L2, fqn, len); // {} "f.q.n"
1229 lua_rawget( L2, -2); // {} f 1239 lua_rawget( L2, -2); // {} f
@@ -1290,7 +1300,7 @@ static void inter_copy_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_
1290 luaL_Buffer b; 1300 luaL_Buffer b;
1291 ASSERT_L( L2_cache_i != 0); // ... {cache} ... p 1301 ASSERT_L( L2_cache_i != 0); // ... {cache} ... p
1292 STACK_GROW( L, 2); 1302 STACK_GROW( L, 2);
1293 STACK_CHECK( L); 1303 STACK_CHECK( L, 0);
1294 1304
1295 // 'lua_dump()' needs the function at top of stack 1305 // 'lua_dump()' needs the function at top of stack
1296 // if already on top of the stack, no need to push again 1306 // if already on top of the stack, no need to push again
@@ -1447,7 +1457,7 @@ static void push_cached_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua
1447 1457
1448 // L2_cache[id_str]= function 1458 // L2_cache[id_str]= function
1449 // 1459 //
1450 STACK_CHECK( L2); 1460 STACK_CHECK( L2, 0);
1451 1461
1452 // We don't need to use the from state ('L') in ID since the life span 1462 // We don't need to use the from state ('L') in ID since the life span
1453 // is only for the duration of a copy (both states are locked). 1463 // is only for the duration of a copy (both states are locked).
@@ -1492,7 +1502,7 @@ static bool_t push_cached_metatable( Universe* U, lua_State* L2, uint_t L2_cache
1492 { 1502 {
1493 uint_t const mt_id = get_mt_id( U, L, -1); // Unique id for the metatable 1503 uint_t const mt_id = get_mt_id( U, L, -1); // Unique id for the metatable
1494 1504
1495 STACK_CHECK( L2); 1505 STACK_CHECK( L2, 0);
1496 STACK_GROW( L2, 4); 1506 STACK_GROW( L2, 4);
1497 // do we already know this metatable? 1507 // do we already know this metatable?
1498 push_registry_subtable( L2, REG_MTID); // rst 1508 push_registry_subtable( L2, REG_MTID); // rst
@@ -1605,8 +1615,8 @@ static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lu
1605 bool_t ret = TRUE; 1615 bool_t ret = TRUE;
1606 int val_type = lua_type( L, i); 1616 int val_type = lua_type( L, i);
1607 STACK_GROW( L2, 1); 1617 STACK_GROW( L2, 1);
1608 STACK_CHECK( L); // L // L2 1618 STACK_CHECK( L, 0); // L // L2
1609 STACK_CHECK( L2); // L // L2 1619 STACK_CHECK( L2, 0); // L // L2
1610 1620
1611 /* Skip the object if it has metatable with { __lanesignore = true } */ 1621 /* Skip the object if it has metatable with { __lanesignore = true } */
1612 if( lua_getmetatable( L, i)) // ... mt 1622 if( lua_getmetatable( L, i)) // ... mt
@@ -1618,6 +1628,7 @@ static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lu
1618 } 1628 }
1619 lua_pop( L, 2); // ... 1629 lua_pop( L, 2); // ...
1620 } 1630 }
1631 STACK_MID( L, 0);
1621 1632
1622 /* Lets push nil to L2 if the object should be ignored */ 1633 /* Lets push nil to L2 if the object should be ignored */
1623 switch( val_type) 1634 switch( val_type)
@@ -1786,7 +1797,7 @@ static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lu
1786 { 1797 {
1787 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "FUNCTION %s\n" INDENT_END, upName_)); 1798 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "FUNCTION %s\n" INDENT_END, upName_));
1788 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1799 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1789 STACK_CHECK( L2); 1800 STACK_CHECK( L2, 0);
1790 push_cached_func( U, L2, L2_cache_i, L, i, mode_, upName_); 1801 push_cached_func( U, L2, L2_cache_i, L, i, mode_, upName_);
1791 STACK_END( L2, 1); 1802 STACK_END( L2, 1);
1792 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 1803 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
@@ -1800,8 +1811,8 @@ static bool_t inter_copy_one_( Universe* U, lua_State* L2, uint_t L2_cache_i, lu
1800 break; 1811 break;
1801 } 1812 }
1802 { 1813 {
1803 STACK_CHECK( L); 1814 STACK_CHECK( L, 0);
1804 STACK_CHECK( L2); 1815 STACK_CHECK( L2, 0);
1805 1816
1806 /* 1817 /*
1807 * First, let's try to see if this table is special (aka is it some table that we registered in our lookup databases during module registration?) 1818 * First, let's try to see if this table is special (aka is it some table that we registered in our lookup databases during module registration?)
@@ -1943,8 +1954,8 @@ int luaG_inter_copy_package( Universe* U, lua_State* L, lua_State* L2, int packa
1943 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END)); 1954 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END));
1944 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 1955 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1945 // package 1956 // package
1946 STACK_CHECK( L); 1957 STACK_CHECK( L, 0);
1947 STACK_CHECK( L2); 1958 STACK_CHECK( L2, 0);
1948 package_idx_ = lua_absindex( L, package_idx_); 1959 package_idx_ = lua_absindex( L, package_idx_);
1949 if( lua_type( L, package_idx_) != LUA_TTABLE) 1960 if( lua_type( L, package_idx_) != LUA_TTABLE)
1950 { 1961 {
@@ -2009,7 +2020,7 @@ int luaG_new_require( lua_State* L)
2009 //char const* modname = luaL_checkstring( L, 1); 2020 //char const* modname = luaL_checkstring( L, 1);
2010 2021
2011 STACK_GROW( L, args + 1); 2022 STACK_GROW( L, args + 1);
2012 STACK_CHECK( L); 2023 STACK_CHECK( L, 0);
2013 2024
2014 lua_pushvalue( L, lua_upvalueindex( 1)); 2025 lua_pushvalue( L, lua_upvalueindex( 1));
2015 for( i = 1; i <= args; ++ i) 2026 for( i = 1; i <= args; ++ i)
@@ -2041,7 +2052,7 @@ int luaG_new_require( lua_State* L)
2041void serialize_require( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L) 2052void serialize_require( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L)
2042{ 2053{
2043 STACK_GROW( L, 1); 2054 STACK_GROW( L, 1);
2044 STACK_CHECK( L); 2055 STACK_CHECK( L, 0);
2045 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "serializing require()\n" INDENT_END)); 2056 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "serializing require()\n" INDENT_END));
2046 2057
2047 // Check 'require' is there and not already wrapped; if not, do nothing 2058 // Check 'require' is there and not already wrapped; if not, do nothing
diff --git a/src/tools.h b/src/tools.h
index 84e323c..ca0b9fc 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -18,7 +18,9 @@ typedef struct s_Universe Universe;
18#define luaG_optunsigned(L,i,d) ((uint_t) luaL_optinteger(L,i,d)) 18#define luaG_optunsigned(L,i,d) ((uint_t) luaL_optinteger(L,i,d))
19#define luaG_tounsigned(L,i) ((uint_t) lua_tointeger(L,i)) 19#define luaG_tounsigned(L,i) ((uint_t) lua_tointeger(L,i))
20 20
21void luaG_dump( lua_State* L ); 21#ifdef _DEBUG
22void luaG_dump( lua_State* L);
23#endif // _DEBUG
22 24
23lua_State* luaG_newstate( Universe* U, lua_State* _from, char const* libs); 25lua_State* luaG_newstate( Universe* U, lua_State* _from, char const* libs);
24 26
@@ -39,7 +41,10 @@ void call_on_state_create( Universe* U, lua_State* L, lua_State* from_, LookupMo
39 41
40// ################################################################################################ 42// ################################################################################################
41 43
42extern char const* const CONFIG_REGKEY; 44// crc64/we of string "CONFIG_REGKEY" generated at http://www.nitrxgen.net/hashgen/
43extern char const* const LOOKUP_REGKEY; 45static DECLARE_CONST_UNIQUE_KEY( CONFIG_REGKEY, 0x31cd24894eae8624); // 'cancel_error' sentinel
46
47// crc64/we of string "LOOKUP_REGKEY" generated at http://www.nitrxgen.net/hashgen/
48static DECLARE_CONST_UNIQUE_KEY( LOOKUP_REGKEY, 0x5051ed67ee7b51a1); // 'cancel_error' sentinel
44 49
45#endif // __LANES_TOOLS_H__ 50#endif // __LANES_TOOLS_H__
diff --git a/src/universe.c b/src/universe.c
index 4689a09..d531bf2 100644
--- a/src/universe.c
+++ b/src/universe.c
@@ -29,6 +29,7 @@ THE SOFTWARE.
29*/ 29*/
30 30
31#include <string.h> 31#include <string.h>
32#include <assert.h>
32 33
33#include "universe.h" 34#include "universe.h"
34#include "compat.h" 35#include "compat.h"
@@ -44,9 +45,9 @@ Universe* universe_create( lua_State* L)
44{ 45{
45 Universe* U = (Universe*) lua_newuserdata( L, sizeof(Universe)); // universe 46 Universe* U = (Universe*) lua_newuserdata( L, sizeof(Universe)); // universe
46 memset( U, 0, sizeof( Universe)); 47 memset( U, 0, sizeof( Universe));
47 push_unique_key( L, UNIVERSE_REGKEY); // universe UNIVERSE_REGKEY 48 STACK_CHECK( L, 1);
48 lua_pushvalue( L, -2); // universe UNIVERSE_REGKEY universe 49 REGISTRY_SET( L, UNIVERSE_REGKEY, lua_pushvalue(L, -2)); // universe
49 lua_rawset( L, LUA_REGISTRYINDEX); // universe 50 STACK_END( L, 1);
50 return U; 51 return U;
51} 52}
52 53
@@ -54,17 +55,8 @@ Universe* universe_create( lua_State* L)
54 55
55void universe_store( lua_State* L, Universe* U) 56void universe_store( lua_State* L, Universe* U)
56{ 57{
57 STACK_CHECK( L); 58 STACK_CHECK( L, 0);
58 push_unique_key( L, UNIVERSE_REGKEY); 59 REGISTRY_SET( L, UNIVERSE_REGKEY, (NULL != U) ? lua_pushlightuserdata( L, U) : lua_pushnil( L));
59 if( NULL != U)
60 {
61 lua_pushlightuserdata( L, U);
62 }
63 else
64 {
65 lua_pushnil( L);
66 }
67 lua_rawset( L, LUA_REGISTRYINDEX);
68 STACK_END( L, 0); 60 STACK_END( L, 0);
69} 61}
70 62
@@ -74,9 +66,8 @@ Universe* universe_get( lua_State* L)
74{ 66{
75 Universe* universe; 67 Universe* universe;
76 STACK_GROW( L, 2); 68 STACK_GROW( L, 2);
77 STACK_CHECK( L); 69 STACK_CHECK( L, 0);
78 push_unique_key( L, UNIVERSE_REGKEY); 70 REGISTRY_GET( L, UNIVERSE_REGKEY);
79 lua_rawget( L, LUA_REGISTRYINDEX);
80 universe = lua_touserdata( L, -1); // NULL if nil 71 universe = lua_touserdata( L, -1); // NULL if nil
81 lua_pop( L, 1); 72 lua_pop( L, 1);
82 STACK_END( L, 0); 73 STACK_END( L, 0);