Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scratchpad #434

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bindings/rust/evmc-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ mod tests {
// TODO: add other checks from test/unittests/test_helpers.cpp
assert_eq!(size_of::<evmc_bytes32>(), 32);
assert_eq!(size_of::<evmc_address>(), 20);
assert!(size_of::<evmc_result>() <= 64);
assert!(size_of::<evmc_result>() <= 128);
assert!(size_of::<evmc_vm>() <= 64);
}
}
6 changes: 3 additions & 3 deletions bindings/rust/evmc-vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ impl Into<ffi::evmc_result> for ExecutionResult {
} else {
Address { bytes: [0u8; 20] }
},
padding: [0u8; 4],
scratchpad: ffi::evmc_result_scratchpad { bytes: [0u8; 32] },
}
}
}
Expand Down Expand Up @@ -532,7 +532,7 @@ mod tests {
output_size: 4,
release: Some(test_result_dispose),
create_address: Address { bytes: [0u8; 20] },
padding: [0u8; 4],
scratchpad: ffi::evmc_result_scratchpad { bytes: [0u8; 32] },
};

let r: ExecutionResult = f.into();
Expand Down Expand Up @@ -778,7 +778,7 @@ mod tests {
output_size: msg.input_size,
release: None,
create_address: ffi::evmc_address::default(),
padding: [0u8; 4],
scratchpad: ffi::evmc_result_scratchpad { bytes: [0u8; 32] },
}
}

Expand Down
30 changes: 18 additions & 12 deletions include/evmc/evmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ struct evmc_result;
*/
typedef void (*evmc_release_result_fn)(const struct evmc_result* result);


/** The EVM code execution result. */
struct evmc_result
{
Expand Down Expand Up @@ -402,18 +403,23 @@ struct evmc_result
*/
evmc_address create_address;

/**
* Reserved data that MAY be used by a evmc_result object creator.
*
* This reserved 4 bytes together with 20 bytes from create_address form
* 24 bytes of memory called "optional data" within evmc_result struct
* to be optionally used by the evmc_result object creator.
*
* @see evmc_result_optional_data, evmc_get_optional_data().
*
* Also extends the size of the evmc_result to 64 bytes (full cache line).
*/
uint8_t padding[4];
union scratchpad
{
/**
* Reserved data that MAY be used by a evmc_result object creator.
*
* This reserved 4 bytes together with 20 bytes from create_address form
* 24 bytes of memory called "optional data" within evmc_result struct
* to be optionally used by the evmc_result object creator.
*
* @see evmc_result_optional_data, evmc_get_optional_data().
*
* Also extends the size of the evmc_result to 64 bytes (full cache line).
*/
uint8_t bytes[32];

void* pointer;
} scratchpad;
};


Expand Down
2 changes: 1 addition & 1 deletion include/evmc/evmc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,11 @@ constexpr auto make_result = evmc_make_result;
class result : private evmc_result
{
public:
using evmc_result::create_address;
using evmc_result::gas_left;
using evmc_result::output_data;
using evmc_result::output_size;
using evmc_result::status_code;
using evmc_result::create_address;

/// Creates the result from the provided arguments.
///
Expand Down
49 changes: 0 additions & 49 deletions include/evmc/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,53 +160,4 @@ static inline void evmc_release_result(struct evmc_result* result)
result->release(result);
}


/**
* Helpers for optional storage of evmc_result.
*
* In some contexts (i.e. evmc_result::create_address is unused) objects of
* type evmc_result contains a memory storage that MAY be used by the object
* owner. This group defines helper types and functions for accessing
* the optional storage.
*
* @defgroup result_optional_storage Result Optional Storage
* @{
*/

/**
* The union representing evmc_result "optional storage".
*
* The evmc_result struct contains 24 bytes of optional storage that can be
* reused by the object creator if the object does not contain
* evmc_result::create_address.
*
* A VM implementation MAY use this memory to keep additional data
* when returning result from evmc_execute_fn().
* The host application MAY use this memory to keep additional data
* when returning result of performed calls from evmc_call_fn().
*
* @see evmc_get_optional_storage(), evmc_get_const_optional_storage().
*/
union evmc_result_optional_storage
{
uint8_t bytes[24]; /**< 24 bytes of optional storage. */
void* pointer; /**< Optional pointer. */
};

/** Provides read-write access to evmc_result "optional storage". */
static inline union evmc_result_optional_storage* evmc_get_optional_storage(
struct evmc_result* result)
{
return (union evmc_result_optional_storage*)&result->create_address;
}

/** Provides read-only access to evmc_result "optional storage". */
static inline const union evmc_result_optional_storage* evmc_get_const_optional_storage(
const struct evmc_result* result)
{
return (const union evmc_result_optional_storage*)&result->create_address;
}

/** @} */

/** @} */
4 changes: 2 additions & 2 deletions test/unittests/test_cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,13 @@ TEST(cpp, result)
int release_called = 0;
{
auto raw_result = evmc_result{};
evmc_get_optional_storage(&raw_result)->pointer = &release_called;
raw_result.scratchpad.pointer = &release_called;
EXPECT_EQ(release_called, 0);

raw_result.output_data = &output;
raw_result.release = [](const evmc_result* r) {
EXPECT_EQ(r->output_data, &output);
++*static_cast<int*>(evmc_get_const_optional_storage(r)->pointer);
++*static_cast<int*>(r->scratchpad.pointer);
};
EXPECT_EQ(release_called, 0);

Expand Down
9 changes: 4 additions & 5 deletions test/unittests/test_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

static_assert(sizeof(evmc_bytes32) == 32, "evmc_bytes32 is too big");
static_assert(sizeof(evmc_address) == 20, "evmc_address is too big");
static_assert(sizeof(evmc_result) <= 64, "evmc_result does not fit cache line");
static_assert(sizeof(evmc_result) <= 128, "evmc_result does not fit 2 cache lines");
static_assert(sizeof(evmc_vm) <= 64, "evmc_vm does not fit cache line");
static_assert(offsetof(evmc_message, value) % sizeof(size_t) == 0,
"evmc_message.value not aligned");
Expand All @@ -21,10 +21,9 @@ static_assert(sizeof(evmc_call_kind) == sizeof(int),
"Enum `evmc_call_kind` is not the size of int");
static_assert(sizeof(evmc_revision) == sizeof(int), "Enum `evmc_revision` is not the size of int");

static constexpr size_t optionalDataSize =
sizeof(evmc_result) - offsetof(evmc_result, create_address);
static_assert(optionalDataSize >= sizeof(evmc_result_optional_storage),
"evmc_result's optional data space is too small");

static_assert(offsetof(evmc_result, scratchpad) % 8 == 0,
"evmc_result's scratchpad not properly aligned");

TEST(helpers, release_result)
{
Expand Down