diff options
-rw-r--r-- | CHANGES | 1 | ||||
-rw-r--r-- | docs/index.html | 2 | ||||
-rw-r--r-- | src/deep.cpp | 9 | ||||
-rw-r--r-- | src/deep.h | 1 | ||||
-rw-r--r-- | src/linda.cpp | 8 |
5 files changed, 19 insertions, 2 deletions
@@ -30,6 +30,7 @@ CHANGE 2: BGe 11-Jun-24 | |||
30 | - linda :receive(), :send(), :get(), :set(), :limit() return nil, error in case of problem. Returned values in case of success change too. | 30 | - linda :receive(), :send(), :get(), :set(), :limit() return nil, error in case of problem. Returned values in case of success change too. |
31 | - Lindas have a __close metamethod that calls any suitable handler that was provided at Linda creation. | 31 | - Lindas have a __close metamethod that calls any suitable handler that was provided at Linda creation. |
32 | - linda:dump outputs <key>.limit as 'unlimited' instead of -1 for unlimited keys. | 32 | - linda:dump outputs <key>.limit as 'unlimited' instead of -1 for unlimited keys. |
33 | - deep userdata are an acceptable key to send data into (for example, another linda). | ||
33 | - Lane generator settings: | 34 | - Lane generator settings: |
34 | - error_trace_level added. Replaces the global verbose_errors setting. | 35 | - error_trace_level added. Replaces the global verbose_errors setting. |
35 | - name added. Can be used to set the name early (before the lane body calls set_debug_threadname()). | 36 | - name added. Can be used to set the name early (before the lane body calls set_debug_threadname()). |
diff --git a/docs/index.html b/docs/index.html index db9ec5a..281bd82 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -1183,7 +1183,7 @@ | |||
1183 | Characteristics of the Lanes implementation of Lindas are: | 1183 | Characteristics of the Lanes implementation of Lindas are: |
1184 | 1184 | ||
1185 | <ul> | 1185 | <ul> |
1186 | <li>Keys can be of boolean, number, string or light userdata type. Tables and functions can't be keys because their identity isn't preserved when transfered from one Lua state to another.</li> | 1186 | <li>Keys can be of boolean, number, string, light userdata, and deep userdata type. Tables and functions can't be keys because their identity isn't preserved when transfered from one Lua state to another.</li> |
1187 | <li>values can be any type supported by inter-state copying (same <a href="#limitations">limits</a> as for function arguments and upvalues).</li> | 1187 | <li>values can be any type supported by inter-state copying (same <a href="#limitations">limits</a> as for function arguments and upvalues).</li> |
1188 | <li>consuming method is <tt>:receive</tt> (not in).</li> | 1188 | <li>consuming method is <tt>:receive</tt> (not in).</li> |
1189 | <li>non-consuming method is <tt>:get</tt> (not rd).</li> | 1189 | <li>non-consuming method is <tt>:get</tt> (not rd).</li> |
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_) | |||
130 | 130 | ||
131 | // ################################################################################################# | 131 | // ################################################################################################# |
132 | 132 | ||
133 | bool DeepFactory::IsDeepUserdata(lua_State* const L_, int const idx_) | ||
134 | { | ||
135 | return LookupFactory(L_, idx_, LookupMode::LaneBody) != nullptr; | ||
136 | } | ||
137 | |||
138 | // ################################################################################################# | ||
139 | |||
133 | // Return the registered factory for 'index' (deep userdata proxy), or nullptr if 'index' is not a deep userdata proxy. | 140 | // Return the registered factory for 'index' (deep userdata proxy), or nullptr if 'index' is not a deep userdata proxy. |
134 | [[nodiscard]] DeepFactory* DeepFactory::LookupFactory(lua_State* const L_, int const index_, LookupMode const mode_) | 141 | DeepFactory* DeepFactory::LookupFactory(lua_State* const L_, int const index_, LookupMode const mode_) |
135 | { | 142 | { |
136 | // when looking inside a keeper, we are 100% sure the object is a deep userdata | 143 | // when looking inside a keeper, we are 100% sure the object is a deep userdata |
137 | if (mode_ == LookupMode::FromKeeper) { | 144 | if (mode_ == LookupMode::FromKeeper) { |
@@ -66,6 +66,7 @@ class DeepFactory | |||
66 | public: | 66 | public: |
67 | // NVI: public interface | 67 | // NVI: public interface |
68 | static void DeleteDeepObject(lua_State* L_, DeepPrelude* o_); | 68 | static void DeleteDeepObject(lua_State* L_, DeepPrelude* o_); |
69 | [[nodiscard]] static bool IsDeepUserdata(lua_State* const L_, int const idx_); | ||
69 | [[nodiscard]] static DeepFactory* LookupFactory(lua_State* L_, int index_, LookupMode mode_); | 70 | [[nodiscard]] static DeepFactory* LookupFactory(lua_State* L_, int index_, LookupMode mode_); |
70 | static void PushDeepProxy(DestState L_, DeepPrelude* o_, int nuv_, LookupMode mode_, lua_State* errL_); | 71 | static void PushDeepProxy(DestState L_, DeepPrelude* o_, int nuv_, LookupMode mode_, lua_State* errL_); |
71 | void pushDeepUserdata(DestState L_, int nuv_) const; | 72 | 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 { | |||
46 | 46 | ||
47 | static void CheckKeyTypes(lua_State* const L_, int const start_, int const end_) | 47 | static void CheckKeyTypes(lua_State* const L_, int const start_, int const end_) |
48 | { | 48 | { |
49 | STACK_CHECK_START_REL(L_, 0); | ||
49 | for (int const _i : std::ranges::iota_view{ start_, end_ + 1 }) { | 50 | for (int const _i : std::ranges::iota_view{ start_, end_ + 1 }) { |
50 | switch (LuaType const _t{ luaG_type(L_, _i) }) { | 51 | switch (LuaType const _t{ luaG_type(L_, _i) }) { |
51 | case LuaType::BOOLEAN: | 52 | case LuaType::BOOLEAN: |
@@ -53,6 +54,12 @@ namespace { | |||
53 | case LuaType::STRING: | 54 | case LuaType::STRING: |
54 | break; | 55 | break; |
55 | 56 | ||
57 | case LuaType::USERDATA: | ||
58 | if (!DeepFactory::IsDeepUserdata(L_, _i)) { | ||
59 | raise_luaL_error(L_, "argument #%d: can't use non-deep userdata as a key", _i); | ||
60 | } | ||
61 | break; | ||
62 | |||
56 | case LuaType::LIGHTUSERDATA: | 63 | case LuaType::LIGHTUSERDATA: |
57 | { | 64 | { |
58 | static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; | 65 | static constexpr std::array<std::reference_wrapper<UniqueKey const>, 3> kKeysToCheck{ kLindaBatched, kCancelError, kNilSentinel }; |
@@ -69,6 +76,7 @@ namespace { | |||
69 | raise_luaL_error(L_, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", _i); | 76 | raise_luaL_error(L_, "argument #%d: invalid key type (not a boolean, string, number or light userdata)", _i); |
70 | } | 77 | } |
71 | } | 78 | } |
79 | STACK_CHECK(L_, 0); | ||
72 | } | 80 | } |
73 | 81 | ||
74 | // ############################################################################################# | 82 | // ############################################################################################# |