diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-12-09 17:39:30 +0100 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-12-09 17:39:30 +0100 |
commit | 5f9ef9e1b75adc27a4ae4129cc33137aa7aaa565 (patch) | |
tree | 2500bc537a045a66ae68288f01bff569decdd80c /src/deep.cpp | |
parent | a334c7662a1a7be5b79efe72076c49ab7c714070 (diff) | |
download | lanes-5f9ef9e1b75adc27a4ae4129cc33137aa7aaa565.tar.gz lanes-5f9ef9e1b75adc27a4ae4129cc33137aa7aaa565.tar.bz2 lanes-5f9ef9e1b75adc27a4ae4129cc33137aa7aaa565.zip |
Improved DeepPrelude architecture
Diffstat (limited to 'src/deep.cpp')
-rw-r--r-- | src/deep.cpp | 66 |
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]] | ||
100 | int 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() |
125 | void DeepFactory::DeleteDeepObject(lua_State* const L_, DeepPrelude* const o_) | 127 | void 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 | ||
384 | void DeepPrelude::push(lua_State* L_) const | 386 | void 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 |