aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsolidity/analysis/TypeChecker.cpp4
-rw-r--r--libsolidity/ast/ASTAnnotations.h4
-rw-r--r--libsolidity/codegen/ContractCompiler.cpp4
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.h6
-rw-r--r--libsolidity/inlineasm/AsmCodeGen.cpp31
-rw-r--r--libsolidity/inlineasm/AsmCodeGen.h20
-rw-r--r--libsolidity/inlineasm/AsmStack.cpp12
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.