mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Fix up inheritance with special metamethods
- Inheritance was causing __index and __new_index to be overriden on the named metatables - This meant special constructors and other metamethods might not have been set properly - Use lua_rawset to directly slam dunk the value into the table
This commit is contained in:
parent
9c4e2d1094
commit
220335d95c
|
@ -1136,7 +1136,7 @@ namespace sol {
|
|||
template <typename T>
|
||||
using is_msvc_callable_rigged = meta::any<meta::is_specialization_of<T, push_invoke_t>, meta::is_specialization_of<T, as_table_t>,
|
||||
meta::is_specialization_of<T, forward_as_value_t>, meta::is_specialization_of<T, as_container_t>, meta::is_specialization_of<T, nested>,
|
||||
meta::is_specialization_of<T, yielding_t>, meta::is_specialization_of<T, ebco>>;
|
||||
meta::is_specialization_of<T, yielding_t>>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_msvc_callable_rigged_v = is_msvc_callable_rigged<T>::value;
|
||||
|
|
|
@ -647,11 +647,13 @@ namespace sol { namespace u_detail {
|
|||
|
||||
this->named_index_table.push();
|
||||
absolute_index metametatable_index(L, -1);
|
||||
std::string_view call_metamethod_name = to_string(meta_function::call);
|
||||
lua_pushlstring(L, call_metamethod_name.data(), call_metamethod_name.size());
|
||||
stack::push(L, nullptr);
|
||||
stack::push(L, b.data());
|
||||
lua_CFunction target_func = &b.template call<false, false>;
|
||||
lua_pushcclosure(L, target_func, 2);
|
||||
lua_setfield(L, metametatable_index, to_string(meta_function::call).c_str());
|
||||
lua_rawset(L, metametatable_index);
|
||||
this->named_index_table.pop();
|
||||
}
|
||||
else if constexpr (std::is_same_v<KeyU, base_classes_tag>) {
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// This file was generated with a script.
|
||||
// Generated 2020-12-18 04:17:10.718684 UTC
|
||||
// This header was generated with sol v3.2.3 (revision 561c90ab)
|
||||
// Generated 2020-12-18 15:03:36.644037 UTC
|
||||
// This header was generated with sol v3.2.3 (revision 9c4e2d10)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_CONFIG_HPP
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// This file was generated with a script.
|
||||
// Generated 2020-12-18 04:17:10.578992 UTC
|
||||
// This header was generated with sol v3.2.3 (revision 561c90ab)
|
||||
// Generated 2020-12-18 15:03:36.620043 UTC
|
||||
// This header was generated with sol v3.2.3 (revision 9c4e2d10)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// This file was generated with a script.
|
||||
// Generated 2020-12-18 04:17:09.361797 UTC
|
||||
// This header was generated with sol v3.2.3 (revision 561c90ab)
|
||||
// Generated 2020-12-18 15:03:35.924132 UTC
|
||||
// This header was generated with sol v3.2.3 (revision 9c4e2d10)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||
|
@ -7803,7 +7803,7 @@ namespace sol {
|
|||
template <typename T>
|
||||
using is_msvc_callable_rigged = meta::any<meta::is_specialization_of<T, push_invoke_t>, meta::is_specialization_of<T, as_table_t>,
|
||||
meta::is_specialization_of<T, forward_as_value_t>, meta::is_specialization_of<T, as_container_t>, meta::is_specialization_of<T, nested>,
|
||||
meta::is_specialization_of<T, yielding_t>, meta::is_specialization_of<T, ebco>>;
|
||||
meta::is_specialization_of<T, yielding_t>>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_msvc_callable_rigged_v = is_msvc_callable_rigged<T>::value;
|
||||
|
@ -22583,11 +22583,13 @@ namespace sol { namespace u_detail {
|
|||
|
||||
this->named_index_table.push();
|
||||
absolute_index metametatable_index(L, -1);
|
||||
std::string_view call_metamethod_name = to_string(meta_function::call);
|
||||
lua_pushlstring(L, call_metamethod_name.data(), call_metamethod_name.size());
|
||||
stack::push(L, nullptr);
|
||||
stack::push(L, b.data());
|
||||
lua_CFunction target_func = &b.template call<false, false>;
|
||||
lua_pushcclosure(L, target_func, 2);
|
||||
lua_setfield(L, metametatable_index, to_string(meta_function::call).c_str());
|
||||
lua_rawset(L, metametatable_index);
|
||||
this->named_index_table.pop();
|
||||
}
|
||||
else if constexpr (std::is_same_v<KeyU, base_classes_tag>) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
inline namespace sol2_test_usertypes_inheritance {
|
||||
struct inh_test_A {
|
||||
int a = 5;
|
||||
};
|
||||
|
@ -49,6 +50,24 @@ struct inh_test_D : inh_test_C {
|
|||
}
|
||||
};
|
||||
|
||||
class A {
|
||||
public:
|
||||
void hello() { std::cout << "This is class A" << std::endl; }
|
||||
virtual void vhello() { std::cout << "A::vhello" << std::endl; }
|
||||
virtual ~A() {}
|
||||
public:
|
||||
int a = 1;
|
||||
};
|
||||
|
||||
class B : public A {
|
||||
public:
|
||||
virtual void vhello() override { std::cout << "B::vhello" << std::endl; }
|
||||
virtual ~B() override {}
|
||||
public:
|
||||
int b = 2;
|
||||
};
|
||||
}
|
||||
|
||||
SOL_BASE_CLASSES(inh_test_D, inh_test_C);
|
||||
SOL_BASE_CLASSES(inh_test_C, inh_test_B, inh_test_A);
|
||||
SOL_DERIVED_CLASSES(inh_test_C, inh_test_D);
|
||||
|
@ -113,3 +132,37 @@ TEST_CASE("inheritance/usertype derived non-hiding", "usertype classes must play
|
|||
REQUIRE((lua.get<int>("dgn10") == 70));
|
||||
REQUIRE((lua.get<int>("dgn") == 7));
|
||||
}
|
||||
|
||||
TEST_CASE("inheritance/usertype metatable interference", "usertypes with overriden index/new_index methods (from e.g. base classes) were intercepting calls to the named metatable") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::coroutine, sol::lib::string, sol::lib::os, sol::lib::math, sol::lib::table, sol::lib::io, sol::lib::debug);
|
||||
|
||||
sol::usertype<A> uta = lua.new_usertype<A>("A", sol::base_classes, sol::base_list<>());
|
||||
uta.set(sol::call_constructor, sol::constructors<A()>());
|
||||
uta.set("a", &A::a);
|
||||
uta.set("hello", &A::hello);
|
||||
uta.set("vhello", &A::vhello);
|
||||
|
||||
sol::usertype<B> utb = lua.new_usertype<B>("B", sol::base_classes, sol::base_list<A>());
|
||||
utb.set(sol::call_constructor, sol::constructors<B()>());
|
||||
utb.set("b", &B::b);
|
||||
utb.set("vhello", &B::vhello);
|
||||
|
||||
sol::optional<sol::error> maybe_error0 = lua.safe_script(R"(
|
||||
local aa = A()
|
||||
aa:hello()
|
||||
)", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(maybe_error0.has_value());
|
||||
|
||||
sol::optional<sol::error> maybe_error1 = lua.safe_script(R"(
|
||||
local bb0 = B.new()
|
||||
bb0:hello()
|
||||
)", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(maybe_error1.has_value());
|
||||
|
||||
sol::optional<sol::error> maybe_error2 = lua.safe_script(R"(
|
||||
local bb1 = B()
|
||||
bb1:hello()
|
||||
)", sol::script_pass_on_error);
|
||||
REQUIRE_FALSE(maybe_error2.has_value());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user