From 9a7c7f5f7ec66576447b4d225066cc388f8ca6b0 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Fri, 7 Jun 2024 16:52:59 +0200 Subject: Improvements in compat.h --- src/compat.h | 124 +++++++++++++++++++++++++++++------------------ src/intercopycontext.cpp | 4 +- src/lanes.cpp | 4 +- src/nameof.cpp | 2 +- src/state.cpp | 2 +- 5 files changed, 84 insertions(+), 52 deletions(-) diff --git a/src/compat.h b/src/compat.h index d84447b..bc8b165 100644 --- a/src/compat.h +++ b/src/compat.h @@ -26,6 +26,19 @@ extern "C" #define LUA_JITLIBNAME "jit" #endif // LUA_JITLIBNAME +#ifndef LUA_OK +#define LUA_OK 0 // doesn't exist in Lua 5.1 +#endif // LUA_OK + +#ifndef LUA_ERRGCMM +#define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1 and Lua 5.4, we don't care about the actual value +#endif // LUA_ERRGCMM + + +#ifndef LUA_LOADED_TABLE +#define LUA_LOADED_TABLE "_LOADED" // doesn't exist before Lua 5.3 +#endif // LUA_LOADED_TABLE + // code is now preferring Lua 5.4 API // ################################################################################################# @@ -46,35 +59,16 @@ enum class LuaType CDATA = 10 // LuaJIT CDATA }; -inline LuaType luaG_type(lua_State* L_, int idx_) -{ - return static_cast(lua_type(L_, idx_)); -} -inline char const* luaG_typename(lua_State* L_, LuaType t_) -{ - return lua_typename(L_, static_cast(t_)); -} - // ################################################################################################# // add some Lua 5.3-style API when building for Lua 5.1 #if LUA_VERSION_NUM == 501 -#if LUAJIT_VERSION_NUM < 20200 // moonjit is 5.1 plus bits of 5.2 that we don't need to wrap -inline void lua_pushglobaltable(lua_State* L_) -{ - lua_pushvalue(L_, LUA_GLOBALSINDEX); -} -#endif // LUAJIT_VERSION_NUM inline size_t lua_rawlen(lua_State* L_, int idx_) { return lua_objlen(L_, idx_); } -// keep as macros to be consistent with Lua headers -#define LUA_OK 0 -#define LUA_ERRGCMM 666 // doesn't exist in Lua 5.1, we don't care about the actual value void luaL_requiref(lua_State* L_, const char* modname_, lua_CFunction openf_, int glb_); // implementation copied from Lua 5.2 sources -#define LUA_LOADED_TABLE "_LOADED" // // doesn't exist in Lua 5.1 int luaL_getsubtable(lua_State* L_, int idx_, const char* fname_); @@ -82,28 +76,6 @@ int luaL_getsubtable(lua_State* L_, int idx_, const char* fname_); // ################################################################################################# -// wrap Lua 5.2 calls under Lua 5.1 API when it is simpler that way -#if LUA_VERSION_NUM == 502 - -#define LUA_LOADED_TABLE "_LOADED" // // doesn't exist in Lua 5.2 - -#endif // LUA_VERSION_NUM == 502 - -// ################################################################################################# - -[[nodiscard]] inline LuaType luaG_getfield(lua_State* L_, int idx_, std::string_view const& k_) -{ -// starting with Lua 5.3, lua_getfield returns the type of the value it found -#if LUA_VERSION_NUM < 503 - lua_getfield(L_, idx_, k_.data()); - return luaG_type(L_, -1); -#else // LUA_VERSION_NUM >= 503 - return static_cast(lua_getfield(L_, idx_, k_.data())); -#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 @@ -135,7 +107,6 @@ inline int luaL_optint(lua_State* L_, int n_, lua_Integer d_) { return static_cast(luaL_optinteger(L_, n_, d_)); } -#define LUA_ERRGCMM 666 // doesn't exist in Lua 5.4, we don't care about the actual value #endif // LUA_VERSION_NUM == 504 @@ -149,19 +120,27 @@ enum class LuaError ERRRUN = LUA_ERRRUN, ERRSYNTAX = LUA_ERRSYNTAX, ERRMEM = LUA_ERRMEM, - ERRGCMM = LUA_ERRGCMM, // pre-5.4 + ERRGCMM = LUA_ERRGCMM, ERRERR = LUA_ERRERR, ERRFILE = LUA_ERRFILE }; -inline constexpr LuaError ToLuaError(int rc_) +inline constexpr LuaError ToLuaError(int const rc_) { - assert(rc_ == LUA_OK || rc_ == LUA_YIELD || rc_ == LUA_ERRRUN || rc_ == LUA_ERRSYNTAX || rc_ == LUA_ERRMEM || rc_ == LUA_ERRGCMM || rc_ == LUA_ERRERR); + assert(rc_ == LUA_OK || rc_ == LUA_YIELD || rc_ == LUA_ERRRUN || rc_ == LUA_ERRSYNTAX || rc_ == LUA_ERRMEM || rc_ == LUA_ERRGCMM || rc_ == LUA_ERRERR || rc_ == LUA_ERRFILE); return static_cast(rc_); } // ################################################################################################# +// break lexical order for that one because it's needed below +inline LuaType luaG_type(lua_State* const L_, int const idx_) +{ + return static_cast(lua_type(L_, idx_)); +} + +// ------------------------------------------------------------------------------------------------- + // Default matches Lua 5.4 as of now template struct Wrap @@ -171,6 +150,12 @@ struct Wrap return ::lua_dump(L_, writer_, data_, strip_); } + static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_) + { + // starting with Lua 5.3, lua_getfield returns the type of the pushed value + return static_cast(::lua_getfield(L_, idx_, k_.data())); + } + template static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) { @@ -199,6 +184,12 @@ struct Wrap::type> return ::lua_dump(L_, writer_, data_, strip_); } + static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_) + { + // starting with Lua 5.3, lua_getfield returns the type of the pushed value + return static_cast(::lua_getfield(L_, idx_, k_.data())); + } + template static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) { @@ -227,10 +218,17 @@ struct Wrap::type> return ::lua_dump(L_, writer_, data_); } + static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_) + { + // before Lua 5.3, lua_getfield returns nothing + ::lua_getfield(L_, idx_, k_.data()); + return luaG_type(L_, -1); + } + template static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) { - lua_createtable(L_, 0, N - 1); + ::lua_createtable(L_, 0, N - 1); ::luaL_setfuncs(L_, funcs_, 0); } @@ -255,6 +253,13 @@ struct Wrap::type> return ::lua_dump(L_, writer_, data_); } + static inline LuaType lua_getfield(lua_State* L_, int idx_, std::string_view const& k_) + { + // before Lua 5.3, lua_getfield returns nothing + ::lua_getfield(L_, idx_, k_.data()); + return luaG_type(L_, -1); + } + template static inline void (luaL_newlib)(lua_State* const L_, luaL_Reg const (&funcs_)[N]) { @@ -277,6 +282,8 @@ struct Wrap::type> // ################################################################################################# // All the compatibility wrappers we expose start with luaG_ +// ------------------------------------------------------------------------------------------------- + // use this in place of lua_absindex to save a function call inline int luaG_absindex(lua_State* L_, int idx_) { @@ -296,6 +303,13 @@ int luaG_getalluservalues(lua_State* L_, int idx_); // ------------------------------------------------------------------------------------------------- +[[nodiscard]] inline LuaType luaG_getfield(lua_State* L_, int idx_, std::string_view const& k_) +{ + return Wrap::lua_getfield(L_, idx_, k_); +} + +// ------------------------------------------------------------------------------------------------- + LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_); // ------------------------------------------------------------------------------------------------- @@ -316,6 +330,17 @@ template // ------------------------------------------------------------------------------------------------- +inline void luaG_pushglobaltable(lua_State* const L_) +{ +#ifdef LUA_GLOBALSINDEX // All flavors of Lua 5.1 + ::lua_pushvalue(L_, LUA_GLOBALSINDEX); +#else // LUA_GLOBALSINDEX + ::lua_rawgeti(L_, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); +#endif // LUA_GLOBALSINDEX +} + +// ------------------------------------------------------------------------------------------------- + inline void luaG_registerlibfuncs(lua_State* L_, luaL_Reg const funcs_[]) { Wrap::luaL_setfuncs(L_, funcs_, 0); @@ -351,6 +376,13 @@ template } } +// ------------------------------------------------------------------------------------------------- + +inline char const* luaG_typename(lua_State* L_, LuaType t_) +{ + return lua_typename(L_, static_cast(t_)); +} + // ################################################################################################# // must keep as a macro as long as we do constant string concatenations diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index b2eda83..fcec38a 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp @@ -262,12 +262,12 @@ void InterCopyContext::copy_func() const { InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, {} }; // if we encounter an upvalue equal to the global table in the source, bind it to the destination's global table - lua_pushglobaltable(L1); // L1: ... _G + luaG_pushglobaltable(L1); // L1: ... _G for (_n = 0; (_c.name = lua_getupvalue(L1, L1_i, 1 + _n)) != nullptr; ++_n) { // L1: ... _G up[n] DEBUGSPEW_CODE(DebugSpew(U) << "UPNAME[" << _n << "]: " << _c.name << " -> "); if (lua_rawequal(L1, -1, -2)) { // is the upvalue equal to the global table? DEBUGSPEW_CODE(DebugSpew(nullptr) << "pushing destination global scope" << std::endl); - lua_pushglobaltable(L2); // L2: ... {cache} ... function + luaG_pushglobaltable(L2); // L2: ... {cache} ... function } else { DEBUGSPEW_CODE(DebugSpew(nullptr) << "copying value" << std::endl); _c.L1_i = SourceIndex{ lua_gettop(L1) }; diff --git a/src/lanes.cpp b/src/lanes.cpp index a7631bb..b7cd148 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp @@ -466,7 +466,7 @@ LUAG_FUNC(lane_new) lua_pushnil(L_); // L_: [fixed] args... nil L2: // Lua 5.2 wants us to push the globals table on the stack InterCopyContext _c{ _U, DestState{ _L2 }, SourceState{ L_ }, {}, {}, {}, {}, {} }; - lua_pushglobaltable(_L2); // L_: [fixed] args... nil L2: _G + luaG_pushglobaltable(_L2); // L_: [fixed] args... nil L2: _G while (lua_next(L_, _globals_idx)) { // L_: [fixed] args... k v L2: _G std::ignore = _c.inter_copy(2); // L_: [fixed] args... k v L2: _G k v // assign it in L2's globals table @@ -740,7 +740,7 @@ LUAG_FUNC(configure) // don't do this when called during the initialization of a new lane, // because we will do it after on_state_create() is called, // and we don't want to skip _G because of caching in case globals are created then - lua_pushglobaltable(L_); // L_: settings M _G + luaG_pushglobaltable(L_); // L_: settings M _G tools::PopulateFuncLookupTable(L_, -1, {}); lua_pop(L_, 1); // L_: settings M } diff --git a/src/nameof.cpp b/src/nameof.cpp index 6c968d5..543c3d4 100644 --- a/src/nameof.cpp +++ b/src/nameof.cpp @@ -191,7 +191,7 @@ LUAG_FUNC(nameof) lua_pushliteral(L_, LUA_GNAME); // L_: o nil {c} {fqn} "_G" lua_rawseti(L_, -2, 1); // L_: o nil {c} {fqn} // this is where we start the search - lua_pushglobaltable(L_); // L_: o nil {c} {fqn} _G + luaG_pushglobaltable(L_); // L_: o nil {c} {fqn} _G std::ignore = DiscoverObjectNameRecur(L_, std::numeric_limits::max(), 1); if (lua_isnil(L_, 2)) { // try again with registry, just in case... lua_pop(L_, 1); // L_: o nil {c} {fqn} diff --git a/src/state.cpp b/src/state.cpp index cafabf1..77e1fd9 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -352,7 +352,7 @@ namespace state { STACK_CHECK(_L, 0); // after all this, register everything we find in our name<->function database - lua_pushglobaltable(_L); // L: _G + luaG_pushglobaltable(_L); // L: _G tools::PopulateFuncLookupTable(_L, -1, {}); lua_pop(_L, 1); // L: STACK_CHECK(_L, 0); -- cgit v1.2.3-55-g6feb