diff options
Diffstat (limited to 'src/tools.cpp')
-rw-r--r-- | src/tools.cpp | 192 |
1 files changed, 106 insertions, 86 deletions
diff --git a/src/tools.cpp b/src/tools.cpp index c995fdd..ad706be 100644 --- a/src/tools.cpp +++ b/src/tools.cpp | |||
@@ -38,7 +38,7 @@ THE SOFTWARE. | |||
38 | // functions implemented in deep.c | 38 | // functions implemented in deep.c |
39 | extern void push_registry_subtable( lua_State* L, UniqueKey key_); | 39 | extern void push_registry_subtable( lua_State* L, UniqueKey key_); |
40 | 40 | ||
41 | DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); | 41 | DEBUGSPEW_CODE(char const* const DebugSpewIndentScope::debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); |
42 | 42 | ||
43 | 43 | ||
44 | // ################################################################################################ | 44 | // ################################################################################################ |
@@ -348,7 +348,7 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L | |||
348 | char const* prevName; | 348 | char const* prevName; |
349 | DEBUGSPEW_CODE(char const *newName); | 349 | DEBUGSPEW_CODE(char const *newName); |
350 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "update_lookup_entry()\n" INDENT_END)); | 350 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "update_lookup_entry()\n" INDENT_END)); |
351 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); | 351 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
352 | 352 | ||
353 | STACK_CHECK_START_REL(L, 0); | 353 | STACK_CHECK_START_REL(L, 0); |
354 | // first, raise an error if the function is already known | 354 | // first, raise an error if the function is already known |
@@ -408,7 +408,6 @@ static void update_lookup_entry(DEBUGSPEW_PARAM_COMMA( Universe* U) lua_State* L | |||
408 | } | 408 | } |
409 | -- _depth; | 409 | -- _depth; |
410 | STACK_CHECK(L, -1); | 410 | STACK_CHECK(L, -1); |
411 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); | ||
412 | } | 411 | } |
413 | 412 | ||
414 | // ################################################################################################# | 413 | // ################################################################################################# |
@@ -423,7 +422,7 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) | |||
423 | // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search) | 422 | // we need to remember subtables to process them after functions encountered at the current depth (breadth-first search) |
424 | int const breadth_first_cache = lua_gettop( L) + 1; | 423 | int const breadth_first_cache = lua_gettop( L) + 1; |
425 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "populate_func_lookup_table_recur()\n" INDENT_END)); | 424 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "populate_func_lookup_table_recur()\n" INDENT_END)); |
426 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); | 425 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
427 | 426 | ||
428 | STACK_GROW( L, 6); | 427 | STACK_GROW( L, 6); |
429 | // slot _i contains a table where we search for functions (or a full userdata with a metatable) | 428 | // slot _i contains a table where we search for functions (or a full userdata with a metatable) |
@@ -445,7 +444,6 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) | |||
445 | if( visit_count > 0) | 444 | if( visit_count > 0) |
446 | { | 445 | { |
447 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "already visited\n" INDENT_END)); | 446 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "already visited\n" INDENT_END)); |
448 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); | ||
449 | return; | 447 | return; |
450 | } | 448 | } |
451 | 449 | ||
@@ -500,7 +498,7 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) | |||
500 | { | 498 | { |
501 | DEBUGSPEW_CODE( char const* key = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : "not a string"); | 499 | DEBUGSPEW_CODE( char const* key = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : "not a string"); |
502 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "table '%s'\n" INDENT_END, key)); | 500 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "table '%s'\n" INDENT_END, key)); |
503 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); | 501 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
504 | // un-visit this table in case we do need to process it | 502 | // un-visit this table in case we do need to process it |
505 | lua_pushvalue( L, -1); // ... {_i} {bfc} k {} {} | 503 | lua_pushvalue( L, -1); // ... {_i} {bfc} k {} {} |
506 | lua_rawget( L, cache); // ... {_i} {bfc} k {} n | 504 | lua_rawget( L, cache); // ... {_i} {bfc} k {} n |
@@ -523,7 +521,6 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) | |||
523 | populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( U) L, _ctx_base, lua_gettop( L), _depth); | 521 | populate_func_lookup_table_recur( DEBUGSPEW_PARAM_COMMA( U) L, _ctx_base, lua_gettop( L), _depth); |
524 | lua_pop( L, 1); // ... {_i} {bfc} k | 522 | lua_pop( L, 1); // ... {_i} {bfc} k |
525 | STACK_CHECK( L, 2); | 523 | STACK_CHECK( L, 2); |
526 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); | ||
527 | } | 524 | } |
528 | // remove table name from fqn stack | 525 | // remove table name from fqn stack |
529 | lua_pushnil( L); // ... {_i} {bfc} nil | 526 | lua_pushnil( L); // ... {_i} {bfc} nil |
@@ -533,7 +530,6 @@ static void populate_func_lookup_table_recur(DEBUGSPEW_PARAM_COMMA(Universe* U) | |||
533 | lua_pop( L, 1); // ... {_i} | 530 | lua_pop( L, 1); // ... {_i} |
534 | STACK_CHECK( L, 0); | 531 | STACK_CHECK( L, 0); |
535 | // we are done // ... {_i} {bfc} | 532 | // we are done // ... {_i} {bfc} |
536 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); | ||
537 | } | 533 | } |
538 | 534 | ||
539 | // ################################################################################################# | 535 | // ################################################################################################# |
@@ -548,8 +544,8 @@ void populate_func_lookup_table(lua_State* L, int i_, char const* name_) | |||
548 | int start_depth = 0; | 544 | int start_depth = 0; |
549 | DEBUGSPEW_CODE( Universe* U = universe_get( L)); | 545 | DEBUGSPEW_CODE( Universe* U = universe_get( L)); |
550 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "nullptr")); | 546 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: populate_func_lookup_table('%s')\n" INDENT_END, L, name_ ? name_ : "nullptr")); |
551 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); | 547 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
552 | STACK_GROW( L, 3); | 548 | STACK_GROW(L, 3); |
553 | STACK_CHECK_START_REL(L, 0); | 549 | STACK_CHECK_START_REL(L, 0); |
554 | LOOKUP_REGKEY.pushValue(L); // {} | 550 | LOOKUP_REGKEY.pushValue(L); // {} |
555 | STACK_CHECK( L, 1); | 551 | STACK_CHECK( L, 1); |
@@ -599,7 +595,6 @@ void populate_func_lookup_table(lua_State* L, int i_, char const* name_) | |||
599 | (void) luaL_error( L, "unsupported module type %s", lua_typename( L, lua_type( L, in_base))); | 595 | (void) luaL_error( L, "unsupported module type %s", lua_typename( L, lua_type( L, in_base))); |
600 | } | 596 | } |
601 | STACK_CHECK( L, 0); | 597 | STACK_CHECK( L, 0); |
602 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); | ||
603 | } | 598 | } |
604 | 599 | ||
605 | // ################################################################################################# | 600 | // ################################################################################################# |
@@ -1782,9 +1777,8 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1782 | else // regular function | 1777 | else // regular function |
1783 | { | 1778 | { |
1784 | DEBUGSPEW_CODE(fprintf( stderr, "FUNCTION %s\n", name)); | 1779 | DEBUGSPEW_CODE(fprintf( stderr, "FUNCTION %s\n", name)); |
1785 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); | 1780 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
1786 | copy_cached_func(); // ... f | 1781 | copy_cached_func(); // ... f |
1787 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); | ||
1788 | } | 1782 | } |
1789 | STACK_CHECK(L2, 1); | 1783 | STACK_CHECK(L2, 1); |
1790 | STACK_CHECK(L1, 0); | 1784 | STACK_CHECK(L1, 0); |
@@ -1872,13 +1866,14 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1872 | STACK_CHECK_START_REL(L1, 0); // L1 // L2 | 1866 | STACK_CHECK_START_REL(L1, 0); // L1 // L2 |
1873 | STACK_CHECK_START_REL(L2, 0); // L1 // L2 | 1867 | STACK_CHECK_START_REL(L2, 0); // L1 // L2 |
1874 | 1868 | ||
1875 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "inter_copy_one()\n" INDENT_END)); | 1869 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "inter_copy_one()\n" INDENT_END)); |
1876 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); | 1870 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
1877 | DEBUGSPEW_CODE(fprintf( stderr, INDENT_BEGIN "%s %s: " INDENT_END, lua_type_names[val_type], vt_names[static_cast<int>(vt)])); | ||
1878 | 1871 | ||
1879 | // Non-POD can be skipped if its metatable contains { __lanesignore = true } | ||
1880 | LuaType val_type{ lua_type_as_enum(L1, L1_i) }; | 1872 | LuaType val_type{ lua_type_as_enum(L1, L1_i) }; |
1881 | if( ((1 << static_cast<int>(val_type)) & pod_mask) == 0) | 1873 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "%s %s: " INDENT_END, lua_type_names[static_cast<int>(val_type)], vt_names[static_cast<int>(vt)])); |
1874 | |||
1875 | // Non-POD can be skipped if its metatable contains { __lanesignore = true } | ||
1876 | if (((1 << static_cast<int>(val_type)) & pod_mask) == 0) | ||
1882 | { | 1877 | { |
1883 | if (lua_getmetatable(L1, L1_i)) // ... mt | 1878 | if (lua_getmetatable(L1, L1_i)) // ... mt |
1884 | { | 1879 | { |
@@ -1974,8 +1969,6 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1974 | break; | 1969 | break; |
1975 | } | 1970 | } |
1976 | 1971 | ||
1977 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); | ||
1978 | |||
1979 | STACK_CHECK(L2, ret ? 1 : 0); | 1972 | STACK_CHECK(L2, ret ? 1 : 0); |
1980 | STACK_CHECK(L1, 0); | 1973 | STACK_CHECK(L1, 0); |
1981 | return ret; | 1974 | return ret; |
@@ -1983,30 +1976,25 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
1983 | 1976 | ||
1984 | // ################################################################################################# | 1977 | // ################################################################################################# |
1985 | 1978 | ||
1986 | /* | 1979 | // Akin to 'lua_xmove' but copies values between _any_ Lua states. |
1987 | * Akin to 'lua_xmove' but copies values between _any_ Lua states. | 1980 | // NOTE: Both the states must be solely in the current OS thread's possession. |
1988 | * | 1981 | [[nodiscard]] InterCopyResult InterCopyContext::inter_copy(int n_) const |
1989 | * NOTE: Both the states must be solely in the current OS thread's posession. | ||
1990 | * | ||
1991 | * Note: Parameters are in this order ('L' = from first) to be same as 'lua_xmove'. | ||
1992 | */ | ||
1993 | [[nodiscard]] InterCopyResult luaG_inter_copy(Universe* U, Source L, Dest L2, int n, LookupMode mode_) | ||
1994 | { | 1982 | { |
1995 | int const top_L{ lua_gettop(L) }; // ... {}n | 1983 | _ASSERT_L(L1, vt == VT::NORMAL); |
1996 | 1984 | ||
1997 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "luaG_inter_copy()\n" INDENT_END)); | 1985 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "InterCopyContext::inter_copy()\n" INDENT_END)); |
1998 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); | 1986 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
1999 | 1987 | ||
2000 | if (n > top_L) | 1988 | int const top_L1{ lua_gettop(L1) }; |
1989 | if (n_ > top_L1) | ||
2001 | { | 1990 | { |
2002 | // requesting to copy more than is available? | 1991 | // requesting to copy more than is available? |
2003 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "nothing to copy()\n" INDENT_END)); | 1992 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "nothing to copy()\n" INDENT_END)); |
2004 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); | ||
2005 | return InterCopyResult::NotEnoughValues; | 1993 | return InterCopyResult::NotEnoughValues; |
2006 | } | 1994 | } |
2007 | 1995 | ||
2008 | STACK_CHECK_START_REL(L2, 0); | 1996 | STACK_CHECK_START_REL(L2, 0); |
2009 | STACK_GROW(L2, n + 1); | 1997 | STACK_GROW(L2, n_ + 1); |
2010 | 1998 | ||
2011 | /* | 1999 | /* |
2012 | * Make a cache table for the duration of this copy. Collects tables and | 2000 | * Make a cache table for the duration of this copy. Collects tables and |
@@ -2018,10 +2006,10 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
2018 | 2006 | ||
2019 | char tmpBuf[16]; | 2007 | char tmpBuf[16]; |
2020 | char const* const pBuf{ U->verboseErrors ? tmpBuf : "?" }; | 2008 | char const* const pBuf{ U->verboseErrors ? tmpBuf : "?" }; |
2021 | InterCopyContext c{ U, L2, L, CacheIndex{ top_L2 + 1 }, {}, VT::NORMAL, mode_, pBuf }; | 2009 | InterCopyContext c{ U, L2, L1, CacheIndex{ top_L2 + 1 }, {}, VT::NORMAL, mode, pBuf }; |
2022 | bool copyok{ true }; | 2010 | bool copyok{ true }; |
2023 | STACK_CHECK_START_REL(L, 0); | 2011 | STACK_CHECK_START_REL(L1, 0); |
2024 | for (int i = top_L - n + 1, j = 1; i <= top_L; ++i, ++j) | 2012 | for (int i{ top_L1 - n_ + 1 }, j{ 1 }; i <= top_L1; ++i, ++j) |
2025 | { | 2013 | { |
2026 | if (U->verboseErrors) | 2014 | if (U->verboseErrors) |
2027 | { | 2015 | { |
@@ -2034,13 +2022,11 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
2034 | break; | 2022 | break; |
2035 | } | 2023 | } |
2036 | } | 2024 | } |
2037 | STACK_CHECK(L, 0); | 2025 | STACK_CHECK(L1, 0); |
2038 | |||
2039 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); | ||
2040 | 2026 | ||
2041 | if (copyok) | 2027 | if (copyok) |
2042 | { | 2028 | { |
2043 | STACK_CHECK(L2, n + 1); | 2029 | STACK_CHECK(L2, n_ + 1); |
2044 | // Remove the cache table. Persistent caching would cause i.e. multiple | 2030 | // Remove the cache table. Persistent caching would cause i.e. multiple |
2045 | // messages passed in the same table to use the same table also in receiving end. | 2031 | // messages passed in the same table to use the same table also in receiving end. |
2046 | lua_remove(L2, top_L2 + 1); | 2032 | lua_remove(L2, top_L2 + 1); |
@@ -2055,74 +2041,108 @@ static constexpr UniqueKey CLONABLES_CACHE_KEY{ 0xD04EE018B3DEE8F5ull }; | |||
2055 | 2041 | ||
2056 | // ################################################################################################# | 2042 | // ################################################################################################# |
2057 | 2043 | ||
2058 | [[nodiscard]] InterCopyResult luaG_inter_move(Universe* U, Source L, Dest L2, int n_, LookupMode mode_) | 2044 | [[nodiscard]] InterCopyResult InterCopyContext::inter_move(int n_) const |
2059 | { | 2045 | { |
2060 | InterCopyResult const ret{ luaG_inter_copy(U, L, L2, n_, mode_) }; | 2046 | InterCopyResult const ret{ inter_copy(n_) }; |
2061 | lua_pop( L, n_); | 2047 | lua_pop( L1, n_); |
2062 | return ret; | 2048 | return ret; |
2063 | } | 2049 | } |
2064 | 2050 | ||
2065 | // ################################################################################################# | 2051 | // ################################################################################################# |
2066 | 2052 | ||
2067 | // transfers stuff from L->_G["package"] to L2->_G["package"] | 2053 | // transfers stuff from L1->_G["package"] to L2->_G["package"] |
2068 | // returns InterCopyResult::Success if everything is fine | 2054 | // returns InterCopyResult::Success if everything is fine |
2069 | // returns InterCopyResult::Error if pushed an error message in L | 2055 | // returns InterCopyResult::Error if pushed an error message in L1 |
2070 | // else raise an error in L | 2056 | // else raise an error in L1 |
2071 | [[nodiscard]] InterCopyResult luaG_inter_copy_package(Universe* U, Source L, Dest L2, int package_idx_, LookupMode mode_) | 2057 | [[nodiscard]] InterCopyResult InterCopyContext::inter_copy_package() const |
2072 | { | 2058 | { |
2073 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "luaG_inter_copy_package()\n" INDENT_END)); | 2059 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "InterCopyContext::inter_copy_package()\n" INDENT_END)); |
2074 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); | 2060 | |
2075 | // package | 2061 | class OnExit |
2076 | STACK_CHECK_START_REL(L, 0); | ||
2077 | STACK_CHECK_START_REL(L2, 0); | ||
2078 | package_idx_ = lua_absindex(L, package_idx_); | ||
2079 | if (lua_type(L, package_idx_) != LUA_TTABLE) | ||
2080 | { | 2062 | { |
2081 | lua_pushfstring(L, "expected package as table, got %s", luaL_typename(L, package_idx_)); | 2063 | private: |
2082 | STACK_CHECK(L, 1); | 2064 | |
2065 | lua_State* const L2; | ||
2066 | int const top_L2; | ||
2067 | DEBUGSPEW_CODE(DebugSpewIndentScope m_scope); | ||
2068 | |||
2069 | public: | ||
2070 | |||
2071 | OnExit(Universe* U_, lua_State* L2_) | ||
2072 | : L2{ L2_ } | ||
2073 | , top_L2{ lua_gettop(L2) } | ||
2074 | DEBUGSPEW_COMMA_PARAM(m_scope{ U_ }) | ||
2075 | { | ||
2076 | } | ||
2077 | |||
2078 | ~OnExit() | ||
2079 | { | ||
2080 | lua_settop(L2, top_L2); | ||
2081 | } | ||
2082 | } onExit{ U, L2 }; | ||
2083 | |||
2084 | STACK_CHECK_START_REL(L1, 0); | ||
2085 | if (lua_type_as_enum(L1, L1_i) != LuaType::TABLE) | ||
2086 | { | ||
2087 | lua_pushfstring(L1, "expected package as table, got %s", luaL_typename(L1, L1_i)); | ||
2088 | STACK_CHECK(L1, 1); | ||
2083 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later | 2089 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later |
2084 | if (mode_ == LookupMode::LaneBody) | 2090 | if (mode == LookupMode::LaneBody) |
2085 | { | 2091 | { |
2086 | lua_error(L); // doesn't return | 2092 | lua_error(L1); // doesn't return |
2087 | } | 2093 | } |
2088 | return InterCopyResult::Error; | 2094 | return InterCopyResult::Error; |
2089 | } | 2095 | } |
2090 | lua_getglobal(L2, "package"); | 2096 | lua_getglobal(L2, "package"); // TODO: use _R._LOADED.package instead of _G.package |
2091 | if (!lua_isnil(L2, -1)) // package library not loaded: do nothing | 2097 | if (lua_isnil(L2, -1)) // package library not loaded: do nothing |
2092 | { | 2098 | { |
2093 | // package.loaders is renamed package.searchers in Lua 5.2 | 2099 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "'package' not loaded, nothing to do\n" INDENT_END)); |
2094 | // but don't copy it anyway, as the function names change depending on the slot index! | 2100 | STACK_CHECK(L1, 0); |
2095 | // users should provide an on_state_create function to setup custom loaders instead | 2101 | return InterCopyResult::Success; |
2096 | // don't copy package.preload in keeper states (they don't know how to translate functions) | 2102 | } |
2097 | char const* entries[] = { "path", "cpath", (mode_ == LookupMode::LaneBody) ? "preload" : nullptr /*, (LUA_VERSION_NUM == 501) ? "loaders" : "searchers"*/, nullptr }; | 2103 | |
2098 | for (char const* const entry : entries) | 2104 | InterCopyResult result{ InterCopyResult::Success }; |
2105 | // package.loaders is renamed package.searchers in Lua 5.2 | ||
2106 | // but don't copy it anyway, as the function names change depending on the slot index! | ||
2107 | // users should provide an on_state_create function to setup custom loaders instead | ||
2108 | // don't copy package.preload in keeper states (they don't know how to translate functions) | ||
2109 | char const* entries[] = { "path", "cpath", (mode == LookupMode::LaneBody) ? "preload" : nullptr /*, (LUA_VERSION_NUM == 501) ? "loaders" : "searchers"*/, nullptr }; | ||
2110 | for (char const* const entry : entries) | ||
2111 | { | ||
2112 | if (!entry) | ||
2113 | { | ||
2114 | continue; | ||
2115 | } | ||
2116 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "package.%s\n" INDENT_END, entry)); | ||
2117 | lua_getfield(L1, L1_i, entry); | ||
2118 | if (lua_isnil(L1, -1)) | ||
2119 | { | ||
2120 | lua_pop(L1, 1); | ||
2121 | } | ||
2122 | else | ||
2099 | { | 2123 | { |
2100 | if (!entry) | ||
2101 | { | 2124 | { |
2102 | continue; | 2125 | DEBUGSPEW_CODE(DebugSpewIndentScope scope{ U }); |
2126 | result = inter_move(1); // moves the entry to L2 | ||
2127 | STACK_CHECK(L1, 0); | ||
2103 | } | 2128 | } |
2104 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "package.%s\n" INDENT_END, entry)); | 2129 | if (result == InterCopyResult::Success) |
2105 | lua_getfield(L, package_idx_, entry); | ||
2106 | if (lua_isnil(L, -1)) | ||
2107 | { | 2130 | { |
2108 | lua_pop(L, 1); | 2131 | lua_setfield(L2, -2, entry); // set package[entry] |
2109 | } | 2132 | } |
2110 | else | 2133 | else |
2111 | { | 2134 | { |
2112 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_add(1, std::memory_order_relaxed)); | 2135 | lua_pushfstring(L1, "failed to copy package entry %s", entry); |
2113 | std::ignore = luaG_inter_move(U, L, L2, 1, mode_); // moves the entry to L2 | 2136 | // raise the error when copying from lane to lane, else just leave it on the stack to be raised later |
2114 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); | 2137 | if (mode == LookupMode::LaneBody) |
2115 | lua_setfield(L2, -2, entry); // set package[entry] | 2138 | { |
2139 | lua_error(L1); // doesn't return | ||
2140 | } | ||
2141 | lua_pop(L1, 1); | ||
2142 | break; | ||
2116 | } | 2143 | } |
2117 | } | 2144 | } |
2118 | } | 2145 | } |
2119 | else | 2146 | STACK_CHECK(L1, 0); |
2120 | { | 2147 | return result; |
2121 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "'package' not loaded, nothing to do\n" INDENT_END)); | ||
2122 | } | ||
2123 | lua_pop(L2, 1); | ||
2124 | STACK_CHECK(L2, 0); | ||
2125 | STACK_CHECK(L, 0); | ||
2126 | DEBUGSPEW_CODE(U->debugspew_indent_depth.fetch_sub(1, std::memory_order_relaxed)); | ||
2127 | return InterCopyResult::Success; | ||
2128 | } | 2148 | } |