mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add verbatim builtin.
This commit is contained in:
@@ -33,7 +33,8 @@
|
||||
namespace solidity::evmasm
|
||||
{
|
||||
|
||||
enum AssemblyItemType {
|
||||
enum AssemblyItemType
|
||||
{
|
||||
UndefinedItem,
|
||||
Operation,
|
||||
Push,
|
||||
@@ -47,7 +48,8 @@ enum AssemblyItemType {
|
||||
PushLibraryAddress, ///< Push a currently unknown address of another (library) contract.
|
||||
PushDeployTimeAddress, ///< Push an address to be filled at deploy time. Should not be touched by the optimizer.
|
||||
PushImmutable, ///< Push the currently unknown value of an immutable variable. The actual value will be filled in by the constructor.
|
||||
AssignImmutable ///< Assigns the current value on the stack to an immutable variable. Only valid during creation code.
|
||||
AssignImmutable, ///< Assigns the current value on the stack to an immutable variable. Only valid during creation code.
|
||||
VerbatimBytecode ///< Contains data that is inserted into the bytecode code section without modification.
|
||||
};
|
||||
|
||||
class Assembly;
|
||||
@@ -75,6 +77,12 @@ public:
|
||||
else
|
||||
m_data = std::make_shared<u256>(std::move(_data));
|
||||
}
|
||||
explicit AssemblyItem(bytes const& _verbatimData, int _deposit):
|
||||
m_type(VerbatimBytecode),
|
||||
m_instruction{},
|
||||
m_verbatimBytecode{{_deposit, _verbatimData}}
|
||||
{}
|
||||
|
||||
AssemblyItem(AssemblyItem const&) = default;
|
||||
AssemblyItem(AssemblyItem&&) = default;
|
||||
AssemblyItem& operator=(AssemblyItem const&) = default;
|
||||
@@ -95,6 +103,8 @@ public:
|
||||
u256 const& data() const { assertThrow(m_type != Operation, util::Exception, ""); return *m_data; }
|
||||
void setData(u256 const& _data) { assertThrow(m_type != Operation, util::Exception, ""); m_data = std::make_shared<u256>(_data); }
|
||||
|
||||
bytes const& verbatimData() const { assertThrow(m_type == VerbatimBytecode, util::Exception, ""); return m_verbatimBytecode->second; }
|
||||
|
||||
/// @returns the instruction of this item (only valid if type() == Operation)
|
||||
Instruction instruction() const { assertThrow(m_type == Operation, util::Exception, ""); return m_instruction; }
|
||||
|
||||
@@ -105,6 +115,8 @@ public:
|
||||
return false;
|
||||
if (type() == Operation)
|
||||
return instruction() == _other.instruction();
|
||||
else if (type() == VerbatimBytecode)
|
||||
return *m_verbatimBytecode == *_other.m_verbatimBytecode;
|
||||
else
|
||||
return data() == _other.data();
|
||||
}
|
||||
@@ -116,6 +128,8 @@ public:
|
||||
return type() < _other.type();
|
||||
else if (type() == Operation)
|
||||
return instruction() < _other.instruction();
|
||||
else if (type() == VerbatimBytecode)
|
||||
return *m_verbatimBytecode == *_other.m_verbatimBytecode;
|
||||
else
|
||||
return data() < _other.data();
|
||||
}
|
||||
@@ -137,7 +151,7 @@ public:
|
||||
size_t bytesRequired(size_t _addressLength) const;
|
||||
size_t arguments() const;
|
||||
size_t returnValues() const;
|
||||
size_t deposit() const { return returnValues() - arguments(); }
|
||||
size_t deposit() const { return m_type == VerbatimBytecode ? static_cast<size_t>(m_verbatimBytecode->first) : returnValues() - arguments(); }
|
||||
|
||||
/// @returns true if the assembly item can be used in a functional context.
|
||||
bool canBeFunctional() const;
|
||||
@@ -162,6 +176,8 @@ private:
|
||||
AssemblyItemType m_type;
|
||||
Instruction m_instruction; ///< Only valid if m_type == Operation
|
||||
std::shared_ptr<u256> m_data; ///< Only valid if m_type != Operation
|
||||
/// If m_type == VerbatimBytecode, this holds stack difference and verbatim bytecode.
|
||||
std::optional<std::pair<int, bytes>> m_verbatimBytecode;
|
||||
langutil::SourceLocation m_location;
|
||||
JumpType m_jumpType = JumpType::Ordinary;
|
||||
/// Pushed value for operations with data to be determined during assembly stage,
|
||||
|
||||
Reference in New Issue
Block a user