mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
re-implement xmove implicit transfers and hope it works proper this time
This commit is contained in:
parent
5816c6c34b
commit
dcff5cdaa0
|
@ -20,8 +20,8 @@
|
||||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// This file was generated with a script.
|
// This file was generated with a script.
|
||||||
// Generated 2017-09-13 06:45:53.519071 UTC
|
// Generated 2017-09-13 14:18:42.960702 UTC
|
||||||
// This header was generated with sol v2.18.2 (revision 66eb025)
|
// This header was generated with sol v2.18.2 (revision 5816c6c)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||||
|
@ -5672,6 +5672,17 @@ namespace sol {
|
||||||
// beginning of sol/stack_reference.hpp
|
// beginning of sol/stack_reference.hpp
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
namespace detail {
|
||||||
|
inline bool xmovable(lua_State* leftL, lua_State* rightL) {
|
||||||
|
if (rightL == nullptr || leftL == nullptr || leftL == rightL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const void* leftregistry = lua_topointer(leftL, LUA_REGISTRYINDEX);
|
||||||
|
const void* rightregistry = lua_topointer(rightL, LUA_REGISTRYINDEX);
|
||||||
|
return leftregistry == rightregistry;
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
class stack_reference {
|
class stack_reference {
|
||||||
private:
|
private:
|
||||||
lua_State* luastate = nullptr;
|
lua_State* luastate = nullptr;
|
||||||
|
@ -5707,7 +5718,7 @@ namespace sol {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int i = r.stack_index();
|
int i = r.stack_index();
|
||||||
if (r.lua_state() != luastate) {
|
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
lua_pushvalue(r.lua_state(), r.index);
|
lua_pushvalue(r.lua_state(), r.index);
|
||||||
lua_xmove(r.lua_state(), luastate, 1);
|
lua_xmove(r.lua_state(), luastate, 1);
|
||||||
i = absolute_index(luastate, -1);
|
i = absolute_index(luastate, -1);
|
||||||
|
@ -5931,40 +5942,54 @@ namespace sol {
|
||||||
}
|
}
|
||||||
reference(lua_State* L, const reference& r) noexcept
|
reference(lua_State* L, const reference& r) noexcept
|
||||||
: luastate(L) {
|
: luastate(L) {
|
||||||
if (r.ref == LUA_NOREF) {
|
if (r.ref == LUA_REFNIL) {
|
||||||
|
ref = LUA_REFNIL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (r.ref == LUA_NOREF || lua_state() == nullptr) {
|
||||||
ref = LUA_NOREF;
|
ref = LUA_NOREF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int p = r.push();
|
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
if (r.lua_state() != luastate) {
|
r.push(lua_state());
|
||||||
lua_xmove(r.lua_state(), L, p);
|
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
ref = r.copy();
|
||||||
}
|
}
|
||||||
reference(lua_State* L, reference&& r) noexcept
|
reference(lua_State* L, reference&& r) noexcept
|
||||||
: luastate(L) {
|
: luastate(L) {
|
||||||
if (r.ref == LUA_NOREF) {
|
if (r.ref == LUA_REFNIL) {
|
||||||
|
ref = LUA_REFNIL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (r.ref == LUA_NOREF || lua_state() == nullptr) {
|
||||||
ref = LUA_NOREF;
|
ref = LUA_NOREF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (r.lua_state() != luastate) {
|
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
int p = r.push();
|
r.push(lua_state());
|
||||||
lua_xmove(r.lua_state(), L, p);
|
|
||||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
ref = r.ref;
|
||||||
ref = r.ref;
|
r.ref = LUA_NOREF;
|
||||||
r.luastate = nullptr;
|
r.luastate = nullptr;
|
||||||
r.ref = LUA_NOREF;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
reference(lua_State* L, const stack_reference& r) noexcept
|
reference(lua_State* L, const stack_reference& r) noexcept
|
||||||
: luastate(L) {
|
: luastate(L) {
|
||||||
if (!r.valid()) {
|
if (lua_state() == nullptr || r.lua_state() == nullptr || r.get_type() == type::none) {
|
||||||
ref = LUA_NOREF;
|
ref = LUA_NOREF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
r.push(luastate);
|
if (r.get_type() == type::nil) {
|
||||||
|
ref = LUA_REFNIL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lua_state() != r.lua_state() && !detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r.push(lua_state());
|
||||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||||
}
|
}
|
||||||
reference(lua_State* L, int index = -1) noexcept
|
reference(lua_State* L, int index = -1) noexcept
|
||||||
|
@ -5995,26 +6020,43 @@ namespace sol {
|
||||||
o.ref = LUA_NOREF;
|
o.ref = LUA_NOREF;
|
||||||
}
|
}
|
||||||
|
|
||||||
reference& operator=(reference&& o) noexcept {
|
reference& operator=(reference&& r) noexcept {
|
||||||
if (valid()) {
|
if (r.ref == LUA_REFNIL) {
|
||||||
deref();
|
ref = LUA_REFNIL;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (r.ref == LUA_NOREF || lua_state() == nullptr) {
|
||||||
|
ref = LUA_NOREF;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
|
r.push(lua_state());
|
||||||
|
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
luastate = o.luastate;
|
|
||||||
ref = o.ref;
|
|
||||||
|
|
||||||
o.luastate = nullptr;
|
|
||||||
o.ref = LUA_NOREF;
|
|
||||||
|
|
||||||
|
ref = r.ref;
|
||||||
|
r.ref = LUA_NOREF;
|
||||||
|
r.luastate = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
reference& operator=(const reference& o) noexcept {
|
reference& operator=(const reference& r) noexcept {
|
||||||
if (valid()) {
|
if (r.ref == LUA_REFNIL) {
|
||||||
deref();
|
ref = LUA_REFNIL;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (r.ref == LUA_NOREF || lua_state() == nullptr) {
|
||||||
|
ref = LUA_NOREF;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
|
r.push(lua_state());
|
||||||
|
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
luastate = o.luastate;
|
ref = r.copy();
|
||||||
ref = o.copy();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,40 +167,54 @@ namespace sol {
|
||||||
}
|
}
|
||||||
reference(lua_State* L, const reference& r) noexcept
|
reference(lua_State* L, const reference& r) noexcept
|
||||||
: luastate(L) {
|
: luastate(L) {
|
||||||
if (r.ref == LUA_NOREF) {
|
if (r.ref == LUA_REFNIL) {
|
||||||
|
ref = LUA_REFNIL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (r.ref == LUA_NOREF || lua_state() == nullptr) {
|
||||||
ref = LUA_NOREF;
|
ref = LUA_NOREF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int p = r.push();
|
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
if (r.lua_state() != luastate) {
|
r.push(lua_state());
|
||||||
lua_xmove(r.lua_state(), L, p);
|
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
ref = r.copy();
|
||||||
}
|
}
|
||||||
reference(lua_State* L, reference&& r) noexcept
|
reference(lua_State* L, reference&& r) noexcept
|
||||||
: luastate(L) {
|
: luastate(L) {
|
||||||
if (r.ref == LUA_NOREF) {
|
if (r.ref == LUA_REFNIL) {
|
||||||
|
ref = LUA_REFNIL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (r.ref == LUA_NOREF || lua_state() == nullptr) {
|
||||||
ref = LUA_NOREF;
|
ref = LUA_NOREF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (r.lua_state() != luastate) {
|
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
int p = r.push();
|
r.push(lua_state());
|
||||||
lua_xmove(r.lua_state(), L, p);
|
|
||||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
ref = r.ref;
|
||||||
ref = r.ref;
|
r.ref = LUA_NOREF;
|
||||||
r.luastate = nullptr;
|
r.luastate = nullptr;
|
||||||
r.ref = LUA_NOREF;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
reference(lua_State* L, const stack_reference& r) noexcept
|
reference(lua_State* L, const stack_reference& r) noexcept
|
||||||
: luastate(L) {
|
: luastate(L) {
|
||||||
if (!r.valid()) {
|
if (lua_state() == nullptr || r.lua_state() == nullptr || r.get_type() == type::none) {
|
||||||
ref = LUA_NOREF;
|
ref = LUA_NOREF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
r.push(luastate);
|
if (r.get_type() == type::nil) {
|
||||||
|
ref = LUA_REFNIL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lua_state() != r.lua_state() && !detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r.push(lua_state());
|
||||||
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||||
}
|
}
|
||||||
reference(lua_State* L, int index = -1) noexcept
|
reference(lua_State* L, int index = -1) noexcept
|
||||||
|
@ -231,26 +245,43 @@ namespace sol {
|
||||||
o.ref = LUA_NOREF;
|
o.ref = LUA_NOREF;
|
||||||
}
|
}
|
||||||
|
|
||||||
reference& operator=(reference&& o) noexcept {
|
reference& operator=(reference&& r) noexcept {
|
||||||
if (valid()) {
|
if (r.ref == LUA_REFNIL) {
|
||||||
deref();
|
ref = LUA_REFNIL;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (r.ref == LUA_NOREF || lua_state() == nullptr) {
|
||||||
|
ref = LUA_NOREF;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
|
r.push(lua_state());
|
||||||
|
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
luastate = o.luastate;
|
|
||||||
ref = o.ref;
|
|
||||||
|
|
||||||
o.luastate = nullptr;
|
|
||||||
o.ref = LUA_NOREF;
|
|
||||||
|
|
||||||
|
ref = r.ref;
|
||||||
|
r.ref = LUA_NOREF;
|
||||||
|
r.luastate = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
reference& operator=(const reference& o) noexcept {
|
reference& operator=(const reference& r) noexcept {
|
||||||
if (valid()) {
|
if (r.ref == LUA_REFNIL) {
|
||||||
deref();
|
ref = LUA_REFNIL;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (r.ref == LUA_NOREF || lua_state() == nullptr) {
|
||||||
|
ref = LUA_NOREF;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
|
r.push(lua_state());
|
||||||
|
ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
luastate = o.luastate;
|
ref = r.copy();
|
||||||
ref = o.copy();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,17 @@
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
namespace detail {
|
||||||
|
inline bool xmovable(lua_State* leftL, lua_State* rightL) {
|
||||||
|
if (rightL == nullptr || leftL == nullptr || leftL == rightL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const void* leftregistry = lua_topointer(leftL, LUA_REGISTRYINDEX);
|
||||||
|
const void* rightregistry = lua_topointer(rightL, LUA_REGISTRYINDEX);
|
||||||
|
return leftregistry == rightregistry;
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
class stack_reference {
|
class stack_reference {
|
||||||
private:
|
private:
|
||||||
lua_State* luastate = nullptr;
|
lua_State* luastate = nullptr;
|
||||||
|
@ -60,7 +71,7 @@ namespace sol {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int i = r.stack_index();
|
int i = r.stack_index();
|
||||||
if (r.lua_state() != luastate) {
|
if (detail::xmovable(lua_state(), r.lua_state())) {
|
||||||
lua_pushvalue(r.lua_state(), r.index);
|
lua_pushvalue(r.lua_state(), r.index);
|
||||||
lua_xmove(r.lua_state(), luastate, 1);
|
lua_xmove(r.lua_state(), luastate, 1);
|
||||||
i = absolute_index(luastate, -1);
|
i = absolute_index(luastate, -1);
|
||||||
|
|
|
@ -108,7 +108,7 @@ end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("coroutines/implicit transfer", "check that copy and move assignment constructors implicitly shift things around") {
|
TEST_CASE("coroutines/explicit transfer", "check that the xmove constructors shift things around appropriately") {
|
||||||
const std::string code = R"(
|
const std::string code = R"(
|
||||||
-- main thread - L1
|
-- main thread - L1
|
||||||
-- co - L2
|
-- co - L2
|
||||||
|
@ -194,3 +194,90 @@ co = nil
|
||||||
std::string s = t[1];
|
std::string s = t[1];
|
||||||
REQUIRE(s == "SOME_TABLE");
|
REQUIRE(s == "SOME_TABLE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("coroutines/implicit transfer", "check that copy and move assignment constructors implicitly shift things around") {
|
||||||
|
const std::string code = R"(
|
||||||
|
-- main thread - L1
|
||||||
|
-- co - L2
|
||||||
|
-- co2 - L3
|
||||||
|
|
||||||
|
x = co_test.new("x")
|
||||||
|
local co = coroutine.wrap(
|
||||||
|
function()
|
||||||
|
local t = co_test.new("t")
|
||||||
|
local co2 = coroutine.wrap(
|
||||||
|
function()
|
||||||
|
local t2 = { "SOME_TABLE" }
|
||||||
|
t:copy_store(t2) -- t2 = [L3], t.obj = [L2]
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
co2()
|
||||||
|
co2 = nil
|
||||||
|
|
||||||
|
collectgarbage() -- t2 ref in t remains valid!
|
||||||
|
|
||||||
|
x:store(t:get()) -- t.obj = [L2], x.obj = [L1]
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
co()
|
||||||
|
collectgarbage()
|
||||||
|
collectgarbage()
|
||||||
|
co = nil
|
||||||
|
)";
|
||||||
|
|
||||||
|
struct co_test_implicit {
|
||||||
|
std::string identifier;
|
||||||
|
sol::reference obj;
|
||||||
|
|
||||||
|
co_test_implicit(sol::this_state L, std::string id) : identifier(id), obj(L, sol::lua_nil) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void store(sol::table ref) {
|
||||||
|
// must be explicit
|
||||||
|
obj = std::move(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_store(sol::table ref) {
|
||||||
|
// must be explicit
|
||||||
|
obj = ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::reference get() {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
~co_test_implicit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.open_libraries(sol::lib::coroutine, sol::lib::base);
|
||||||
|
|
||||||
|
lua.new_usertype<co_test_implicit>("co_test",
|
||||||
|
sol::constructors<co_test_implicit(sol::this_state, std::string)>(),
|
||||||
|
"store", &co_test_implicit::store,
|
||||||
|
"copy_store", &co_test_implicit::copy_store,
|
||||||
|
"get", &co_test_implicit::get
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
auto r = lua.safe_script(code);
|
||||||
|
REQUIRE(r.valid());
|
||||||
|
|
||||||
|
co_test_implicit& ct = lua["x"];
|
||||||
|
|
||||||
|
lua_State* Lmain1 = lua.lua_state();
|
||||||
|
lua_State* Lmain2 = sol::main_thread(lua);
|
||||||
|
lua_State* Lmain3 = ct.get().lua_state();
|
||||||
|
REQUIRE(Lmain1 == Lmain2);
|
||||||
|
REQUIRE(Lmain1 == Lmain3);
|
||||||
|
|
||||||
|
sol::table t = ct.get();
|
||||||
|
REQUIRE(t.size() == 1);
|
||||||
|
std::string s = t[1];
|
||||||
|
REQUIRE(s == "SOME_TABLE");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user