cpp: Allow moving evmc::vm

This commit is contained in:
Paweł Bylica 2019-07-03 18:28:00 +02:00
parent bc551318e0
commit fff439a53b
No known key found for this signature in database
GPG Key ID: 7A0C037434FE77EF
2 changed files with 59 additions and 2 deletions

View File

@ -80,11 +80,32 @@ public:
class vm class vm
{ {
public: public:
vm() noexcept = default;
/// Converting constructor from evmc_instance. /// Converting constructor from evmc_instance.
explicit vm(evmc_instance* instance) noexcept : m_instance{instance} {} explicit vm(evmc_instance* instance) noexcept : m_instance{instance} {}
/// Destructor responsible for automatically destroying the VM 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 /// The constructor that captures a VM instance and configures the instance
/// with provided list of options. /// with provided list of options.
@ -128,7 +149,7 @@ public:
} }
private: private:
evmc_instance* const m_instance = nullptr; evmc_instance* m_instance = nullptr;
}; };
/// The EVMC Host interface /// The EVMC Host interface

View File

@ -70,6 +70,42 @@ TEST(cpp, vm_set_option)
EXPECT_EQ(vm.set_option("1", "2"), EVMC_SET_OPTION_INVALID_NAME); EXPECT_EQ(vm.set_option("1", "2"), EVMC_SET_OPTION_INVALID_NAME);
} }
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};
vm1 = evmc::vm{&v2};
(void)vm1;
}
EXPECT_EQ(destroy_counter, 2);
{
auto v1 = template_instance;
auto vm1 = evmc::vm{&v1};
vm1 = evmc::vm{};
(void)vm1;
}
EXPECT_EQ(destroy_counter, 3);
{
auto v1 = template_instance;
auto vm1 = evmc::vm{&v1};
auto vm2 = std::move(vm1);
auto vm3 = std::move(vm2);
(void)vm3;
}
EXPECT_EQ(destroy_counter, 4);
}
TEST(cpp, host) TEST(cpp, host)
{ {
// Use example host to execute all methods from the C++ host wrapper. // Use example host to execute all methods from the C++ host wrapper.