aboutsummaryrefslogtreecommitdiff
path: root/src/tools.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools.c')
-rw-r--r--src/tools.c597
1 files changed, 367 insertions, 230 deletions
diff --git a/src/tools.c b/src/tools.c
index f1b0372..c2491ba 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -8,7 +8,7 @@
8=============================================================================== 8===============================================================================
9 9
10Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com> 10Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com>
11 2011-14 benoit Germain <bnt.germain@gmail.com> 11 2011-17 benoit Germain <bnt.germain@gmail.com>
12 12
13Permission is hereby granted, free of charge, to any person obtaining a copy 13Permission is hereby granted, free of charge, to any person obtaining a copy
14of this software and associated documentation files (the "Software"), to deal 14of this software and associated documentation files (the "Software"), to deal
@@ -71,48 +71,52 @@ DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!--
71 71
72/*---=== luaG_dump ===---*/ 72/*---=== luaG_dump ===---*/
73 73
74void luaG_dump( lua_State* L ) { 74void luaG_dump( lua_State* L)
75 75{
76 int top= lua_gettop(L); 76 int top = lua_gettop( L);
77 int i; 77 int i;
78 78
79 fprintf( stderr, "\n\tDEBUG STACK:\n" ); 79 fprintf( stderr, "\n\tDEBUG STACK:\n");
80 80
81 if (top==0) 81 if( top == 0)
82 fprintf( stderr, "\t(none)\n" ); 82 fprintf( stderr, "\t(none)\n");
83 83
84 for( i=1; i<=top; i++ ) { 84 for( i = 1; i <= top; ++ i)
85 int type= lua_type( L, i ); 85 {
86 int type = lua_type( L, i);
86 87
87 fprintf( stderr, "\t[%d]= (%s) ", i, lua_typename(L,type) ); 88 fprintf( stderr, "\t[%d]= (%s) ", i, lua_typename( L, type));
88 89
89 // Print item contents here... 90 // Print item contents here...
90 // 91 //
91 // Note: this requires 'tostring()' to be defined. If it is NOT, 92 // Note: this requires 'tostring()' to be defined. If it is NOT,
92 // enable it for more debugging. 93 // enable it for more debugging.
93 // 94 //
94 STACK_CHECK( L); 95 STACK_CHECK( L);
95 STACK_GROW( L, 2); 96 STACK_GROW( L, 2);
96 97
97 lua_getglobal( L, "tostring" ); 98 lua_getglobal( L, "tostring");
98 // 99 //
99 // [-1]: tostring function, or nil 100 // [-1]: tostring function, or nil
100 101
101 if (!lua_isfunction(L,-1)) { 102 if( !lua_isfunction( L, -1))
102 fprintf( stderr, "('tostring' not available)" ); 103 {
103 } else { 104 fprintf( stderr, "('tostring' not available)");
104 lua_pushvalue( L, i );
105 lua_call( L, 1 /*args*/, 1 /*retvals*/ );
106
107 // Don't trust the string contents
108 //
109 fprintf( stderr, "%s", lua_tostring(L,-1) );
110 }
111 lua_pop(L,1);
112 STACK_END( L, 0);
113 fprintf( stderr, "\n" );
114 } 105 }
115 fprintf( stderr, "\n" ); 106 else
107 {
108 lua_pushvalue( L, i);
109 lua_call( L, 1 /*args*/, 1 /*retvals*/);
110
111 // Don't trust the string contents
112 //
113 fprintf( stderr, "%s", lua_tostring( L, -1));
114 }
115 lua_pop( L, 1);
116 STACK_END( L, 0);
117 fprintf( stderr, "\n");
118 }
119 fprintf( stderr, "\n");
116} 120}
117 121
118void initialize_on_state_create( struct s_Universe* U, lua_State* L) 122void initialize_on_state_create( struct s_Universe* U, lua_State* L)
@@ -206,6 +210,14 @@ static const luaL_Reg libs[] =
206 { LUA_COLIBNAME, NULL}, // Lua 5.1: part of base package 210 { LUA_COLIBNAME, NULL}, // Lua 5.1: part of base package
207#endif // LUA_VERSION_NUM 211#endif // LUA_VERSION_NUM
208 { LUA_DBLIBNAME, luaopen_debug}, 212 { LUA_DBLIBNAME, luaopen_debug},
213#if defined LUA_JITLIBNAME // building against LuaJIT headers, add some LuaJIT-specific libs
214//#pragma message( "supporting JIT base libs")
215 { LUA_BITLIBNAME, luaopen_bit},
216 { LUA_JITLIBNAME, luaopen_jit},
217 { LUA_FFILIBNAME, luaopen_ffi},
218#endif // LUA_JITLIBNAME
219
220 { LUA_DBLIBNAME, luaopen_debug},
209 { "lanes.core", require_lanes_core}, // So that we can open it like any base library (possible since we have access to the init function) 221 { "lanes.core", require_lanes_core}, // So that we can open it like any base library (possible since we have access to the init function)
210 // 222 //
211 { "base", NULL}, // ignore "base" (already acquired it) 223 { "base", NULL}, // ignore "base" (already acquired it)
@@ -246,7 +258,8 @@ static void open1lib( struct s_Universe* U, lua_State* L, char const* name_, siz
246 } 258 }
247} 259}
248 260
249static int dummy_writer(lua_State *L, const void* p, size_t sz, void* ud) 261
262static int dummy_writer( lua_State* L, void const* p, size_t sz, void* ud)
250{ 263{
251 (void)L; (void)p; (void)sz; (void) ud; // unused 264 (void)L; (void)p; (void)sz; (void) ud; // unused
252 return 666; 265 return 666;
@@ -314,12 +327,12 @@ static lua_CFunction luaG_tocfunction( lua_State *L, int _i, FuncSubType *_out)
314 327
315 328
316// inspired from tconcat() in ltablib.c 329// inspired from tconcat() in ltablib.c
317static char const* luaG_pushFQN(lua_State *L, int t, int last, size_t* length) 330static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length)
318{ 331{
319 int i = 1; 332 int i = 1;
320 luaL_Buffer b; 333 luaL_Buffer b;
321 STACK_CHECK( L); 334 STACK_CHECK( L);
322 luaL_buffinit(L, &b); 335 luaL_buffinit( L, &b);
323 for( ; i < last; ++ i) 336 for( ; i < last; ++ i)
324 { 337 {
325 lua_rawgeti( L, t, i); 338 lua_rawgeti( L, t, i);
@@ -336,12 +349,89 @@ static char const* luaG_pushFQN(lua_State *L, int t, int last, size_t* length)
336 return lua_tolstring( L, -1, length); 349 return lua_tolstring( L, -1, length);
337} 350}
338 351
352/*
353 * receives 2 arguments: a name k and an object o
354 * add two entries ["fully.qualified.name"] = o
355 * and [o] = "fully.qualified.name"
356 * where <o> is either a table or a function
357 * if we already had an entry of type [o] = ..., replace the name if the new one is shorter
358 * pops the processed object from the stack
359 */
360static void update_lookup_entry( lua_State* L, int _ctx_base, int _depth)
361{
362 // slot 1 in the stack contains the table that receives everything we found
363 int const dest = _ctx_base;
364 // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i
365 int const fqn = _ctx_base + 1;
366
367 size_t prevNameLength, newNameLength;
368 char const* prevName;
369 DEBUGSPEW_CODE( char const *newName);
370 DEBUGSPEW_CODE( struct s_Universe* U = get_universe( L));
371
372 STACK_CHECK( L);
373 // first, raise an error if the function is already known
374 lua_pushvalue( L, -1); // ... {bfc} k o o
375 lua_rawget( L, dest); // ... {bfc} k o name?
376 prevName = lua_tolstring( L, -1, &prevNameLength); // NULL if we got nil (first encounter of this object)
377 // push name in fqn stack (note that concatenation will crash if name is a not string or a number)
378 lua_pushvalue( L, -3); // ... {bfc} k o name? k
379 ASSERT_L( lua_type( L, -1) == LUA_TNUMBER || lua_type( L, -1) == LUA_TSTRING);
380 ++ _depth;
381 lua_rawseti( L, fqn, _depth); // ... {bfc} k o name?
382 // generate name
383 DEBUGSPEW_CODE( newName =) luaG_pushFQN( L, fqn, _depth, &newNameLength); // ... {bfc} k o name? "f.q.n"
384 // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order
385 // on different VMs even when the tables are populated the exact same way.
386 // When Lua is built with compatibility options (such as LUA_COMPAT_ALL),
387 // this causes several base libraries to register functions under multiple names.
388 // This, with the randomizer, can cause the first generated name of an object to be different on different VMs,
389 // which breaks function transfer.
390 // Also, nothing prevents any external module from exposing a given object under several names, so...
391 // Therefore, when we encounter an object for which a name was previously registered, we need to select the names
392 // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded
393 if( prevName != NULL && (prevNameLength < newNameLength || lua_lessthan( L, -2, -1)))
394 {
395 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s '%s' remained named '%s'\n" INDENT_END, lua_typename( L, lua_type( L, -3)), newName, prevName));
396 // the previous name is 'smaller' than the one we just generated: keep it!
397 lua_pop( L, 3); // ... {bfc} k
398 }
399 else
400 {
401 // the name we generated is either the first one, or a better fit for our purposes
402 if( prevName)
403 {
404 // clear the previous name for the database to avoid clutter
405 lua_insert( L, -2); // ... {bfc} k o "f.q.n" prevName
406 // t[prevName] = nil
407 lua_pushnil( L); // ... {bfc} k o "f.q.n" prevName nil
408 lua_rawset( L, dest); // ... {bfc} k o "f.q.n"
409 }
410 else
411 {
412 lua_remove( L, -2); // ... {bfc} k o "f.q.n"
413 }
414 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s '%s'\n" INDENT_END, lua_typename( L, lua_type( L, -2)), newName));
415 // prepare the stack for database feed
416 lua_pushvalue( L, -1); // ... {bfc} k o "f.q.n" "f.q.n"
417 lua_pushvalue( L, -3); // ... {bfc} k o "f.q.n" "f.q.n" o
418 ASSERT_L( lua_rawequal( L, -1, -4));
419 ASSERT_L( lua_rawequal( L, -2, -3));
420 // t["f.q.n"] = o
421 lua_rawset( L, dest); // ... {bfc} k o "f.q.n"
422 // t[o] = "f.q.n"
423 lua_rawset( L, dest); // ... {bfc} k
424 // remove table name from fqn stack
425 lua_pushnil( L); // ... {bfc} k nil
426 lua_rawseti( L, fqn, _depth); // ... {bfc} k
427 }
428 -- _depth;
429 STACK_END( L, -1);
430}
339 431
340static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _i, int _depth) 432static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _i, int _depth)
341{ 433{
342 lua_Integer visit_count; 434 lua_Integer visit_count;
343 // slot 1 in the stack contains the table that receives everything we found
344 int const dest = _ctx_base;
345 // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i 435 // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i
346 int const fqn = _ctx_base + 1; 436 int const fqn = _ctx_base + 1;
347 // slot 3 contains a cache that stores all already visited tables to avoid infinite recursion loops 437 // slot 3 contains a cache that stores all already visited tables to avoid infinite recursion loops
@@ -400,69 +490,15 @@ static void populate_func_lookup_table_recur( lua_State* L, int _ctx_base, int _
400 lua_rawset( L, cache); // ... {_i} {bfc} k {} 490 lua_rawset( L, cache); // ... {_i} {bfc} k {}
401 // store the table in the breadth-first cache 491 // store the table in the breadth-first cache
402 lua_pushvalue( L, -2); // ... {_i} {bfc} k {} k 492 lua_pushvalue( L, -2); // ... {_i} {bfc} k {} k
403 lua_insert( L, -2); // ... {_i} {bfc} k k {} 493 lua_pushvalue( L, -2); // ... {_i} {bfc} k {} k {}
404 lua_rawset( L, breadth_first_cache); // ... {_i} {bfc} k 494 lua_rawset( L, breadth_first_cache); // ... {_i} {bfc} k {}
495 // generate a name, and if we already had one name, keep whichever is the shorter
496 update_lookup_entry( L, _ctx_base, _depth); // ... {_i} {bfc} k
405 } 497 }
406 else if( lua_isfunction( L, -1) && (luaG_getfuncsubtype( L, -1) != FST_Bytecode)) // ... {_i} {bfc} k func 498 else if( lua_isfunction( L, -1) && (luaG_getfuncsubtype( L, -1) != FST_Bytecode)) // ... {_i} {bfc} k func
407 { 499 {
408 size_t prevNameLength, newNameLength; 500 // generate a name, and if we already had one name, keep whichever is the shorter
409 char const* prevName; 501 update_lookup_entry( L, _ctx_base, _depth); // ... {_i} {bfc} k
410 DEBUGSPEW_CODE( char const *newName);
411 // first, raise an error if the function is already known
412 lua_pushvalue( L, -1); // ... {_i} {bfc} k func func
413 lua_rawget( L, dest); // ... {_i} {bfc} k func name?
414 prevName = lua_tolstring( L, -1, &prevNameLength); // NULL if we got nil (first encounter of this function)
415 // push function name in fqn stack (note that concatenation will crash if name is a not string or a number)
416 lua_pushvalue( L, -3); // ... {_i} {bfc} k func name? k
417 ++ _depth;
418 lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k func name?
419 // generate name
420 DEBUGSPEW_CODE( newName =) luaG_pushFQN( L, fqn, _depth, &newNameLength); // ... {_i} {bfc} k func name? "f.q.n"
421 // Lua 5.2 introduced a hash randomizer seed which causes table iteration to yield a different key order
422 // on different VMs even when the tables are populated the exact same way.
423 // When Lua is built with compatibility options (such as LUA_COMPAT_ALL),
424 // this causes several base libraries to register functions under multiple names.
425 // This, with the randomizer, can cause the first name of a function to be different on different VMs,
426 // which breaks function transfer.
427 // Also, nothing prevents any external module from exposing a given function under several names, so...
428 // Therefore, when we encounter a function for which a name was previously registered, we need to select the names
429 // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded
430 if( prevName != NULL && (prevNameLength < newNameLength || lua_lessthan( L, -2, -1)))
431 {
432 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function '%s' remained named '%s'\n" INDENT_END, newName, prevName));
433 // the previous name is 'smaller' than the one we just generated: keep it!
434 lua_pop( L, 3); // ... {_i} {bfc} k
435 }
436 else
437 {
438 // the name we generated is either the first one, or a better fit for our purposes
439 if( prevName)
440 {
441 // clear the previous name for the database to avoid clutter
442 lua_insert( L, -2); // ... {_i} {bfc} k func "f.q.n" prevName
443 // t[prevName] = nil
444 lua_pushnil( L); // ... {_i} {bfc} k func "f.q.n" prevName nil
445 lua_rawset( L, dest); // ... {_i} {bfc} k func "f.q.n"
446 }
447 else
448 {
449 lua_remove( L, -2); // ... {_i} {bfc} k func "f.q.n"
450 }
451 // prepare the stack for database feed
452 lua_pushvalue( L, -1); // ... {_i} {bfc} k func "f.q.n" "f.q.n"
453 lua_pushvalue( L, -3); // ... {_i} {bfc} k func "f.q.n" "f.q.n" func
454 ASSERT_L( lua_rawequal( L, -1, -4));
455 ASSERT_L( lua_rawequal( L, -2, -3));
456 // t["f.q.n"] = func
457 lua_rawset( L, dest); // ... {_i} {bfc} k func "f.q.n"
458 // t[func] = "f.q.n"
459 lua_rawset( L, dest); // ... {_i} {bfc} k
460 // remove table name from fqn stack
461 lua_pushnil( L); // ... {_i} {bfc} k nil
462 lua_rawseti( L, fqn, _depth); // ... {_i} {bfc} k
463 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function '%s'\n" INDENT_END, newName));
464 }
465 -- _depth;
466 } 502 }
467 else 503 else
468 { 504 {
@@ -519,7 +555,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
519{ 555{
520 int const ctx_base = lua_gettop( L) + 1; 556 int const ctx_base = lua_gettop( L) + 1;
521 int const in_base = lua_absindex( L, _i); 557 int const in_base = lua_absindex( L, _i);
522 int const start_depth = name_ ? 1 : 0; 558 int start_depth = 0;
523 DEBUGSPEW_CODE( struct s_Universe* U = get_universe( L)); 559 DEBUGSPEW_CODE( struct s_Universe* U = get_universe( L));
524 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "NULL")); 560 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "NULL"));
525 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 561 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
@@ -543,9 +579,17 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
543 lua_newtable( L); // {} {fqn} 579 lua_newtable( L); // {} {fqn}
544 if( name_) 580 if( name_)
545 { 581 {
582 STACK_MID( L, 2);
546 lua_pushstring( L, name_); // {} {fqn} "name" 583 lua_pushstring( L, name_); // {} {fqn} "name"
584 // generate a name, and if we already had one name, keep whichever is the shorter
585 lua_pushvalue( L, in_base); // {} {fqn} "name" t
586 update_lookup_entry( L, ctx_base, start_depth); // {} {fqn} "name"
587 // don't forget to store the name at the bottom of the fqn stack
588 ++ start_depth;
547 lua_rawseti( L, -2, start_depth); // {} {fqn} 589 lua_rawseti( L, -2, start_depth); // {} {fqn}
590 STACK_MID( L, 2);
548 } 591 }
592 // retrieve the cache, create it if we haven't done it yet
549 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY_CACHE); // {} {fqn} {cache}? 593 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY_CACHE); // {} {fqn} {cache}?
550 if( lua_isnil( L, -1)) 594 if( lua_isnil( L, -1))
551 { 595 {
@@ -554,6 +598,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
554 lua_pushvalue( L, -1); // {} {fqn} {cache} {cache} 598 lua_pushvalue( L, -1); // {} {fqn} {cache} {cache}
555 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY_CACHE); // {} {fqn} {cache} 599 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY_CACHE); // {} {fqn} {cache}
556 } 600 }
601 // process everything we find in that table, filling in lookup data for all functions and tables we see there
557 populate_func_lookup_table_recur( L, ctx_base, in_base, start_depth); // {...} {fqn} {cache} 602 populate_func_lookup_table_recur( L, ctx_base, in_base, start_depth); // {...} {fqn} {cache}
558 lua_pop( L, 3); 603 lua_pop( L, 3);
559 } 604 }
@@ -795,6 +840,158 @@ static int buf_writer( lua_State *L, const void* b, size_t n, void* B ) {
795} 840}
796 841
797 842
843// function sentinel used to transfer native functions from/to keeper states
844static int func_lookup_sentinel( lua_State* L)
845{
846 return luaL_error( L, "function lookup sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1)));
847}
848
849
850// function sentinel used to transfer native table from/to keeper states
851static int table_lookup_sentinel( lua_State* L)
852{
853 return luaL_error( L, "table lookup sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex(1)));
854}
855
856/*
857 * retrieve the name of a function/table in the lookup database
858 */
859static char const* find_lookup_name( lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_, size_t* len_)
860{
861 DEBUGSPEW_CODE( struct s_Universe* const U = get_universe( L));
862 char const* fqn;
863 ASSERT_L( lua_isfunction( L, i) || lua_istable( L, i)); // ... v ...
864 STACK_CHECK( L);
865 STACK_GROW( L, 3); // up to 3 slots are necessary on error
866 if( mode_ == eLM_FromKeeper)
867 {
868 lua_CFunction f = lua_tocfunction( L, i); // should *always* be func_lookup_sentinel or table_lookup_sentinel!
869 if( f == func_lookup_sentinel || f == table_lookup_sentinel)
870 {
871 lua_getupvalue( L, i, 1); // ... v ... "f.q.n"
872 }
873 else
874 {
875 // if this is not a sentinel, this is some user-created table we wanted to lookup
876 ASSERT_L( NULL == f && lua_istable( L, i));
877 // push anything that will convert to NULL string
878 lua_pushnil( L); // ... v ... nil
879 }
880 }
881 else
882 {
883 // fetch the name from the source state's lookup table
884 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // ... v ... {}
885 ASSERT_L( lua_istable( L, -1));
886 lua_pushvalue( L, i); // ... v ... {} v
887 lua_rawget( L, -2); // ... v ... {} "f.q.n"
888 }
889 fqn = lua_tolstring( L, -1, len_);
890 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn));
891 // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database
892 lua_pop( L, (mode_ == eLM_FromKeeper) ? 1 : 2); // ... v ...
893 STACK_MID( L, 0);
894 if( NULL == fqn && !lua_istable( L, i)) // raise an error if we try to send an unknown function (but not for tables)
895 {
896 char const *from, *typewhat, *what, *gotchaA, *gotchaB;
897 // try to discover the name of the function we want to send
898 lua_getglobal( L, "decoda_name"); // ... v ... decoda_name
899 from = lua_tostring( L, -1);
900 lua_pushcfunction( L, luaG_nameof); // ... v ... decoda_name luaG_nameof
901 lua_pushvalue( L, i); // ... v ... decoda_name luaG_nameof t
902 lua_call( L, 1, 2); // ... v ... decoda_name "type" "name"|nil
903 typewhat = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : luaL_typename( L, -2);
904 // second return value can be nil if the table was not found
905 // probable reason: the function was removed from the source Lua state before Lanes was required.
906 if( lua_isnil( L, -1))
907 {
908 gotchaA = " referenced by";
909 gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)";
910 what = upName_;
911 }
912 else
913 {
914 gotchaA = "";
915 gotchaB = "";
916 what = (lua_type( L, -1) == LUA_TSTRING) ? lua_tostring( L, -1) : luaL_typename( L, -1);
917 }
918 (void) luaL_error( L, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB);
919 *len_ = 0;
920 return NULL;
921 }
922 STACK_END( L, 0);
923 return fqn;
924}
925
926
927/*
928 * Push a looked-up table, or nothing if we found nothing
929 */
930static bool_t lookup_table( lua_State* L2, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_)
931{
932 // get the name of the table we want to send
933 size_t len;
934 char const* fqn = find_lookup_name( L, i, mode_, upName_, &len);
935 if( NULL == fqn) // name not found, it is some user-created table
936 {
937 return FALSE;
938 }
939 // push the equivalent table in the destination's stack, retrieved from the lookup table
940 STACK_CHECK( L2); // L // L2
941 STACK_GROW( L2, 3); // up to 3 slots are necessary on error
942 switch( mode_)
943 {
944 default: // shouldn't happen, in theory...
945 (void) luaL_error( L, "internal error: unknown lookup mode");
946 return FALSE;
947
948 case eLM_ToKeeper:
949 // push a sentinel closure that holds the lookup name as upvalue
950 lua_pushlstring( L2, fqn, len); // "f.q.n"
951 lua_pushcclosure( L2, table_lookup_sentinel, 1); // f
952 break;
953
954 case eLM_LaneBody:
955 case eLM_FromKeeper:
956 lua_getfield( L2, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // {}
957 ASSERT_L( lua_istable( L2, -1));
958 lua_pushlstring( L2, fqn, len); // {} "f.q.n"
959 lua_rawget( L2, -2); // {} t
960 // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead)
961 // but not when we extract something out of a keeper, as there is nothing to clone!
962 if( lua_isnil( L2, -1) && mode_ == eLM_LaneBody)
963 {
964 lua_pop( L2, 2); //
965 STACK_MID( L2, 0);
966 return FALSE;
967 }
968 else if( !lua_istable( L2, -1))
969 {
970 char const* from, *to;
971 lua_getglobal( L, "decoda_name"); // ... t ... decoda_name
972 from = lua_tostring( L, -1);
973 lua_pop( L, 1); // ... t ...
974 lua_getglobal( L2, "decoda_name"); // {} t decoda_name
975 to = lua_tostring( L2, -1);
976 lua_pop( L2, 1); // {} t
977 // when mode_ == eLM_FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error
978 (void) luaL_error(
979 (mode_ == eLM_FromKeeper) ? L2 : L
980 , "INTERNAL ERROR IN %s: table '%s' not found in %s destination transfer database."
981 , from ? from : "main"
982 , fqn
983 , to ? to : "main"
984 );
985 return FALSE;
986 }
987 lua_remove( L2, -2); // t
988 break;
989 }
990 STACK_END( L2, 1);
991 return TRUE;
992}
993
994
798/* 995/*
799 * Check if we've already copied the same table from 'L', and 996 * Check if we've already copied the same table from 'L', and
800 * reuse the old copy. This allows table upvalues shared by multiple 997 * reuse the old copy. This allows table upvalues shared by multiple
@@ -805,60 +1002,35 @@ static int buf_writer( lua_State *L, const void* b, size_t n, void* B ) {
805 * Returns TRUE if the table was cached (no need to fill it!); FALSE if 1002 * Returns TRUE if the table was cached (no need to fill it!); FALSE if
806 * it's a virgin. 1003 * it's a virgin.
807 */ 1004 */
808static bool_t push_cached_table( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) 1005static bool_t push_cached_table( lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i)
809{ 1006{
810 bool_t ret; 1007 bool_t not_found_in_cache; // L2
1008 void* const p = (void*)lua_topointer( L, i);
811 1009
812 ASSERT_L( L2_cache_i != 0 ); 1010 ASSERT_L( L2_cache_i != 0);
813 1011 STACK_GROW( L2, 3);
814 STACK_GROW(L2,3);
815
816 // L2_cache[id_str]= [{...}]
817 //
818 STACK_CHECK( L2); 1012 STACK_CHECK( L2);
819 1013
820 // We don't need to use the from state ('L') in ID since the life span 1014 // We don't need to use the from state ('L') in ID since the life span
821 // is only for the duration of a copy (both states are locked). 1015 // is only for the duration of a copy (both states are locked).
822 // 1016 // push a light userdata uniquely representing the table
823 lua_pushlightuserdata( L2, (void*)lua_topointer( L, i )); // push a light userdata uniquely representing the table 1017 lua_pushlightuserdata( L2, p); // ... p
824
825 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) );
826 1018
827 lua_pushvalue( L2, -1 ); 1019 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring( L2, -1));
828 lua_rawget( L2, L2_cache_i );
829 //
830 // [-2]: identity table pointer lightuserdata
831 // [-1]: table|nil
832 1020
833 if (lua_isnil(L2,-1)) 1021 lua_rawget( L2, L2_cache_i); // ... {cached|nil}
1022 not_found_in_cache = lua_isnil( L2, -1);
1023 if( not_found_in_cache)
834 { 1024 {
835 lua_pop(L2,1); 1025 lua_pop( L2, 1); // ...
836 lua_newtable(L2); 1026 lua_newtable( L2); // ... {}
837 lua_pushvalue(L2,-1); 1027 lua_pushlightuserdata( L2, p); // ... {} p
838 lua_insert(L2,-3); 1028 lua_pushvalue( L2, -2); // ... {} p {}
839 // 1029 lua_rawset( L2, L2_cache_i); // ... {}
840 // [-3]: new table (2nd ref)
841 // [-2]: identity table pointer lightuserdata
842 // [-1]: new table
843
844 lua_rawset(L2, L2_cache_i);
845 //
846 // [-1]: new table (tied to 'L2_cache' table')
847
848 ret= FALSE; // brand new
849
850 }
851 else
852 {
853 lua_remove(L2,-2);
854 ret= TRUE; // from cache
855 } 1030 }
856 STACK_END( L2, 1); 1031 STACK_END( L2, 1);
857 // 1032 ASSERT_L( lua_istable( L2, -1));
858 // L2 [-1]: table to use as destination 1033 return !not_found_in_cache;
859
860 ASSERT_L( lua_istable(L2,-1) );
861 return ret;
862} 1034}
863 1035
864 1036
@@ -999,6 +1171,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
999 return shortest_; 1171 return shortest_;
1000} 1172}
1001 1173
1174
1002/* 1175/*
1003 * "type", "name" = lanes.nameof( o) 1176 * "type", "name" = lanes.nameof( o)
1004 */ 1177 */
@@ -1046,72 +1219,17 @@ int luaG_nameof( lua_State* L)
1046 return 2; 1219 return 2;
1047} 1220}
1048 1221
1049// function sentinel used to transfer native functions from/to keeper states
1050static int sentinelfunc( lua_State* L)
1051{
1052 return luaL_error( L, "transfer sentinel function for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1)));
1053}
1054 1222
1055/* 1223/*
1056* Push a looked-up native/LuaJIT function. 1224 * Push a looked-up native/LuaJIT function.
1057*/ 1225 */
1058static void lookup_native_func( struct s_Universe* U, lua_State* L2, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_) 1226static void lookup_native_func( lua_State* L2, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_)
1059{ 1227{
1060 char const* fqn; // L // L2 1228 // get the name of the function we want to send
1061 size_t len; 1229 size_t len;
1062 ASSERT_L( lua_isfunction( L, i)); // ... f ... 1230 char const* fqn = find_lookup_name( L, i, mode_, upName_, &len);
1063 STACK_CHECK( L);
1064 STACK_GROW( L, 3); // up to 3 slots are necessary on error
1065 if( mode_ == eLM_FromKeeper)
1066 {
1067 lua_CFunction f = lua_tocfunction( L, i); // should *always* be sentinelfunc!
1068 ASSERT_L( f == sentinelfunc);
1069 lua_getupvalue( L, i, 1); // ... f ... "f.q.n"
1070 fqn = lua_tolstring( L, -1, &len);
1071 }
1072 else
1073 {
1074 // fetch the name from the source state's lookup table
1075 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // ... f ... {}
1076 ASSERT_L( lua_istable( L, -1));
1077 lua_pushvalue( L, i); // ... f ... {} f
1078 lua_rawget( L, -2); // ... f ... {} "f.q.n"
1079 fqn = lua_tolstring( L, -1, &len);
1080 }
1081 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn));
1082 // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database
1083 lua_pop( L, (mode_ == eLM_FromKeeper) ? 1 : 2); // ... f ...
1084 STACK_MID( L, 0);
1085 if( !fqn)
1086 {
1087 char const *from, *typewhat, *what, *gotchaA, *gotchaB;
1088 // try to discover the name of the function we want to send
1089 lua_getglobal( L, "decoda_name"); // ... f ... decoda_name
1090 from = lua_tostring( L, -1);
1091 lua_pushcfunction( L, luaG_nameof); // ... f ... decoda_name luaG_nameof
1092 lua_pushvalue( L, i); // ... f ... decoda_name luaG_nameof f
1093 lua_call( L, 1, 2); // ... f ... decoda_name "type" "name"|nil
1094 typewhat = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : luaL_typename( L, -2);
1095 // second return value can be nil if the function was not found
1096 // probable reason: the function was removed from the source Lua state before Lanes was required.
1097 if( lua_isnil( L, -1))
1098 {
1099 gotchaA = " referenced by";
1100 gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)";
1101 what = upName_;
1102 }
1103 else
1104 {
1105 gotchaA = "";
1106 gotchaB = "";
1107 what = (lua_type( L, -1) == LUA_TSTRING) ? lua_tostring( L, -1) : luaL_typename( L, -1);
1108 }
1109 (void) luaL_error( L, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB);
1110 return;
1111 }
1112 STACK_END( L, 0);
1113 // push the equivalent function in the destination's stack, retrieved from the lookup table 1231 // push the equivalent function in the destination's stack, retrieved from the lookup table
1114 STACK_CHECK( L2); 1232 STACK_CHECK( L2); // L // L2
1115 STACK_GROW( L2, 3); // up to 3 slots are necessary on error 1233 STACK_GROW( L2, 3); // up to 3 slots are necessary on error
1116 switch( mode_) 1234 switch( mode_)
1117 { 1235 {
@@ -1122,7 +1240,7 @@ static void lookup_native_func( struct s_Universe* U, lua_State* L2, lua_State*
1122 case eLM_ToKeeper: 1240 case eLM_ToKeeper:
1123 // push a sentinel closure that holds the lookup name as upvalue 1241 // push a sentinel closure that holds the lookup name as upvalue
1124 lua_pushlstring( L2, fqn, len); // "f.q.n" 1242 lua_pushlstring( L2, fqn, len); // "f.q.n"
1125 lua_pushcclosure( L2, sentinelfunc, 1); // f 1243 lua_pushcclosure( L2, func_lookup_sentinel, 1); // f
1126 break; 1244 break;
1127 1245
1128 case eLM_LaneBody: 1246 case eLM_LaneBody:
@@ -1131,15 +1249,26 @@ static void lookup_native_func( struct s_Universe* U, lua_State* L2, lua_State*
1131 ASSERT_L( lua_istable( L2, -1)); 1249 ASSERT_L( lua_istable( L2, -1));
1132 lua_pushlstring( L2, fqn, len); // {} "f.q.n" 1250 lua_pushlstring( L2, fqn, len); // {} "f.q.n"
1133 lua_rawget( L2, -2); // {} f 1251 lua_rawget( L2, -2); // {} f
1134 if( !lua_isfunction( L2, -1)) 1252 // nil means we don't know how to transfer stuff: user should do something
1253 // anything other than function or table should not happen!
1254 if( !lua_isfunction( L2, -1) && !lua_istable( L2, -1))
1135 { 1255 {
1136 char const* from, * to; 1256 char const* from, * to;
1137 lua_getglobal( L, "decoda_name"); // ... f ... decoda_name 1257 lua_getglobal( L, "decoda_name"); // ... f ... decoda_name
1138 from = lua_tostring( L, -1); 1258 from = lua_tostring( L, -1);
1259 lua_pop( L, 1); // ... f ...
1139 lua_getglobal( L2, "decoda_name"); // {} f decoda_name 1260 lua_getglobal( L2, "decoda_name"); // {} f decoda_name
1140 to = lua_tostring( L2, -1); 1261 to = lua_tostring( L2, -1);
1262 lua_pop( L2, 1); // {} f
1141 // when mode_ == eLM_FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error 1263 // when mode_ == eLM_FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error
1142 (void) luaL_error( (mode_ == eLM_FromKeeper) ? L2 : L, "%s: function '%s' not found in %s destination transfer database.", from ? from : "main", fqn, to ? to : "main"); 1264 (void) luaL_error(
1265 (mode_ == eLM_FromKeeper) ? L2 : L
1266 , "%s%s: function '%s' not found in %s destination transfer database."
1267 , lua_isnil( L2, -1) ? "" : "INTERNAL ERROR IN "
1268 , from ? from : "main"
1269 , fqn
1270 , to ? to : "main"
1271 );
1143 return; 1272 return;
1144 } 1273 }
1145 lua_remove( L2, -2); // f 1274 lua_remove( L2, -2); // f
@@ -1164,6 +1293,7 @@ static void lookup_native_func( struct s_Universe* U, lua_State* L2, lua_State*
1164 STACK_END( L2, 1); 1293 STACK_END( L2, 1);
1165} 1294}
1166 1295
1296
1167/* 1297/*
1168 * Copy a function over, which has not been found in the cache. 1298 * Copy a function over, which has not been found in the cache.
1169 * L2 has the cache key for this function at the top of the stack 1299 * L2 has the cache key for this function at the top of the stack
@@ -1181,7 +1311,7 @@ static void inter_copy_func( struct s_Universe* U, lua_State* L2, uint_t L2_cach
1181 int n, needToPush; 1311 int n, needToPush;
1182 luaL_Buffer b; 1312 luaL_Buffer b;
1183 ASSERT_L( L2_cache_i != 0); // ... {cache} ... p 1313 ASSERT_L( L2_cache_i != 0); // ... {cache} ... p
1184 STACK_GROW(L,2); 1314 STACK_GROW( L, 2);
1185 STACK_CHECK( L); 1315 STACK_CHECK( L);
1186 1316
1187 // 'lua_dump()' needs the function at top of stack 1317 // 'lua_dump()' needs the function at top of stack
@@ -1223,7 +1353,7 @@ static void inter_copy_func( struct s_Universe* U, lua_State* L2, uint_t L2_cach
1223 lua_Debug ar; 1353 lua_Debug ar;
1224 lua_pushvalue( L, i); // ... b f 1354 lua_pushvalue( L, i); // ... b f
1225 // fills 'name' 'namewhat' and 'linedefined', pops function 1355 // fills 'name' 'namewhat' and 'linedefined', pops function
1226 lua_getinfo(L, ">nS", &ar); // ... b 1356 lua_getinfo( L, ">nS", &ar); // ... b
1227 name = ar.namewhat; 1357 name = ar.namewhat;
1228 fprintf( stderr, INDENT_BEGIN "FNAME: %s @ %d\n", i, s_indent, ar.short_src, ar.linedefined); // just gives NULL 1358 fprintf( stderr, INDENT_BEGIN "FNAME: %s @ %d\n", i, s_indent, ar.short_src, ar.linedefined); // just gives NULL
1229 } 1359 }
@@ -1348,12 +1478,12 @@ static void push_cached_func( struct s_Universe* U, lua_State* L2, uint_t L2_cac
1348 // push a light userdata uniquely representing the function 1478 // push a light userdata uniquely representing the function
1349 lua_pushlightuserdata( L2, aspointer); // ... {cache} ... p 1479 lua_pushlightuserdata( L2, aspointer); // ... {cache} ... p
1350 1480
1351 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); 1481 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring( L2, -1));
1352 1482
1353 lua_pushvalue( L2, -1); // ... {cache} ... p p 1483 lua_pushvalue( L2, -1); // ... {cache} ... p p
1354 lua_rawget( L2, L2_cache_i); // ... {cache} ... p function|nil|true 1484 lua_rawget( L2, L2_cache_i); // ... {cache} ... p function|nil|true
1355 1485
1356 if( lua_isnil(L2,-1)) // function is unknown 1486 if( lua_isnil( L2, -1)) // function is unknown
1357 { 1487 {
1358 lua_pop( L2, 1); // ... {cache} ... p 1488 lua_pop( L2, 1); // ... {cache} ... p
1359 1489
@@ -1368,15 +1498,14 @@ static void push_cached_func( struct s_Universe* U, lua_State* L2, uint_t L2_cac
1368 lua_remove( L2, -2); // ... {cache} ... function 1498 lua_remove( L2, -2); // ... {cache} ... function
1369 } 1499 }
1370 STACK_END( L2, 1); 1500 STACK_END( L2, 1);
1501 ASSERT_L( lua_isfunction( L2, -1));
1371 } 1502 }
1372 else // function is native/LuaJIT: no need to cache 1503 else // function is native/LuaJIT: no need to cache
1373 { 1504 {
1374 lookup_native_func( U, L2, L, i, mode_, upName_); // ... {cache} ... function 1505 lookup_native_func( L2, L, i, mode_, upName_); // ... {cache} ... function
1506 // if the function was in fact a lookup sentinel, we can either get a function or a table here
1507 ASSERT_L( lua_isfunction( L2, -1) || lua_istable( L2, -1));
1375 } 1508 }
1376
1377 //
1378 // L2 [-1]: function
1379 ASSERT_L( lua_isfunction( L2, -1));
1380} 1509}
1381 1510
1382/* 1511/*
@@ -1393,25 +1522,23 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1393{ 1522{
1394 bool_t ret = TRUE; 1523 bool_t ret = TRUE;
1395 bool_t ignore = FALSE; 1524 bool_t ignore = FALSE;
1525 int val_type = lua_type( L, i);
1396 STACK_GROW( L2, 1); 1526 STACK_GROW( L2, 1);
1397 STACK_CHECK( L2); 1527 STACK_CHECK( L2);
1398 1528
1399 /* Skip the object if it has metatable with { __lanesignore = true } */ 1529 /* Skip the object if it has metatable with { __lanesignore = true } */
1400 if( lua_getmetatable( L, i)) // ... mt 1530 if( lua_getmetatable( L, i)) // ... mt
1401 { 1531 {
1402 lua_pushstring( L, "__lanesignore"); // ... mt "__lanesignore" 1532 lua_getfield( L, -1, "__lanesignore"); // ... mt ignore?
1403 lua_gettable( L, -2); // ... mt ignore?
1404
1405 if( lua_isboolean( L, -1) && lua_toboolean( L, -1)) 1533 if( lua_isboolean( L, -1) && lua_toboolean( L, -1))
1406 { 1534 {
1407 ignore = TRUE; 1535 val_type = LUA_TNIL;
1408 } 1536 }
1409
1410 lua_pop( L, 2); // ... 1537 lua_pop( L, 2); // ...
1411 } 1538 }
1412 1539
1413 /* Lets push nil to L2 if the object should be ignored */ 1540 /* Lets push nil to L2 if the object should be ignored */
1414 switch( ignore ? LUA_TNIL : lua_type( L, i)) 1541 switch( val_type)
1415 { 1542 {
1416 /* Basic types allowed both as values, and as table keys */ 1543 /* Basic types allowed both as values, and as table keys */
1417 1544
@@ -1425,7 +1552,7 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1425 if( lua_isinteger( L, i)) 1552 if( lua_isinteger( L, i))
1426 { 1553 {
1427 lua_Integer v = lua_tointeger( L, i); 1554 lua_Integer v = lua_tointeger( L, i);
1428 DEBUGSPEW_CODE( if( vt == VT_KEY) fprintf( stderr, INDENT_BEGIN "KEY: %d\n" INDENT_END, v)); 1555 DEBUGSPEW_CODE( if( vt == VT_KEY) fprintf( stderr, INDENT_BEGIN "KEY: " LUA_INTEGER_FMT "\n" INDENT_END, v));
1429 lua_pushinteger( L2, v); 1556 lua_pushinteger( L2, v);
1430 break; 1557 break;
1431 } 1558 }
@@ -1448,7 +1575,7 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1448 break; 1575 break;
1449 1576
1450 case LUA_TLIGHTUSERDATA: 1577 case LUA_TLIGHTUSERDATA:
1451 lua_pushlightuserdata( L2, lua_touserdata(L, i)); 1578 lua_pushlightuserdata( L2, lua_touserdata( L, i));
1452 break; 1579 break;
1453 1580
1454 /* The following types are not allowed as table keys */ 1581 /* The following types are not allowed as table keys */
@@ -1524,6 +1651,16 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1524 STACK_CHECK( L); 1651 STACK_CHECK( L);
1525 STACK_CHECK( L2); 1652 STACK_CHECK( L2);
1526 1653
1654 /*
1655 * First, let's try to see if this table is special (aka is it some table that we registered in our lookup databases during module registration?)
1656 * Note that this table CAN be a module table, but we just didn't register it, in which case we'll send it through the table cloning mechanism
1657 */
1658 if( lookup_table( L2, L, i, mode_, upName_))
1659 {
1660 ASSERT_L( lua_istable( L2, -1) || (lua_tocfunction( L2, -1) == table_lookup_sentinel)); // from lookup datables // can also be table_lookup_sentinel if this is a table we know
1661 break;
1662 }
1663
1527 /* Check if we've already copied the same table from 'L' (during this transmission), and 1664 /* Check if we've already copied the same table from 'L' (during this transmission), and
1528 * reuse the old copy. This allows table upvalues shared by multiple 1665 * reuse the old copy. This allows table upvalues shared by multiple
1529 * local functions to point to the same table, also in the target. 1666 * local functions to point to the same table, also in the target.
@@ -1531,14 +1668,14 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1531 * to the same subtable. 1668 * to the same subtable.
1532 * 1669 *
1533 * Note: Even metatables need to go through this test; to detect 1670 * Note: Even metatables need to go through this test; to detect
1534 * loops s.a. those in required module tables (getmetatable(lanes).lanes == lanes) 1671 * loops such as those in required module tables (getmetatable(lanes).lanes == lanes)
1535 */ 1672 */
1536 if( push_cached_table( L2, L2_cache_i, L, i)) 1673 if( push_cached_table( L2, L2_cache_i, L, i))
1537 { 1674 {
1538 ASSERT_L( lua_istable( L2, -1)); // from cache 1675 ASSERT_L( lua_istable( L2, -1)); // from cache
1539 break; 1676 break;
1540 } 1677 }
1541 ASSERT_L( lua_istable( L2,-1)); 1678 ASSERT_L( lua_istable( L2, -1));
1542 1679
1543 STACK_GROW( L, 2); 1680 STACK_GROW( L, 2);
1544 STACK_GROW( L2, 2); 1681 STACK_GROW( L2, 2);
@@ -1546,11 +1683,10 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1546 lua_pushnil( L); // start iteration 1683 lua_pushnil( L); // start iteration
1547 while( lua_next( L, i)) 1684 while( lua_next( L, i))
1548 { 1685 {
1549 uint_t val_i = lua_gettop(L); 1686 uint_t val_i = lua_gettop( L);
1550 uint_t key_i = val_i - 1; 1687 uint_t key_i = val_i - 1;
1551 1688
1552 /* Only basic key types are copied over; others ignored 1689 // Only basic key types are copied over; others ignored
1553 */
1554 if( inter_copy_one_( U, L2, 0 /*key*/, L, key_i, VT_KEY, mode_, upName_)) 1690 if( inter_copy_one_( U, L2, 0 /*key*/, L, key_i, VT_KEY, mode_, upName_))
1555 { 1691 {
1556 char* valPath = (char*) upName_; 1692 char* valPath = (char*) upName_;
@@ -1613,8 +1749,8 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1613 { /* L2 did not know the metatable */ 1749 { /* L2 did not know the metatable */
1614 lua_pop( L2, 1); 1750 lua_pop( L2, 1);
1615 STACK_MID( L2, 2); 1751 STACK_MID( L2, 2);
1616 ASSERT_L( lua_istable(L,-1)); 1752 ASSERT_L( lua_istable( L,-1));
1617 if( inter_copy_one_( U, L2, L2_cache_i /*for function cacheing*/, L, lua_gettop(L) /*[-1]*/, VT_METATABLE, mode_, upName_)) 1753 if( inter_copy_one_( U, L2, L2_cache_i /*for function cacheing*/, L, lua_gettop( L) /*[-1]*/, VT_METATABLE, mode_, upName_))
1618 { 1754 {
1619 // 1755 //
1620 // L2 ([-3]: copied table) 1756 // L2 ([-3]: copied table)
@@ -1664,6 +1800,7 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1664 1800
1665 /* The following types cannot be copied */ 1801 /* The following types cannot be copied */
1666 1802
1803 case 10: // LuaJIT CDATA
1667 case LUA_TTHREAD: 1804 case LUA_TTHREAD:
1668 ret = FALSE; 1805 ret = FALSE;
1669 break; 1806 break;