aboutsummaryrefslogtreecommitdiff
path: root/src/tools.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools.c')
-rw-r--r--src/tools.c318
1 files changed, 227 insertions, 91 deletions
diff --git a/src/tools.c b/src/tools.c
index d97b231..a4d781f 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -85,7 +85,7 @@ void luaG_dump( lua_State* L)
85 { 85 {
86 int type = lua_type( L, i); 86 int type = lua_type( L, i);
87 87
88 fprintf( stderr, "\t[%d]= (%s) ", i, lua_typename(L, type)); 88 fprintf( stderr, "\t[%d]= (%s) ", i, lua_typename( L, type));
89 89
90 // Print item contents here... 90 // Print item contents here...
91 // 91 //
@@ -99,7 +99,7 @@ void luaG_dump( lua_State* L)
99 // 99 //
100 // [-1]: tostring function, or nil 100 // [-1]: tostring function, or nil
101 101
102 if( !lua_isfunction(L, -1)) 102 if( !lua_isfunction( L, -1))
103 { 103 {
104 fprintf( stderr, "('tostring' not available)"); 104 fprintf( stderr, "('tostring' not available)");
105 } 105 }
@@ -110,7 +110,7 @@ void luaG_dump( lua_State* L)
110 110
111 // Don't trust the string contents 111 // Don't trust the string contents
112 // 112 //
113 fprintf( stderr, "%s", lua_tostring(L, -1)); 113 fprintf( stderr, "%s", lua_tostring( L, -1));
114 } 114 }
115 lua_pop( L, 1); 115 lua_pop( L, 1);
116 STACK_END( L, 0); 116 STACK_END( L, 0);
@@ -258,7 +258,8 @@ static void open1lib( struct s_Universe* U, lua_State* L, char const* name_, siz
258 } 258 }
259} 259}
260 260
261static 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)
262{ 263{
263 (void)L; (void)p; (void)sz; (void) ud; // unused 264 (void)L; (void)p; (void)sz; (void) ud; // unused
264 return 666; 265 return 666;
@@ -326,12 +327,12 @@ static lua_CFunction luaG_tocfunction( lua_State *L, int _i, FuncSubType *_out)
326 327
327 328
328// inspired from tconcat() in ltablib.c 329// inspired from tconcat() in ltablib.c
329static 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)
330{ 331{
331 int i = 1; 332 int i = 1;
332 luaL_Buffer b; 333 luaL_Buffer b;
333 STACK_CHECK( L); 334 STACK_CHECK( L);
334 luaL_buffinit(L, &b); 335 luaL_buffinit( L, &b);
335 for( ; i < last; ++ i) 336 for( ; i < last; ++ i)
336 { 337 {
337 lua_rawgeti( L, t, i); 338 lua_rawgeti( L, t, i);
@@ -349,10 +350,12 @@ static char const* luaG_pushFQN(lua_State *L, int t, int last, size_t* length)
349} 350}
350 351
351/* 352/*
353 * receives 2 arguments: a name k and an object o
352 * add two entries ["fully.qualified.name"] = o 354 * add two entries ["fully.qualified.name"] = o
353 * and [o] = "fully.qualified.name" 355 * and [o] = "fully.qualified.name"
354 * where <o> is either a table or a function 356 * where <o> is either a table or a function
355 * if we already had an entry of type [o] = ..., replace the name if the new one is shorter 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
356 */ 359 */
357static void update_lookup_entry( lua_State* L, int _ctx_base, int _depth) 360static void update_lookup_entry( lua_State* L, int _ctx_base, int _depth)
358{ 361{
@@ -364,12 +367,16 @@ static void update_lookup_entry( lua_State* L, int _ctx_base, int _depth)
364 size_t prevNameLength, newNameLength; 367 size_t prevNameLength, newNameLength;
365 char const* prevName; 368 char const* prevName;
366 DEBUGSPEW_CODE( char const *newName); 369 DEBUGSPEW_CODE( char const *newName);
370 DEBUGSPEW_CODE( struct s_Universe* U = get_universe( L));
371
372 STACK_CHECK( L);
367 // first, raise an error if the function is already known 373 // first, raise an error if the function is already known
368 lua_pushvalue( L, -1); // ... {bfc} k o o 374 lua_pushvalue( L, -1); // ... {bfc} k o o
369 lua_rawget( L, dest); // ... {bfc} k o name? 375 lua_rawget( L, dest); // ... {bfc} k o name?
370 prevName = lua_tolstring( L, -1, &prevNameLength); // NULL if we got nil (first encounter of this object) 376 prevName = lua_tolstring( L, -1, &prevNameLength); // NULL if we got nil (first encounter of this object)
371 // push name in fqn stack (note that concatenation will crash if name is a not string or a number) 377 // push name in fqn stack (note that concatenation will crash if name is a not string or a number)
372 lua_pushvalue( L, -3); // ... {bfc} k o name? k 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);
373 ++ _depth; 380 ++ _depth;
374 lua_rawseti( L, fqn, _depth); // ... {bfc} k o name? 381 lua_rawseti( L, fqn, _depth); // ... {bfc} k o name?
375 // generate name 382 // generate name
@@ -385,7 +392,7 @@ static void update_lookup_entry( lua_State* L, int _ctx_base, int _depth)
385 // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded 392 // based on some sorting order so that we end up with the same name in all databases whatever order the table walk yielded
386 if( prevName != NULL && (prevNameLength < newNameLength || lua_lessthan( L, -2, -1))) 393 if( prevName != NULL && (prevNameLength < newNameLength || lua_lessthan( L, -2, -1)))
387 { 394 {
388 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s '%s' remained named '%s'\n" INDENT_END, lua_typename( L, -3), newName, prevName)); 395 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s '%s' remained named '%s'\n" INDENT_END, lua_typename( L, lua_type( L, -3)), newName, prevName));
389 // the previous name is 'smaller' than the one we just generated: keep it! 396 // the previous name is 'smaller' than the one we just generated: keep it!
390 lua_pop( L, 3); // ... {bfc} k 397 lua_pop( L, 3); // ... {bfc} k
391 } 398 }
@@ -404,7 +411,7 @@ static void update_lookup_entry( lua_State* L, int _ctx_base, int _depth)
404 { 411 {
405 lua_remove( L, -2); // ... {bfc} k o "f.q.n" 412 lua_remove( L, -2); // ... {bfc} k o "f.q.n"
406 } 413 }
407 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s '%s'\n" INDENT_END, lua_typename( L, -2), newName)); 414 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s '%s'\n" INDENT_END, lua_typename( L, lua_type( L, -2)), newName));
408 // prepare the stack for database feed 415 // prepare the stack for database feed
409 lua_pushvalue( L, -1); // ... {bfc} k o "f.q.n" "f.q.n" 416 lua_pushvalue( L, -1); // ... {bfc} k o "f.q.n" "f.q.n"
410 lua_pushvalue( L, -3); // ... {bfc} k o "f.q.n" "f.q.n" o 417 lua_pushvalue( L, -3); // ... {bfc} k o "f.q.n" "f.q.n" o
@@ -419,6 +426,7 @@ static void update_lookup_entry( lua_State* L, int _ctx_base, int _depth)
419 lua_rawseti( L, fqn, _depth); // ... {bfc} k 426 lua_rawseti( L, fqn, _depth); // ... {bfc} k
420 } 427 }
421 -- _depth; 428 -- _depth;
429 STACK_END( L, -1);
422} 430}
423 431
424static 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)
@@ -547,7 +555,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
547{ 555{
548 int const ctx_base = lua_gettop( L) + 1; 556 int const ctx_base = lua_gettop( L) + 1;
549 int const in_base = lua_absindex( L, _i); 557 int const in_base = lua_absindex( L, _i);
550 int const start_depth = name_ ? 1 : 0; 558 int start_depth = 0;
551 DEBUGSPEW_CODE( struct s_Universe* U = get_universe( L)); 559 DEBUGSPEW_CODE( struct s_Universe* U = get_universe( L));
552 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"));
553 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 561 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
@@ -571,9 +579,17 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
571 lua_newtable( L); // {} {fqn} 579 lua_newtable( L); // {} {fqn}
572 if( name_) 580 if( name_)
573 { 581 {
582 STACK_MID( L, 2);
574 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;
575 lua_rawseti( L, -2, start_depth); // {} {fqn} 589 lua_rawseti( L, -2, start_depth); // {} {fqn}
590 STACK_MID( L, 2);
576 } 591 }
592 // retrieve the cache, create it if we haven't done it yet
577 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY_CACHE); // {} {fqn} {cache}? 593 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY_CACHE); // {} {fqn} {cache}?
578 if( lua_isnil( L, -1)) 594 if( lua_isnil( L, -1))
579 { 595 {
@@ -582,6 +598,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_)
582 lua_pushvalue( L, -1); // {} {fqn} {cache} {cache} 598 lua_pushvalue( L, -1); // {} {fqn} {cache} {cache}
583 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY_CACHE); // {} {fqn} {cache} 599 lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_KEY_CACHE); // {} {fqn} {cache}
584 } 600 }
601 // process everything we find in that table, filling in lookup data for all functions and tables we see there
585 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}
586 lua_pop( L, 3); 603 lua_pop( L, 3);
587 } 604 }
@@ -823,6 +840,158 @@ static int buf_writer( lua_State *L, const void* b, size_t n, void* B ) {
823} 840}
824 841
825 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
826/* 995/*
827 * 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
828 * reuse the old copy. This allows table upvalues shared by multiple 997 * reuse the old copy. This allows table upvalues shared by multiple
@@ -847,7 +1016,7 @@ static bool_t push_cached_table( lua_State* L2, uint_t L2_cache_i, lua_State* L,
847 // push a light userdata uniquely representing the table 1016 // push a light userdata uniquely representing the table
848 lua_pushlightuserdata( L2, p); // ... p 1017 lua_pushlightuserdata( L2, p); // ... p
849 1018
850 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); 1019 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring( L2, -1));
851 1020
852 lua_rawget( L2, L2_cache_i); // ... {cached|nil} 1021 lua_rawget( L2, L2_cache_i); // ... {cached|nil}
853 not_found_in_cache = lua_isnil( L2, -1); 1022 not_found_in_cache = lua_isnil( L2, -1);
@@ -1002,6 +1171,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_)
1002 return shortest_; 1171 return shortest_;
1003} 1172}
1004 1173
1174
1005/* 1175/*
1006 * "type", "name" = lanes.nameof( o) 1176 * "type", "name" = lanes.nameof( o)
1007 */ 1177 */
@@ -1049,72 +1219,17 @@ int luaG_nameof( lua_State* L)
1049 return 2; 1219 return 2;
1050} 1220}
1051 1221
1052// function sentinel used to transfer native functions from/to keeper states
1053static int sentinelfunc( lua_State* L)
1054{
1055 return luaL_error( L, "transfer sentinel function for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1)));
1056}
1057 1222
1058/* 1223/*
1059* Push a looked-up native/LuaJIT function. 1224 * Push a looked-up native/LuaJIT function.
1060*/ 1225 */
1061static 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_)
1062{ 1227{
1063 char const* fqn; // L // L2 1228 // get the name of the function we want to send
1064 size_t len; 1229 size_t len;
1065 ASSERT_L( lua_isfunction( L, i)); // ... f ... 1230 char const* fqn = find_lookup_name( L, i, mode_, upName_, &len);
1066 STACK_CHECK( L);
1067 STACK_GROW( L, 3); // up to 3 slots are necessary on error
1068 if( mode_ == eLM_FromKeeper)
1069 {
1070 lua_CFunction f = lua_tocfunction( L, i); // should *always* be sentinelfunc!
1071 ASSERT_L( f == sentinelfunc);
1072 lua_getupvalue( L, i, 1); // ... f ... "f.q.n"
1073 fqn = lua_tolstring( L, -1, &len);
1074 }
1075 else
1076 {
1077 // fetch the name from the source state's lookup table
1078 lua_getfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); // ... f ... {}
1079 ASSERT_L( lua_istable( L, -1));
1080 lua_pushvalue( L, i); // ... f ... {} f
1081 lua_rawget( L, -2); // ... f ... {} "f.q.n"
1082 fqn = lua_tolstring( L, -1, &len);
1083 }
1084 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn));
1085 // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database
1086 lua_pop( L, (mode_ == eLM_FromKeeper) ? 1 : 2); // ... f ...
1087 STACK_MID( L, 0);
1088 if( !fqn)
1089 {
1090 char const *from, *typewhat, *what, *gotchaA, *gotchaB;
1091 // try to discover the name of the function we want to send
1092 lua_getglobal( L, "decoda_name"); // ... f ... decoda_name
1093 from = lua_tostring( L, -1);
1094 lua_pushcfunction( L, luaG_nameof); // ... f ... decoda_name luaG_nameof
1095 lua_pushvalue( L, i); // ... f ... decoda_name luaG_nameof f
1096 lua_call( L, 1, 2); // ... f ... decoda_name "type" "name"|nil
1097 typewhat = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : luaL_typename( L, -2);
1098 // second return value can be nil if the function was not found
1099 // probable reason: the function was removed from the source Lua state before Lanes was required.
1100 if( lua_isnil( L, -1))
1101 {
1102 gotchaA = " referenced by";
1103 gotchaB = "\n(did you remove it from the source Lua state before requiring Lanes?)";
1104 what = upName_;
1105 }
1106 else
1107 {
1108 gotchaA = "";
1109 gotchaB = "";
1110 what = (lua_type( L, -1) == LUA_TSTRING) ? lua_tostring( L, -1) : luaL_typename( L, -1);
1111 }
1112 (void) luaL_error( L, "%s%s '%s' not found in %s origin transfer database.%s", typewhat, gotchaA, what, from ? from : "main", gotchaB);
1113 return;
1114 }
1115 STACK_END( L, 0);
1116 // 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
1117 STACK_CHECK( L2); 1232 STACK_CHECK( L2); // L // L2
1118 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
1119 switch( mode_) 1234 switch( mode_)
1120 { 1235 {
@@ -1125,7 +1240,7 @@ static void lookup_native_func( struct s_Universe* U, lua_State* L2, lua_State*
1125 case eLM_ToKeeper: 1240 case eLM_ToKeeper:
1126 // push a sentinel closure that holds the lookup name as upvalue 1241 // push a sentinel closure that holds the lookup name as upvalue
1127 lua_pushlstring( L2, fqn, len); // "f.q.n" 1242 lua_pushlstring( L2, fqn, len); // "f.q.n"
1128 lua_pushcclosure( L2, sentinelfunc, 1); // f 1243 lua_pushcclosure( L2, func_lookup_sentinel, 1); // f
1129 break; 1244 break;
1130 1245
1131 case eLM_LaneBody: 1246 case eLM_LaneBody:
@@ -1134,15 +1249,26 @@ static void lookup_native_func( struct s_Universe* U, lua_State* L2, lua_State*
1134 ASSERT_L( lua_istable( L2, -1)); 1249 ASSERT_L( lua_istable( L2, -1));
1135 lua_pushlstring( L2, fqn, len); // {} "f.q.n" 1250 lua_pushlstring( L2, fqn, len); // {} "f.q.n"
1136 lua_rawget( L2, -2); // {} f 1251 lua_rawget( L2, -2); // {} f
1137 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))
1138 { 1255 {
1139 char const* from, * to; 1256 char const* from, * to;
1140 lua_getglobal( L, "decoda_name"); // ... f ... decoda_name 1257 lua_getglobal( L, "decoda_name"); // ... f ... decoda_name
1141 from = lua_tostring( L, -1); 1258 from = lua_tostring( L, -1);
1259 lua_pop( L, 1); // ... f ...
1142 lua_getglobal( L2, "decoda_name"); // {} f decoda_name 1260 lua_getglobal( L2, "decoda_name"); // {} f decoda_name
1143 to = lua_tostring( L2, -1); 1261 to = lua_tostring( L2, -1);
1262 lua_pop( L2, 1); // {} f
1144 // 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
1145 (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 );
1146 return; 1272 return;
1147 } 1273 }
1148 lua_remove( L2, -2); // f 1274 lua_remove( L2, -2); // f
@@ -1167,6 +1293,7 @@ static void lookup_native_func( struct s_Universe* U, lua_State* L2, lua_State*
1167 STACK_END( L2, 1); 1293 STACK_END( L2, 1);
1168} 1294}
1169 1295
1296
1170/* 1297/*
1171 * 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.
1172 * 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
@@ -1184,7 +1311,7 @@ static void inter_copy_func( struct s_Universe* U, lua_State* L2, uint_t L2_cach
1184 int n, needToPush; 1311 int n, needToPush;
1185 luaL_Buffer b; 1312 luaL_Buffer b;
1186 ASSERT_L( L2_cache_i != 0); // ... {cache} ... p 1313 ASSERT_L( L2_cache_i != 0); // ... {cache} ... p
1187 STACK_GROW(L,2); 1314 STACK_GROW( L, 2);
1188 STACK_CHECK( L); 1315 STACK_CHECK( L);
1189 1316
1190 // 'lua_dump()' needs the function at top of stack 1317 // 'lua_dump()' needs the function at top of stack
@@ -1226,7 +1353,7 @@ static void inter_copy_func( struct s_Universe* U, lua_State* L2, uint_t L2_cach
1226 lua_Debug ar; 1353 lua_Debug ar;
1227 lua_pushvalue( L, i); // ... b f 1354 lua_pushvalue( L, i); // ... b f
1228 // fills 'name' 'namewhat' and 'linedefined', pops function 1355 // fills 'name' 'namewhat' and 'linedefined', pops function
1229 lua_getinfo(L, ">nS", &ar); // ... b 1356 lua_getinfo( L, ">nS", &ar); // ... b
1230 name = ar.namewhat; 1357 name = ar.namewhat;
1231 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
1232 } 1359 }
@@ -1351,12 +1478,12 @@ static void push_cached_func( struct s_Universe* U, lua_State* L2, uint_t L2_cac
1351 // push a light userdata uniquely representing the function 1478 // push a light userdata uniquely representing the function
1352 lua_pushlightuserdata( L2, aspointer); // ... {cache} ... p 1479 lua_pushlightuserdata( L2, aspointer); // ... {cache} ... p
1353 1480
1354 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring(L2,-1) ); 1481 //fprintf( stderr, "<< ID: %s >>\n", lua_tostring( L2, -1));
1355 1482
1356 lua_pushvalue( L2, -1); // ... {cache} ... p p 1483 lua_pushvalue( L2, -1); // ... {cache} ... p p
1357 lua_rawget( L2, L2_cache_i); // ... {cache} ... p function|nil|true 1484 lua_rawget( L2, L2_cache_i); // ... {cache} ... p function|nil|true
1358 1485
1359 if( lua_isnil(L2,-1)) // function is unknown 1486 if( lua_isnil( L2, -1)) // function is unknown
1360 { 1487 {
1361 lua_pop( L2, 1); // ... {cache} ... p 1488 lua_pop( L2, 1); // ... {cache} ... p
1362 1489
@@ -1371,15 +1498,14 @@ static void push_cached_func( struct s_Universe* U, lua_State* L2, uint_t L2_cac
1371 lua_remove( L2, -2); // ... {cache} ... function 1498 lua_remove( L2, -2); // ... {cache} ... function
1372 } 1499 }
1373 STACK_END( L2, 1); 1500 STACK_END( L2, 1);
1501 ASSERT_L( lua_isfunction( L2, -1));
1374 } 1502 }
1375 else // function is native/LuaJIT: no need to cache 1503 else // function is native/LuaJIT: no need to cache
1376 { 1504 {
1377 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));
1378 } 1508 }
1379
1380 //
1381 // L2 [-1]: function
1382 ASSERT_L( lua_isfunction( L2, -1));
1383} 1509}
1384 1510
1385/* 1511/*
@@ -1396,12 +1522,12 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1396{ 1522{
1397 bool_t ret = TRUE; 1523 bool_t ret = TRUE;
1398 bool_t ignore = FALSE; 1524 bool_t ignore = FALSE;
1399 int val_type = lua_type(L, i); 1525 int val_type = lua_type( L, i);
1400 STACK_GROW( L2, 1); 1526 STACK_GROW( L2, 1);
1401 STACK_CHECK( L2); 1527 STACK_CHECK( L2);
1402 1528
1403 /* Skip the object if it has metatable with { __lanesignore = true } */ 1529 /* Skip the object if it has metatable with { __lanesignore = true } */
1404 if( lua_getmetatable( L, i)) // ... mt 1530 if( lua_getmetatable( L, i)) // ... mt
1405 { 1531 {
1406 lua_getfield( L, -1, "__lanesignore"); // ... mt ignore? 1532 lua_getfield( L, -1, "__lanesignore"); // ... mt ignore?
1407 if( lua_isboolean( L, -1) && lua_toboolean( L, -1)) 1533 if( lua_isboolean( L, -1) && lua_toboolean( L, -1))
@@ -1426,7 +1552,7 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1426 if( lua_isinteger( L, i)) 1552 if( lua_isinteger( L, i))
1427 { 1553 {
1428 lua_Integer v = lua_tointeger( L, i); 1554 lua_Integer v = lua_tointeger( L, i);
1429 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));
1430 lua_pushinteger( L2, v); 1556 lua_pushinteger( L2, v);
1431 break; 1557 break;
1432 } 1558 }
@@ -1449,7 +1575,7 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1449 break; 1575 break;
1450 1576
1451 case LUA_TLIGHTUSERDATA: 1577 case LUA_TLIGHTUSERDATA:
1452 lua_pushlightuserdata( L2, lua_touserdata(L, i)); 1578 lua_pushlightuserdata( L2, lua_touserdata( L, i));
1453 break; 1579 break;
1454 1580
1455 /* The following types are not allowed as table keys */ 1581 /* The following types are not allowed as table keys */
@@ -1525,6 +1651,16 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1525 STACK_CHECK( L); 1651 STACK_CHECK( L);
1526 STACK_CHECK( L2); 1652 STACK_CHECK( L2);
1527 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
1528 /* 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
1529 * reuse the old copy. This allows table upvalues shared by multiple 1665 * reuse the old copy. This allows table upvalues shared by multiple
1530 * 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.
@@ -1539,7 +1675,7 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1539 ASSERT_L( lua_istable( L2, -1)); // from cache 1675 ASSERT_L( lua_istable( L2, -1)); // from cache
1540 break; 1676 break;
1541 } 1677 }
1542 ASSERT_L( lua_istable( L2,-1)); 1678 ASSERT_L( lua_istable( L2, -1));
1543 1679
1544 STACK_GROW( L, 2); 1680 STACK_GROW( L, 2);
1545 STACK_GROW( L2, 2); 1681 STACK_GROW( L2, 2);
@@ -1547,7 +1683,7 @@ static bool_t inter_copy_one_( struct s_Universe* U, lua_State* L2, uint_t L2_ca
1547 lua_pushnil( L); // start iteration 1683 lua_pushnil( L); // start iteration
1548 while( lua_next( L, i)) 1684 while( lua_next( L, i))
1549 { 1685 {
1550 uint_t val_i = lua_gettop(L); 1686 uint_t val_i = lua_gettop( L);
1551 uint_t key_i = val_i - 1; 1687 uint_t key_i = val_i - 1;
1552 1688
1553 // Only basic key types are copied over; others ignored 1689 // Only basic key types are copied over; others ignored
@@ -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)