From 5e3f33bd66ef5b21568fde7866ca4ba9a7496180 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Mon, 24 Jun 2024 18:03:06 +0200 Subject: Lindas now accept deep user data as valid keys --- src/deep.cpp | 9 ++++++++- src/deep.h | 1 + src/linda.cpp | 8 ++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/deep.cpp b/src/deep.cpp index 8754178..bac011f 100644 --- a/src/deep.cpp +++ b/src/deep.cpp @@ -130,8 +130,15 @@ void DeepFactory::DeleteDeepObject(lua_State* const L_, DeepPrelude* const o_) // ################################################################################################# +bool DeepFactory::IsDeepUserdata(lua_State* const L_, int const idx_) +{ + return LookupFactory(L_, idx_, LookupMode::LaneBody) != nullptr; +} + +// ################################################################################################# + // Return the registered factory for 'index' (deep userdata proxy), or nullptr if 'index' is not a deep userdata proxy. -[[nodiscard]] DeepFactory* DeepFactory::LookupFactory(lua_State* const L_, int const index_, LookupMode const mode_) +DeepFactory* DeepFactory::LookupFactory(lua_State* const L_, int const index_, LookupMode const mode_) { // when looking inside a keeper, we are 100% sure the object is a deep userdata if (mode_ == LookupMode::FromKeeper) { diff --git a/src/deep.h b/src/deep.h index bb86c20..c4c6fd7 100644 --- a/src/deep.h +++ b/src/deep.h @@ -66,6 +66,7 @@ class DeepFactory public: // NVI: public interface static void DeleteDeepObject(lua_State* L_, DeepPrelude* o_); + [[nodiscard]] static bool IsDeepUserdata(lua_State* const L_, int const idx_); [[nodiscard]] static DeepFactory* LookupFactory(lua_State* L_, int index_, LookupMode mode_); static void PushDeepProxy(DestState L_, DeepPrelude* o_, int nuv_, LookupMode mode_, lua_State* errL_); void pushDeepUserdata(DestState L_, int nuv_) const; diff --git a/src/linda.cpp b/src/linda.cpp index 4edc029..079ab9d 100644 --- a/src/linda.cpp +++ b/src/linda.cpp @@ -46,6 +46,7 @@ namespace { static void CheckKeyTypes(lua_State* const L_, int const start_, int const end_) { + STACK_CHECK_START_REL(L_, 0); for (int const _i : std::ranges::iota_view{ start_, end_ + 1 }) { switch (LuaType const _t{ luaG_type(L_, _i) }) { case LuaType::BOOLEAN: @@ -53,6 +54,12 @@ namespace { case LuaType::STRING: break; + case LuaType::USERDATA: + if (!DeepFactory::IsDeepUserdata(L_, _i)) { + raise_luaL_error(L_, "argument #%d: can't use non-deep userdata as a key", _i); + } + break; + case LuaType::LIGHTUSERDATA: { static constexpr std::array, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; @@ -69,6 +76,7 @@ namespace { raise_luaL_error(L_, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", _i); } } + STACK_CHECK(L_, 0); } // ############################################################################################# -- cgit v1.2.3-55-g6feb