aboutsummaryrefslogtreecommitdiff
path: root/src/deep.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/deep.cpp')
-rw-r--r--src/deep.cpp64
1 files changed, 33 insertions, 31 deletions
diff --git a/src/deep.cpp b/src/deep.cpp
index e0c2a39..9474666 100644
--- a/src/deep.cpp
+++ b/src/deep.cpp
@@ -59,6 +59,8 @@ static constexpr RegistryUniqueKey kDeepLookupRegKey{ 0xC6788345703C6059ull };
59 */ 59 */
60static constexpr RegistryUniqueKey kDeepProxyCacheRegKey{ 0xEBCD49AE1A3DD35Eull }; 60static constexpr RegistryUniqueKey kDeepProxyCacheRegKey{ 0xEBCD49AE1A3DD35Eull };
61 61
62// #################################################################################################
63
62/* 64/*
63 * Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. 65 * Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists.
64 * Pops the both values off the stack. 66 * Pops the both values off the stack.
@@ -106,9 +108,9 @@ static void LookupDeep(lua_State* L_)
106{ 108{
107 // when looking inside a keeper, we are 100% sure the object is a deep userdata 109 // when looking inside a keeper, we are 100% sure the object is a deep userdata
108 if (mode_ == LookupMode::FromKeeper) { 110 if (mode_ == LookupMode::FromKeeper) {
109 DeepPrelude* const proxy{ *lua_tofulluserdata<DeepPrelude*>(L_, index_) }; 111 DeepPrelude* const _proxy{ *lua_tofulluserdata<DeepPrelude*>(L_, index_) };
110 // we can (and must) cast and fetch the internally stored factory 112 // we can (and must) cast and fetch the internally stored factory
111 return &proxy->factory; 113 return &_proxy->factory;
112 } else { 114 } else {
113 // essentially we are making sure that the metatable of the object we want to copy is stored in our metatable/factory database 115 // essentially we are making sure that the metatable of the object we want to copy is stored in our metatable/factory database
114 // it is the only way to ensure that the userdata is indeed a deep userdata! 116 // it is the only way to ensure that the userdata is indeed a deep userdata!
@@ -123,10 +125,10 @@ static void LookupDeep(lua_State* L_)
123 // replace metatable with the factory pointer, if it is actually a deep userdata 125 // replace metatable with the factory pointer, if it is actually a deep userdata
124 LookupDeep(L_); // L_: deep ... factory|nil 126 LookupDeep(L_); // L_: deep ... factory|nil
125 127
126 DeepFactory* const ret{ lua_tolightuserdata<DeepFactory>(L_, -1) }; // nullptr if not a userdata 128 DeepFactory* const _ret{ lua_tolightuserdata<DeepFactory>(L_, -1) }; // nullptr if not a userdata
127 lua_pop(L_, 1); 129 lua_pop(L_, 1);
128 STACK_CHECK(L_, 0); 130 STACK_CHECK(L_, 0);
129 return ret; 131 return _ret;
130 } 132 }
131} 133}
132 134
@@ -149,12 +151,12 @@ void DeepFactory::DeleteDeepObject(lua_State* L_, DeepPrelude* o_)
149 */ 151 */
150[[nodiscard]] static int deep_userdata_gc(lua_State* L_) 152[[nodiscard]] static int deep_userdata_gc(lua_State* L_)
151{ 153{
152 DeepPrelude* const* const proxy{ lua_tofulluserdata<DeepPrelude*>(L_, 1) }; 154 DeepPrelude* const* const _proxy{ lua_tofulluserdata<DeepPrelude*>(L_, 1) };
153 DeepPrelude* const p{ *proxy }; 155 DeepPrelude* const _p{ *_proxy };
154 156
155 // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded 157 // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded
156 // in that case, we are not multithreaded and locking isn't necessary anyway 158 // in that case, we are not multithreaded and locking isn't necessary anyway
157 bool const isLastRef{ p->refcount.fetch_sub(1, std::memory_order_relaxed) == 1 }; 159 bool const isLastRef{ _p->refcount.fetch_sub(1, std::memory_order_relaxed) == 1 };
158 160
159 if (isLastRef) { 161 if (isLastRef) {
160 // retrieve wrapped __gc 162 // retrieve wrapped __gc
@@ -166,7 +168,7 @@ void DeepFactory::DeleteDeepObject(lua_State* L_, DeepPrelude* o_)
166 // need an empty stack in case we are GC_ing from a Keeper, so that empty stack checks aren't triggered 168 // need an empty stack in case we are GC_ing from a Keeper, so that empty stack checks aren't triggered
167 lua_pop(L_, 2); // L_: 169 lua_pop(L_, 2); // L_:
168 } 170 }
169 DeepFactory::DeleteDeepObject(L_, p); 171 DeepFactory::DeleteDeepObject(L_, _p);
170 } 172 }
171 return 0; 173 return 0;
172} 174}
@@ -219,9 +221,9 @@ char const* DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_, int
219 STACK_CHECK_START_REL(L_, 0); 221 STACK_CHECK_START_REL(L_, 0);
220 222
221 // a new full userdata, fitted with the specified number of uservalue slots (always 1 for Lua < 5.4) 223 // a new full userdata, fitted with the specified number of uservalue slots (always 1 for Lua < 5.4)
222 DeepPrelude** const proxy{ lua_newuserdatauv<DeepPrelude*>(L_, nuv_) }; // L_: DPC proxy 224 DeepPrelude** const _proxy{ lua_newuserdatauv<DeepPrelude*>(L_, nuv_) }; // L_: DPC proxy
223 LUA_ASSERT(L_, proxy); 225 LUA_ASSERT(L_, _proxy);
224 *proxy = prelude_; 226 *_proxy = prelude_;
225 prelude_->refcount.fetch_add(1, std::memory_order_relaxed); // one more proxy pointing to this deep data 227 prelude_->refcount.fetch_add(1, std::memory_order_relaxed); // one more proxy pointing to this deep data
226 228
227 // Get/create metatable for 'factory' (in this state) 229 // Get/create metatable for 'factory' (in this state)
@@ -231,13 +233,13 @@ char const* DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_, int
231 233
232 if (lua_isnil(L_, -1)) { // No metatable yet. 234 if (lua_isnil(L_, -1)) { // No metatable yet.
233 lua_pop(L_, 1); // L_: DPC proxy 235 lua_pop(L_, 1); // L_: DPC proxy
234 int const oldtop{ lua_gettop(L_) }; 236 int const _oldtop{ lua_gettop(L_) };
235 // 1 - make one and register it 237 // 1 - make one and register it
236 if (mode_ != LookupMode::ToKeeper) { 238 if (mode_ != LookupMode::ToKeeper) {
237 factory.createMetatable(L_); // L_: DPC proxy metatable 239 factory.createMetatable(L_); // L_: DPC proxy metatable
238 if (lua_gettop(L_) - oldtop != 1 || !lua_istable(L_, -1)) { 240 if (lua_gettop(L_) - _oldtop != 1 || !lua_istable(L_, -1)) {
239 // factory didn't push exactly 1 value, or the value it pushed is not a table: ERROR! 241 // factory didn't push exactly 1 value, or the value it pushed is not a table: ERROR!
240 lua_settop(L_, oldtop); // L_: DPC proxy X 242 lua_settop(L_, _oldtop); // L_: DPC proxy X
241 lua_pop(L_, 3); // L_: 243 lua_pop(L_, 3); // L_:
242 return "Bad DeepFactory::createMetatable overload: unexpected pushed value"; 244 return "Bad DeepFactory::createMetatable overload: unexpected pushed value";
243 } 245 }
@@ -262,12 +264,12 @@ char const* DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_, int
262 factory.storeDeepLookup(L_); 264 factory.storeDeepLookup(L_);
263 265
264 // 2 - cause the target state to require the module that exported the factory 266 // 2 - cause the target state to require the module that exported the factory
265 if (char const* const modname{ factory.moduleName() }; modname) { // we actually got a module name 267 if (char const* const _modname{ factory.moduleName() }; _modname) { // we actually got a module name
266 // L.registry._LOADED exists without having registered the 'package' library. 268 // L.registry._LOADED exists without having registered the 'package' library.
267 lua_getglobal(L_, "require"); // DPC proxy metatable require() 269 lua_getglobal(L_, "require"); // DPC proxy metatable require()
268 // check that the module is already loaded (or being loaded, we are happy either way) 270 // check that the module is already loaded (or being loaded, we are happy either way)
269 if (lua_isfunction(L_, -1)) { 271 if (lua_isfunction(L_, -1)) {
270 lua_pushstring(L_, modname); // L_: DPC proxy metatable require() "module" 272 lua_pushstring(L_, _modname); // L_: DPC proxy metatable require() "module"
271 lua_getfield(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); // L_: DPC proxy metatable require() "module" _R._LOADED 273 lua_getfield(L_, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); // L_: DPC proxy metatable require() "module" _R._LOADED
272 if (lua_istable(L_, -1)) { 274 if (lua_istable(L_, -1)) {
273 lua_pushvalue(L_, -2); // L_: DPC proxy metatable require() "module" _R._LOADED "module" 275 lua_pushvalue(L_, -2); // L_: DPC proxy metatable require() "module" _R._LOADED "module"
@@ -280,7 +282,7 @@ char const* DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_, int
280 require_result = lua_pcall(L_, 1, 0, 0); // L_: DPC proxy metatable error? 282 require_result = lua_pcall(L_, 1, 0, 0); // L_: DPC proxy metatable error?
281 if (require_result != LUA_OK) { 283 if (require_result != LUA_OK) {
282 // failed, return the error message 284 // failed, return the error message
283 lua_pushfstring(L_, "error while requiring '%s' identified by DeepFactory::moduleName: ", modname); 285 lua_pushfstring(L_, "error while requiring '%s' identified by DeepFactory::moduleName: ", _modname);
284 lua_insert(L_, -2); // L_: DPC proxy metatable prefix error 286 lua_insert(L_, -2); // L_: DPC proxy metatable prefix error
285 lua_concat(L_, 2); // L_: DPC proxy metatable error 287 lua_concat(L_, 2); // L_: DPC proxy metatable error
286 return lua_tostring(L_, -1); 288 return lua_tostring(L_, -1);
@@ -334,30 +336,30 @@ int DeepFactory::pushDeepUserdata(DestState L_, int nuv_) const
334{ 336{
335 STACK_GROW(L_, 1); 337 STACK_GROW(L_, 1);
336 STACK_CHECK_START_REL(L_, 0); 338 STACK_CHECK_START_REL(L_, 0);
337 int const oldtop{ lua_gettop(L_) }; 339 int const _oldtop{ lua_gettop(L_) };
338 DeepPrelude* const prelude{ newDeepObjectInternal(L_) }; 340 DeepPrelude* const _prelude{ newDeepObjectInternal(L_) };
339 if (prelude == nullptr) { 341 if (_prelude == nullptr) {
340 raise_luaL_error(L_, "DeepFactory::newDeepObjectInternal failed to create deep userdata (out of memory)"); 342 raise_luaL_error(L_, "DeepFactory::newDeepObjectInternal failed to create deep userdata (out of memory)");
341 } 343 }
342 344
343 if (prelude->magic != kDeepVersion) { 345 if (_prelude->magic != kDeepVersion) {
344 // just in case, don't leak the newly allocated deep userdata object 346 // just in case, don't leak the newly allocated deep userdata object
345 deleteDeepObjectInternal(L_, prelude); 347 deleteDeepObjectInternal(L_, _prelude);
346 raise_luaL_error(L_, "Bad Deep Factory: kDeepVersion is incorrect, rebuild your implementation with the latest deep implementation"); 348 raise_luaL_error(L_, "Bad Deep Factory: kDeepVersion is incorrect, rebuild your implementation with the latest deep implementation");
347 } 349 }
348 350
349 LUA_ASSERT(L_, prelude->refcount.load(std::memory_order_relaxed) == 0); // 'DeepFactory::PushDeepProxy' will lift it to 1 351 LUA_ASSERT(L_, _prelude->refcount.load(std::memory_order_relaxed) == 0); // 'DeepFactory::PushDeepProxy' will lift it to 1
350 LUA_ASSERT(L_, &prelude->factory == this); 352 LUA_ASSERT(L_, &_prelude->factory == this);
351 353
352 if (lua_gettop(L_) - oldtop != 0) { 354 if (lua_gettop(L_) - _oldtop != 0) {
353 // just in case, don't leak the newly allocated deep userdata object 355 // just in case, don't leak the newly allocated deep userdata object
354 deleteDeepObjectInternal(L_, prelude); 356 deleteDeepObjectInternal(L_, _prelude);
355 raise_luaL_error(L_, "Bad DeepFactory::newDeepObjectInternal overload: should not push anything on the stack"); 357 raise_luaL_error(L_, "Bad DeepFactory::newDeepObjectInternal overload: should not push anything on the stack");
356 } 358 }
357 359
358 char const* const errmsg{ DeepFactory::PushDeepProxy(L_, prelude, nuv_, LookupMode::LaneBody) }; // proxy 360 char const* const _err{ DeepFactory::PushDeepProxy(L_, _prelude, nuv_, LookupMode::LaneBody) }; // proxy
359 if (errmsg != nullptr) { 361 if (_err != nullptr) {
360 raise_luaL_error(L_, errmsg); 362 raise_luaL_error(L_, _err);
361 } 363 }
362 STACK_CHECK(L_, 1); 364 STACK_CHECK(L_, 1);
363 return 1; 365 return 1;
@@ -380,6 +382,6 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index_) const
380 } 382 }
381 STACK_CHECK(L_, 0); 383 STACK_CHECK(L_, 0);
382 384
383 DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L_, index_) }; 385 DeepPrelude** const _proxy{ lua_tofulluserdata<DeepPrelude*>(L_, index_) };
384 return *proxy; 386 return *_proxy;
385} 387}