Skip to content

Commit c5c7005

Browse files
committed
pattern: Speed up pattern post-processing
1 parent 8be1680 commit c5c7005

23 files changed

Lines changed: 178 additions & 59 deletions

generators/include/pl/formatters/formatter_html.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ namespace pl::gen::fmt {
1818
}
1919

2020
private:
21-
static std::string generateTooltip(const std::vector<ptrn::Pattern*> &patterns) {
21+
static std::string generateTooltip(std::vector<ptrn::Pattern*> &patterns) {
2222
if (patterns.empty())
2323
return "";
2424

2525
std::string content;
26-
for (const auto *pattern : patterns) {
26+
for (auto *pattern : patterns) {
2727
if (pattern->getVisibility() == ptrn::Visibility::Hidden) continue;
2828
if (pattern->getVisibility() == ptrn::Visibility::TreeHidden) continue;
2929

@@ -46,7 +46,7 @@ namespace pl::gen::fmt {
4646
}
4747

4848
static std::string generateCell(u64 address, const PatternLanguage &runtime) {
49-
const auto patterns = runtime.getPatternsAtAddress(address);
49+
auto patterns = runtime.getPatternsAtAddress(address);
5050

5151
u8 byte = 0;
5252
runtime.getInternals().evaluator->readData(address, &byte, sizeof(byte), ptrn::Pattern::MainSectionId);

generators/include/pl/formatters/formatter_json.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ namespace pl::gen::fmt {
6060
this->m_inArray = false;
6161
}
6262

63-
void formatString(const pl::ptrn::Pattern *pattern) {
63+
void formatString(pl::ptrn::Pattern *pattern) {
6464
if (pattern->getVisibility() == ptrn::Visibility::Hidden) return;
6565
if (pattern->getVisibility() == ptrn::Visibility::TreeHidden) return;
6666

@@ -125,7 +125,7 @@ namespace pl::gen::fmt {
125125
}
126126
}
127127

128-
void formatValue(const pl::ptrn::Pattern *pattern) {
128+
void formatValue(pl::ptrn::Pattern *pattern) {
129129
if (pattern->getVisibility() == ptrn::Visibility::Hidden) return;
130130
if (pattern->getVisibility() == ptrn::Visibility::TreeHidden) return;
131131

generators/include/pl/formatters/formatter_yaml.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ namespace pl::gen::fmt {
100100
}
101101
}
102102

103-
void formatString(const pl::ptrn::Pattern *pattern) {
103+
void formatString(pl::ptrn::Pattern *pattern) {
104104
if (pattern->getVisibility() == ptrn::Visibility::Hidden) return;
105105
if (pattern->getVisibility() == ptrn::Visibility::TreeHidden) return;
106106

@@ -110,7 +110,7 @@ namespace pl::gen::fmt {
110110
addLine(pattern->getVariableName(), ::fmt::format("\"{}\"", hlp::encodeByteString({ result.begin(), result.end() })));
111111
}
112112

113-
void formatValue(const pl::ptrn::Pattern *pattern) {
113+
void formatValue(pl::ptrn::Pattern *pattern) {
114114
if (pattern->getVisibility() == ptrn::Visibility::Hidden) return;
115115
if (pattern->getVisibility() == ptrn::Visibility::TreeHidden) return;
116116

lib/include/pl/pattern_language.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <vector>
99
#include <filesystem>
1010
#include <set>
11+
#include <thread>
1112

1213
#include <pl/api.hpp>
1314

@@ -417,7 +418,9 @@ namespace pl {
417418
core::ParserManager m_parserManager;
418419

419420
std::map<u64, std::vector<std::shared_ptr<ptrn::Pattern>>> m_patterns;
421+
std::atomic<bool> m_flattenedPatternsValid = false;
420422
std::map<u64, wolv::container::IntervalTree<ptrn::Pattern*, u64, 5>> m_flattenedPatterns;
423+
std::thread m_flattenThread;
421424
std::vector<std::function<void(PatternLanguage&)>> m_cleanupCallbacks;
422425
std::vector<std::shared_ptr<core::ast::ASTNode>> m_currAST;
423426

lib/include/pl/patterns/pattern.hpp

Lines changed: 100 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include <string>
1616

1717
namespace pl::ptrn {
18-
1918
using namespace ::std::literals::string_literals;
2019

2120
class IInlinable {
@@ -264,7 +263,7 @@ namespace pl::ptrn {
264263
}
265264
}
266265

267-
[[nodiscard]] virtual std::string toString() const {
266+
[[nodiscard]] virtual std::string toString() {
268267
auto result = fmt::format("{} {} @ 0x{:X}", this->getTypeName(), this->getVariableName(), this->getOffset());
269268

270269
return this->callUserFormatFunc(this->getValue(), true).value_or(result);
@@ -544,6 +543,8 @@ namespace pl::ptrn {
544543
m_arrayIndex = index;
545544
}
546545

546+
[[nodiscard]] virtual std::string formatDisplayValue() = 0;
547+
547548
protected:
548549
std::optional<std::endian> m_endian;
549550

@@ -561,8 +562,6 @@ namespace pl::ptrn {
561562
return value;
562563
}
563564

564-
[[nodiscard]] virtual std::string formatDisplayValue() = 0;
565-
566565
/**
567566
* @brief Calls an user-defined PL function to format the given literal (pattern), if existing. Else, returns defaultValue
568567
*/
@@ -636,4 +635,101 @@ namespace pl::ptrn {
636635
bool m_manualColor = false;
637636
};
638637

638+
struct PatternRef {
639+
class NoIIndexable {};
640+
class NoIInlinable {};
641+
class NoIIterable {
642+
public:
643+
NoIIterable(auto*){}
644+
};
645+
646+
template<typename T>
647+
class PatternRefIterable : public IIndexable {
648+
public:
649+
PatternRefIterable() = default;
650+
PatternRefIterable(T *refPattern) : m_refPattern(refPattern) {}
651+
PatternRefIterable(const PatternRefIterable &other) {
652+
this->m_refPattern = other.m_refPattern;
653+
}
654+
655+
std::vector<std::shared_ptr<Pattern>> getEntries() override {
656+
return m_refPattern->getEntries();
657+
}
658+
659+
void setEntries(const std::vector<std::shared_ptr<Pattern>> &entries) override {
660+
m_refPattern->setEntries(entries);
661+
}
662+
663+
[[nodiscard]] std::shared_ptr<Pattern> getEntry(size_t index) const override {
664+
return m_refPattern->getEntry(index);
665+
}
666+
667+
void forEachEntry(u64 start, u64 end, const std::function<void(u64, Pattern*)> &callback) override {
668+
m_refPattern->forEachEntry(start, end, callback);
669+
}
670+
671+
[[nodiscard]] size_t getEntryCount() const override {
672+
return m_refPattern->getEntryCount();
673+
}
674+
675+
void addEntry(const std::shared_ptr<Pattern> &entry) override {
676+
return m_refPattern->addEntry(entry);
677+
}
678+
679+
private:
680+
T *m_refPattern;
681+
};
682+
683+
template<typename T>
684+
class PatternRefImpl
685+
: public Pattern,
686+
public std::conditional_t<std::derived_from<T, IInlinable>, IInlinable, NoIInlinable>,
687+
public std::conditional_t<std::derived_from<T, IIterable> || std::derived_from<T, IIndexable>, PatternRefIterable<T>, NoIIterable> {
688+
public:
689+
PatternRefImpl() = default;
690+
PatternRefImpl(T *refPattern)
691+
: Pattern(refPattern->getEvaluator(), refPattern->getOffset(), refPattern->getSize(), refPattern->getLine()),
692+
std::conditional_t<std::derived_from<T, IIterable> || std::derived_from<T, IIndexable>, PatternRefIterable<T>, NoIIterable>(refPattern) {
693+
this->m_refPattern = refPattern;
694+
}
695+
696+
PatternRefImpl(const PatternRefImpl &other)
697+
: Pattern(other),
698+
std::conditional_t<std::derived_from<T, IIterable> || std::derived_from<T, IIndexable>, PatternRefIterable<T>, NoIIterable>(other),
699+
m_refPattern(other.m_refPattern) {}
700+
701+
std::unique_ptr<Pattern> clone() const override {
702+
return std::make_unique<PatternRefImpl>(*this);
703+
}
704+
705+
void accept(PatternVisitor &v) override {
706+
m_refPattern->accept(v);
707+
}
708+
709+
std::string formatDisplayValue() override {
710+
return m_refPattern->formatDisplayValue();
711+
}
712+
713+
std::string getFormattedName() const override {
714+
return m_refPattern->getFormattedName();
715+
}
716+
717+
std::vector<u8> getRawBytes() override {
718+
return m_refPattern->getRawBytes();
719+
}
720+
721+
bool operator==(const Pattern &other) const override {
722+
return *this->m_refPattern == other;
723+
}
724+
725+
private:
726+
T *m_refPattern;
727+
};
728+
729+
template<typename PatternType>
730+
static std::shared_ptr<Pattern> create(PatternType *pattern) {
731+
return std::shared_ptr<Pattern>(new PatternRefImpl<std::remove_cvref_t<PatternType>>(pattern));
732+
}
733+
};
734+
639735
}

lib/include/pl/patterns/pattern_array_dynamic.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ namespace pl::ptrn {
149149
this->setBaseColor(this->m_entries.front()->getColor());
150150
}
151151

152-
[[nodiscard]] std::string toString() const override {
152+
[[nodiscard]] std::string toString() override {
153153
std::string result;
154154

155155
result += "[ ";
@@ -173,7 +173,7 @@ namespace pl::ptrn {
173173

174174
result += " ]";
175175

176-
return Pattern::callUserFormatFunc(this->clone(), true).value_or(result);
176+
return Pattern::callUserFormatFunc(PatternRef::create(this), true).value_or(result);
177177
}
178178

179179
[[nodiscard]] bool operator==(const Pattern &other) const override {
@@ -208,7 +208,7 @@ namespace pl::ptrn {
208208
}
209209

210210
std::string formatDisplayValue() override {
211-
return Pattern::callUserFormatFunc(this->clone()).value_or("[ ... ]");
211+
return Pattern::callUserFormatFunc(PatternRef::create(this)).value_or("[ ... ]");
212212
}
213213

214214
std::vector<u8> getRawBytes() override {

lib/include/pl/patterns/pattern_array_static.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,10 @@ namespace pl::ptrn {
191191
}
192192

193193
std::string formatDisplayValue() override {
194-
return Pattern::callUserFormatFunc(this->clone()).value_or("[ ... ]");
194+
return Pattern::callUserFormatFunc(PatternRef::create(this)).value_or("[ ... ]");
195195
}
196196

197-
[[nodiscard]] std::string toString() const override {
197+
[[nodiscard]] std::string toString() override {
198198
std::string result;
199199

200200
result += "[ ";
@@ -220,7 +220,7 @@ namespace pl::ptrn {
220220

221221
result += " ]";
222222

223-
return Pattern::callUserFormatFunc(this->clone(), true).value_or(result);
223+
return Pattern::callUserFormatFunc(PatternRef::create(this), true).value_or(result);
224224
}
225225

226226
std::vector<u8> getRawBytes() override {

lib/include/pl/patterns/pattern_bitfield.hpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ namespace pl::ptrn {
110110
return Pattern::callUserFormatFunc(literal).value_or(fmt::format("{}", value));
111111
}
112112

113-
[[nodiscard]] std::string toString() const override {
113+
[[nodiscard]] std::string toString() override {
114114
auto value = this->readValue();
115115
return Pattern::callUserFormatFunc(value, true).value_or(fmt::format("{}", value));
116116
}
@@ -175,7 +175,7 @@ namespace pl::ptrn {
175175
return Pattern::callUserFormatFunc(value).value_or(fmt::format("{}", value));
176176
}
177177

178-
[[nodiscard]] std::string toString() const override {
178+
[[nodiscard]] std::string toString() override {
179179
auto result = fmt::format("{}", this->getValue().toSigned());
180180
return Pattern::callUserFormatFunc(this->getValue(), true).value_or(result);
181181
}
@@ -207,7 +207,7 @@ namespace pl::ptrn {
207207
return "true*";
208208
}
209209

210-
[[nodiscard]] std::string toString() const override {
210+
[[nodiscard]] std::string toString() override {
211211
auto value = this->getValue();
212212
return Pattern::callUserFormatFunc(value, true).value_or(fmt::format("{}", value.toBoolean() ? "true" : "false"));
213213
}
@@ -254,7 +254,7 @@ namespace pl::ptrn {
254254
return Pattern::callUserFormatFunc(value).value_or(fmt::format("{}", enumName));
255255
}
256256

257-
[[nodiscard]] std::string toString() const override {
257+
[[nodiscard]] std::string toString() override {
258258
auto enumName = PatternEnum::getEnumName(this->getTypeName(), this->readValue(), this->getEnumValues());
259259
return Pattern::callUserFormatFunc(this->getValue(), true).value_or(enumName);
260260
}
@@ -431,7 +431,7 @@ namespace pl::ptrn {
431431
this->setBaseColor(this->m_entries.front()->getColor());
432432
}
433433

434-
[[nodiscard]] std::string toString() const override {
434+
[[nodiscard]] std::string toString() override {
435435
std::string result;
436436

437437
result += "[ ";
@@ -455,7 +455,7 @@ namespace pl::ptrn {
455455

456456
result += " ]";
457457

458-
return Pattern::callUserFormatFunc(this->clone(), true).value_or(result);
458+
return Pattern::callUserFormatFunc(PatternRef::create(this), true).value_or(result);
459459
}
460460

461461
[[nodiscard]] bool operator==(const Pattern &other) const override {
@@ -495,7 +495,7 @@ namespace pl::ptrn {
495495
}
496496

497497
std::string formatDisplayValue() override {
498-
return Pattern::callUserFormatFunc(this->clone()).value_or("[ ... ]");
498+
return Pattern::callUserFormatFunc(PatternRef::create(this)).value_or("[ ... ]");
499499
}
500500

501501
void sort(const std::function<bool (const Pattern *, const Pattern *)> &comparator) override {
@@ -673,7 +673,7 @@ namespace pl::ptrn {
673673
v.visit(*this);
674674
}
675675

676-
[[nodiscard]] std::string toString() const override {
676+
[[nodiscard]] std::string toString() override {
677677
std::string result = this->getFormattedName();
678678

679679
result += " { ";
@@ -691,7 +691,7 @@ namespace pl::ptrn {
691691

692692
result += " }";
693693

694-
return Pattern::callUserFormatFunc(this->clone(), true).value_or(result);
694+
return Pattern::callUserFormatFunc(PatternRef::create(this), true).value_or(result);
695695
}
696696

697697
std::string formatDisplayValue() override {
@@ -725,9 +725,9 @@ namespace pl::ptrn {
725725
}
726726

727727
if (valueString.size() > 64)
728-
return Pattern::callUserFormatFunc(this->clone()).value_or(fmt::format("{{ ... }}", valueString));
728+
return Pattern::callUserFormatFunc(PatternRef::create(this)).value_or(fmt::format("{{ ... }}", valueString));
729729
else
730-
return Pattern::callUserFormatFunc(this->clone()).value_or(fmt::format("{{ {} }}", valueString));
730+
return Pattern::callUserFormatFunc(PatternRef::create(this)).value_or(fmt::format("{{ {} }}", valueString));
731731
}
732732

733733
void setEndian(std::endian endian) override {

lib/include/pl/patterns/pattern_boolean.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ namespace pl::ptrn {
4646
v.visit(*this);
4747
}
4848

49-
[[nodiscard]] std::string toString() const override {
49+
[[nodiscard]] std::string toString() override {
5050
auto value = this->getValue();
5151
auto result = fmt::format("{}", value.toBoolean() ? "true" : "false");
5252

lib/include/pl/patterns/pattern_character.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ namespace pl::ptrn {
4242
v.visit(*this);
4343
}
4444

45-
[[nodiscard]] std::string toString() const override {
45+
[[nodiscard]] std::string toString() override {
4646
auto value = this->getValue();
4747
auto result = fmt::format("{}", hlp::encodeByteString({ u8(value.toCharacter()) }));
4848

0 commit comments

Comments
 (0)