From 05004253ba9f7bf5a3d71d8ed590367619ebbe4f Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 1 Jun 2017 14:16:01 +0200 Subject: Refactor to use expectExpression in analyzer. --- libsolidity/inlineasm/AsmAnalysis.cpp | 60 ++++++++++++++--------------------- 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> 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(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(_deposit) + - " item(s) to the stack, but did deposit " + - boost::lexical_cast(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; + 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); -- cgit From 40f3e4413b7eb36d32ab314dc1d854d8428116e6 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 1 Jun 2017 15:31:07 +0200 Subject: Improved error message. --- libsolidity/inlineasm/AsmAnalysis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 8ed59bc9..8fa72d7e 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -345,7 +345,7 @@ bool AsmAnalyzer::expectExpression(Statement const& _statement) { m_errorReporter.typeError( locationOf(_statement), - "Expected instruction(s) to deposit one item to the stack but did deposit " + + "Expected expression to return one item to the stack but did return " + boost::lexical_cast(m_stackHeight - initialHeight) + " items." ); -- cgit From d5408f78ad2089beaabc60e7b876ad1ff0d276a1 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 1 Jun 2017 15:56:49 +0200 Subject: Add comma. --- libsolidity/inlineasm/AsmAnalysis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 8fa72d7e..3edc01ad 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -345,7 +345,7 @@ bool AsmAnalyzer::expectExpression(Statement const& _statement) { m_errorReporter.typeError( locationOf(_statement), - "Expected expression to return one item to the stack but did return " + + "Expected expression to return one item to the stack, but did return " + boost::lexical_cast(m_stackHeight - initialHeight) + " items." ); -- cgit