aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsolidity/codegen/AsmCodeGen.cpp36
-rw-r--r--libsolidity/codegen/AsmCodeGen.h6
-rw-r--r--libyul/backends/evm/AbstractAssembly.h10
-rw-r--r--libyul/backends/evm/EVMAssembly.cpp21
-rw-r--r--libyul/backends/evm/EVMAssembly.h4
5 files changed, 77 insertions, 0 deletions
diff --git a/libsolidity/codegen/AsmCodeGen.cpp b/libsolidity/codegen/AsmCodeGen.cpp
index 4ca0c4e2..dfcc900b 100644
--- a/libsolidity/codegen/AsmCodeGen.cpp
+++ b/libsolidity/codegen/AsmCodeGen.cpp
@@ -27,10 +27,13 @@
#include <libyul/backends/evm/EVMCodeTransform.h>
#include <libevmasm/Assembly.h>
+#include <libevmasm/AssemblyItem.h>
#include <libevmasm/Instruction.h>
#include <liblangutil/SourceLocation.h>
+#include <libdevcore/FixedHash.h>
+
#include <memory>
#include <functional>
@@ -131,6 +134,39 @@ void EthAssemblyAdapter::appendAssemblySize()
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)
{
u256 id = _tag.data();
diff --git a/libsolidity/codegen/AsmCodeGen.h b/libsolidity/codegen/AsmCodeGen.h
index b5bd33d5..4c6d97f4 100644
--- a/libsolidity/codegen/AsmCodeGen.h
+++ b/libsolidity/codegen/AsmCodeGen.h
@@ -63,11 +63,17 @@ public:
void appendJumpsub(LabelID, int, int) override;
void appendReturnsub(int, int) 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:
static LabelID assemblyTagToIdentifier(eth::AssemblyItem const& _tag);
eth::Assembly& m_assembly;
+ std::map<SubID, dev::u256> m_dataHashBySubId;
+ size_t m_nextDataCounter = std::numeric_limits<size_t>::max() / 2;
};
class CodeGenerator
diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h
index 97b1d305..1f224ded 100644
--- a/libyul/backends/evm/AbstractAssembly.h
+++ b/libyul/backends/evm/AbstractAssembly.h
@@ -26,6 +26,7 @@
#include <libdevcore/CommonData.h>
#include <functional>
+#include <memory>
namespace langutil
{
@@ -52,6 +53,7 @@ class AbstractAssembly
{
public:
using LabelID = size_t;
+ using SubID = size_t;
virtual ~AbstractAssembly() {}
@@ -98,6 +100,14 @@ public:
/// Append the assembled size as a constant.
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 };
diff --git a/libyul/backends/evm/EVMAssembly.cpp b/libyul/backends/evm/EVMAssembly.cpp
index 99506317..2cf9f001 100644
--- a/libyul/backends/evm/EVMAssembly.cpp
+++ b/libyul/backends/evm/EVMAssembly.cpp
@@ -194,6 +194,27 @@ void EVMAssembly::appendAssemblySize()
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)
{
solAssert(m_bytecode.size() >= size && pos <= m_bytecode.size() - size, "");
diff --git a/libyul/backends/evm/EVMAssembly.h b/libyul/backends/evm/EVMAssembly.h
index d0a437cc..cef9c19a 100644
--- a/libyul/backends/evm/EVMAssembly.h
+++ b/libyul/backends/evm/EVMAssembly.h
@@ -77,6 +77,10 @@ public:
/// Append the assembled size as a constant.
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.
dev::eth::LinkerObject finalize();