diff options
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 4 | ||||
-rw-r--r-- | libsolidity/ast/ASTAnnotations.h | 4 | ||||
-rw-r--r-- | libsolidity/codegen/ContractCompiler.cpp | 4 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.h | 6 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmCodeGen.cpp | 31 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmCodeGen.h | 20 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmStack.cpp | 12 |
7 files changed, 55 insertions, 26 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index f26c0a39..29011676 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -692,8 +692,8 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) ref->second.valueSize = 1; return size_t(1); }; - assembly::AsmAnalyzer::Scopes scopes; - assembly::AsmAnalyzer analyzer(scopes, m_errors, identifierAccess); + solAssert(_inlineAssembly.annotation().scopes.empty(), ""); + assembly::AsmAnalyzer analyzer(_inlineAssembly.annotation().scopes, m_errors, identifierAccess); if (!analyzer.analyze(_inlineAssembly.operations())) return false; return true; diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 9ca7f66c..48524be3 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -113,6 +113,8 @@ struct StatementAnnotation: ASTAnnotation, DocumentedAnnotation namespace assembly { struct Identifier; // forward +struct Block; // forward +struct Scope; // forward } struct InlineAssemblyAnnotation: StatementAnnotation @@ -125,6 +127,8 @@ struct InlineAssemblyAnnotation: StatementAnnotation /// Mapping containing resolved references to external identifiers and their value size std::map<assembly::Identifier const*, ExternalIdentifierInfo> externalReferences; + /// Mapping containing the scopes (the result of the analysis phase). + std::map<assembly::Block const*, std::shared_ptr<assembly::Scope>> scopes; }; struct ReturnAnnotation: StatementAnnotation diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 9bef8a8f..5257b1f7 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -520,7 +520,7 @@ bool ContractCompiler::visit(FunctionDefinition const& _function) bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) { ErrorList errors; - assembly::CodeGenerator codeGen(_inlineAssembly.operations(), errors); + assembly::CodeGenerator codeGen(errors); unsigned startStackHeight = m_context.stackHeight(); assembly::ExternalIdentifierAccess identifierAccess; identifierAccess.resolve = [&](assembly::Identifier const& _identifier, assembly::IdentifierContext) @@ -598,6 +598,8 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) } }; codeGen.assemble( + _inlineAssembly.operations(), + _inlineAssembly.annotation().scopes, m_context.nonConstAssembly(), identifierAccess ); diff --git a/libsolidity/inlineasm/AsmAnalysis.h b/libsolidity/inlineasm/AsmAnalysis.h index ed357561..5980b582 100644 --- a/libsolidity/inlineasm/AsmAnalysis.h +++ b/libsolidity/inlineasm/AsmAnalysis.h @@ -59,7 +59,11 @@ class AsmAnalyzer: public boost::static_visitor<bool> { public: using Scopes = std::map<assembly::Block const*, std::shared_ptr<Scope>>; - AsmAnalyzer(Scopes& _scopes, ErrorList& _errors, ExternalIdentifierAccess::Resolver const& _resolver); + AsmAnalyzer( + Scopes& _scopes, + ErrorList& _errors, + ExternalIdentifierAccess::Resolver const& _resolver = ExternalIdentifierAccess::Resolver() + ); bool analyze(assembly::Block const& _block); diff --git a/libsolidity/inlineasm/AsmCodeGen.cpp b/libsolidity/inlineasm/AsmCodeGen.cpp index ad413216..68d674f9 100644 --- a/libsolidity/inlineasm/AsmCodeGen.cpp +++ b/libsolidity/inlineasm/AsmCodeGen.cpp @@ -47,8 +47,8 @@ using namespace dev::solidity::assembly; struct GeneratorState { - GeneratorState(ErrorList& _errors, eth::Assembly& _assembly): - errors(_errors), assembly(_assembly) {} + GeneratorState(ErrorList& _errors, AsmAnalyzer::Scopes& _scopes, eth::Assembly& _assembly): + errors(_errors), scopes(_scopes), assembly(_assembly) {} size_t newLabelId() { @@ -62,8 +62,8 @@ struct GeneratorState return size_t(id); } - AsmAnalyzer::Scopes scopes; ErrorList& errors; + AsmAnalyzer::Scopes scopes; eth::Assembly& assembly; }; @@ -260,20 +260,25 @@ private: ExternalIdentifierAccess m_identifierAccess; }; -eth::Assembly assembly::CodeGenerator::assemble(ExternalIdentifierAccess const& _identifierAccess) +eth::Assembly assembly::CodeGenerator::assemble( + Block const& _parsedData, + AsmAnalyzer::Scopes& _scopes, + ExternalIdentifierAccess const& _identifierAccess +) { eth::Assembly assembly; - GeneratorState state(m_errors, assembly); - if (!(AsmAnalyzer(state.scopes, m_errors, _identifierAccess.resolve)).analyze(m_parsedData)) - solAssert(false, "Assembly error"); - CodeTransform(state, m_parsedData, _identifierAccess); + GeneratorState state(m_errors, _scopes, assembly); + CodeTransform(state, _parsedData, _identifierAccess); return assembly; } -void assembly::CodeGenerator::assemble(eth::Assembly& _assembly, ExternalIdentifierAccess const& _identifierAccess) +void assembly::CodeGenerator::assemble( + Block const& _parsedData, + AsmAnalyzer::Scopes& _scopes, + eth::Assembly& _assembly, + ExternalIdentifierAccess const& _identifierAccess +) { - GeneratorState state(m_errors, _assembly); - if (!(AsmAnalyzer(state.scopes, m_errors, _identifierAccess.resolve)).analyze(m_parsedData)) - solAssert(false, "Assembly error"); - CodeTransform(state, m_parsedData, _identifierAccess); + GeneratorState state(m_errors, _scopes, _assembly); + CodeTransform(state, _parsedData, _identifierAccess); } diff --git a/libsolidity/inlineasm/AsmCodeGen.h b/libsolidity/inlineasm/AsmCodeGen.h index ed61a7eb..18165cbd 100644 --- a/libsolidity/inlineasm/AsmCodeGen.h +++ b/libsolidity/inlineasm/AsmCodeGen.h @@ -22,8 +22,8 @@ #pragma once +#include <libsolidity/inlineasm/AsmAnalysis.h> #include <libsolidity/interface/Exceptions.h> -#include <libsolidity/inlineasm/AsmStack.h> #include <functional> @@ -42,15 +42,23 @@ struct Block; class CodeGenerator { public: - CodeGenerator(Block const& _parsedData, ErrorList& _errors): - m_parsedData(_parsedData), m_errors(_errors) {} + CodeGenerator(ErrorList& _errors): + m_errors(_errors) {} /// Performs code generation and @returns the result. - eth::Assembly assemble(ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess()); + eth::Assembly assemble( + Block const& _parsedData, + AsmAnalyzer::Scopes& _scopes, + ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess() + ); /// Performs code generation and appends generated to to _assembly. - void assemble(eth::Assembly& _assembly, ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess()); + void assemble( + Block const& _parsedData, + AsmAnalyzer::Scopes& _scopes, + eth::Assembly& _assembly, + ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess() + ); private: - Block const& m_parsedData; ErrorList& m_errors; }; diff --git a/libsolidity/inlineasm/AsmStack.cpp b/libsolidity/inlineasm/AsmStack.cpp index 146fc114..1903de42 100644 --- a/libsolidity/inlineasm/AsmStack.cpp +++ b/libsolidity/inlineasm/AsmStack.cpp @@ -62,8 +62,11 @@ string InlineAssemblyStack::toString() eth::Assembly InlineAssemblyStack::assemble() { - CodeGenerator codeGen(*m_parserResult, m_errors); - return codeGen.assemble(); + AsmAnalyzer::Scopes scopes; + AsmAnalyzer analyzer(scopes, m_errors); + solAssert(analyzer.analyze(*m_parserResult), ""); + CodeGenerator codeGen(m_errors); + return codeGen.assemble(*m_parserResult, scopes); } bool InlineAssemblyStack::parseAndAssemble( @@ -78,7 +81,10 @@ bool InlineAssemblyStack::parseAndAssemble( if (!errors.empty()) return false; - CodeGenerator(*parserResult, errors).assemble(_assembly, _identifierAccess); + AsmAnalyzer::Scopes scopes; + AsmAnalyzer analyzer(scopes, m_errors); + solAssert(analyzer.analyze(*m_parserResult), ""); + CodeGenerator(errors).assemble(*parserResult, scopes, _assembly, _identifierAccess); // At this point, the assembly might be messed up, but we should throw an // internal compiler error anyway. |