[Yul] Directly jump over a series of function definitions

Implement a AbstractAssembly::setStackHeight function
Update the tests
Update Changelog
This commit is contained in:
Vedant Agarwala
2019-06-19 12:40:11 +08:00
committed by Vedant Agarwala
parent b66950711e
commit 5d6cbd97df
9 changed files with 69 additions and 15 deletions
+1
View File
@@ -62,6 +62,7 @@ public:
/// Retrieve the current height of the stack. This does not have to be zero
/// at the beginning.
virtual int stackHeight() const = 0;
virtual void setStackHeight(int height) = 0;
/// Append an EVM instruction.
virtual void appendInstruction(dev::eth::Instruction _instruction) = 0;
/// Append a constant.
+5
View File
@@ -57,6 +57,11 @@ int EthAssemblyAdapter::stackHeight() const
return m_assembly.deposit();
}
void EthAssemblyAdapter::setStackHeight(int height)
{
m_assembly.setDeposit(height);
}
void EthAssemblyAdapter::appendInstruction(dev::eth::Instruction _instruction)
{
m_assembly.append(_instruction);
+1
View File
@@ -44,6 +44,7 @@ public:
explicit EthAssemblyAdapter(dev::eth::Assembly& _assembly);
void setSourceLocation(langutil::SourceLocation const& _location) override;
int stackHeight() const override;
void setStackHeight(int height) override;
void appendInstruction(dev::eth::Instruction _instruction) override;
void appendConstant(dev::u256 const& _constant) override;
void appendLabel(LabelID _labelId) override;
+1
View File
@@ -45,6 +45,7 @@ public:
/// Retrieve the current height of the stack. This does not have to be zero
/// at the beginning.
int stackHeight() const override { return m_stackHeight; }
void setStackHeight(int height) override { m_stackHeight = height; }
/// Append an EVM instruction.
void appendInstruction(dev::eth::Instruction _instruction) override;
/// Append a constant.
+26 -9
View File
@@ -490,19 +490,15 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
}
m_assembly.setSourceLocation(_function.location);
int stackHeightBefore = m_assembly.stackHeight();
AbstractAssembly::LabelID afterFunction = m_assembly.newLabelId();
int const stackHeightBefore = m_assembly.stackHeight();
if (m_evm15)
{
m_assembly.appendJumpTo(afterFunction, -stackHeightBefore);
m_assembly.appendBeginsub(functionEntryID(_function.name, function), _function.parameters.size());
}
else
{
m_assembly.appendJumpTo(afterFunction, -stackHeightBefore + height);
m_assembly.appendLabel(functionEntryID(_function.name, function));
}
m_assembly.setStackHeight(height);
m_stackAdjustment += localStackAdjustment;
for (auto const& v: _function.returnVariables)
@@ -592,8 +588,8 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
else
m_assembly.appendJump(stackHeightBefore - _function.returnVariables.size());
m_stackAdjustment -= localStackAdjustment;
m_assembly.appendLabel(afterFunction);
checkStackHeight(&_function);
m_assembly.setStackHeight(stackHeightBefore);
}
void CodeTransform::operator()(ForLoop const& _forLoop)
@@ -727,11 +723,32 @@ void CodeTransform::visitExpression(Expression const& _expression)
void CodeTransform::visitStatements(vector<Statement> const& _statements)
{
// Workaround boost bug:
// https://www.boost.org/doc/libs/1_63_0/libs/optional/doc/html/boost_optional/tutorial/gotchas/false_positive_with__wmaybe_uninitialized.html
boost::optional<AbstractAssembly::LabelID> jumpTarget = boost::make_optional(false, AbstractAssembly::LabelID());
for (auto const& statement: _statements)
{
freeUnusedVariables();
auto const* functionDefinition = boost::get<FunctionDefinition>(&statement);
if (functionDefinition && !jumpTarget)
{
m_assembly.setSourceLocation(locationOf(statement));
jumpTarget = m_assembly.newLabelId();
m_assembly.appendJumpTo(*jumpTarget, 0);
}
else if (!functionDefinition && jumpTarget)
{
m_assembly.appendLabel(*jumpTarget);
jumpTarget = boost::none;
}
boost::apply_visitor(*this, statement);
}
// we may have a leftover jumpTarget
if (jumpTarget)
m_assembly.appendLabel(*jumpTarget);
freeUnusedVariables();
}
+1
View File
@@ -49,6 +49,7 @@ public:
void setSourceLocation(langutil::SourceLocation const&) override {}
int stackHeight() const override { return m_stackHeight; }
void setStackHeight(int height) override { m_stackHeight = height; }
void appendInstruction(dev::eth::Instruction _instruction) override;
void appendConstant(dev::u256 const& _constant) override;
void appendLabel(LabelID _labelId) override;