mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Refactor to use expectExpression in analyzer.
This commit is contained in:
parent
d4a57d81ba
commit
05004253ba
@ -139,13 +139,8 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr)
|
|||||||
solAssert(!m_julia, "");
|
solAssert(!m_julia, "");
|
||||||
bool success = true;
|
bool success = true;
|
||||||
for (auto const& arg: _instr.arguments | boost::adaptors::reversed)
|
for (auto const& arg: _instr.arguments | boost::adaptors::reversed)
|
||||||
{
|
if (!expectExpression(arg))
|
||||||
int const stackHeight = m_stackHeight;
|
|
||||||
if (!boost::apply_visitor(*this, arg))
|
|
||||||
success = false;
|
success = false;
|
||||||
if (!expectDeposit(1, stackHeight, locationOf(arg)))
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
// Parser already checks that the number of arguments is correct.
|
// Parser already checks that the number of arguments is correct.
|
||||||
solAssert(instructionInfo(_instr.instruction.instruction).args == int(_instr.arguments.size()), "");
|
solAssert(instructionInfo(_instr.instruction.instruction).args == int(_instr.arguments.size()), "");
|
||||||
if (!(*this)(_instr.instruction))
|
if (!(*this)(_instr.instruction))
|
||||||
@ -260,13 +255,8 @@ bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto const& arg: _funCall.arguments | boost::adaptors::reversed)
|
for (auto const& arg: _funCall.arguments | boost::adaptors::reversed)
|
||||||
{
|
if (!expectExpression(arg))
|
||||||
int const stackHeight = m_stackHeight;
|
|
||||||
if (!boost::apply_visitor(*this, arg))
|
|
||||||
success = false;
|
success = false;
|
||||||
if (!expectDeposit(1, stackHeight, locationOf(arg)))
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
m_stackHeight += int(returns) - int(arguments);
|
m_stackHeight += int(returns) - int(arguments);
|
||||||
m_info.stackHeightInfo[&_funCall] = m_stackHeight;
|
m_info.stackHeightInfo[&_funCall] = m_stackHeight;
|
||||||
return success;
|
return success;
|
||||||
@ -276,20 +266,16 @@ bool AsmAnalyzer::operator()(Switch const& _switch)
|
|||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
int const initialStackHeight = m_stackHeight;
|
if (!expectExpression(*_switch.expression))
|
||||||
if (!boost::apply_visitor(*this, *_switch.expression))
|
|
||||||
success = false;
|
success = false;
|
||||||
expectDeposit(1, initialStackHeight, locationOf(*_switch.expression));
|
|
||||||
|
|
||||||
set<tuple<LiteralKind, string>> cases;
|
set<tuple<LiteralKind, string>> cases;
|
||||||
for (auto const& _case: _switch.cases)
|
for (auto const& _case: _switch.cases)
|
||||||
{
|
{
|
||||||
if (_case.value)
|
if (_case.value)
|
||||||
{
|
{
|
||||||
int const initialStackHeight = m_stackHeight;
|
if (!expectExpression(*_case.value))
|
||||||
if (!(*this)(*_case.value))
|
|
||||||
success = false;
|
success = false;
|
||||||
expectDeposit(1, initialStackHeight, _case.value->location);
|
|
||||||
m_stackHeight--;
|
m_stackHeight--;
|
||||||
|
|
||||||
/// Note: the parser ensures there is only one default case
|
/// Note: the parser ensures there is only one default case
|
||||||
@ -349,6 +335,25 @@ bool AsmAnalyzer::operator()(Block const& _block)
|
|||||||
return success;
|
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 AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t _valueSize)
|
||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
@ -401,25 +406,6 @@ bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t
|
|||||||
return success;
|
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)
|
Scope& AsmAnalyzer::scope(Block const* _block)
|
||||||
{
|
{
|
||||||
solAssert(m_info.scopes.count(_block) == 1, "Scope requested but not present.");
|
solAssert(m_info.scopes.count(_block) == 1, "Scope requested but not present.");
|
||||||
|
@ -47,6 +47,8 @@ struct StackAssignment;
|
|||||||
struct FunctionDefinition;
|
struct FunctionDefinition;
|
||||||
struct FunctionCall;
|
struct FunctionCall;
|
||||||
struct Switch;
|
struct Switch;
|
||||||
|
using Statement = boost::variant<Instruction, Literal, Label, StackAssignment, Identifier, Assignment, FunctionCall, FunctionalInstruction, VariableDeclaration, FunctionDefinition, Switch, Block>;
|
||||||
|
|
||||||
|
|
||||||
struct Scope;
|
struct Scope;
|
||||||
|
|
||||||
@ -83,10 +85,13 @@ public:
|
|||||||
bool operator()(assembly::Block const& _block);
|
bool operator()(assembly::Block const& _block);
|
||||||
|
|
||||||
private:
|
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
|
/// 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.
|
/// as the value, @a _valueSize, unless that is equal to -1.
|
||||||
bool checkAssignment(assembly::Identifier const& _assignment, size_t _valueSize = size_t(-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);
|
Scope& scope(assembly::Block const* _block);
|
||||||
void expectValidType(std::string const& type, SourceLocation const& _location);
|
void expectValidType(std::string const& type, SourceLocation const& _location);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user