diff options
Diffstat (limited to 'src/intercopycontext.cpp')
-rw-r--r-- | src/intercopycontext.cpp | 36 |
1 files changed, 13 insertions, 23 deletions
diff --git a/src/intercopycontext.cpp b/src/intercopycontext.cpp index 8142b6a..b2eda83 100644 --- a/src/intercopycontext.cpp +++ b/src/intercopycontext.cpp | |||
@@ -653,13 +653,9 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
653 | int const _mt{ luaG_absindex(L1, -2) }; // L1: ... mt __lanesclone | 653 | int const _mt{ luaG_absindex(L1, -2) }; // L1: ... mt __lanesclone |
654 | size_t const userdata_size{ lua_rawlen(L1, _L1_i) }; | 654 | size_t const userdata_size{ lua_rawlen(L1, _L1_i) }; |
655 | // extract all the uservalues, but don't transfer them yet | 655 | // extract all the uservalues, but don't transfer them yet |
656 | int _uvi{ 0 }; | 656 | int const _nuv{ luaG_getalluservalues(L1, _L1_i) }; // L1: ... mt __lanesclone [uv]* |
657 | while (lua_getiuservalue(L1, _L1_i, ++_uvi) != LUA_TNONE) {} // L1: ... mt __lanesclone [uv]+ nil | ||
658 | // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now | ||
659 | lua_pop(L1, 1); // L1: ... mt __lanesclone [uv]+ | ||
660 | --_uvi; | ||
661 | // create the clone userdata with the required number of uservalue slots | 657 | // create the clone userdata with the required number of uservalue slots |
662 | void* const _clone{ lua_newuserdatauv(L2, userdata_size, _uvi) }; // L2: ... u | 658 | void* const _clone{ lua_newuserdatauv(L2, userdata_size, _nuv) }; // L2: ... u |
663 | // copy the metatable in the target state, and give it to the clone we put there | 659 | // copy the metatable in the target state, and give it to the clone we put there |
664 | InterCopyContext _c{ U, L2, L1, L2_cache_i, SourceIndex{ _mt }, VT::NORMAL, mode, name }; | 660 | InterCopyContext _c{ U, L2, L1, L2_cache_i, SourceIndex{ _mt }, VT::NORMAL, mode, name }; |
665 | if (_c.inter_copy_one()) { // L2: ... u mt|sentinel | 661 | if (_c.inter_copy_one()) { // L2: ... u mt|sentinel |
@@ -687,6 +683,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
687 | lua_getupvalue(L2, -1, 2); // L2: ... userdata_clone_sentinel u | 683 | lua_getupvalue(L2, -1, 2); // L2: ... userdata_clone_sentinel u |
688 | } | 684 | } |
689 | // assign uservalues | 685 | // assign uservalues |
686 | int _uvi{ _nuv }; | ||
690 | while (_uvi > 0) { | 687 | while (_uvi > 0) { |
691 | _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; | 688 | _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; |
692 | if (!_c.inter_copy_one()) { // L2: ... u uv | 689 | if (!_c.inter_copy_one()) { // L2: ... u uv |
@@ -732,12 +729,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
732 | STACK_CHECK_START_REL(L2, 0); | 729 | STACK_CHECK_START_REL(L2, 0); |
733 | 730 | ||
734 | // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail | 731 | // extract all uservalues of the source. unfortunately, the only way to know their count is to iterate until we fail |
735 | int _nuv{ 0 }; | 732 | int const _nuv{ luaG_getalluservalues(L1, L1_i) }; // L1: ... deep ... [uv]* |
736 | while (lua_getiuservalue(L1, L1_i, _nuv + 1) != LUA_TNONE) { // L1: ... deep ... [uv]* nil | ||
737 | ++_nuv; | ||
738 | } | ||
739 | // last call returned TNONE and pushed nil, that we don't need | ||
740 | lua_pop(L1, 1); // L1: ... deep ... [uv]* | ||
741 | STACK_CHECK(L1, _nuv); | 733 | STACK_CHECK(L1, _nuv); |
742 | 734 | ||
743 | DeepPrelude* const _deep{ *luaG_tofulluserdata<DeepPrelude*>(L1, L1_i) }; | 735 | DeepPrelude* const _deep{ *luaG_tofulluserdata<DeepPrelude*>(L1, L1_i) }; |
@@ -747,16 +739,17 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
747 | { | 739 | { |
748 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, name }; | 740 | InterCopyContext _c{ U, L2, L1, L2_cache_i, {}, VT::NORMAL, mode, name }; |
749 | int const _clone_i{ lua_gettop(L2) }; | 741 | int const _clone_i{ lua_gettop(L2) }; |
750 | // TODO: STACK_GROW(L2, _nuv), and same for L1 above and everywhere we use lua_getiuservalue | 742 | STACK_GROW(L2, _nuv); |
751 | while (_nuv) { | 743 | int _uvi{ _nuv }; |
744 | while (_uvi) { | ||
752 | _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; | 745 | _c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; |
753 | if (!_c.inter_copy_one()) { // L1: ... deep ... [uv]* L2: deep uv | 746 | if (!_c.inter_copy_one()) { // L1: ... deep ... [uv]* L2: deep uv |
754 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); | 747 | raise_luaL_error(getErrL(), "Cannot copy upvalue type '%s'", luaL_typename(L1, -1)); |
755 | } | 748 | } |
756 | lua_pop(L1, 1); // L1: ... deep ... [uv]* | 749 | lua_pop(L1, 1); // L1: ... deep ... [uv]* |
757 | // this pops the value from the stack | 750 | // this pops the value from the stack |
758 | lua_setiuservalue(L2, _clone_i, _nuv); // L2: deep | 751 | lua_setiuservalue(L2, _clone_i, _uvi); // L2: deep |
759 | --_nuv; | 752 | --_uvi; |
760 | } // loop done: no uv remains on L1 stack // L1: ... deep ... | 753 | } // loop done: no uv remains on L1 stack // L1: ... deep ... |
761 | } | 754 | } |
762 | 755 | ||
@@ -818,14 +811,10 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
818 | size_t const userdata_size{ lua_rawlen(L1, -1) }; | 811 | size_t const userdata_size{ lua_rawlen(L1, -1) }; |
819 | { | 812 | { |
820 | // extract uservalues (don't transfer them yet) | 813 | // extract uservalues (don't transfer them yet) |
821 | int _uvi = 0; | 814 | int const _nuv{ luaG_getalluservalues(L1, source_i) }; // L1: ... u [uv]* |
822 | while (lua_getiuservalue(L1, source_i, ++_uvi) != LUA_TNONE) {} // L1: ... u uv | 815 | STACK_CHECK(L1, _nuv + 1); |
823 | // when lua_getiuservalue() returned LUA_TNONE, it pushed a nil. pop it now | ||
824 | lua_pop(L1, 1); // L1: ... u [uv]* | ||
825 | --_uvi; | ||
826 | STACK_CHECK(L1, _uvi + 1); | ||
827 | // create the clone userdata with the required number of uservalue slots | 816 | // create the clone userdata with the required number of uservalue slots |
828 | _clone = lua_newuserdatauv(L2, userdata_size, _uvi); // L2: ... mt u | 817 | _clone = lua_newuserdatauv(L2, userdata_size, _nuv); // L2: ... mt u |
829 | // add it in the cache | 818 | // add it in the cache |
830 | lua_pushlightuserdata(L2, _source); // L2: ... mt u source | 819 | lua_pushlightuserdata(L2, _source); // L2: ... mt u source |
831 | lua_pushvalue(L2, -2); // L2: ... mt u source u | 820 | lua_pushvalue(L2, -2); // L2: ... mt u source u |
@@ -835,6 +824,7 @@ void InterCopyContext::inter_copy_keyvaluepair() const | |||
835 | lua_setmetatable(L2, -2); // L2: ... mt u | 824 | lua_setmetatable(L2, -2); // L2: ... mt u |
836 | // transfer and assign uservalues | 825 | // transfer and assign uservalues |
837 | InterCopyContext c{ *this }; | 826 | InterCopyContext c{ *this }; |
827 | int _uvi{ _nuv }; | ||
838 | while (_uvi > 0) { | 828 | while (_uvi > 0) { |
839 | c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; | 829 | c.L1_i = SourceIndex{ luaG_absindex(L1, -1) }; |
840 | if (!c.inter_copy_one()) { // L2: ... mt u uv | 830 | if (!c.inter_copy_one()) { // L2: ... mt u uv |