Fix segfault by initialization of BaseHolder type
This commit is contained in:
parent
ca6ffd040d
commit
df871d3c8e
@ -22,7 +22,8 @@ void SharedTable::set(StoredObject key, StoredObject value) noexcept {
|
||||
}
|
||||
|
||||
void SharedTable::luaSet(sol::stack_object luaKey, sol::stack_object luaValue) noexcept {
|
||||
assert(luaKey.valid());
|
||||
if (!luaKey.valid())
|
||||
throw sol::error("Invalid table index");
|
||||
|
||||
StoredObject key(luaKey);
|
||||
if (luaValue.get_type() == sol::type::nil) {
|
||||
|
||||
@ -17,24 +17,19 @@ template<typename StoredType>
|
||||
class PrimitiveHolder : public BaseHolder {
|
||||
public:
|
||||
PrimitiveHolder(sol::stack_object luaObject) noexcept
|
||||
: data_(luaObject.as<StoredType>()) {}
|
||||
: BaseHolder(luaObject.get_type()), data_(luaObject.as<StoredType>()) {}
|
||||
|
||||
PrimitiveHolder(sol::object luaObject) noexcept
|
||||
: data_(luaObject.as<StoredType>()) {}
|
||||
: BaseHolder(luaObject.get_type()), data_(luaObject.as<StoredType>()) {}
|
||||
|
||||
PrimitiveHolder(const StoredType& init) noexcept
|
||||
: data_(init) {}
|
||||
PrimitiveHolder(sol::type type, const StoredType& init) noexcept
|
||||
: BaseHolder(type), data_(init) {}
|
||||
|
||||
bool rawCompare(const BaseHolder* other) const noexcept final {
|
||||
assert(type_ == other->type());
|
||||
return static_cast<const PrimitiveHolder<StoredType>*>(other)->data_ == data_;
|
||||
}
|
||||
|
||||
bool rawLess(const BaseHolder* other) const noexcept final {
|
||||
assert(type_ == other->type());
|
||||
return data_ < static_cast<const PrimitiveHolder<StoredType>*>(other)->data_;
|
||||
}
|
||||
|
||||
std::size_t hash() const noexcept final {
|
||||
return std::hash<StoredType>()(data_);
|
||||
}
|
||||
@ -50,7 +45,8 @@ private:
|
||||
class FunctionHolder : public BaseHolder {
|
||||
public:
|
||||
template<typename SolObject>
|
||||
FunctionHolder(SolObject luaObject) noexcept {
|
||||
FunctionHolder(SolObject luaObject) noexcept
|
||||
: BaseHolder(sol::type::function) {
|
||||
sol::state_view lua(luaObject.lua_state());
|
||||
sol::function dumper = lua["string"]["dump"];
|
||||
|
||||
@ -62,10 +58,6 @@ public:
|
||||
return function_ == static_cast<const FunctionHolder*>(other)->function_;
|
||||
}
|
||||
|
||||
bool rawLess(const BaseHolder* other) const noexcept final {
|
||||
return function_ < static_cast<const FunctionHolder*>(other)->function_;
|
||||
}
|
||||
|
||||
std::size_t hash() const noexcept final {
|
||||
return std::hash<std::string>()(function_);
|
||||
}
|
||||
@ -149,7 +141,7 @@ std::unique_ptr<BaseHolder> fromSolObject(SolObject luaObject) {
|
||||
// SolTableToShared is used to prevent from infinity recursion
|
||||
// in recursive tables
|
||||
dumpTable(table, luaTable, visited);
|
||||
return std::make_unique<PrimitiveHolder<SharedTable*>>(table);
|
||||
return std::make_unique<PrimitiveHolder<SharedTable*>>(sol::type::userdata, table);
|
||||
}
|
||||
default:
|
||||
ERROR << "Unable to store object of that type: " << (int)luaObject.get_type() << std::endl;
|
||||
@ -163,7 +155,7 @@ StoredObject::StoredObject(StoredObject&& init) noexcept
|
||||
: data_(std::move(init.data_)) {}
|
||||
|
||||
StoredObject::StoredObject(SharedTable* table) noexcept
|
||||
: data_(new PrimitiveHolder<SharedTable*>(table)) {
|
||||
: data_(new PrimitiveHolder<SharedTable*>(sol::type::userdata, table)) {
|
||||
}
|
||||
|
||||
StoredObject::StoredObject(sol::object object) noexcept
|
||||
@ -204,11 +196,4 @@ bool StoredObject::operator==(const StoredObject& o) const noexcept {
|
||||
return data_.get() == o.data_.get();
|
||||
}
|
||||
|
||||
bool StoredObject::operator<(const StoredObject& o) const noexcept {
|
||||
if (data_)
|
||||
return data_->less(o.data_.get());
|
||||
else
|
||||
return data_.get() < o.data_.get();
|
||||
}
|
||||
|
||||
} // effil
|
||||
|
||||
@ -9,7 +9,7 @@ namespace effil {
|
||||
|
||||
class BaseHolder {
|
||||
public:
|
||||
BaseHolder() noexcept : type_(sol::type::nil) {}
|
||||
BaseHolder(sol::type t) noexcept : type_(t) {}
|
||||
virtual ~BaseHolder() = default;
|
||||
|
||||
sol::type type() const noexcept {
|
||||
@ -20,13 +20,8 @@ public:
|
||||
assert(other != nullptr);
|
||||
return type_ == other->type_ && rawCompare(other);
|
||||
}
|
||||
virtual bool less(const BaseHolder* other) const noexcept {
|
||||
assert(other != nullptr);
|
||||
return type_ < other->type_ && rawLess(other);
|
||||
}
|
||||
|
||||
virtual bool rawCompare(const BaseHolder* other) const noexcept = 0;
|
||||
virtual bool rawLess(const BaseHolder* other) const noexcept = 0;
|
||||
virtual std::size_t hash() const noexcept = 0;
|
||||
virtual sol::object unpack(sol::this_state state) const noexcept = 0;
|
||||
|
||||
@ -53,7 +48,6 @@ public:
|
||||
sol::object unpack(sol::this_state state) const noexcept;
|
||||
StoredObject& operator=(StoredObject&& o) noexcept;
|
||||
bool operator==(const StoredObject& o) const noexcept;
|
||||
bool operator<(const StoredObject& o) const noexcept;
|
||||
|
||||
private:
|
||||
std::unique_ptr<BaseHolder> data_;
|
||||
|
||||
@ -34,12 +34,12 @@ st.del = "secret"
|
||||
st.del = nil
|
||||
)");
|
||||
|
||||
ASSERT_TRUE(res1.valid()) << "Set res1 failed";
|
||||
ASSERT_EQ(lua["st"]["fst"], std::string("first"));
|
||||
ASSERT_EQ(lua["st"]["snd"], (double)2);
|
||||
ASSERT_EQ(lua["st"]["thr"], true);
|
||||
ASSERT_EQ(lua["st"]["del"], sol::nil);
|
||||
ASSERT_EQ(lua["st"]["nex"], sol::nil);
|
||||
EXPECT_TRUE(res1.valid()) << "Set res1 failed";
|
||||
EXPECT_EQ(lua["st"]["fst"], std::string("first"));
|
||||
EXPECT_EQ(lua["st"]["snd"], (double)2);
|
||||
EXPECT_EQ(lua["st"]["thr"], true);
|
||||
EXPECT_EQ(lua["st"]["del"], sol::nil);
|
||||
EXPECT_EQ(lua["st"]["nex"], sol::nil);
|
||||
|
||||
auto res2 = lua.script(R"(
|
||||
st[1] = 3
|
||||
@ -50,20 +50,20 @@ st[42] = nil
|
||||
st.deleted = st[42] == nil
|
||||
)");
|
||||
|
||||
ASSERT_TRUE(res2.valid()) << "Set res2 failed";
|
||||
ASSERT_EQ(lua["st"][1], 3);
|
||||
ASSERT_EQ(lua["st"][2], std::string("number"));
|
||||
ASSERT_EQ(lua["st"][-1], false);
|
||||
ASSERT_EQ(lua["st"]["deleted"], true);
|
||||
EXPECT_TRUE(res2.valid()) << "Set res2 failed";
|
||||
EXPECT_EQ(lua["st"][1], 3);
|
||||
EXPECT_EQ(lua["st"][2], std::string("number"));
|
||||
EXPECT_EQ(lua["st"][-1], false);
|
||||
EXPECT_EQ(lua["st"]["deleted"], true);
|
||||
|
||||
auto res3 = lua.script(R"(
|
||||
st[true] = false
|
||||
st[false] = 9
|
||||
)");
|
||||
|
||||
ASSERT_TRUE(res3.valid()) << "Set res3 failed";
|
||||
ASSERT_EQ(lua["st"][true], false);
|
||||
ASSERT_EQ(lua["st"][false], 9);
|
||||
EXPECT_TRUE(res3.valid()) << "Set res3 failed";
|
||||
EXPECT_EQ(lua["st"][true], false);
|
||||
EXPECT_EQ(lua["st"][false], 9);
|
||||
}
|
||||
|
||||
TEST(sharedTable, multipleStates) {
|
||||
@ -82,9 +82,9 @@ cats.sparky = false
|
||||
cats.wow = 3
|
||||
)");
|
||||
|
||||
ASSERT_EQ(lua2["dogs"]["fluffy"], std::string("gav"));
|
||||
ASSERT_EQ(lua2["dogs"]["sparky"], false);
|
||||
ASSERT_EQ(lua2["dogs"]["wow"], 3);
|
||||
EXPECT_EQ(lua2["dogs"]["fluffy"], std::string("gav"));
|
||||
EXPECT_EQ(lua2["dogs"]["sparky"], false);
|
||||
EXPECT_EQ(lua2["dogs"]["wow"], 3);
|
||||
}
|
||||
|
||||
TEST(sharedTable, multipleThreads) {
|
||||
@ -126,9 +126,9 @@ st.thr = true)");
|
||||
|
||||
for(auto& thread : threads) { thread.join(); }
|
||||
|
||||
ASSERT_EQ(lua["st"]["fst"], true);
|
||||
ASSERT_EQ(lua["st"]["snd"], true);
|
||||
ASSERT_EQ(lua["st"]["thr"], true);
|
||||
EXPECT_EQ(lua["st"]["fst"], true);
|
||||
EXPECT_EQ(lua["st"]["snd"], true);
|
||||
EXPECT_EQ(lua["st"]["thr"], true);
|
||||
}
|
||||
|
||||
TEST(sharedTable, playingWithSharedTables) {
|
||||
@ -146,8 +146,8 @@ st1.proxy.value = true
|
||||
recursive.next = recursive
|
||||
recursive.val = "yes"
|
||||
)");
|
||||
ASSERT_EQ(lua["st2"]["value"], true);
|
||||
ASSERT_EQ(lua["recursive"]["next"]["next"]["next"]["val"], std::string("yes"));
|
||||
EXPECT_EQ(lua["st2"]["value"], true);
|
||||
EXPECT_EQ(lua["recursive"]["next"]["next"]["next"]["val"], std::string("yes"));
|
||||
}
|
||||
|
||||
TEST(sharedTable, playingWithFunctions) {
|
||||
@ -166,7 +166,7 @@ st.fn()
|
||||
)");
|
||||
|
||||
sol::function sf = lua["st"]["fn"];
|
||||
ASSERT_TRUE((bool)sf());
|
||||
EXPECT_TRUE((bool)sf());
|
||||
|
||||
sol::state lua2;
|
||||
bootstrapState(lua2);
|
||||
@ -180,7 +180,7 @@ end
|
||||
|
||||
sol::function sf2 = lua["st"]["fn2"];
|
||||
|
||||
ASSERT_EQ(sf2(std::string("SUCCESS")).get<std::string>(), std::string("*SUCCESS*"));
|
||||
EXPECT_EQ(sf2(std::string("SUCCESS")).get<std::string>(), std::string("*SUCCESS*"));
|
||||
}
|
||||
|
||||
TEST(sharedTable, playingWithTables) {
|
||||
@ -207,15 +207,15 @@ recursive.val = "recursive"
|
||||
st.recursive = recursive
|
||||
)");
|
||||
|
||||
ASSERT_TRUE(res.valid());
|
||||
ASSERT_EQ(lua["st"]["person"]["name"], std::string("John Doe"));
|
||||
ASSERT_EQ(lua["st"]["person"]["age"], 25);
|
||||
ASSERT_EQ(lua["st"]["pet"]["type"], std::string("cat"));
|
||||
ASSERT_EQ(lua["st"]["pet"]["name"], std::string("Tomas"));
|
||||
ASSERT_EQ(lua["st"]["pet"]["real"], std::string("Яша"));
|
||||
ASSERT_EQ(lua["st"]["pet"]["spec"]["colour"], std::string("grey"));
|
||||
ASSERT_EQ(lua["st"]["pet"]["spec"]["legs"], 4);
|
||||
ASSERT_EQ(lua["st"]["recursive"]["prev"]["next"]["next"]["val"], std::string("recursive"));
|
||||
EXPECT_TRUE(res.valid());
|
||||
EXPECT_EQ(lua["st"]["person"]["name"], std::string("John Doe"));
|
||||
EXPECT_EQ(lua["st"]["person"]["age"], 25);
|
||||
EXPECT_EQ(lua["st"]["pet"]["type"], std::string("cat"));
|
||||
EXPECT_EQ(lua["st"]["pet"]["name"], std::string("Tomas"));
|
||||
EXPECT_EQ(lua["st"]["pet"]["real"], std::string("Яша"));
|
||||
EXPECT_EQ(lua["st"]["pet"]["spec"]["colour"], std::string("grey"));
|
||||
EXPECT_EQ(lua["st"]["pet"]["spec"]["legs"], 4);
|
||||
EXPECT_EQ(lua["st"]["recursive"]["prev"]["next"]["next"]["val"], std::string("recursive"));
|
||||
|
||||
defaultPool().clear();
|
||||
}
|
||||
@ -233,16 +233,16 @@ for i = 1, 1000000 do
|
||||
end
|
||||
)");
|
||||
|
||||
ASSERT_TRUE(res1.valid());
|
||||
ASSERT_TRUE(st.size() == 1'000'000);
|
||||
EXPECT_TRUE(res1.valid());
|
||||
EXPECT_TRUE(st.size() == 1'000'000);
|
||||
|
||||
auto res2 = lua.script(R"(
|
||||
for i = 1000000, 1, -1 do
|
||||
st[i] = nil
|
||||
end
|
||||
)");
|
||||
ASSERT_TRUE(res2.valid());
|
||||
ASSERT_TRUE(st.size() == 0);
|
||||
EXPECT_TRUE(res2.valid());
|
||||
EXPECT_TRUE(st.size() == 0);
|
||||
}
|
||||
|
||||
TEST(sharedTable, stressWithThreads) {
|
||||
@ -272,6 +272,6 @@ TEST(sharedTable, stressWithThreads) {
|
||||
bootstrapState(lua);
|
||||
lua["st"] = &st;
|
||||
for(size_t i = 0; i < threadCount; i++) {
|
||||
ASSERT_TRUE(lua["st"][i] == 100'001) << (double)lua["st"][i] << std::endl;
|
||||
EXPECT_TRUE(lua["st"][i] == 100'001) << (double)lua["st"][i] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user