aboutsummaryrefslogtreecommitdiff
path: root/deep_test/deep_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'deep_test/deep_test.cpp')
-rw-r--r--deep_test/deep_test.cpp135
1 files changed, 67 insertions, 68 deletions
diff --git a/deep_test/deep_test.cpp b/deep_test/deep_test.cpp
index 0a09921..da467f3 100644
--- a/deep_test/deep_test.cpp
+++ b/deep_test/deep_test.cpp
@@ -1,18 +1,12 @@
1#include "lanes/src/deep.h" 1#include "lanes/src/deep.h"
2#include "lanes/src/compat.h" 2#include "lanes/src/compat.h"
3 3
4#include <malloc.h>
5#include <memory.h>
6#include <assert.h>
7
8class MyDeepFactory : public DeepFactory 4class MyDeepFactory : public DeepFactory
9{ 5{
10 public: 6 public:
11
12 static MyDeepFactory Instance; 7 static MyDeepFactory Instance;
13 8
14 private: 9 private:
15
16 void createMetatable(lua_State* const L_) const override 10 void createMetatable(lua_State* const L_) const override
17 { 11 {
18 luaL_getmetatable(L_, "deep"); 12 luaL_getmetatable(L_, "deep");
@@ -28,6 +22,7 @@ class MyDeepFactory : public DeepFactory
28// a lanes-deep userdata. needs DeepPrelude and luaG_newdeepuserdata from Lanes code. 22// a lanes-deep userdata. needs DeepPrelude and luaG_newdeepuserdata from Lanes code.
29struct MyDeepUserdata : public DeepPrelude // Deep userdata MUST start with a DeepPrelude 23struct MyDeepUserdata : public DeepPrelude // Deep userdata MUST start with a DeepPrelude
30{ 24{
25 std::atomic<int> inUse{};
31 lua_Integer val{ 0 }; 26 lua_Integer val{ 0 };
32}; 27};
33 28
@@ -49,22 +44,20 @@ void MyDeepFactory::deleteDeepObjectInternal(lua_State* const L_, DeepPrelude* c
49 44
50// ################################################################################################# 45// #################################################################################################
51 46
52[[nodiscard]] static int deep_set(lua_State* const L_) 47[[nodiscard]] static int deep_gc(lua_State* L)
53{ 48{
54 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L_, 1)) }; 49 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) };
55 lua_Integer i = lua_tointeger(L_, 2);
56 _self->val = i;
57 return 0; 50 return 0;
58} 51}
59 52
60// ################################################################################################# 53// #################################################################################################
61 54
62[[nodiscard]] static int deep_setuv(lua_State* L) 55[[nodiscard]] static int deep_tostring(lua_State* L)
63{ 56{
64 MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; 57 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) };
65 int uv = (int) luaL_optinteger(L, 2, 1); 58 _self->inUse.fetch_add(1, std::memory_order_seq_cst);
66 lua_settop( L, 3); 59 lua_pushfstring(L, "%p:deep(%d)", lua_topointer(L, 1), _self->val);
67 lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0); 60 _self->inUse.fetch_sub(1, std::memory_order_seq_cst);
68 return 1; 61 return 1;
69} 62}
70 63
@@ -73,44 +66,53 @@ void MyDeepFactory::deleteDeepObjectInternal(lua_State* const L_, DeepPrelude* c
73// won't actually do anything as deep userdata don't have uservalue slots 66// won't actually do anything as deep userdata don't have uservalue slots
74[[nodiscard]] static int deep_getuv(lua_State* L) 67[[nodiscard]] static int deep_getuv(lua_State* L)
75{ 68{
76 MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; 69 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) };
77 int uv = (int) luaL_optinteger(L, 2, 1); 70 _self->inUse.fetch_add(1, std::memory_order_seq_cst);
78 lua_getiuservalue( L, 1, uv); 71 int _uv = (int) luaL_optinteger(L, 2, 1);
72 lua_getiuservalue(L, 1, _uv);
73 _self->inUse.fetch_sub(1, std::memory_order_seq_cst);
79 return 1; 74 return 1;
80} 75}
81 76
82// ################################################################################################# 77// #################################################################################################
83 78
84[[nodiscard]] static int deep_tostring(lua_State* L) 79[[nodiscard]] static int deep_set(lua_State* const L_)
85{ 80{
86 MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; 81 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L_, 1)) };
87 lua_pushfstring(L, "%p:deep(%d)", lua_topointer(L, 1), self->val); 82 _self->inUse.fetch_add(1, std::memory_order_seq_cst);
88 return 1; 83 lua_Integer _i = lua_tointeger(L_, 2);
84 _self->val = _i;
85 _self->inUse.fetch_sub(1, std::memory_order_seq_cst);
86 return 0;
89} 87}
90 88
91// ################################################################################################# 89// #################################################################################################
92 90
93[[nodiscard]] static int deep_gc(lua_State* L) 91[[nodiscard]] static int deep_setuv(lua_State* L)
94{ 92{
95 MyDeepUserdata* const self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) }; 93 MyDeepUserdata* const _self{ static_cast<MyDeepUserdata*>(MyDeepFactory::Instance.toDeep(L, 1)) };
96 return 0; 94 _self->inUse.fetch_add(1, std::memory_order_seq_cst);
95 int _uv = (int) luaL_optinteger(L, 2, 1);
96 lua_settop(L, 3);
97 lua_pushboolean(L, lua_setiuservalue(L, 1, _uv) != 0);
98 _self->inUse.fetch_sub(1, std::memory_order_seq_cst);
99 return 1;
97} 100}
98 101
99// ################################################################################################# 102// #################################################################################################
100 103
101static luaL_Reg const deep_mt[] = 104static luaL_Reg const deep_mt[] = {
102{ 105 { "__gc", deep_gc },
103 { "__tostring", deep_tostring}, 106 { "__tostring", deep_tostring },
104 { "__gc", deep_gc}, 107 { "getuv", deep_getuv },
105 { "set", deep_set}, 108 { "set", deep_set },
106 { "setuv", deep_setuv}, 109 { "setuv", deep_setuv },
107 { "getuv", deep_getuv},
108 { nullptr, nullptr } 110 { nullptr, nullptr }
109}; 111};
110 112
111// ################################################################################################# 113// #################################################################################################
112 114
113int luaD_new_deep( lua_State* L) 115int luaD_new_deep(lua_State* L)
114{ 116{
115 int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 0)) }; 117 int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 0)) };
116 lua_settop(L, 0); 118 lua_settop(L, 0);
@@ -141,8 +143,8 @@ struct MyClonableUserdata
141{ 143{
142 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); 144 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
143 int uv = (int) luaL_optinteger(L, 2, 1); 145 int uv = (int) luaL_optinteger(L, 2, 1);
144 lua_settop( L, 3); 146 lua_settop(L, 3);
145 lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0); 147 lua_pushboolean(L, lua_setiuservalue(L, 1, uv) != 0);
146 return 1; 148 return 1;
147} 149}
148 150
@@ -152,7 +154,7 @@ struct MyClonableUserdata
152{ 154{
153 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); 155 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
154 int uv = (int) luaL_optinteger(L, 2, 1); 156 int uv = (int) luaL_optinteger(L, 2, 1);
155 lua_getiuservalue( L, 1, uv); 157 lua_getiuservalue(L, 1, uv);
156 return 1; 158 return 1;
157} 159}
158 160
@@ -178,19 +180,18 @@ struct MyClonableUserdata
178// this is all we need to make a userdata lanes-clonable. no dependency on Lanes code. 180// this is all we need to make a userdata lanes-clonable. no dependency on Lanes code.
179[[nodiscard]] static int clonable_lanesclone(lua_State* L) 181[[nodiscard]] static int clonable_lanesclone(lua_State* L)
180{ 182{
181 switch( lua_gettop(L)) 183 switch (lua_gettop(L)) {
182 { 184 case 3:
183 case 3:
184 { 185 {
185 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1)); 186 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
186 MyClonableUserdata* from = static_cast<MyClonableUserdata*>(lua_touserdata(L, 2)); 187 MyClonableUserdata* from = static_cast<MyClonableUserdata*>(lua_touserdata(L, 2));
187 size_t len = lua_tointeger(L, 3); 188 size_t len = lua_tointeger(L, 3);
188 assert( len == sizeof(MyClonableUserdata)); 189 assert(len == sizeof(MyClonableUserdata));
189 *self = *from; 190 *self = *from;
190 } 191 }
191 return 0; 192 return 0;
192 193
193 default: 194 default:
194 raise_luaL_error(L, "Lanes called clonable_lanesclone with unexpected parameters"); 195 raise_luaL_error(L, "Lanes called clonable_lanesclone with unexpected parameters");
195 } 196 }
196 return 0; 197 return 0;
@@ -198,34 +199,32 @@ struct MyClonableUserdata
198 199
199// ################################################################################################# 200// #################################################################################################
200 201
201static luaL_Reg const clonable_mt[] = 202static luaL_Reg const clonable_mt[] = {
202{ 203 { "__tostring", clonable_tostring },
203 { "__tostring", clonable_tostring}, 204 { "__gc", clonable_gc },
204 { "__gc", clonable_gc}, 205 { "__lanesclone", clonable_lanesclone },
205 { "__lanesclone", clonable_lanesclone}, 206 { "set", clonable_set },
206 { "set", clonable_set}, 207 { "setuv", clonable_setuv },
207 { "setuv", clonable_setuv}, 208 { "getuv", clonable_getuv },
208 { "getuv", clonable_getuv},
209 { nullptr, nullptr } 209 { nullptr, nullptr }
210}; 210};
211 211
212// ################################################################################################# 212// #################################################################################################
213 213
214int luaD_new_clonable( lua_State* L) 214int luaD_new_clonable(lua_State* L)
215{ 215{
216 int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 1)) }; 216 int const _nuv{ static_cast<int>(luaL_optinteger(L, 1, 1)) };
217 lua_newuserdatauv( L, sizeof(MyClonableUserdata), nuv); 217 lua_newuserdatauv(L, sizeof(MyClonableUserdata), _nuv);
218 luaL_setmetatable( L, "clonable"); 218 luaG_setmetatable(L, "clonable");
219 return 1; 219 return 1;
220} 220}
221 221
222// ################################################################################################# 222// #################################################################################################
223// ################################################################################################# 223// #################################################################################################
224 224
225static luaL_Reg const deep_module[] = 225static luaL_Reg const deep_module[] = {
226{ 226 { "new_deep", luaD_new_deep },
227 { "new_deep", luaD_new_deep}, 227 { "new_clonable", luaD_new_clonable },
228 { "new_clonable", luaD_new_clonable},
229 { nullptr, nullptr } 228 { nullptr, nullptr }
230}; 229};
231 230
@@ -233,24 +232,24 @@ static luaL_Reg const deep_module[] =
233 232
234LANES_API int luaopen_deep_test(lua_State* L) 233LANES_API int luaopen_deep_test(lua_State* L)
235{ 234{
236 luaL_newlib( L, deep_module); // M 235 luaG_newlib<std::size(deep_module)>(L, deep_module); // M
237 236
238 // preregister the metatables for the types we can instantiate so that Lanes can know about them 237 // preregister the metatables for the types we can instantiate so that Lanes can know about them
239 if (luaL_newmetatable( L, "clonable")) // M mt 238 if (luaL_newmetatable(L, "clonable")) // M mt
240 { 239 {
241 luaL_setfuncs( L, clonable_mt, 0); 240 luaG_registerlibfuncs(L, clonable_mt);
242 lua_pushvalue(L, -1); // M mt mt 241 lua_pushvalue(L, -1); // M mt mt
243 lua_setfield(L, -2, "__index"); // M mt 242 lua_setfield(L, -2, "__index"); // M mt
244 } 243 }
245 lua_setfield(L, -2, "__clonableMT"); // M 244 lua_setfield(L, -2, "__clonableMT"); // M
246 245
247 if (luaL_newmetatable( L, "deep")) // mt 246 if (luaL_newmetatable(L, "deep")) // mt
248 { 247 {
249 luaL_setfuncs( L, deep_mt, 0); 248 luaG_registerlibfuncs(L, deep_mt);
250 lua_pushvalue(L, -1); // mt mt 249 lua_pushvalue(L, -1); // mt mt
251 lua_setfield(L, -2, "__index"); // mt 250 lua_setfield(L, -2, "__index"); // mt
252 } 251 }
253 lua_setfield(L, -2, "__deepMT"); // M 252 lua_setfield(L, -2, "__deepMT"); // M
254 253
255 return 1; 254 return 1;
256} 255}