Expose EthAssemblyAdapter.

This commit is contained in:
chriseth 2018-12-04 16:26:38 +01:00
parent 0e8841005c
commit 4721cf332f
2 changed files with 123 additions and 86 deletions

View File

@ -40,98 +40,104 @@ using namespace langutil;
using namespace yul; using namespace yul;
using namespace dev::solidity; using namespace dev::solidity;
class EthAssemblyAdapter: public AbstractAssembly EthAssemblyAdapter::EthAssemblyAdapter(eth::Assembly& _assembly):
{
public:
explicit EthAssemblyAdapter(eth::Assembly& _assembly):
m_assembly(_assembly) m_assembly(_assembly)
{ {
} }
virtual void setSourceLocation(SourceLocation const& _location) override
void EthAssemblyAdapter::setSourceLocation(SourceLocation const& _location)
{ {
m_assembly.setSourceLocation(_location); m_assembly.setSourceLocation(_location);
} }
virtual int stackHeight() const override { return m_assembly.deposit(); }
virtual void appendInstruction(solidity::Instruction _instruction) override int EthAssemblyAdapter::stackHeight() const
{
return m_assembly.deposit();
}
void EthAssemblyAdapter::appendInstruction(solidity::Instruction _instruction)
{ {
m_assembly.append(_instruction); m_assembly.append(_instruction);
} }
virtual void appendConstant(u256 const& _constant) override
void EthAssemblyAdapter::appendConstant(u256 const& _constant)
{ {
m_assembly.append(_constant); m_assembly.append(_constant);
} }
/// Append a label.
virtual void appendLabel(LabelID _labelId) override void EthAssemblyAdapter::appendLabel(LabelID _labelId)
{ {
m_assembly.append(eth::AssemblyItem(eth::Tag, _labelId)); m_assembly.append(eth::AssemblyItem(eth::Tag, _labelId));
} }
/// Append a label reference.
virtual void appendLabelReference(LabelID _labelId) override void EthAssemblyAdapter::appendLabelReference(LabelID _labelId)
{ {
m_assembly.append(eth::AssemblyItem(eth::PushTag, _labelId)); m_assembly.append(eth::AssemblyItem(eth::PushTag, _labelId));
} }
virtual size_t newLabelId() override
size_t EthAssemblyAdapter::newLabelId()
{ {
return assemblyTagToIdentifier(m_assembly.newTag()); return assemblyTagToIdentifier(m_assembly.newTag());
} }
virtual size_t namedLabel(std::string const& _name) override
size_t EthAssemblyAdapter::namedLabel(std::string const& _name)
{ {
return assemblyTagToIdentifier(m_assembly.namedTag(_name)); return assemblyTagToIdentifier(m_assembly.namedTag(_name));
} }
virtual void appendLinkerSymbol(std::string const& _linkerSymbol) override
void EthAssemblyAdapter::appendLinkerSymbol(std::string const& _linkerSymbol)
{ {
m_assembly.appendLibraryAddress(_linkerSymbol); m_assembly.appendLibraryAddress(_linkerSymbol);
} }
virtual void appendJump(int _stackDiffAfter) override
void EthAssemblyAdapter::appendJump(int _stackDiffAfter)
{ {
appendInstruction(solidity::Instruction::JUMP); appendInstruction(solidity::Instruction::JUMP);
m_assembly.adjustDeposit(_stackDiffAfter); m_assembly.adjustDeposit(_stackDiffAfter);
} }
virtual void appendJumpTo(LabelID _labelId, int _stackDiffAfter) override
void EthAssemblyAdapter::appendJumpTo(LabelID _labelId, int _stackDiffAfter)
{ {
appendLabelReference(_labelId); appendLabelReference(_labelId);
appendJump(_stackDiffAfter); appendJump(_stackDiffAfter);
} }
virtual void appendJumpToIf(LabelID _labelId) override
void EthAssemblyAdapter::appendJumpToIf(LabelID _labelId)
{ {
appendLabelReference(_labelId); appendLabelReference(_labelId);
appendInstruction(solidity::Instruction::JUMPI); appendInstruction(solidity::Instruction::JUMPI);
} }
virtual void appendBeginsub(LabelID, int) override
void EthAssemblyAdapter::appendBeginsub(LabelID, int)
{ {
// TODO we could emulate that, though // TODO we could emulate that, though
solAssert(false, "BEGINSUB not implemented for EVM 1.0"); solAssert(false, "BEGINSUB not implemented for EVM 1.0");
} }
/// Call a subroutine.
virtual void appendJumpsub(LabelID, int, int) override void EthAssemblyAdapter::appendJumpsub(LabelID, int, int)
{ {
// TODO we could emulate that, though // TODO we could emulate that, though
solAssert(false, "JUMPSUB not implemented for EVM 1.0"); solAssert(false, "JUMPSUB not implemented for EVM 1.0");
} }
/// Return from a subroutine. void EthAssemblyAdapter::appendReturnsub(int, int)
virtual void appendReturnsub(int, int) override
{ {
// TODO we could emulate that, though // TODO we could emulate that, though
solAssert(false, "RETURNSUB not implemented for EVM 1.0"); solAssert(false, "RETURNSUB not implemented for EVM 1.0");
} }
virtual void appendAssemblySize() override void EthAssemblyAdapter::appendAssemblySize()
{ {
m_assembly.appendProgramSize(); m_assembly.appendProgramSize();
} }
private: EthAssemblyAdapter::LabelID EthAssemblyAdapter::assemblyTagToIdentifier(eth::AssemblyItem const& _tag)
static LabelID assemblyTagToIdentifier(eth::AssemblyItem const& _tag)
{ {
u256 id = _tag.data(); u256 id = _tag.data();
solAssert(id <= std::numeric_limits<LabelID>::max(), "Tag id too large."); solAssert(id <= std::numeric_limits<LabelID>::max(), "Tag id too large.");
return LabelID(id); return LabelID(id);
} }
eth::Assembly& m_assembly;
};
void CodeGenerator::assemble( void CodeGenerator::assemble(
Block const& _parsedData, Block const& _parsedData,
AsmAnalysisInfo& _analysisInfo, AsmAnalysisInfo& _analysisInfo,

View File

@ -21,6 +21,9 @@
#pragma once #pragma once
#include <libyul/AsmAnalysis.h> #include <libyul/AsmAnalysis.h>
#include <libyul/backends/evm/AbstractAssembly.h>
#include <liblangutil/SourceLocation.h>
#include <functional> #include <functional>
@ -34,11 +37,39 @@ namespace dev
namespace eth namespace eth
{ {
class Assembly; class Assembly;
class AssemblyItem;
} }
namespace solidity namespace solidity
{ {
class EthAssemblyAdapter: public yul::AbstractAssembly
{
public:
explicit EthAssemblyAdapter(eth::Assembly& _assembly);
void setSourceLocation(langutil::SourceLocation const& _location) override;
int stackHeight() const override;
void appendInstruction(solidity::Instruction _instruction) override;
void appendConstant(u256 const& _constant) override;
void appendLabel(LabelID _labelId) override;
void appendLabelReference(LabelID _labelId) override;
size_t newLabelId() override;
size_t namedLabel(std::string const& _name) override;
void appendLinkerSymbol(std::string const& _linkerSymbol) override;
void appendJump(int _stackDiffAfter) override;
void appendJumpTo(LabelID _labelId, int _stackDiffAfter) override;
void appendJumpToIf(LabelID _labelId) override;
void appendBeginsub(LabelID, int) override;
void appendJumpsub(LabelID, int, int) override;
void appendReturnsub(int, int) override;
void appendAssemblySize() override;
private:
static LabelID assemblyTagToIdentifier(eth::AssemblyItem const& _tag);
eth::Assembly& m_assembly;
};
class CodeGenerator class CodeGenerator
{ {
public: public: