mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Stack height checks and fix.
This commit is contained in:
parent
c62828c8ff
commit
e7528c6af8
40
Compiler.cpp
40
Compiler.cpp
@ -34,6 +34,20 @@ using namespace std;
|
||||
namespace dev {
|
||||
namespace solidity {
|
||||
|
||||
/**
|
||||
* Simple helper class to ensure that the stack height is the same at certain places in the code.
|
||||
*/
|
||||
class StackHeightChecker
|
||||
{
|
||||
public:
|
||||
StackHeightChecker(CompilerContext const& _context):
|
||||
m_context(_context), stackHeight(m_context.getStackHeight()) {}
|
||||
void check() { solAssert(m_context.getStackHeight() == stackHeight, "I sense a disturbance in the stack."); }
|
||||
private:
|
||||
CompilerContext const& m_context;
|
||||
unsigned stackHeight;
|
||||
};
|
||||
|
||||
void Compiler::compileContract(ContractDefinition const& _contract,
|
||||
map<ContractDefinition const*, bytes const*> const& _contracts)
|
||||
{
|
||||
@ -340,6 +354,8 @@ bool Compiler::visit(FunctionDefinition const& _function)
|
||||
|
||||
bool Compiler::visit(IfStatement const& _ifStatement)
|
||||
{
|
||||
StackHeightChecker checker(m_context);
|
||||
|
||||
compileExpression(_ifStatement.getCondition());
|
||||
eth::AssemblyItem trueTag = m_context.appendConditionalJump();
|
||||
if (_ifStatement.getFalseStatement())
|
||||
@ -348,11 +364,15 @@ bool Compiler::visit(IfStatement const& _ifStatement)
|
||||
m_context << trueTag;
|
||||
_ifStatement.getTrueStatement().accept(*this);
|
||||
m_context << endTag;
|
||||
|
||||
checker.check();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(WhileStatement const& _whileStatement)
|
||||
{
|
||||
StackHeightChecker checker(m_context);
|
||||
|
||||
eth::AssemblyItem loopStart = m_context.newTag();
|
||||
eth::AssemblyItem loopEnd = m_context.newTag();
|
||||
m_continueTags.push_back(loopStart);
|
||||
@ -370,11 +390,15 @@ bool Compiler::visit(WhileStatement const& _whileStatement)
|
||||
|
||||
m_continueTags.pop_back();
|
||||
m_breakTags.pop_back();
|
||||
|
||||
checker.check();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(ForStatement const& _forStatement)
|
||||
{
|
||||
StackHeightChecker checker(m_context);
|
||||
|
||||
eth::AssemblyItem loopStart = m_context.newTag();
|
||||
eth::AssemblyItem loopEnd = m_context.newTag();
|
||||
m_continueTags.push_back(loopStart);
|
||||
@ -404,6 +428,8 @@ bool Compiler::visit(ForStatement const& _forStatement)
|
||||
|
||||
m_continueTags.pop_back();
|
||||
m_breakTags.pop_back();
|
||||
|
||||
checker.check();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -438,29 +464,35 @@ bool Compiler::visit(Return const& _return)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(VariableDeclarationStatement const& _variableDefinition)
|
||||
bool Compiler::visit(VariableDeclarationStatement const& _variableDeclarationStatement)
|
||||
{
|
||||
if (Expression const* expression = _variableDefinition.getExpression())
|
||||
StackHeightChecker checker(m_context);
|
||||
if (Expression const* expression = _variableDeclarationStatement.getExpression())
|
||||
{
|
||||
compileExpression(*expression, _variableDefinition.getDeclaration().getType());
|
||||
CompilerUtils(m_context).moveToStackVariable(_variableDefinition.getDeclaration());
|
||||
compileExpression(*expression, _variableDeclarationStatement.getDeclaration().getType());
|
||||
CompilerUtils(m_context).moveToStackVariable(_variableDeclarationStatement.getDeclaration());
|
||||
}
|
||||
checker.check();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(ExpressionStatement const& _expressionStatement)
|
||||
{
|
||||
StackHeightChecker checker(m_context);
|
||||
Expression const& expression = _expressionStatement.getExpression();
|
||||
compileExpression(expression);
|
||||
CompilerUtils(m_context).popStackElement(*expression.getType());
|
||||
checker.check();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(PlaceholderStatement const&)
|
||||
{
|
||||
StackHeightChecker checker(m_context);
|
||||
++m_modifierDepth;
|
||||
appendModifierOrFunctionCode();
|
||||
--m_modifierDepth;
|
||||
checker.check();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ private:
|
||||
virtual bool visit(Continue const& _continue) override;
|
||||
virtual bool visit(Break const& _break) override;
|
||||
virtual bool visit(Return const& _return) override;
|
||||
virtual bool visit(VariableDeclarationStatement const& _variableDefinition) override;
|
||||
virtual bool visit(VariableDeclarationStatement const& _variableDeclarationStatement) override;
|
||||
virtual bool visit(ExpressionStatement const& _expressionStatement) override;
|
||||
virtual bool visit(PlaceholderStatement const&) override;
|
||||
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
bytes const& getCompiledContract(ContractDefinition const& _contract) const;
|
||||
|
||||
void adjustStackOffset(int _adjustment) { m_asm.adjustDeposit(_adjustment); }
|
||||
unsigned getStackHeight() { solAssert(m_asm.deposit() >= 0, ""); return unsigned(m_asm.deposit()); }
|
||||
unsigned getStackHeight() const { solAssert(m_asm.deposit() >= 0, ""); return unsigned(m_asm.deposit()); }
|
||||
|
||||
bool isMagicGlobal(Declaration const* _declaration) const { return m_magicGlobals.count(_declaration) != 0; }
|
||||
bool isLocalVariable(Declaration const* _declaration) const;
|
||||
|
11
Types.cpp
11
Types.cpp
@ -833,10 +833,17 @@ string FunctionType::toString() const
|
||||
|
||||
unsigned FunctionType::getSizeOnStack() const
|
||||
{
|
||||
Location location = m_location;
|
||||
if (m_location == Location::SetGas || m_location == Location::SetValue)
|
||||
{
|
||||
solAssert(m_returnParameterTypes.size() == 1, "");
|
||||
location = dynamic_cast<FunctionType const&>(*m_returnParameterTypes.front()).m_location;
|
||||
}
|
||||
|
||||
unsigned size = 0;
|
||||
if (m_location == Location::External)
|
||||
if (location == Location::External)
|
||||
size = 2;
|
||||
else if (m_location == Location::Internal || m_location == Location::Bare)
|
||||
else if (location == Location::Internal || location == Location::Bare)
|
||||
size = 1;
|
||||
if (m_gasSet)
|
||||
size++;
|
||||
|
Loading…
Reference in New Issue
Block a user