1
0
mirror of synced 2024-11-28 17:40:51 +01:00

Fixed pointers to built-in types and endian handling

This commit is contained in:
WerWolv 2021-01-08 15:03:53 +01:00
parent 56330686be
commit f84b661af7
2 changed files with 30 additions and 13 deletions

View File

@ -37,7 +37,7 @@ namespace hex::lang {
prv::Provider* &m_provider; prv::Provider* &m_provider;
std::endian m_defaultDataEndian; std::endian m_defaultDataEndian;
u64 m_currOffset = 0; u64 m_currOffset = 0;
std::optional<std::endian> m_currEndian; std::vector<std::endian> m_endianStack;
std::vector<std::vector<PatternData*>*> m_currMembers; std::vector<std::vector<PatternData*>*> m_currMembers;
std::map<std::string, Function> m_functions; std::map<std::string, Function> m_functions;
@ -50,7 +50,7 @@ namespace hex::lang {
} }
[[nodiscard]] std::endian getCurrentEndian() const { [[nodiscard]] std::endian getCurrentEndian() const {
return this->m_currEndian.value_or(this->m_defaultDataEndian); return this->m_endianStack.back();
} }
void addFunction(std::string_view name, u32 parameterCount, std::function<ASTNodeIntegerLiteral*(std::vector<ASTNodeIntegerLiteral*>)> func) { void addFunction(std::string_view name, u32 parameterCount, std::function<ASTNodeIntegerLiteral*(std::vector<ASTNodeIntegerLiteral*>)> func) {

View File

@ -314,13 +314,12 @@ namespace hex::lang {
this->m_currOffset += typeSize; this->m_currOffset += typeSize;
pattern->setTypeName(Token::getTypeName(type)); pattern->setTypeName(Token::getTypeName(type));
pattern->setEndian(this->getCurrentEndian());
return pattern; return pattern;
} }
std::vector<PatternData*> Evaluator::evaluateMember(ASTNode *node) { std::vector<PatternData*> Evaluator::evaluateMember(ASTNode *node) {
this->m_currEndian.reset();
if (auto memberVariableNode = dynamic_cast<ASTNodeVariableDecl*>(node); memberVariableNode != nullptr) if (auto memberVariableNode = dynamic_cast<ASTNodeVariableDecl*>(node); memberVariableNode != nullptr)
return { this->evaluateVariable(memberVariableNode) }; return { this->evaluateVariable(memberVariableNode) };
else if (auto memberArrayNode = dynamic_cast<ASTNodeArrayVariableDecl*>(node); memberArrayNode != nullptr) else if (auto memberArrayNode = dynamic_cast<ASTNodeArrayVariableDecl*>(node); memberArrayNode != nullptr)
@ -440,8 +439,7 @@ namespace hex::lang {
PatternData* Evaluator::evaluateType(ASTNodeTypeDecl *node) { PatternData* Evaluator::evaluateType(ASTNodeTypeDecl *node) {
auto type = node->getType(); auto type = node->getType();
if (!this->m_currEndian.has_value()) this->m_endianStack.push_back(node->getEndian().value_or(this->m_defaultDataEndian));
this->m_currEndian = node->getEndian();
PatternData *pattern; PatternData *pattern;
@ -463,6 +461,8 @@ namespace hex::lang {
if (!node->getName().empty()) if (!node->getName().empty())
pattern->setTypeName(node->getName().data()); pattern->setTypeName(node->getName().data());
this->m_endianStack.pop_back();
return pattern; return pattern;
} }
@ -491,7 +491,6 @@ namespace hex::lang {
pattern->setVariableName(node->getName().data()); pattern->setVariableName(node->getName().data());
pattern->setEndian(this->getCurrentEndian()); pattern->setEndian(this->getCurrentEndian());
this->m_currEndian.reset();
return pattern; return pattern;
} }
@ -572,8 +571,6 @@ namespace hex::lang {
throwEvaluateError("array exceeds size of file", node->getLineNumber()); throwEvaluateError("array exceeds size of file", node->getLineNumber());
} }
this->m_currEndian.reset();
PatternData *pattern; PatternData *pattern;
if (entries.empty()) { if (entries.empty()) {
pattern = new PatternDataPadding(startOffset, 0); pattern = new PatternDataPadding(startOffset, 0);
@ -619,11 +616,27 @@ namespace hex::lang {
u128 pointedAtOffset = 0; u128 pointedAtOffset = 0;
this->m_provider->read(pointerOffset, &pointedAtOffset, pointerSize); this->m_provider->read(pointerOffset, &pointedAtOffset, pointerSize);
this->m_currOffset = pointedAtOffset; this->m_currOffset = hex::changeEndianess(pointedAtOffset, 1, this->getCurrentEndian());
auto pointedAt = evaluateType(dynamic_cast<ASTNodeTypeDecl*>(node->getType()));
if (this->m_currOffset > this->m_provider->getActualSize())
throwEvaluateError("pointer points past the end of the data", 1);
PatternData *pointedAt;
if (auto typeDecl = dynamic_cast<ASTNodeTypeDecl*>(node->getType()); typeDecl != nullptr)
pointedAt = this->evaluateType(typeDecl);
else if (auto builtinTypeDecl = dynamic_cast<ASTNodeBuiltinType*>(node->getType()); builtinTypeDecl != nullptr)
pointedAt = this->evaluateBuiltinType(builtinTypeDecl);
else
throwEvaluateError("ASTNodeVariableDecl had an invalid type. This is a bug!", 1);
this->m_currOffset = pointerOffset + pointerSize; this->m_currOffset = pointerOffset + pointerSize;
return new PatternDataPointer(pointerOffset, pointerSize, pointedAt); auto pattern = new PatternDataPointer(pointerOffset, pointerSize, pointedAt);
pattern->setVariableName(node->getName().data());
pattern->setEndian(this->getCurrentEndian());
return pattern;
} }
std::optional<std::vector<PatternData*>> Evaluator::evaluate(const std::vector<ASTNode *> &ast) { std::optional<std::vector<PatternData*>> Evaluator::evaluate(const std::vector<ASTNode *> &ast) {
@ -632,7 +645,7 @@ namespace hex::lang {
try { try {
for (const auto& node : ast) { for (const auto& node : ast) {
this->m_currEndian.reset(); this->m_endianStack.push_back(this->m_defaultDataEndian);
if (auto variableDeclNode = dynamic_cast<ASTNodeVariableDecl*>(node); variableDeclNode != nullptr) { if (auto variableDeclNode = dynamic_cast<ASTNodeVariableDecl*>(node); variableDeclNode != nullptr) {
patterns.push_back(this->evaluateVariable(variableDeclNode)); patterns.push_back(this->evaluateVariable(variableDeclNode));
@ -644,12 +657,16 @@ namespace hex::lang {
this->m_types[typeDeclNode->getName().data()] = typeDeclNode->getType(); this->m_types[typeDeclNode->getName().data()] = typeDeclNode->getType();
} }
this->m_endianStack.pop_back();
} }
} catch (EvaluateError &e) { } catch (EvaluateError &e) {
this->m_error = e; this->m_error = e;
this->m_endianStack.clear();
return { }; return { };
} }
this->m_endianStack.clear();
return patterns; return patterns;
} }