A very simple fix for a very complex problem

This commit is contained in:
ThePhD 2019-04-05 18:56:37 -04:00
parent fbf94844b1
commit 2f7607840f
No known key found for this signature in database
GPG Key ID: 1509DB1C0F702BFA
4 changed files with 130 additions and 8 deletions

View File

@ -446,11 +446,17 @@ namespace sol { namespace u_detail {
}
(void)L;
(void)self;
// TODO: get base table, dump it out
#if defined(SOL_UNSAFE_BASE_LOOKUP) && SOL_UNSAFE_BASE_LOOKUP
usertype_storage_base& base_storage = get_usertype_storage<Base>(L);
base_result = self_index_call<is_new_index, true>(bases(), L, base_storage);
#else
optional<usertype_storage<Base>&> maybe_base_storage = maybe_get_usertype_storage<Base>(L);
if (maybe_base_storage.has_value()) {
base_result = self_index_call<is_new_index, true>(bases(), L, *maybe_base_storage);
keep_going = base_result == base_walking_failed_index;
}
#endif // Fast versus slow, safe base lookup
}
template <bool is_new_index = false, bool base_walking = false, bool from_named_metatable = false, typename... Bases>
static inline int self_index_call(types<Bases...>, lua_State* L, usertype_storage_base& self) {

View File

@ -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 2019-04-05 02:47:40.154863 UTC
// This header was generated with sol v3.0.1-beta2 (revision 83f702b)
// Generated 2019-04-05 22:56:20.263143 UTC
// This header was generated with sol v3.0.1-beta2 (revision fbf9484)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP

View File

@ -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 2019-04-05 02:47:39.333872 UTC
// This header was generated with sol v3.0.1-beta2 (revision 83f702b)
// Generated 2019-04-05 22:56:19.784998 UTC
// This header was generated with sol v3.0.1-beta2 (revision fbf9484)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP
@ -20927,11 +20927,17 @@ namespace sol { namespace u_detail {
}
(void)L;
(void)self;
// TODO: get base table, dump it out
#if defined(SOL_UNSAFE_BASE_LOOKUP) && SOL_UNSAFE_BASE_LOOKUP
usertype_storage_base& base_storage = get_usertype_storage<Base>(L);
base_result = self_index_call<is_new_index, true>(bases(), L, base_storage);
#else
optional<usertype_storage<Base>&> maybe_base_storage = maybe_get_usertype_storage<Base>(L);
if (maybe_base_storage.has_value()) {
base_result = self_index_call<is_new_index, true>(bases(), L, *maybe_base_storage);
keep_going = base_result == base_walking_failed_index;
}
#endif // Fast versus slow, safe base lookup
}
template <bool is_new_index = false, bool base_walking = false, bool from_named_metatable = false, typename... Bases>
static inline int self_index_call(types<Bases...>, lua_State* L, usertype_storage_base& self) {

View File

@ -287,3 +287,113 @@ 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/bad_base-class", "check to make sure bad/unregistered base classes do not blow up usertypes") {
struct a {
a(sol::this_state ts, sol::this_environment te) {
lua_State* L = ts;
ud = sol::userdata(L, -2);
}
sol::object get_property_lua(const char* name, sol::this_state s) {
return props[name];
}
void set_property_lua(const char* name, sol::stack_object object) {
props[name] = object.as<sol::object>();
}
std::unordered_map<std::string, sol::object> props;
sol::userdata ud;
};
struct nofun {
nofun() {
}
};
struct b : public a, public nofun {
b(sol::this_state ts, sol::this_environment te, int ab) : a(ts, te) {
sol::state_view lua = ts;
lua.script("function break_crap(b_obj) b_obj.test3 = {} end");
sol::protected_function pf = lua["break_crap"];
sol::optional<sol::error> result = pf(this);
REQUIRE_FALSE(result.has_value());
}
b(sol::this_state ts, sol::this_environment te, int ab, int bc) : a(ts, te) {
}
~b() {
}
};
struct c : public b {
c(sol::this_state ts, sol::this_environment te, int ab) : b(ts, te, ab) {
}
c(sol::this_state ts, sol::this_environment te, int ab, int bc) : b(ts, te, ab, bc) {
}
~c() {
}
};
sol::state lua;
lua.open_libraries(sol::lib::base, sol::lib::os, sol::lib::string, sol::lib::math, sol::lib::table, sol::lib::package, sol::lib::debug);
lua.new_usertype<a>("a", sol::meta_function::new_index, &a::set_property_lua, sol::meta_function::index, &a::get_property_lua);
lua.new_usertype<b>("b",
sol::constructors<b(sol::this_state, sol::this_environment, int), b(sol::this_state, sol::this_environment, int, int)>(),
sol::meta_function::new_index,
&b::set_property_lua,
sol::meta_function::index,
&b::get_property_lua,
sol::base_classes,
sol::bases<a, nofun>());
lua.new_usertype<c>("c",
sol::constructors<c(sol::this_state, sol::this_environment, int), c(sol::this_state, sol::this_environment, int, int)>(),
sol::meta_function::new_index,
&c::set_property_lua,
sol::meta_function::index,
&c::get_property_lua,
sol::base_classes,
sol::bases<b>());
lua.script(R"(
function init_entity(e)
init_entity_properties(e)
return true
end
function init_entity_properties(e)
e._internal_entity_properties_ = {}
function e : GetName()
return self._internal_entity_properties_['name']
end
function e : SetName(s)
self._internal_entity_properties_['name'] = s
end
--return e
end
)");
sol::optional<sol::error> result = lua.safe_script("b_tmp = b.new(1)", sol::script_pass_on_error);
REQUIRE_FALSE(result.has_value());
a* b_base = lua["b_tmp"]; // get the base...
sol::protected_function pf = lua["init_entity"];
sol::optional<sol::error> result1 = pf(b_base);
REQUIRE_FALSE(result1.has_value());
sol::optional<sol::error> result2 = lua.script("c_tmp = c.new(1)", sol::script_pass_on_error);
REQUIRE_FALSE(result2.has_value());
}