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>
|
||||
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>) {
|
||||
return detail::usertype_alloc_destruct<T>(L);
|
||||
}
|
||||
else {
|
||||
if constexpr (std::is_void_v<T>) {
|
||||
using bt = meta::bind_traits<meta::unqualified_t<decltype(f.fx)>>;
|
||||
using arg0_t = typename bt::template arg_at<0>;
|
||||
|
||||
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;
|
||||
}
|
||||
using uFx = meta::unqualified_t<Fx>;
|
||||
lua_call_wrapper<T, uFx, is_index, is_variable, checked, boost, clean_stack> lcw{};
|
||||
return lcw.call(L, std::forward<F>(f).fx);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -595,3 +595,29 @@ TEST_CASE("gc/alignment", "test that allocation is always on aligned boundaries,
|
|||
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