From a2824ef0c87034d535d3b12e6d582dfcf2265f27 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Thu, 2 May 2024 18:50:40 +0200 Subject: Remove dependency on _G["package"] --- src/compat.cpp | 19 ++++++++++++++++++- src/compat.h | 21 +++++++++++++++++++++ src/keeper.cpp | 7 +++---- src/tools.cpp | 5 ++--- 4 files changed, 44 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/compat.cpp b/src/compat.cpp index 591e19f..6ceed8f 100644 --- a/src/compat.cpp +++ b/src/compat.cpp @@ -5,6 +5,23 @@ #include "compat.h" #include "macros_and_utils.h" +// ################################################################################################# + +// a small helper to obtain the "package" module table from the registry instead of relying on the presence of _G.package +int luaG_getpackage(lua_State* L_) +{ + STACK_CHECK_START_REL(L_, 0); + int type{ lua503_getfield(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE) }; // L_: _R._LOADED|nil + if (type != LUA_TTABLE) { // L_: _R._LOADED|nil + STACK_CHECK(L_, 1); + return type; + } + type = lua503_getfield(L_, -1, LUA_LOADLIBNAME); // L_: _R._LOADED package|nil + lua_remove(L_, -2); // L_: package|nil + STACK_CHECK(L_, 1); + return type; +} + // ################################################################################################# // ################################################################################################# #if LUA_VERSION_NUM == 501 @@ -71,7 +88,7 @@ int lua_getiuservalue(lua_State* L_, int idx_, int n_) #if LUA_VERSION_NUM == 501 /* default environment is not a nil (see lua_getfenv) */ - lua_getglobal(L_, "package"); + lua_getglobal(L_, LUA_LOADLIBNAME); if (lua_rawequal(L_, -2, -1) || lua_rawequal(L_, -2, LUA_GLOBALSINDEX)) { lua_pop(L_, 2); lua_pushnil(L_); diff --git a/src/compat.h b/src/compat.h index 4816cb7..f98e142 100644 --- a/src/compat.h +++ b/src/compat.h @@ -100,6 +100,25 @@ inline int lua504_dump(lua_State* L_, lua_Writer writer_, void* data_, [[maybe_u // ################################################################################################# +#if LUA_VERSION_NUM < 503 +// starting with Lua 5.3, lua_getfield returns the type of the value it found +inline int lua503_getfield(lua_State* L_, int idx_, char const* k_) +{ + lua_getfield(L_, idx_, k_); + return lua_type(L_, -1); +} + +#else // LUA_VERSION_NUM >= 503 + +inline int lua503_getfield(lua_State* L_, int idx_, char const* k_) +{ + return lua_getfield(L_, idx_, k_); +} + +#endif // LUA_VERSION_NUM >= 503 + +// ################################################################################################# + // wrap Lua 5.3 calls under Lua 5.1 API when it is simpler that way #if LUA_VERSION_NUM == 503 @@ -199,3 +218,5 @@ inline char const* lua_typename(lua_State* L_, LuaType t_) { return lua_typename(L_, static_cast(t_)); } + +int luaG_getpackage(lua_State* L_); diff --git a/src/keeper.cpp b/src/keeper.cpp index 763bcf7..8e76247 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp @@ -651,15 +651,14 @@ void init_keepers(Universe* U_, lua_State* L_) // make sure 'package' is initialized in keeper states, so that we have require() // this because this is needed when transferring deep userdata object - luaL_requiref(K, "package", luaopen_package, 1); // L_: settings K: package + luaL_requiref(K, LUA_LOADLIBNAME, luaopen_package, 1); // L_: settings K: package lua_pop(K, 1); // L_: settings K: STACK_CHECK(K, 0); serialize_require(DEBUGSPEW_PARAM_COMMA(U_) K); STACK_CHECK(K, 0); - // copy package.path and package.cpath from the source state (TODO: use _R._LOADED.package instead of _G.package) - lua_getglobal(L_, "package"); // L_: settings package K: - if (!lua_isnil(L_, -1)) { + // copy package.path and package.cpath from the source state + if (luaG_getpackage(L_) != LUA_TNIL) { // L_: settings package K: // when copying with mode LookupMode::ToKeeper, error message is pushed at the top of the stack, not raised immediately InterCopyContext c{ U_, DestState{ K }, SourceState{ L_ }, {}, SourceIndex{ lua_absindex(L_, -1) }, {}, LookupMode::ToKeeper, {} }; if (c.inter_copy_package() != InterCopyResult::Success) { // L_: settings ... error_msg K: diff --git a/src/tools.cpp b/src/tools.cpp index a55ee75..049a065 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -1826,12 +1826,11 @@ void InterCopyContext::inter_copy_keyvaluepair() const STACK_CHECK(L1, 1); // raise the error when copying from lane to lane, else just leave it on the stack to be raised later if (mode == LookupMode::LaneBody) { - raise_lua_error(getErrL()); + raise_lua_error(getErrL()); // that's ok, getErrL() is L1 in that case } return InterCopyResult::Error; } - lua_getglobal(L2, "package"); // TODO: use _R._LOADED.package instead of _G.package - if (lua_isnil(L2, -1)) { // package library not loaded: do nothing + if (luaG_getpackage(L2) == LUA_TNIL) { // package library not loaded: do nothing DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "'package' not loaded, nothing to do\n" INDENT_END(U))); STACK_CHECK(L1, 0); return InterCopyResult::Success; -- cgit v1.2.3-55-g6feb