aboutsummaryrefslogtreecommitdiff
path: root/src/tools.c
diff options
context:
space:
mode:
authorBenoit Germain <bnt period germain arrobase gmail period com>2014-02-26 11:53:30 +0100
committerBenoit Germain <bnt period germain arrobase gmail period com>2014-02-26 11:53:30 +0100
commitfe3c44e63f99538a02d42d2504ba405a6977ec0a (patch)
treeee369b7c44fb52b2030b784297e2b5ee788305c3 /src/tools.c
parentd2bd8f65c678d898b6b7e5e92f76cb4dcce97b3c (diff)
downloadlanes-fe3c44e63f99538a02d42d2504ba405a6977ec0a.tar.gz
lanes-fe3c44e63f99538a02d42d2504ba405a6977ec0a.tar.bz2
lanes-fe3c44e63f99538a02d42d2504ba405a6977ec0a.zip
Multiverse compatibility
* bumped version to 3.9.2 * Internal rework: the whole Lanes engine now works "per universe" to allow concurrent Lanes execution in more than one embedded master state * this universe is a full userdata created in the master state, selfdestruct_gc is the __gc for this userdata * most of what was initialized only once is now per-universe * Fixed potential crashes at desinit if problems occur during keeper states initialisation * Fixed require() not always serialized properly * Raise an error instead of crashing on deep userdata prelude memory allocation failure * Added forgotten mutex desinitialisation at universe shutdown
Diffstat (limited to 'src/tools.c')
-rw-r--r--src/tools.c347
1 files changed, 197 insertions, 150 deletions
diff --git a/src/tools.c b/src/tools.c
index 81ddf5c..65387e5 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -46,6 +46,8 @@ THE SOFTWARE.
46#include <malloc.h> 46#include <malloc.h>
47#endif 47#endif
48 48
49void* const UNIVERSE_REGKEY = (void*) luaopen_lanes_core;
50
49/* 51/*
50 * ############################################################################################### 52 * ###############################################################################################
51 * ########################################### ASSERT ############################################ 53 * ########################################### ASSERT ############################################
@@ -59,9 +61,6 @@ void ASSERT_IMPL( lua_State* L, bool_t cond_, char const* file_, int const line_
59 } 61 }
60} 62}
61 63
62// for verbose errors
63bool_t GVerboseErrors = FALSE;
64
65char const* const CONFIG_REGKEY = "ee932492-a654-4506-9da8-f16540bdb5d4"; 64char const* const CONFIG_REGKEY = "ee932492-a654-4506-9da8-f16540bdb5d4";
66char const* const LOOKUP_REGKEY = "ddea37aa-50c7-4d3f-8e0b-fb7a9d62bac5"; 65char const* const LOOKUP_REGKEY = "ddea37aa-50c7-4d3f-8e0b-fb7a9d62bac5";
67 66
@@ -109,11 +108,7 @@ void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int
109#endif // LUA_VERSION_NUM 108#endif // LUA_VERSION_NUM
110 109
111DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); 110DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+");
112DEBUGSPEW_CODE( int debugspew_indent_depth = 0);
113
114 111
115MUTEX_T deep_lock;
116MUTEX_T mtid_lock;
117 112
118/*---=== luaG_dump ===---*/ 113/*---=== luaG_dump ===---*/
119 114
@@ -161,46 +156,58 @@ void luaG_dump( lua_State* L ) {
161 fprintf( stderr, "\n" ); 156 fprintf( stderr, "\n" );
162} 157}
163 158
164static lua_CFunction s_on_state_create_func = NULL; 159void initialize_on_state_create( struct s_Universe* U, lua_State* L)
165int initialize_on_state_create( lua_State* L)
166{ 160{
167 STACK_CHECK( L); 161 STACK_CHECK( L);
168 lua_getfield( L, -1, "on_state_create"); // settings on_state_create|nil 162 lua_getfield( L, -1, "on_state_create"); // settings on_state_create|nil
169 if( !lua_isnil( L, -1)) 163 if( !lua_isnil( L, -1))
170 { 164 {
171 // store C function pointer in an internal variable 165 // store C function pointer in an internal variable
172 s_on_state_create_func = lua_tocfunction( L, -1); // settings on_state_create 166 U->on_state_create_func = lua_tocfunction( L, -1); // settings on_state_create
173 if( s_on_state_create_func != NULL) 167 if( U->on_state_create_func != NULL)
174 { 168 {
175 // make sure the function doesn't have upvalues 169 // make sure the function doesn't have upvalues
176 char const* upname = lua_getupvalue( L, -1, 1); // settings on_state_create upval? 170 char const* upname = lua_getupvalue( L, -1, 1); // settings on_state_create upval?
177 if( upname != NULL) // should be "" for C functions with upvalues if any 171 if( upname != NULL) // should be "" for C functions with upvalues if any
178 { 172 {
179 luaL_error( L, "on_state_create shouldn't have upvalues"); 173 (void) luaL_error( L, "on_state_create shouldn't have upvalues");
180 } 174 }
181 // remove this C function from the config table so that it doesn't cause problems 175 // remove this C function from the config table so that it doesn't cause problems
182 // when we transfer the config table in newly created Lua states 176 // when we transfer the config table in newly created Lua states
183 lua_pushnil( L); // settings on_state_create nil 177 lua_pushnil( L); // settings on_state_create nil
184 lua_setfield( L, -3, "on_state_create"); // settings on_state_create 178 lua_setfield( L, -3, "on_state_create"); // settings on_state_create
185 } 179 }
186 else 180 else
187 { 181 {
188 // optim: store marker saying we have such a function in the config table 182 // optim: store marker saying we have such a function in the config table
189 s_on_state_create_func = initialize_on_state_create; 183 U->on_state_create_func = (lua_CFunction) initialize_on_state_create;
190 } 184 }
191 } 185 }
192 lua_pop( L, 1); // settings 186 lua_pop( L, 1); // settings
193 STACK_END( L, 0); 187 STACK_END( L, 0);
194 return 0; 188}
189
190
191struct s_Universe* get_universe( lua_State* L)
192{
193 struct s_Universe* universe;
194 STACK_GROW( L, 2);
195 STACK_CHECK( L);
196 lua_pushlightuserdata( L, UNIVERSE_REGKEY);
197 lua_rawget( L, LUA_REGISTRYINDEX);
198 universe = lua_touserdata( L, -1); // NULL if nil
199 lua_pop( L, 1);
200 STACK_END( L, 0);
201 return universe;
195} 202}
196 203
197// just like lua_xmove, args are (from, to) 204// just like lua_xmove, args are (from, to)
198void luaG_copy_one_time_settings( lua_State* L, lua_State* L2) 205void luaG_copy_one_time_settings( struct s_Universe* U, lua_State* L, lua_State* L2)
199{ 206{
200 STACK_GROW( L, 1); 207 STACK_GROW( L, 1);
201 // copy settings from from source to destination registry 208 // copy settings from from source to destination registry
202 lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); 209 lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY);
203 if( luaG_inter_move( L, L2, 1, eLM_LaneBody) < 0) // error? 210 if( luaG_inter_move( U, L, L2, 1, eLM_LaneBody) < 0) // error?
204 { 211 {
205 (void) luaL_error( L, "failed to copy settings when loading lanes.core"); 212 (void) luaL_error( L, "failed to copy settings when loading lanes.core");
206 } 213 }
@@ -241,7 +248,7 @@ static const luaL_Reg libs[] =
241 { NULL, NULL } 248 { NULL, NULL }
242}; 249};
243 250
244static void open1lib( lua_State* L, char const* name_, size_t len_, lua_State* from_) 251static void open1lib( struct s_Universe* U, lua_State* L, char const* name_, size_t len_, lua_State* from_)
245{ 252{
246 int i; 253 int i;
247 for( i = 0; libs[i].name; ++ i) 254 for( i = 0; libs[i].name; ++ i)
@@ -258,7 +265,7 @@ static void open1lib( lua_State* L, char const* name_, size_t len_, lua_State* f
258 if( isLanesCore == TRUE) 265 if( isLanesCore == TRUE)
259 { 266 {
260 // copy settings from from source to destination registry 267 // copy settings from from source to destination registry
261 luaG_copy_one_time_settings( from_, L); 268 luaG_copy_one_time_settings( U, from_, L);
262 } 269 }
263 // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) 270 // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack)
264 luaL_requiref( L, name_, libfunc, !isLanesCore); 271 luaL_requiref( L, name_, libfunc, !isLanesCore);
@@ -377,6 +384,7 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _
377 int const cache = _ctx_base + 2; 384 int const cache = _ctx_base + 2;
378 // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search) 385 // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search)
379 int const breadth_first_cache = lua_gettop( L) + 1; 386 int const breadth_first_cache = lua_gettop( L) + 1;
387 DEBUGSPEW_CODE( struct s_Universe* U = get_universe( L));
380 388
381 STACK_GROW( L, 6); 389 STACK_GROW( L, 6);
382 // slot _i contains a table where we search for functions (or a full userdata with a metatable) 390 // slot _i contains a table where we search for functions (or a full userdata with a metatable)
@@ -503,7 +511,7 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _
503 { 511 {
504 DEBUGSPEW_CODE( char const* key = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : "not a string"); 512 DEBUGSPEW_CODE( char const* key = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : "not a string");
505 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "table '%s'\n" INDENT_END, key)); 513 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "table '%s'\n" INDENT_END, key));
506 DEBUGSPEW_CODE( ++ debugspew_indent_depth); 514 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
507 // un-visit this table in case we do need to process it 515 // un-visit this table in case we do need to process it
508 lua_pushvalue( L, -1); // ... {_i} {bfc} k {} {} 516 lua_pushvalue( L, -1); // ... {_i} {bfc} k {} {}
509 lua_rawget( L, cache); // ... {_i} {bfc} k {} n 517 lua_rawget( L, cache); // ... {_i} {bfc} k {} n
@@ -526,7 +534,7 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _
526 populate_func_lookup_table_recur( L, _ctx_base, lua_gettop( L), _depth); // ... {_i} {bfc} k {} 534 populate_func_lookup_table_recur( L, _ctx_base, lua_gettop( L), _depth); // ... {_i} {bfc} k {}
527 lua_pop( L, 1); // ... {_i} {bfc} k 535 lua_pop( L, 1); // ... {_i} {bfc} k
528 STACK_MID( L, 2); 536 STACK_MID( L, 2);
529 DEBUGSPEW_CODE( -- debugspew_indent_depth); 537 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
530 } 538 }
531 // remove table name from fqn stack 539 // remove table name from fqn stack
532 lua_pushnil( L); // ... {_i} {bfc} nil 540 lua_pushnil( L); // ... {_i} {bfc} nil
@@ -546,8 +554,9 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
546 int const ctx_base = lua_gettop( L) + 1; 554 int const ctx_base = lua_gettop( L) + 1;
547 int const in_base = lua_absindex( L, _i); 555 int const in_base = lua_absindex( L, _i);
548 int const start_depth = name_ ? 1 : 0; 556 int const start_depth = name_ ? 1 : 0;
557 DEBUGSPEW_CODE( struct s_Universe* U = get_universe( L));
549 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "NULL")); 558 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "NULL"));
550 DEBUGSPEW_CODE( ++ debugspew_indent_depth); 559 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
551 STACK_GROW( L, 3); 560 STACK_GROW( L, 3);
552 STACK_CHECK( L); 561 STACK_CHECK( L);
553 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {} 562 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {}
@@ -588,19 +597,19 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
588 (void) luaL_error( L, "unsupported module type %s", lua_typename( L, lua_type( L, in_base))); 597 (void) luaL_error( L, "unsupported module type %s", lua_typename( L, lua_type( L, in_base)));
589 } 598 }
590 STACK_END( L, 0); 599 STACK_END( L, 0);
591 DEBUGSPEW_CODE( -- debugspew_indent_depth); 600 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
592} 601}
593 602
594int call_on_state_create( lua_State* L, lua_State* from_, enum eLookupMode mode_) 603void call_on_state_create( struct s_Universe* U, lua_State* L, lua_State* from_, enum eLookupMode mode_)
595{ 604{
596 if( s_on_state_create_func != NULL) 605 if( U->on_state_create_func != NULL)
597 { 606 {
598 STACK_CHECK( L); 607 STACK_CHECK( L);
599 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); 608 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END));
600 if( s_on_state_create_func != initialize_on_state_create) 609 if( U->on_state_create_func != (lua_CFunction) initialize_on_state_create)
601 { 610 {
602 // C function: recreate a closure in the new state, bypassing the lookup scheme 611 // C function: recreate a closure in the new state, bypassing the lookup scheme
603 lua_pushcfunction( L, s_on_state_create_func); 612 lua_pushcfunction( L, U->on_state_create_func);
604 } 613 }
605 else // Lua function located in the config table, copied when we opened "lanes.core" 614 else // Lua function located in the config table, copied when we opened "lanes.core"
606 { 615 {
@@ -608,24 +617,22 @@ int call_on_state_create( lua_State* L, lua_State* from_, enum eLookupMode mode_
608 { 617 {
609 // if attempting to call in a keeper state, do nothing because the function doesn't exist there 618 // if attempting to call in a keeper state, do nothing because the function doesn't exist there
610 // this doesn't count as an error though 619 // this doesn't count as an error though
611 return 0; 620 return;
612 } 621 }
613 lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); 622 lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY);
614 lua_getfield( L, -1, "on_state_create"); 623 lua_getfield( L, -1, "on_state_create");
615 lua_remove( L, -2); 624 lua_remove( L, -2);
616 } 625 }
617 // capture error and forward it to main state 626 // capture error and raise it in caller state
618 if( lua_pcall( L, 0, 0, 0) != LUA_OK) 627 if( lua_pcall( L, 0, 0, 0) != LUA_OK)
619 { 628 {
620 lua_pushfstring( from_, "on_state_create failed: \"%s\"", lua_isstring( L, -1) ? lua_tostring( L, -1) : lua_typename( L, lua_type( L, -1))); 629 luaL_error( from_, "on_state_create failed: \"%s\"", lua_isstring( L, -1) ? lua_tostring( L, -1) : lua_typename( L, lua_type( L, -1)));
621 return 1;
622 } 630 }
623 STACK_END( L, 0); 631 STACK_END( L, 0);
624 } 632 }
625 return 0;
626} 633}
627 634
628/* 635/*
629 * Like 'luaL_openlibs()' but allows the set of libraries be selected 636 * Like 'luaL_openlibs()' but allows the set of libraries be selected
630 * 637 *
631 * NULL no libraries, not even base 638 * NULL no libraries, not even base
@@ -638,7 +645,7 @@ int call_on_state_create( lua_State* L, lua_State* from_, enum eLookupMode mode_
638 * *NOT* called for keeper states! 645 * *NOT* called for keeper states!
639 * 646 *
640 */ 647 */
641lua_State* luaG_newstate( lua_State* from_, char const* libs_) 648lua_State* luaG_newstate( struct s_Universe* U, lua_State* from_, char const* libs_)
642{ 649{
643 // re-use alloc function from the originating state 650 // re-use alloc function from the originating state
644#if PROPAGATE_ALLOCF 651#if PROPAGATE_ALLOCF
@@ -651,22 +658,30 @@ lua_State* luaG_newstate( lua_State* from_, char const* libs_)
651 (void) luaL_error( from_, "luaG_newstate() failed while creating state; out of memory"); 658 (void) luaL_error( from_, "luaG_newstate() failed while creating state; out of memory");
652 } 659 }
653 660
661 STACK_GROW( L, 2);
662 STACK_CHECK( L);
663
664 // copy the universe as a light userdata (only the master state holds the full userdata)
665 // that way, if Lanes is required in this new state, we'll know we are part of this universe
666 lua_pushlightuserdata( L, UNIVERSE_REGKEY);
667 lua_pushlightuserdata( L, U);
668 lua_rawset( L, LUA_REGISTRYINDEX);
669 STACK_MID( L, 0);
670
654 // we'll need this every time we transfer some C function from/to this state 671 // we'll need this every time we transfer some C function from/to this state
655 lua_newtable( L); 672 lua_newtable( L);
656 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); 673 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY);
657 674
658 // neither libs (not even 'base') nor special init func: we are done 675 // neither libs (not even 'base') nor special init func: we are done
659 if( libs_ == NULL && s_on_state_create_func == NULL) 676 if( libs_ == NULL && U->on_state_create_func == NULL)
660 { 677 {
661 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate(NULL)\n" INDENT_END)); 678 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate(NULL)\n" INDENT_END));
662 return L; 679 return L;
663 } 680 }
664 681
665 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate()\n" INDENT_END)); 682 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate()\n" INDENT_END));
666 DEBUGSPEW_CODE( ++ debugspew_indent_depth); 683 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
667 684
668 STACK_GROW( L, 2);
669 STACK_CHECK( L);
670 // 'lua.c' stops GC during initialization so perhaps its a good idea. :) 685 // 'lua.c' stops GC during initialization so perhaps its a good idea. :)
671 lua_gc( L, LUA_GCSTOP, 0); 686 lua_gc( L, LUA_GCSTOP, 0);
672 687
@@ -681,7 +696,7 @@ lua_State* luaG_newstate( lua_State* from_, char const* libs_)
681 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END)); 696 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END));
682 luaL_openlibs( L); 697 luaL_openlibs( L);
683 // don't forget lanes.core for regular lane states 698 // don't forget lanes.core for regular lane states
684 open1lib( L, "lanes.core", 10, from_); 699 open1lib( U, L, "lanes.core", 10, from_);
685 libs_ = NULL; // done with libs 700 libs_ = NULL; // done with libs
686 } 701 }
687 else 702 else
@@ -715,19 +730,16 @@ lua_State* luaG_newstate( lua_State* from_, char const* libs_)
715 while( isalnum( p[len]) || p[len] == '.') 730 while( isalnum( p[len]) || p[len] == '.')
716 ++ len; 731 ++ len;
717 // open library 732 // open library
718 open1lib( L, p, len, from_); 733 open1lib( U, L, p, len, from_);
719 } 734 }
720 serialize_require( L);
721 } 735 }
722
723 lua_gc( L, LUA_GCRESTART, 0); 736 lua_gc( L, LUA_GCRESTART, 0);
724 737
738 serialize_require( L);
739
725 // call this after the base libraries are loaded and GC is restarted 740 // call this after the base libraries are loaded and GC is restarted
726 if( call_on_state_create( L, from_, eLM_LaneBody)) 741 // will raise an error in from_ in case of problem
727 { 742 call_on_state_create( U, L, from_, eLM_LaneBody);
728 // if something went wrong, the error message is pushed on the stack
729 lua_error( from_);
730 }
731 743
732 STACK_CHECK( L); 744 STACK_CHECK( L);
733 // after all this, register everything we find in our name<->function database 745 // after all this, register everything we find in our name<->function database
@@ -735,7 +747,7 @@ lua_State* luaG_newstate( lua_State* from_, char const* libs_)
735 populate_func_lookup_table( L, -1, NULL); 747 populate_func_lookup_table( L, -1, NULL);
736 lua_pop( L, 1); 748 lua_pop( L, 1);
737 STACK_END( L, 0); 749 STACK_END( L, 0);
738 DEBUGSPEW_CODE( -- debugspew_indent_depth); 750 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
739 return L; 751 return L;
740} 752}
741 753
@@ -845,6 +857,16 @@ static inline luaG_IdFunction get_idfunc( lua_State* L, int index, enum eLookupM
845} 857}
846 858
847 859
860void free_deep_prelude( lua_State* L, DEEP_PRELUDE* prelude_)
861{
862 // Call 'idfunc( "delete", deep_ptr )' to make deep cleanup
863 lua_pushlightuserdata( L, prelude_->deep);
864 ASSERT_L( prelude_->idfunc);
865 prelude_->idfunc( L, eDO_delete);
866 DEEP_FREE( (void*) prelude_);
867}
868
869
848/* 870/*
849* void= mt.__gc( proxy_ud ) 871* void= mt.__gc( proxy_ud )
850* 872*
@@ -855,23 +877,20 @@ static int deep_userdata_gc( lua_State* L)
855{ 877{
856 DEEP_PRELUDE** proxy = (DEEP_PRELUDE**) lua_touserdata( L, 1); 878 DEEP_PRELUDE** proxy = (DEEP_PRELUDE**) lua_touserdata( L, 1);
857 DEEP_PRELUDE* p = *proxy; 879 DEEP_PRELUDE* p = *proxy;
880 struct s_Universe* U = get_universe( L);
858 int v; 881 int v;
859 882
860 *proxy = 0; // make sure we don't use it any more 883 *proxy = 0; // make sure we don't use it any more
861 884
862 MUTEX_LOCK( &deep_lock); 885 MUTEX_LOCK( &U->deep_lock);
863 v = -- (p->refcount); 886 v = -- (p->refcount);
864 MUTEX_UNLOCK( &deep_lock); 887 MUTEX_UNLOCK( &U->deep_lock);
865 888
866 if( v == 0) 889 if( v == 0)
867 { 890 {
868 // clean stack so we can call 'idfunc' directly 891 // 'idfunc' expects a clean stack to work on
869 lua_settop( L, 0); 892 lua_settop( L, 0);
870 // Call 'idfunc( "delete", deep_ptr )' to make deep cleanup 893 free_deep_prelude( L, p);
871 lua_pushlightuserdata( L, p->deep);
872 ASSERT_L( p->idfunc);
873 p->idfunc( L, eDO_delete);
874 DEEP_FREE( (void*) p);
875 894
876 // top was set to 0, then userdata was pushed. "delete" might want to pop the userdata (we don't care), but should not push anything! 895 // top was set to 0, then userdata was pushed. "delete" might want to pop the userdata (we don't care), but should not push anything!
877 if ( lua_gettop( L) > 1) 896 if ( lua_gettop( L) > 1)
@@ -892,7 +911,7 @@ static int deep_userdata_gc( lua_State* L)
892 * used in this Lua state (metatable, registring it). Otherwise, increments the 911 * used in this Lua state (metatable, registring it). Otherwise, increments the
893 * reference count. 912 * reference count.
894 */ 913 */
895char const* push_deep_proxy( lua_State* L, DEEP_PRELUDE* prelude, enum eLookupMode mode_) 914char const* push_deep_proxy( struct s_Universe* U, lua_State* L, DEEP_PRELUDE* prelude, enum eLookupMode mode_)
896{ 915{
897 DEEP_PRELUDE** proxy; 916 DEEP_PRELUDE** proxy;
898 917
@@ -910,9 +929,9 @@ char const* push_deep_proxy( lua_State* L, DEEP_PRELUDE* prelude, enum eLookupMo
910 lua_pop( L, 1); // DPC 929 lua_pop( L, 1); // DPC
911 } 930 }
912 931
913 MUTEX_LOCK( &deep_lock); 932 MUTEX_LOCK( &U->deep_lock);
914 ++ (prelude->refcount); // one more proxy pointing to this deep data 933 ++ (prelude->refcount); // one more proxy pointing to this deep data
915 MUTEX_UNLOCK( &deep_lock); 934 MUTEX_UNLOCK( &U->deep_lock);
916 935
917 STACK_GROW( L, 7); 936 STACK_GROW( L, 7);
918 STACK_CHECK( L); 937 STACK_CHECK( L);
@@ -1048,9 +1067,9 @@ char const* push_deep_proxy( lua_State* L, DEEP_PRELUDE* prelude, enum eLookupMo
1048* 1067*
1049* 'idfunc' must fulfill the following features: 1068* 'idfunc' must fulfill the following features:
1050* 1069*
1051* lightuserdata= idfunc( "new" [, ...] ) -- creates a new deep data instance 1070* lightuserdata = idfunc( eDO_new [, ...] ) -- creates a new deep data instance
1052* void= idfunc( "delete", lightuserdata ) -- releases a deep data instance 1071* void = idfunc( eDO_delete, lightuserdata ) -- releases a deep data instance
1053* tbl= idfunc( "metatable" ) -- gives metatable for userdata proxies 1072* tbl = idfunc( eDO_metatable ) -- gives metatable for userdata proxies
1054* 1073*
1055* Reference counting and true userdata proxying are taken care of for the 1074* Reference counting and true userdata proxying are taken care of for the
1056* actual data type. 1075* actual data type.
@@ -1064,7 +1083,10 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc)
1064{ 1083{
1065 char const* errmsg; 1084 char const* errmsg;
1066 DEEP_PRELUDE* prelude = DEEP_MALLOC( sizeof(DEEP_PRELUDE)); 1085 DEEP_PRELUDE* prelude = DEEP_MALLOC( sizeof(DEEP_PRELUDE));
1067 ASSERT_L( prelude); 1086 if( prelude == NULL)
1087 {
1088 return luaL_error( L, "couldn't not allocate deep prelude: out of memory");
1089 }
1068 1090
1069 prelude->refcount = 0; // 'push_deep_proxy' will lift it to 1 1091 prelude->refcount = 0; // 'push_deep_proxy' will lift it to 1
1070 prelude->idfunc = idfunc; 1092 prelude->idfunc = idfunc;
@@ -1084,7 +1106,7 @@ int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc)
1084 luaL_error( L, "Bad idfunc(eDO_new): should not push anything on the stack"); 1106 luaL_error( L, "Bad idfunc(eDO_new): should not push anything on the stack");
1085 } 1107 }
1086 } 1108 }
1087 errmsg = push_deep_proxy( L, prelude, eLM_LaneBody); // proxy 1109 errmsg = push_deep_proxy( get_universe( L), L, prelude, eLM_LaneBody); // proxy
1088 if( errmsg != NULL) 1110 if( errmsg != NULL)
1089 { 1111 {
1090 luaL_error( L, errmsg); 1112 luaL_error( L, errmsg);
@@ -1125,7 +1147,7 @@ void* luaG_todeep( lua_State* L, luaG_IdFunction idfunc, int index)
1125 * the id function of the copied value, or NULL for non-deep userdata 1147 * the id function of the copied value, or NULL for non-deep userdata
1126 * (not copied) 1148 * (not copied)
1127 */ 1149 */
1128static luaG_IdFunction copydeep( lua_State* L, lua_State* L2, int index, enum eLookupMode mode_) 1150static luaG_IdFunction copydeep( struct s_Universe* U, lua_State* L, lua_State* L2, int index, enum eLookupMode mode_)
1129{ 1151{
1130 char const* errmsg; 1152 char const* errmsg;
1131 luaG_IdFunction idfunc = get_idfunc( L, index, mode_); 1153 luaG_IdFunction idfunc = get_idfunc( L, index, mode_);
@@ -1134,7 +1156,7 @@ static luaG_IdFunction copydeep( lua_State* L, lua_State* L2, int index, enum eL
1134 return NULL; // not a deep userdata 1156 return NULL; // not a deep userdata
1135 } 1157 }
1136 1158
1137 errmsg = push_deep_proxy( L2, *(DEEP_PRELUDE**) lua_touserdata( L, index), mode_); 1159 errmsg = push_deep_proxy( U, L2, *(DEEP_PRELUDE**) lua_touserdata( L, index), mode_);
1138 if( errmsg != NULL) 1160 if( errmsg != NULL)
1139 { 1161 {
1140 // raise the error in the proper state (not the keeper) 1162 // raise the error in the proper state (not the keeper)
@@ -1207,47 +1229,47 @@ static inline void push_registry_subtable( lua_State* L, void* key_)
1207/* 1229/*
1208* Get a unique ID for metatable at [i]. 1230* Get a unique ID for metatable at [i].
1209*/ 1231*/
1210static 1232static uint_t get_mt_id( struct s_Universe* U, lua_State* L, int i)
1211uint_t get_mt_id( lua_State *L, int i ) { 1233{
1212 static uint_t last_id= 0; 1234 uint_t id;
1213 uint_t id; 1235
1214 1236 i = lua_absindex( L, i);
1215 i = lua_absindex( L, i); 1237
1216 1238 STACK_GROW( L, 3);
1217 STACK_GROW(L,3); 1239
1218 1240 STACK_CHECK( L);
1219 STACK_CHECK( L); 1241 push_registry_subtable( L, REG_MTID);
1220 push_registry_subtable( L, REG_MTID ); 1242 lua_pushvalue( L, i);
1221 lua_pushvalue(L, i); 1243 lua_rawget( L, -2);
1222 lua_rawget( L, -2 ); 1244 //
1223 // 1245 // [-2]: reg[REG_MTID]
1224 // [-2]: reg[REG_MTID] 1246 // [-1]: nil/uint
1225 // [-1]: nil/uint 1247
1226 1248 id = (uint_t) lua_tointeger( L, -1); // 0 for nil
1227 id= (uint_t)lua_tointeger(L,-1); // 0 for nil 1249 lua_pop( L, 1);
1228 lua_pop(L,1); 1250 STACK_MID( L, 1);
1229 STACK_MID( L, 1); 1251
1230 1252 if( id == 0)
1231 if (id==0) { 1253 {
1232 MUTEX_LOCK( &mtid_lock ); 1254 MUTEX_LOCK( &U->mtid_lock);
1233 id= ++last_id; 1255 id = ++ U->last_mt_id;
1234 MUTEX_UNLOCK( &mtid_lock ); 1256 MUTEX_UNLOCK( &U->mtid_lock);
1235 1257
1236 /* Create two-way references: id_uint <-> table 1258 /* Create two-way references: id_uint <-> table
1237 */ 1259 */
1238 lua_pushvalue(L,i); 1260 lua_pushvalue( L, i);
1239 lua_pushinteger(L,id); 1261 lua_pushinteger( L, id);
1240 lua_rawset( L, -3 ); 1262 lua_rawset( L, -3);
1241 1263
1242 lua_pushinteger(L,id); 1264 lua_pushinteger( L, id);
1243 lua_pushvalue(L,i); 1265 lua_pushvalue( L, i);
1244 lua_rawset( L, -3 ); 1266 lua_rawset( L, -3);
1245 } 1267 }
1246 lua_pop(L,1); // remove 'reg[REG_MTID]' reference 1268 lua_pop( L, 1); // remove 'reg[REG_MTID]' reference
1247 1269
1248 STACK_END( L, 0); 1270 STACK_END( L, 0);
1249 1271
1250 return id; 1272 return id;
1251} 1273}
1252 1274
1253 1275
@@ -1518,7 +1540,7 @@ static int sentinelfunc( lua_State* L)
1518/* 1540/*
1519* Push a looked-up native/LuaJIT function. 1541* Push a looked-up native/LuaJIT function.
1520*/ 1542*/
1521static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_) 1543static void lookup_native_func( struct s_Universe* U, lua_State* L2, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_)
1522{ 1544{
1523 char const* fqn; // L // L2 1545 char const* fqn; // L // L2
1524 size_t len; 1546 size_t len;
@@ -1576,14 +1598,20 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, enum eLoo
1576 // push the equivalent function in the destination's stack, retrieved from the lookup table 1598 // push the equivalent function in the destination's stack, retrieved from the lookup table
1577 STACK_CHECK( L2); 1599 STACK_CHECK( L2);
1578 STACK_GROW( L2, 3); // up to 3 slots are necessary on error 1600 STACK_GROW( L2, 3); // up to 3 slots are necessary on error
1579 if( mode_ == eLM_ToKeeper) 1601 switch( mode_)
1580 { 1602 {
1603 default: // shouldn't happen, in theory...
1604 (void) luaL_error( L, "internal error: unknown lookup mode");
1605 return;
1606
1607 case eLM_ToKeeper:
1581 // push a sentinel closure that holds the lookup name as upvalue 1608 // push a sentinel closure that holds the lookup name as upvalue
1582 lua_pushlstring( L2, fqn, len); // "f.q.n" 1609 lua_pushlstring( L2, fqn, len); // "f.q.n"
1583 lua_pushcclosure( L2, sentinelfunc, 1); // f 1610 lua_pushcclosure( L2, sentinelfunc, 1); // f
1584 } 1611 break;
1585 else 1612
1586 { 1613 case eLM_LaneBody:
1614 case eLM_FromKeeper:
1587 lua_getfield( L2, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {} 1615 lua_getfield( L2, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {}
1588 ASSERT_L( lua_istable( L2, -1)); 1616 ASSERT_L( lua_istable( L2, -1));
1589 lua_pushlstring( L2, fqn, len); // {} "f.q.n" 1617 lua_pushlstring( L2, fqn, len); // {} "f.q.n"
@@ -1600,6 +1628,23 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, enum eLoo
1600 return; 1628 return;
1601 } 1629 }
1602 lua_remove( L2, -2); // f 1630 lua_remove( L2, -2); // f
1631 break;
1632
1633 /* keep it in case I need it someday, who knows...
1634 case eLM_RawFunctions:
1635 {
1636 int n;
1637 char const* upname;
1638 lua_CFunction f = lua_tocfunction( L, i);
1639 // copy upvalues
1640 for( n = 0; (upname = lua_getupvalue( L, i, 1 + n)) != NULL; ++ n)
1641 {
1642 luaG_inter_move( U, L, L2, 1, mode_); // [up[,up ...]]
1643 }
1644 lua_pushcclosure( L2, f, n); //
1645 }
1646 break;
1647 */
1603 } 1648 }
1604 STACK_END( L2, 1); 1649 STACK_END( L2, 1);
1605} 1650}
@@ -1608,12 +1653,15 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, enum eLoo
1608 * Copy a function over, which has not been found in the cache. 1653 * Copy a function over, which has not been found in the cache.
1609 * L2 has the cache key for this function at the top of the stack 1654 * L2 has the cache key for this function at the top of the stack
1610*/ 1655*/
1611enum e_vt { 1656enum e_vt
1612 VT_NORMAL, VT_KEY, VT_METATABLE 1657{
1658 VT_NORMAL,
1659 VT_KEY,
1660 VT_METATABLE
1613}; 1661};
1614static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt value_type, enum eLookupMode mode_, char const* upName_); 1662static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt value_type, enum eLookupMode mode_, char const* upName_);
1615 1663
1616static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_) 1664static void inter_copy_func( struct s_Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_)
1617{ 1665{
1618 int n, needToPush; 1666 int n, needToPush;
1619 luaL_Buffer b; 1667 luaL_Buffer b;
@@ -1722,7 +1770,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin
1722#endif // LUA_VERSION_NUM 1770#endif // LUA_VERSION_NUM
1723 { 1771 {
1724 DEBUGSPEW_CODE( fprintf( stderr, "copying value\n")); 1772 DEBUGSPEW_CODE( fprintf( stderr, "copying value\n"));
1725 if( !inter_copy_one_( L2, L2_cache_i, L, lua_gettop( L), VT_NORMAL, mode_, upname)) // ... {cache} ... function <upvalues> 1773 if( !inter_copy_one_( U, L2, L2_cache_i, L, lua_gettop( L), VT_NORMAL, mode_, upname)) // ... {cache} ... function <upvalues>
1726 { 1774 {
1727 luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1)); 1775 luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1));
1728 } 1776 }
@@ -1742,7 +1790,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin
1742 int func_index = lua_gettop( L2) - n; 1790 int func_index = lua_gettop( L2) - n;
1743 for( ; n > 0; -- n) 1791 for( ; n > 0; -- n)
1744 { 1792 {
1745 char const* rc = lua_setupvalue( L2, func_index, n); // ... {cache} ... function 1793 char const* rc = lua_setupvalue( L2, func_index, n); // ... {cache} ... function
1746 // 1794 //
1747 // "assigns the value at the top of the stack to the upvalue and returns its name. 1795 // "assigns the value at the top of the stack to the upvalue and returns its name.
1748 // It also pops the value from the stack." 1796 // It also pops the value from the stack."
@@ -1750,7 +1798,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin
1750 ASSERT_L( rc); // not having enough slots? 1798 ASSERT_L( rc); // not having enough slots?
1751 } 1799 }
1752 // once all upvalues have been set we are left 1800 // once all upvalues have been set we are left
1753 // with the function at the top of the stack // ... {cache} ... function 1801 // with the function at the top of the stack // ... {cache} ... function
1754 } 1802 }
1755 } 1803 }
1756 STACK_END( L, 0); 1804 STACK_END( L, 0);
@@ -1762,7 +1810,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin
1762 * 1810 *
1763 * Always pushes a function to 'L2'. 1811 * Always pushes a function to 'L2'.
1764 */ 1812 */
1765static void push_cached_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_) 1813static void push_cached_func( struct s_Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_)
1766{ 1814{
1767 FuncSubType funcSubType; 1815 FuncSubType funcSubType;
1768 /*lua_CFunction cfunc =*/ luaG_tocfunction( L, i, &funcSubType); // NULL for LuaJIT-fast && bytecode functions 1816 /*lua_CFunction cfunc =*/ luaG_tocfunction( L, i, &funcSubType); // NULL for LuaJIT-fast && bytecode functions
@@ -1798,7 +1846,7 @@ static void push_cached_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, ui
1798 // via upvalues 1846 // via upvalues
1799 // 1847 //
1800 // pushes a copy of the func, stores a reference in the cache 1848 // pushes a copy of the func, stores a reference in the cache
1801 inter_copy_func( L2, L2_cache_i, L, i, mode_, upName_); // ... {cache} ... function 1849 inter_copy_func( U, L2, L2_cache_i, L, i, mode_, upName_); // ... {cache} ... function
1802 } 1850 }
1803 else // found function in the cache 1851 else // found function in the cache
1804 { 1852 {
@@ -1808,7 +1856,7 @@ static void push_cached_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, ui
1808 } 1856 }
1809 else // function is native/LuaJIT: no need to cache 1857 else // function is native/LuaJIT: no need to cache
1810 { 1858 {
1811 lookup_native_func( L2, L, i, mode_, upName_); // ... {cache} ... function 1859 lookup_native_func( U, L2, L, i, mode_, upName_); // ... {cache} ... function
1812 } 1860 }
1813 1861
1814 // 1862 //
@@ -1826,7 +1874,7 @@ static void push_cached_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, ui
1826* 1874*
1827* Returns TRUE if value was pushed, FALSE if its type is non-supported. 1875* Returns TRUE if value was pushed, FALSE if its type is non-supported.
1828*/ 1876*/
1829static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt vt, enum eLookupMode mode_, char const* upName_) 1877static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt vt, enum eLookupMode mode_, char const* upName_)
1830{ 1878{
1831 bool_t ret = TRUE; 1879 bool_t ret = TRUE;
1832 STACK_GROW( L2, 1); 1880 STACK_GROW( L2, 1);
@@ -1884,7 +1932,7 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u
1884 /* Allow only deep userdata entities to be copied across 1932 /* Allow only deep userdata entities to be copied across
1885 */ 1933 */
1886 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "USERDATA\n" INDENT_END)); 1934 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "USERDATA\n" INDENT_END));
1887 if( !copydeep( L, L2, i, mode_)) 1935 if( !copydeep( U, L, L2, i, mode_))
1888 { 1936 {
1889 // Not a deep full userdata 1937 // Not a deep full userdata
1890 bool_t demote = FALSE; 1938 bool_t demote = FALSE;
@@ -1928,11 +1976,11 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u
1928 } 1976 }
1929 { 1977 {
1930 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "FUNCTION %s\n" INDENT_END, upName_)); 1978 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "FUNCTION %s\n" INDENT_END, upName_));
1931 DEBUGSPEW_CODE( ++ debugspew_indent_depth); 1979 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
1932 STACK_CHECK( L2); 1980 STACK_CHECK( L2);
1933 push_cached_func( L2, L2_cache_i, L, i, mode_, upName_); 1981 push_cached_func( U, L2, L2_cache_i, L, i, mode_, upName_);
1934 STACK_END( L2, 1); 1982 STACK_END( L2, 1);
1935 DEBUGSPEW_CODE( -- debugspew_indent_depth); 1983 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
1936 } 1984 }
1937 break; 1985 break;
1938 1986
@@ -1973,10 +2021,10 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u
1973 2021
1974 /* Only basic key types are copied over; others ignored 2022 /* Only basic key types are copied over; others ignored
1975 */ 2023 */
1976 if( inter_copy_one_( L2, 0 /*key*/, L, key_i, VT_KEY, mode_, upName_)) 2024 if( inter_copy_one_( U, L2, 0 /*key*/, L, key_i, VT_KEY, mode_, upName_))
1977 { 2025 {
1978 char* valPath = (char*) upName_; 2026 char* valPath = (char*) upName_;
1979 if( GVerboseErrors) 2027 if( U->verboseErrors)
1980 { 2028 {
1981 // for debug purposes, let's try to build a useful name 2029 // for debug purposes, let's try to build a useful name
1982 if( lua_type( L, key_i) == LUA_TSTRING) 2030 if( lua_type( L, key_i) == LUA_TSTRING)
@@ -1994,7 +2042,7 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u
1994 * Contents of metatables are copied with cache checking; 2042 * Contents of metatables are copied with cache checking;
1995 * important to detect loops. 2043 * important to detect loops.
1996 */ 2044 */
1997 if( inter_copy_one_( L2, L2_cache_i, L, val_i, VT_NORMAL, mode_, valPath)) 2045 if( inter_copy_one_( U, L2, L2_cache_i, L, val_i, VT_NORMAL, mode_, valPath))
1998 { 2046 {
1999 ASSERT_L( lua_istable( L2, -3)); 2047 ASSERT_L( lua_istable( L2, -3));
2000 lua_rawset( L2, -3); // add to table (pops key & val) 2048 lua_rawset( L2, -3); // add to table (pops key & val)
@@ -2016,7 +2064,7 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u
2016 // 2064 //
2017 // L [-1]: metatable 2065 // L [-1]: metatable
2018 2066
2019 uint_t mt_id = get_mt_id( L, -1); // Unique id for the metatable 2067 uint_t mt_id = get_mt_id( U, L, -1); // Unique id for the metatable
2020 2068
2021 STACK_GROW( L2, 4); 2069 STACK_GROW( L2, 4);
2022 2070
@@ -2036,7 +2084,7 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u
2036 lua_pop( L2, 1); 2084 lua_pop( L2, 1);
2037 STACK_MID( L2, 2); 2085 STACK_MID( L2, 2);
2038 ASSERT_L( lua_istable(L,-1)); 2086 ASSERT_L( lua_istable(L,-1));
2039 if( inter_copy_one_( L2, L2_cache_i /*for function cacheing*/, L, lua_gettop(L) /*[-1]*/, VT_METATABLE, mode_, upName_)) 2087 if( inter_copy_one_( U, L2, L2_cache_i /*for function cacheing*/, L, lua_gettop(L) /*[-1]*/, VT_METATABLE, mode_, upName_))
2040 { 2088 {
2041 // 2089 //
2042 // L2 ([-3]: copied table) 2090 // L2 ([-3]: copied table)
@@ -2103,13 +2151,13 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u
2103* 2151*
2104* Note: Parameters are in this order ('L' = from first) to be same as 'lua_xmove'. 2152* Note: Parameters are in this order ('L' = from first) to be same as 'lua_xmove'.
2105*/ 2153*/
2106int luaG_inter_copy( lua_State* L, lua_State* L2, uint_t n, enum eLookupMode mode_) 2154int luaG_inter_copy( struct s_Universe* U, lua_State* L, lua_State* L2, uint_t n, enum eLookupMode mode_)
2107{ 2155{
2108 uint_t top_L = lua_gettop( L); 2156 uint_t top_L = lua_gettop( L);
2109 uint_t top_L2 = lua_gettop( L2); 2157 uint_t top_L2 = lua_gettop( L2);
2110 uint_t i, j; 2158 uint_t i, j;
2111 char tmpBuf[16]; 2159 char tmpBuf[16];
2112 char* pBuf = GVerboseErrors ? tmpBuf : "?"; 2160 char* pBuf = U->verboseErrors ? tmpBuf : "?";
2113 bool_t copyok = TRUE; 2161 bool_t copyok = TRUE;
2114 2162
2115 if( n > top_L) 2163 if( n > top_L)
@@ -2129,11 +2177,11 @@ int luaG_inter_copy( lua_State* L, lua_State* L2, uint_t n, enum eLookupMode mod
2129 2177
2130 for( i = top_L - n + 1, j = 1; i <= top_L; ++ i, ++ j) 2178 for( i = top_L - n + 1, j = 1; i <= top_L; ++ i, ++ j)
2131 { 2179 {
2132 if( GVerboseErrors) 2180 if( U->verboseErrors)
2133 { 2181 {
2134 sprintf( tmpBuf, "arg_%d", j); 2182 sprintf( tmpBuf, "arg_%d", j);
2135 } 2183 }
2136 copyok = inter_copy_one_( L2, top_L2 + 1, L, i, VT_NORMAL, mode_, pBuf); 2184 copyok = inter_copy_one_( U, L2, top_L2 + 1, L, i, VT_NORMAL, mode_, pBuf);
2137 if( !copyok) 2185 if( !copyok)
2138 { 2186 {
2139 break; 2187 break;
@@ -2161,17 +2209,17 @@ int luaG_inter_copy( lua_State* L, lua_State* L2, uint_t n, enum eLookupMode mod
2161} 2209}
2162 2210
2163 2211
2164int luaG_inter_move( lua_State* L, lua_State* L2, uint_t n, enum eLookupMode mode_) 2212int luaG_inter_move( struct s_Universe* U, lua_State* L, lua_State* L2, uint_t n, enum eLookupMode mode_)
2165{ 2213{
2166 int ret = luaG_inter_copy( L, L2, n, mode_); 2214 int ret = luaG_inter_copy( U, L, L2, n, mode_);
2167 lua_pop( L, (int) n); 2215 lua_pop( L, (int) n);
2168 return ret; 2216 return ret;
2169} 2217}
2170 2218
2171int luaG_inter_copy_package( lua_State* L, lua_State* L2, int package_idx_, enum eLookupMode mode_) 2219int luaG_inter_copy_package( struct s_Universe* U, lua_State* L, lua_State* L2, int package_idx_, enum eLookupMode mode_)
2172{ 2220{
2173 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END)); 2221 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END));
2174 DEBUGSPEW_CODE( ++ debugspew_indent_depth); 2222 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
2175 // package 2223 // package
2176 STACK_CHECK( L); 2224 STACK_CHECK( L);
2177 STACK_CHECK( L2); 2225 STACK_CHECK( L2);
@@ -2202,9 +2250,9 @@ int luaG_inter_copy_package( lua_State* L, lua_State* L2, int package_idx_, enum
2202 } 2250 }
2203 else 2251 else
2204 { 2252 {
2205 DEBUGSPEW_CODE( ++ debugspew_indent_depth); 2253 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
2206 luaG_inter_move( L, L2, 1, mode_); // moves the entry to L2 2254 luaG_inter_move( U, L, L2, 1, mode_); // moves the entry to L2
2207 DEBUGSPEW_CODE( -- debugspew_indent_depth); 2255 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
2208 lua_setfield( L2, -2, entries[i]); // set package[entries[i]] 2256 lua_setfield( L2, -2, entries[i]); // set package[entries[i]]
2209 } 2257 }
2210 } 2258 }
@@ -2216,7 +2264,7 @@ int luaG_inter_copy_package( lua_State* L, lua_State* L2, int package_idx_, enum
2216 lua_pop( L2, 1); 2264 lua_pop( L2, 1);
2217 STACK_END( L2, 0); 2265 STACK_END( L2, 0);
2218 STACK_END( L, 0); 2266 STACK_END( L, 0);
2219 DEBUGSPEW_CODE( -- debugspew_indent_depth); 2267 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
2220 return 0; 2268 return 0;
2221} 2269}
2222 2270
@@ -2224,8 +2272,6 @@ int luaG_inter_copy_package( lua_State* L, lua_State* L2, int package_idx_, enum
2224/*---=== Serialize require ===--- 2272/*---=== Serialize require ===---
2225*/ 2273*/
2226 2274
2227MUTEX_T require_cs;
2228
2229//--- 2275//---
2230// [val]= new_require( ... ) 2276// [val]= new_require( ... )
2231// 2277//
@@ -2237,12 +2283,13 @@ int luaG_new_require( lua_State* L)
2237{ 2283{
2238 int rc, i; 2284 int rc, i;
2239 int args = lua_gettop( L); 2285 int args = lua_gettop( L);
2286 struct s_Universe* U = get_universe( L);
2240 //char const* modname = luaL_checkstring( L, 1); 2287 //char const* modname = luaL_checkstring( L, 1);
2241 2288
2242 STACK_GROW( L, args + 1); 2289 STACK_GROW( L, args + 1);
2243 STACK_CHECK( L); 2290 STACK_CHECK( L);
2244 2291
2245 lua_pushvalue( L, lua_upvalueindex(1)); 2292 lua_pushvalue( L, lua_upvalueindex( 1));
2246 for( i = 1; i <= args; ++ i) 2293 for( i = 1; i <= args; ++ i)
2247 { 2294 {
2248 lua_pushvalue( L, i); 2295 lua_pushvalue( L, i);
@@ -2251,9 +2298,9 @@ int luaG_new_require( lua_State* L)
2251 // Using 'lua_pcall()' to catch errors; otherwise a failing 'require' would 2298 // Using 'lua_pcall()' to catch errors; otherwise a failing 'require' would
2252 // leave us locked, blocking any future 'require' calls from other lanes. 2299 // leave us locked, blocking any future 'require' calls from other lanes.
2253 // 2300 //
2254 MUTEX_LOCK( &require_cs); 2301 MUTEX_LOCK( &U->require_cs);
2255 rc = lua_pcall( L, args, 1 /*retvals*/, 0 /*errfunc*/ ); 2302 rc = lua_pcall( L, args, 1 /*retvals*/, 0 /*errfunc*/ );
2256 MUTEX_UNLOCK( &require_cs); 2303 MUTEX_UNLOCK( &U->require_cs);
2257 2304
2258 // the required module (or an error message) is left on the stack as returned value by original require function 2305 // the required module (or an error message) is left on the stack as returned value by original require function
2259 STACK_END( L, 1); 2306 STACK_END( L, 1);