From b92dbd75b1c9988dcc83e5876e1ce2815145fa30 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Thu, 6 Mar 2025 15:14:21 +0100 Subject: New compatibility helper luaG_rawget --- src/compat.hpp | 35 +++++++++++++++++++++++++++++++++++ src/deep.cpp | 3 +-- src/intercopycontext.cpp | 28 +++++++++------------------- src/keeper.cpp | 14 +++++--------- src/lane.cpp | 12 ++++-------- src/linda.cpp | 3 +-- 6 files changed, 55 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/compat.hpp b/src/compat.hpp index d864ae9..9a8dedf 100644 --- a/src/compat.hpp +++ b/src/compat.hpp @@ -271,6 +271,7 @@ static inline int WrapLuaGetField(LUA_GETFIELD f_, lua_State* const L_, StackInd // ------------------------------------------------------------------------------------------------- +[[nodiscard]] static inline LuaType luaG_getfield(lua_State* const L_, StackIndex const idx_, std::string_view const& name_) { return static_cast(WrapLuaGetField(lua_getfield, L_, idx_, name_)); @@ -278,6 +279,7 @@ static inline LuaType luaG_getfield(lua_State* const L_, StackIndex const idx_, // ################################################################################################# +[[nodiscard]] LuaType luaG_getmodule(lua_State* L_, std::string_view const& name_); // ################################################################################################# @@ -350,6 +352,7 @@ static inline int WrapLuaResume(LUA_RESUME const lua_resume_, lua_State* const L // ------------------------------------------------------------------------------------------------- +[[nodiscard]] static inline LuaError luaG_resume(lua_State* const L_, lua_State* const from_, int const nargs_, int* const nresults_) { return ToLuaError(WrapLuaResume(lua_resume, L_, from_, nargs_, nresults_)); @@ -357,6 +360,38 @@ static inline LuaError luaG_resume(lua_State* const L_, lua_State* const from_, // ################################################################################################# +template +concept RequiresOldLuaRawget = requires(LUA_RAWGET f_) { { f_(nullptr, 0) } -> std::same_as; }; + +template +static inline LuaType WrapLuaRawget(LUA_RAWGET lua_rawget_, lua_State* const L_, StackIndex const idx_) +{ + // until Lua 5.3, lua_rawget -> void + lua_rawget_(L_, idx_); + return luaG_type(L_, kIdxTop); +} + +// ------------------------------------------------------------------------------------------------- + +template +concept RequiresNewLuaRawget = requires(LUA_RAWGET f_) { { f_(nullptr, 0) } -> std::same_as; }; + +template +static inline LuaType WrapLuaRawget(LUA_RAWGET lua_rawget_, lua_State* const L_, StackIndex const idx_) +{ + // starting with Lua 5.3, lua_rawget -> int (the type of the extracted value) + return static_cast(lua_rawget_(L_, idx_)); +} + +// ------------------------------------------------------------------------------------------------- + +static inline LuaType luaG_rawget(lua_State* const L_, StackIndex const idx_) +{ + return WrapLuaRawget(lua_rawget, L_, idx_); +} + +// ################################################################################################# + static inline LuaType luaG_rawgetfield(lua_State* const L_, StackIndex const idx_, std::string_view const& name_) { auto const _absIdx{ luaG_absindex(L_, idx_) }; diff --git a/src/deep.cpp b/src/deep.cpp index c1ef30e..82f1214 100644 --- a/src/deep.cpp +++ b/src/deep.cpp @@ -190,8 +190,7 @@ void DeepFactory::PushDeepProxy(DestState const L_, DeepPrelude* const prelude_, // Check if a proxy already exists lua_pushlightuserdata(L_, prelude_); // L_: DPC deep - lua_rawget(L_, -2); // L_: DPC proxy - if (!lua_isnil(L_, -1)) { + if (luaG_rawget(L_, StackIndex{ -2 }) != LuaType::NIL) { // L_: DPC proxy lua_remove(L_, -2); // L_: proxy STACK_CHECK(L_, 1); return; diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index da4340e..d6716a3 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp @@ -337,10 +337,9 @@ void InterCopyContext::lookupNativeFunction() const STACK_CHECK(L2, 1); LUA_ASSERT(L1, lua_istable(L2, -1)); luaG_pushstring(L2, _fqn); // L1: ... f ... L2: {} "f.q.n" - lua_rawget(L2, -2); // L1: ... f ... L2: {} f + LuaType const _objType{ luaG_rawget(L2, StackIndex{ -2 }) }; // L1: ... f ... L2: {} f // nil means we don't know how to transfer stuff: user should do something // anything other than function or table should not happen! - LuaType const _objType{ luaG_type(L2, kIdxTop) }; if (_objType != LuaType::FUNCTION && _objType != LuaType::TABLE && _objType != LuaType::USERDATA) { kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name std::string_view const _from{ luaG_tostring(L1, kIdxTop) }; @@ -390,9 +389,7 @@ void InterCopyContext::copyCachedFunction() const //DEBUGSPEW_CODE(DebugSpew(U) << "<< ID: " << luaG_tostring(L2, -1) << " >>" << std::endl); lua_pushvalue(L2, -1); // L2: ... {cache} ... p p - lua_rawget(L2, L2_cache_i); // L2: ... {cache} ... p function|nil|true - - if (lua_isnil(L2, -1)) { // function is unknown + if (luaG_rawget(L2, L2_cache_i) == LuaType::NIL) { // function is unknown // L2: ... {cache} ... p function|nil|true lua_pop(L2, 1); // L2: ... {cache} ... p // Set to 'true' for the duration of creation; need to find self-references @@ -443,10 +440,9 @@ bool InterCopyContext::lookupTable() const STACK_CHECK(L2, 1); LUA_ASSERT(L1, lua_istable(L2, -1)); luaG_pushstring(L2, _fqn); // L2: {} "f.q.n" - lua_rawget(L2, -2); // L2: {} t // we accept destination lookup failures in the case of transfering the Lanes body function (this will result in the source table being cloned instead) // but not when we extract something out of a keeper, as there is nothing to clone! - if (lua_isnil(L2, -1) && mode == LookupMode::LaneBody) { + if (luaG_rawget(L2, StackIndex{ -2 }) == LuaType::NIL && mode == LookupMode::LaneBody) { // L2: {} t lua_pop(L2, 2); // L1: ... t ... L2: STACK_CHECK(L2, 0); return false; @@ -619,10 +615,7 @@ bool InterCopyContext::pushCachedMetatable() const // do we already know this metatable? std::ignore = kMtIdRegKey.getSubTable(L2, NArr{ 0 }, NRec{ 0 }); // L2: _R[kMtIdRegKey] lua_pushinteger(L2, _mt_id); // L2: _R[kMtIdRegKey] id - lua_rawget(L2, -2); // L2: _R[kMtIdRegKey] mt|nil - STACK_CHECK(L2, 2); - - if (lua_isnil(L2, -1)) { // L2 did not know the metatable + if (luaG_rawget(L2, StackIndex{ -2 }) == LuaType::NIL) { // L2 did not know the metatable // L2: _R[kMtIdRegKey] mt|nil lua_pop(L2, 1); // L2: _R[kMtIdRegKey] InterCopyContext const _c{ U, L2, L1, L2_cache_i, SourceIndex{ lua_gettop(L1) }, VT::METATABLE, mode, name }; if (_c.interCopyOne() != InterCopyResult::Success) { // L2: _R[kMtIdRegKey] mt? @@ -671,8 +664,7 @@ bool InterCopyContext::pushCachedTable() const //DEBUGSPEW_CODE(DebugSpew(U) << "<< ID: " << luaG_tostring(L2, -1) << " >>" << std::endl); - lua_rawget(L2, L2_cache_i); // L1: ... t ... L2: ... {cached|nil} - bool const _not_found_in_cache{ lua_isnil(L2, -1) }; + bool const _not_found_in_cache{ luaG_rawget(L2, L2_cache_i) == LuaType::NIL }; // L1: ... t ... L2: ... {cached|nil} if (_not_found_in_cache) { // create a new entry in the cache lua_pop(L2, 1); // L1: ... t ... L2: ... @@ -714,10 +706,10 @@ bool InterCopyContext::lookupUserdata() const STACK_CHECK(L2, 1); LUA_ASSERT(L1, lua_istable(L2, -1)); luaG_pushstring(L2, _fqn); // L1: ... f ... L2: {} "f.q.n" - lua_rawget(L2, -2); // L1: ... f ... L2: {} f + LuaType const _type{ luaG_rawget(L2, StackIndex{ -2 }) }; // L1: ... f ... L2: {} f // nil means we don't know how to transfer stuff: user should do something // anything other than function or table should not happen! - if (!lua_isfunction(L2, -1) && !lua_istable(L2, -1)) { + if (_type != LuaType::FUNCTION && _type != LuaType::TABLE) { kLaneNameRegKey.pushValue(L1); // L1: ... f ... lane_name std::string_view const _from{ luaG_tostring(L1, kIdxTop) }; lua_pop(L1, 1); // L1: ... f ... @@ -752,8 +744,7 @@ bool InterCopyContext::tryCopyClonable() const // Check if the source was already cloned during this copy lua_pushlightuserdata(L2, _source); // L2: ... source - lua_rawget(L2, L2_cache_i); // L2: ... clone? - if (!lua_isnil(L2, -1)) { + if (luaG_rawget(L2, L2_cache_i) != LuaType::NIL) { // L2: ... clone? STACK_CHECK(L2, 1); return true; } else { @@ -920,8 +911,7 @@ bool InterCopyContext::interCopyFunction() const lua_getupvalue(L1, L1_i, 2); // L1: ... u void* _source{ lua_touserdata(L1, -1) }; lua_pushlightuserdata(L2, _source); // L2: ... source - lua_rawget(L2, L2_cache_i); // L2: ... u? - if (!lua_isnil(L2, -1)) { + if (luaG_rawget(L2, L2_cache_i) != LuaType::NIL) { // L2: ... u? lua_pop(L1, 1); // L1: ... STACK_CHECK(L1, 0); STACK_CHECK(L2, 1); diff --git a/src/keeper.cpp b/src/keeper.cpp index 43f3125..cad9207 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp @@ -315,9 +315,7 @@ static void PushKeysDB(KeeperState const K_, StackIndex const idx_) StackIndex const _absidx{ luaG_absindex(K_, idx_) }; kLindasRegKey.pushValue(K_); // K_: ... LindasDB lua_pushvalue(K_, _absidx); // K_: ... LindasDB linda - lua_rawget(K_, -2); // K_: ... LindasDB KeysDB - STACK_CHECK(K_, 2); - if (lua_isnil(K_, -1)) { + if (luaG_rawget(K_, StackIndex{ -2 }) == LuaType::NIL) { // K_: ... LindasDB KeysDB lua_pop(K_, 1); // K_: ... LindasDB // add a new KeysDB table for this linda lua_newtable(K_); // K_: ... LindasDB KeysDB @@ -372,8 +370,7 @@ int keepercall_count(lua_State* const L_) case 2: // _K: linda key PushKeysDB(_K, StackIndex{ 1 }); // _K: linda key KeysDB lua_replace(_K, 1); // _K: KeysDB key - lua_rawget(_K, -2); // _K: KeysDB KeyUD|nil - if (lua_isnil(_K, -1)) { // the key is unknown // _K: KeysDB nil + if (luaG_rawget(_K, StackIndex{ -2 }) == LuaType::NIL) { // the key is unknown // _K: KeysDB KeyUD|nil lua_remove(_K, -2); // _K: nil } else { // the key is known // _K: KeysDB KeyUD KeyUD* const _key{ KeyUD::GetPtr(_K, kIdxTop) }; @@ -656,8 +653,7 @@ int keepercall_send(lua_State* const L_) PushKeysDB(_K, StackIndex{ 1 }); // _K: linda key val... KeysDB // get the fifo associated to this key in this linda, create it if it doesn't exist lua_pushvalue(_K, 2); // _K: linda key val... KeysDB key - lua_rawget(_K, -2); // _K: linda key val... KeysDB KeyUD|nil - if (lua_isnil(_K, -1)) { + if (luaG_rawget(_K, StackIndex{ -2 }) == LuaType::NIL) { // _K: linda key val... KeysDB KeyUD|nil lua_pop(_K, 1); // _K: linda key val... KeysDB std::ignore = KeyUD::Create(KeeperState{ _K }); // _K: linda key val... KeysDB KeyUD // KeysDB[key] = KeyUD @@ -853,9 +849,9 @@ int Keeper::PushLindaStorage(Linda& linda_, DestState const L_) STACK_CHECK_START_REL(_K, 0); kLindasRegKey.pushValue(_K); // _K: LindasDB L_: lua_pushlightuserdata(_K, &linda_); // _K: LindasDB linda L_: - lua_rawget(_K, -2); // _K: LindasDB KeysDB L_: + LuaType const _type{ luaG_rawget(_K, StackIndex{ -2 }) }; // _K: LindasDB KeysDB L_: lua_remove(_K, -2); // _K: KeysDB L_: - if (!lua_istable(_K, -1)) { // possible if we didn't send anything through that linda + if (_type != LuaType::TABLE) { // possible if we didn't send anything through that linda lua_pop(_K, 1); // _K: L_: STACK_CHECK(_K, 0); return 0; diff --git a/src/lane.cpp b/src/lane.cpp index 5b05b4e..7a5c257 100644 --- a/src/lane.cpp +++ b/src/lane.cpp @@ -298,8 +298,7 @@ static int lane_index_string(lua_State* L_) // look in metatable first lua_getmetatable(L_, kIdxSelf); // L_: lane "key" mt lua_replace(L_, -3); // L_: mt "key" - lua_rawget(L_, -2); // L_: mt value - if (luaG_type(L_, kIdxTop) != LuaType::NIL) { // found something? + if (luaG_rawget(L_, StackIndex{ -2 }) != LuaType::NIL) { // found something? // L_: mt value return 1; // done } @@ -335,14 +334,12 @@ static LUAG_FUNC(lane_index) default: // unknown key lua_getmetatable(L_, kIdxSelf); // L_: mt kCachedError.pushKey(L_); // L_: mt kCachedError - lua_rawget(L_, -2); // L_: mt error() - if (luaG_type(L_, kIdxTop) != LuaType::FUNCTION) { + if (luaG_rawget(L_, StackIndex{ -2 }) != LuaType::FUNCTION) { // L_: mt error() raise_luaL_error(L_, "INTERNAL ERROR: cached error() is a %s, not a function", luaG_typename(L_, kIdxTop).data()); } luaG_pushstring(L_, "Unknown key: "); // L_: mt error() "Unknown key: " kCachedTostring.pushKey(L_); // L_: mt error() "Unknown key: " kCachedTostring - lua_rawget(L_, -4); // L_: mt error() "Unknown key: " tostring() - if (luaG_type(L_, kIdxTop) != LuaType::FUNCTION) { + if (luaG_rawget(L_, StackIndex{ -4 }) != LuaType::FUNCTION) { // L_: mt error() "Unknown key: " tostring() raise_luaL_error(L_, "INTERNAL ERROR: cached tostring() is a %s, not a function", luaG_typename(L_, kIdxTop).data()); } lua_pushvalue(L_, kKey); // L_: mt error() "Unknown key: " tostring() k @@ -840,8 +837,7 @@ static LUAG_FUNC(lane_gc) // if there a gc callback? lua_getiuservalue(L_, StackIndex{ 1 }, UserValueIndex{ 1 }); // L_: ud uservalue kLaneGC.pushKey(L_); // L_: ud uservalue __gc - lua_rawget(L_, -2); // L_: ud uservalue gc_cb|nil - if (!lua_isnil(L_, -1)) { + if (luaG_rawget(L_, StackIndex{ -2 }) != LuaType::NIL) { // L_: ud uservalue gc_cb|nil lua_remove(L_, -2); // L_: ud gc_cb|nil luaG_pushstring(L_, _lane->getDebugName()); // L_: ud gc_cb name _have_gc_cb = true; diff --git a/src/linda.cpp b/src/linda.cpp index 4f33899..a094a8f 100644 --- a/src/linda.cpp +++ b/src/linda.cpp @@ -417,8 +417,7 @@ static int linda_index_string(lua_State* L_) // look in metatable first lua_getmetatable(L_, kIdxSelf); // L_: linda "key" mt lua_replace(L_, -3); // L_: mt "key" - lua_rawget(L_, -2); // L_: mt value - if (luaG_type(L_, kIdxTop) != LuaType::NIL) { // found something? + if (luaG_rawget(L_, StackIndex{ -2 }) != LuaType::NIL) { // found something? // L_: mt value return 1; // done } -- cgit v1.2.3-55-g6feb