diff options
Diffstat (limited to 'src/deep.cpp')
-rw-r--r-- | src/deep.cpp | 56 |
1 files changed, 1 insertions, 55 deletions
diff --git a/src/deep.cpp b/src/deep.cpp index 6570e55..e0c2a39 100644 --- a/src/deep.cpp +++ b/src/deep.cpp | |||
@@ -34,10 +34,7 @@ THE SOFTWARE. | |||
34 | 34 | ||
35 | #include "deep.h" | 35 | #include "deep.h" |
36 | 36 | ||
37 | #include "compat.h" | ||
38 | #include "tools.h" | 37 | #include "tools.h" |
39 | #include "uniquekey.h" | ||
40 | #include "universe.h" | ||
41 | 38 | ||
42 | #include <bit> | 39 | #include <bit> |
43 | #include <cassert> | 40 | #include <cassert> |
@@ -105,7 +102,7 @@ static void LookupDeep(lua_State* L_) | |||
105 | // ################################################################################################# | 102 | // ################################################################################################# |
106 | 103 | ||
107 | // Return the registered factory for 'index' (deep userdata proxy), or nullptr if 'index' is not a deep userdata proxy. | 104 | // Return the registered factory for 'index' (deep userdata proxy), or nullptr if 'index' is not a deep userdata proxy. |
108 | [[nodiscard]] static inline DeepFactory* LookupFactory(lua_State* L_, int index_, LookupMode mode_) | 105 | [[nodiscard]] DeepFactory* LookupFactory(lua_State* L_, int index_, LookupMode mode_) |
109 | { | 106 | { |
110 | // when looking inside a keeper, we are 100% sure the object is a deep userdata | 107 | // when looking inside a keeper, we are 100% sure the object is a deep userdata |
111 | if (mode_ == LookupMode::FromKeeper) { | 108 | if (mode_ == LookupMode::FromKeeper) { |
@@ -386,54 +383,3 @@ DeepPrelude* DeepFactory::toDeep(lua_State* L_, int index_) const | |||
386 | DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L_, index_) }; | 383 | DeepPrelude** const proxy{ lua_tofulluserdata<DeepPrelude*>(L_, index_) }; |
387 | return *proxy; | 384 | return *proxy; |
388 | } | 385 | } |
389 | |||
390 | // ################################################################################################# | ||
391 | |||
392 | // Copy deep userdata between two separate Lua states (from L1 to L2) | ||
393 | // Returns false if not a deep userdata, else true (unless an error occured) | ||
394 | [[nodiscard]] bool InterCopyContext::tryCopyDeep() const | ||
395 | { | ||
396 | DeepFactory* const factory{ LookupFactory(L1, L1_i, mode) }; | ||
397 | if (factory == nullptr) { | ||
398 | return false; // not a deep userdata | ||
399 | } | ||
400 | |||
401 | STACK_CHECK_START_REL(L1, 0); | ||
402 | STACK_CHECK_START_REL(L2, 0); | ||
403 | |||
404 | // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail | ||
405 | int nuv = 0; | ||
406 | while (lua_getiuservalue(L1, L1_i, nuv + 1) != LUA_TNONE) { // L1: ... u [uv]* nil | ||
407 | ++nuv; | ||
408 | } | ||
409 | // last call returned TNONE and pushed nil, that we don't need | ||
410 | lua_pop(L1, 1); // L1: ... u [uv]* | ||
411 | STACK_CHECK(L1, nuv); | ||
412 | |||
413 | DeepPrelude* const u{ *lua_tofulluserdata<DeepPrelude*>(L1, L1_i) }; | ||
414 | char const* errmsg{ DeepFactory::PushDeepProxy(L2, u, nuv, mode) }; // L1: ... u [uv]* L2: u | ||
415 | if (errmsg != nullptr) { | ||
416 | raise_luaL_error(getErrL(), errmsg); | ||
417 | } | ||
418 | |||
419 | // transfer all uservalues of the source in the destination | ||
420 | { | ||
421 | InterCopyContext c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, name }; | ||
422 | int const clone_i{ lua_gettop(L2) }; | ||
423 | while (nuv) { | ||
424 | c.L1_i = SourceIndex{ lua_absindex(L1, -1) }; | ||
425 | if (!c.inter_copy_one()) { // L1: ... u [uv]* L2: u uv | ||
426 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); | ||
427 | } | ||
428 | lua_pop(L1, 1); // L1: ... u [uv]* | ||
429 | // this pops the value from the stack | ||
430 | lua_setiuservalue(L2, clone_i, nuv); // L2: u | ||
431 | --nuv; | ||
432 | } | ||
433 | } | ||
434 | |||
435 | STACK_CHECK(L2, 1); | ||
436 | STACK_CHECK(L1, 0); | ||
437 | |||
438 | return true; | ||
439 | } \ No newline at end of file | ||