diff options
Diffstat (limited to 'src/tools.c')
-rw-r--r-- | src/tools.c | 577 |
1 files changed, 323 insertions, 254 deletions
diff --git a/src/tools.c b/src/tools.c index ade8cb8..552e61e 100644 --- a/src/tools.c +++ b/src/tools.c | |||
@@ -43,6 +43,8 @@ THE SOFTWARE. | |||
43 | #include <stdlib.h> | 43 | #include <stdlib.h> |
44 | 44 | ||
45 | DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); | 45 | DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); |
46 | DEBUGSPEW_CODE( int debugspew_indent_depth = 0); | ||
47 | |||
46 | 48 | ||
47 | MUTEX_T deep_lock; | 49 | MUTEX_T deep_lock; |
48 | MUTEX_T mtid_lock; | 50 | MUTEX_T mtid_lock; |
@@ -69,7 +71,7 @@ void luaG_dump( lua_State* L ) { | |||
69 | // Note: this requires 'tostring()' to be defined. If it is NOT, | 71 | // Note: this requires 'tostring()' to be defined. If it is NOT, |
70 | // enable it for more debugging. | 72 | // enable it for more debugging. |
71 | // | 73 | // |
72 | STACK_CHECK(L) | 74 | STACK_CHECK( L); |
73 | STACK_GROW( L, 2); | 75 | STACK_GROW( L, 2); |
74 | 76 | ||
75 | lua_getglobal( L, "tostring" ); | 77 | lua_getglobal( L, "tostring" ); |
@@ -87,7 +89,7 @@ void luaG_dump( lua_State* L ) { | |||
87 | fprintf( stderr, "%s", lua_tostring(L,-1) ); | 89 | fprintf( stderr, "%s", lua_tostring(L,-1) ); |
88 | } | 90 | } |
89 | lua_pop(L,1); | 91 | lua_pop(L,1); |
90 | STACK_END(L,0) | 92 | STACK_END( L, 0); |
91 | fprintf( stderr, "\n" ); | 93 | fprintf( stderr, "\n" ); |
92 | } | 94 | } |
93 | fprintf( stderr, "\n" ); | 95 | fprintf( stderr, "\n" ); |
@@ -125,8 +127,8 @@ static void open1lib( lua_State* L, char const* name, size_t len) | |||
125 | { | 127 | { |
126 | if( libs[i].func) | 128 | if( libs[i].func) |
127 | { | 129 | { |
128 | DEBUGSPEW_CODE( fprintf( stderr, "opening %.*s library\n", len, name)); | 130 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening %.*s library\n" INDENT_END, len, name)); |
129 | STACK_CHECK( L) | 131 | STACK_CHECK( L); |
130 | #if LUA_VERSION_NUM >= 502 | 132 | #if LUA_VERSION_NUM >= 502 |
131 | // open the library as if through require(), and create a global as well (the library table is left on the stack) | 133 | // open the library as if through require(), and create a global as well (the library table is left on the stack) |
132 | luaL_requiref( L, libs[i].name, libs[i].func, 1); | 134 | luaL_requiref( L, libs[i].name, libs[i].func, 1); |
@@ -137,7 +139,7 @@ static void open1lib( lua_State* L, char const* name, size_t len) | |||
137 | // pushes the module table on the stack | 139 | // pushes the module table on the stack |
138 | lua_call( L, 0, 0); | 140 | lua_call( L, 0, 0); |
139 | #endif // LUA_VERSION_NUM | 141 | #endif // LUA_VERSION_NUM |
140 | STACK_END( L, 0) | 142 | STACK_END( L, 0); |
141 | } | 143 | } |
142 | break; | 144 | break; |
143 | } | 145 | } |
@@ -216,7 +218,7 @@ static char const* luaG_pushFQN(lua_State *L, int t, int last) | |||
216 | { | 218 | { |
217 | int i = 1; | 219 | int i = 1; |
218 | luaL_Buffer b; | 220 | luaL_Buffer b; |
219 | STACK_CHECK( L) | 221 | STACK_CHECK( L); |
220 | luaL_buffinit(L, &b); | 222 | luaL_buffinit(L, &b); |
221 | for( ; i < last; ++ i) | 223 | for( ; i < last; ++ i) |
222 | { | 224 | { |
@@ -230,7 +232,7 @@ static char const* luaG_pushFQN(lua_State *L, int t, int last) | |||
230 | luaL_addvalue( &b); | 232 | luaL_addvalue( &b); |
231 | } | 233 | } |
232 | luaL_pushresult( &b); | 234 | luaL_pushresult( &b); |
233 | STACK_END( L, 1) | 235 | STACK_END( L, 1); |
234 | return lua_tostring( L, -1); | 236 | return lua_tostring( L, -1); |
235 | } | 237 | } |
236 | 238 | ||
@@ -249,14 +251,14 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _ | |||
249 | 251 | ||
250 | STACK_GROW( L, 6); | 252 | STACK_GROW( L, 6); |
251 | // slot _i contains a table where we search for functions | 253 | // slot _i contains a table where we search for functions |
252 | STACK_CHECK( L) // ... {_i} | 254 | STACK_CHECK( L); // ... {_i} |
253 | 255 | ||
254 | // if table is already visited, we are done | 256 | // if table is already visited, we are done |
255 | lua_pushvalue( L, _i); // ... {_i} {} | 257 | lua_pushvalue( L, _i); // ... {_i} {} |
256 | lua_rawget( L, cache); // ... {_i} nil|n | 258 | lua_rawget( L, cache); // ... {_i} nil|n |
257 | visit_count = lua_tointeger( L, -1); // 0 if nil, else n | 259 | visit_count = lua_tointeger( L, -1); // 0 if nil, else n |
258 | lua_pop( L, 1); // ... {_i} | 260 | lua_pop( L, 1); // ... {_i} |
259 | STACK_MID( L, 0) | 261 | STACK_MID( L, 0); |
260 | if( visit_count > 0) | 262 | if( visit_count > 0) |
261 | { | 263 | { |
262 | return; | 264 | return; |
@@ -266,7 +268,7 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _ | |||
266 | lua_pushvalue( L, _i); // ... {_i} {} | 268 | lua_pushvalue( L, _i); // ... {_i} {} |
267 | lua_pushinteger( L, visit_count + 1); // ... {_i} {} 1 | 269 | lua_pushinteger( L, visit_count + 1); // ... {_i} {} 1 |
268 | lua_rawset( L, cache); // ... {_i} | 270 | lua_rawset( L, cache); // ... {_i} |
269 | STACK_MID( L, 0) | 271 | STACK_MID( L, 0); |
270 | 272 | ||
271 | // this table is at breadth_first_cache index | 273 | // this table is at breadth_first_cache index |
272 | lua_newtable( L); // ... {_i} {bfc} | 274 | lua_newtable( L); // ... {_i} {bfc} |
@@ -276,7 +278,7 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _ | |||
276 | while( lua_next( L, _i) != 0) // ... {_i} {bfc} k v | 278 | while( lua_next( L, _i) != 0) // ... {_i} {bfc} k v |
277 | { | 279 | { |
278 | // just for debug, not actually needed | 280 | // just for debug, not actually needed |
279 | //char const * key = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : "not a string"; | 281 | //char const* key = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : "not a string"; |
280 | // subtable: process it recursively | 282 | // subtable: process it recursively |
281 | if( lua_istable( L, -1)) // ... {_i} {bfc} k {} | 283 | if( lua_istable( L, -1)) // ... {_i} {bfc} k {} |
282 | { | 284 | { |
@@ -332,20 +334,23 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _ | |||
332 | // remove table name from fqn stack | 334 | // remove table name from fqn stack |
333 | lua_pushnil( L); // ... {_i} {bfc} k nil | 335 | lua_pushnil( L); // ... {_i} {bfc} k nil |
334 | lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k | 336 | lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k |
335 | DEBUGSPEW_CODE( fprintf( stderr, "%.*spopulating: %s\n", _i, debugspew_indent, newName)); | 337 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function '%s'\n" INDENT_END, newName)); |
336 | -- _depth; | 338 | -- _depth; |
337 | } | 339 | } |
338 | else | 340 | else |
339 | { | 341 | { |
340 | lua_pop( L, 1); // ... {_i} {bfc} k | 342 | lua_pop( L, 1); // ... {_i} {bfc} k |
341 | } | 343 | } |
342 | STACK_MID( L, 2) | 344 | STACK_MID( L, 2); |
343 | } | 345 | } |
344 | // now process the tables we encountered at that depth | 346 | // now process the tables we encountered at that depth |
345 | ++ _depth; | 347 | ++ _depth; |
346 | lua_pushnil( L); // ... {_i} {bfc} nil | 348 | lua_pushnil( L); // ... {_i} {bfc} nil |
347 | while( lua_next( L, breadth_first_cache) != 0) // ... {_i} {bfc} k {} | 349 | while( lua_next( L, breadth_first_cache) != 0) // ... {_i} {bfc} k {} |
348 | { | 350 | { |
351 | DEBUGSPEW_CODE( char const* key = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : "not a string"); | ||
352 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "table '%s'\n" INDENT_END, key)); | ||
353 | DEBUGSPEW_CODE( ++ debugspew_indent_depth); | ||
349 | // un-visit this table in case we do need to process it | 354 | // un-visit this table in case we do need to process it |
350 | lua_pushvalue( L, -1); // ... {_i} {bfc} k {} {} | 355 | lua_pushvalue( L, -1); // ... {_i} {bfc} k {} {} |
351 | lua_rawget( L, cache); // ... {_i} {bfc} k {} n | 356 | lua_rawget( L, cache); // ... {_i} {bfc} k {} n |
@@ -367,7 +372,8 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _ | |||
367 | lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k {} | 372 | lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k {} |
368 | populate_func_lookup_table_recur( L, _ctx_base, lua_gettop( L), _depth); // ... {_i} {bfc} k {} | 373 | populate_func_lookup_table_recur( L, _ctx_base, lua_gettop( L), _depth); // ... {_i} {bfc} k {} |
369 | lua_pop( L, 1); // ... {_i} {bfc} k | 374 | lua_pop( L, 1); // ... {_i} {bfc} k |
370 | STACK_MID( L, 2) | 375 | STACK_MID( L, 2); |
376 | DEBUGSPEW_CODE( -- debugspew_indent_depth); | ||
371 | } | 377 | } |
372 | // remove table name from fqn stack | 378 | // remove table name from fqn stack |
373 | lua_pushnil( L); // ... {_i} {bfc} nil | 379 | lua_pushnil( L); // ... {_i} {bfc} nil |
@@ -375,7 +381,7 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _ | |||
375 | -- _depth; | 381 | -- _depth; |
376 | // we are done with our cache | 382 | // we are done with our cache |
377 | lua_pop( L, 1); // ... {_i} | 383 | lua_pop( L, 1); // ... {_i} |
378 | STACK_END( L, 0) | 384 | STACK_END( L, 0); |
379 | // we are done // ... {_i} {bfc} | 385 | // we are done // ... {_i} {bfc} |
380 | } | 386 | } |
381 | 387 | ||
@@ -387,9 +393,10 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* _name) | |||
387 | int const ctx_base = lua_gettop( L) + 1; | 393 | int const ctx_base = lua_gettop( L) + 1; |
388 | int const in_base = lua_absindex( L, _i); | 394 | int const in_base = lua_absindex( L, _i); |
389 | int const start_depth = _name ? 1 : 0; | 395 | int const start_depth = _name ? 1 : 0; |
390 | DEBUGSPEW_CODE( fprintf( stderr, "%p: populate_func_lookup_table('%s')\n", L, _name ? _name : "NULL")); | 396 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, _name ? _name : "NULL")); |
397 | DEBUGSPEW_CODE( ++ debugspew_indent_depth); | ||
391 | STACK_GROW( L, 3); | 398 | STACK_GROW( L, 3); |
392 | STACK_CHECK( L) | 399 | STACK_CHECK( L); |
393 | lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY); // {}? | 400 | lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY); // {}? |
394 | if( lua_isnil( L, -1)) // nil | 401 | if( lua_isnil( L, -1)) // nil |
395 | { | 402 | { |
@@ -414,7 +421,8 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* _name) | |||
414 | } | 421 | } |
415 | populate_func_lookup_table_recur( L, ctx_base, in_base, start_depth); // {...} {fqn} {cache} | 422 | populate_func_lookup_table_recur( L, ctx_base, in_base, start_depth); // {...} {fqn} {cache} |
416 | lua_pop( L, 3); | 423 | lua_pop( L, 3); |
417 | STACK_END( L, 0) | 424 | STACK_END( L, 0); |
425 | DEBUGSPEW_CODE( -- debugspew_indent_depth); | ||
418 | } | 426 | } |
419 | 427 | ||
420 | /* | 428 | /* |
@@ -447,11 +455,14 @@ lua_State* luaG_newstate( lua_State* _from, char const* libs, lua_CFunction _on_ | |||
447 | return L; | 455 | return L; |
448 | } | 456 | } |
449 | 457 | ||
458 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate()\n" INDENT_END)); | ||
459 | DEBUGSPEW_CODE( ++ debugspew_indent_depth); | ||
460 | |||
450 | STACK_GROW( L, 2); | 461 | STACK_GROW( L, 2); |
451 | STACK_CHECK( L) | 462 | STACK_CHECK( L); |
452 | if( _on_state_create) | 463 | if( _on_state_create) |
453 | { | 464 | { |
454 | DEBUGSPEW_CODE( fprintf( stderr, "calling on_state_create()\n")); | 465 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); |
455 | lua_pushcfunction( L, _on_state_create); | 466 | lua_pushcfunction( L, _on_state_create); |
456 | lua_call( L, 0, 0); | 467 | lua_call( L, 0, 0); |
457 | } | 468 | } |
@@ -466,13 +477,13 @@ lua_State* luaG_newstate( lua_State* _from, char const* libs, lua_CFunction _on_ | |||
466 | { | 477 | { |
467 | if( libs[0] == '*' && libs[1] == 0) // special "*" case (mainly to help with LuaJIT compatibility) | 478 | if( libs[0] == '*' && libs[1] == 0) // special "*" case (mainly to help with LuaJIT compatibility) |
468 | { | 479 | { |
469 | DEBUGSPEW_CODE( fprintf( stderr, "opening ALL standard libraries\n")); | 480 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END)); |
470 | luaL_openlibs( L); | 481 | luaL_openlibs( L); |
471 | libs = NULL; // done with libs | 482 | libs = NULL; // done with libs |
472 | } | 483 | } |
473 | else | 484 | else |
474 | { | 485 | { |
475 | DEBUGSPEW_CODE( fprintf( stderr, "opening base library\n")); | 486 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening base library\n" INDENT_END)); |
476 | #if LUA_VERSION_NUM >= 502 | 487 | #if LUA_VERSION_NUM >= 502 |
477 | // open base library the same way as in luaL_openlibs() | 488 | // open base library the same way as in luaL_openlibs() |
478 | luaL_requiref( L, "_G", luaopen_base, 1); | 489 | luaL_requiref( L, "_G", luaopen_base, 1); |
@@ -484,7 +495,7 @@ lua_State* luaG_newstate( lua_State* _from, char const* libs, lua_CFunction _on_ | |||
484 | #endif // LUA_VERSION_NUM | 495 | #endif // LUA_VERSION_NUM |
485 | } | 496 | } |
486 | } | 497 | } |
487 | STACK_END( L, 0) | 498 | STACK_END( L, 0); |
488 | 499 | ||
489 | // scan all libraries, open them one by one | 500 | // scan all libraries, open them one by one |
490 | if( libs) | 501 | if( libs) |
@@ -508,12 +519,13 @@ lua_State* luaG_newstate( lua_State* _from, char const* libs, lua_CFunction _on_ | |||
508 | 519 | ||
509 | lua_gc( L, LUA_GCRESTART, 0); | 520 | lua_gc( L, LUA_GCRESTART, 0); |
510 | 521 | ||
511 | STACK_CHECK( L) | 522 | STACK_CHECK( L); |
512 | // after opening base, register the functions it exported in our name<->function database | 523 | // after opening base, register the functions it exported in our name<->function database |
513 | lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack | 524 | lua_pushglobaltable( L); // Lua 5.2 no longer has LUA_GLOBALSINDEX: we must push globals table on the stack |
514 | populate_func_lookup_table( L, -1, NULL); | 525 | populate_func_lookup_table( L, -1, NULL); |
515 | lua_pop( L, 1); | 526 | lua_pop( L, 1); |
516 | STACK_END( L, 0) | 527 | STACK_END( L, 0); |
528 | DEBUGSPEW_CODE( -- debugspew_indent_depth); | ||
517 | return L; | 529 | return L; |
518 | } | 530 | } |
519 | 531 | ||
@@ -554,7 +566,7 @@ void set_deep_lookup( lua_State *L ) { | |||
554 | 566 | ||
555 | STACK_GROW(L,3); | 567 | STACK_GROW(L,3); |
556 | 568 | ||
557 | STACK_CHECK(L) | 569 | STACK_CHECK( L); |
558 | #if 1 | 570 | #if 1 |
559 | push_registry_subtable( L, DEEP_LOOKUP_KEY ); | 571 | push_registry_subtable( L, DEEP_LOOKUP_KEY ); |
560 | #else | 572 | #else |
@@ -580,7 +592,7 @@ void set_deep_lookup( lua_State *L ) { | |||
580 | // [-1]: lookup table (empty) | 592 | // [-1]: lookup table (empty) |
581 | } | 593 | } |
582 | #endif | 594 | #endif |
583 | STACK_MID(L,1) | 595 | STACK_MID( L, 1); |
584 | 596 | ||
585 | lua_insert(L,-3); | 597 | lua_insert(L,-3); |
586 | 598 | ||
@@ -594,7 +606,7 @@ void set_deep_lookup( lua_State *L ) { | |||
594 | lua_rawset( L, -3 ); // A->B | 606 | lua_rawset( L, -3 ); // A->B |
595 | lua_pop( L,1 ); | 607 | lua_pop( L,1 ); |
596 | 608 | ||
597 | STACK_END(L,-2) | 609 | STACK_END( L, -2); |
598 | } | 610 | } |
599 | 611 | ||
600 | /* | 612 | /* |
@@ -605,7 +617,7 @@ void get_deep_lookup( lua_State *L ) { | |||
605 | 617 | ||
606 | STACK_GROW(L,1); | 618 | STACK_GROW(L,1); |
607 | 619 | ||
608 | STACK_CHECK(L) | 620 | STACK_CHECK( L); |
609 | lua_pushlightuserdata( L, DEEP_LOOKUP_KEY ); | 621 | lua_pushlightuserdata( L, DEEP_LOOKUP_KEY ); |
610 | lua_rawget( L, LUA_REGISTRYINDEX ); | 622 | lua_rawget( L, LUA_REGISTRYINDEX ); |
611 | 623 | ||
@@ -621,7 +633,7 @@ void get_deep_lookup( lua_State *L ) { | |||
621 | } | 633 | } |
622 | lua_remove(L,-2); | 634 | lua_remove(L,-2); |
623 | // remove lookup, or unused key | 635 | // remove lookup, or unused key |
624 | STACK_END(L,0) | 636 | STACK_END( L, 0); |
625 | } | 637 | } |
626 | 638 | ||
627 | /* | 639 | /* |
@@ -637,7 +649,7 @@ luaG_IdFunction get_idfunc( lua_State *L, int index ) | |||
637 | 649 | ||
638 | STACK_GROW(L,1); | 650 | STACK_GROW(L,1); |
639 | 651 | ||
640 | STACK_CHECK(L) | 652 | STACK_CHECK( L); |
641 | if (!lua_getmetatable( L, index )) | 653 | if (!lua_getmetatable( L, index )) |
642 | return NULL; // no metatable | 654 | return NULL; // no metatable |
643 | 655 | ||
@@ -649,7 +661,7 @@ luaG_IdFunction get_idfunc( lua_State *L, int index ) | |||
649 | 661 | ||
650 | ret= (luaG_IdFunction)lua_touserdata(L,-1); | 662 | ret= (luaG_IdFunction)lua_touserdata(L,-1); |
651 | lua_pop(L,1); | 663 | lua_pop(L,1); |
652 | STACK_END(L,0) | 664 | STACK_END( L, 0); |
653 | return ret; | 665 | return ret; |
654 | } | 666 | } |
655 | 667 | ||
@@ -728,7 +740,7 @@ void luaG_push_proxy( lua_State *L, luaG_IdFunction idfunc, DEEP_PRELUDE *prelud | |||
728 | 740 | ||
729 | STACK_GROW(L,4); | 741 | STACK_GROW(L,4); |
730 | 742 | ||
731 | STACK_CHECK(L) | 743 | STACK_CHECK( L); |
732 | 744 | ||
733 | proxy= lua_newuserdata( L, sizeof( DEEP_PRELUDE* ) ); | 745 | proxy= lua_newuserdata( L, sizeof( DEEP_PRELUDE* ) ); |
734 | ASSERT_L(proxy); | 746 | ASSERT_L(proxy); |
@@ -784,7 +796,7 @@ void luaG_push_proxy( lua_State *L, luaG_IdFunction idfunc, DEEP_PRELUDE *prelud | |||
784 | 796 | ||
785 | // 2 - cause the target state to require the module that exported the idfunc | 797 | // 2 - cause the target state to require the module that exported the idfunc |
786 | // this is needed because we must make sure the shared library is still loaded as long as we hold a pointer on the idfunc | 798 | // this is needed because we must make sure the shared library is still loaded as long as we hold a pointer on the idfunc |
787 | STACK_CHECK(L) | 799 | STACK_CHECK( L); |
788 | { | 800 | { |
789 | char const * modname; | 801 | char const * modname; |
790 | // make sure the function pushed a single value on the stack! | 802 | // make sure the function pushed a single value on the stack! |
@@ -839,9 +851,9 @@ void luaG_push_proxy( lua_State *L, luaG_IdFunction idfunc, DEEP_PRELUDE *prelud | |||
839 | lua_pop( L, 1); // ... | 851 | lua_pop( L, 1); // ... |
840 | } | 852 | } |
841 | } | 853 | } |
842 | STACK_END(L,0) | 854 | STACK_END( L, 0); |
843 | } | 855 | } |
844 | STACK_MID(L,2) | 856 | STACK_MID( L, 2); |
845 | ASSERT_L( lua_isuserdata(L,-2) ); | 857 | ASSERT_L( lua_isuserdata(L,-2) ); |
846 | ASSERT_L( lua_istable(L,-1) ); | 858 | ASSERT_L( lua_istable(L,-1) ); |
847 | 859 | ||
@@ -857,7 +869,7 @@ void luaG_push_proxy( lua_State *L, luaG_IdFunction idfunc, DEEP_PRELUDE *prelud | |||
857 | lua_rawset(L, -3); | 869 | lua_rawset(L, -3); |
858 | lua_pop(L, 1); // Remove the cache proxy table | 870 | lua_pop(L, 1); // Remove the cache proxy table |
859 | 871 | ||
860 | STACK_END(L,1) | 872 | STACK_END( L, 1); |
861 | // [-1]: proxy userdata | 873 | // [-1]: proxy userdata |
862 | } | 874 | } |
863 | 875 | ||
@@ -894,7 +906,7 @@ int luaG_deep_userdata( lua_State *L, luaG_IdFunction idfunc) | |||
894 | prelude->refcount= 0; // 'luaG_push_proxy' will lift it to 1 | 906 | prelude->refcount= 0; // 'luaG_push_proxy' will lift it to 1 |
895 | 907 | ||
896 | STACK_GROW(L,1); | 908 | STACK_GROW(L,1); |
897 | STACK_CHECK(L) | 909 | STACK_CHECK( L); |
898 | 910 | ||
899 | // lightuserdata= idfunc( "new" [, ...] ) | 911 | // lightuserdata= idfunc( "new" [, ...] ) |
900 | // | 912 | // |
@@ -915,7 +927,7 @@ int luaG_deep_userdata( lua_State *L, luaG_IdFunction idfunc) | |||
915 | // | 927 | // |
916 | // [-1]: proxy userdata | 928 | // [-1]: proxy userdata |
917 | 929 | ||
918 | STACK_END(L,1) | 930 | STACK_END( L, 1); |
919 | return 1; | 931 | return 1; |
920 | } | 932 | } |
921 | 933 | ||
@@ -930,12 +942,12 @@ void *luaG_todeep( lua_State *L, luaG_IdFunction idfunc, int index ) | |||
930 | { | 942 | { |
931 | DEEP_PRELUDE **proxy; | 943 | DEEP_PRELUDE **proxy; |
932 | 944 | ||
933 | STACK_CHECK(L) | 945 | STACK_CHECK( L); |
934 | if( get_idfunc(L,index) != idfunc) | 946 | if( get_idfunc(L,index) != idfunc) |
935 | return NULL; // no metatable, or wrong kind | 947 | return NULL; // no metatable, or wrong kind |
936 | 948 | ||
937 | proxy= (DEEP_PRELUDE**)lua_touserdata( L, index ); | 949 | proxy= (DEEP_PRELUDE**)lua_touserdata( L, index ); |
938 | STACK_END(L,0) | 950 | STACK_END( L, 0); |
939 | 951 | ||
940 | return (*proxy)->deep; | 952 | return (*proxy)->deep; |
941 | } | 953 | } |
@@ -993,7 +1005,7 @@ void push_registry_subtable_mode( lua_State *L, void *token, const char* mode ) | |||
993 | 1005 | ||
994 | STACK_GROW(L,3); | 1006 | STACK_GROW(L,3); |
995 | 1007 | ||
996 | STACK_CHECK(L) | 1008 | STACK_CHECK( L); |
997 | 1009 | ||
998 | lua_pushlightuserdata( L, token ); | 1010 | lua_pushlightuserdata( L, token ); |
999 | lua_rawget( L, LUA_REGISTRYINDEX ); | 1011 | lua_rawget( L, LUA_REGISTRYINDEX ); |
@@ -1021,7 +1033,7 @@ void push_registry_subtable_mode( lua_State *L, void *token, const char* mode ) | |||
1021 | lua_setmetatable(L, -2); | 1033 | lua_setmetatable(L, -2); |
1022 | } | 1034 | } |
1023 | } | 1035 | } |
1024 | STACK_END(L,1) | 1036 | STACK_END( L, 1); |
1025 | 1037 | ||
1026 | ASSERT_L( lua_istable(L,-1) ); | 1038 | ASSERT_L( lua_istable(L,-1) ); |
1027 | } | 1039 | } |
@@ -1049,7 +1061,7 @@ uint_t get_mt_id( lua_State *L, int i ) { | |||
1049 | 1061 | ||
1050 | STACK_GROW(L,3); | 1062 | STACK_GROW(L,3); |
1051 | 1063 | ||
1052 | STACK_CHECK(L) | 1064 | STACK_CHECK( L); |
1053 | push_registry_subtable( L, REG_MTID ); | 1065 | push_registry_subtable( L, REG_MTID ); |
1054 | lua_pushvalue(L, i); | 1066 | lua_pushvalue(L, i); |
1055 | lua_rawget( L, -2 ); | 1067 | lua_rawget( L, -2 ); |
@@ -1059,7 +1071,7 @@ uint_t get_mt_id( lua_State *L, int i ) { | |||
1059 | 1071 | ||
1060 | id= (uint_t)lua_tointeger(L,-1); // 0 for nil | 1072 | id= (uint_t)lua_tointeger(L,-1); // 0 for nil |
1061 | lua_pop(L,1); | 1073 | lua_pop(L,1); |
1062 | STACK_MID(L,1) | 1074 | STACK_MID( L, 1); |
1063 | 1075 | ||
1064 | if (id==0) { | 1076 | if (id==0) { |
1065 | MUTEX_LOCK( &mtid_lock ); | 1077 | MUTEX_LOCK( &mtid_lock ); |
@@ -1078,7 +1090,7 @@ uint_t get_mt_id( lua_State *L, int i ) { | |||
1078 | } | 1090 | } |
1079 | lua_pop(L,1); // remove 'reg[REG_MTID]' reference | 1091 | lua_pop(L,1); // remove 'reg[REG_MTID]' reference |
1080 | 1092 | ||
1081 | STACK_END(L,0) | 1093 | STACK_END( L, 0); |
1082 | 1094 | ||
1083 | return id; | 1095 | return id; |
1084 | } | 1096 | } |
@@ -1111,7 +1123,7 @@ static bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, | |||
1111 | 1123 | ||
1112 | // L2_cache[id_str]= [{...}] | 1124 | // L2_cache[id_str]= [{...}] |
1113 | // | 1125 | // |
1114 | STACK_CHECK(L2) | 1126 | STACK_CHECK( L2); |
1115 | 1127 | ||
1116 | // We don't need to use the from state ('L') in ID since the life span | 1128 | // We don't need to use the from state ('L') in ID since the life span |
1117 | // is only for the duration of a copy (both states are locked). | 1129 | // is only for the duration of a copy (both states are locked). |
@@ -1149,7 +1161,7 @@ static bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, | |||
1149 | lua_remove(L2,-2); | 1161 | lua_remove(L2,-2); |
1150 | ret= TRUE; // from cache | 1162 | ret= TRUE; // from cache |
1151 | } | 1163 | } |
1152 | STACK_END(L2,1) | 1164 | STACK_END( L2, 1); |
1153 | // | 1165 | // |
1154 | // L2 [-1]: table to use as destination | 1166 | // L2 [-1]: table to use as destination |
1155 | 1167 | ||
@@ -1176,7 +1188,7 @@ static void push_cached_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, ui | |||
1176 | 1188 | ||
1177 | // L2_cache[id_str]= function | 1189 | // L2_cache[id_str]= function |
1178 | // | 1190 | // |
1179 | STACK_CHECK( L2) | 1191 | STACK_CHECK( L2); |
1180 | 1192 | ||
1181 | // We don't need to use the from state ('L') in ID since the life span | 1193 | // We don't need to use the from state ('L') in ID since the life span |
1182 | // is only for the duration of a copy (both states are locked). | 1194 | // is only for the duration of a copy (both states are locked). |
@@ -1204,7 +1216,7 @@ static void push_cached_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, ui | |||
1204 | { | 1216 | { |
1205 | lua_remove( L2, -2); // ... {cache} ... function | 1217 | lua_remove( L2, -2); // ... {cache} ... function |
1206 | } | 1218 | } |
1207 | STACK_END( L2, 1) | 1219 | STACK_END( L2, 1); |
1208 | // | 1220 | // |
1209 | // L2 [-1]: function | 1221 | // L2 [-1]: function |
1210 | 1222 | ||
@@ -1226,7 +1238,7 @@ int discover_object_name_recur( lua_State* L, int _shortest, int _length) | |||
1226 | return _shortest; | 1238 | return _shortest; |
1227 | } | 1239 | } |
1228 | STACK_GROW( L, 3); | 1240 | STACK_GROW( L, 3); |
1229 | STACK_CHECK(L) | 1241 | STACK_CHECK( L); |
1230 | // stack top contains the table to search in | 1242 | // stack top contains the table to search in |
1231 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} | 1243 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} |
1232 | lua_rawget( L, cache); // o "r" {c} {fqn} ... {?} nil/1 | 1244 | lua_rawget( L, cache); // o "r" {c} {fqn} ... {?} nil/1 |
@@ -1299,7 +1311,7 @@ int discover_object_name_recur( lua_State* L, int _shortest, int _length) | |||
1299 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} | 1311 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} |
1300 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} {?} nil | 1312 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} {?} nil |
1301 | lua_rawset( L, cache); // o "r" {c} {fqn} ... {?} | 1313 | lua_rawset( L, cache); // o "r" {c} {fqn} ... {?} |
1302 | STACK_END( L, 0) | 1314 | STACK_END( L, 0); |
1303 | return _shortest; | 1315 | return _shortest; |
1304 | } | 1316 | } |
1305 | 1317 | ||
@@ -1345,13 +1357,14 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i) | |||
1345 | char const* fqn; // L // L2 | 1357 | char const* fqn; // L // L2 |
1346 | size_t len; | 1358 | size_t len; |
1347 | _ASSERT_L( L, lua_isfunction( L, i)); // ... f ... | 1359 | _ASSERT_L( L, lua_isfunction( L, i)); // ... f ... |
1348 | STACK_CHECK( L) | 1360 | STACK_CHECK( L); |
1349 | // fetch the name from the source state's lookup table | 1361 | // fetch the name from the source state's lookup table |
1350 | lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY); // ... f ... {} | 1362 | lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY); // ... f ... {} |
1351 | _ASSERT_L( L, lua_istable( L, -1)); | 1363 | _ASSERT_L( L, lua_istable( L, -1)); |
1352 | lua_pushvalue( L, i); // ... f ... {} f | 1364 | lua_pushvalue( L, i); // ... f ... {} f |
1353 | lua_rawget( L, -2); // ... f ... {} "f.q.n" | 1365 | lua_rawget( L, -2); // ... f ... {} "f.q.n" |
1354 | fqn = lua_tolstring( L, -1, &len); | 1366 | fqn = lua_tolstring( L, -1, &len); |
1367 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn)); | ||
1355 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database | 1368 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database |
1356 | lua_pop( L, 2); // ... f ... | 1369 | lua_pop( L, 2); // ... f ... |
1357 | if( !fqn) | 1370 | if( !fqn) |
@@ -1366,9 +1379,9 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i) | |||
1366 | (void) luaL_error( L, "%s '%s' not found in %s origin transfer database.", lua_tostring( L, -3), lua_tostring( L, -2), from ? from : "main"); | 1379 | (void) luaL_error( L, "%s '%s' not found in %s origin transfer database.", lua_tostring( L, -3), lua_tostring( L, -2), from ? from : "main"); |
1367 | return; | 1380 | return; |
1368 | } | 1381 | } |
1369 | STACK_END( L, 0) | 1382 | STACK_END( L, 0); |
1370 | // push the equivalent function in the destination's stack, retrieved from the lookup table | 1383 | // push the equivalent function in the destination's stack, retrieved from the lookup table |
1371 | STACK_CHECK( L2) | 1384 | STACK_CHECK( L2); |
1372 | lua_getfield( L2, LUA_REGISTRYINDEX, LOOKUP_KEY); // {} | 1385 | lua_getfield( L2, LUA_REGISTRYINDEX, LOOKUP_KEY); // {} |
1373 | _ASSERT_L( L2, lua_istable( L2, -1)); | 1386 | _ASSERT_L( L2, lua_istable( L2, -1)); |
1374 | lua_pushlstring( L2, fqn, len); // {} "f.q.n" | 1387 | lua_pushlstring( L2, fqn, len); // {} "f.q.n" |
@@ -1384,7 +1397,7 @@ static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i) | |||
1384 | return; | 1397 | return; |
1385 | } | 1398 | } |
1386 | lua_remove( L2, -2); // f | 1399 | lua_remove( L2, -2); // f |
1387 | STACK_END( L2, 1) | 1400 | STACK_END( L2, 1); |
1388 | } | 1401 | } |
1389 | 1402 | ||
1390 | /* | 1403 | /* |
@@ -1403,7 +1416,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1403 | 1416 | ||
1404 | ASSERT_L( L2_cache_i != 0); // ... {cache} ... p | 1417 | ASSERT_L( L2_cache_i != 0); // ... {cache} ... p |
1405 | STACK_GROW(L,2); | 1418 | STACK_GROW(L,2); |
1406 | STACK_CHECK(L) | 1419 | STACK_CHECK( L); |
1407 | 1420 | ||
1408 | if( funcSubType == FST_Bytecode) | 1421 | if( funcSubType == FST_Bytecode) |
1409 | { | 1422 | { |
@@ -1448,7 +1461,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1448 | // fills 'name' 'namewhat' and 'linedefined', pops function | 1461 | // fills 'name' 'namewhat' and 'linedefined', pops function |
1449 | lua_getinfo(L, ">nS", &ar); // ... b | 1462 | lua_getinfo(L, ">nS", &ar); // ... b |
1450 | name = ar.namewhat; | 1463 | name = ar.namewhat; |
1451 | fprintf( stderr, "%.*sFNAME: %s @ %d\n", i, s_indent, ar.short_src, ar.linedefined); // just gives NULL | 1464 | fprintf( stderr, INDENT_BEGIN "FNAME: %s @ %d\n", i, s_indent, ar.short_src, ar.linedefined); // just gives NULL |
1452 | } | 1465 | } |
1453 | #endif // LOG_FUNC_INFO | 1466 | #endif // LOG_FUNC_INFO |
1454 | { | 1467 | { |
@@ -1480,7 +1493,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1480 | // cache[p] = function | 1493 | // cache[p] = function |
1481 | lua_rawset( L2, L2_cache_i); // ... {cache} ... function | 1494 | lua_rawset( L2, L2_cache_i); // ... {cache} ... function |
1482 | } | 1495 | } |
1483 | STACK_MID( L, 0) | 1496 | STACK_MID( L, 0); |
1484 | 1497 | ||
1485 | /* push over any upvalues; references to this function will come from | 1498 | /* push over any upvalues; references to this function will come from |
1486 | * cache so we don't end up in eternal loop. | 1499 | * cache so we don't end up in eternal loop. |
@@ -1497,7 +1510,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1497 | #endif // LUA_VERSION_NUM | 1510 | #endif // LUA_VERSION_NUM |
1498 | for( n = 0; (DEBUGSPEW_CODE( upname =) lua_getupvalue( L, i, 1 + n)) != NULL; ++ n) | 1511 | for( n = 0; (DEBUGSPEW_CODE( upname =) lua_getupvalue( L, i, 1 + n)) != NULL; ++ n) |
1499 | { // ... _G up[n] | 1512 | { // ... _G up[n] |
1500 | DEBUGSPEW_CODE( fprintf( stderr, "%.*sUPNAME[%d]: %s\n", i, debugspew_indent, n, upname)); | 1513 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "UPNAME[%d]: %s\n" INDENT_END, n, upname)); |
1501 | #if LUA_VERSION_NUM == 502 | 1514 | #if LUA_VERSION_NUM == 502 |
1502 | if( lua_rawequal( L, -1, -2)) // is the upvalue equal to the global table? | 1515 | if( lua_rawequal( L, -1, -2)) // is the upvalue equal to the global table? |
1503 | { | 1516 | { |
@@ -1517,7 +1530,7 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1517 | } | 1530 | } |
1518 | // L2: function + 'n' upvalues (>=0) | 1531 | // L2: function + 'n' upvalues (>=0) |
1519 | 1532 | ||
1520 | STACK_MID( L, 0) | 1533 | STACK_MID( L, 0); |
1521 | 1534 | ||
1522 | // Set upvalues (originally set to 'nil' by 'lua_load') | 1535 | // Set upvalues (originally set to 'nil' by 'lua_load') |
1523 | { | 1536 | { |
@@ -1539,11 +1552,10 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1539 | else // C function OR LuaJIT fast function!!! | 1552 | else // C function OR LuaJIT fast function!!! |
1540 | { | 1553 | { |
1541 | lua_pop( L2, 1); // ... {cache} ... | 1554 | lua_pop( L2, 1); // ... {cache} ... |
1542 | DEBUGSPEW_CODE( fprintf( stderr, "%.*sFNAME: [C] function %p \n", i, debugspew_indent, cfunc)); | ||
1543 | // No need to transfer upvalues for C/JIT functions since they weren't actually copied, only looked up | 1555 | // No need to transfer upvalues for C/JIT functions since they weren't actually copied, only looked up |
1544 | lookup_native_func( L2, L, i); // ... {cache} ... function | 1556 | lookup_native_func( L2, L, i); // ... {cache} ... function |
1545 | } | 1557 | } |
1546 | STACK_END( L, 0) | 1558 | STACK_END( L, 0); |
1547 | } | 1559 | } |
1548 | 1560 | ||
1549 | /* | 1561 | /* |
@@ -1558,206 +1570,253 @@ static void inter_copy_func( lua_State* L2, uint_t L2_cache_i, lua_State* L, uin | |||
1558 | */ | 1570 | */ |
1559 | static bool_t inter_copy_one_( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i, enum e_vt vt ) | 1571 | static bool_t inter_copy_one_( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i, enum e_vt vt ) |
1560 | { | 1572 | { |
1561 | bool_t ret= TRUE; | 1573 | bool_t ret= TRUE; |
1562 | 1574 | ||
1563 | STACK_GROW( L2, 1 ); | 1575 | STACK_GROW( L2, 1 ); |
1564 | 1576 | ||
1565 | STACK_CHECK(L2) | 1577 | STACK_CHECK( L2); |
1566 | 1578 | ||
1567 | switch ( lua_type(L,i) ) { | 1579 | switch ( lua_type( L, i)) |
1568 | /* Basic types allowed both as values, and as table keys */ | 1580 | { |
1581 | /* Basic types allowed both as values, and as table keys */ | ||
1569 | 1582 | ||
1570 | case LUA_TBOOLEAN: | 1583 | case LUA_TBOOLEAN: |
1571 | lua_pushboolean( L2, lua_toboolean(L, i) ); | 1584 | lua_pushboolean( L2, lua_toboolean( L, i)); |
1572 | break; | 1585 | break; |
1573 | 1586 | ||
1574 | case LUA_TNUMBER: | 1587 | case LUA_TNUMBER: |
1575 | /* LNUM patch support (keeping integer accuracy) */ | 1588 | /* LNUM patch support (keeping integer accuracy) */ |
1576 | #ifdef LUA_LNUM | 1589 | #ifdef LUA_LNUM |
1577 | if (lua_isinteger(L,i)) { | 1590 | if( lua_isinteger(L,i)) |
1578 | lua_pushinteger( L2, lua_tointeger(L, i) ); | 1591 | { |
1579 | break; | 1592 | lua_Integer v = lua_tointeger( L, i); |
1580 | } | 1593 | DEBUGSPEW_CODE( if( vt == VT_KEY) fprintf( stderr, INDENT_BEGIN "KEY: %d\n" INDENT_END, v)); |
1594 | lua_pushinteger( L2, v); | ||
1595 | break; | ||
1596 | } | ||
1597 | else | ||
1581 | #endif | 1598 | #endif |
1582 | lua_pushnumber( L2, lua_tonumber(L, i) ); | 1599 | { |
1583 | break; | 1600 | lua_Number v = lua_tonumber( L, i); |
1584 | 1601 | DEBUGSPEW_CODE( if( vt == VT_KEY) fprintf( stderr, INDENT_BEGIN "KEY: " LUA_NUMBER_FMT "\n" INDENT_END, v)); | |
1585 | case LUA_TSTRING: { | 1602 | lua_pushnumber( L2, v); |
1586 | size_t len; const char* s = lua_tolstring( L, i, &len); | 1603 | } |
1587 | DEBUGSPEW_CODE( if( vt == VT_KEY) fprintf( stderr, "%.*sKEY: %s\n", i, debugspew_indent, s)); | 1604 | break; |
1588 | lua_pushlstring( L2, s, len ); | 1605 | |
1589 | } break; | 1606 | case LUA_TSTRING: |
1590 | 1607 | { | |
1591 | case LUA_TLIGHTUSERDATA: | 1608 | size_t len; |
1592 | lua_pushlightuserdata( L2, lua_touserdata(L, i) ); | 1609 | char const* s = lua_tolstring( L, i, &len); |
1593 | break; | 1610 | DEBUGSPEW_CODE( if( vt == VT_KEY) fprintf( stderr, INDENT_BEGIN "KEY: %s\n" INDENT_END, s)); |
1594 | 1611 | lua_pushlstring( L2, s, len); | |
1595 | /* The following types are not allowed as table keys */ | 1612 | } |
1596 | 1613 | break; | |
1597 | case LUA_TUSERDATA: if (vt==VT_KEY) { ret=FALSE; break; } | 1614 | |
1598 | /* Allow only deep userdata entities to be copied across | 1615 | case LUA_TLIGHTUSERDATA: |
1599 | */ | 1616 | lua_pushlightuserdata( L2, lua_touserdata(L, i)); |
1600 | if (!luaG_copydeep( L, L2, i )) { | 1617 | break; |
1601 | // Cannot copy it full; copy as light userdata | 1618 | |
1602 | // | 1619 | /* The following types are not allowed as table keys */ |
1603 | lua_pushlightuserdata( L2, lua_touserdata(L, i) ); | 1620 | |
1604 | } break; | 1621 | case LUA_TUSERDATA: |
1605 | 1622 | if( vt == VT_KEY) | |
1606 | case LUA_TNIL: if (vt==VT_KEY) { ret=FALSE; break; } | 1623 | { |
1607 | lua_pushnil(L2); | 1624 | ret = FALSE; |
1608 | break; | 1625 | break; |
1609 | 1626 | } | |
1610 | case LUA_TFUNCTION: if (vt==VT_KEY) { ret=FALSE; break; } { | 1627 | /* Allow only deep userdata entities to be copied across |
1611 | /* | 1628 | */ |
1612 | * Passing C functions is risky; if they refer to LUA_ENVIRONINDEX | 1629 | if( !luaG_copydeep( L, L2, i)) |
1613 | * and/or LUA_REGISTRYINDEX they might work unintended (not work) | 1630 | { |
1614 | * at the target. | 1631 | // Cannot copy it full; copy as light userdata |
1615 | * | 1632 | // |
1616 | * On the other hand, NOT copying them causes many self tests not | 1633 | lua_pushlightuserdata( L2, lua_touserdata( L, i)); |
1617 | * to work (timer, hangtest, ...) | 1634 | } |
1618 | * | 1635 | break; |
1619 | * The trouble is, we cannot KNOW if the function at hand is safe | 1636 | |
1620 | * or not. We cannot study it's behaviour. We could trust the user, | 1637 | case LUA_TNIL: |
1621 | * but they might not even know they're sending lua_CFunction over | 1638 | if( vt == VT_KEY) |
1622 | * (as upvalues etc.). | 1639 | { |
1623 | */ | 1640 | ret = FALSE; |
1641 | break; | ||
1642 | } | ||
1643 | lua_pushnil( L2); | ||
1644 | break; | ||
1645 | |||
1646 | case LUA_TFUNCTION: | ||
1647 | if( vt == VT_KEY) | ||
1648 | { | ||
1649 | ret = FALSE; | ||
1650 | break; | ||
1651 | } | ||
1652 | { | ||
1653 | /* | ||
1654 | * Passing C functions is risky; if they refer to LUA_ENVIRONINDEX | ||
1655 | * and/or LUA_REGISTRYINDEX they might work unintended (not work) | ||
1656 | * at the target. | ||
1657 | * | ||
1658 | * On the other hand, NOT copying them causes many self tests not | ||
1659 | * to work (timer, hangtest, ...) | ||
1660 | * | ||
1661 | * The trouble is, we cannot KNOW if the function at hand is safe | ||
1662 | * or not. We cannot study it's behaviour. We could trust the user, | ||
1663 | * but they might not even know they're sending lua_CFunction over | ||
1664 | * (as upvalues etc.). | ||
1665 | */ | ||
1624 | #if 0 | 1666 | #if 0 |
1625 | if (lua_iscfunction(L,i)) | 1667 | if( lua_iscfunction( L, i)) |
1626 | luaL_error( L, "Copying lua_CFunction between Lua states is risky, and currently disabled." ); | 1668 | luaL_error( L, "Copying lua_CFunction between Lua states is risky, and currently disabled." ); |
1627 | #endif | 1669 | #endif |
1628 | STACK_CHECK(L2) | 1670 | STACK_CHECK( L2); |
1629 | push_cached_func( L2, L2_cache_i, L, i ); | 1671 | push_cached_func( L2, L2_cache_i, L, i); |
1630 | ASSERT_L( lua_isfunction(L2,-1) ); | 1672 | ASSERT_L( lua_isfunction( L2, -1)); |
1631 | STACK_END(L2,1) | 1673 | STACK_END( L2, 1); |
1632 | } break; | 1674 | } |
1675 | break; | ||
1633 | 1676 | ||
1634 | case LUA_TTABLE: if (vt==VT_KEY) { ret=FALSE; break; } { | 1677 | case LUA_TTABLE: |
1635 | 1678 | if( vt == VT_KEY) | |
1636 | STACK_CHECK(L) | 1679 | { |
1637 | STACK_CHECK(L2) | 1680 | ret = FALSE; |
1638 | 1681 | break; | |
1639 | /* Check if we've already copied the same table from 'L' (during this transmission), and | 1682 | } |
1640 | * reuse the old copy. This allows table upvalues shared by multiple | 1683 | { |
1641 | * local functions to point to the same table, also in the target. | 1684 | STACK_CHECK( L); |
1642 | * Also, this takes care of cyclic tables and multiple references | 1685 | STACK_CHECK( L2); |
1643 | * to the same subtable. | 1686 | |
1644 | * | 1687 | /* Check if we've already copied the same table from 'L' (during this transmission), and |
1645 | * Note: Even metatables need to go through this test; to detect | 1688 | * reuse the old copy. This allows table upvalues shared by multiple |
1646 | * loops s.a. those in required module tables (getmetatable(lanes).lanes == lanes) | 1689 | * local functions to point to the same table, also in the target. |
1647 | */ | 1690 | * Also, this takes care of cyclic tables and multiple references |
1648 | if (push_cached_table( L2, L2_cache_i, L, i )) { | 1691 | * to the same subtable. |
1649 | ASSERT_L( lua_istable(L2, -1) ); // from cache | 1692 | * |
1650 | break; | 1693 | * Note: Even metatables need to go through this test; to detect |
1651 | } | 1694 | * loops s.a. those in required module tables (getmetatable(lanes).lanes == lanes) |
1652 | ASSERT_L( lua_istable(L2,-1) ); | 1695 | */ |
1653 | 1696 | if( push_cached_table( L2, L2_cache_i, L, i)) | |
1654 | STACK_GROW( L, 2 ); | 1697 | { |
1655 | STACK_GROW( L2, 2 ); | 1698 | ASSERT_L( lua_istable( L2, -1)); // from cache |
1656 | 1699 | break; | |
1657 | lua_pushnil(L); // start iteration | 1700 | } |
1658 | while( lua_next( L, i ) ) { | 1701 | ASSERT_L( lua_istable( L2,-1)); |
1659 | uint_t val_i= lua_gettop(L); | ||
1660 | uint_t key_i= val_i-1; | ||
1661 | |||
1662 | /* Only basic key types are copied over; others ignored | ||
1663 | */ | ||
1664 | if (inter_copy_one_( L2, 0 /*key*/, L, key_i, VT_KEY )) { | ||
1665 | /* | ||
1666 | * Contents of metatables are copied with cache checking; | ||
1667 | * important to detect loops. | ||
1668 | */ | ||
1669 | if (inter_copy_one_( L2, L2_cache_i, L, val_i, VT_NORMAL )) { | ||
1670 | ASSERT_L( lua_istable(L2,-3) ); | ||
1671 | lua_rawset( L2, -3 ); // add to table (pops key & val) | ||
1672 | } else { | ||
1673 | luaL_error( L, "Unable to copy over type '%s' (in %s)", | ||
1674 | luaL_typename(L,val_i), | ||
1675 | vt==VT_NORMAL ? "table":"metatable" ); | ||
1676 | } | ||
1677 | } | ||
1678 | lua_pop( L, 1 ); // pop value (next round) | ||
1679 | } | ||
1680 | STACK_MID(L,0) | ||
1681 | STACK_MID(L2,1) | ||
1682 | |||
1683 | /* Metatables are expected to be immutable, and copied only once. | ||
1684 | */ | ||
1685 | if (lua_getmetatable( L, i )) { | ||
1686 | // | ||
1687 | // L [-1]: metatable | ||
1688 | |||
1689 | uint_t mt_id= get_mt_id( L, -1 ); // Unique id for the metatable | ||
1690 | |||
1691 | STACK_GROW(L2,4); | ||
1692 | |||
1693 | push_registry_subtable( L2, REG_MTID ); | ||
1694 | STACK_MID(L2,2); | ||
1695 | lua_pushinteger( L2, mt_id ); | ||
1696 | lua_rawget( L2, -2 ); | ||
1697 | // | ||
1698 | // L2 ([-3]: copied table) | ||
1699 | // [-2]: reg[REG_MTID] | ||
1700 | // [-1]: nil/metatable pre-known in L2 | ||
1701 | |||
1702 | STACK_MID(L2,3); | ||
1703 | |||
1704 | if (lua_isnil(L2,-1)) { /* L2 did not know the metatable */ | ||
1705 | lua_pop(L2,1); | ||
1706 | STACK_MID(L2,2); | ||
1707 | ASSERT_L( lua_istable(L,-1) ); | ||
1708 | if (inter_copy_one_( L2, L2_cache_i /*for function cacheing*/, L, lua_gettop(L) /*[-1]*/, VT_METATABLE )) { | ||
1709 | // | ||
1710 | // L2 ([-3]: copied table) | ||
1711 | // [-2]: reg[REG_MTID] | ||
1712 | // [-1]: metatable (copied from L) | ||
1713 | |||
1714 | STACK_MID(L2,3); | ||
1715 | // mt_id -> metatable | ||
1716 | // | ||
1717 | lua_pushinteger(L2,mt_id); | ||
1718 | lua_pushvalue(L2,-2); | ||
1719 | lua_rawset(L2,-4); | ||
1720 | |||
1721 | // metatable -> mt_id | ||
1722 | // | ||
1723 | lua_pushvalue(L2,-1); | ||
1724 | lua_pushinteger(L2,mt_id); | ||
1725 | lua_rawset(L2,-4); | ||
1726 | |||
1727 | STACK_MID(L2,3); | ||
1728 | } else { | ||
1729 | luaL_error( L, "Error copying a metatable" ); | ||
1730 | } | ||
1731 | STACK_MID(L2,3); | ||
1732 | } | ||
1733 | // L2 ([-3]: copied table) | ||
1734 | // [-2]: reg[REG_MTID] | ||
1735 | // [-1]: metatable (pre-known or copied from L) | ||
1736 | 1702 | ||
1737 | lua_remove(L2,-2); // take away 'reg[REG_MTID]' | 1703 | STACK_GROW( L, 2); |
1738 | // | 1704 | STACK_GROW( L2, 2); |
1739 | // L2: ([-2]: copied table) | ||
1740 | // [-1]: metatable for that table | ||
1741 | 1705 | ||
1742 | lua_setmetatable( L2, -2 ); | 1706 | lua_pushnil( L); // start iteration |
1743 | 1707 | while( lua_next( L, i)) | |
1744 | // L2: [-1]: copied table (with metatable set if source had it) | 1708 | { |
1709 | uint_t val_i = lua_gettop(L); | ||
1710 | uint_t key_i = val_i - 1; | ||
1745 | 1711 | ||
1746 | lua_pop(L,1); // remove source metatable (L, not L2!) | 1712 | /* Only basic key types are copied over; others ignored |
1747 | } | 1713 | */ |
1748 | STACK_END(L2,1) | 1714 | if( inter_copy_one_( L2, 0 /*key*/, L, key_i, VT_KEY)) |
1749 | STACK_END(L,0) | 1715 | { |
1750 | } break; | 1716 | /* |
1717 | * Contents of metatables are copied with cache checking; | ||
1718 | * important to detect loops. | ||
1719 | */ | ||
1720 | if( inter_copy_one_( L2, L2_cache_i, L, val_i, VT_NORMAL)) | ||
1721 | { | ||
1722 | ASSERT_L( lua_istable(L2,-3)); | ||
1723 | lua_rawset( L2, -3); // add to table (pops key & val) | ||
1724 | } | ||
1725 | else | ||
1726 | { | ||
1727 | luaL_error( L, "Unable to copy over type '%s' (in %s)", luaL_typename( L, val_i), (vt == VT_NORMAL) ? "table" : "metatable"); | ||
1728 | } | ||
1729 | } | ||
1730 | lua_pop( L, 1); // pop value (next round) | ||
1731 | } | ||
1732 | STACK_MID( L, 0); | ||
1733 | STACK_MID( L2, 1); | ||
1751 | 1734 | ||
1752 | /* The following types cannot be copied */ | 1735 | /* Metatables are expected to be immutable, and copied only once. |
1736 | */ | ||
1737 | if( lua_getmetatable( L, i)) | ||
1738 | { | ||
1739 | // | ||
1740 | // L [-1]: metatable | ||
1753 | 1741 | ||
1754 | case LUA_TTHREAD: | 1742 | uint_t mt_id = get_mt_id( L, -1); // Unique id for the metatable |
1755 | ret=FALSE; break; | ||
1756 | } | ||
1757 | 1743 | ||
1758 | STACK_END(L2, ret? 1:0) | 1744 | STACK_GROW( L2, 4); |
1759 | 1745 | ||
1760 | return ret; | 1746 | push_registry_subtable( L2, REG_MTID); |
1747 | STACK_MID( L2, 2); | ||
1748 | lua_pushinteger( L2, mt_id); | ||
1749 | lua_rawget( L2, -2); | ||
1750 | // | ||
1751 | // L2 ([-3]: copied table) | ||
1752 | // [-2]: reg[REG_MTID] | ||
1753 | // [-1]: nil/metatable pre-known in L2 | ||
1754 | |||
1755 | STACK_MID( L2, 3); | ||
1756 | |||
1757 | if( lua_isnil( L2, -1)) | ||
1758 | { /* L2 did not know the metatable */ | ||
1759 | lua_pop( L2, 1); | ||
1760 | STACK_MID( L2, 2); | ||
1761 | ASSERT_L( lua_istable(L,-1)); | ||
1762 | if( inter_copy_one_( L2, L2_cache_i /*for function cacheing*/, L, lua_gettop(L) /*[-1]*/, VT_METATABLE)) | ||
1763 | { | ||
1764 | // | ||
1765 | // L2 ([-3]: copied table) | ||
1766 | // [-2]: reg[REG_MTID] | ||
1767 | // [-1]: metatable (copied from L) | ||
1768 | |||
1769 | STACK_MID( L2, 3); | ||
1770 | // mt_id -> metatable | ||
1771 | // | ||
1772 | lua_pushinteger( L2, mt_id); | ||
1773 | lua_pushvalue( L2, -2); | ||
1774 | lua_rawset( L2, -4); | ||
1775 | |||
1776 | // metatable -> mt_id | ||
1777 | // | ||
1778 | lua_pushvalue( L2, -1); | ||
1779 | lua_pushinteger( L2, mt_id); | ||
1780 | lua_rawset( L2, -4); | ||
1781 | |||
1782 | STACK_MID( L2, 3); | ||
1783 | } | ||
1784 | else | ||
1785 | { | ||
1786 | luaL_error( L, "Error copying a metatable"); | ||
1787 | } | ||
1788 | STACK_MID( L2, 3); | ||
1789 | } | ||
1790 | // L2 ([-3]: copied table) | ||
1791 | // [-2]: reg[REG_MTID] | ||
1792 | // [-1]: metatable (pre-known or copied from L) | ||
1793 | |||
1794 | lua_remove( L2, -2); // take away 'reg[REG_MTID]' | ||
1795 | // | ||
1796 | // L2: ([-2]: copied table) | ||
1797 | // [-1]: metatable for that table | ||
1798 | |||
1799 | lua_setmetatable( L2, -2); | ||
1800 | |||
1801 | // L2: [-1]: copied table (with metatable set if source had it) | ||
1802 | |||
1803 | lua_pop( L, 1); // remove source metatable (L, not L2!) | ||
1804 | } | ||
1805 | STACK_END( L2, 1); | ||
1806 | STACK_END( L, 0); | ||
1807 | } | ||
1808 | break; | ||
1809 | |||
1810 | /* The following types cannot be copied */ | ||
1811 | |||
1812 | case LUA_TTHREAD: | ||
1813 | ret = FALSE; | ||
1814 | break; | ||
1815 | } | ||
1816 | |||
1817 | STACK_END( L2, ret ? 1 : 0); | ||
1818 | |||
1819 | return ret; | ||
1761 | } | 1820 | } |
1762 | 1821 | ||
1763 | 1822 | ||
@@ -1829,9 +1888,11 @@ int luaG_inter_move( lua_State* L, lua_State* L2, uint_t n) | |||
1829 | 1888 | ||
1830 | void luaG_inter_copy_package( lua_State* L, lua_State* L2, int _idx) | 1889 | void luaG_inter_copy_package( lua_State* L, lua_State* L2, int _idx) |
1831 | { | 1890 | { |
1891 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END)); | ||
1892 | DEBUGSPEW_CODE( ++ debugspew_indent_depth); | ||
1832 | // package | 1893 | // package |
1833 | STACK_CHECK( L) | 1894 | STACK_CHECK( L); |
1834 | STACK_CHECK( L2) | 1895 | STACK_CHECK( L2); |
1835 | _idx = lua_absindex( L, _idx); | 1896 | _idx = lua_absindex( L, _idx); |
1836 | if( lua_type( L, _idx) != LUA_TTABLE) | 1897 | if( lua_type( L, _idx) != LUA_TTABLE) |
1837 | { | 1898 | { |
@@ -1845,6 +1906,7 @@ void luaG_inter_copy_package( lua_State* L, lua_State* L2, int _idx) | |||
1845 | char const* entries[] = { "path", "cpath", "preload", (LUA_VERSION_NUM == 501) ? "loaders" : "searchers", NULL}; | 1906 | char const* entries[] = { "path", "cpath", "preload", (LUA_VERSION_NUM == 501) ? "loaders" : "searchers", NULL}; |
1846 | for( i = 0; entries[i]; ++ i) | 1907 | for( i = 0; entries[i]; ++ i) |
1847 | { | 1908 | { |
1909 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s\n" INDENT_END, entries[i])); | ||
1848 | lua_getfield( L, _idx, entries[i]); | 1910 | lua_getfield( L, _idx, entries[i]); |
1849 | if( lua_isnil( L, -1)) | 1911 | if( lua_isnil( L, -1)) |
1850 | { | 1912 | { |
@@ -1852,14 +1914,21 @@ void luaG_inter_copy_package( lua_State* L, lua_State* L2, int _idx) | |||
1852 | } | 1914 | } |
1853 | else | 1915 | else |
1854 | { | 1916 | { |
1917 | DEBUGSPEW_CODE( ++ debugspew_indent_depth); | ||
1855 | luaG_inter_move( L, L2, 1); // moves the entry to L2 | 1918 | luaG_inter_move( L, L2, 1); // moves the entry to L2 |
1919 | DEBUGSPEW_CODE( -- debugspew_indent_depth); | ||
1856 | lua_setfield( L2, -2, entries[i]); // set package[entries[i]] | 1920 | lua_setfield( L2, -2, entries[i]); // set package[entries[i]] |
1857 | } | 1921 | } |
1858 | } | 1922 | } |
1859 | } | 1923 | } |
1924 | else | ||
1925 | { | ||
1926 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "'package' not loaded, nothing to do\n" INDENT_END)); | ||
1927 | } | ||
1860 | lua_pop( L2, 1); | 1928 | lua_pop( L2, 1); |
1861 | STACK_END( L2, 0) | 1929 | STACK_END( L2, 0); |
1862 | STACK_END( L, 0) | 1930 | STACK_END( L, 0); |
1931 | DEBUGSPEW_CODE( -- debugspew_indent_depth); | ||
1863 | } | 1932 | } |
1864 | 1933 | ||
1865 | 1934 | ||
@@ -1882,7 +1951,7 @@ static int new_require( lua_State *L) | |||
1882 | //char const* modname = luaL_checkstring( L, 1); | 1951 | //char const* modname = luaL_checkstring( L, 1); |
1883 | 1952 | ||
1884 | STACK_GROW( L, args + 1); | 1953 | STACK_GROW( L, args + 1); |
1885 | STACK_CHECK( L) | 1954 | STACK_CHECK( L); |
1886 | 1955 | ||
1887 | lua_pushvalue( L, lua_upvalueindex(1)); | 1956 | lua_pushvalue( L, lua_upvalueindex(1)); |
1888 | for( i = 1; i <= args; ++ i) | 1957 | for( i = 1; i <= args; ++ i) |
@@ -1900,7 +1969,7 @@ static int new_require( lua_State *L) | |||
1900 | MUTEX_UNLOCK( &require_cs); | 1969 | MUTEX_UNLOCK( &require_cs); |
1901 | 1970 | ||
1902 | // the required module (or an error message) is left on the stack as returned value by original require function | 1971 | // the required module (or an error message) is left on the stack as returned value by original require function |
1903 | STACK_END( L, 1) | 1972 | STACK_END( L, 1); |
1904 | 1973 | ||
1905 | if (rc) | 1974 | if (rc) |
1906 | lua_error(L); // error message already at [-1] | 1975 | lua_error(L); // error message already at [-1] |
@@ -1914,7 +1983,7 @@ static int new_require( lua_State *L) | |||
1914 | void serialize_require( lua_State *L ) | 1983 | void serialize_require( lua_State *L ) |
1915 | { | 1984 | { |
1916 | STACK_GROW( L, 1); | 1985 | STACK_GROW( L, 1); |
1917 | STACK_CHECK( L) | 1986 | STACK_CHECK( L); |
1918 | 1987 | ||
1919 | // Check 'require' is there; if not, do nothing | 1988 | // Check 'require' is there; if not, do nothing |
1920 | // | 1989 | // |
@@ -1931,5 +2000,5 @@ void serialize_require( lua_State *L ) | |||
1931 | lua_pop( L, 1); | 2000 | lua_pop( L, 1); |
1932 | } | 2001 | } |
1933 | 2002 | ||
1934 | STACK_END( L, 0) | 2003 | STACK_END( L, 0); |
1935 | } | 2004 | } |