patterns: Added button to abort evaluation

This commit is contained in:
WerWolv
2021-10-07 11:34:46 +02:00
parent 3e30f75e7b
commit 6d8b7bef09
9 changed files with 137 additions and 32 deletions

View File

@@ -516,7 +516,10 @@ namespace hex::pl {
FunctionResult execute(Evaluator *evaluator) override {
u64 loopIterations = 0;
while (evaluateCondition(evaluator)) {
evaluator->handleAbort();
auto variables = *evaluator->getScope(0).scope;
u32 startVariableCount = variables.size();
ON_SCOPE_EXIT {
@@ -538,6 +541,12 @@ namespace hex::pl {
return { true, result };
}
}
loopIterations++;
if (loopIterations >= evaluator->getLoopLimit())
LogConsole::abortEvaluation(hex::format("loop iterations exceeded limit of {}", evaluator->getLoopLimit()), this);
evaluator->handleAbort();
}
return { false, { } };
@@ -807,6 +816,7 @@ namespace hex::pl {
while (whileStatement->evaluateCondition(evaluator)) {
entryCount++;
evaluator->dataOffset() += templatePattern->getSize();
evaluator->handleAbort();
}
}
} else {
@@ -829,6 +839,7 @@ namespace hex::pl {
}
if (reachedEnd) break;
evaluator->handleAbort();
}
}
@@ -901,6 +912,8 @@ namespace hex::pl {
entries.push_back(pattern);
size += pattern->getSize();
evaluator->handleAbort();
}
} else if (auto whileStatement = dynamic_cast<ASTNodeWhileStatement*>(sizeNode)) {
while (whileStatement->evaluateCondition(evaluator)) {
@@ -917,6 +930,8 @@ namespace hex::pl {
entryCount++;
size += pattern->getSize();
evaluator->handleAbort();
}
}
} else {
@@ -951,6 +966,7 @@ namespace hex::pl {
}
if (reachedEnd) break;
evaluator->handleAbort();
}
}
@@ -1380,6 +1396,10 @@ namespace hex::pl {
std::visit(overloaded {
[&](std::string &assignmentValue) { },
[&](s128 assignmentValue) {
std::memcpy(&value, &assignmentValue, pattern->getSize());
value = hex::signExtend(pattern->getSize() * 8, value);
},
[&](auto &&assignmentValue) { std::memcpy(&value, &assignmentValue, pattern->getSize()); }
}, literal);
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include <atomic>
#include <bit>
#include <map>
#include <optional>
@@ -31,8 +32,10 @@ namespace hex::pl {
struct Scope { PatternData *parent; std::vector<PatternData*>* scope; };
void pushScope(PatternData *parent, std::vector<PatternData*> &scope) {
if (this->m_scopes.size() > this->m_evalDepth)
LogConsole::abortEvaluation(hex::format("recursion limit of {} reached", this->m_evalDepth));
if (this->m_scopes.size() > this->getEvaluationDepth())
LogConsole::abortEvaluation(hex::format("evaluation depth exceeded set limit of {}", this->getEvaluationDepth()));
this->handleAbort();
this->m_scopes.push_back({ parent, &scope });
}
@@ -70,38 +73,47 @@ namespace hex::pl {
return this->m_defaultEndian;
}
void setEvaluationDepth(u32 evalDepth) {
void setEvaluationDepth(u64 evalDepth) {
this->m_evalDepth = evalDepth;
}
[[nodiscard]]
u32 getEvaluationDepth() const {
u64 getEvaluationDepth() const {
return this->m_evalDepth;
}
void setArrayLimit(u32 arrayLimit) {
void setArrayLimit(u64 arrayLimit) {
this->m_arrayLimit = arrayLimit;
}
[[nodiscard]]
u32 getArrayLimit() const {
u64 getArrayLimit() const {
return this->m_arrayLimit;
}
void setPatternLimit(u32 limit) {
void setPatternLimit(u64 limit) {
this->m_patternLimit = limit;
}
[[nodiscard]]
u32 getPatternLimit() {
u64 getPatternLimit() {
return this->m_patternLimit;
}
[[nodiscard]]
u32 getPatternCount() {
u64 getPatternCount() {
return this->m_currPatternCount;
}
void setLoopLimit(u64 limit) {
this->m_loopLimit = limit;
}
[[nodiscard]]
u64 getLoopLimit() {
return this->m_loopLimit;
}
u64& dataOffset() { return this->m_currOffset; }
bool addCustomFunction(const std::string &name, u32 numParams, const ContentRegistry::PatternLanguageFunctions::Callback &function) {
@@ -123,6 +135,15 @@ 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);
void abort() {
this->m_aborted = true;
}
void handleAbort() {
if (this->m_aborted)
LogConsole::abortEvaluation("evaluation aborted by user");
}
private:
void patternCreated();
@@ -134,11 +155,14 @@ namespace hex::pl {
LogConsole m_console;
std::endian m_defaultEndian = std::endian::native;
u32 m_evalDepth;
u32 m_arrayLimit;
u32 m_patternLimit;
u64 m_evalDepth;
u64 m_arrayLimit;
u64 m_patternLimit;
u64 m_loopLimit;
u32 m_currPatternCount;
u64 m_currPatternCount;
std::atomic<bool> m_aborted;
std::vector<Scope> m_scopes;
std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> m_customFunctions;

View File

@@ -31,6 +31,8 @@ namespace hex::pl {
std::optional<std::vector<PatternData*>> executeString(prv::Provider *provider, const std::string &string);
std::optional<std::vector<PatternData*>> executeFile(prv::Provider *provider, const std::string &path);
void abort();
const std::vector<std::pair<LogConsole::Level, std::string>>& getConsoleLog();
const std::optional<std::pair<u32, std::string>>& getError();