mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[Yul] Directly jump over a series of function definitions
Implement a AbstractAssembly::setStackHeight function Update the tests Update Changelog
This commit is contained in:
committed by
Vedant Agarwala
parent
b66950711e
commit
5d6cbd97df
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user