mirror of https://github.com/status-im/evmc.git
Merge pull request #341 from ethereum/cpp
cpp: Extend API to allow moving evmc::vm objects
This commit is contained in:
commit
f6d3f97e13
|
@ -10,6 +10,8 @@
|
|||
new `evmc_load_and_configure()` function.
|
||||
- Added: [[#327](https://github.com/ethereum/evmc/pull/327)]
|
||||
Full support for 32-bit architectures has been added.
|
||||
- Added: [[#341](https://github.com/ethereum/evmc/pull/341)]
|
||||
Support for moving `evmc::vm` objects in C++ API.
|
||||
- Changed: [[#293](https://github.com/ethereum/evmc/pull/293)]
|
||||
In C++ API `evmc::result::raw()` renamed to `evmc::result::release_raw()`.
|
||||
- Changed: [[#311](https://github.com/ethereum/evmc/pull/311)]
|
||||
|
|
|
@ -80,11 +80,32 @@ public:
|
|||
class vm
|
||||
{
|
||||
public:
|
||||
vm() noexcept = default;
|
||||
|
||||
/// Converting constructor from evmc_instance.
|
||||
explicit vm(evmc_instance* instance) noexcept : m_instance{instance} {}
|
||||
|
||||
/// Destructor responsible for automatically destroying the VM instance.
|
||||
~vm() noexcept { m_instance->destroy(m_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 provided list of options.
|
||||
|
@ -96,6 +117,9 @@ public:
|
|||
set_option(option.first, option.second);
|
||||
}
|
||||
|
||||
/// 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; }
|
||||
|
||||
|
@ -128,7 +152,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
evmc_instance* const m_instance = nullptr;
|
||||
evmc_instance* m_instance = nullptr;
|
||||
};
|
||||
|
||||
/// The EVMC Host interface
|
||||
|
|
|
@ -70,6 +70,67 @@ TEST(cpp, vm_set_option)
|
|||
EXPECT_EQ(vm.set_option("1", "2"), EVMC_SET_OPTION_INVALID_NAME);
|
||||
}
|
||||
|
||||
TEST(cpp, vm_null)
|
||||
{
|
||||
evmc::vm vm;
|
||||
EXPECT_FALSE(vm);
|
||||
EXPECT_TRUE(!vm);
|
||||
}
|
||||
|
||||
TEST(cpp, vm_move)
|
||||
{
|
||||
static int destroy_counter = 0;
|
||||
const auto template_instance =
|
||||
evmc_instance{EVMC_ABI_VERSION, "", "", [](evmc_instance*) { ++destroy_counter; },
|
||||
nullptr, nullptr, nullptr, nullptr};
|
||||
|
||||
EXPECT_EQ(destroy_counter, 0);
|
||||
{
|
||||
auto v1 = template_instance;
|
||||
auto v2 = template_instance;
|
||||
|
||||
auto vm1 = evmc::vm{&v1};
|
||||
EXPECT_TRUE(vm1);
|
||||
vm1 = evmc::vm{&v2};
|
||||
EXPECT_TRUE(vm1);
|
||||
}
|
||||
EXPECT_EQ(destroy_counter, 2);
|
||||
{
|
||||
auto v1 = template_instance;
|
||||
|
||||
auto vm1 = evmc::vm{&v1};
|
||||
EXPECT_TRUE(vm1);
|
||||
vm1 = evmc::vm{};
|
||||
EXPECT_FALSE(vm1);
|
||||
}
|
||||
EXPECT_EQ(destroy_counter, 3);
|
||||
{
|
||||
auto v1 = template_instance;
|
||||
|
||||
auto vm1 = evmc::vm{&v1};
|
||||
EXPECT_TRUE(vm1);
|
||||
auto vm2 = std::move(vm1);
|
||||
EXPECT_TRUE(vm2);
|
||||
EXPECT_FALSE(vm1); // NOLINT
|
||||
auto vm3 = std::move(vm2);
|
||||
EXPECT_TRUE(vm3);
|
||||
EXPECT_FALSE(vm2); // NOLINT
|
||||
EXPECT_FALSE(vm1);
|
||||
}
|
||||
EXPECT_EQ(destroy_counter, 4);
|
||||
{
|
||||
// Moving to itself will destroy the VM and reset the evmc::vm.
|
||||
auto v1 = template_instance;
|
||||
|
||||
auto vm1 = evmc::vm{&v1};
|
||||
auto& vm1_ref = vm1;
|
||||
vm1 = std::move(vm1_ref);
|
||||
EXPECT_EQ(destroy_counter, 5); // Already destroyed.
|
||||
EXPECT_FALSE(vm1); // Null.
|
||||
}
|
||||
EXPECT_EQ(destroy_counter, 5);
|
||||
}
|
||||
|
||||
TEST(cpp, host)
|
||||
{
|
||||
// Use example host to execute all methods from the C++ host wrapper.
|
||||
|
|
Loading…
Reference in New Issue