diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2018-11-19 09:16:49 +0100 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2018-11-19 09:16:49 +0100 |
commit | 7b4f59c5ebc84e426e2876906b24d7dd73342f07 (patch) | |
tree | f05748fc2d75c43c25865be01677271fff5d86e4 /src | |
parent | 01f83215a2ad235fbf306f591c6c0547b1bb7047 (diff) | |
download | lanes-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.c | 39 | ||||
-rw-r--r-- | src/keeper.c | 34 | ||||
-rw-r--r-- | src/lanes.c | 62 | ||||
-rw-r--r-- | src/lanes_private.h | 5 | ||||
-rw-r--r-- | src/linda.c | 9 | ||||
-rw-r--r-- | src/macros_and_utils.h | 68 | ||||
-rw-r--r-- | src/tools.c | 107 | ||||
-rw-r--r-- | src/tools.h | 11 | ||||
-rw-r--r-- | src/universe.c | 25 |
9 files changed, 202 insertions, 158 deletions
@@ -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. | |||
63 | static void push_registry_subtable_mode( lua_State* L, UniqueKey key_, const char* mode_) | 64 | static 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); | |||
128 | static void set_deep_lookup( lua_State* L) | 127 | static 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) | |||
147 | static void get_deep_lookup( lua_State* L) | 146 | static 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); | |||
166 | static void push_table( lua_State* L, int idx_) | 166 | static 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 | |||
240 | int keepercall_clear( lua_State* L) | 238 | int 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 |
115 | static void securize_debug_threadname( lua_State* L, Lane* s) | 115 | static 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; | |||
196 | static bool_t push_registry_table( lua_State* L, UniqueKey key, bool_t create) | 196 | static 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 |
2371 | void LANES_API luaopen_lanes_embedded( lua_State* L, lua_CFunction _luaopen_lanes) | 2369 | void 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. | |||
50 | extern bool_t copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode mode_); | 51 | extern bool_t copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode mode_); |
51 | extern void push_registry_subtable( lua_State* L, void* key_); | 52 | extern void push_registry_subtable( lua_State* L, void* key_); |
52 | 53 | ||
53 | char const* const CONFIG_REGKEY = "ee932492-a654-4506-9da8-f16540bdb5d4"; | ||
54 | char const* const LOOKUP_REGKEY = "ddea37aa-50c7-4d3f-8e0b-fb7a9d62bac5"; | ||
55 | |||
56 | DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); | 54 | DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); |
57 | 55 | ||
58 | 56 | ||
59 | /*---=== luaG_dump ===---*/ | 57 | /*---=== luaG_dump ===---*/ |
60 | 58 | #ifdef _DEBUG | |
61 | void luaG_dump( lua_State* L) | 59 | void 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 | ||
109 | void initialize_on_state_create( Universe* U, lua_State* L) | 108 | void 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) |
143 | static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2) | 142 | static 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) | |||
2041 | void serialize_require( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L) | 2052 | void 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 | ||
21 | void luaG_dump( lua_State* L ); | 21 | #ifdef _DEBUG |
22 | void luaG_dump( lua_State* L); | ||
23 | #endif // _DEBUG | ||
22 | 24 | ||
23 | lua_State* luaG_newstate( Universe* U, lua_State* _from, char const* libs); | 25 | lua_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 | ||
42 | extern char const* const CONFIG_REGKEY; | 44 | // crc64/we of string "CONFIG_REGKEY" generated at http://www.nitrxgen.net/hashgen/ |
43 | extern char const* const LOOKUP_REGKEY; | 45 | static 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/ | ||
48 | static 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 | ||
55 | void universe_store( lua_State* L, Universe* U) | 56 | void 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); |