diff options
author | chriseth <chris@ethereum.org> | 2017-04-26 18:34:24 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2017-04-26 18:34:24 +0800 |
commit | 68218387cf29b3ce7de72aa0348e68dbdae29751 (patch) | |
tree | 50383cf7df14c99a323d4490899774b6df132941 | |
parent | a46a059e3a4b860c51821cabcfd8316b021f4245 (diff) | |
download | dexon-solidity-68218387cf29b3ce7de72aa0348e68dbdae29751.tar.gz dexon-solidity-68218387cf29b3ce7de72aa0348e68dbdae29751.tar.zst dexon-solidity-68218387cf29b3ce7de72aa0348e68dbdae29751.zip |
Store stack height in analysis phase.
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.cpp | 30 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.h | 10 |
2 files changed, 35 insertions, 5 deletions
diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 97ec8b1f..68c5a064 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -41,9 +41,10 @@ using namespace dev::solidity::assembly; AsmAnalyzer::AsmAnalyzer( AsmAnalyzer::Scopes& _scopes, ErrorList& _errors, - ExternalIdentifierAccess::Resolver const& _resolver + ExternalIdentifierAccess::Resolver const& _resolver, + StackHeightInfo* _stackHeightInfo ): - m_resolver(_resolver), m_scopes(_scopes), m_errors(_errors) + m_resolver(_resolver), m_scopes(_scopes), m_errors(_errors), m_stackHeightInfo(_stackHeightInfo) { } @@ -55,10 +56,16 @@ bool AsmAnalyzer::analyze(Block const& _block) return (*this)(_block); } +bool AsmAnalyzer::operator()(const Label& _label) +{ + storeStackHeight(_label); return true; +} + bool AsmAnalyzer::operator()(assembly::Instruction const& _instruction) { auto const& info = instructionInfo(_instruction.instruction); m_stackHeight += info.ret - info.args; + storeStackHeight(_instruction); return true; } @@ -74,6 +81,7 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal) )); return false; } + storeStackHeight(_literal); return true; } @@ -129,6 +137,7 @@ bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier) } m_stackHeight += stackSize == size_t(-1) ? 1 : stackSize; } + storeStackHeight(_identifier); return success; } @@ -147,14 +156,18 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr) solAssert(instructionInfo(_instr.instruction.instruction).args == int(_instr.arguments.size()), ""); if (!(*this)(_instr.instruction)) success = false; + storeStackHeight(_instr); return success; } bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment) { - return checkAssignment(_assignment.variableName, size_t(-1)); + bool success = checkAssignment(_assignment.variableName, size_t(-1)); + storeStackHeight(_assignment); + return success; } + bool AsmAnalyzer::operator()(FunctionalAssignment const& _assignment) { int const stackHeight = m_stackHeight; @@ -162,6 +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); return success; } @@ -171,6 +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); return success; } @@ -187,6 +202,7 @@ bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef) bool success = (*this)(_funDef.body); m_stackHeight = stackHeight; + storeStackHeight(_funDef); return success; } @@ -253,6 +269,7 @@ bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall) success = false; } m_stackHeight += int(returns) - int(arguments); + storeStackHeight(_funCall); return success; } @@ -289,6 +306,7 @@ bool AsmAnalyzer::operator()(Block const& _block) } m_currentScope = m_currentScope->superScope; + storeStackHeight(_block); return success; } @@ -354,6 +372,12 @@ 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; diff --git a/libsolidity/inlineasm/AsmAnalysis.h b/libsolidity/inlineasm/AsmAnalysis.h index 5980b582..8256ed3c 100644 --- a/libsolidity/inlineasm/AsmAnalysis.h +++ b/libsolidity/inlineasm/AsmAnalysis.h @@ -50,6 +50,9 @@ 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>; + /** * Performs the full analysis stage, calls the ScopeFiller internally, then resolves * references and performs other checks. @@ -62,7 +65,8 @@ public: AsmAnalyzer( Scopes& _scopes, ErrorList& _errors, - ExternalIdentifierAccess::Resolver const& _resolver = ExternalIdentifierAccess::Resolver() + ExternalIdentifierAccess::Resolver const& _resolver = ExternalIdentifierAccess::Resolver(), + StackHeightInfo* _stackHeightInfo = nullptr ); bool analyze(assembly::Block const& _block); @@ -71,7 +75,7 @@ public: bool operator()(assembly::Literal const& _literal); bool operator()(assembly::Identifier const&); bool operator()(assembly::FunctionalInstruction const& _functionalInstruction); - bool operator()(assembly::Label const&) { return true; } + bool operator()(assembly::Label const& _label); bool operator()(assembly::Assignment const&); bool operator()(assembly::FunctionalAssignment const& _functionalAssignment); bool operator()(assembly::VariableDeclaration const& _variableDeclaration); @@ -84,6 +88,7 @@ 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 @@ -95,6 +100,7 @@ private: Scope* m_currentScope = nullptr; Scopes& m_scopes; ErrorList& m_errors; + StackHeightInfo* m_stackHeightInfo; }; } |