diff options
author | chriseth <chris@ethereum.org> | 2017-06-01 20:16:01 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2017-06-01 20:28:39 +0800 |
commit | 05004253ba9f7bf5a3d71d8ed590367619ebbe4f (patch) | |
tree | 31e43abe776796e994a55c84ffecf41dbfc73af8 /libsolidity | |
parent | d4a57d81ba7f2a9b5db57397d36f1a17adb4b142 (diff) | |
download | dexon-solidity-05004253ba9f7bf5a3d71d8ed590367619ebbe4f.tar.gz dexon-solidity-05004253ba9f7bf5a3d71d8ed590367619ebbe4f.tar.zst dexon-solidity-05004253ba9f7bf5a3d71d8ed590367619ebbe4f.zip |
Refactor to use expectExpression in analyzer.
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.cpp | 60 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.h | 7 |
2 files changed, 29 insertions, 38 deletions
diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 22e43127..8ed59bc9 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -139,13 +139,8 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr) solAssert(!m_julia, ""); bool success = true; for (auto const& arg: _instr.arguments | boost::adaptors::reversed) - { - int const stackHeight = m_stackHeight; - if (!boost::apply_visitor(*this, arg)) - success = false; - if (!expectDeposit(1, stackHeight, locationOf(arg))) + if (!expectExpression(arg)) success = false; - } // Parser already checks that the number of arguments is correct. solAssert(instructionInfo(_instr.instruction.instruction).args == int(_instr.arguments.size()), ""); if (!(*this)(_instr.instruction)) @@ -260,13 +255,8 @@ bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall) } } for (auto const& arg: _funCall.arguments | boost::adaptors::reversed) - { - int const stackHeight = m_stackHeight; - if (!boost::apply_visitor(*this, arg)) + if (!expectExpression(arg)) success = false; - if (!expectDeposit(1, stackHeight, locationOf(arg))) - success = false; - } m_stackHeight += int(returns) - int(arguments); m_info.stackHeightInfo[&_funCall] = m_stackHeight; return success; @@ -276,20 +266,16 @@ bool AsmAnalyzer::operator()(Switch const& _switch) { bool success = true; - int const initialStackHeight = m_stackHeight; - if (!boost::apply_visitor(*this, *_switch.expression)) + if (!expectExpression(*_switch.expression)) success = false; - expectDeposit(1, initialStackHeight, locationOf(*_switch.expression)); set<tuple<LiteralKind, string>> cases; for (auto const& _case: _switch.cases) { if (_case.value) { - int const initialStackHeight = m_stackHeight; - if (!(*this)(*_case.value)) + if (!expectExpression(*_case.value)) success = false; - expectDeposit(1, initialStackHeight, _case.value->location); m_stackHeight--; /// Note: the parser ensures there is only one default case @@ -349,6 +335,25 @@ bool AsmAnalyzer::operator()(Block const& _block) return success; } +bool AsmAnalyzer::expectExpression(Statement const& _statement) +{ + bool success = true; + int const initialHeight = m_stackHeight; + if (!boost::apply_visitor(*this, _statement)) + success = false; + if (m_stackHeight - initialHeight != 1) + { + m_errorReporter.typeError( + locationOf(_statement), + "Expected instruction(s) to deposit one item to the stack but did deposit " + + boost::lexical_cast<string>(m_stackHeight - initialHeight) + + " items." + ); + success = false; + } + return success; +} + bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t _valueSize) { bool success = true; @@ -401,25 +406,6 @@ bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t return success; } -bool AsmAnalyzer::expectDeposit(int const _deposit, int const _oldHeight, SourceLocation const& _location) -{ - int stackDiff = m_stackHeight - _oldHeight; - if (stackDiff != _deposit) - { - m_errorReporter.typeError( - _location, - "Expected instruction(s) to deposit " + - boost::lexical_cast<string>(_deposit) + - " item(s) to the stack, but did deposit " + - boost::lexical_cast<string>(stackDiff) + - " item(s)." - ); - return false; - } - else - return true; -} - Scope& AsmAnalyzer::scope(Block const* _block) { solAssert(m_info.scopes.count(_block) == 1, "Scope requested but not present."); diff --git a/libsolidity/inlineasm/AsmAnalysis.h b/libsolidity/inlineasm/AsmAnalysis.h index 7e4d78df..e52e6302 100644 --- a/libsolidity/inlineasm/AsmAnalysis.h +++ b/libsolidity/inlineasm/AsmAnalysis.h @@ -47,6 +47,8 @@ struct StackAssignment; struct FunctionDefinition; struct FunctionCall; struct Switch; +using Statement = boost::variant<Instruction, Literal, Label, StackAssignment, Identifier, Assignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Switch, Block>; + struct Scope; @@ -83,10 +85,13 @@ public: bool operator()(assembly::Block const& _block); private: + /// Visits the statement and expects it to deposit one item onto the stack. + bool expectExpression(Statement const& _statement); + /// Verifies that a variable to be assigned to exists and has the same size /// 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); + Scope& scope(assembly::Block const* _block); void expectValidType(std::string const& type, SourceLocation const& _location); |