aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2017-06-01 21:57:28 +0800
committerGitHub <noreply@github.com>2017-06-01 21:57:28 +0800
commitb4ae188a0f6da55317ca04bd64a7524592089ed0 (patch)
tree38b0b837fd37b2499e9b98463de3da99bde2b880
parent96de7a83264e3926831889bf48a897591efb3ff5 (diff)
parentd5408f78ad2089beaabc60e7b876ad1ff0d276a1 (diff)
downloaddexon-solidity-b4ae188a0f6da55317ca04bd64a7524592089ed0.tar
dexon-solidity-b4ae188a0f6da55317ca04bd64a7524592089ed0.tar.gz
dexon-solidity-b4ae188a0f6da55317ca04bd64a7524592089ed0.tar.bz2
dexon-solidity-b4ae188a0f6da55317ca04bd64a7524592089ed0.tar.lz
dexon-solidity-b4ae188a0f6da55317ca04bd64a7524592089ed0.tar.xz
dexon-solidity-b4ae188a0f6da55317ca04bd64a7524592089ed0.tar.zst
dexon-solidity-b4ae188a0f6da55317ca04bd64a7524592089ed0.zip
Merge pull request #2336 from ethereum/expectExpression
Refactor to use expectExpression in analyzer.
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.cpp60
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.h7
2 files changed, 29 insertions, 38 deletions
diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp
index 22e43127..3edc01ad 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 expression to return one item to the stack, but did return " +
+ 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);