aboutsummaryrefslogtreecommitdiff
path: root/src/state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/state.c')
-rw-r--r--src/state.c554
1 files changed, 277 insertions, 277 deletions
diff --git a/src/state.c b/src/state.c
index 81371b7..9075c02 100644
--- a/src/state.c
+++ b/src/state.c
@@ -59,32 +59,32 @@ THE SOFTWARE.
59// 59//
60static int luaG_new_require( lua_State* L) 60static int luaG_new_require( lua_State* L)
61{ 61{
62 int rc; 62 int rc;
63 int const args = lua_gettop( L); // args 63 int const args = lua_gettop( L); // args
64 Universe* U = universe_get( L); 64 Universe* U = universe_get( L);
65 //char const* modname = luaL_checkstring( L, 1); 65 //char const* modname = luaL_checkstring( L, 1);
66 66
67 STACK_GROW( L, 1); 67 STACK_GROW( L, 1);
68 68
69 lua_pushvalue( L, lua_upvalueindex( 1)); // args require 69 lua_pushvalue( L, lua_upvalueindex( 1)); // args require
70 lua_insert( L, 1); // require args 70 lua_insert( L, 1); // require args
71 71
72 // Using 'lua_pcall()' to catch errors; otherwise a failing 'require' would 72 // Using 'lua_pcall()' to catch errors; otherwise a failing 'require' would
73 // leave us locked, blocking any future 'require' calls from other lanes. 73 // leave us locked, blocking any future 'require' calls from other lanes.
74 74
75 MUTEX_LOCK( &U->require_cs); 75 MUTEX_LOCK( &U->require_cs);
76 // starting with Lua 5.4, require may return a second optional value, so we need LUA_MULTRET 76 // starting with Lua 5.4, require may return a second optional value, so we need LUA_MULTRET
77 rc = lua_pcall( L, args, LUA_MULTRET, 0 /*errfunc*/ ); // err|result(s) 77 rc = lua_pcall( L, args, LUA_MULTRET, 0 /*errfunc*/ ); // err|result(s)
78 MUTEX_UNLOCK( &U->require_cs); 78 MUTEX_UNLOCK( &U->require_cs);
79 79
80 // the required module (or an error message) is left on the stack as returned value by original require function 80 // the required module (or an error message) is left on the stack as returned value by original require function
81 81
82 if( rc != LUA_OK) // LUA_ERRRUN / LUA_ERRMEM ? 82 if( rc != LUA_OK) // LUA_ERRRUN / LUA_ERRMEM ?
83 { 83 {
84 return lua_error( L); 84 return lua_error( L);
85 } 85 }
86 // should be 1 for Lua <= 5.3, 1 or 2 starting with Lua 5.4 86 // should be 1 for Lua <= 5.3, 1 or 2 starting with Lua 5.4
87 return lua_gettop(L); // result(s) 87 return lua_gettop(L); // result(s)
88} 88}
89 89
90/* 90/*
@@ -92,26 +92,26 @@ static int luaG_new_require( lua_State* L)
92*/ 92*/
93void serialize_require( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L) 93void serialize_require( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L)
94{ 94{
95 STACK_GROW( L, 1); 95 STACK_GROW( L, 1);
96 STACK_CHECK( L, 0); 96 STACK_CHECK( L, 0);
97 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "serializing require()\n" INDENT_END)); 97 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "serializing require()\n" INDENT_END));
98 98
99 // Check 'require' is there and not already wrapped; if not, do nothing 99 // Check 'require' is there and not already wrapped; if not, do nothing
100 // 100 //
101 lua_getglobal( L, "require"); 101 lua_getglobal( L, "require");
102 if( lua_isfunction( L, -1) && lua_tocfunction( L, -1) != luaG_new_require) 102 if( lua_isfunction( L, -1) && lua_tocfunction( L, -1) != luaG_new_require)
103 { 103 {
104 // [-1]: original 'require' function 104 // [-1]: original 'require' function
105 lua_pushcclosure( L, luaG_new_require, 1 /*upvalues*/); 105 lua_pushcclosure( L, luaG_new_require, 1 /*upvalues*/);
106 lua_setglobal( L, "require"); 106 lua_setglobal( L, "require");
107 } 107 }
108 else 108 else
109 { 109 {
110 // [-1]: nil 110 // [-1]: nil
111 lua_pop( L, 1); 111 lua_pop( L, 1);
112 } 112 }
113 113
114 STACK_END( L, 0); 114 STACK_END( L, 0);
115} 115}
116 116
117// ################################################################################################ 117// ################################################################################################
@@ -120,15 +120,15 @@ void serialize_require( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L)
120 120
121static int require_lanes_core( lua_State* L) 121static int require_lanes_core( lua_State* L)
122{ 122{
123 // leaves a copy of 'lanes.core' module table on the stack 123 // leaves a copy of 'lanes.core' module table on the stack
124 luaL_requiref( L, "lanes.core", luaopen_lanes_core, 0); 124 luaL_requiref( L, "lanes.core", luaopen_lanes_core, 0);
125 return 1; 125 return 1;
126} 126}
127 127
128 128
129static const luaL_Reg libs[] = 129static const luaL_Reg libs[] =
130{ 130{
131 { LUA_LOADLIBNAME, luaopen_package}, 131 { LUA_LOADLIBNAME, luaopen_package},
132{ LUA_TABLIBNAME, luaopen_table}, 132{ LUA_TABLIBNAME, luaopen_table},
133{ LUA_STRLIBNAME, luaopen_string}, 133{ LUA_STRLIBNAME, luaopen_string},
134{ LUA_MATHLIBNAME, luaopen_math}, 134{ LUA_MATHLIBNAME, luaopen_math},
@@ -157,152 +157,152 @@ static const luaL_Reg libs[] =
157 157
158{ LUA_DBLIBNAME, luaopen_debug}, 158{ LUA_DBLIBNAME, luaopen_debug},
159{ "lanes.core", require_lanes_core}, // So that we can open it like any base library (possible since we have access to the init function) 159{ "lanes.core", require_lanes_core}, // So that we can open it like any base library (possible since we have access to the init function)
160 // 160 //
161{ "base", NULL}, // ignore "base" (already acquired it) 161{ "base", NULL}, // ignore "base" (already acquired it)
162{ NULL, NULL } 162{ NULL, NULL }
163}; 163};
164 164
165static void open1lib( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L, char const* name_, size_t len_) 165static void open1lib( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L, char const* name_, size_t len_)
166{ 166{
167 int i; 167 int i;
168 for( i = 0; libs[i].name; ++ i) 168 for( i = 0; libs[i].name; ++ i)
169 { 169 {
170 if( strncmp( name_, libs[i].name, len_) == 0) 170 if( strncmp( name_, libs[i].name, len_) == 0)
171 { 171 {
172 lua_CFunction libfunc = libs[i].func; 172 lua_CFunction libfunc = libs[i].func;
173 name_ = libs[i].name; // note that the provided name_ doesn't necessarily ends with '\0', hence len_ 173 name_ = libs[i].name; // note that the provided name_ doesn't necessarily ends with '\0', hence len_
174 if( libfunc != NULL) 174 if( libfunc != NULL)
175 { 175 {
176 bool_t const isLanesCore = (libfunc == require_lanes_core) ? TRUE : FALSE; // don't want to create a global for "lanes.core" 176 bool_t const isLanesCore = (libfunc == require_lanes_core) ? TRUE : FALSE; // don't want to create a global for "lanes.core"
177 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, (int) len_, name_)); 177 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, (int) len_, name_));
178 STACK_CHECK( L, 0); 178 STACK_CHECK( L, 0);
179 // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack) 179 // open the library as if through require(), and create a global as well if necessary (the library table is left on the stack)
180 luaL_requiref( L, name_, libfunc, !isLanesCore); 180 luaL_requiref( L, name_, libfunc, !isLanesCore);
181 // lanes.core doesn't declare a global, so scan it here and now 181 // lanes.core doesn't declare a global, so scan it here and now
182 if( isLanesCore == TRUE) 182 if( isLanesCore == TRUE)
183 { 183 {
184 populate_func_lookup_table( L, -1, name_); 184 populate_func_lookup_table( L, -1, name_);
185 } 185 }
186 lua_pop( L, 1); 186 lua_pop( L, 1);
187 STACK_END( L, 0); 187 STACK_END( L, 0);
188 } 188 }
189 break; 189 break;
190 } 190 }
191 } 191 }
192} 192}
193 193
194 194
195// just like lua_xmove, args are (from, to) 195// just like lua_xmove, args are (from, to)
196static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2) 196static void copy_one_time_settings( Universe* U, lua_State* L, lua_State* L2)
197{ 197{
198 STACK_GROW( L, 2); 198 STACK_GROW( L, 2);
199 STACK_CHECK( L, 0); 199 STACK_CHECK( L, 0);
200 STACK_CHECK( L2, 0); 200 STACK_CHECK( L2, 0);
201 201
202 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "copy_one_time_settings()\n" INDENT_END)); 202 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "copy_one_time_settings()\n" INDENT_END));
203 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 203 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
204 204
205 REGISTRY_GET( L, CONFIG_REGKEY); // config 205 REGISTRY_GET( L, CONFIG_REGKEY); // config
206 // copy settings from from source to destination registry 206 // copy settings from from source to destination registry
207 if( luaG_inter_move( U, L, L2, 1, eLM_LaneBody) < 0) // // config 207 if( luaG_inter_move( U, L, L2, 1, eLM_LaneBody) < 0) // // config
208 { 208 {
209 (void) luaL_error( L, "failed to copy settings when loading lanes.core"); 209 (void) luaL_error( L, "failed to copy settings when loading lanes.core");
210 } 210 }
211 // set L2:_R[CONFIG_REGKEY] = settings 211 // set L2:_R[CONFIG_REGKEY] = settings
212 REGISTRY_SET( L2, CONFIG_REGKEY, lua_insert( L2, -2)); // 212 REGISTRY_SET( L2, CONFIG_REGKEY, lua_insert( L2, -2)); //
213 STACK_END( L2, 0); 213 STACK_END( L2, 0);
214 STACK_END( L, 0); 214 STACK_END( L, 0);
215 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 215 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
216} 216}
217 217
218void initialize_on_state_create( Universe* U, lua_State* L) 218void initialize_on_state_create( Universe* U, lua_State* L)
219{ 219{
220 STACK_CHECK( L, 0); 220 STACK_CHECK( L, 0);
221 lua_getfield( L, -1, "on_state_create"); // settings on_state_create|nil 221 lua_getfield( L, -1, "on_state_create"); // settings on_state_create|nil
222 if( !lua_isnil( L, -1)) 222 if( !lua_isnil( L, -1))
223 { 223 {
224 // store C function pointer in an internal variable 224 // store C function pointer in an internal variable
225 U->on_state_create_func = lua_tocfunction( L, -1); // settings on_state_create 225 U->on_state_create_func = lua_tocfunction( L, -1); // settings on_state_create
226 if( U->on_state_create_func != NULL) 226 if( U->on_state_create_func != NULL)
227 { 227 {
228 // make sure the function doesn't have upvalues 228 // make sure the function doesn't have upvalues
229 char const* upname = lua_getupvalue( L, -1, 1); // settings on_state_create upval? 229 char const* upname = lua_getupvalue( L, -1, 1); // settings on_state_create upval?
230 if( upname != NULL) // should be "" for C functions with upvalues if any 230 if( upname != NULL) // should be "" for C functions with upvalues if any
231 { 231 {
232 (void) luaL_error( L, "on_state_create shouldn't have upvalues"); 232 (void) luaL_error( L, "on_state_create shouldn't have upvalues");
233 } 233 }
234 // remove this C function from the config table so that it doesn't cause problems 234 // remove this C function from the config table so that it doesn't cause problems
235 // when we transfer the config table in newly created Lua states 235 // when we transfer the config table in newly created Lua states
236 lua_pushnil( L); // settings on_state_create nil 236 lua_pushnil( L); // settings on_state_create nil
237 lua_setfield( L, -3, "on_state_create"); // settings on_state_create 237 lua_setfield( L, -3, "on_state_create"); // settings on_state_create
238 } 238 }
239 else 239 else
240 { 240 {
241 // optim: store marker saying we have such a function in the config table 241 // optim: store marker saying we have such a function in the config table
242 U->on_state_create_func = (lua_CFunction) initialize_on_state_create; 242 U->on_state_create_func = (lua_CFunction) initialize_on_state_create;
243 } 243 }
244 } 244 }
245 lua_pop( L, 1); // settings 245 lua_pop( L, 1); // settings
246 STACK_END( L, 0); 246 STACK_END( L, 0);
247} 247}
248 248
249lua_State* create_state( Universe* U, lua_State* from_) 249lua_State* create_state( Universe* U, lua_State* from_)
250{ 250{
251 lua_State* L; 251 lua_State* L;
252 if( U->provide_allocator != NULL) 252 if( U->provide_allocator != NULL)
253 { 253 {
254 lua_pushcclosure( from_, U->provide_allocator, 0); 254 lua_pushcclosure( from_, U->provide_allocator, 0);
255 lua_call( from_, 0, 1); 255 lua_call( from_, 0, 1);
256 { 256 {
257 AllocatorDefinition* def = lua_touserdata( from_, -1); 257 AllocatorDefinition* def = lua_touserdata( from_, -1);
258 L = lua_newstate( def->allocF, def->allocUD); 258 L = lua_newstate( def->allocF, def->allocUD);
259 } 259 }
260 lua_pop( from_, 1); 260 lua_pop( from_, 1);
261 } 261 }
262 else 262 else
263 { 263 {
264 L = luaL_newstate(); 264 L = luaL_newstate();
265 } 265 }
266 266
267 if( L == NULL) 267 if( L == NULL)
268 { 268 {
269 (void) luaL_error( from_, "luaG_newstate() failed while creating state; out of memory"); 269 (void) luaL_error( from_, "luaG_newstate() failed while creating state; out of memory");
270 } 270 }
271 return L; 271 return L;
272} 272}
273 273
274void call_on_state_create( Universe* U, lua_State* L, lua_State* from_, LookupMode mode_) 274void call_on_state_create( Universe* U, lua_State* L, lua_State* from_, LookupMode mode_)
275{ 275{
276 if( U->on_state_create_func != NULL) 276 if( U->on_state_create_func != NULL)
277 { 277 {
278 STACK_CHECK( L, 0); 278 STACK_CHECK( L, 0);
279 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); 279 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END));
280 if( U->on_state_create_func != (lua_CFunction) initialize_on_state_create) 280 if( U->on_state_create_func != (lua_CFunction) initialize_on_state_create)
281 { 281 {
282 // C function: recreate a closure in the new state, bypassing the lookup scheme 282 // C function: recreate a closure in the new state, bypassing the lookup scheme
283 lua_pushcfunction( L, U->on_state_create_func); // on_state_create() 283 lua_pushcfunction( L, U->on_state_create_func); // on_state_create()
284 } 284 }
285 else // Lua function located in the config table, copied when we opened "lanes.core" 285 else // Lua function located in the config table, copied when we opened "lanes.core"
286 { 286 {
287 if( mode_ != eLM_LaneBody) 287 if( mode_ != eLM_LaneBody)
288 { 288 {
289 // if attempting to call in a keeper state, do nothing because the function doesn't exist there 289 // if attempting to call in a keeper state, do nothing because the function doesn't exist there
290 // this doesn't count as an error though 290 // this doesn't count as an error though
291 return; 291 return;
292 } 292 }
293 REGISTRY_GET( L, CONFIG_REGKEY); // {} 293 REGISTRY_GET( L, CONFIG_REGKEY); // {}
294 STACK_MID( L, 1); 294 STACK_MID( L, 1);
295 lua_getfield( L, -1, "on_state_create"); // {} on_state_create() 295 lua_getfield( L, -1, "on_state_create"); // {} on_state_create()
296 lua_remove( L, -2); // on_state_create() 296 lua_remove( L, -2); // on_state_create()
297 } 297 }
298 STACK_MID( L, 1); 298 STACK_MID( L, 1);
299 // capture error and raise it in caller state 299 // capture error and raise it in caller state
300 if( lua_pcall( L, 0, 0, 0) != LUA_OK) 300 if( lua_pcall( L, 0, 0, 0) != LUA_OK)
301 { 301 {
302 luaL_error( from_, "on_state_create failed: \"%s\"", lua_isstring( L, -1) ? lua_tostring( L, -1) : lua_typename( L, lua_type( L, -1))); 302 luaL_error( from_, "on_state_create failed: \"%s\"", lua_isstring( L, -1) ? lua_tostring( L, -1) : lua_typename( L, lua_type( L, -1)));
303 } 303 }
304 STACK_END( L, 0); 304 STACK_END( L, 0);
305 } 305 }
306} 306}
307 307
308/* 308/*
@@ -320,116 +320,116 @@ void call_on_state_create( Universe* U, lua_State* L, lua_State* from_, LookupMo
320*/ 320*/
321lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_) 321lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_)
322{ 322{
323 lua_State* L = create_state( U, from_); 323 lua_State* L = create_state( U, from_);
324 324
325 STACK_GROW( L, 2); 325 STACK_GROW( L, 2);
326 STACK_CHECK_ABS( L, 0); 326 STACK_CHECK_ABS( L, 0);
327 327
328 // copy the universe as a light userdata (only the master state holds the full userdata) 328 // copy the universe as a light userdata (only the master state holds the full userdata)
329 // that way, if Lanes is required in this new state, we'll know we are part of this universe 329 // that way, if Lanes is required in this new state, we'll know we are part of this universe
330 universe_store( L, U); 330 universe_store( L, U);
331 STACK_MID( L, 0); 331 STACK_MID( L, 0);
332 332
333 // we'll need this every time we transfer some C function from/to this state 333 // we'll need this every time we transfer some C function from/to this state
334 REGISTRY_SET( L, LOOKUP_REGKEY, lua_newtable( L)); 334 REGISTRY_SET( L, LOOKUP_REGKEY, lua_newtable( L));
335 STACK_MID( L, 0); 335 STACK_MID( L, 0);
336 336
337 // neither libs (not even 'base') nor special init func: we are done 337 // neither libs (not even 'base') nor special init func: we are done
338 if( libs_ == NULL && U->on_state_create_func == NULL) 338 if( libs_ == NULL && U->on_state_create_func == NULL)
339 { 339 {
340 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate(NULL)\n" INDENT_END)); 340 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate(NULL)\n" INDENT_END));
341 return L; 341 return L;
342 } 342 }
343 343
344 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate()\n" INDENT_END)); 344 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate()\n" INDENT_END));
345 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 345 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
346 346
347 // copy settings (for example because it may contain a Lua on_state_create function) 347 // copy settings (for example because it may contain a Lua on_state_create function)
348 copy_one_time_settings( U, from_, L); 348 copy_one_time_settings( U, from_, L);
349 349
350 // 'lua.c' stops GC during initialization so perhaps its a good idea. :) 350 // 'lua.c' stops GC during initialization so perhaps its a good idea. :)
351 lua_gc( L, LUA_GCSTOP, 0); 351 lua_gc( L, LUA_GCSTOP, 0);
352 352
353 353
354 // Anything causes 'base' to be taken in 354 // Anything causes 'base' to be taken in
355 // 355 //
356 if( libs_ != NULL) 356 if( libs_ != NULL)
357 { 357 {
358 // special "*" case (mainly to help with LuaJIT compatibility) 358 // special "*" case (mainly to help with LuaJIT compatibility)
359 // as we are called from luaopen_lanes_core() already, and that would deadlock 359 // as we are called from luaopen_lanes_core() already, and that would deadlock
360 if( libs_[0] == '*' && libs_[1] == 0) 360 if( libs_[0] == '*' && libs_[1] == 0)
361 { 361 {
362 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END)); 362 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END));
363 luaL_openlibs( L); 363 luaL_openlibs( L);
364 // don't forget lanes.core for regular lane states 364 // don't forget lanes.core for regular lane states
365 open1lib( DEBUGSPEW_PARAM_COMMA( U) L, "lanes.core", 10); 365 open1lib( DEBUGSPEW_PARAM_COMMA( U) L, "lanes.core", 10);
366 libs_ = NULL; // done with libs 366 libs_ = NULL; // done with libs
367 } 367 }
368 else 368 else
369 { 369 {
370 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening base library\n" INDENT_END)); 370 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening base library\n" INDENT_END));
371#if LUA_VERSION_NUM >= 502 371#if LUA_VERSION_NUM >= 502
372 // open base library the same way as in luaL_openlibs() 372 // open base library the same way as in luaL_openlibs()
373 luaL_requiref( L, "_G", luaopen_base, 1); 373 luaL_requiref( L, "_G", luaopen_base, 1);
374 lua_pop( L, 1); 374 lua_pop( L, 1);
375#else // LUA_VERSION_NUM 375#else // LUA_VERSION_NUM
376 lua_pushcfunction( L, luaopen_base); 376 lua_pushcfunction( L, luaopen_base);
377 lua_pushstring( L, ""); 377 lua_pushstring( L, "");
378 lua_call( L, 1, 0); 378 lua_call( L, 1, 0);
379#endif // LUA_VERSION_NUM 379#endif // LUA_VERSION_NUM
380 } 380 }
381 } 381 }
382 STACK_END( L, 0); 382 STACK_END( L, 0);
383 383
384 // scan all libraries, open them one by one 384 // scan all libraries, open them one by one
385 if( libs_) 385 if( libs_)
386 { 386 {
387 char const* p; 387 char const* p;
388 unsigned int len = 0; 388 unsigned int len = 0;
389 for( p = libs_; *p; p += len) 389 for( p = libs_; *p; p += len)
390 { 390 {
391 // skip delimiters ('.' can be part of name for "lanes.core") 391 // skip delimiters ('.' can be part of name for "lanes.core")
392 while( *p && !isalnum( *p) && *p != '.') 392 while( *p && !isalnum( *p) && *p != '.')
393 ++ p; 393 ++ p;
394 // skip name 394 // skip name
395 len = 0; 395 len = 0;
396 while( isalnum( p[len]) || p[len] == '.') 396 while( isalnum( p[len]) || p[len] == '.')
397 ++ len; 397 ++ len;
398 // open library 398 // open library
399 open1lib( DEBUGSPEW_PARAM_COMMA( U) L, p, len); 399 open1lib( DEBUGSPEW_PARAM_COMMA( U) L, p, len);
400 } 400 }
401 } 401 }
402 lua_gc( L, LUA_GCRESTART, 0); 402 lua_gc( L, LUA_GCRESTART, 0);
403 403
404 serialize_require( DEBUGSPEW_PARAM_COMMA( U) L); 404 serialize_require( DEBUGSPEW_PARAM_COMMA( U) L);
405 405
406 // call this after the base libraries are loaded and GC is restarted 406 // call this after the base libraries are loaded and GC is restarted
407 // will raise an error in from_ in case of problem 407 // will raise an error in from_ in case of problem
408 call_on_state_create( U, L, from_, eLM_LaneBody); 408 call_on_state_create( U, L, from_, eLM_LaneBody);
409 409
410 STACK_CHECK( L, 0); 410 STACK_CHECK( L, 0);
411 // after all this, register everything we find in our name<->function database 411 // after all this, register everything we find in our name<->function database
412 lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack 412 lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack
413 populate_func_lookup_table( L, -1, NULL); 413 populate_func_lookup_table( L, -1, NULL);
414 414
415#if 0 && USE_DEBUG_SPEW 415#if 0 && USE_DEBUG_SPEW
416 // dump the lookup database contents 416 // dump the lookup database contents
417 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {} 417 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {}
418 lua_pushnil( L); // {} nil 418 lua_pushnil( L); // {} nil
419 while( lua_next( L, -2)) // {} k v 419 while( lua_next( L, -2)) // {} k v
420 { 420 {
421 lua_getglobal( L, "print"); // {} k v print 421 lua_getglobal( L, "print"); // {} k v print
422 lua_pushlstring( L, debugspew_indent, U->debugspew_indent_depth); // {} k v print " " 422 lua_pushlstring( L, debugspew_indent, U->debugspew_indent_depth); // {} k v print " "
423 lua_pushvalue( L, -4); // {} k v print " " k 423 lua_pushvalue( L, -4); // {} k v print " " k
424 lua_pushvalue( L, -4); // {} k v print " " k v 424 lua_pushvalue( L, -4); // {} k v print " " k v
425 lua_call( L, 3, 0); // {} k v 425 lua_call( L, 3, 0); // {} k v
426 lua_pop( L, 1); // {} k 426 lua_pop( L, 1); // {} k
427 } 427 }
428 lua_pop( L, 1); // {} 428 lua_pop( L, 1); // {}
429#endif // USE_DEBUG_SPEW 429#endif // USE_DEBUG_SPEW
430 430
431 lua_pop( L, 1); 431 lua_pop( L, 1);
432 STACK_END( L, 0); 432 STACK_END( L, 0);
433 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 433 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
434 return L; 434 return L;
435} 435}