mirror of https://github.com/status-im/evmc.git
helpers, cpp: Add evmc_make_result() for constructing results
This moves the evmc_result construction logic from evmc::result() constructor to helper.h. This function is now exposed as a C helper, C++ evmc::make_result() helper and used in the evmc::result() constructor. This is convenient for VM implementations which need to construct C evmc_result, not C++ evmc::result.
This commit is contained in:
parent
e4ae2162c5
commit
55329d8dfa
|
@ -7,8 +7,6 @@
|
|||
#include <evmc/evmc.h>
|
||||
#include <evmc/helpers.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
|
@ -257,6 +255,10 @@ constexpr bytes32 operator"" _bytes32() noexcept
|
|||
|
||||
using namespace literals;
|
||||
|
||||
|
||||
/// Alias for evmc_make_result().
|
||||
constexpr auto make_result = evmc_make_result;
|
||||
|
||||
/// @copydoc evmc_result
|
||||
///
|
||||
/// This is a RAII wrapper for evmc_result and objects of this type
|
||||
|
@ -283,19 +285,8 @@ public:
|
|||
int64_t _gas_left,
|
||||
const uint8_t* _output_data,
|
||||
size_t _output_size) noexcept
|
||||
: evmc_result{_status_code, _gas_left, nullptr, _output_size, {}, {}, {}}
|
||||
{
|
||||
if (output_size != 0)
|
||||
{
|
||||
auto mem = static_cast<uint8_t*>(std::malloc(output_size));
|
||||
std::copy_n(_output_data, output_size, mem);
|
||||
output_data = mem;
|
||||
release = [](const evmc_result* r) noexcept
|
||||
{
|
||||
std::free(const_cast<uint8_t*>(r->output_data));
|
||||
};
|
||||
}
|
||||
}
|
||||
: evmc_result{make_result(_status_code, _gas_left, _output_data, _output_size)}
|
||||
{}
|
||||
|
||||
/// Converting constructor from raw evmc_result.
|
||||
explicit result(evmc_result const& res) noexcept : evmc_result{res} {}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <evmc/evmc.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Returns true if the VM instance has a compatible ABI version.
|
||||
|
@ -107,6 +109,46 @@ static inline struct evmc_result evmc_execute(struct evmc_instance* instance,
|
|||
return instance->execute(instance, context, rev, msg, code, code_size);
|
||||
}
|
||||
|
||||
/// The evmc_result release function using free() for releasing the memory.
|
||||
///
|
||||
/// This function is used in the evmc_make_result(),
|
||||
/// but may be also used in other case if convenient.
|
||||
///
|
||||
/// @param result The result object.
|
||||
static void evmc_free_result_memory(const struct evmc_result* result)
|
||||
{
|
||||
free((uint8_t*)result->output_data);
|
||||
}
|
||||
|
||||
/// Creates the result from the provided arguments.
|
||||
///
|
||||
/// The provided output is copied to memory allocated with malloc()
|
||||
/// and the evmc_result::release function is set to one invoking free().
|
||||
///
|
||||
/// @param status_code The status code.
|
||||
/// @param gas_left The amount of gas left.
|
||||
/// @param output_data The pointer to the output.
|
||||
/// @param output_size The output size.
|
||||
static inline struct evmc_result evmc_make_result(enum evmc_status_code status_code,
|
||||
int64_t gas_left,
|
||||
const uint8_t* output_data,
|
||||
size_t output_size)
|
||||
{
|
||||
struct evmc_result result;
|
||||
memset(&result, 0, sizeof(result));
|
||||
result.status_code = status_code;
|
||||
result.gas_left = gas_left;
|
||||
result.output_size = output_size;
|
||||
if (output_size != 0)
|
||||
{
|
||||
uint8_t* buffer = (uint8_t*)malloc(output_size);
|
||||
memcpy(buffer, output_data, output_size);
|
||||
result.output_data = buffer;
|
||||
result.release = evmc_free_result_memory;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the resources allocated to the execution result.
|
||||
*
|
||||
|
|
|
@ -492,4 +492,13 @@ TEST(cpp, result_create)
|
|||
ASSERT_EQ(r.output_size, 2);
|
||||
EXPECT_EQ(r.output_data[0], 1);
|
||||
EXPECT_EQ(r.output_data[1], 2);
|
||||
|
||||
auto c = evmc::make_result(r.status_code, r.gas_left, r.output_data, r.output_size);
|
||||
EXPECT_EQ(c.status_code, r.status_code);
|
||||
EXPECT_EQ(c.gas_left, r.gas_left);
|
||||
ASSERT_EQ(c.output_size, r.output_size);
|
||||
EXPECT_EQ(evmc::address{c.create_address}, evmc::address{r.create_address});
|
||||
ASSERT_TRUE(c.release);
|
||||
EXPECT_TRUE(std::memcmp(c.output_data, r.output_data, c.output_size) == 0);
|
||||
c.release(&c);
|
||||
}
|
Loading…
Reference in New Issue