mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
improve gc and call handling, o boi
This commit is contained in:
parent
b7050de53b
commit
55ebe1b76a
|
@ -672,26 +672,16 @@ namespace sol {
|
||||||
|
|
||||||
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
|
||||||
struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, clean_stack, C> {
|
struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, clean_stack, C> {
|
||||||
typedef destructor_wrapper<Fx> F;
|
|
||||||
|
|
||||||
static int call(lua_State* L, const F& f) {
|
template <typename F>
|
||||||
|
static int call(lua_State* L, F&& f) {
|
||||||
if constexpr (std::is_void_v<Fx>) {
|
if constexpr (std::is_void_v<Fx>) {
|
||||||
return detail::usertype_alloc_destruct<T>(L);
|
return detail::usertype_alloc_destruct<T>(L);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if constexpr (std::is_void_v<T>) {
|
using uFx = meta::unqualified_t<Fx>;
|
||||||
using bt = meta::bind_traits<meta::unqualified_t<decltype(f.fx)>>;
|
lua_call_wrapper<T, uFx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||||
using arg0_t = typename bt::template arg_at<0>;
|
return lcw.call(L, std::forward<F>(f).fx);
|
||||||
|
|
||||||
decltype(auto) obj = stack::get<arg0_t>(L, -1);
|
|
||||||
f.fx(detail::implicit_wrapper<std::remove_reference_t<decltype(obj)>>(obj));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
T& obj = stack::get<T>(L, -1);
|
|
||||||
f.fx(detail::implicit_wrapper<T>(obj));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -595,3 +595,29 @@ TEST_CASE("gc/alignment", "test that allocation is always on aligned boundaries,
|
||||||
lobj.check_alignment();
|
lobj.check_alignment();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("gc/multi-argument destructors", "make sure transparent arguments come along for the ride") {
|
||||||
|
static int transparent_foos_destroyed = 0;
|
||||||
|
|
||||||
|
struct transparent_foo {
|
||||||
|
~transparent_foo() {
|
||||||
|
++transparent_foos_destroyed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
lua_State* lua_state = nullptr;
|
||||||
|
lua_State* call_state = nullptr;
|
||||||
|
auto call_des = [&call_state](transparent_foo* f, sol::this_state s) {
|
||||||
|
call_state = s;
|
||||||
|
return f->~transparent_foo();
|
||||||
|
};
|
||||||
|
{
|
||||||
|
sol::state lua;
|
||||||
|
lua_state = lua;
|
||||||
|
lua.new_usertype<transparent_foo>("foo", sol::meta_function::garbage_collect, sol::destructor(std::move(call_des)));
|
||||||
|
|
||||||
|
lua.script("foo.new()");
|
||||||
|
}
|
||||||
|
REQUIRE(transparent_foos_destroyed == 1);
|
||||||
|
REQUIRE(call_state == lua_state);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user