mirror of https://github.com/WerWolv/ImHex.git
patterns: Limit max number of patterns
Can be overriden with the pattern_limit pragma Further improves situation with #313
This commit is contained in:
parent
aef959854f
commit
12a8cadcfe
|
@ -310,21 +310,21 @@ namespace hex::pl {
|
|||
|
||||
PatternData *pattern;
|
||||
if (Token::isUnsigned(this->m_type))
|
||||
pattern = new PatternDataUnsigned(offset, size);
|
||||
pattern = new PatternDataUnsigned(offset, size, evaluator);
|
||||
else if (Token::isSigned(this->m_type))
|
||||
pattern = new PatternDataSigned(offset, size);
|
||||
pattern = new PatternDataSigned(offset, size, evaluator);
|
||||
else if (Token::isFloatingPoint(this->m_type))
|
||||
pattern = new PatternDataFloat(offset, size);
|
||||
pattern = new PatternDataFloat(offset, size, evaluator);
|
||||
else if (this->m_type == Token::ValueType::Boolean)
|
||||
pattern = new PatternDataBoolean(offset);
|
||||
pattern = new PatternDataBoolean(offset, evaluator);
|
||||
else if (this->m_type == Token::ValueType::Character)
|
||||
pattern = new PatternDataCharacter(offset);
|
||||
pattern = new PatternDataCharacter(offset, evaluator);
|
||||
else if (this->m_type == Token::ValueType::Character16)
|
||||
pattern = new PatternDataCharacter16(offset);
|
||||
pattern = new PatternDataCharacter16(offset, evaluator);
|
||||
else if (this->m_type == Token::ValueType::Padding)
|
||||
pattern = new PatternDataPadding(offset, 1);
|
||||
pattern = new PatternDataPadding(offset, 1, evaluator);
|
||||
else if (this->m_type == Token::ValueType::String)
|
||||
pattern = new PatternDataString(offset, 1);
|
||||
pattern = new PatternDataString(offset, 1, evaluator);
|
||||
else if (this->m_type == Token::ValueType::Auto)
|
||||
return { nullptr };
|
||||
else
|
||||
|
@ -589,7 +589,6 @@ namespace hex::pl {
|
|||
if (function.parameterCount != 1)
|
||||
LogConsole::abortEvaluation("formatter function needs exactly one parameter", node);
|
||||
|
||||
pattern->setEvaluator(evaluator);
|
||||
pattern->setFormatterFunction(function);
|
||||
} else if (name == "transform" && requiresValue()) {
|
||||
auto functions = evaluator->getCustomFunctions();
|
||||
|
@ -600,7 +599,6 @@ namespace hex::pl {
|
|||
if (function.parameterCount != 1)
|
||||
LogConsole::abortEvaluation("transform function needs exactly one parameter", node);
|
||||
|
||||
pattern->setEvaluator(evaluator);
|
||||
pattern->setTransformFunction(function);
|
||||
} else if (name == "pointer_base" && requiresValue()) {
|
||||
auto functions = evaluator->getCustomFunctions();
|
||||
|
@ -816,13 +814,13 @@ namespace hex::pl {
|
|||
|
||||
PatternData *outputPattern;
|
||||
if (dynamic_cast<PatternDataPadding*>(templatePattern)) {
|
||||
outputPattern = new PatternDataPadding(startOffset, 0);
|
||||
outputPattern = new PatternDataPadding(startOffset, 0, evaluator);
|
||||
} else if (dynamic_cast<PatternDataCharacter*>(templatePattern)) {
|
||||
outputPattern = new PatternDataString(startOffset, 0);
|
||||
outputPattern = new PatternDataString(startOffset, 0, evaluator);
|
||||
} else if (dynamic_cast<PatternDataCharacter16*>(templatePattern)) {
|
||||
outputPattern = new PatternDataString16(startOffset, 0);
|
||||
outputPattern = new PatternDataString16(startOffset, 0, evaluator);
|
||||
} else {
|
||||
auto arrayPattern = new PatternDataStaticArray(startOffset, 0);
|
||||
auto arrayPattern = new PatternDataStaticArray(startOffset, 0, evaluator);
|
||||
arrayPattern->setEntries(templatePattern->clone(), entryCount);
|
||||
outputPattern = arrayPattern;
|
||||
}
|
||||
|
@ -839,10 +837,15 @@ namespace hex::pl {
|
|||
}
|
||||
|
||||
PatternData* createDynamicArray(Evaluator *evaluator) const {
|
||||
auto arrayPattern = new PatternDataDynamicArray(evaluator->dataOffset(), 0);
|
||||
auto arrayPattern = new PatternDataDynamicArray(evaluator->dataOffset(), 0, evaluator);
|
||||
arrayPattern->setVariableName(this->m_name);
|
||||
|
||||
std::vector<PatternData *> entries;
|
||||
auto arrayCleanup = SCOPE_GUARD {
|
||||
for (auto entry : entries)
|
||||
delete entry;
|
||||
};
|
||||
|
||||
size_t size = 0;
|
||||
u64 entryCount = 0;
|
||||
|
||||
|
@ -934,6 +937,8 @@ namespace hex::pl {
|
|||
arrayPattern->setEntries(entries);
|
||||
arrayPattern->setSize(size);
|
||||
|
||||
arrayCleanup.release();
|
||||
|
||||
return arrayPattern;
|
||||
}
|
||||
};
|
||||
|
@ -986,7 +991,7 @@ namespace hex::pl {
|
|||
auto sizePattern = this->m_sizeType->createPatterns(evaluator).front();
|
||||
ON_SCOPE_EXIT { delete sizePattern; };
|
||||
|
||||
auto pattern = new PatternDataPointer(offset, sizePattern->getSize());
|
||||
auto pattern = new PatternDataPointer(offset, sizePattern->getSize(), evaluator);
|
||||
pattern->setVariableName(this->m_name);
|
||||
|
||||
offset = evaluator->dataOffset();
|
||||
|
@ -1085,10 +1090,15 @@ namespace hex::pl {
|
|||
}
|
||||
|
||||
[[nodiscard]] std::vector<PatternData*> createPatterns(Evaluator *evaluator) const override {
|
||||
auto pattern = new PatternDataStruct(evaluator->dataOffset(), 0);
|
||||
auto pattern = new PatternDataStruct(evaluator->dataOffset(), 0, evaluator);
|
||||
|
||||
u64 startOffset = evaluator->dataOffset();
|
||||
std::vector<PatternData*> memberPatterns;
|
||||
auto structCleanup = SCOPE_GUARD {
|
||||
delete pattern;
|
||||
for (auto member : memberPatterns)
|
||||
delete member;
|
||||
};
|
||||
|
||||
evaluator->pushScope(pattern, memberPatterns);
|
||||
|
||||
|
@ -1116,6 +1126,8 @@ namespace hex::pl {
|
|||
pattern->setMembers(memberPatterns);
|
||||
pattern->setSize(evaluator->dataOffset() - startOffset);
|
||||
|
||||
structCleanup.release();
|
||||
|
||||
return { pattern };
|
||||
}
|
||||
|
||||
|
@ -1149,12 +1161,18 @@ namespace hex::pl {
|
|||
}
|
||||
|
||||
[[nodiscard]] std::vector<PatternData*> createPatterns(Evaluator *evaluator) const override {
|
||||
auto pattern = new PatternDataUnion(evaluator->dataOffset(), 0);
|
||||
auto pattern = new PatternDataUnion(evaluator->dataOffset(), 0, evaluator);
|
||||
|
||||
size_t size = 0;
|
||||
std::vector<PatternData*> memberPatterns;
|
||||
u64 startOffset = evaluator->dataOffset();
|
||||
|
||||
auto unionCleanup = SCOPE_GUARD {
|
||||
delete pattern;
|
||||
for (auto member : memberPatterns)
|
||||
delete member;
|
||||
};
|
||||
|
||||
evaluator->pushScope(pattern, memberPatterns);
|
||||
for (auto member : this->m_members) {
|
||||
for (auto &memberPattern : member->createPatterns(evaluator)) {
|
||||
|
@ -1169,6 +1187,8 @@ namespace hex::pl {
|
|||
pattern->setMembers(memberPatterns);
|
||||
pattern->setSize(size);
|
||||
|
||||
unionCleanup.release();
|
||||
|
||||
return { pattern };
|
||||
}
|
||||
|
||||
|
@ -1200,7 +1220,9 @@ namespace hex::pl {
|
|||
}
|
||||
|
||||
[[nodiscard]] std::vector<PatternData*> createPatterns(Evaluator *evaluator) const override {
|
||||
auto pattern = new PatternDataEnum(evaluator->dataOffset(), 0);
|
||||
auto pattern = new PatternDataEnum(evaluator->dataOffset(), 0, evaluator);
|
||||
auto enumCleanup = SCOPE_GUARD { delete pattern; };
|
||||
|
||||
|
||||
std::vector<std::pair<Token::Literal, std::string>> enumEntries;
|
||||
for (const auto &[name, value] : this->m_entries) {
|
||||
|
@ -1217,6 +1239,8 @@ namespace hex::pl {
|
|||
pattern->setSize(underlying->getSize());
|
||||
pattern->setEndian(underlying->getEndian());
|
||||
|
||||
enumCleanup.release();
|
||||
|
||||
return { pattern };
|
||||
}
|
||||
|
||||
|
@ -1252,10 +1276,17 @@ namespace hex::pl {
|
|||
void addEntry(const std::string &name, ASTNode* size) { this->m_entries.emplace_back(name, size); }
|
||||
|
||||
[[nodiscard]] std::vector<PatternData*> createPatterns(Evaluator *evaluator) const override {
|
||||
auto pattern = new PatternDataBitfield(evaluator->dataOffset(), 0);
|
||||
auto pattern = new PatternDataBitfield(evaluator->dataOffset(), 0, evaluator);
|
||||
|
||||
size_t bitOffset = 0;
|
||||
std::vector<PatternData*> fields;
|
||||
|
||||
auto bitfieldCleanup = SCOPE_GUARD {
|
||||
delete pattern;
|
||||
for (auto field : fields)
|
||||
delete field;
|
||||
};
|
||||
|
||||
evaluator->pushScope(pattern, fields);
|
||||
for (auto [name, bitSizeNode] : this->m_entries) {
|
||||
auto literal = bitSizeNode->evaluate(evaluator);
|
||||
|
@ -1267,7 +1298,7 @@ namespace hex::pl {
|
|||
[](auto &&offset) -> u8 { return static_cast<u8>(offset); }
|
||||
}, dynamic_cast<ASTNodeLiteral*>(literal)->getValue());
|
||||
|
||||
auto field = new PatternDataBitfieldField(evaluator->dataOffset(), bitOffset, bitSize);
|
||||
auto field = new PatternDataBitfieldField(evaluator->dataOffset(), bitOffset, bitSize, evaluator);
|
||||
field->setVariableName(name);
|
||||
|
||||
bitOffset += bitSize;
|
||||
|
@ -1280,6 +1311,8 @@ namespace hex::pl {
|
|||
|
||||
evaluator->dataOffset() += pattern->getSize();
|
||||
|
||||
bitfieldCleanup.release();
|
||||
|
||||
return { pattern };
|
||||
}
|
||||
|
||||
|
@ -1915,7 +1948,12 @@ namespace hex::pl {
|
|||
std::vector<PatternData*> variables;
|
||||
|
||||
ctx->pushScope(nullptr, variables);
|
||||
ON_SCOPE_EXIT { ctx->popScope(); };
|
||||
ON_SCOPE_EXIT {
|
||||
for (auto variable : variables)
|
||||
delete variable;
|
||||
|
||||
ctx->popScope();
|
||||
};
|
||||
|
||||
u32 paramIndex = 0;
|
||||
for (const auto &[name, type] : this->m_params) {
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace hex::prv { class Provider; }
|
|||
namespace hex::pl {
|
||||
|
||||
class PatternData;
|
||||
class PatternCreationLimiter;
|
||||
class ASTNode;
|
||||
|
||||
class Evaluator {
|
||||
|
@ -87,6 +88,20 @@ namespace hex::pl {
|
|||
return this->m_arrayLimit;
|
||||
}
|
||||
|
||||
void setPatternLimit(u32 limit) {
|
||||
this->m_patternLimit = limit;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
u32 getPatternLimit() {
|
||||
return this->m_patternLimit;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
u32 getPatternCount() {
|
||||
return this->m_currPatternCount;
|
||||
}
|
||||
|
||||
u64& dataOffset() { return this->m_currOffset; }
|
||||
|
||||
bool addCustomFunction(const std::string &name, u32 numParams, const ContentRegistry::PatternLanguageFunctions::Callback &function) {
|
||||
|
@ -106,9 +121,13 @@ namespace hex::pl {
|
|||
}
|
||||
|
||||
void createVariable(const std::string &name, ASTNode *type, const std::optional<Token::Literal> &value = std::nullopt);
|
||||
|
||||
void setVariable(const std::string &name, const Token::Literal& value);
|
||||
|
||||
private:
|
||||
|
||||
void patternCreated();
|
||||
void patternDestroyed();
|
||||
|
||||
private:
|
||||
u64 m_currOffset;
|
||||
prv::Provider *m_provider = nullptr;
|
||||
|
@ -117,11 +136,16 @@ namespace hex::pl {
|
|||
std::endian m_defaultEndian = std::endian::native;
|
||||
u32 m_evalDepth;
|
||||
u32 m_arrayLimit;
|
||||
u32 m_patternLimit;
|
||||
|
||||
u32 m_currPatternCount;
|
||||
|
||||
std::vector<Scope> m_scopes;
|
||||
std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> m_customFunctions;
|
||||
std::vector<ASTNode*> m_customFunctionDefinitions;
|
||||
std::vector<Token::Literal> m_stack;
|
||||
|
||||
friend class PatternCreationLimiter;
|
||||
};
|
||||
|
||||
}
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <hex/providers/provider.hpp>
|
||||
#include <hex/pattern_language/token.hpp>
|
||||
#include <hex/pattern_language/evaluator.hpp>
|
||||
|
||||
#include <hex/views/view.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
|
@ -51,10 +53,29 @@ namespace hex::pl {
|
|||
bool m_inlined = false;
|
||||
};
|
||||
|
||||
class PatternData {
|
||||
class PatternCreationLimiter {
|
||||
public:
|
||||
PatternData(u64 offset, size_t size, u32 color = 0)
|
||||
: m_offset(offset), m_size(size), m_color(color), m_parent(nullptr) {
|
||||
explicit PatternCreationLimiter(Evaluator *evaluator) : m_evaluator(evaluator) {
|
||||
this->m_evaluator->patternCreated();
|
||||
}
|
||||
|
||||
PatternCreationLimiter(const PatternCreationLimiter &other) {
|
||||
this->m_evaluator = other.m_evaluator;
|
||||
this->m_evaluator->patternCreated();
|
||||
}
|
||||
|
||||
~PatternCreationLimiter() {
|
||||
this->m_evaluator->patternDestroyed();
|
||||
}
|
||||
|
||||
private:
|
||||
Evaluator *m_evaluator;
|
||||
};
|
||||
|
||||
class PatternData : public PatternCreationLimiter {
|
||||
public:
|
||||
PatternData(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternCreationLimiter(evaluator), m_offset(offset), m_size(size), m_color(color), m_parent(nullptr), m_evaluator(evaluator) {
|
||||
constexpr u32 Palette[] = { 0x70b4771f, 0x700e7fff, 0x702ca02c, 0x702827d6, 0x70bd6794, 0x704b568c, 0x70c277e3, 0x707f7f7f, 0x7022bdbc, 0x70cfbe17 };
|
||||
|
||||
if (color != 0)
|
||||
|
@ -100,7 +121,6 @@ namespace hex::pl {
|
|||
void setDisplayName(const std::string &name) { this->m_displayName = name; }
|
||||
|
||||
[[nodiscard]] Evaluator* getEvaluator() const { return this->m_evaluator; }
|
||||
void setEvaluator(Evaluator *evaluator) { this->m_evaluator = evaluator; }
|
||||
|
||||
[[nodiscard]] const auto& getTransformFunction() const { return this->m_transformFunction; }
|
||||
void setTransformFunction(const ContentRegistry::PatternLanguageFunctions::Function &function) { this->m_transformFunction = function; }
|
||||
|
@ -295,7 +315,7 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataPadding : public PatternData {
|
||||
public:
|
||||
PatternDataPadding(u64 offset, size_t size) : PatternData(offset, size, 0xFF000000) { }
|
||||
PatternDataPadding(u64 offset, size_t size, Evaluator *evaluator) : PatternData(offset, size, evaluator, 0xFF000000) { }
|
||||
|
||||
PatternData* clone() override {
|
||||
return new PatternDataPadding(*this);
|
||||
|
@ -313,8 +333,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataPointer : public PatternData {
|
||||
public:
|
||||
PatternDataPointer(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color), m_pointedAt(nullptr) {
|
||||
PatternDataPointer(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color), m_pointedAt(nullptr) {
|
||||
}
|
||||
|
||||
PatternDataPointer(const PatternDataPointer &other) : PatternData(other) {
|
||||
|
@ -415,8 +435,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataUnsigned : public PatternData {
|
||||
public:
|
||||
PatternDataUnsigned(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) { }
|
||||
PatternDataUnsigned(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color) { }
|
||||
|
||||
PatternData* clone() override {
|
||||
return new PatternDataUnsigned(*this);
|
||||
|
@ -446,8 +466,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataSigned : public PatternData {
|
||||
public:
|
||||
PatternDataSigned(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) { }
|
||||
PatternDataSigned(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color) { }
|
||||
|
||||
PatternData* clone() override {
|
||||
return new PatternDataSigned(*this);
|
||||
|
@ -478,8 +498,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataFloat : public PatternData {
|
||||
public:
|
||||
PatternDataFloat(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) { }
|
||||
PatternDataFloat(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color) { }
|
||||
|
||||
PatternData* clone() override {
|
||||
return new PatternDataFloat(*this);
|
||||
|
@ -514,8 +534,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataBoolean : public PatternData {
|
||||
public:
|
||||
explicit PatternDataBoolean(u64 offset, u32 color = 0)
|
||||
: PatternData(offset, 1, color) { }
|
||||
explicit PatternDataBoolean(u64 offset, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, 1, evaluator, color) { }
|
||||
|
||||
PatternData* clone() override {
|
||||
return new PatternDataBoolean(*this);
|
||||
|
@ -542,8 +562,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataCharacter : public PatternData {
|
||||
public:
|
||||
explicit PatternDataCharacter(u64 offset, u32 color = 0)
|
||||
: PatternData(offset, 1, color) { }
|
||||
explicit PatternDataCharacter(u64 offset, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, 1, evaluator, color) { }
|
||||
|
||||
PatternData* clone() override {
|
||||
return new PatternDataCharacter(*this);
|
||||
|
@ -565,8 +585,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataCharacter16 : public PatternData {
|
||||
public:
|
||||
explicit PatternDataCharacter16(u64 offset, u32 color = 0)
|
||||
: PatternData(offset, 2, color) { }
|
||||
explicit PatternDataCharacter16(u64 offset, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, 2, evaluator, color) { }
|
||||
|
||||
PatternData* clone() override {
|
||||
return new PatternDataCharacter16(*this);
|
||||
|
@ -590,8 +610,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataString : public PatternData {
|
||||
public:
|
||||
PatternDataString(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) { }
|
||||
PatternDataString(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color) { }
|
||||
|
||||
PatternData* clone() override {
|
||||
return new PatternDataString(*this);
|
||||
|
@ -613,8 +633,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataString16 : public PatternData {
|
||||
public:
|
||||
PatternDataString16(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) { }
|
||||
PatternDataString16(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color) { }
|
||||
|
||||
PatternData* clone() override {
|
||||
return new PatternDataString16(*this);
|
||||
|
@ -641,8 +661,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataDynamicArray : public PatternData, public Inlinable {
|
||||
public:
|
||||
PatternDataDynamicArray(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) {
|
||||
PatternDataDynamicArray(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color) {
|
||||
}
|
||||
|
||||
PatternDataDynamicArray(const PatternDataDynamicArray &other) : PatternData(other) {
|
||||
|
@ -773,8 +793,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataStaticArray : public PatternData, public Inlinable {
|
||||
public:
|
||||
PatternDataStaticArray(u64 offset, size_t size, u32 color = 0)
|
||||
: PatternData(offset, size, color) {
|
||||
PatternDataStaticArray(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color) {
|
||||
}
|
||||
|
||||
PatternDataStaticArray(const PatternDataStaticArray &other) : PatternData(other) {
|
||||
|
@ -910,7 +930,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataStruct : public PatternData, public Inlinable {
|
||||
public:
|
||||
PatternDataStruct(u64 offset, size_t size, u32 color = 0) : PatternData(offset, size, color){
|
||||
PatternDataStruct(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color){
|
||||
}
|
||||
|
||||
PatternDataStruct(const PatternDataStruct &other) : PatternData(other) {
|
||||
|
@ -1045,7 +1066,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataUnion : public PatternData, public Inlinable {
|
||||
public:
|
||||
PatternDataUnion(u64 offset, size_t size, u32 color = 0) : PatternData(offset, size, color) {
|
||||
PatternDataUnion(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -1181,7 +1203,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataEnum : public PatternData {
|
||||
public:
|
||||
PatternDataEnum(u64 offset, size_t size, u32 color = 0) : PatternData(offset, size, color) {
|
||||
PatternDataEnum(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -1274,8 +1297,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataBitfieldField : public PatternData {
|
||||
public:
|
||||
PatternDataBitfieldField(u64 offset, u8 bitOffset, u8 bitSize, u32 color = 0)
|
||||
: m_bitOffset(bitOffset), m_bitSize(bitSize), PatternData(offset, 0, color) {
|
||||
PatternDataBitfieldField(u64 offset, u8 bitOffset, u8 bitSize, Evaluator *evaluator, u32 color = 0)
|
||||
: m_bitOffset(bitOffset), m_bitSize(bitSize), PatternData(offset, 0, evaluator, color) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -1343,7 +1366,8 @@ namespace hex::pl {
|
|||
|
||||
class PatternDataBitfield : public PatternData, public Inlinable {
|
||||
public:
|
||||
PatternDataBitfield(u64 offset, size_t size, u32 color = 0) : PatternData(offset, size, color) {
|
||||
PatternDataBitfield(u64 offset, size_t size, Evaluator *evaluator, u32 color = 0)
|
||||
: PatternData(offset, size, evaluator, color) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@ namespace hex::pl {
|
|||
const std::vector<std::pair<LogConsole::Level, std::string>>& getConsoleLog();
|
||||
const std::optional<std::pair<u32, std::string>>& getError();
|
||||
|
||||
u32 getCreatedPatternCount();
|
||||
u32 getMaximumPatternCount();
|
||||
|
||||
private:
|
||||
Preprocessor *m_preprocessor;
|
||||
Lexer *m_lexer;
|
||||
|
@ -45,8 +48,6 @@ namespace hex::pl {
|
|||
|
||||
prv::Provider *m_provider = nullptr;
|
||||
std::endian m_defaultEndian = std::endian::native;
|
||||
u32 m_evalDepth;
|
||||
u32 m_arrayLimit;
|
||||
|
||||
std::optional<std::pair<u32, std::string>> m_currError;
|
||||
};
|
||||
|
|
|
@ -21,19 +21,21 @@ namespace hex::pl {
|
|||
LogConsole::abortEvaluation("cannot determine type of auto variable", type);
|
||||
|
||||
if (std::get_if<u128>(&*value) != nullptr)
|
||||
pattern = new PatternDataUnsigned(0, sizeof(u128));
|
||||
pattern = new PatternDataUnsigned(0, sizeof(u128), this);
|
||||
else if (std::get_if<s128>(&*value) != nullptr)
|
||||
pattern = new PatternDataSigned(0, sizeof(s128));
|
||||
pattern = new PatternDataSigned(0, sizeof(s128), this);
|
||||
else if (std::get_if<double>(&*value) != nullptr)
|
||||
pattern = new PatternDataFloat(0, sizeof(double));
|
||||
pattern = new PatternDataFloat(0, sizeof(double), this);
|
||||
else if (std::get_if<bool>(&*value) != nullptr)
|
||||
pattern = new PatternDataBoolean(0);
|
||||
pattern = new PatternDataBoolean(0, this);
|
||||
else if (std::get_if<char>(&*value) != nullptr)
|
||||
pattern = new PatternDataCharacter(0);
|
||||
pattern = new PatternDataCharacter(0, this);
|
||||
else if (std::get_if<PatternData*>(&*value) != nullptr)
|
||||
pattern = std::get<PatternData*>(*value)->clone();
|
||||
else if (std::get_if<std::string>(&*value) != nullptr)
|
||||
pattern = new PatternDataString(0, 1);
|
||||
pattern = new PatternDataString(0, 1, this);
|
||||
else
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
pattern->setVariableName(name);
|
||||
|
@ -106,6 +108,7 @@ namespace hex::pl {
|
|||
this->m_scopes.clear();
|
||||
|
||||
this->dataOffset() = 0x00;
|
||||
this->m_currPatternCount = 0;
|
||||
|
||||
for (auto &func : this->m_customFunctionDefinitions)
|
||||
delete func;
|
||||
|
@ -139,10 +142,22 @@ namespace hex::pl {
|
|||
delete pattern;
|
||||
patterns.clear();
|
||||
|
||||
this->m_currPatternCount = 0;
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return patterns;
|
||||
}
|
||||
|
||||
void Evaluator::patternCreated() {
|
||||
if (this->m_currPatternCount > this->m_patternLimit)
|
||||
LogConsole::abortEvaluation(hex::format("exceeded maximum number of patterns: {}", this->m_patternLimit));
|
||||
this->m_currPatternCount++;
|
||||
}
|
||||
|
||||
void Evaluator::patternDestroyed() {
|
||||
this->m_currPatternCount--;
|
||||
}
|
||||
|
||||
}
|
|
@ -43,21 +43,31 @@ namespace hex::pl {
|
|||
if (limit <= 0)
|
||||
return false;
|
||||
|
||||
this->m_evalDepth = limit;
|
||||
this->m_evaluator->setEvaluationDepth(limit);
|
||||
return true;
|
||||
});
|
||||
|
||||
this->m_preprocessor->addPragmaHandler("array_limit", [this](std::string value) {
|
||||
this->m_preprocessor->addPragmaHandler("array_limit", [this](const std::string &value) {
|
||||
auto limit = strtol(value.c_str(), nullptr, 0);
|
||||
|
||||
if (limit <= 0)
|
||||
return false;
|
||||
|
||||
this->m_arrayLimit = limit;
|
||||
this->m_evaluator->setArrayLimit(limit);
|
||||
return true;
|
||||
});
|
||||
|
||||
this->m_preprocessor->addPragmaHandler("base_address", [](std::string value) {
|
||||
this->m_preprocessor->addPragmaHandler("pattern_limit", [this](const std::string &value) {
|
||||
auto limit = strtol(value.c_str(), nullptr, 0);
|
||||
|
||||
if (limit <= 0)
|
||||
return false;
|
||||
|
||||
this->m_evaluator->setPatternLimit(limit);
|
||||
return true;
|
||||
});
|
||||
|
||||
this->m_preprocessor->addPragmaHandler("base_address", [](const std::string &value) {
|
||||
auto baseAddress = strtoull(value.c_str(), nullptr, 0);
|
||||
|
||||
ImHexApi::Provider::get()->setBaseAddress(baseAddress);
|
||||
|
@ -79,8 +89,10 @@ namespace hex::pl {
|
|||
this->m_currError.reset();
|
||||
this->m_evaluator->getConsole().clear();
|
||||
this->m_evaluator->setProvider(provider);
|
||||
this->m_evalDepth = 32;
|
||||
this->m_arrayLimit = 0x1000;
|
||||
this->m_evaluator->setDefaultEndian(std::endian::native);
|
||||
this->m_evaluator->setEvaluationDepth(32);
|
||||
this->m_evaluator->setArrayLimit(0x1000);
|
||||
this->m_evaluator->setPatternLimit(0x2000);
|
||||
|
||||
for (auto &node : this->m_currAST)
|
||||
delete node;
|
||||
|
@ -92,10 +104,6 @@ namespace hex::pl {
|
|||
return { };
|
||||
}
|
||||
|
||||
this->m_evaluator->setDefaultEndian(this->m_defaultEndian);
|
||||
this->m_evaluator->setEvaluationDepth(this->m_evalDepth);
|
||||
this->m_evaluator->setArrayLimit(this->m_arrayLimit);
|
||||
|
||||
auto tokens = this->m_lexer->lex(preprocessedCode.value());
|
||||
if (!tokens.has_value()) {
|
||||
this->m_currError = this->m_lexer->getError();
|
||||
|
@ -134,4 +142,12 @@ namespace hex::pl {
|
|||
return this->m_currError;
|
||||
}
|
||||
|
||||
u32 PatternLanguage::getCreatedPatternCount() {
|
||||
return this->m_evaluator->getPatternCount();
|
||||
}
|
||||
|
||||
u32 PatternLanguage::getMaximumPatternCount() {
|
||||
return this->m_evaluator->getPatternLimit();
|
||||
}
|
||||
|
||||
}
|
|
@ -259,12 +259,23 @@ namespace hex {
|
|||
ImGui::SameLine();
|
||||
if (this->m_evaluatorRunning)
|
||||
ImGui::TextSpinner("hex.view.pattern.evaluating"_lang);
|
||||
else
|
||||
else {
|
||||
if (ImGui::Checkbox("hex.view.pattern.auto"_lang, &this->m_runAutomatically)) {
|
||||
if (this->m_runAutomatically)
|
||||
this->m_hasUnevaluatedChanges = true;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::TextUnformatted(hex::format("{} / {}",
|
||||
this->m_patternLanguageRuntime->getCreatedPatternCount(),
|
||||
this->m_patternLanguageRuntime->getMaximumPatternCount()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->m_textEditor.IsTextChanged()) {
|
||||
ProjectFile::markDirty();
|
||||
|
||||
|
|
Loading…
Reference in New Issue