diff options
| author | chriseth <chris@ethereum.org> | 2018-11-24 00:01:18 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-11-24 00:01:18 +0800 |
| commit | 9a94e503da84cc66f643b3972bf8ad4defa02060 (patch) | |
| tree | 8efb3b6d25ba2574689731bcbea2eac901523d24 /libyul/AsmCodeGen.cpp | |
| parent | 4fb15c9327c2c4bfae29f0ff23c1ab0b1218f735 (diff) | |
| parent | 8dd0338d127b50e60d50f978be68605e8f8faee5 (diff) | |
| download | dexon-solidity-9a94e503da84cc66f643b3972bf8ad4defa02060.tar dexon-solidity-9a94e503da84cc66f643b3972bf8ad4defa02060.tar.gz dexon-solidity-9a94e503da84cc66f643b3972bf8ad4defa02060.tar.bz2 dexon-solidity-9a94e503da84cc66f643b3972bf8ad4defa02060.tar.lz dexon-solidity-9a94e503da84cc66f643b3972bf8ad4defa02060.tar.xz dexon-solidity-9a94e503da84cc66f643b3972bf8ad4defa02060.tar.zst dexon-solidity-9a94e503da84cc66f643b3972bf8ad4defa02060.zip | |
Merge pull request #5491 from ethereum/libyul-as-library
Libyul as static library (version 3 ;( )
Diffstat (limited to 'libyul/AsmCodeGen.cpp')
| -rw-r--r-- | libyul/AsmCodeGen.cpp | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/libyul/AsmCodeGen.cpp b/libyul/AsmCodeGen.cpp new file mode 100644 index 00000000..23bf395d --- /dev/null +++ b/libyul/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 <http://www.gnu.org/licenses/>. +*/ +/** + * @author Christian <c@ethdev.com> + * @date 2016 + * Code-generating part of inline assembly. + */ + +#include <libyul/AsmCodeGen.h> + +#include <libyul/AsmParser.h> +#include <libyul/AsmData.h> +#include <libyul/AsmScope.h> +#include <libyul/AsmAnalysis.h> +#include <libyul/AsmAnalysisInfo.h> + +#include <libyul/backends/evm/AbstractAssembly.h> +#include <libyul/backends/evm/EVMCodeTransform.h> + +#include <libevmasm/Assembly.h> +#include <libevmasm/Instruction.h> + +#include <liblangutil/SourceLocation.h> + +#include <libdevcore/CommonIO.h> + +#include <boost/range/adaptor/reversed.hpp> +#include <boost/range/adaptor/map.hpp> +#include <boost/range/algorithm/count_if.hpp> + +#include <memory> +#include <functional> + +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<LabelID>::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); +} |
