From 0ec7a0e72cbc2ab2f05005a19ff29651a47c1b45 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 4 Dec 2018 15:10:47 +0100 Subject: Move AsmCodeGen. --- libsolidity/codegen/AsmCodeGen.cpp | 163 +++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 libsolidity/codegen/AsmCodeGen.cpp (limited to 'libsolidity/codegen/AsmCodeGen.cpp') diff --git a/libsolidity/codegen/AsmCodeGen.cpp b/libsolidity/codegen/AsmCodeGen.cpp new file mode 100644 index 00000000..23bf395d --- /dev/null +++ b/libsolidity/codegen/AsmCodeGen.cpp @@ -0,0 +1,163 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +/** + * @author Christian + * @date 2016 + * Code-generating part of inline assembly. + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include + +#include +#include +#include + +#include +#include + +using namespace std; +using namespace dev; +using namespace langutil; +using namespace yul; +using namespace dev::solidity; + +class EthAssemblyAdapter: public AbstractAssembly +{ +public: + explicit EthAssemblyAdapter(eth::Assembly& _assembly): + m_assembly(_assembly) + { + } + virtual void setSourceLocation(SourceLocation const& _location) override + { + m_assembly.setSourceLocation(_location); + } + virtual int stackHeight() const override { return m_assembly.deposit(); } + virtual void appendInstruction(solidity::Instruction _instruction) override + { + m_assembly.append(_instruction); + } + virtual void appendConstant(u256 const& _constant) override + { + m_assembly.append(_constant); + } + /// Append a label. + virtual void appendLabel(LabelID _labelId) override + { + m_assembly.append(eth::AssemblyItem(eth::Tag, _labelId)); + } + /// Append a label reference. + virtual void appendLabelReference(LabelID _labelId) override + { + m_assembly.append(eth::AssemblyItem(eth::PushTag, _labelId)); + } + virtual size_t newLabelId() override + { + return assemblyTagToIdentifier(m_assembly.newTag()); + } + virtual size_t namedLabel(std::string const& _name) override + { + return assemblyTagToIdentifier(m_assembly.namedTag(_name)); + } + virtual void appendLinkerSymbol(std::string const& _linkerSymbol) override + { + m_assembly.appendLibraryAddress(_linkerSymbol); + } + virtual void appendJump(int _stackDiffAfter) override + { + appendInstruction(solidity::Instruction::JUMP); + m_assembly.adjustDeposit(_stackDiffAfter); + } + virtual void appendJumpTo(LabelID _labelId, int _stackDiffAfter) override + { + appendLabelReference(_labelId); + appendJump(_stackDiffAfter); + } + virtual void appendJumpToIf(LabelID _labelId) override + { + appendLabelReference(_labelId); + appendInstruction(solidity::Instruction::JUMPI); + } + virtual void appendBeginsub(LabelID, int) override + { + // TODO we could emulate that, though + solAssert(false, "BEGINSUB not implemented for EVM 1.0"); + } + /// Call a subroutine. + virtual void appendJumpsub(LabelID, int, int) override + { + // TODO we could emulate that, though + solAssert(false, "JUMPSUB not implemented for EVM 1.0"); + } + + /// Return from a subroutine. + virtual void appendReturnsub(int, int) override + { + // TODO we could emulate that, though + solAssert(false, "RETURNSUB not implemented for EVM 1.0"); + } + + virtual void appendAssemblySize() override + { + m_assembly.appendProgramSize(); + } + +private: + static LabelID assemblyTagToIdentifier(eth::AssemblyItem const& _tag) + { + u256 id = _tag.data(); + solAssert(id <= std::numeric_limits::max(), "Tag id too large."); + return LabelID(id); + } + + eth::Assembly& m_assembly; +}; + +void CodeGenerator::assemble( + Block const& _parsedData, + AsmAnalysisInfo& _analysisInfo, + eth::Assembly& _assembly, + ExternalIdentifierAccess const& _identifierAccess, + bool _useNamedLabelsForFunctions +) +{ + EthAssemblyAdapter assemblyAdapter(_assembly); + CodeTransform( + assemblyAdapter, + _analysisInfo, + false, + false, + _identifierAccess, + _useNamedLabelsForFunctions + )(_parsedData); +} -- cgit v1.2.3 From 3ebb78a886b606cad345534758b4dcc4ab2863d0 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 4 Dec 2018 15:20:29 +0100 Subject: Adjust include paths. --- libsolidity/codegen/AsmCodeGen.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'libsolidity/codegen/AsmCodeGen.cpp') diff --git a/libsolidity/codegen/AsmCodeGen.cpp b/libsolidity/codegen/AsmCodeGen.cpp index 23bf395d..eb3d6d12 100644 --- a/libsolidity/codegen/AsmCodeGen.cpp +++ b/libsolidity/codegen/AsmCodeGen.cpp @@ -15,12 +15,10 @@ along with solidity. If not, see . */ /** - * @author Christian - * @date 2016 - * Code-generating part of inline assembly. + * Adaptor between the abstract assembly and eth assembly. */ -#include +#include #include #include -- cgit v1.2.3 From 0b1125281aa36d84977c279314ef459ca3d533ca Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 4 Dec 2018 15:31:00 +0100 Subject: Remove some includes. --- libsolidity/codegen/AsmCodeGen.cpp | 9 --------- 1 file changed, 9 deletions(-) (limited to 'libsolidity/codegen/AsmCodeGen.cpp') diff --git a/libsolidity/codegen/AsmCodeGen.cpp b/libsolidity/codegen/AsmCodeGen.cpp index eb3d6d12..83dd08fb 100644 --- a/libsolidity/codegen/AsmCodeGen.cpp +++ b/libsolidity/codegen/AsmCodeGen.cpp @@ -20,10 +20,7 @@ #include -#include #include -#include -#include #include #include @@ -34,12 +31,6 @@ #include -#include - -#include -#include -#include - #include #include -- cgit v1.2.3 From 4721cf332f0ca8af5fa16244c651cd6a635b3cdc Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 4 Dec 2018 16:26:38 +0100 Subject: Expose EthAssemblyAdapter. --- libsolidity/codegen/AsmCodeGen.cpp | 188 +++++++++++++++++++------------------ 1 file changed, 97 insertions(+), 91 deletions(-) (limited to 'libsolidity/codegen/AsmCodeGen.cpp') diff --git a/libsolidity/codegen/AsmCodeGen.cpp b/libsolidity/codegen/AsmCodeGen.cpp index 83dd08fb..4ca0c4e2 100644 --- a/libsolidity/codegen/AsmCodeGen.cpp +++ b/libsolidity/codegen/AsmCodeGen.cpp @@ -40,97 +40,103 @@ using namespace langutil; using namespace yul; using namespace dev::solidity; -class EthAssemblyAdapter: public AbstractAssembly -{ -public: - explicit EthAssemblyAdapter(eth::Assembly& _assembly): - m_assembly(_assembly) - { - } - virtual void setSourceLocation(SourceLocation const& _location) override - { - m_assembly.setSourceLocation(_location); - } - virtual int stackHeight() const override { return m_assembly.deposit(); } - virtual void appendInstruction(solidity::Instruction _instruction) override - { - m_assembly.append(_instruction); - } - virtual void appendConstant(u256 const& _constant) override - { - m_assembly.append(_constant); - } - /// Append a label. - virtual void appendLabel(LabelID _labelId) override - { - m_assembly.append(eth::AssemblyItem(eth::Tag, _labelId)); - } - /// Append a label reference. - virtual void appendLabelReference(LabelID _labelId) override - { - m_assembly.append(eth::AssemblyItem(eth::PushTag, _labelId)); - } - virtual size_t newLabelId() override - { - return assemblyTagToIdentifier(m_assembly.newTag()); - } - virtual size_t namedLabel(std::string const& _name) override - { - return assemblyTagToIdentifier(m_assembly.namedTag(_name)); - } - virtual void appendLinkerSymbol(std::string const& _linkerSymbol) override - { - m_assembly.appendLibraryAddress(_linkerSymbol); - } - virtual void appendJump(int _stackDiffAfter) override - { - appendInstruction(solidity::Instruction::JUMP); - m_assembly.adjustDeposit(_stackDiffAfter); - } - virtual void appendJumpTo(LabelID _labelId, int _stackDiffAfter) override - { - appendLabelReference(_labelId); - appendJump(_stackDiffAfter); - } - virtual void appendJumpToIf(LabelID _labelId) override - { - appendLabelReference(_labelId); - appendInstruction(solidity::Instruction::JUMPI); - } - virtual void appendBeginsub(LabelID, int) override - { - // TODO we could emulate that, though - solAssert(false, "BEGINSUB not implemented for EVM 1.0"); - } - /// Call a subroutine. - virtual void appendJumpsub(LabelID, int, int) override - { - // TODO we could emulate that, though - solAssert(false, "JUMPSUB not implemented for EVM 1.0"); - } - - /// Return from a subroutine. - virtual void appendReturnsub(int, int) override - { - // TODO we could emulate that, though - solAssert(false, "RETURNSUB not implemented for EVM 1.0"); - } - - virtual void appendAssemblySize() override - { - m_assembly.appendProgramSize(); - } - -private: - static LabelID assemblyTagToIdentifier(eth::AssemblyItem const& _tag) - { - u256 id = _tag.data(); - solAssert(id <= std::numeric_limits::max(), "Tag id too large."); - return LabelID(id); - } - - eth::Assembly& m_assembly; -}; +EthAssemblyAdapter::EthAssemblyAdapter(eth::Assembly& _assembly): + m_assembly(_assembly) +{ +} + +void EthAssemblyAdapter::setSourceLocation(SourceLocation const& _location) +{ + m_assembly.setSourceLocation(_location); +} + +int EthAssemblyAdapter::stackHeight() const +{ + return m_assembly.deposit(); +} + +void EthAssemblyAdapter::appendInstruction(solidity::Instruction _instruction) +{ + m_assembly.append(_instruction); +} + +void EthAssemblyAdapter::appendConstant(u256 const& _constant) +{ + m_assembly.append(_constant); +} + +void EthAssemblyAdapter::appendLabel(LabelID _labelId) +{ + m_assembly.append(eth::AssemblyItem(eth::Tag, _labelId)); +} + +void EthAssemblyAdapter::appendLabelReference(LabelID _labelId) +{ + m_assembly.append(eth::AssemblyItem(eth::PushTag, _labelId)); +} + +size_t EthAssemblyAdapter::newLabelId() +{ + return assemblyTagToIdentifier(m_assembly.newTag()); +} + +size_t EthAssemblyAdapter::namedLabel(std::string const& _name) +{ + return assemblyTagToIdentifier(m_assembly.namedTag(_name)); +} + +void EthAssemblyAdapter::appendLinkerSymbol(std::string const& _linkerSymbol) +{ + m_assembly.appendLibraryAddress(_linkerSymbol); +} + +void EthAssemblyAdapter::appendJump(int _stackDiffAfter) +{ + appendInstruction(solidity::Instruction::JUMP); + m_assembly.adjustDeposit(_stackDiffAfter); +} + +void EthAssemblyAdapter::appendJumpTo(LabelID _labelId, int _stackDiffAfter) +{ + appendLabelReference(_labelId); + appendJump(_stackDiffAfter); +} + +void EthAssemblyAdapter::appendJumpToIf(LabelID _labelId) +{ + appendLabelReference(_labelId); + appendInstruction(solidity::Instruction::JUMPI); +} + +void EthAssemblyAdapter::appendBeginsub(LabelID, int) +{ + // TODO we could emulate that, though + solAssert(false, "BEGINSUB not implemented for EVM 1.0"); +} + +void EthAssemblyAdapter::appendJumpsub(LabelID, int, int) +{ + // TODO we could emulate that, though + solAssert(false, "JUMPSUB not implemented for EVM 1.0"); +} + +void EthAssemblyAdapter::appendReturnsub(int, int) +{ + // TODO we could emulate that, though + solAssert(false, "RETURNSUB not implemented for EVM 1.0"); +} + +void EthAssemblyAdapter::appendAssemblySize() +{ + m_assembly.appendProgramSize(); +} + +EthAssemblyAdapter::LabelID EthAssemblyAdapter::assemblyTagToIdentifier(eth::AssemblyItem const& _tag) +{ + u256 id = _tag.data(); + solAssert(id <= std::numeric_limits::max(), "Tag id too large."); + return LabelID(id); +} void CodeGenerator::assemble( Block const& _parsedData, -- cgit v1.2.3 From f6ed29b88b0a721984173df04f04ad4c48d8711d Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 4 Dec 2018 18:57:07 +0100 Subject: Extend abstract assembly to be able to handle sub-objects. --- libsolidity/codegen/AsmCodeGen.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'libsolidity/codegen/AsmCodeGen.cpp') 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 #include +#include #include #include +#include + #include #include @@ -131,6 +134,39 @@ void EthAssemblyAdapter::appendAssemblySize() m_assembly.appendProgramSize(); } +pair, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly() +{ + shared_ptr assembly{make_shared()}; + auto sub = m_assembly.newSub(assembly); + return {make_shared(*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(); -- cgit v1.2.3 From 362648a45042d74da4e631520c0be581902c871b Mon Sep 17 00:00:00 2001 From: liangdzou Date: Tue, 25 Sep 2018 10:47:25 +0800 Subject: Reuse stack slots in Yul to EVM code generation. --- libsolidity/codegen/AsmCodeGen.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'libsolidity/codegen/AsmCodeGen.cpp') diff --git a/libsolidity/codegen/AsmCodeGen.cpp b/libsolidity/codegen/AsmCodeGen.cpp index dfcc900b..3f770f62 100644 --- a/libsolidity/codegen/AsmCodeGen.cpp +++ b/libsolidity/codegen/AsmCodeGen.cpp @@ -179,13 +179,16 @@ void CodeGenerator::assemble( AsmAnalysisInfo& _analysisInfo, eth::Assembly& _assembly, ExternalIdentifierAccess const& _identifierAccess, - bool _useNamedLabelsForFunctions + bool _useNamedLabelsForFunctions, + bool _optimize ) { EthAssemblyAdapter assemblyAdapter(_assembly); CodeTransform( assemblyAdapter, _analysisInfo, + _parsedData, + _optimize, false, false, _identifierAccess, -- cgit v1.2.3 From 8d49e539951791a25a63f470e8a9935679c7404f Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 6 Dec 2018 18:07:08 +0100 Subject: Provide Dialect to EVMCodeTransform. --- libsolidity/codegen/AsmCodeGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libsolidity/codegen/AsmCodeGen.cpp') diff --git a/libsolidity/codegen/AsmCodeGen.cpp b/libsolidity/codegen/AsmCodeGen.cpp index 3f770f62..45efe55b 100644 --- a/libsolidity/codegen/AsmCodeGen.cpp +++ b/libsolidity/codegen/AsmCodeGen.cpp @@ -189,7 +189,7 @@ void CodeGenerator::assemble( _analysisInfo, _parsedData, _optimize, - false, + Dialect::strictAssemblyForEVM(), false, _identifierAccess, _useNamedLabelsForFunctions -- cgit v1.2.3 From fb3a0ac1c7d2c4624df6ae62d290a2de7768d036 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 7 Dec 2018 00:56:16 +0100 Subject: Codegen for object access. --- libsolidity/codegen/AsmCodeGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libsolidity/codegen/AsmCodeGen.cpp') diff --git a/libsolidity/codegen/AsmCodeGen.cpp b/libsolidity/codegen/AsmCodeGen.cpp index 45efe55b..c04c1c34 100644 --- a/libsolidity/codegen/AsmCodeGen.cpp +++ b/libsolidity/codegen/AsmCodeGen.cpp @@ -188,8 +188,8 @@ void CodeGenerator::assemble( assemblyAdapter, _analysisInfo, _parsedData, + *EVMDialect::strictAssemblyForEVM(), _optimize, - Dialect::strictAssemblyForEVM(), false, _identifierAccess, _useNamedLabelsForFunctions -- cgit v1.2.3