aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES1
-rw-r--r--docs/index.html2
-rw-r--r--src/deep.cpp9
-rw-r--r--src/deep.h1
-rw-r--r--src/linda.cpp8
5 files changed, 19 insertions, 2 deletions
diff --git a/CHANGES b/CHANGES
index 8234215..292af52 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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
133bool 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_) 141DeepFactory* 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) {
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
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 // #############################################################################################