diff options
author | chriseth <chris@ethereum.org> | 2017-04-26 21:41:08 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2017-04-26 23:12:04 +0800 |
commit | f3ec2ba39e7f4b85d148a7b696ef5af499fbb6fb (patch) | |
tree | be9367a377cd81badbac4bbf6bdf5377586823b3 /libsolidity/inlineasm | |
parent | 68218387cf29b3ce7de72aa0348e68dbdae29751 (diff) | |
download | dexon-solidity-f3ec2ba39e7f4b85d148a7b696ef5af499fbb6fb.tar.gz dexon-solidity-f3ec2ba39e7f4b85d148a7b696ef5af499fbb6fb.tar.zst dexon-solidity-f3ec2ba39e7f4b85d148a7b696ef5af499fbb6fb.zip |
Refactor to combined scope and stack height info.
Diffstat (limited to 'libsolidity/inlineasm')
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.cpp | 44 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.h | 13 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysisInfo.cpp | 26 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysisInfo.h | 61 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmCodeGen.cpp | 17 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmCodeGen.h | 4 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmStack.cpp | 17 |
7 files changed, 130 insertions, 52 deletions
diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 68c5a064..dad05a78 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -23,6 +23,7 @@ #include <libsolidity/inlineasm/AsmData.h> #include <libsolidity/inlineasm/AsmScopeFiller.h> #include <libsolidity/inlineasm/AsmScope.h> +#include <libsolidity/inlineasm/AsmAnalysisInfo.h> #include <libsolidity/interface/Exceptions.h> #include <libsolidity/interface/Utils.h> @@ -37,35 +38,34 @@ using namespace dev; using namespace dev::solidity; using namespace dev::solidity::assembly; - AsmAnalyzer::AsmAnalyzer( - AsmAnalyzer::Scopes& _scopes, + AsmAnalysisInfo& _analysisInfo, ErrorList& _errors, - ExternalIdentifierAccess::Resolver const& _resolver, - StackHeightInfo* _stackHeightInfo + ExternalIdentifierAccess::Resolver const& _resolver ): - m_resolver(_resolver), m_scopes(_scopes), m_errors(_errors), m_stackHeightInfo(_stackHeightInfo) + m_resolver(_resolver), m_info(_analysisInfo), m_errors(_errors) { } bool AsmAnalyzer::analyze(Block const& _block) { - if (!(ScopeFiller(m_scopes, m_errors))(_block)) + if (!(ScopeFiller(m_info.scopes, m_errors))(_block)) return false; return (*this)(_block); } -bool AsmAnalyzer::operator()(const Label& _label) +bool AsmAnalyzer::operator()(Label const& _label) { - storeStackHeight(_label); return true; + m_info.stackHeightInfo[&_label] = m_stackHeight; + return true; } bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction) { auto const& info = instructionInfo(_instruction.instruction); m_stackHeight += info.ret - info.args; - storeStackHeight(_instruction); + m_info.stackHeightInfo[&_instruction] = m_stackHeight; return true; } @@ -81,7 +81,7 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal) )); return false; } - storeStackHeight(_literal); + m_info.stackHeightInfo[&_literal] = m_stackHeight; return true; } @@ -137,7 +137,7 @@ bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier) } m_stackHeight += stackSize == size_t(-1) ? 1 : stackSize; } - storeStackHeight(_identifier); + m_info.stackHeightInfo[&_identifier] = m_stackHeight; return success; } @@ -156,14 +156,14 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr) solAssert(instructionInfo(_instr.instruction.instruction).args == int(_instr.arguments.size()), ""); if (!(*this)(_instr.instruction)) success = false; - storeStackHeight(_instr); + m_info.stackHeightInfo[&_instr] = m_stackHeight; return success; } bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment) { bool success = checkAssignment(_assignment.variableName, size_t(-1)); - storeStackHeight(_assignment); + m_info.stackHeightInfo[&_assignment] = m_stackHeight; return success; } @@ -175,7 +175,7 @@ bool AsmAnalyzer::operator()(FunctionalAssignment const& _assignment) solAssert(m_stackHeight >= stackHeight, "Negative value size."); if (!checkAssignment(_assignment.variableName, m_stackHeight - stackHeight)) success = false; - storeStackHeight(_assignment); + m_info.stackHeightInfo[&_assignment] = m_stackHeight; return success; } @@ -185,7 +185,7 @@ bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl) bool success = boost::apply_visitor(*this, *_varDecl.value); solAssert(m_stackHeight - stackHeight == 1, "Invalid value size."); boost::get<Scope::Variable>(m_currentScope->identifiers.at(_varDecl.name)).active = true; - storeStackHeight(_varDecl); + m_info.stackHeightInfo[&_varDecl] = m_stackHeight; return success; } @@ -202,7 +202,7 @@ bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef) bool success = (*this)(_funDef.body); m_stackHeight = stackHeight; - storeStackHeight(_funDef); + m_info.stackHeightInfo[&_funDef] = m_stackHeight; return success; } @@ -269,7 +269,7 @@ bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall) success = false; } m_stackHeight += int(returns) - int(arguments); - storeStackHeight(_funCall); + m_info.stackHeightInfo[&_funCall] = m_stackHeight; return success; } @@ -306,7 +306,7 @@ bool AsmAnalyzer::operator()(Block const& _block) } m_currentScope = m_currentScope->superScope; - storeStackHeight(_block); + m_info.stackHeightInfo[&_block] = m_stackHeight; return success; } @@ -372,12 +372,6 @@ bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t return success; } -void AsmAnalyzer::storeStackHeight(const assembly::Statement& _statement) -{ - if (m_stackHeightInfo) - (*m_stackHeightInfo)[&_statement] = m_stackHeight; -} - bool AsmAnalyzer::expectDeposit(int const _deposit, int const _oldHeight, SourceLocation const& _location) { int stackDiff = m_stackHeight - _oldHeight; @@ -400,7 +394,7 @@ bool AsmAnalyzer::expectDeposit(int const _deposit, int const _oldHeight, Source Scope& AsmAnalyzer::scope(Block const* _block) { - auto scopePtr = m_scopes.at(_block); + auto scopePtr = m_info.scopes.at(_block); solAssert(scopePtr, "Scope requested but not present."); return *scopePtr; } diff --git a/libsolidity/inlineasm/AsmAnalysis.h b/libsolidity/inlineasm/AsmAnalysis.h index 8256ed3c..426ee0d2 100644 --- a/libsolidity/inlineasm/AsmAnalysis.h +++ b/libsolidity/inlineasm/AsmAnalysis.h @@ -50,8 +50,7 @@ struct FunctionCall; struct Scope; -using Statement = boost::variant<Instruction, Literal, Label, Assignment, Identifier, FunctionalAssignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Block>; -using StackHeightInfo = std::map<assembly::Statement const*, int>; +struct AsmAnalysisInfo; /** * Performs the full analysis stage, calls the ScopeFiller internally, then resolves @@ -61,12 +60,10 @@ using StackHeightInfo = std::map<assembly::Statement const*, int>; class AsmAnalyzer: public boost::static_visitor<bool> { public: - using Scopes = std::map<assembly::Block const*, std::shared_ptr<Scope>>; AsmAnalyzer( - Scopes& _scopes, + AsmAnalysisInfo& _analysisInfo, ErrorList& _errors, - ExternalIdentifierAccess::Resolver const& _resolver = ExternalIdentifierAccess::Resolver(), - StackHeightInfo* _stackHeightInfo = nullptr + ExternalIdentifierAccess::Resolver const& _resolver = ExternalIdentifierAccess::Resolver() ); bool analyze(assembly::Block const& _block); @@ -88,7 +85,6 @@ private: /// as the value, @a _valueSize, unless that is equal to -1. bool checkAssignment(assembly::Identifier const& _assignment, size_t _valueSize = size_t(-1)); bool expectDeposit(int _deposit, int _oldHeight, SourceLocation const& _location); - void storeStackHeight(assembly::Statement const& _statement); Scope& scope(assembly::Block const* _block); /// This is used when we enter the body of a function definition. There, the parameters @@ -98,9 +94,8 @@ private: int m_stackHeight = 0; ExternalIdentifierAccess::Resolver const& m_resolver; Scope* m_currentScope = nullptr; - Scopes& m_scopes; + AsmAnalysisInfo& m_info; ErrorList& m_errors; - StackHeightInfo* m_stackHeightInfo; }; } diff --git a/libsolidity/inlineasm/AsmAnalysisInfo.cpp b/libsolidity/inlineasm/AsmAnalysisInfo.cpp new file mode 100644 index 00000000..22318b12 --- /dev/null +++ b/libsolidity/inlineasm/AsmAnalysisInfo.cpp @@ -0,0 +1,26 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * Information generated during analyzer part of inline assembly. + */ + +#include <libsolidity/inlineasm/AsmAnalysisInfo.h> + +#include <libsolidity/inlineasm/AsmScope.h> + +#include <ostream> + diff --git a/libsolidity/inlineasm/AsmAnalysisInfo.h b/libsolidity/inlineasm/AsmAnalysisInfo.h new file mode 100644 index 00000000..e21eb2c5 --- /dev/null +++ b/libsolidity/inlineasm/AsmAnalysisInfo.h @@ -0,0 +1,61 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * Information generated during analyzer part of inline assembly. + */ + +#pragma once + +#include <boost/variant.hpp> + +#include <map> +#include <memory> + +namespace dev +{ +namespace solidity +{ +namespace assembly +{ + +struct Literal; +struct Block; +struct Label; +struct FunctionalInstruction; +struct FunctionalAssignment; +struct VariableDeclaration; +struct Instruction; +struct Identifier; +struct Assignment; +struct FunctionDefinition; +struct FunctionCall; + +struct Scope; + +using Statement = boost::variant<Instruction, Literal, Label, Assignment, Identifier, FunctionalAssignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Block>; + +struct AsmAnalysisInfo +{ + using StackHeightInfo = std::map<void const*, int>; + using Scopes = std::map<assembly::Block const*, std::shared_ptr<Scope>>; + Scopes scopes; + StackHeightInfo stackHeightInfo; +}; + +} +} +} diff --git a/libsolidity/inlineasm/AsmCodeGen.cpp b/libsolidity/inlineasm/AsmCodeGen.cpp index 68d674f9..be52db46 100644 --- a/libsolidity/inlineasm/AsmCodeGen.cpp +++ b/libsolidity/inlineasm/AsmCodeGen.cpp @@ -26,6 +26,7 @@ #include <libsolidity/inlineasm/AsmData.h> #include <libsolidity/inlineasm/AsmScope.h> #include <libsolidity/inlineasm/AsmAnalysis.h> +#include <libsolidity/inlineasm/AsmAnalysisInfo.h> #include <libevmasm/Assembly.h> #include <libevmasm/SourceLocation.h> @@ -47,8 +48,8 @@ using namespace dev::solidity::assembly; struct GeneratorState { - GeneratorState(ErrorList& _errors, AsmAnalyzer::Scopes& _scopes, eth::Assembly& _assembly): - errors(_errors), scopes(_scopes), assembly(_assembly) {} + GeneratorState(ErrorList& _errors, AsmAnalysisInfo& _analysisInfo, eth::Assembly& _assembly): + errors(_errors), info(_analysisInfo), assembly(_assembly) {} size_t newLabelId() { @@ -63,7 +64,7 @@ struct GeneratorState } ErrorList& errors; - AsmAnalyzer::Scopes scopes; + AsmAnalysisInfo info; eth::Assembly& assembly; }; @@ -79,7 +80,7 @@ public: assembly::ExternalIdentifierAccess const& _identifierAccess = assembly::ExternalIdentifierAccess() ): m_state(_state), - m_scope(*m_state.scopes.at(&_block)), + m_scope(*m_state.info.scopes.at(&_block)), m_initialDeposit(m_state.assembly.deposit()), m_identifierAccess(_identifierAccess) { @@ -262,23 +263,23 @@ private: eth::Assembly assembly::CodeGenerator::assemble( Block const& _parsedData, - AsmAnalyzer::Scopes& _scopes, + AsmAnalysisInfo& _analysisInfo, ExternalIdentifierAccess const& _identifierAccess ) { eth::Assembly assembly; - GeneratorState state(m_errors, _scopes, assembly); + GeneratorState state(m_errors, _analysisInfo, assembly); CodeTransform(state, _parsedData, _identifierAccess); return assembly; } void assembly::CodeGenerator::assemble( Block const& _parsedData, - AsmAnalyzer::Scopes& _scopes, + AsmAnalysisInfo& _analysisInfo, eth::Assembly& _assembly, ExternalIdentifierAccess const& _identifierAccess ) { - GeneratorState state(m_errors, _scopes, _assembly); + GeneratorState state(m_errors, _analysisInfo, _assembly); CodeTransform(state, _parsedData, _identifierAccess); } diff --git a/libsolidity/inlineasm/AsmCodeGen.h b/libsolidity/inlineasm/AsmCodeGen.h index 18165cbd..e830e047 100644 --- a/libsolidity/inlineasm/AsmCodeGen.h +++ b/libsolidity/inlineasm/AsmCodeGen.h @@ -47,13 +47,13 @@ public: /// Performs code generation and @returns the result. eth::Assembly assemble( Block const& _parsedData, - AsmAnalyzer::Scopes& _scopes, + AsmAnalysisInfo& _analysisInfo, ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess() ); /// Performs code generation and appends generated to to _assembly. void assemble( Block const& _parsedData, - AsmAnalyzer::Scopes& _scopes, + AsmAnalysisInfo& _analysisInfo, eth::Assembly& _assembly, ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess() ); diff --git a/libsolidity/inlineasm/AsmStack.cpp b/libsolidity/inlineasm/AsmStack.cpp index 5defae4c..c2a7d8ea 100644 --- a/libsolidity/inlineasm/AsmStack.cpp +++ b/libsolidity/inlineasm/AsmStack.cpp @@ -26,6 +26,7 @@ #include <libsolidity/inlineasm/AsmCodeGen.h> #include <libsolidity/inlineasm/AsmPrinter.h> #include <libsolidity/inlineasm/AsmAnalysis.h> +#include <libsolidity/inlineasm/AsmAnalysisInfo.h> #include <libsolidity/parsing/Scanner.h> @@ -51,8 +52,8 @@ bool InlineAssemblyStack::parse( return false; *m_parserResult = std::move(*result); - AsmAnalyzer::Scopes scopes; - return (AsmAnalyzer(scopes, m_errors, _resolver)).analyze(*m_parserResult); + AsmAnalysisInfo analysisInfo; + return (AsmAnalyzer(analysisInfo, m_errors, _resolver)).analyze(*m_parserResult); } string InlineAssemblyStack::toString() @@ -62,11 +63,11 @@ string InlineAssemblyStack::toString() eth::Assembly InlineAssemblyStack::assemble() { - AsmAnalyzer::Scopes scopes; - AsmAnalyzer analyzer(scopes, m_errors); + AsmAnalysisInfo analysisInfo; + AsmAnalyzer analyzer(analysisInfo, m_errors); solAssert(analyzer.analyze(*m_parserResult), ""); CodeGenerator codeGen(m_errors); - return codeGen.assemble(*m_parserResult, scopes); + return codeGen.assemble(*m_parserResult, analysisInfo); } bool InlineAssemblyStack::parseAndAssemble( @@ -82,10 +83,10 @@ bool InlineAssemblyStack::parseAndAssemble( return false; solAssert(parserResult, ""); - AsmAnalyzer::Scopes scopes; - AsmAnalyzer analyzer(scopes, errors, _identifierAccess.resolve); + AsmAnalysisInfo analysisInfo; + AsmAnalyzer analyzer(analysisInfo, errors, _identifierAccess.resolve); solAssert(analyzer.analyze(*parserResult), ""); - CodeGenerator(errors).assemble(*parserResult, scopes, _assembly, _identifierAccess); + CodeGenerator(errors).assemble(*parserResult, analysisInfo, _assembly, _identifierAccess); // At this point, the assembly might be messed up, but we should throw an // internal compiler error anyway. |