mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #7756 from ethereum/evmc7
Ensure the EVMC7 update is properly matching 7.0.0
This commit is contained in:
commit
7535039f40
@ -16,7 +16,6 @@ target_sources(evmc INTERFACE
|
|||||||
${PROJECT_SOURCE_DIR}/test/evmc/evmc.h
|
${PROJECT_SOURCE_DIR}/test/evmc/evmc.h
|
||||||
${PROJECT_SOURCE_DIR}/test/evmc/evmc.hpp
|
${PROJECT_SOURCE_DIR}/test/evmc/evmc.hpp
|
||||||
${PROJECT_SOURCE_DIR}/test/evmc/helpers.h
|
${PROJECT_SOURCE_DIR}/test/evmc/helpers.h
|
||||||
${PROJECT_SOURCE_DIR}/test/evmc/helpers.hpp
|
|
||||||
${PROJECT_SOURCE_DIR}/test/evmc/utils.h
|
${PROJECT_SOURCE_DIR}/test/evmc/utils.h
|
||||||
)
|
)
|
||||||
target_include_directories(evmc INTERFACE ${PROJECT_SOURCE_DIR}/test/)
|
target_include_directories(evmc INTERFACE ${PROJECT_SOURCE_DIR}/test/)
|
||||||
|
@ -334,118 +334,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Host;
|
|
||||||
|
|
||||||
/// @copybrief evmc_vm
|
|
||||||
///
|
|
||||||
/// This is a RAII wrapper for evmc_vm and objects of this type
|
|
||||||
/// automatically destroys the VM instance.
|
|
||||||
class VM
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VM() noexcept = default;
|
|
||||||
|
|
||||||
/// Converting constructor from evmc_vm.
|
|
||||||
explicit VM(evmc_vm* vm) noexcept : m_instance{vm} {}
|
|
||||||
|
|
||||||
/// Destructor responsible for automatically destroying the VM instance.
|
|
||||||
~VM() noexcept
|
|
||||||
{
|
|
||||||
if (m_instance)
|
|
||||||
m_instance->destroy(m_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
VM(const VM&) = delete;
|
|
||||||
VM& operator=(const VM&) = delete;
|
|
||||||
|
|
||||||
/// Move constructor.
|
|
||||||
VM(VM&& other) noexcept : m_instance{other.m_instance} { other.m_instance = nullptr; }
|
|
||||||
|
|
||||||
/// Move assignment operator.
|
|
||||||
VM& operator=(VM&& other) noexcept
|
|
||||||
{
|
|
||||||
this->~VM();
|
|
||||||
m_instance = other.m_instance;
|
|
||||||
other.m_instance = nullptr;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The constructor that captures a VM instance and configures the instance
|
|
||||||
/// with the provided list of options.
|
|
||||||
inline VM(evmc_vm* vm,
|
|
||||||
std::initializer_list<std::pair<const char*, const char*>> options) noexcept;
|
|
||||||
|
|
||||||
/// Checks if contains a valid pointer to the VM instance.
|
|
||||||
explicit operator bool() const noexcept { return m_instance != nullptr; }
|
|
||||||
|
|
||||||
/// Checks whenever the VM instance is ABI compatible with the current EVMC API.
|
|
||||||
bool is_abi_compatible() const noexcept { return m_instance->abi_version == EVMC_ABI_VERSION; }
|
|
||||||
|
|
||||||
/// @copydoc evmc_vm::name
|
|
||||||
char const* name() const noexcept { return m_instance->name; }
|
|
||||||
|
|
||||||
/// @copydoc evmc_vm::version
|
|
||||||
char const* version() const noexcept { return m_instance->version; }
|
|
||||||
|
|
||||||
/// @copydoc evmc::vm::get_capabilities
|
|
||||||
evmc_capabilities_flagset get_capabilities() const noexcept
|
|
||||||
{
|
|
||||||
return m_instance->get_capabilities(m_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @copydoc evmc_set_option()
|
|
||||||
evmc_set_option_result set_option(const char name[], const char value[]) noexcept
|
|
||||||
{
|
|
||||||
return evmc_set_option(m_instance, name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @copydoc evmc_execute()
|
|
||||||
result execute(const evmc_host_interface& host,
|
|
||||||
evmc_host_context* ctx,
|
|
||||||
evmc_revision rev,
|
|
||||||
const evmc_message& msg,
|
|
||||||
const uint8_t* code,
|
|
||||||
size_t code_size) noexcept
|
|
||||||
{
|
|
||||||
return result{m_instance->execute(m_instance, &host, ctx, rev, &msg, code, code_size)};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convenient variant of the VM::execute() that takes reference to evmc::Host class.
|
|
||||||
inline result execute(Host& host,
|
|
||||||
evmc_revision rev,
|
|
||||||
const evmc_message& msg,
|
|
||||||
const uint8_t* code,
|
|
||||||
size_t code_size) noexcept;
|
|
||||||
|
|
||||||
/// Executes code without the Host context.
|
|
||||||
///
|
|
||||||
/// The same as
|
|
||||||
/// execute(const evmc_host_interface&, evmc_host_context*, evmc_revision,
|
|
||||||
/// const evmc_message&, const uint8_t*, size_t),
|
|
||||||
/// but without providing the Host context and interface.
|
|
||||||
/// This method is for experimental precompiles support where execution is
|
|
||||||
/// guaranteed not to require any Host access.
|
|
||||||
result execute(evmc_revision rev,
|
|
||||||
const evmc_message& msg,
|
|
||||||
const uint8_t* code,
|
|
||||||
size_t code_size) noexcept
|
|
||||||
{
|
|
||||||
return result{
|
|
||||||
m_instance->execute(m_instance, nullptr, nullptr, rev, &msg, code, code_size)};
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
evmc_vm* m_instance = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline VM::VM(evmc_vm* vm,
|
|
||||||
std::initializer_list<std::pair<const char*, const char*>> options) noexcept
|
|
||||||
: m_instance{vm}
|
|
||||||
{
|
|
||||||
for (const auto& option : options)
|
|
||||||
set_option(option.first, option.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// The EVMC Host interface
|
/// The EVMC Host interface
|
||||||
class HostInterface
|
class HostInterface
|
||||||
@ -514,8 +402,10 @@ public:
|
|||||||
HostContext() = default;
|
HostContext() = default;
|
||||||
|
|
||||||
/// Constructor from the EVMC Host primitives.
|
/// Constructor from the EVMC Host primitives.
|
||||||
HostContext(const evmc_host_interface* interface, evmc_host_context* ctx) noexcept
|
/// @param interface The reference to the Host interface.
|
||||||
: host{interface}, context{ctx}
|
/// @param ctx The pointer to the Host context object. This parameter MAY be null.
|
||||||
|
HostContext(const evmc_host_interface& interface, evmc_host_context* ctx) noexcept
|
||||||
|
: host{&interface}, context{ctx}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool account_exists(const address& address) noexcept final
|
bool account_exists(const address& address) noexcept final
|
||||||
@ -596,6 +486,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Abstract class to be used by Host implementations.
|
/// Abstract class to be used by Host implementations.
|
||||||
///
|
///
|
||||||
/// When implementing EVMC Host, you can directly inherit from the evmc::Host class.
|
/// When implementing EVMC Host, you can directly inherit from the evmc::Host class.
|
||||||
@ -628,13 +519,118 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline result VM::execute(Host& host,
|
/// @copybrief evmc_vm
|
||||||
evmc_revision rev,
|
///
|
||||||
const evmc_message& msg,
|
/// This is a RAII wrapper for evmc_vm, and object of this type
|
||||||
const uint8_t* code,
|
/// automatically destroys the VM instance.
|
||||||
size_t code_size) noexcept
|
class VM
|
||||||
{
|
{
|
||||||
return execute(Host::get_interface(), host.to_context(), rev, msg, code, code_size);
|
public:
|
||||||
|
VM() noexcept = default;
|
||||||
|
|
||||||
|
/// Converting constructor from evmc_vm.
|
||||||
|
explicit VM(evmc_vm* vm) noexcept : m_instance{vm} {}
|
||||||
|
|
||||||
|
/// Destructor responsible for automatically destroying the VM instance.
|
||||||
|
~VM() noexcept
|
||||||
|
{
|
||||||
|
if (m_instance)
|
||||||
|
m_instance->destroy(m_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
VM(const VM&) = delete;
|
||||||
|
VM& operator=(const VM&) = delete;
|
||||||
|
|
||||||
|
/// Move constructor.
|
||||||
|
VM(VM&& other) noexcept : m_instance{other.m_instance} { other.m_instance = nullptr; }
|
||||||
|
|
||||||
|
/// Move assignment operator.
|
||||||
|
VM& operator=(VM&& other) noexcept
|
||||||
|
{
|
||||||
|
this->~VM();
|
||||||
|
m_instance = other.m_instance;
|
||||||
|
other.m_instance = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The constructor that captures a VM instance and configures the instance
|
||||||
|
/// with the provided list of options.
|
||||||
|
inline VM(evmc_vm* vm,
|
||||||
|
std::initializer_list<std::pair<const char*, const char*>> options) noexcept;
|
||||||
|
|
||||||
|
/// Checks if contains a valid pointer to the VM instance.
|
||||||
|
explicit operator bool() const noexcept { return m_instance != nullptr; }
|
||||||
|
|
||||||
|
/// Checks whenever the VM instance is ABI compatible with the current EVMC API.
|
||||||
|
bool is_abi_compatible() const noexcept { return m_instance->abi_version == EVMC_ABI_VERSION; }
|
||||||
|
|
||||||
|
/// @copydoc evmc_vm::name
|
||||||
|
char const* name() const noexcept { return m_instance->name; }
|
||||||
|
|
||||||
|
/// @copydoc evmc_vm::version
|
||||||
|
char const* version() const noexcept { return m_instance->version; }
|
||||||
|
|
||||||
|
/// @copydoc evmc::vm::get_capabilities
|
||||||
|
evmc_capabilities_flagset get_capabilities() const noexcept
|
||||||
|
{
|
||||||
|
return m_instance->get_capabilities(m_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @copydoc evmc_set_option()
|
||||||
|
evmc_set_option_result set_option(const char name[], const char value[]) noexcept
|
||||||
|
{
|
||||||
|
return evmc_set_option(m_instance, name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @copydoc evmc_execute()
|
||||||
|
result execute(const evmc_host_interface& host,
|
||||||
|
evmc_host_context* ctx,
|
||||||
|
evmc_revision rev,
|
||||||
|
const evmc_message& msg,
|
||||||
|
const uint8_t* code,
|
||||||
|
size_t code_size) noexcept
|
||||||
|
{
|
||||||
|
return result{m_instance->execute(m_instance, &host, ctx, rev, &msg, code, code_size)};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenient variant of the VM::execute() that takes reference to evmc::Host class.
|
||||||
|
result execute(Host& host,
|
||||||
|
evmc_revision rev,
|
||||||
|
const evmc_message& msg,
|
||||||
|
const uint8_t* code,
|
||||||
|
size_t code_size) noexcept
|
||||||
|
{
|
||||||
|
return execute(Host::get_interface(), host.to_context(), rev, msg, code, code_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Executes code without the Host context.
|
||||||
|
///
|
||||||
|
/// The same as
|
||||||
|
/// execute(const evmc_host_interface&, evmc_host_context*, evmc_revision,
|
||||||
|
/// const evmc_message&, const uint8_t*, size_t),
|
||||||
|
/// but without providing the Host context and interface.
|
||||||
|
/// This method is for experimental precompiles support where execution is
|
||||||
|
/// guaranteed not to require any Host access.
|
||||||
|
result execute(evmc_revision rev,
|
||||||
|
const evmc_message& msg,
|
||||||
|
const uint8_t* code,
|
||||||
|
size_t code_size) noexcept
|
||||||
|
{
|
||||||
|
return result{
|
||||||
|
m_instance->execute(m_instance, nullptr, nullptr, rev, &msg, code, code_size)};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
evmc_vm* m_instance = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline VM::VM(evmc_vm* vm,
|
||||||
|
std::initializer_list<std::pair<const char*, const char*>> options) noexcept
|
||||||
|
: m_instance{vm}
|
||||||
|
{
|
||||||
|
// This constructor is implemented outside of the class definition to workaround a doxygen bug.
|
||||||
|
for (const auto& option : options)
|
||||||
|
set_option(option.first, option.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
/* EVMC: Ethereum Client-VM Connector API.
|
|
||||||
* Copyright 2018-2019 The EVMC Authors.
|
|
||||||
* Licensed under the Apache License, Version 2.0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* A collection of helpers (overloaded operators) for using EVMC types effectively in C++.
|
|
||||||
*
|
|
||||||
* @addtogroup helpers
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <evmc/evmc.hpp>
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
using evmc::is_zero;
|
|
||||||
|
|
||||||
/// The comparator for std::map<evmc_address, ...>.
|
|
||||||
EVMC_DEPRECATED
|
|
||||||
inline bool operator<(const evmc_address& a, const evmc_address& b)
|
|
||||||
{
|
|
||||||
return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The comparator for std::map<evmc_bytes32, ...>.
|
|
||||||
EVMC_DEPRECATED
|
|
||||||
inline bool operator<(const evmc_bytes32& a, const evmc_bytes32& b)
|
|
||||||
{
|
|
||||||
return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The comparator for equality.
|
|
||||||
EVMC_DEPRECATED
|
|
||||||
inline bool operator==(const evmc_address& a, const evmc_address& b)
|
|
||||||
{
|
|
||||||
return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The comparator for equality.
|
|
||||||
EVMC_DEPRECATED
|
|
||||||
inline bool operator==(const evmc_bytes32& a, const evmc_bytes32& b)
|
|
||||||
{
|
|
||||||
return std::memcmp(a.bytes, b.bytes, sizeof(a.bytes)) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parameters for the fnv1a hash function, specialized by the hash result size (size_t).
|
|
||||||
///
|
|
||||||
/// The values for the matching size are taken from
|
|
||||||
/// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV_hash_parameters.
|
|
||||||
///
|
|
||||||
/// @tparam size The size of the hash result (size_t).
|
|
||||||
template <size_t size>
|
|
||||||
struct fnv1_params
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Parameters for the fnv1a hash function, specialized for the hash result of 4 bytes.
|
|
||||||
template <>
|
|
||||||
struct fnv1_params<4>
|
|
||||||
{
|
|
||||||
static constexpr auto prime = 0x1000193; ///< The FNV prime.
|
|
||||||
static constexpr auto offset_basis = 0x811c9dc5; ///< The FNV offset basis.
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Parameters for the fnv1a hash function, specialized for the hash result of 8 bytes.
|
|
||||||
template <>
|
|
||||||
struct fnv1_params<8>
|
|
||||||
{
|
|
||||||
static constexpr auto prime = 0x100000001b3; ///< The FNV prime.
|
|
||||||
static constexpr auto offset_basis = 0xcbf29ce484222325; ///< The FNV offset basis.
|
|
||||||
};
|
|
||||||
|
|
||||||
/// FNV1a hash function.
|
|
||||||
inline size_t fnv1a(const uint8_t* ptr, size_t len) noexcept
|
|
||||||
{
|
|
||||||
using params = fnv1_params<sizeof(size_t)>;
|
|
||||||
|
|
||||||
auto ret = size_t{params::offset_basis};
|
|
||||||
for (size_t i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
ret ^= ptr[i];
|
|
||||||
ret *= params::prime;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
/// Hash operator template specialization for evmc_address needed for unordered containers.
|
|
||||||
template <>
|
|
||||||
struct EVMC_DEPRECATED hash<evmc_address>
|
|
||||||
{
|
|
||||||
/// Hash operator using FNV1a.
|
|
||||||
size_t operator()(const evmc_address& s) const noexcept
|
|
||||||
{
|
|
||||||
return fnv1a(s.bytes, sizeof(s.bytes));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Hash operator template needed for std::unordered_set and others using hashes.
|
|
||||||
template <>
|
|
||||||
struct EVMC_DEPRECATED hash<evmc_bytes32>
|
|
||||||
{
|
|
||||||
/// Hash operator using FNV1a.
|
|
||||||
size_t operator()(const evmc_bytes32& s) const noexcept
|
|
||||||
{
|
|
||||||
return fnv1a(s.bytes, sizeof(s.bytes));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
/** @} */
|
|
Loading…
Reference in New Issue
Block a user