diff --git a/lib/include/pl/api.hpp b/lib/include/pl/api.hpp index f90bbf0d..6317692b 100644 --- a/lib/include/pl/api.hpp +++ b/lib/include/pl/api.hpp @@ -126,7 +126,7 @@ namespace pl::api { /** * @brief A function callback called when a custom built-in type is being instantiated */ - using TypeCallback = std::function(core::Evaluator *, const std::vector &)>; + using TypeCallback = std::function(core::Evaluator *, const std::vector &)>; /** * @brief A type representing a function. diff --git a/lib/include/pl/patterns/pattern.hpp b/lib/include/pl/patterns/pattern.hpp index e0cd35da..6e6238d0 100644 --- a/lib/include/pl/patterns/pattern.hpp +++ b/lib/include/pl/patterns/pattern.hpp @@ -116,7 +116,13 @@ namespace pl::ptrn { } virtual std::shared_ptr clone() const = 0; - std::shared_ptr reference() { return shared_from_this(); } + std::shared_ptr reference() { + auto weakPtr = weak_from_this(); + if (weakPtr.expired()) { + core::err::E0001.throwError("Cannot call shared_from_this if this is not shared."); + } + return shared_from_this(); + } [[nodiscard]] u64 getOffset() const { return this->m_offset; } [[nodiscard]] virtual u128 getOffsetForSorting() const { return this->getOffset() << 3; } @@ -538,14 +544,14 @@ namespace pl::ptrn { } [[nodiscard]] const Pattern* getParent() const { - return m_parent; + return m_parent.lock().get(); } [[nodiscard]] Pattern* getParent() { - return m_parent; + return m_parent.lock().get(); } - void setParent(Pattern *parent) { + void setParent(std::shared_ptr parent) { m_parent = parent; } @@ -623,7 +629,7 @@ namespace pl::ptrn { core::Evaluator *m_evaluator; std::unique_ptr>> m_attributes; - Pattern *m_parent = nullptr; + std::weak_ptr m_parent; u32 m_line = 0; std::set::const_iterator m_variableName; diff --git a/lib/include/pl/patterns/pattern_array_dynamic.hpp b/lib/include/pl/patterns/pattern_array_dynamic.hpp index 7334f1eb..4e7f14e8 100644 --- a/lib/include/pl/patterns/pattern_array_dynamic.hpp +++ b/lib/include/pl/patterns/pattern_array_dynamic.hpp @@ -20,7 +20,11 @@ namespace pl::ptrn { } [[nodiscard]] std::shared_ptr clone() const override { - return std::unique_ptr(new PatternArrayDynamic(*this)); + auto other = std::make_shared(*this); + for (const auto &entry : other->m_entries) + entry->setParent(other->reference()); + + return other; } void setColor(u32 color) override { @@ -133,7 +137,6 @@ namespace pl::ptrn { if (!entry->hasOverriddenColor()) entry->setBaseColor(this->getColor()); - entry->setParent(this); this->m_entries.emplace_back(entry); } diff --git a/lib/include/pl/patterns/pattern_array_static.hpp b/lib/include/pl/patterns/pattern_array_static.hpp index 36de9798..4e5d004c 100644 --- a/lib/include/pl/patterns/pattern_array_static.hpp +++ b/lib/include/pl/patterns/pattern_array_static.hpp @@ -16,7 +16,9 @@ namespace pl::ptrn { } [[nodiscard]] std::shared_ptr clone() const override { - return std::unique_ptr(new PatternArrayStatic(*this)); + auto other = std::make_shared(*this); + other->m_template->setParent(other->reference()); + return other; } [[nodiscard]] std::shared_ptr getEntry(size_t index) const override { @@ -153,7 +155,6 @@ namespace pl::ptrn { void setEntries(std::shared_ptr &&templatePattern, size_t count) { this->m_template = std::move(templatePattern); - this->m_template->setParent(this); this->m_highlightTemplates.push_back(this->m_template->clone()); this->m_entryCount = count; diff --git a/lib/include/pl/patterns/pattern_bitfield.hpp b/lib/include/pl/patterns/pattern_bitfield.hpp index de64a087..812b56a7 100644 --- a/lib/include/pl/patterns/pattern_bitfield.hpp +++ b/lib/include/pl/patterns/pattern_bitfield.hpp @@ -55,7 +55,8 @@ namespace pl::ptrn { public: PatternBitfieldField(core::Evaluator *evaluator, u64 offset, u8 bitOffset, u8 bitSize, u32 line, PatternBitfieldMember *parentBitfield = nullptr) : PatternBitfieldMember(evaluator, offset, (bitOffset + bitSize + 7) / 8, line), m_bitOffset(bitOffset % 8), m_bitSize(bitSize) { - this->setParent(parentBitfield); + if (parentBitfield != nullptr) + this->setParent(parentBitfield->reference()); } PatternBitfieldField(const PatternBitfieldField &other) : PatternBitfieldMember(other) { @@ -282,7 +283,10 @@ namespace pl::ptrn { } [[nodiscard]] std::shared_ptr clone() const override { - return std::unique_ptr(new PatternBitfieldArray(*this)); + auto other = std::make_shared(*this); + for (const auto &entry : other->m_entries) + entry->setParent(other->reference()); + return other; } [[nodiscard]] u8 getBitOffset() const override { @@ -422,8 +426,6 @@ namespace pl::ptrn { if (!entry->hasOverriddenColor()) entry->setBaseColor(this->getColor()); - entry->setParent(this); - this->m_sortedEntries.push_back(entry.get()); } @@ -643,7 +645,7 @@ namespace pl::ptrn { this->setBaseColor(this->m_fields.front()->getColor()); for (const auto &field : this->m_fields) { - field->setParent(this); + field->setParent(this->reference()); this->m_sortedFields.push_back(field.get()); } } diff --git a/lib/include/pl/patterns/pattern_struct.hpp b/lib/include/pl/patterns/pattern_struct.hpp index 3bd42bbd..032dda26 100644 --- a/lib/include/pl/patterns/pattern_struct.hpp +++ b/lib/include/pl/patterns/pattern_struct.hpp @@ -15,14 +15,17 @@ namespace pl::ptrn { for (const auto &member : other.m_members) { auto copy = member->clone(); - copy->setParent(this); this->m_sortedMembers.push_back(copy.get()); this->m_members.push_back(std::move(copy)); } } [[nodiscard]] std::shared_ptr clone() const override { - return std::unique_ptr(new PatternStruct(*this)); + auto other = std::make_shared(*this); + for (const auto &member : other->m_members) + member->setParent(other->reference()); + + return other; } [[nodiscard]] std::shared_ptr getEntry(size_t index) const override { @@ -36,7 +39,7 @@ namespace pl::ptrn { void addEntry(const std::shared_ptr &entry) override { if (entry == nullptr) return; - entry->setParent(this); + entry->setParent(this->reference()); this->m_sortedMembers.push_back(entry.get()); this->m_members.push_back(entry); } diff --git a/lib/include/pl/patterns/pattern_union.hpp b/lib/include/pl/patterns/pattern_union.hpp index fa2939e3..a1ddd179 100644 --- a/lib/include/pl/patterns/pattern_union.hpp +++ b/lib/include/pl/patterns/pattern_union.hpp @@ -21,7 +21,11 @@ namespace pl::ptrn { } [[nodiscard]] std::shared_ptr clone() const override { - return std::unique_ptr(new PatternUnion(*this)); + auto other = std::make_shared(*this); + for (const auto &member : other->m_members) + member->setParent(other->reference()); + + return other; } [[nodiscard]] std::shared_ptr getEntry(size_t index) const override { @@ -35,7 +39,6 @@ namespace pl::ptrn { void addEntry(const std::shared_ptr &entry) override { if (entry == nullptr) return; - entry->setParent(this); this->m_sortedMembers.push_back(entry.get()); this->m_members.push_back(entry); } diff --git a/lib/source/pl/core/ast/ast_node_bitfield.cpp b/lib/source/pl/core/ast/ast_node_bitfield.cpp index fde1deca..7f95226d 100644 --- a/lib/source/pl/core/ast/ast_node_bitfield.cpp +++ b/lib/source/pl/core/ast/ast_node_bitfield.cpp @@ -139,7 +139,7 @@ namespace pl::core::ast { for (auto &pattern : potentialPatterns) { if (auto bitfieldMember = dynamic_cast(pattern.get()); bitfieldMember != nullptr) { - bitfieldMember->setParent(bitfieldPattern.get()); + bitfieldMember->setParent(bitfieldPattern->reference()); if (!bitfieldMember->isPadding()) fields.push_back(pattern); } else { diff --git a/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp b/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp index 7a87c518..7d82fa32 100644 --- a/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp +++ b/lib/source/pl/core/ast/ast_node_bitfield_array_variable_decl.cpp @@ -53,7 +53,7 @@ namespace pl::core::ast { }; auto position = evaluator->getBitwiseReadOffset(); - auto arrayPattern = std::make_unique(evaluator, position.byteOffset, position.bitOffset, 0, getLocation().line); + auto arrayPattern = std::make_shared(evaluator, position.byteOffset, position.bitOffset, 0, getLocation().line); arrayPattern->setVariableName(this->m_name); arrayPattern->setSection(evaluator->getSectionId()); arrayPattern->setReversed(evaluator->isReadOrderReversed()); @@ -133,7 +133,7 @@ namespace pl::core::ast { for (auto &pattern : entries) { if (auto bitfieldMember = dynamic_cast(pattern.get()); bitfieldMember != nullptr) - bitfieldMember->setParent(arrayPattern.get()); + bitfieldMember->setParent(arrayPattern->reference()); } arrayPattern->setEntries(entries); diff --git a/lib/source/pl/core/ast/ast_node_builtin_type.cpp b/lib/source/pl/core/ast/ast_node_builtin_type.cpp index 9f0b2a29..fbac27f8 100644 --- a/lib/source/pl/core/ast/ast_node_builtin_type.cpp +++ b/lib/source/pl/core/ast/ast_node_builtin_type.cpp @@ -23,23 +23,23 @@ namespace pl::core::ast { auto size = Token::getTypeSize(this->m_type); auto offset = evaluator->getReadOffsetAndIncrement(size); - std::unique_ptr pattern; + std::shared_ptr pattern; if (Token::isUnsigned(this->m_type)) - pattern = std::make_unique(evaluator, offset, size, getLocation().line); + pattern = std::make_shared(evaluator, offset, size, getLocation().line); else if (Token::isSigned(this->m_type)) - pattern = std::make_unique(evaluator, offset, size, getLocation().line); + pattern = std::make_shared(evaluator, offset, size, getLocation().line); else if (Token::isFloatingPoint(this->m_type)) - pattern = std::make_unique(evaluator, offset, size, getLocation().line); + pattern = std::make_shared(evaluator, offset, size, getLocation().line); else if (this->m_type == Token::ValueType::Boolean) - pattern = std::make_unique(evaluator, offset, getLocation().line); + pattern = std::make_shared(evaluator, offset, getLocation().line); else if (this->m_type == Token::ValueType::Character) - pattern = std::make_unique(evaluator, offset, getLocation().line); + pattern = std::make_shared(evaluator, offset, getLocation().line); else if (this->m_type == Token::ValueType::Character16) - pattern = std::make_unique(evaluator, offset, getLocation().line); + pattern = std::make_shared(evaluator, offset, getLocation().line); else if (this->m_type == Token::ValueType::Padding) - pattern = std::make_unique(evaluator, offset, 1, getLocation().line); + pattern = std::make_shared(evaluator, offset, 1, getLocation().line); else if (this->m_type == Token::ValueType::String) - pattern = std::make_unique(evaluator, offset, 0, getLocation().line); + pattern = std::make_shared(evaluator, offset, 0, getLocation().line); else if (this->m_type == Token::ValueType::CustomType) { std::vector params; diff --git a/tests/include/test_patterns/test_pattern.hpp b/tests/include/test_patterns/test_pattern.hpp index 78a054b0..cd8853de 100644 --- a/tests/include/test_patterns/test_pattern.hpp +++ b/tests/include/test_patterns/test_pattern.hpp @@ -30,18 +30,18 @@ namespace pl::test { virtual ~TestPattern() = default; template - std::unique_ptr create(const std::string &typeName, const std::string &varName, auto... args) { - auto pattern = std::make_unique(m_evaluator, args...); + std::shared_ptr create(const std::string &typeName, const std::string &varName, auto... args) { + auto pattern = std::make_shared(m_evaluator, args...); pattern->setTypeName(typeName); pattern->setVariableName(varName); - return std::move(pattern); + return pattern; } [[nodiscard]] virtual std::string getSourceCode() const = 0; - [[nodiscard]] virtual const std::vector> &getPatterns() const final { return this->m_patterns; } - virtual void addPattern(std::unique_ptr &&pattern) final { + [[nodiscard]] virtual const std::vector> &getPatterns() const final { return this->m_patterns; } + virtual void addPattern(std::shared_ptr &&pattern) final { this->m_patterns.push_back(std::move(pattern)); } @@ -60,7 +60,7 @@ namespace pl::test { } private: - std::vector> m_patterns; + std::vector> m_patterns; core::Evaluator *m_evaluator; Mode m_mode; diff --git a/tests/include/test_patterns/test_pattern_bitfields.hpp b/tests/include/test_patterns/test_pattern_bitfields.hpp index 0b41af6d..cb3c69ea 100644 --- a/tests/include/test_patterns/test_pattern_bitfields.hpp +++ b/tests/include/test_patterns/test_pattern_bitfields.hpp @@ -22,7 +22,7 @@ namespace pl::test { nestedFields.push_back(create("", "nestedA", 0x25, 5, 4, 0, testBitfield.get())); nestedFields.push_back(create("", "nestedB", 0x26, 1, 4, 0, testBitfield.get())); } - nestedBitfield->setParent(testBitfield.get()); + nestedBitfield->setParent(testBitfield->reference()); nestedBitfield->setFields(std::move(nestedFields)); nestedBitfield->setEndian(std::endian::big); bitfieldFields.push_back(std::move(nestedBitfield)); @@ -39,7 +39,7 @@ namespace pl::test { array0Fields.push_back(create("", "nestedA", 0x27, 5, 4, 0, array0Bitfield.get())); array0Fields.push_back(create("", "nestedB", 0x28, 1, 4, 0, array0Bitfield.get())); } - array0Bitfield->setParent(array.get()); + array0Bitfield->setParent(array->reference()); array0Bitfield->setFields(std::move(array0Fields)); array0Bitfield->setEndian(std::endian::big); arrayEntries.push_back(std::move(array0Bitfield)); @@ -50,12 +50,12 @@ namespace pl::test { array1Fields.push_back(create("", "nestedA", 0x28, 5, 4, 0, array1Bitfield.get())); array1Fields.push_back(create("", "nestedB", 0x29, 1, 4, 0, array1Bitfield.get())); } - array1Bitfield->setParent(array.get()); + array1Bitfield->setParent(array->reference()); array1Bitfield->setFields(std::move(array1Fields)); array1Bitfield->setEndian(std::endian::big); arrayEntries.push_back(std::move(array1Bitfield)); } - array->setParent(testBitfield.get()); + array->setParent(testBitfield->reference()); array->setEntries(arrayEntries); array->setEndian(std::endian::big); bitfieldFields.push_back(std::move(array));