diff options
Diffstat (limited to 'src/deep.cpp')
-rw-r--r-- | src/deep.cpp | 64 |
1 files changed, 28 insertions, 36 deletions
diff --git a/src/deep.cpp b/src/deep.cpp index 11e1ea7..6358745 100644 --- a/src/deep.cpp +++ b/src/deep.cpp | |||
@@ -66,28 +66,30 @@ static constexpr RegistryUniqueKey kDeepProxyCacheRegKey{ 0xEBCD49AE1A3DD35Eull | |||
66 | * Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. | 66 | * Sets up [-1]<->[-2] two-way lookups, and ensures the lookup table exists. |
67 | * Pops the both values off the stack. | 67 | * Pops the both values off the stack. |
68 | */ | 68 | */ |
69 | static void set_deep_lookup(lua_State* L_) | 69 | void DeepFactory::storeDeepLookup(lua_State* L_) const |
70 | { | 70 | { |
71 | // the deep metatable is at the top of the stack // L_: mt | ||
71 | STACK_GROW(L_, 3); | 72 | STACK_GROW(L_, 3); |
72 | STACK_CHECK_START_REL(L_, 2); // L_: a b | 73 | STACK_CHECK_START_REL(L_, 0); // L_: mt |
73 | push_registry_subtable(L_, kDeepLookupRegKey); // L_: a b {} | 74 | push_registry_subtable(L_, kDeepLookupRegKey); // L_: mt {} |
74 | STACK_CHECK(L_, 3); | 75 | lua_pushvalue(L_, -2); // L_: mt {} mt |
75 | lua_insert(L_, -3); // L_: {} a b | 76 | lua_pushlightuserdata(L_, std::bit_cast<void*>(this)); // L_: mt {} mt factory |
76 | lua_pushvalue(L_, -1); // L_: {} a b b | 77 | lua_rawset(L_, -3); // L_: mt {} |
77 | lua_pushvalue(L_, -3); // L_: {} a b b a | 78 | STACK_CHECK(L_, 1); |
78 | lua_rawset(L_, -5); // L_: {} a b | 79 | |
79 | lua_rawset(L_, -3); // L_: {} | 80 | lua_pushlightuserdata(L_, std::bit_cast<void*>(this)); // L_: mt {} factory |
80 | lua_pop(L_, 1); // L_: | 81 | lua_pushvalue(L_, -3); // L_: mt {} factory mt |
82 | lua_rawset(L_, -3); // L_: mt {} | ||
83 | STACK_CHECK(L_, 1); | ||
84 | |||
85 | lua_pop(L_, 1); // L_: mt | ||
81 | STACK_CHECK(L_, 0); | 86 | STACK_CHECK(L_, 0); |
82 | } | 87 | } |
83 | 88 | ||
84 | // ################################################################################################# | 89 | // ################################################################################################# |
85 | 90 | ||
86 | /* | 91 | // Pops the key (metatable or factory) off the stack, and replaces with the deep lookup value (factory/metatable/nil). |
87 | * Pops the key (metatable or factory) off the stack, and replaces with the | 92 | static void LookupDeep(lua_State* L_) |
88 | * deep lookup value (factory/metatable/nil). | ||
89 | */ | ||
90 | static void get_deep_lookup(lua_State* L_) | ||
91 | { | 93 | { |
92 | STACK_GROW(L_, 1); | 94 | STACK_GROW(L_, 1); |
93 | STACK_CHECK_START_REL(L_, 1); // L_: a | 95 | STACK_CHECK_START_REL(L_, 1); // L_: a |
@@ -102,11 +104,8 @@ static void get_deep_lookup(lua_State* L_) | |||
102 | 104 | ||
103 | // ################################################################################################# | 105 | // ################################################################################################# |
104 | 106 | ||
105 | /* | 107 | // Return the registered factory for 'index' (deep userdata proxy), or nullptr if 'index' is not a deep userdata proxy. |
106 | * Return the registered factory for 'index' (deep userdata proxy), | 108 | [[nodiscard]] static inline DeepFactory* LookupFactory(lua_State* L_, int index_, LookupMode mode_) |
107 | * or nullptr if 'index' is not a deep userdata proxy. | ||
108 | */ | ||
109 | [[nodiscard]] static inline DeepFactory* get_factory(lua_State* L_, int index_, LookupMode mode_) | ||
110 | { | 109 | { |
111 | // when looking inside a keeper, we are 100% sure the object is a deep userdata | 110 | // when looking inside a keeper, we are 100% sure the object is a deep userdata |
112 | if (mode_ == LookupMode::FromKeeper) { | 111 | if (mode_ == LookupMode::FromKeeper) { |
@@ -125,7 +124,7 @@ static void get_deep_lookup(lua_State* L_) | |||
125 | } | 124 | } |
126 | 125 | ||
127 | // replace metatable with the factory pointer, if it is actually a deep userdata | 126 | // replace metatable with the factory pointer, if it is actually a deep userdata |
128 | get_deep_lookup(L_); // L_: deep ... factory|nil | 127 | LookupDeep(L_); // L_: deep ... factory|nil |
129 | 128 | ||
130 | DeepFactory* const ret{ lua_tolightuserdata<DeepFactory>(L_, -1) }; // nullptr if not a userdata | 129 | DeepFactory* const ret{ lua_tolightuserdata<DeepFactory>(L_, -1) }; // nullptr if not a userdata |
131 | lua_pop(L_, 1); | 130 | lua_pop(L_, 1); |
@@ -211,7 +210,7 @@ char const* DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_, int | |||
211 | // Get/create metatable for 'factory' (in this state) | 210 | // Get/create metatable for 'factory' (in this state) |
212 | DeepFactory& factory = prelude_->m_factory; | 211 | DeepFactory& factory = prelude_->m_factory; |
213 | lua_pushlightuserdata(L_, std::bit_cast<void*>(&factory)); // L_: DPC proxy factory | 212 | lua_pushlightuserdata(L_, std::bit_cast<void*>(&factory)); // L_: DPC proxy factory |
214 | get_deep_lookup(L_); // L_: DPC proxy metatable? | 213 | LookupDeep(L_); // L_: DPC proxy metatable|nil |
215 | 214 | ||
216 | if (lua_isnil(L_, -1)) { // No metatable yet. | 215 | if (lua_isnil(L_, -1)) { // No metatable yet. |
217 | lua_pop(L_, 1); // L_: DPC proxy | 216 | lua_pop(L_, 1); // L_: DPC proxy |
@@ -240,12 +239,10 @@ char const* DeepFactory::PushDeepProxy(DestState L_, DeepPrelude* prelude_, int | |||
240 | // Add our own '__gc' method wrapping the original | 239 | // Add our own '__gc' method wrapping the original |
241 | lua_pushcclosure(L_, deep_userdata_gc, 1); // DPC proxy metatable deep_userdata_gc | 240 | lua_pushcclosure(L_, deep_userdata_gc, 1); // DPC proxy metatable deep_userdata_gc |
242 | } | 241 | } |
243 | lua_setfield(L_, -2, "__gc"); // DPC proxy metatable | 242 | lua_setfield(L_, -2, "__gc"); // L_: DPC proxy metatable |
244 | 243 | ||
245 | // Memorize for later rounds | 244 | // Memorize for later rounds |
246 | lua_pushvalue(L_, -1); // L_: DPC proxy metatable metatable | 245 | factory.storeDeepLookup(L_); |
247 | lua_pushlightuserdata(L_, std::bit_cast<void*>(&factory)); // L_: DPC proxy metatable metatable factory | ||
248 | set_deep_lookup(L_); // L_: DPC proxy metatable | ||
249 | 246 | ||
250 | // 2 - cause the target state to require the module that exported the factory | 247 | // 2 - cause the target state to require the module that exported the factory |
251 | if (char const* const modname{ factory.moduleName() }; modname) { // we actually got a module name | 248 | if (char const* const modname{ factory.moduleName() }; modname) { // we actually got a module name |
@@ -361,7 +358,7 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index_) const | |||
361 | { | 358 | { |
362 | STACK_CHECK_START_REL(L_, 0); | 359 | STACK_CHECK_START_REL(L_, 0); |
363 | // ensure it is actually a deep userdata we created | 360 | // ensure it is actually a deep userdata we created |
364 | if (get_factory(L_, index_, LookupMode::LaneBody) != this) { | 361 | if (LookupFactory(L_, index_, LookupMode::LaneBody) != this) { |
365 | return nullptr; // no metatable, or wrong kind | 362 | return nullptr; // no metatable, or wrong kind |
366 | } | 363 | } |
367 | STACK_CHECK(L_, 0); | 364 | STACK_CHECK(L_, 0); |
@@ -372,16 +369,11 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index_) const | |||
372 | 369 | ||
373 | // ################################################################################################# | 370 | // ################################################################################################# |
374 | 371 | ||
375 | /* | 372 | // Copy deep userdata between two separate Lua states (from L1 to L2) |
376 | * Copy deep userdata between two separate Lua states (from L1 to L2) | 373 | // Returns false if not a deep userdata, else true (unless an error occured) |
377 | * | 374 | [[nodiscard]] bool InterCopyContext::tryCopyDeep() const |
378 | * Returns: | ||
379 | * the id function of the copied value, or nullptr for non-deep userdata | ||
380 | * (not copied) | ||
381 | */ | ||
382 | [[nodiscard]] bool InterCopyContext::copyDeep() const | ||
383 | { | 375 | { |
384 | DeepFactory* const factory{ get_factory(L1, L1_i, mode) }; | 376 | DeepFactory* const factory{ LookupFactory(L1, L1_i, mode) }; |
385 | if (factory == nullptr) { | 377 | if (factory == nullptr) { |
386 | return false; // not a deep userdata | 378 | return false; // not a deep userdata |
387 | } | 379 | } |