aboutsummaryrefslogtreecommitdiff
path: root/src/deep.cpp
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-12-09 17:39:30 +0100
committerBenoit Germain <benoit.germain@ubisoft.com>2024-12-09 17:39:30 +0100
commit5f9ef9e1b75adc27a4ae4129cc33137aa7aaa565 (patch)
tree2500bc537a045a66ae68288f01bff569decdd80c /src/deep.cpp
parenta334c7662a1a7be5b79efe72076c49ab7c714070 (diff)
downloadlanes-5f9ef9e1b75adc27a4ae4129cc33137aa7aaa565.tar.gz
lanes-5f9ef9e1b75adc27a4ae4129cc33137aa7aaa565.tar.bz2
lanes-5f9ef9e1b75adc27a4ae4129cc33137aa7aaa565.zip
Improved DeepPrelude architecture
Diffstat (limited to 'src/deep.cpp')
-rw-r--r--src/deep.cpp66
1 files changed, 34 insertions, 32 deletions
diff --git a/src/deep.cpp b/src/deep.cpp
index 6f4da9f..7b287f5 100644
--- a/src/deep.cpp
+++ b/src/deep.cpp
@@ -62,37 +62,6 @@ namespace {
62 // ############################################################################################# 62 // #############################################################################################
63 // ############################################################################################# 63 // #############################################################################################
64 64
65 /*
66 * void= mt.__gc( proxy_ud )
67 *
68 * End of life for a proxy object; reduce the deep reference count and clean it up if reaches 0.
69 *
70 */
71 [[nodiscard]]
72 static int DeepGC(lua_State* const L_)
73 {
74 DeepPrelude* const* const _proxy{ luaG_tofulluserdata<DeepPrelude*>(L_, StackIndex{ 1 }) };
75 DeepPrelude* const _p{ *_proxy };
76
77 // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded
78 // in that case, we are not multithreaded and locking isn't necessary anyway
79 bool const _isLastRef{ _p->refcount.fetch_sub(1, std::memory_order_relaxed) == 1 };
80
81 if (_isLastRef) {
82 // retrieve wrapped __gc, if any
83 lua_pushvalue(L_, lua_upvalueindex(1)); // L_: self __gc?
84 if (!lua_isnil(L_, -1)) {
85 lua_insert(L_, -2); // L_: __gc self
86 lua_call(L_, 1, 0); // L_:
87 } else {
88 // need an empty stack in case we are GC_ing from a Keeper, so that empty stack checks aren't triggered
89 lua_pop(L_, 2); // L_:
90 }
91 DeepFactory::DeleteDeepObject(L_, _p);
92 }
93 return 0;
94 }
95
96 // ############################################################################################# 65 // #############################################################################################
97 66
98 // Pops the key (metatable or factory) off the stack, and replaces with the deep lookup value (factory/metatable/nil). 67 // Pops the key (metatable or factory) off the stack, and replaces with the deep lookup value (factory/metatable/nil).
@@ -121,6 +90,39 @@ namespace {
121// ################################################################################################# 90// #################################################################################################
122// ################################################################################################# 91// #################################################################################################
123 92
93/*
94 * void= mt.__gc( proxy_ud )
95 *
96 * End of life for a proxy object; reduce the deep reference count and clean it up if reaches 0.
97 *
98 */
99[[nodiscard]]
100int DeepFactory::DeepGC(lua_State* const L_)
101{
102 DeepPrelude* const* const _proxy{ luaG_tofulluserdata<DeepPrelude*>(L_, StackIndex{ 1 }) };
103 DeepPrelude* const _p{ *_proxy };
104
105 // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded
106 // in that case, we are not multithreaded and locking isn't necessary anyway
107 bool const _isLastRef{ _p->refcount.fetch_sub(1, std::memory_order_relaxed) == 1 };
108
109 if (_isLastRef) {
110 // retrieve wrapped __gc, if any
111 lua_pushvalue(L_, lua_upvalueindex(1)); // L_: self __gc?
112 if (!lua_isnil(L_, -1)) {
113 lua_insert(L_, -2); // L_: __gc self
114 lua_call(L_, 1, 0); // L_:
115 } else {
116 // need an empty stack in case we are GC_ing from a Keeper, so that empty stack checks aren't triggered
117 lua_pop(L_, 2); // L_:
118 }
119 DeepFactory::DeleteDeepObject(L_, _p);
120 }
121 return 0;
122}
123
124// #################################################################################################
125
124// NEVER call deleteDeepObjectInternal by itself, ALWAYS go through DeleteDeepObject() 126// NEVER call deleteDeepObjectInternal by itself, ALWAYS go through DeleteDeepObject()
125void DeepFactory::DeleteDeepObject(lua_State* const L_, DeepPrelude* const o_) 127void DeepFactory::DeleteDeepObject(lua_State* const L_, DeepPrelude* const o_)
126{ 128{
@@ -381,7 +383,7 @@ DeepPrelude* DeepFactory::toDeep(lua_State* const L_, StackIndex const index_) c
381 383
382// ################################################################################################# 384// #################################################################################################
383 385
384void DeepPrelude::push(lua_State* L_) const 386void DeepPrelude::push(lua_State* const L_) const
385{ 387{
386 STACK_CHECK_START_REL(L_, 0); 388 STACK_CHECK_START_REL(L_, 0);
387 kDeepProxyCacheRegKey.getSubTableMode(L_, "v"); // L_: DPC 389 kDeepProxyCacheRegKey.getSubTableMode(L_, "v"); // L_: DPC