diff options
Diffstat (limited to 'src/tools.cpp')
-rw-r--r-- | src/tools.cpp | 139 |
1 files changed, 92 insertions, 47 deletions
diff --git a/src/tools.cpp b/src/tools.cpp index 98224ae..103122e 100644 --- a/src/tools.cpp +++ b/src/tools.cpp | |||
@@ -301,7 +301,9 @@ FuncSubType luaG_getfuncsubtype( lua_State *L, int _i) | |||
301 | return FST_FastJIT; | 301 | return FST_FastJIT; |
302 | } | 302 | } |
303 | 303 | ||
304 | static lua_CFunction luaG_tocfunction( lua_State *L, int _i, FuncSubType *_out) | 304 | // ################################################################################################# |
305 | |||
306 | static lua_CFunction luaG_tocfunction(lua_State* L, int _i, FuncSubType* _out) | ||
305 | { | 307 | { |
306 | lua_CFunction p = lua_tocfunction( L, _i); | 308 | lua_CFunction p = lua_tocfunction( L, _i); |
307 | *_out = luaG_getfuncsubtype( L, _i); | 309 | *_out = luaG_getfuncsubtype( L, _i); |
@@ -311,6 +313,8 @@ static lua_CFunction luaG_tocfunction( lua_State *L, int _i, FuncSubType *_out) | |||
311 | // crc64/we of string "LOOKUPCACHE_REGKEY" generated at http://www.nitrxgen.net/hashgen/ | 313 | // crc64/we of string "LOOKUPCACHE_REGKEY" generated at http://www.nitrxgen.net/hashgen/ |
312 | static constexpr UniqueKey LOOKUPCACHE_REGKEY{ 0x837a68dfc6fcb716ull }; | 314 | static constexpr UniqueKey LOOKUPCACHE_REGKEY{ 0x837a68dfc6fcb716ull }; |
313 | 315 | ||
316 | // ################################################################################################# | ||
317 | |||
314 | // inspired from tconcat() in ltablib.c | 318 | // inspired from tconcat() in ltablib.c |
315 | static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length) | 319 | static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length) |
316 | { | 320 | { |
@@ -336,6 +340,8 @@ static char const* luaG_pushFQN( lua_State* L, int t, int last, size_t* length) | |||
336 | return lua_tolstring( L, -1, length); | 340 | return lua_tolstring( L, -1, length); |
337 | } | 341 | } |
338 | 342 | ||
343 | // ################################################################################################# | ||
344 | |||
339 | /* | 345 | /* |
340 | * receives 2 arguments: a name k and an object o | 346 | * receives 2 arguments: a name k and an object o |
341 | * add two entries ["fully.qualified.name"] = o | 347 | * add two entries ["fully.qualified.name"] = o |
@@ -418,7 +424,9 @@ static void update_lookup_entry( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* | |||
418 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 424 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
419 | } | 425 | } |
420 | 426 | ||
421 | static void populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L, int _ctx_base, int _i, int _depth) | 427 | // ################################################################################################# |
428 | |||
429 | static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L, int _ctx_base, int _i, int _depth) | ||
422 | { | 430 | { |
423 | lua_Integer visit_count; | 431 | lua_Integer visit_count; |
424 | // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i | 432 | // slot 2 contains a table that, when concatenated, produces the fully qualified name of scanned elements in the table provided at slot _i |
@@ -541,6 +549,8 @@ static void populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( Universe* U | |||
541 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 549 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
542 | } | 550 | } |
543 | 551 | ||
552 | // ################################################################################################# | ||
553 | |||
544 | /* | 554 | /* |
545 | * create a "fully.qualified.name" <-> function equivalence database | 555 | * create a "fully.qualified.name" <-> function equivalence database |
546 | */ | 556 | */ |
@@ -605,6 +615,8 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_) | |||
605 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); | 615 | DEBUGSPEW_CODE( -- U->debugspew_indent_depth); |
606 | } | 616 | } |
607 | 617 | ||
618 | // ################################################################################################# | ||
619 | |||
608 | /*---=== Inter-state copying ===---*/ | 620 | /*---=== Inter-state copying ===---*/ |
609 | 621 | ||
610 | // crc64/we of string "REG_MTID" generated at http://www.nitrxgen.net/hashgen/ | 622 | // crc64/we of string "REG_MTID" generated at http://www.nitrxgen.net/hashgen/ |
@@ -651,12 +663,15 @@ static lua_Integer get_mt_id( Universe* U, lua_State* L, int i) | |||
651 | return id; | 663 | return id; |
652 | } | 664 | } |
653 | 665 | ||
666 | // ################################################################################################# | ||
667 | |||
654 | // function sentinel used to transfer native functions from/to keeper states | 668 | // function sentinel used to transfer native functions from/to keeper states |
655 | static int func_lookup_sentinel( lua_State* L) | 669 | static int func_lookup_sentinel( lua_State* L) |
656 | { | 670 | { |
657 | return luaL_error( L, "function lookup sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1))); | 671 | return luaL_error( L, "function lookup sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1))); |
658 | } | 672 | } |
659 | 673 | ||
674 | // ################################################################################################# | ||
660 | 675 | ||
661 | // function sentinel used to transfer native table from/to keeper states | 676 | // function sentinel used to transfer native table from/to keeper states |
662 | static int table_lookup_sentinel( lua_State* L) | 677 | static int table_lookup_sentinel( lua_State* L) |
@@ -664,12 +679,16 @@ static int table_lookup_sentinel( lua_State* L) | |||
664 | return luaL_error( L, "table lookup sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1))); | 679 | return luaL_error( L, "table lookup sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1))); |
665 | } | 680 | } |
666 | 681 | ||
682 | // ################################################################################################# | ||
683 | |||
667 | // function sentinel used to transfer cloned full userdata from/to keeper states | 684 | // function sentinel used to transfer cloned full userdata from/to keeper states |
668 | static int userdata_clone_sentinel( lua_State* L) | 685 | static int userdata_clone_sentinel( lua_State* L) |
669 | { | 686 | { |
670 | return luaL_error( L, "userdata clone sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1))); | 687 | return luaL_error( L, "userdata clone sentinel for %s, should never be called", lua_tostring( L, lua_upvalueindex( 1))); |
671 | } | 688 | } |
672 | 689 | ||
690 | // ################################################################################################# | ||
691 | |||
673 | /* | 692 | /* |
674 | * retrieve the name of a function/table in the lookup database | 693 | * retrieve the name of a function/table in the lookup database |
675 | */ | 694 | */ |
@@ -680,7 +699,7 @@ static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char | |||
680 | ASSERT_L( lua_isfunction( L, i) || lua_istable( L, i)); // ... v ... | 699 | ASSERT_L( lua_isfunction( L, i) || lua_istable( L, i)); // ... v ... |
681 | STACK_CHECK_START_REL(L, 0); | 700 | STACK_CHECK_START_REL(L, 0); |
682 | STACK_GROW( L, 3); // up to 3 slots are necessary on error | 701 | STACK_GROW( L, 3); // up to 3 slots are necessary on error |
683 | if( mode_ == eLM_FromKeeper) | 702 | if (mode_ == LookupMode::FromKeeper) |
684 | { | 703 | { |
685 | lua_CFunction f = lua_tocfunction( L, i); // should *always* be func_lookup_sentinel or table_lookup_sentinel! | 704 | lua_CFunction f = lua_tocfunction( L, i); // should *always* be func_lookup_sentinel or table_lookup_sentinel! |
686 | if( f == func_lookup_sentinel || f == table_lookup_sentinel || f == userdata_clone_sentinel) | 705 | if( f == func_lookup_sentinel || f == table_lookup_sentinel || f == userdata_clone_sentinel) |
@@ -707,7 +726,7 @@ static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char | |||
707 | fqn = lua_tolstring( L, -1, len_); | 726 | fqn = lua_tolstring( L, -1, len_); |
708 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn)); | 727 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "function [C] %s \n" INDENT_END, fqn)); |
709 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database | 728 | // popping doesn't invalidate the pointer since this is an interned string gotten from the lookup database |
710 | lua_pop( L, (mode_ == eLM_FromKeeper) ? 1 : 2); // ... v ... | 729 | lua_pop( L, (mode_ == LookupMode::FromKeeper) ? 1 : 2); // ... v ... |
711 | STACK_CHECK( L, 0); | 730 | STACK_CHECK( L, 0); |
712 | if (nullptr == fqn && !lua_istable(L, i)) // raise an error if we try to send an unknown function (but not for tables) | 731 | if (nullptr == fqn && !lua_istable(L, i)) // raise an error if we try to send an unknown function (but not for tables) |
713 | { | 732 | { |
@@ -741,6 +760,7 @@ static char const* find_lookup_name(lua_State* L, int i, LookupMode mode_, char | |||
741 | return fqn; | 760 | return fqn; |
742 | } | 761 | } |
743 | 762 | ||
763 | // ################################################################################################# | ||
744 | 764 | ||
745 | /* | 765 | /* |
746 | * Push a looked-up table, or nothing if we found nothing | 766 | * Push a looked-up table, or nothing if we found nothing |
@@ -763,14 +783,14 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c | |||
763 | (void) luaL_error( L, "internal error: unknown lookup mode"); | 783 | (void) luaL_error( L, "internal error: unknown lookup mode"); |
764 | return false; | 784 | return false; |
765 | 785 | ||
766 | case eLM_ToKeeper: | 786 | case LookupMode::ToKeeper: |
767 | // push a sentinel closure that holds the lookup name as upvalue | 787 | // push a sentinel closure that holds the lookup name as upvalue |
768 | lua_pushlstring( L2, fqn, len); // "f.q.n" | 788 | lua_pushlstring( L2, fqn, len); // "f.q.n" |
769 | lua_pushcclosure( L2, table_lookup_sentinel, 1); // f | 789 | lua_pushcclosure( L2, table_lookup_sentinel, 1); // f |
770 | break; | 790 | break; |
771 | 791 | ||
772 | case eLM_LaneBody: | 792 | case LookupMode::LaneBody: |
773 | case eLM_FromKeeper: | 793 | case LookupMode::FromKeeper: |
774 | LOOKUP_REGKEY.pushValue(L2); // {} | 794 | LOOKUP_REGKEY.pushValue(L2); // {} |
775 | STACK_CHECK( L2, 1); | 795 | STACK_CHECK( L2, 1); |
776 | ASSERT_L( lua_istable( L2, -1)); | 796 | ASSERT_L( lua_istable( L2, -1)); |
@@ -778,7 +798,7 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c | |||
778 | lua_rawget( L2, -2); // {} t | 798 | lua_rawget( L2, -2); // {} t |
779 | // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead) | 799 | // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead) |
780 | // but not when we extract something out of a keeper, as there is nothing to clone! | 800 | // but not when we extract something out of a keeper, as there is nothing to clone! |
781 | if( lua_isnil( L2, -1) && mode_ == eLM_LaneBody) | 801 | if (lua_isnil(L2, -1) && mode_ == LookupMode::LaneBody) |
782 | { | 802 | { |
783 | lua_pop( L2, 2); // | 803 | lua_pop( L2, 2); // |
784 | STACK_CHECK( L2, 0); | 804 | STACK_CHECK( L2, 0); |
@@ -793,9 +813,9 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c | |||
793 | lua_getglobal( L2, "decoda_name"); // {} t decoda_name | 813 | lua_getglobal( L2, "decoda_name"); // {} t decoda_name |
794 | to = lua_tostring( L2, -1); | 814 | to = lua_tostring( L2, -1); |
795 | lua_pop( L2, 1); // {} t | 815 | lua_pop( L2, 1); // {} t |
796 | // 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 | 816 | // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error |
797 | (void) luaL_error( | 817 | (void) luaL_error( |
798 | (mode_ == eLM_FromKeeper) ? L2 : L | 818 | (mode_ == LookupMode::FromKeeper) ? L2 : L |
799 | , "INTERNAL ERROR IN %s: table '%s' not found in %s destination transfer database." | 819 | , "INTERNAL ERROR IN %s: table '%s' not found in %s destination transfer database." |
800 | , from ? from : "main" | 820 | , from ? from : "main" |
801 | , fqn | 821 | , fqn |
@@ -810,6 +830,7 @@ static bool lookup_table(lua_State* L2, lua_State* L, int i, LookupMode mode_, c | |||
810 | return true; | 830 | return true; |
811 | } | 831 | } |
812 | 832 | ||
833 | // ################################################################################################# | ||
813 | 834 | ||
814 | /* | 835 | /* |
815 | * Check if we've already copied the same table from 'L', and | 836 | * Check if we've already copied the same table from 'L', and |
@@ -852,6 +873,7 @@ static bool push_cached_table(lua_State* L2, int L2_cache_i, lua_State* L, int i | |||
852 | return !not_found_in_cache; | 873 | return !not_found_in_cache; |
853 | } | 874 | } |
854 | 875 | ||
876 | // ################################################################################################# | ||
855 | 877 | ||
856 | /* | 878 | /* |
857 | * Return some name helping to identify an object | 879 | * Return some name helping to identify an object |
@@ -998,6 +1020,7 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
998 | return shortest_; | 1020 | return shortest_; |
999 | } | 1021 | } |
1000 | 1022 | ||
1023 | // ################################################################################################# | ||
1001 | 1024 | ||
1002 | /* | 1025 | /* |
1003 | * "type", "name" = lanes.nameof( o) | 1026 | * "type", "name" = lanes.nameof( o) |
@@ -1046,6 +1069,7 @@ int luaG_nameof( lua_State* L) | |||
1046 | return 2; | 1069 | return 2; |
1047 | } | 1070 | } |
1048 | 1071 | ||
1072 | // ################################################################################################# | ||
1049 | 1073 | ||
1050 | /* | 1074 | /* |
1051 | * Push a looked-up native/LuaJIT function. | 1075 | * Push a looked-up native/LuaJIT function. |
@@ -1064,14 +1088,14 @@ static void lookup_native_func(lua_State* L2, lua_State* L, int i, LookupMode mo | |||
1064 | (void) luaL_error( L, "internal error: unknown lookup mode"); | 1088 | (void) luaL_error( L, "internal error: unknown lookup mode"); |
1065 | return; | 1089 | return; |
1066 | 1090 | ||
1067 | case eLM_ToKeeper: | 1091 | case LookupMode::ToKeeper: |
1068 | // push a sentinel closure that holds the lookup name as upvalue | 1092 | // push a sentinel closure that holds the lookup name as upvalue |
1069 | lua_pushlstring( L2, fqn, len); // "f.q.n" | 1093 | lua_pushlstring( L2, fqn, len); // "f.q.n" |
1070 | lua_pushcclosure( L2, func_lookup_sentinel, 1); // f | 1094 | lua_pushcclosure( L2, func_lookup_sentinel, 1); // f |
1071 | break; | 1095 | break; |
1072 | 1096 | ||
1073 | case eLM_LaneBody: | 1097 | case LookupMode::LaneBody: |
1074 | case eLM_FromKeeper: | 1098 | case LookupMode::FromKeeper: |
1075 | LOOKUP_REGKEY.pushValue(L2); // {} | 1099 | LOOKUP_REGKEY.pushValue(L2); // {} |
1076 | STACK_CHECK( L2, 1); | 1100 | STACK_CHECK( L2, 1); |
1077 | ASSERT_L( lua_istable( L2, -1)); | 1101 | ASSERT_L( lua_istable( L2, -1)); |
@@ -1088,9 +1112,9 @@ static void lookup_native_func(lua_State* L2, lua_State* L, int i, LookupMode mo | |||
1088 | lua_getglobal( L2, "decoda_name"); // {} f decoda_name | 1112 | lua_getglobal( L2, "decoda_name"); // {} f decoda_name |
1089 | to = lua_tostring( L2, -1); | 1113 | to = lua_tostring( L2, -1); |
1090 | lua_pop( L2, 1); // {} f | 1114 | lua_pop( L2, 1); // {} f |
1091 | // 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 | 1115 | // when mode_ == LookupMode::FromKeeper, L is a keeper state and L2 is not, therefore L2 is the state where we want to raise the error |
1092 | (void) luaL_error( | 1116 | (void) luaL_error( |
1093 | (mode_ == eLM_FromKeeper) ? L2 : L | 1117 | (mode_ == LookupMode::FromKeeper) ? L2 : L |
1094 | , "%s%s: function '%s' not found in %s destination transfer database." | 1118 | , "%s%s: function '%s' not found in %s destination transfer database." |
1095 | , lua_isnil( L2, -1) ? "" : "INTERNAL ERROR IN " | 1119 | , lua_isnil( L2, -1) ? "" : "INTERNAL ERROR IN " |
1096 | , from ? from : "main" | 1120 | , from ? from : "main" |
@@ -1103,7 +1127,7 @@ static void lookup_native_func(lua_State* L2, lua_State* L, int i, LookupMode mo | |||
1103 | break; | 1127 | break; |
1104 | 1128 | ||
1105 | /* keep it in case I need it someday, who knows... | 1129 | /* keep it in case I need it someday, who knows... |
1106 | case eLM_RawFunctions: | 1130 | case LookupMode::RawFunctions: |
1107 | { | 1131 | { |
1108 | int n; | 1132 | int n; |
1109 | char const* upname; | 1133 | char const* upname; |
@@ -1121,6 +1145,7 @@ static void lookup_native_func(lua_State* L2, lua_State* L, int i, LookupMode mo | |||
1121 | STACK_CHECK( L2, 1); | 1145 | STACK_CHECK( L2, 1); |
1122 | } | 1146 | } |
1123 | 1147 | ||
1148 | // ################################################################################################# | ||
1124 | 1149 | ||
1125 | /* | 1150 | /* |
1126 | * Copy a function over, which has not been found in the cache. | 1151 | * Copy a function over, which has not been found in the cache. |
@@ -1144,12 +1169,14 @@ static char const* lua_type_names[] = | |||
1144 | }; | 1169 | }; |
1145 | static char const* vt_names[] = | 1170 | static char const* vt_names[] = |
1146 | { | 1171 | { |
1147 | "VT_NORMAL" | 1172 | "VT::NORMAL" |
1148 | , "VT_KEY" | 1173 | , "VT::KEY" |
1149 | , "VT_METATABLE" | 1174 | , "VT::METATABLE" |
1150 | }; | 1175 | }; |
1151 | #endif // USE_DEBUG_SPEW() | 1176 | #endif // USE_DEBUG_SPEW() |
1152 | 1177 | ||
1178 | // ################################################################################################# | ||
1179 | |||
1153 | // Lua 5.4.3 style of dumping (see lstrlib.c) | 1180 | // Lua 5.4.3 style of dumping (see lstrlib.c) |
1154 | // we have to do it that way because we can't unbalance the stack between buffer operations | 1181 | // we have to do it that way because we can't unbalance the stack between buffer operations |
1155 | // namely, this means we can't push a function on top of the stack *after* we initialize the buffer! | 1182 | // namely, this means we can't push a function on top of the stack *after* we initialize the buffer! |
@@ -1165,6 +1192,8 @@ static int buf_writer( lua_State* L, void const* b, size_t size, void* ud) | |||
1165 | return 0; | 1192 | return 0; |
1166 | } | 1193 | } |
1167 | 1194 | ||
1195 | // ################################################################################################# | ||
1196 | |||
1168 | static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) | 1197 | static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) |
1169 | { | 1198 | { |
1170 | int n, needToPush; | 1199 | int n, needToPush; |
@@ -1277,7 +1306,7 @@ static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
1277 | #endif // LUA_VERSION_NUM | 1306 | #endif // LUA_VERSION_NUM |
1278 | { | 1307 | { |
1279 | DEBUGSPEW_CODE( fprintf( stderr, "copying value\n")); | 1308 | DEBUGSPEW_CODE( fprintf( stderr, "copying value\n")); |
1280 | if( !inter_copy_one( U, L2, L2_cache_i, L, lua_gettop( L), VT_NORMAL, mode_, upname)) // ... {cache} ... function <upvalues> | 1309 | if( !inter_copy_one( U, L2, L2_cache_i, L, lua_gettop( L), VT::NORMAL, mode_, upname)) // ... {cache} ... function <upvalues> |
1281 | { | 1310 | { |
1282 | luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1)); | 1311 | luaL_error( L, "Cannot copy upvalue type '%s'", luaL_typename( L, -1)); |
1283 | } | 1312 | } |
@@ -1311,6 +1340,8 @@ static void copy_func(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
1311 | STACK_CHECK( L, 0); | 1340 | STACK_CHECK( L, 0); |
1312 | } | 1341 | } |
1313 | 1342 | ||
1343 | // ################################################################################################# | ||
1344 | |||
1314 | /* | 1345 | /* |
1315 | * Check if we've already copied the same function from 'L', and reuse the old | 1346 | * Check if we've already copied the same function from 'L', and reuse the old |
1316 | * copy. | 1347 | * copy. |
@@ -1370,6 +1401,8 @@ static void copy_cached_func(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta | |||
1370 | } | 1401 | } |
1371 | } | 1402 | } |
1372 | 1403 | ||
1404 | // ################################################################################################# | ||
1405 | |||
1373 | static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) | 1406 | static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, LookupMode mode_, char const* upName_) |
1374 | { | 1407 | { |
1375 | STACK_CHECK_START_REL(L, 0); | 1408 | STACK_CHECK_START_REL(L, 0); |
@@ -1389,7 +1422,7 @@ static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lu | |||
1389 | if( lua_isnil( L2, -1)) | 1422 | if( lua_isnil( L2, -1)) |
1390 | { // L2 did not know the metatable | 1423 | { // L2 did not know the metatable |
1391 | lua_pop( L2, 1); // _R[REG_MTID] | 1424 | lua_pop( L2, 1); // _R[REG_MTID] |
1392 | if( inter_copy_one( U, L2, L2_cache_i, L, lua_gettop( L), VT_METATABLE, mode_, upName_)) // _R[REG_MTID] mt | 1425 | if (inter_copy_one(U, L2, L2_cache_i, L, lua_gettop( L), VT::METATABLE, mode_, upName_)) // _R[REG_MTID] mt |
1393 | { | 1426 | { |
1394 | STACK_CHECK( L2, 2); | 1427 | STACK_CHECK( L2, 2); |
1395 | // mt_id -> metatable | 1428 | // mt_id -> metatable |
@@ -1419,13 +1452,15 @@ static bool push_cached_metatable(Universe* U, lua_State* L2, int L2_cache_i, lu | |||
1419 | return false; | 1452 | return false; |
1420 | } | 1453 | } |
1421 | 1454 | ||
1422 | static void inter_copy_keyvaluepair(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, enum e_vt vt, LookupMode mode_, char const* upName_) | 1455 | // ################################################################################################# |
1456 | |||
1457 | static void inter_copy_keyvaluepair(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, VT vt_, LookupMode mode_, char const* upName_) | ||
1423 | { | 1458 | { |
1424 | int val_i = lua_gettop(L); | 1459 | int val_i = lua_gettop(L); |
1425 | int key_i = val_i - 1; | 1460 | int key_i = val_i - 1; |
1426 | 1461 | ||
1427 | // Only basic key types are copied over; others ignored | 1462 | // Only basic key types are copied over; others ignored |
1428 | if( inter_copy_one( U, L2, 0 /*key*/, L, key_i, VT_KEY, mode_, upName_)) | 1463 | if (inter_copy_one(U, L2, 0 /*key*/, L, key_i, VT::KEY, mode_, upName_)) |
1429 | { | 1464 | { |
1430 | char* valPath = (char*) upName_; | 1465 | char* valPath = (char*) upName_; |
1431 | if( U->verboseErrors) | 1466 | if( U->verboseErrors) |
@@ -1471,18 +1506,20 @@ static void inter_copy_keyvaluepair(Universe* U, lua_State* L2, int L2_cache_i, | |||
1471 | * Contents of metatables are copied with cache checking; | 1506 | * Contents of metatables are copied with cache checking; |
1472 | * important to detect loops. | 1507 | * important to detect loops. |
1473 | */ | 1508 | */ |
1474 | if( inter_copy_one( U, L2, L2_cache_i, L, val_i, VT_NORMAL, mode_, valPath)) | 1509 | if (inter_copy_one(U, L2, L2_cache_i, L, val_i, VT::NORMAL, mode_, valPath)) |
1475 | { | 1510 | { |
1476 | ASSERT_L( lua_istable( L2, -3)); | 1511 | ASSERT_L( lua_istable( L2, -3)); |
1477 | lua_rawset( L2, -3); // add to table (pops key & val) | 1512 | lua_rawset( L2, -3); // add to table (pops key & val) |
1478 | } | 1513 | } |
1479 | else | 1514 | else |
1480 | { | 1515 | { |
1481 | luaL_error( L, "Unable to copy %s entry '%s' because of value is of type '%s'", (vt == VT_NORMAL) ? "table" : "metatable", valPath, luaL_typename( L, val_i)); | 1516 | luaL_error(L, "Unable to copy %s entry '%s' because of value is of type '%s'", (vt_ == VT::NORMAL) ? "table" : "metatable", valPath, luaL_typename(L, val_i)); |
1482 | } | 1517 | } |
1483 | } | 1518 | } |
1484 | } | 1519 | } |
1485 | 1520 | ||
1521 | // ################################################################################################# | ||
1522 | |||
1486 | /* | 1523 | /* |
1487 | * The clone cache is a weak valued table listing all clones, indexed by their userdatapointer | 1524 | * The clone cache is a weak valued table listing all clones, indexed by their userdatapointer |
1488 | * fnv164 of string "CLONABLES_CACHE_KEY" generated at https://www.pelock.com/products/hash-calculator | 1525 | * fnv164 of string "CLONABLES_CACHE_KEY" generated at https://www.pelock.com/products/hash-calculator |
@@ -1541,9 +1578,9 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
1541 | // create the clone userdata with the required number of uservalue slots | 1578 | // create the clone userdata with the required number of uservalue slots |
1542 | clone = lua_newuserdatauv( L2, userdata_size, uvi); // ... u | 1579 | clone = lua_newuserdatauv( L2, userdata_size, uvi); // ... u |
1543 | // copy the metatable in the target state, and give it to the clone we put there | 1580 | // copy the metatable in the target state, and give it to the clone we put there |
1544 | if( inter_copy_one( U, L2, L2_cache_i, L, mt, VT_NORMAL, mode_, upName_)) // ... u mt|sentinel | 1581 | if (inter_copy_one(U, L2, L2_cache_i, L, mt, VT::NORMAL, mode_, upName_)) // ... u mt|sentinel |
1545 | { | 1582 | { |
1546 | if( eLM_ToKeeper == mode_) // ... u sentinel | 1583 | if( LookupMode::ToKeeper == mode_) // ... u sentinel |
1547 | { | 1584 | { |
1548 | ASSERT_L( lua_tocfunction( L2, -1) == table_lookup_sentinel); | 1585 | ASSERT_L( lua_tocfunction( L2, -1) == table_lookup_sentinel); |
1549 | // we want to create a new closure with a 'clone sentinel' function, where the upvalues are the userdata and the metatable fqn | 1586 | // we want to create a new closure with a 'clone sentinel' function, where the upvalues are the userdata and the metatable fqn |
@@ -1568,21 +1605,21 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
1568 | lua_pushvalue( L2, -2); // ... u source u | 1605 | lua_pushvalue( L2, -2); // ... u source u |
1569 | lua_rawset( L2, L2_cache_i); // ... u | 1606 | lua_rawset( L2, L2_cache_i); // ... u |
1570 | // make sure we have the userdata now | 1607 | // make sure we have the userdata now |
1571 | if( eLM_ToKeeper == mode_) // ... userdata_clone_sentinel | 1608 | if( LookupMode::ToKeeper == mode_) // ... userdata_clone_sentinel |
1572 | { | 1609 | { |
1573 | lua_getupvalue( L2, -1, 2); // ... userdata_clone_sentinel u | 1610 | lua_getupvalue( L2, -1, 2); // ... userdata_clone_sentinel u |
1574 | } | 1611 | } |
1575 | // assign uservalues | 1612 | // assign uservalues |
1576 | while( uvi > 0) | 1613 | while( uvi > 0) |
1577 | { | 1614 | { |
1578 | inter_copy_one( U, L2, L2_cache_i, L, lua_absindex( L, -1), VT_NORMAL, mode_, upName_); // ... u uv | 1615 | inter_copy_one(U, L2, L2_cache_i, L, lua_absindex( L, -1), VT::NORMAL, mode_, upName_); // ... u uv |
1579 | lua_pop( L, 1); // ... mt __lanesclone [uv]* | 1616 | lua_pop( L, 1); // ... mt __lanesclone [uv]* |
1580 | // this pops the value from the stack | 1617 | // this pops the value from the stack |
1581 | lua_setiuservalue( L2, -2, uvi); // ... u | 1618 | lua_setiuservalue( L2, -2, uvi); // ... u |
1582 | -- uvi; | 1619 | -- uvi; |
1583 | } | 1620 | } |
1584 | // when we are done, all uservalues are popped from the source stack, and we want only the single transferred value in the destination | 1621 | // when we are done, all uservalues are popped from the source stack, and we want only the single transferred value in the destination |
1585 | if( eLM_ToKeeper == mode_) // ... userdata_clone_sentinel u | 1622 | if( LookupMode::ToKeeper == mode_) // ... userdata_clone_sentinel u |
1586 | { | 1623 | { |
1587 | lua_pop( L2, 1); // ... userdata_clone_sentinel | 1624 | lua_pop( L2, 1); // ... userdata_clone_sentinel |
1588 | } | 1625 | } |
@@ -1602,11 +1639,13 @@ static bool copyclone(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, | |||
1602 | return true; | 1639 | return true; |
1603 | } | 1640 | } |
1604 | 1641 | ||
1605 | static bool inter_copy_userdata(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, enum e_vt vt, LookupMode mode_, char const* upName_) | 1642 | // ################################################################################################# |
1643 | |||
1644 | static bool inter_copy_userdata(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, VT vt_, LookupMode mode_, char const* upName_) | ||
1606 | { | 1645 | { |
1607 | STACK_CHECK_START_REL(L, 0); | 1646 | STACK_CHECK_START_REL(L, 0); |
1608 | STACK_CHECK_START_REL(L2, 0); | 1647 | STACK_CHECK_START_REL(L2, 0); |
1609 | if( vt == VT_KEY) | 1648 | if (vt_ == VT::KEY) |
1610 | { | 1649 | { |
1611 | return false; | 1650 | return false; |
1612 | } | 1651 | } |
@@ -1650,9 +1689,11 @@ static bool inter_copy_userdata(Universe* U, lua_State* L2, int L2_cache_i, lua_ | |||
1650 | return true; | 1689 | return true; |
1651 | } | 1690 | } |
1652 | 1691 | ||
1653 | static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int source_i_, enum e_vt vt, LookupMode mode_, char const* upName_) | 1692 | // ################################################################################################# |
1693 | |||
1694 | static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int source_i_, VT vt_, LookupMode mode_, char const* upName_) | ||
1654 | { | 1695 | { |
1655 | if( vt == VT_KEY) | 1696 | if (vt_ == VT::KEY) |
1656 | { | 1697 | { |
1657 | return false; | 1698 | return false; |
1658 | } | 1699 | } |
@@ -1709,7 +1750,7 @@ static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_ | |||
1709 | // transfer and assign uservalues | 1750 | // transfer and assign uservalues |
1710 | while( uvi > 0) | 1751 | while( uvi > 0) |
1711 | { | 1752 | { |
1712 | inter_copy_one( U, L2, L2_cache_i, L, lua_absindex( L, -1), vt, mode_, upName_); // ... mt u uv | 1753 | inter_copy_one(U, L2, L2_cache_i, L, lua_absindex(L, -1), vt_, mode_, upName_); // ... mt u uv |
1713 | lua_pop( L, 1); // ... u [uv]* | 1754 | lua_pop( L, 1); // ... u [uv]* |
1714 | // this pops the value from the stack | 1755 | // this pops the value from the stack |
1715 | lua_setiuservalue( L2, -2, uvi); // ... mt u | 1756 | lua_setiuservalue( L2, -2, uvi); // ... mt u |
@@ -1743,9 +1784,11 @@ static bool inter_copy_function(Universe* U, lua_State* L2, int L2_cache_i, lua_ | |||
1743 | return true; | 1784 | return true; |
1744 | } | 1785 | } |
1745 | 1786 | ||
1746 | static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, enum e_vt vt, LookupMode mode_, char const* upName_) | 1787 | // ################################################################################################# |
1788 | |||
1789 | static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, VT vt_, LookupMode mode_, char const* upName_) | ||
1747 | { | 1790 | { |
1748 | if( vt == VT_KEY) | 1791 | if (vt_ == VT::KEY) |
1749 | { | 1792 | { |
1750 | return false; | 1793 | return false; |
1751 | } | 1794 | } |
@@ -1787,7 +1830,7 @@ static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta | |||
1787 | while( lua_next( L, i)) | 1830 | while( lua_next( L, i)) |
1788 | { | 1831 | { |
1789 | // need a function to prevent overflowing the stack with verboseErrors-induced alloca() | 1832 | // need a function to prevent overflowing the stack with verboseErrors-induced alloca() |
1790 | inter_copy_keyvaluepair( U, L2, L2_cache_i, L, vt, mode_, upName_); | 1833 | inter_copy_keyvaluepair(U, L2, L2_cache_i, L, vt_, mode_, upName_); |
1791 | lua_pop( L, 1); // pop value (next round) | 1834 | lua_pop( L, 1); // pop value (next round) |
1792 | } | 1835 | } |
1793 | STACK_CHECK( L, 0); | 1836 | STACK_CHECK( L, 0); |
@@ -1803,6 +1846,8 @@ static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta | |||
1803 | return true; | 1846 | return true; |
1804 | } | 1847 | } |
1805 | 1848 | ||
1849 | // ################################################################################################# | ||
1850 | |||
1806 | /* | 1851 | /* |
1807 | * Copies a value from 'L' state (at index 'i') to 'L2' state. Does not remove | 1852 | * Copies a value from 'L' state (at index 'i') to 'L2' state. Does not remove |
1808 | * the original value. | 1853 | * the original value. |
@@ -1813,7 +1858,7 @@ static bool inter_copy_table(Universe* U, lua_State* L2, int L2_cache_i, lua_Sta | |||
1813 | * | 1858 | * |
1814 | * Returns true if value was pushed, false if its type is non-supported. | 1859 | * Returns true if value was pushed, false if its type is non-supported. |
1815 | */ | 1860 | */ |
1816 | bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, enum e_vt vt, LookupMode mode_, char const* upName_) | 1861 | bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, int i, VT vt_, LookupMode mode_, char const* upName_) |
1817 | { | 1862 | { |
1818 | bool ret{ true }; | 1863 | bool ret{ true }; |
1819 | int val_type = lua_type( L, i); | 1864 | int val_type = lua_type( L, i); |
@@ -1824,7 +1869,7 @@ bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, in | |||
1824 | 1869 | ||
1825 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "inter_copy_one()\n" INDENT_END)); | 1870 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "inter_copy_one()\n" INDENT_END)); |
1826 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); | 1871 | DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); |
1827 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s %s: " INDENT_END, lua_type_names[val_type], vt_names[vt])); | 1872 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s %s: " INDENT_END, lua_type_names[val_type], vt_names[static_cast<int>(vt_)])); |
1828 | 1873 | ||
1829 | // Non-POD can be skipped if its metatable contains { __lanesignore = true } | 1874 | // Non-POD can be skipped if its metatable contains { __lanesignore = true } |
1830 | if( ((1 << val_type) & pod_mask) == 0) | 1875 | if( ((1 << val_type) & pod_mask) == 0) |
@@ -1894,11 +1939,11 @@ bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, in | |||
1894 | /* The following types are not allowed as table keys */ | 1939 | /* The following types are not allowed as table keys */ |
1895 | 1940 | ||
1896 | case LUA_TUSERDATA: | 1941 | case LUA_TUSERDATA: |
1897 | ret = inter_copy_userdata( U, L2, L2_cache_i, L, i, vt, mode_, upName_); | 1942 | ret = inter_copy_userdata(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); |
1898 | break; | 1943 | break; |
1899 | 1944 | ||
1900 | case LUA_TNIL: | 1945 | case LUA_TNIL: |
1901 | if( vt == VT_KEY) | 1946 | if (vt_ == VT::KEY) |
1902 | { | 1947 | { |
1903 | ret = false; | 1948 | ret = false; |
1904 | break; | 1949 | break; |
@@ -1907,11 +1952,11 @@ bool inter_copy_one(Universe* U, lua_State* L2, int L2_cache_i, lua_State* L, in | |||
1907 | break; | 1952 | break; |
1908 | 1953 | ||
1909 | case LUA_TFUNCTION: | 1954 | case LUA_TFUNCTION: |
1910 | ret = inter_copy_function( U, L2, L2_cache_i, L, i, vt, mode_, upName_); | 1955 | ret = inter_copy_function(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); |
1911 | break; | 1956 | break; |
1912 | 1957 | ||
1913 | case LUA_TTABLE: | 1958 | case LUA_TTABLE: |
1914 | ret = inter_copy_table( U, L2, L2_cache_i, L, i, vt, mode_, upName_); | 1959 | ret = inter_copy_table(U, L2, L2_cache_i, L, i, vt_, mode_, upName_); |
1915 | break; | 1960 | break; |
1916 | 1961 | ||
1917 | /* The following types cannot be copied */ | 1962 | /* The following types cannot be copied */ |
@@ -1973,7 +2018,7 @@ int luaG_inter_copy(Universe* U, lua_State* L, lua_State* L2, int n, LookupMode | |||
1973 | { | 2018 | { |
1974 | sprintf( tmpBuf, "arg_%d", j); | 2019 | sprintf( tmpBuf, "arg_%d", j); |
1975 | } | 2020 | } |
1976 | copyok = inter_copy_one( U, L2, top_L2 + 1, L, i, VT_NORMAL, mode_, pBuf); // ... cache {}n | 2021 | copyok = inter_copy_one(U, L2, top_L2 + 1, L, i, VT::NORMAL, mode_, pBuf); // ... cache {}n |
1977 | if( !copyok) | 2022 | if( !copyok) |
1978 | { | 2023 | { |
1979 | break; | 2024 | break; |
@@ -2019,7 +2064,7 @@ int luaG_inter_copy_package( Universe* U, lua_State* L, lua_State* L2, int packa | |||
2019 | lua_pushfstring( L, "expected package as table, got %s", luaL_typename( L, package_idx_)); | 2064 | lua_pushfstring( L, "expected package as table, got %s", luaL_typename( L, package_idx_)); |
2020 | STACK_CHECK( L, 1); | 2065 | STACK_CHECK( L, 1); |
2021 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later | 2066 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later |
2022 | return ( mode_ == eLM_LaneBody) ? lua_error( L) : 1; | 2067 | return (mode_ == LookupMode::LaneBody) ? lua_error(L) : 1; |
2023 | } | 2068 | } |
2024 | lua_getglobal( L2, "package"); | 2069 | lua_getglobal( L2, "package"); |
2025 | if( !lua_isnil( L2, -1)) // package library not loaded: do nothing | 2070 | if( !lua_isnil( L2, -1)) // package library not loaded: do nothing |
@@ -2029,7 +2074,7 @@ int luaG_inter_copy_package( Universe* U, lua_State* L, lua_State* L2, int packa | |||
2029 | // but don't copy it anyway, as the function names change depending on the slot index! | 2074 | // but don't copy it anyway, as the function names change depending on the slot index! |
2030 | // users should provide an on_state_create function to setup custom loaders instead | 2075 | // users should provide an on_state_create function to setup custom loaders instead |
2031 | // don't copy package.preload in keeper states (they don't know how to translate functions) | 2076 | // don't copy package.preload in keeper states (they don't know how to translate functions) |
2032 | char const* entries[] = { "path", "cpath", (mode_ == eLM_LaneBody) ? "preload" : nullptr /*, (LUA_VERSION_NUM == 501) ? "loaders" : "searchers"*/, nullptr }; | 2077 | char const* entries[] = { "path", "cpath", (mode_ == LookupMode::LaneBody) ? "preload" : nullptr /*, (LUA_VERSION_NUM == 501) ? "loaders" : "searchers"*/, nullptr }; |
2033 | for( i = 0; entries[i]; ++ i) | 2078 | for( i = 0; entries[i]; ++ i) |
2034 | { | 2079 | { |
2035 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "package.%s\n" INDENT_END, entries[i])); | 2080 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "package.%s\n" INDENT_END, entries[i])); |