diff options
Diffstat (limited to 'src/deep.cpp')
-rw-r--r-- | src/deep.cpp | 149 |
1 files changed, 59 insertions, 90 deletions
diff --git a/src/deep.cpp b/src/deep.cpp index d0b8123..780c86e 100644 --- a/src/deep.cpp +++ b/src/deep.cpp | |||
@@ -47,11 +47,11 @@ THE SOFTWARE. | |||
47 | /*---=== Deep userdata ===---*/ | 47 | /*---=== Deep userdata ===---*/ |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * 'registry[REGKEY]' is a two-way lookup table for 'idfunc's and those type's | 50 | * 'registry[REGKEY]' is a two-way lookup table for 'factory's and those type's |
51 | * metatables: | 51 | * metatables: |
52 | * | 52 | * |
53 | * metatable -> idfunc | 53 | * metatable -> factory |
54 | * idfunc -> metatable | 54 | * factory -> metatable |
55 | */ | 55 | */ |
56 | // crc64/we of string "DEEP_LOOKUP_KEY" generated at http://www.nitrxgen.net/hashgen/ | 56 | // crc64/we of string "DEEP_LOOKUP_KEY" generated at http://www.nitrxgen.net/hashgen/ |
57 | static constexpr UniqueKey DEEP_LOOKUP_KEY{ 0x9fb9b4f3f633d83dull }; | 57 | static constexpr UniqueKey DEEP_LOOKUP_KEY{ 0x9fb9b4f3f633d83dull }; |
@@ -84,8 +84,8 @@ static void set_deep_lookup(lua_State* L) | |||
84 | // ################################################################################################ | 84 | // ################################################################################################ |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * Pops the key (metatable or idfunc) off the stack, and replaces with the | 87 | * Pops the key (metatable or factory) off the stack, and replaces with the |
88 | * deep lookup value (idfunc/metatable/nil). | 88 | * deep lookup value (factory/metatable/nil). |
89 | */ | 89 | */ |
90 | static void get_deep_lookup(lua_State* L) | 90 | static void get_deep_lookup(lua_State* L) |
91 | { | 91 | { |
@@ -104,21 +104,21 @@ static void get_deep_lookup(lua_State* L) | |||
104 | // ################################################################################################ | 104 | // ################################################################################################ |
105 | 105 | ||
106 | /* | 106 | /* |
107 | * Return the registered ID function for 'index' (deep userdata proxy), | 107 | * Return the registered factory for 'index' (deep userdata proxy), |
108 | * or nullptr if 'index' is not a deep userdata proxy. | 108 | * or nullptr if 'index' is not a deep userdata proxy. |
109 | */ | 109 | */ |
110 | [[nodiscard]] static inline luaG_IdFunction get_idfunc(lua_State* L, int index, LookupMode mode_) | 110 | [[nodiscard]] static inline DeepFactory* get_factory(lua_State* L, int index, LookupMode mode_) |
111 | { | 111 | { |
112 | // when looking inside a keeper, we are 100% sure the object is a deep userdata | 112 | // when looking inside a keeper, we are 100% sure the object is a deep userdata |
113 | if (mode_ == LookupMode::FromKeeper) | 113 | if (mode_ == LookupMode::FromKeeper) |
114 | { | 114 | { |
115 | DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L, index) }; | 115 | DeepPrelude* const proxy{ *lua_tofulluserdata<DeepPrelude*>(L, index) }; |
116 | // we can (and must) cast and fetch the internally stored idfunc | 116 | // we can (and must) cast and fetch the internally stored factory |
117 | return (*proxy)->idfunc; | 117 | return &proxy->m_factory; |
118 | } | 118 | } |
119 | else | 119 | else |
120 | { | 120 | { |
121 | // essentially we are making sure that the metatable of the object we want to copy is stored in our metatable/idfunc database | 121 | // essentially we are making sure that the metatable of the object we want to copy is stored in our metatable/factory database |
122 | // it is the only way to ensure that the userdata is indeed a deep userdata! | 122 | // it is the only way to ensure that the userdata is indeed a deep userdata! |
123 | // of course, we could just trust the caller, but we won't | 123 | // of course, we could just trust the caller, but we won't |
124 | STACK_GROW( L, 1); | 124 | STACK_GROW( L, 1); |
@@ -129,10 +129,10 @@ static void get_deep_lookup(lua_State* L) | |||
129 | return nullptr; // no metatable: can't be a deep userdata object! | 129 | return nullptr; // no metatable: can't be a deep userdata object! |
130 | } | 130 | } |
131 | 131 | ||
132 | // replace metatable with the idfunc pointer, if it is actually a deep userdata | 132 | // replace metatable with the factory pointer, if it is actually a deep userdata |
133 | get_deep_lookup( L); // deep ... idfunc|nil | 133 | get_deep_lookup( L); // deep ... factory|nil |
134 | 134 | ||
135 | luaG_IdFunction const ret{ *lua_tolightuserdata<luaG_IdFunction>(L, -1) }; // nullptr if not a userdata | 135 | DeepFactory* const ret{ lua_tolightuserdata<DeepFactory>(L, -1) }; // nullptr if not a userdata |
136 | lua_pop( L, 1); | 136 | lua_pop( L, 1); |
137 | STACK_CHECK( L, 0); | 137 | STACK_CHECK( L, 0); |
138 | return ret; | 138 | return ret; |
@@ -141,14 +141,10 @@ static void get_deep_lookup(lua_State* L) | |||
141 | 141 | ||
142 | // ################################################################################################ | 142 | // ################################################################################################ |
143 | 143 | ||
144 | void free_deep_prelude(lua_State* L, DeepPrelude* prelude_) | 144 | void DeepFactory::DeleteDeepObject(lua_State* L, DeepPrelude* o_) |
145 | { | 145 | { |
146 | ASSERT_L(prelude_->idfunc); | ||
147 | STACK_CHECK_START_REL(L, 0); | 146 | STACK_CHECK_START_REL(L, 0); |
148 | // Call 'idfunc( "delete", deep_ptr )' to make deep cleanup | 147 | o_->m_factory.deleteDeepObjectInternal(L, o_); |
149 | lua_pushlightuserdata( L, prelude_); | ||
150 | prelude_->idfunc( L, DeepOp::Delete); | ||
151 | lua_pop(L, 1); | ||
152 | STACK_CHECK(L, 0); | 148 | STACK_CHECK(L, 0); |
153 | } | 149 | } |
154 | 150 | ||
@@ -162,8 +158,8 @@ void free_deep_prelude(lua_State* L, DeepPrelude* prelude_) | |||
162 | */ | 158 | */ |
163 | [[nodiscard]] static int deep_userdata_gc(lua_State* L) | 159 | [[nodiscard]] static int deep_userdata_gc(lua_State* L) |
164 | { | 160 | { |
165 | DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L, 1) }; | 161 | DeepPrelude* const* const proxy{ lua_tofulluserdata<DeepPrelude*>(L, 1) }; |
166 | DeepPrelude* p = *proxy; | 162 | DeepPrelude* const p{ *proxy }; |
167 | 163 | ||
168 | // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded | 164 | // can work without a universe if creating a deep userdata from some external C module when Lanes isn't loaded |
169 | // in that case, we are not multithreaded and locking isn't necessary anyway | 165 | // in that case, we are not multithreaded and locking isn't necessary anyway |
@@ -178,17 +174,9 @@ void free_deep_prelude(lua_State* L, DeepPrelude* prelude_) | |||
178 | lua_insert( L, -2); // __gc self | 174 | lua_insert( L, -2); // __gc self |
179 | lua_call( L, 1, 0); // | 175 | lua_call( L, 1, 0); // |
180 | } | 176 | } |
181 | // 'idfunc' expects a clean stack to work on | 177 | // we don't really know what remains on the stack at that point (depending on us finding a __gc or not), but we don't care |
182 | lua_settop( L, 0); | 178 | DeepFactory::DeleteDeepObject(L, p); |
183 | free_deep_prelude( L, p); | ||
184 | |||
185 | // top was set to 0, then userdata was pushed. "delete" might want to pop the userdata (we don't care), but should not push anything! | ||
186 | if ( lua_gettop( L) > 1) | ||
187 | { | ||
188 | return luaL_error( L, "Bad idfunc(DeepOp::Delete): should not push anything"); | ||
189 | } | ||
190 | } | 179 | } |
191 | *proxy = nullptr; // make sure we don't use it any more, just in case | ||
192 | return 0; | 180 | return 0; |
193 | } | 181 | } |
194 | 182 | ||
@@ -196,14 +184,14 @@ void free_deep_prelude(lua_State* L, DeepPrelude* prelude_) | |||
196 | 184 | ||
197 | /* | 185 | /* |
198 | * Push a proxy userdata on the stack. | 186 | * Push a proxy userdata on the stack. |
199 | * returns nullptr if ok, else some error string related to bad idfunc behavior or module require problem | 187 | * returns nullptr if ok, else some error string related to bad factory behavior or module require problem |
200 | * (error cannot happen with mode_ == LookupMode::ToKeeper) | 188 | * (error cannot happen with mode_ == LookupMode::ToKeeper) |
201 | * | 189 | * |
202 | * Initializes necessary structures if it's the first time 'idfunc' is being | 190 | * Initializes necessary structures if it's the first time 'factory' is being |
203 | * used in this Lua state (metatable, registring it). Otherwise, increments the | 191 | * used in this Lua state (metatable, registring it). Otherwise, increments the |
204 | * reference count. | 192 | * reference count. |
205 | */ | 193 | */ |
206 | char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode mode_) | 194 | char const* DeepFactory::PushDeepProxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode mode_) |
207 | { | 195 | { |
208 | // Check if a proxy already exists | 196 | // Check if a proxy already exists |
209 | push_registry_subtable_mode( L, DEEP_PROXY_CACHE_KEY, "v"); // DPC | 197 | push_registry_subtable_mode( L, DEEP_PROXY_CACHE_KEY, "v"); // DPC |
@@ -228,24 +216,25 @@ char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode m | |||
228 | *proxy = prelude; | 216 | *proxy = prelude; |
229 | prelude->m_refcount.fetch_add(1, std::memory_order_relaxed); // one more proxy pointing to this deep data | 217 | prelude->m_refcount.fetch_add(1, std::memory_order_relaxed); // one more proxy pointing to this deep data |
230 | 218 | ||
231 | // Get/create metatable for 'idfunc' (in this state) | 219 | // Get/create metatable for 'factory' (in this state) |
232 | lua_pushlightuserdata( L, std::bit_cast<void*>(prelude->idfunc)); // DPC proxy idfunc | 220 | DeepFactory& factory = prelude->m_factory; |
221 | lua_pushlightuserdata( L, std::bit_cast<void*>(&factory)); // DPC proxy factory | ||
233 | get_deep_lookup( L); // DPC proxy metatable? | 222 | get_deep_lookup( L); // DPC proxy metatable? |
234 | 223 | ||
235 | if( lua_isnil( L, -1)) // // No metatable yet. | 224 | if( lua_isnil( L, -1)) // // No metatable yet. |
236 | { | 225 | { |
237 | char const* modname; | ||
238 | int oldtop = lua_gettop( L); // DPC proxy nil | 226 | int oldtop = lua_gettop( L); // DPC proxy nil |
239 | lua_pop( L, 1); // DPC proxy | 227 | lua_pop( L, 1); // DPC proxy |
240 | // 1 - make one and register it | 228 | // 1 - make one and register it |
241 | if (mode_ != LookupMode::ToKeeper) | 229 | if (mode_ != LookupMode::ToKeeper) |
242 | { | 230 | { |
243 | (void) prelude->idfunc( L, DeepOp::Metatable); // DPC proxy metatable | 231 | factory.createMetatable(L); // DPC proxy metatable |
244 | if( lua_gettop( L) - oldtop != 0 || !lua_istable( L, -1)) | 232 | if (lua_gettop(L) - oldtop != 0 || !lua_istable(L, -1)) |
245 | { | 233 | { |
234 | // factory didn't push exactly 1 value, or the value it pushed is not a table: ERROR! | ||
246 | lua_settop( L, oldtop); // DPC proxy X | 235 | lua_settop( L, oldtop); // DPC proxy X |
247 | lua_pop( L, 3); // | 236 | lua_pop( L, 3); // |
248 | return "Bad idfunc(eOP_metatable): unexpected pushed value"; | 237 | return "Bad DeepFactory::createMetatable overload: unexpected pushed value"; |
249 | } | 238 | } |
250 | // if the metatable contains a __gc, we will call it from our own | 239 | // if the metatable contains a __gc, we will call it from our own |
251 | lua_getfield( L, -1, "__gc"); // DPC proxy metatable __gc | 240 | lua_getfield( L, -1, "__gc"); // DPC proxy metatable __gc |
@@ -271,22 +260,11 @@ char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode m | |||
271 | 260 | ||
272 | // Memorize for later rounds | 261 | // Memorize for later rounds |
273 | lua_pushvalue( L, -1); // DPC proxy metatable metatable | 262 | lua_pushvalue( L, -1); // DPC proxy metatable metatable |
274 | lua_pushlightuserdata( L, std::bit_cast<void*>(prelude->idfunc)); // DPC proxy metatable metatable idfunc | 263 | lua_pushlightuserdata(L, std::bit_cast<void*>(&factory)); // DPC proxy metatable metatable factory |
275 | set_deep_lookup( L); // DPC proxy metatable | 264 | set_deep_lookup( L); // DPC proxy metatable |
276 | 265 | ||
277 | // 2 - cause the target state to require the module that exported the idfunc | 266 | // 2 - cause the target state to require the module that exported the factory |
278 | // this is needed because we must make sure the shared library is still loaded as long as we hold a pointer on the idfunc | 267 | if (char const* const modname{ factory.moduleName() }; modname) // we actually got a module name |
279 | { | ||
280 | int oldtop_module = lua_gettop( L); | ||
281 | modname = (char const*) prelude->idfunc( L, DeepOp::Module); // DPC proxy metatable | ||
282 | // make sure the function pushed nothing on the stack! | ||
283 | if( lua_gettop( L) - oldtop_module != 0) | ||
284 | { | ||
285 | lua_pop( L, 3); // | ||
286 | return "Bad idfunc(eOP_module): should not push anything"; | ||
287 | } | ||
288 | } | ||
289 | if (nullptr != modname) // we actually got a module name | ||
290 | { | 268 | { |
291 | // L.registry._LOADED exists without having registered the 'package' library. | 269 | // L.registry._LOADED exists without having registered the 'package' library. |
292 | lua_getglobal( L, "require"); // DPC proxy metatable require() | 270 | lua_getglobal( L, "require"); // DPC proxy metatable require() |
@@ -309,7 +287,7 @@ char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode m | |||
309 | if( require_result != LUA_OK) | 287 | if( require_result != LUA_OK) |
310 | { | 288 | { |
311 | // failed, return the error message | 289 | // failed, return the error message |
312 | lua_pushfstring( L, "error while requiring '%s' identified by idfunc(eOP_module): ", modname); | 290 | lua_pushfstring( L, "error while requiring '%s' identified by DeepFactory::moduleName: ", modname); |
313 | lua_insert( L, -2); // DPC proxy metatable prefix error | 291 | lua_insert( L, -2); // DPC proxy metatable prefix error |
314 | lua_concat( L, 2); // DPC proxy metatable error | 292 | lua_concat( L, 2); // DPC proxy metatable error |
315 | return lua_tostring( L, -1); | 293 | return lua_tostring( L, -1); |
@@ -323,7 +301,7 @@ char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode m | |||
323 | else // no L.registry._LOADED; can this ever happen? | 301 | else // no L.registry._LOADED; can this ever happen? |
324 | { | 302 | { |
325 | lua_pop( L, 6); // | 303 | lua_pop( L, 6); // |
326 | return "unexpected error while requiring a module identified by idfunc(eOP_module)"; | 304 | return "unexpected error while requiring a module identified by DeepFactory::moduleName"; |
327 | } | 305 | } |
328 | } | 306 | } |
329 | else // a module name, but no require() function :-( | 307 | else // a module name, but no require() function :-( |
@@ -334,7 +312,7 @@ char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode m | |||
334 | } | 312 | } |
335 | } | 313 | } |
336 | STACK_CHECK(L, 2); // DPC proxy metatable | 314 | STACK_CHECK(L, 2); // DPC proxy metatable |
337 | ASSERT_L(lua_type(L, -2) == LUA_TUSERDATA); | 315 | ASSERT_L(lua_type_as_enum(L, -2) == LuaType::USERDATA); |
338 | ASSERT_L(lua_istable( L, -1)); | 316 | ASSERT_L(lua_istable( L, -1)); |
339 | lua_setmetatable( L, -2); // DPC proxy | 317 | lua_setmetatable( L, -2); // DPC proxy |
340 | 318 | ||
@@ -343,7 +321,7 @@ char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode m | |||
343 | lua_pushvalue( L, -2); // DPC proxy deep proxy | 321 | lua_pushvalue( L, -2); // DPC proxy deep proxy |
344 | lua_rawset( L, -4); // DPC proxy | 322 | lua_rawset( L, -4); // DPC proxy |
345 | lua_remove( L, -2); // proxy | 323 | lua_remove( L, -2); // proxy |
346 | ASSERT_L(lua_type(L, -1) == LUA_TUSERDATA); | 324 | ASSERT_L(lua_type_as_enum(L, -1) == LuaType::USERDATA); |
347 | STACK_CHECK(L, 0); | 325 | STACK_CHECK(L, 0); |
348 | return nullptr; | 326 | return nullptr; |
349 | } | 327 | } |
@@ -353,56 +331,47 @@ char const* push_deep_proxy(Dest L, DeepPrelude* prelude, int nuv_, LookupMode m | |||
353 | /* | 331 | /* |
354 | * Create a deep userdata | 332 | * Create a deep userdata |
355 | * | 333 | * |
356 | * proxy_ud= deep_userdata( idfunc [, ...] ) | 334 | * proxy_ud= deep_userdata( [...] ) |
357 | * | ||
358 | * Creates a deep userdata entry of the type defined by 'idfunc'. | ||
359 | * Parameters found on the stack are left as is passed on to the 'idfunc' "new" invocation. | ||
360 | * | ||
361 | * 'idfunc' must fulfill the following features: | ||
362 | * | 335 | * |
363 | * lightuserdata = idfunc( DeepOp::New [, ...] ) -- creates a new deep data instance | 336 | * Creates a deep userdata entry of the type defined by the factory. |
364 | * void = idfunc( DeepOp::Delete, lightuserdata ) -- releases a deep data instance | 337 | * Parameters found on the stack are left as is and passed on to DeepFactory::newDeepObjectInternal. |
365 | * tbl = idfunc( DeepOp::Metatable ) -- gives metatable for userdata proxies | ||
366 | * | 338 | * |
367 | * Reference counting and true userdata proxying are taken care of for the | 339 | * Reference counting and true userdata proxying are taken care of for the actual data type. |
368 | * actual data type. | ||
369 | * | 340 | * |
370 | * Types using the deep userdata system (and only those!) can be passed between | 341 | * Types using the deep userdata system (and only those!) can be passed between |
371 | * separate Lua states via 'luaG_inter_move()'. | 342 | * separate Lua states via 'luaG_inter_move()'. |
372 | * | 343 | * |
373 | * Returns: 'proxy' userdata for accessing the deep data via 'luaG_todeep()' | 344 | * Returns: 'proxy' userdata for accessing the deep data via 'DeepFactory::toDeep()' |
374 | */ | 345 | */ |
375 | int luaG_newdeepuserdata(Dest L, luaG_IdFunction idfunc, int nuv_) | 346 | int DeepFactory::pushDeepUserdata(Dest L, int nuv_) const |
376 | { | 347 | { |
377 | STACK_GROW( L, 1); | 348 | STACK_GROW( L, 1); |
378 | STACK_CHECK_START_REL(L, 0); | 349 | STACK_CHECK_START_REL(L, 0); |
379 | int const oldtop{ lua_gettop(L) }; | 350 | int const oldtop{ lua_gettop(L) }; |
380 | DeepPrelude* const prelude{ static_cast<DeepPrelude*>(idfunc(L, DeepOp::New)) }; | 351 | DeepPrelude* const prelude{ newDeepObjectInternal(L) }; |
381 | if (prelude == nullptr) | 352 | if (prelude == nullptr) |
382 | { | 353 | { |
383 | return luaL_error( L, "idfunc(DeepOp::New) failed to create deep userdata (out of memory)"); | 354 | return luaL_error( L, "DeepFactory::newDeepObjectInternal failed to create deep userdata (out of memory)"); |
384 | } | 355 | } |
385 | 356 | ||
386 | if( prelude->magic != DEEP_VERSION) | 357 | if( prelude->m_magic != DEEP_VERSION) |
387 | { | 358 | { |
388 | // just in case, don't leak the newly allocated deep userdata object | 359 | // just in case, don't leak the newly allocated deep userdata object |
389 | lua_pushlightuserdata( L, prelude); | 360 | deleteDeepObjectInternal(L, prelude); |
390 | idfunc( L, DeepOp::Delete); | 361 | return luaL_error( L, "Bad Deep Factory: DEEP_VERSION is incorrect, rebuild your implementation with the latest deep implementation"); |
391 | return luaL_error( L, "Bad idfunc(DeepOp::New): DEEP_VERSION is incorrect, rebuild your implementation with the latest deep implementation"); | ||
392 | } | 362 | } |
393 | 363 | ||
394 | ASSERT_L(prelude->m_refcount.load(std::memory_order_relaxed) == 0); // 'push_deep_proxy' will lift it to 1 | 364 | ASSERT_L(prelude->m_refcount.load(std::memory_order_relaxed) == 0); // 'DeepFactory::PushDeepProxy' will lift it to 1 |
395 | prelude->idfunc = idfunc; | 365 | ASSERT_L(&prelude->m_factory == this); |
396 | 366 | ||
397 | if( lua_gettop( L) - oldtop != 0) | 367 | if( lua_gettop( L) - oldtop != 0) |
398 | { | 368 | { |
399 | // just in case, don't leak the newly allocated deep userdata object | 369 | // just in case, don't leak the newly allocated deep userdata object |
400 | lua_pushlightuserdata( L, prelude); | 370 | deleteDeepObjectInternal(L, prelude); |
401 | idfunc( L, DeepOp::Delete); | 371 | return luaL_error(L, "Bad DeepFactory::newDeepObjectInternal overload: should not push anything on the stack"); |
402 | return luaL_error( L, "Bad idfunc(DeepOp::New): should not push anything on the stack"); | ||
403 | } | 372 | } |
404 | 373 | ||
405 | char const* const errmsg{ push_deep_proxy(L, prelude, nuv_, LookupMode::LaneBody) }; // proxy | 374 | char const* const errmsg{ DeepFactory::PushDeepProxy(L, prelude, nuv_, LookupMode::LaneBody) }; // proxy |
406 | if (errmsg != nullptr) | 375 | if (errmsg != nullptr) |
407 | { | 376 | { |
408 | return luaL_error( L, errmsg); | 377 | return luaL_error( L, errmsg); |
@@ -419,11 +388,11 @@ int luaG_newdeepuserdata(Dest L, luaG_IdFunction idfunc, int nuv_) | |||
419 | * Reference count is not changed, and access to the deep userdata is not | 388 | * Reference count is not changed, and access to the deep userdata is not |
420 | * serialized. It is the module's responsibility to prevent conflicting usage. | 389 | * serialized. It is the module's responsibility to prevent conflicting usage. |
421 | */ | 390 | */ |
422 | DeepPrelude* luaG_todeep(lua_State* L, luaG_IdFunction idfunc, int index) | 391 | DeepPrelude* DeepFactory::toDeep(lua_State* L, int index) const |
423 | { | 392 | { |
424 | STACK_CHECK_START_REL(L, 0); | 393 | STACK_CHECK_START_REL(L, 0); |
425 | // ensure it is actually a deep userdata | 394 | // ensure it is actually a deep userdata we created |
426 | if (get_idfunc(L, index, LookupMode::LaneBody) != idfunc) | 395 | if (get_factory(L, index, LookupMode::LaneBody) != this) |
427 | { | 396 | { |
428 | return nullptr; // no metatable, or wrong kind | 397 | return nullptr; // no metatable, or wrong kind |
429 | } | 398 | } |
@@ -444,8 +413,8 @@ DeepPrelude* luaG_todeep(lua_State* L, luaG_IdFunction idfunc, int index) | |||
444 | */ | 413 | */ |
445 | bool copydeep(Universe* U, Dest L2, int L2_cache_i, Source L, int i, LookupMode mode_, char const* upName_) | 414 | bool copydeep(Universe* U, Dest L2, int L2_cache_i, Source L, int i, LookupMode mode_, char const* upName_) |
446 | { | 415 | { |
447 | luaG_IdFunction const idfunc { get_idfunc(L, i, mode_) }; | 416 | DeepFactory* const factory { get_factory(L, i, mode_) }; |
448 | if (idfunc == nullptr) | 417 | if (factory == nullptr) |
449 | { | 418 | { |
450 | return false; // not a deep userdata | 419 | return false; // not a deep userdata |
451 | } | 420 | } |
@@ -463,7 +432,7 @@ bool copydeep(Universe* U, Dest L2, int L2_cache_i, Source L, int i, LookupMode | |||
463 | lua_pop( L, 1); // ... u [uv]* | 432 | lua_pop( L, 1); // ... u [uv]* |
464 | STACK_CHECK( L, nuv); | 433 | STACK_CHECK( L, nuv); |
465 | 434 | ||
466 | char const* errmsg{ push_deep_proxy(L2, *lua_tofulluserdata<DeepPrelude*>(L, i), nuv, mode_) }; // u | 435 | char const* errmsg{ DeepFactory::PushDeepProxy(L2, *lua_tofulluserdata<DeepPrelude*>(L, i), nuv, mode_) }; // u |
467 | 436 | ||
468 | // transfer all uservalues of the source in the destination | 437 | // transfer all uservalues of the source in the destination |
469 | { | 438 | { |