/* 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 . */ // SPDX-License-Identifier: GPL-3.0 /** * Assembly interface for EVM and EVM1.5. */ #pragma once #include #include #include namespace solidity::langutil { struct SourceLocation; } namespace solidity::yul { class EVMAssembly: public AbstractAssembly { public: explicit EVMAssembly() { } ~EVMAssembly() override = default; /// Set a new source location valid starting from the next instruction. void setSourceLocation(langutil::SourceLocation const& _location) override; /// Retrieve the current height of the stack. This does not have to be zero /// at the beginning. int stackHeight() const override { return m_stackHeight; } void setStackHeight(int height) override { m_stackHeight = height; } /// Append an EVM instruction. void appendInstruction(evmasm::Instruction _instruction) override; /// Append a constant. void appendConstant(u256 const& _constant) override; /// Append a label. void appendLabel(LabelID _labelId) override; /// Append a label reference. void appendLabelReference(LabelID _labelId) override; /// Generate a new unique label. LabelID newLabelId() override; /// Returns a label identified by the given name. Creates it if it does not yet exist. LabelID namedLabel(std::string const& _name) override; /// Append a reference to a to-be-linked symbol. /// Currently, we assume that the value is always a 20 byte number. void appendLinkerSymbol(std::string const& _name) override; /// Append a jump instruction. /// @param _stackDiffAfter the stack adjustment after this instruction. void appendJump(int _stackDiffAfter, JumpType _jumpType) override; /// Append a jump-to-immediate operation. void appendJumpTo(LabelID _labelId, int _stackDiffAfter, JumpType _jumpType) override; /// Append a jump-to-if-immediate operation. void appendJumpToIf(LabelID _labelId, JumpType _jumpType) override; /// Append the assembled size as a constant. void appendAssemblySize() override; std::pair, SubID> createSubAssembly(std::string _name = "") override; void appendDataOffset(std::vector const& _subPath) override; void appendDataSize(std::vector const& _subPath) override; SubID appendData(bytes const& _data) override; void appendImmutable(std::string const& _identifier) override; void appendImmutableAssignment(std::string const& _identifier) override; void markAsInvalid() override { m_invalid = true; } /// Resolves references inside the bytecode and returns the linker object. evmasm::LinkerObject finalize(); private: void setLabelToCurrentPosition(AbstractAssembly::LabelID _labelId); void appendLabelReferenceInternal(AbstractAssembly::LabelID _labelId); void updateReference(size_t pos, size_t size, u256 value); LabelID m_nextLabelId = 0; int m_stackHeight = 0; bytes m_bytecode; std::map m_namedLabels; std::map m_labelPositions; std::map m_labelReferences; std::vector m_assemblySizePositions; bool m_invalid = false; }; }