From dfb7d5ebd955d390142241a2abcb95995ef1ba04 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 12 Apr 2017 18:32:25 +0200 Subject: Move analysis out of code generator. --- libsolidity/analysis/TypeChecker.cpp | 4 ++-- libsolidity/ast/ASTAnnotations.h | 4 ++++ libsolidity/codegen/ContractCompiler.cpp | 4 +++- libsolidity/inlineasm/AsmAnalysis.h | 6 +++++- libsolidity/inlineasm/AsmCodeGen.cpp | 31 ++++++++++++++++++------------- libsolidity/inlineasm/AsmCodeGen.h | 20 ++++++++++++++------ libsolidity/inlineasm/AsmStack.cpp | 12 +++++++++--- 7 files changed, 55 insertions(+), 26 deletions(-) (limited to 'libsolidity') 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 externalReferences; + /// Mapping containing the scopes (the result of the analysis phase). + std::map> 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 { public: using Scopes = std::map>; - 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 #include -#include #include @@ -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. -- cgit v1.2.3