mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Extend abstract assembly to be able to handle sub-objects.
This commit is contained in:
parent
4721cf332f
commit
f6ed29b88b
@ -27,10 +27,13 @@
|
|||||||
#include <libyul/backends/evm/EVMCodeTransform.h>
|
#include <libyul/backends/evm/EVMCodeTransform.h>
|
||||||
|
|
||||||
#include <libevmasm/Assembly.h>
|
#include <libevmasm/Assembly.h>
|
||||||
|
#include <libevmasm/AssemblyItem.h>
|
||||||
#include <libevmasm/Instruction.h>
|
#include <libevmasm/Instruction.h>
|
||||||
|
|
||||||
#include <liblangutil/SourceLocation.h>
|
#include <liblangutil/SourceLocation.h>
|
||||||
|
|
||||||
|
#include <libdevcore/FixedHash.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
@ -131,6 +134,39 @@ void EthAssemblyAdapter::appendAssemblySize()
|
|||||||
m_assembly.appendProgramSize();
|
m_assembly.appendProgramSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly()
|
||||||
|
{
|
||||||
|
shared_ptr<eth::Assembly> assembly{make_shared<eth::Assembly>()};
|
||||||
|
auto sub = m_assembly.newSub(assembly);
|
||||||
|
return {make_shared<EthAssemblyAdapter>(*assembly), size_t(sub.data())};
|
||||||
|
}
|
||||||
|
|
||||||
|
void EthAssemblyAdapter::appendDataOffset(AbstractAssembly::SubID _sub)
|
||||||
|
{
|
||||||
|
auto it = m_dataHashBySubId.find(_sub);
|
||||||
|
if (it == m_dataHashBySubId.end())
|
||||||
|
m_assembly.pushSubroutineOffset(size_t(_sub));
|
||||||
|
else
|
||||||
|
m_assembly << eth::AssemblyItem(eth::PushData, it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EthAssemblyAdapter::appendDataSize(AbstractAssembly::SubID _sub)
|
||||||
|
{
|
||||||
|
auto it = m_dataHashBySubId.find(_sub);
|
||||||
|
if (it == m_dataHashBySubId.end())
|
||||||
|
m_assembly.pushSubroutineSize(size_t(_sub));
|
||||||
|
else
|
||||||
|
m_assembly << u256(m_assembly.data(h256(it->second)).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractAssembly::SubID EthAssemblyAdapter::appendData(bytes const& _data)
|
||||||
|
{
|
||||||
|
eth::AssemblyItem pushData = m_assembly.newData(_data);
|
||||||
|
SubID subID = m_nextDataCounter++;
|
||||||
|
m_dataHashBySubId[subID] = pushData.data();
|
||||||
|
return subID;
|
||||||
|
}
|
||||||
|
|
||||||
EthAssemblyAdapter::LabelID EthAssemblyAdapter::assemblyTagToIdentifier(eth::AssemblyItem const& _tag)
|
EthAssemblyAdapter::LabelID EthAssemblyAdapter::assemblyTagToIdentifier(eth::AssemblyItem const& _tag)
|
||||||
{
|
{
|
||||||
u256 id = _tag.data();
|
u256 id = _tag.data();
|
||||||
|
@ -63,11 +63,17 @@ public:
|
|||||||
void appendJumpsub(LabelID, int, int) override;
|
void appendJumpsub(LabelID, int, int) override;
|
||||||
void appendReturnsub(int, int) override;
|
void appendReturnsub(int, int) override;
|
||||||
void appendAssemblySize() override;
|
void appendAssemblySize() override;
|
||||||
|
std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly() override;
|
||||||
|
void appendDataOffset(SubID _sub) override;
|
||||||
|
void appendDataSize(SubID _sub) override;
|
||||||
|
SubID appendData(dev::bytes const& _data) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static LabelID assemblyTagToIdentifier(eth::AssemblyItem const& _tag);
|
static LabelID assemblyTagToIdentifier(eth::AssemblyItem const& _tag);
|
||||||
|
|
||||||
eth::Assembly& m_assembly;
|
eth::Assembly& m_assembly;
|
||||||
|
std::map<SubID, dev::u256> m_dataHashBySubId;
|
||||||
|
size_t m_nextDataCounter = std::numeric_limits<size_t>::max() / 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CodeGenerator
|
class CodeGenerator
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <libdevcore/CommonData.h>
|
#include <libdevcore/CommonData.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace langutil
|
namespace langutil
|
||||||
{
|
{
|
||||||
@ -52,6 +53,7 @@ class AbstractAssembly
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using LabelID = size_t;
|
using LabelID = size_t;
|
||||||
|
using SubID = size_t;
|
||||||
|
|
||||||
virtual ~AbstractAssembly() {}
|
virtual ~AbstractAssembly() {}
|
||||||
|
|
||||||
@ -98,6 +100,14 @@ public:
|
|||||||
|
|
||||||
/// Append the assembled size as a constant.
|
/// Append the assembled size as a constant.
|
||||||
virtual void appendAssemblySize() = 0;
|
virtual void appendAssemblySize() = 0;
|
||||||
|
/// Creates a new sub-assembly, which can be referenced using dataSize and dataOffset.
|
||||||
|
virtual std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly() = 0;
|
||||||
|
/// Appends the offset of the given sub-assembly or data.
|
||||||
|
virtual void appendDataOffset(SubID _sub) = 0;
|
||||||
|
/// Appends the size of the given sub-assembly or data.
|
||||||
|
virtual void appendDataSize(SubID _sub) = 0;
|
||||||
|
/// Appends the given data to the assembly and returns its ID.
|
||||||
|
virtual SubID appendData(dev::bytes const& _data) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class IdentifierContext { LValue, RValue };
|
enum class IdentifierContext { LValue, RValue };
|
||||||
|
@ -194,6 +194,27 @@ void EVMAssembly::appendAssemblySize()
|
|||||||
m_bytecode += bytes(assemblySizeReferenceSize);
|
m_bytecode += bytes(assemblySizeReferenceSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EVMAssembly::createSubAssembly()
|
||||||
|
{
|
||||||
|
solAssert(false, "Sub assemblies not implemented.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void EVMAssembly::appendDataOffset(AbstractAssembly::SubID)
|
||||||
|
{
|
||||||
|
solAssert(false, "Data not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EVMAssembly::appendDataSize(AbstractAssembly::SubID)
|
||||||
|
{
|
||||||
|
solAssert(false, "Data not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractAssembly::SubID EVMAssembly::appendData(bytes const&)
|
||||||
|
{
|
||||||
|
solAssert(false, "Data not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
void EVMAssembly::updateReference(size_t pos, size_t size, u256 value)
|
void EVMAssembly::updateReference(size_t pos, size_t size, u256 value)
|
||||||
{
|
{
|
||||||
solAssert(m_bytecode.size() >= size && pos <= m_bytecode.size() - size, "");
|
solAssert(m_bytecode.size() >= size && pos <= m_bytecode.size() - size, "");
|
||||||
|
@ -77,6 +77,10 @@ public:
|
|||||||
|
|
||||||
/// Append the assembled size as a constant.
|
/// Append the assembled size as a constant.
|
||||||
void appendAssemblySize() override;
|
void appendAssemblySize() override;
|
||||||
|
std::pair<std::shared_ptr<AbstractAssembly>, SubID> createSubAssembly() override;
|
||||||
|
void appendDataOffset(SubID _sub) override;
|
||||||
|
void appendDataSize(SubID _sub) override;
|
||||||
|
SubID appendData(dev::bytes const& _data) override;
|
||||||
|
|
||||||
/// Resolves references inside the bytecode and returns the linker object.
|
/// Resolves references inside the bytecode and returns the linker object.
|
||||||
dev::eth::LinkerObject finalize();
|
dev::eth::LinkerObject finalize();
|
||||||
|
Loading…
Reference in New Issue
Block a user