Rename evmc_instance -> evmc_vm

This commit is contained in:
Paweł Bylica 2019-09-24 23:59:08 +02:00
parent f38ac75f82
commit 28dfad3930
No known key found for this signature in database
GPG Key ID: 7A0C037434FE77EF
21 changed files with 196 additions and 202 deletions

View File

@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning].
### Changed
- The `evmc_instance` renamed to `evmc_vm`.
[[#430](https://github.com/ethereum/evmc/pull/430)]
- The `evmc::vm` renamed to `evmc::VM` in C++ API.
[[#252](https://github.com/ethereum/evmc/pull/252)]
- Previously deprecated `helpers.hpp` header file has been removed.

View File

@ -15,9 +15,9 @@ package evmc
#include <stdlib.h>
#include <string.h>
static inline enum evmc_set_option_result set_option(struct evmc_instance* instance, char* name, char* value)
static inline enum evmc_set_option_result set_option(struct evmc_vm* vm, char* name, char* value)
{
enum evmc_set_option_result ret = evmc_set_option(instance, name, value);
enum evmc_set_option_result ret = evmc_set_option(vm, name, value);
free(name);
free(value);
return ret;
@ -31,7 +31,7 @@ struct extended_context
extern const struct evmc_host_interface evmc_go_host;
static struct evmc_result execute_wrapper(struct evmc_instance* instance,
static struct evmc_result execute_wrapper(struct evmc_vm* vm,
int64_t context_index, enum evmc_revision rev,
enum evmc_call_kind kind, uint32_t flags, int32_t depth, int64_t gas,
const evmc_address* destination, const evmc_address* sender,
@ -52,7 +52,7 @@ static struct evmc_result execute_wrapper(struct evmc_instance* instance,
};
struct extended_context ctx = {{&evmc_go_host}, context_index};
return evmc_execute(instance, &ctx.context, rev, &msg, code, code_size);
return evmc_execute(vm, &ctx.context, rev, &msg, code, code_size);
}
*/
import "C"
@ -144,18 +144,18 @@ const (
Istanbul Revision = C.EVMC_ISTANBUL
)
type Instance struct {
handle *C.struct_evmc_instance
type VM struct {
handle *C.struct_evmc_vm
}
func Load(filename string) (instance *Instance, err error) {
func Load(filename string) (vm *VM, err error) {
cfilename := C.CString(filename)
var loaderErr C.enum_evmc_loader_error_code
handle := C.evmc_load_and_create(cfilename, &loaderErr)
C.free(unsafe.Pointer(cfilename))
if loaderErr == C.EVMC_LOADER_SUCCESS {
instance = &Instance{handle}
vm = &VM{handle}
} else {
errMsg := C.evmc_last_error_msg()
if errMsg != nil {
@ -165,17 +165,17 @@ func Load(filename string) (instance *Instance, err error) {
}
}
return instance, err
return vm, err
}
func LoadAndConfigure(config string) (instance *Instance, err error) {
func LoadAndConfigure(config string) (vm *VM, err error) {
cconfig := C.CString(config)
var loaderErr C.enum_evmc_loader_error_code
handle := C.evmc_load_and_configure(cconfig, &loaderErr)
C.free(unsafe.Pointer(cconfig))
if loaderErr == C.EVMC_LOADER_SUCCESS {
instance = &Instance{handle}
vm = &VM{handle}
} else {
errMsg := C.evmc_last_error_msg()
if errMsg != nil {
@ -185,21 +185,21 @@ func LoadAndConfigure(config string) (instance *Instance, err error) {
}
}
return instance, err
return vm, err
}
func (instance *Instance) Destroy() {
C.evmc_destroy(instance.handle)
func (vm *VM) Destroy() {
C.evmc_destroy(vm.handle)
}
func (instance *Instance) Name() string {
// TODO: consider using C.evmc_vm_name(instance.handle)
return C.GoString(instance.handle.name)
func (vm *VM) Name() string {
// TODO: consider using C.evmc_vm_name(vm.handle)
return C.GoString(vm.handle.name)
}
func (instance *Instance) Version() string {
// TODO: consider using C.evmc_vm_version(instance.handle)
return C.GoString(instance.handle.version)
func (vm *VM) Version() string {
// TODO: consider using C.evmc_vm_version(vm.handle)
return C.GoString(vm.handle.version)
}
type Capability uint32
@ -209,13 +209,13 @@ const (
CapabilityEWASM Capability = C.EVMC_CAPABILITY_EWASM
)
func (instance *Instance) HasCapability(capability Capability) bool {
return bool(C.evmc_vm_has_capability(instance.handle, uint32(capability)))
func (vm *VM) HasCapability(capability Capability) bool {
return bool(C.evmc_vm_has_capability(vm.handle, uint32(capability)))
}
func (instance *Instance) SetOption(name string, value string) (err error) {
func (vm *VM) SetOption(name string, value string) (err error) {
r := C.set_option(instance.handle, C.CString(name), C.CString(value))
r := C.set_option(vm.handle, C.CString(name), C.CString(value))
switch r {
case C.EVMC_SET_OPTION_INVALID_NAME:
err = fmt.Errorf("evmc: option '%s' not accepted", name)
@ -226,7 +226,7 @@ func (instance *Instance) SetOption(name string, value string) (err error) {
return err
}
func (instance *Instance) Execute(ctx HostContext, rev Revision,
func (vm *VM) Execute(ctx HostContext, rev Revision,
kind CallKind, static bool, depth int, gas int64,
destination common.Address, sender common.Address, input []byte, value common.Hash,
code []byte, create2Salt common.Hash) (output []byte, gasLeft int64, err error) {
@ -242,7 +242,7 @@ func (instance *Instance) Execute(ctx HostContext, rev Revision,
evmcSender := evmcAddress(sender)
evmcValue := evmcBytes32(value)
evmcCreate2Salt := evmcBytes32(create2Salt)
result := C.execute_wrapper(instance.handle, C.int64_t(ctxId), uint32(rev),
result := C.execute_wrapper(vm.handle, C.int64_t(ctxId), uint32(rev),
C.enum_evmc_call_kind(kind), flags, C.int32_t(depth), C.int64_t(gas),
&evmcDestination, &evmcSender, bytesPtr(input), C.size_t(len(input)), &evmcValue,
bytesPtr(code), C.size_t(len(code)), &evmcCreate2Salt)

View File

@ -272,7 +272,7 @@ fn build_capabilities_fn(capabilities: u32) -> proc_macro2::TokenStream {
LitInt::new(capabilities as u64, IntSuffix::U32, capabilities.span());
quote! {
extern "C" fn __evmc_get_capabilities(instance: *mut ::evmc_vm::ffi::evmc_instance) -> ::evmc_vm::ffi::evmc_capabilities_flagset {
extern "C" fn __evmc_get_capabilities(instance: *mut ::evmc_vm::ffi::evmc_vm) -> ::evmc_vm::ffi::evmc_capabilities_flagset {
#capabilities_literal
}
}
@ -289,8 +289,8 @@ fn build_create_fn(names: &VMNameSet) -> proc_macro2::TokenStream {
// Note: we can get CStrs unchecked because we did the checks on instantiation of VMMetaData.
quote! {
#[no_mangle]
extern "C" fn #fn_ident() -> *const ::evmc_vm::ffi::evmc_instance {
let new_instance = ::evmc_vm::ffi::evmc_instance {
extern "C" fn #fn_ident() -> *const ::evmc_vm::ffi::evmc_vm {
let new_instance = ::evmc_vm::ffi::evmc_vm {
abi_version: ::evmc_vm::ffi::EVMC_ABI_VERSION as i32,
destroy: Some(__evmc_destroy),
execute: Some(__evmc_execute),
@ -315,7 +315,7 @@ fn build_destroy_fn(names: &VMNameSet) -> proc_macro2::TokenStream {
let type_ident = names.get_type_as_ident();
quote! {
extern "C" fn __evmc_destroy(instance: *mut ::evmc_vm::ffi::evmc_instance) {
extern "C" fn __evmc_destroy(instance: *mut ::evmc_vm::ffi::evmc_vm) {
if instance.is_null() {
// This is an irrecoverable error that violates the EVMC spec.
std::process::abort();
@ -334,7 +334,7 @@ fn build_execute_fn(names: &VMNameSet) -> proc_macro2::TokenStream {
quote! {
extern "C" fn __evmc_execute(
instance: *mut ::evmc_vm::ffi::evmc_instance,
instance: *mut ::evmc_vm::ffi::evmc_vm,
context: *mut ::evmc_vm::ffi::evmc_host_context,
revision: ::evmc_vm::ffi::evmc_revision,
msg: *const ::evmc_vm::ffi::evmc_message,

View File

@ -13,7 +13,7 @@ where
T: EvmcVm + Sized,
{
#[allow(dead_code)]
instance: ::evmc_sys::evmc_instance,
instance: ::evmc_sys::evmc_vm,
vm: T,
}
@ -22,7 +22,7 @@ where
T: EvmcVm + Sized,
{
/// Basic constructor.
pub fn new(_instance: ::evmc_sys::evmc_instance) -> Box<Self> {
pub fn new(_instance: ::evmc_sys::evmc_vm) -> Box<Self> {
Box::new(Self {
instance: _instance,
vm: T::init(),
@ -30,14 +30,14 @@ where
}
/// Take ownership of the given pointer and return a box.
pub unsafe fn from_ffi_pointer(instance: *mut ::evmc_sys::evmc_instance) -> Box<Self> {
pub unsafe fn from_ffi_pointer(instance: *mut ::evmc_sys::evmc_vm) -> Box<Self> {
assert!(!instance.is_null(), "from_ffi_pointer received NULL");
Box::from_raw(instance as *mut EvmcContainer<T>)
}
/// Convert boxed self into an FFI pointer, surrendering ownership of the heap data.
pub unsafe fn into_ffi_pointer(boxed: Box<Self>) -> *mut ::evmc_sys::evmc_instance {
Box::into_raw(boxed) as *mut ::evmc_sys::evmc_instance
pub unsafe fn into_ffi_pointer(boxed: Box<Self>) -> *mut ::evmc_sys::evmc_vm {
Box::into_raw(boxed) as *mut ::evmc_sys::evmc_vm
}
}
@ -91,7 +91,7 @@ mod tests {
#[test]
fn container_new() {
let instance = ::evmc_sys::evmc_instance {
let instance = ::evmc_sys::evmc_vm {
abi_version: ::evmc_sys::EVMC_ABI_VERSION as i32,
name: std::ptr::null(),
version: std::ptr::null(),

View File

@ -21,17 +21,17 @@ When Host implementation is ready it's time to start using EVMC VMs.
1. Firstly, create a VM instance. You need to know what is the name of the "create"
function in particular VM implementation. The EVMC recommends to name the
function by the VM codename, e.g. ::evmc_create_example_vm().
Invoking the create function will give you the VM instance (::evmc_instance).
Invoking the create function will give you the VM instance (::evmc_vm).
It is recommended to create the VM instance once.
2. If you are interested in loading VMs dynamically (i.e. to use DLLs)
check out the [EVMC Loader](@ref loader) library.
3. The ::evmc_instance contains information about the VM like
name (::evmc_instance::name) or ABI version (::evmc_instance::abi_version)
3. The ::evmc_vm contains information about the VM like
name (::evmc_vm::name) or ABI version (::evmc_vm::abi_version)
and methods.
4. To execute code in the VM use the "execute()" method (::evmc_instance::execute).
4. To execute code in the VM use the "execute()" method (::evmc_vm::execute).
You will need:
- the code to execute,
- the message (::evmc_message) object that describes the execution context,

View File

@ -8,7 +8,7 @@ You can start with [the example implementation of EVMC VM interface in C](@ref e
## VM instance
The VM instance is described by the ::evmc_instance struct. It contains the
The VM instance is described by the ::evmc_vm struct. It contains the
basic static information about the VM like name and version. The struct also
includes the VM methods (in form of function pointers) to allow the Host
to interact with the VM.
@ -25,17 +25,17 @@ e.g. ::evmc_create_example_vm().
## VM methods implementation
Each VM methods takes the pointer to the ::evmc_instance as the first argument.
The VM implementation can extend the ::evmc_instance struct for storing internal
Each VM methods takes the pointer to the ::evmc_vm as the first argument.
The VM implementation can extend the ::evmc_vm struct for storing internal
data. This allow implementing the VM in object-oriented manner.
The most important method is ::evmc_instance::execute() because it executes EVM code.
The most important method is ::evmc_vm::execute() because it executes EVM code.
Remember that the Host is allowed to invoke the execute method concurrently
so do not store data related to a particular execution context in the VM instance.
Before a client can actually execute a VM, it is important to implement the three
basic fields for querying name (::evmc_instance::name), version (::evmc_instance::version)
and capabilities (::evmc_instance::get_capabilities()) as well as the ::evmc_instance::destroy()
basic fields for querying name (::evmc_vm::name), version (::evmc_vm::version)
and capabilities (::evmc_vm::get_capabilities()) as well as the ::evmc_vm::destroy()
method to wind the VM down.
Other methods are optional.

View File

@ -19,15 +19,15 @@ int main(int argc, char* argv[])
#ifdef STATICALLY_LINKED_EXAMPLE
(void)argc;
(void)argv;
struct evmc_instance* vm = evmc_create_example_vm();
struct evmc_vm* vm = evmc_create_example_vm();
if (!vm)
return EVMC_LOADER_INSTANCE_CREATION_FAILURE;
return EVMC_LOADER_VM_CREATION_FAILURE;
if (!evmc_is_abi_compatible(vm))
return EVMC_LOADER_ABI_VERSION_MISMATCH;
#else
const char* config_string = (argc > 1) ? argv[1] : "example-vm.so";
enum evmc_loader_error_code error_code;
struct evmc_instance* vm = evmc_load_and_configure(config_string, &error_code);
struct evmc_vm* vm = evmc_load_and_configure(config_string, &error_code);
if (!vm)
{
printf("Loading error: %d\n", error_code);

View File

@ -48,7 +48,7 @@ static evmc_result not_implemented()
return result;
}
static evmc_result execute(evmc_instance*,
static evmc_result execute(evmc_vm*,
evmc_host_context*,
enum evmc_revision rev,
const evmc_message* msg,
@ -111,16 +111,16 @@ static evmc_result execute(evmc_instance*,
}
}
extern "C" EVMC_EXPORT evmc_instance* evmc_create_example_precompiles_vm()
extern "C" EVMC_EXPORT evmc_vm* evmc_create_example_precompiles_vm()
{
static struct evmc_instance instance = {
static struct evmc_vm vm = {
EVMC_ABI_VERSION,
"example_precompiles_vm",
PROJECT_VERSION,
[](evmc_instance*) {},
[](evmc_vm*) {},
execute,
[](evmc_instance*) { return evmc_capabilities_flagset{EVMC_CAPABILITY_PRECOMPILES}; },
[](evmc_vm*) { return evmc_capabilities_flagset{EVMC_CAPABILITY_PRECOMPILES}; },
nullptr,
};
return &instance;
return &vm;
}

View File

@ -19,21 +19,21 @@
#include <string.h>
/// The example VM instance struct extending the evmc_instance.
/// The example VM instance struct extending the evmc_vm.
struct example_vm
{
struct evmc_instance instance; ///< The base struct.
int verbose; ///< The verbosity level.
struct evmc_vm instance; ///< The base struct.
int verbose; ///< The verbosity level.
};
/// The implementation of the evmc_instance::destroy() method.
static void destroy(struct evmc_instance* vm)
/// The implementation of the evmc_vm::destroy() method.
static void destroy(struct evmc_vm* vm)
{
free(vm);
}
/// The example implementation of the evmc_instance::get_capabilities() method.
static evmc_capabilities_flagset get_capabilities(struct evmc_instance* vm)
/// The example implementation of the evmc_vm::get_capabilities() method.
static evmc_capabilities_flagset get_capabilities(struct evmc_vm* vm)
{
(void)vm;
return EVMC_CAPABILITY_EVM1 | EVMC_CAPABILITY_EWASM;
@ -41,9 +41,9 @@ static evmc_capabilities_flagset get_capabilities(struct evmc_instance* vm)
/// Example VM options.
///
/// The implementation of the evmc_instance::set_option() method.
/// The implementation of the evmc_vm::set_option() method.
/// VMs are allowed to omit this method implementation.
static enum evmc_set_option_result set_option(struct evmc_instance* instance,
static enum evmc_set_option_result set_option(struct evmc_vm* instance,
const char* name,
const char* value)
{
@ -73,8 +73,8 @@ static void free_result_output_data(const struct evmc_result* result)
free((uint8_t*)result->output_data);
}
/// The example implementation of the evmc_instance::execute() method.
static struct evmc_result execute(struct evmc_instance* instance,
/// The example implementation of the evmc_vm::execute() method.
static struct evmc_result execute(struct evmc_vm* instance,
struct evmc_host_context* context,
enum evmc_revision rev,
const struct evmc_message* msg,
@ -215,9 +215,9 @@ static struct evmc_result execute(struct evmc_instance* instance,
#endif
/// @endcond
struct evmc_instance* evmc_create_example_vm()
struct evmc_vm* evmc_create_example_vm()
{
struct evmc_instance init = {
struct evmc_vm init = {
.abi_version = EVMC_ABI_VERSION,
.name = "example_vm",
.version = PROJECT_VERSION,
@ -227,7 +227,7 @@ struct evmc_instance* evmc_create_example_vm()
.set_option = set_option,
};
struct example_vm* vm = calloc(1, sizeof(struct example_vm));
struct evmc_instance* interface = &vm->instance;
struct evmc_vm* interface = &vm->instance;
memcpy(interface, &init, sizeof(init));
return interface;
}

View File

@ -15,7 +15,7 @@ extern "C" {
/**
* Creates EVMC Example VM.
*/
EVMC_EXPORT struct evmc_instance* evmc_create_example_vm(void);
EVMC_EXPORT struct evmc_vm* evmc_create_example_vm(void);
#ifdef __cplusplus
}

View File

@ -9,6 +9,6 @@
int main()
{
struct evmc_instance instance = {.abi_version = EVMC_ABI_VERSION};
return instance.abi_version - EVMC_ABI_VERSION;
struct evmc_vm vm = {.abi_version = EVMC_ABI_VERSION};
return vm.abi_version - EVMC_ABI_VERSION;
}

View File

@ -670,14 +670,14 @@ struct evmc_host_context
/* Forward declaration. */
struct evmc_instance;
struct evmc_vm;
/**
* Destroys the EVM instance.
* Destroys the VM instance.
*
* @param evm The EVM instance to be destroyed.
* @param vm The VM instance to be destroyed.
*/
typedef void (*evmc_destroy_fn)(struct evmc_instance* evm);
typedef void (*evmc_destroy_fn)(struct evmc_vm* vm);
/**
* Possible outcomes of evmc_set_option.
@ -690,19 +690,19 @@ enum evmc_set_option_result
};
/**
* Configures the EVM instance.
* Configures the VM instance.
*
* Allows modifying options of the EVM instance.
* Options:
* - code cache behavior: on, off, read-only, ...
* - optimizations,
* Allows modifying options of the VM instance.
* Options:
* - code cache behavior: on, off, read-only, ...
* - optimizations,
*
* @param evm The EVM instance to be configured.
* @param name The option name. NULL-terminated string. Cannot be NULL.
* @param value The new option value. NULL-terminated string. Cannot be NULL.
* @return The outcome of the operation.
* @param vm The VM instance to be configured.
* @param name The option name. NULL-terminated string. Cannot be NULL.
* @param value The new option value. NULL-terminated string. Cannot be NULL.
* @return The outcome of the operation.
*/
typedef enum evmc_set_option_result (*evmc_set_option_fn)(struct evmc_instance* evm,
typedef enum evmc_set_option_result (*evmc_set_option_fn)(struct evmc_vm* vm,
char const* name,
char const* value);
@ -790,18 +790,18 @@ enum evmc_revision
*
* This function MAY be invoked multiple times for a single VM instance.
*
* @param instance The VM instance. This argument MUST NOT be NULL.
* @param vm The VM instance. This argument MUST NOT be NULL.
* @param context The pointer to the Host execution context to be passed
* to the Host interface methods (::evmc_host_interface).
* This argument MUST NOT be NULL unless
* the @p instance has the ::EVMC_CAPABILITY_PRECOMPILES capability.
* the @p vm has the ::EVMC_CAPABILITY_PRECOMPILES capability.
* @param rev The requested EVM specification revision.
* @param msg The call parameters. See ::evmc_message. This argument MUST NOT be NULL.
* @param code The reference to the code to be executed. This argument MAY be NULL.
* @param code_size The length of the code. If @p code is NULL this argument MUST be 0.
* @return The execution result.
*/
typedef struct evmc_result (*evmc_execute_fn)(struct evmc_instance* instance,
typedef struct evmc_result (*evmc_execute_fn)(struct evmc_vm* vm,
struct evmc_host_context* context,
enum evmc_revision rev,
const struct evmc_message* msg,
@ -847,20 +847,20 @@ typedef uint32_t evmc_capabilities_flagset;
* Return the supported capabilities of the VM instance.
*
* This function MAY be invoked multiple times for a single VM instance,
* and its value MAY be influenced by calls to evmc_instance::set_option.
* and its value MAY be influenced by calls to evmc_vm::set_option.
*
* @param instance The EVM instance.
* @return The supported capabilities of the VM. @see evmc_capabilities.
* @param vm The VM instance.
* @return The supported capabilities of the VM. @see evmc_capabilities.
*/
typedef evmc_capabilities_flagset (*evmc_get_capabilities_fn)(struct evmc_instance* instance);
typedef evmc_capabilities_flagset (*evmc_get_capabilities_fn)(struct evmc_vm* vm);
/**
* The EVM instance.
* The VM instance.
*
* Defines the base struct of the VM implementation.
*/
struct evmc_instance
struct evmc_vm
{
/**
* EVMC ABI version implemented by the VM instance.
@ -887,14 +887,14 @@ struct evmc_instance
const char* version;
/**
* Pointer to function destroying the EVM instance.
* Pointer to function destroying the VM instance.
*
* This is a mandatory method and MUST NOT be set to NULL.
*/
evmc_destroy_fn destroy;
/**
* Pointer to function executing a code by the EVM instance.
* Pointer to function executing a code by the VM instance.
*
* This is a mandatory method and MUST NOT be set to NULL.
*/
@ -936,9 +936,9 @@ struct evmc_instance
* For example, the shared library with the "beta-interpreter" implementation may be named
* `libbeta-interpreter.so`.
*
* @return EVM instance or NULL indicating instance creation failure.
* @return The VM instance or NULL indicating instance creation failure.
*/
struct evmc_instance* evmc_create_example_vm(void);
struct evmc_vm* evmc_create_example_vm(void);
#endif
#if __cplusplus

View File

@ -334,17 +334,17 @@ public:
}
};
/// @copybrief evmc_instance
/// @copybrief evmc_vm
///
/// This is a RAII wrapper for evmc_instance and objects of this type
/// 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_instance.
explicit VM(evmc_instance* instance) noexcept : m_instance{instance} {}
/// Converting constructor from evmc_vm.
explicit VM(evmc_vm* vm) noexcept : m_instance{vm} {}
/// Destructor responsible for automatically destroying the VM instance.
~VM() noexcept
@ -369,8 +369,8 @@ public:
}
/// The constructor that captures a VM instance and configures the instance
/// with provided list of options.
inline VM(evmc_instance* 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.
@ -379,13 +379,13 @@ public:
/// 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_instance::name
/// @copydoc evmc_vm::name
char const* name() const noexcept { return m_instance->name; }
/// @copydoc evmc_instance::version
/// @copydoc evmc_vm::version
char const* version() const noexcept { return m_instance->version; }
/// @copydoc evmc::instance::get_capabilities
/// @copydoc evmc::vm::get_capabilities
evmc_capabilities_flagset get_capabilities() const noexcept
{
return m_instance->get_capabilities(m_instance);
@ -408,12 +408,12 @@ public:
}
private:
evmc_instance* m_instance = nullptr;
evmc_vm* m_instance = nullptr;
};
inline VM::VM(evmc_instance* instance,
inline VM::VM(evmc_vm* vm,
std::initializer_list<std::pair<const char*, const char*>> options) noexcept
: m_instance{instance}
: m_instance{vm}
{
for (const auto& option : options)
set_option(option.first, option.second);

View File

@ -22,36 +22,35 @@
#include <string.h>
/**
* Returns true if the VM instance has a compatible ABI version.
* Returns true if the VM has a compatible ABI version.
*/
static inline int evmc_is_abi_compatible(struct evmc_instance* instance)
static inline int evmc_is_abi_compatible(struct evmc_vm* vm)
{
return instance->abi_version == EVMC_ABI_VERSION;
return vm->abi_version == EVMC_ABI_VERSION;
}
/**
* Returns the name of the VM instance.
* Returns the name of the VM.
*/
static inline const char* evmc_vm_name(struct evmc_instance* instance)
static inline const char* evmc_vm_name(struct evmc_vm* vm)
{
return instance->name;
return vm->name;
}
/**
* Returns the version of the VM instance.
* Returns the version of the VM.
*/
static inline const char* evmc_vm_version(struct evmc_instance* instance)
static inline const char* evmc_vm_version(struct evmc_vm* vm)
{
return instance->version;
return vm->version;
}
/**
* Checks if the VM instance has the given capability.
* Checks if the VM has the given capability.
*
* @see evmc_get_capabilities_fn
*/
static inline bool evmc_vm_has_capability(struct evmc_instance* vm,
enum evmc_capabilities capability)
static inline bool evmc_vm_has_capability(struct evmc_vm* vm, enum evmc_capabilities capability)
{
return (vm->get_capabilities(vm) & (evmc_capabilities_flagset)capability) != 0;
}
@ -61,22 +60,22 @@ static inline bool evmc_vm_has_capability(struct evmc_instance* vm,
*
* @see evmc_destroy_fn
*/
static inline void evmc_destroy(struct evmc_instance* instance)
static inline void evmc_destroy(struct evmc_vm* vm)
{
instance->destroy(instance);
vm->destroy(vm);
}
/**
* Sets the option for the VM instance, if the feature is supported by the VM.
* Sets the option for the VM, if the feature is supported by the VM.
*
* @see evmc_set_option_fn
*/
static inline enum evmc_set_option_result evmc_set_option(struct evmc_instance* instance,
static inline enum evmc_set_option_result evmc_set_option(struct evmc_vm* vm,
char const* name,
char const* value)
{
if (instance->set_option)
return instance->set_option(instance, name, value);
if (vm->set_option)
return vm->set_option(vm, name, value);
return EVMC_SET_OPTION_INVALID_NAME;
}
@ -85,14 +84,14 @@ static inline enum evmc_set_option_result evmc_set_option(struct evmc_instance*
*
* @see evmc_execute_fn.
*/
static inline struct evmc_result evmc_execute(struct evmc_instance* instance,
static inline struct evmc_result evmc_execute(struct evmc_vm* vm,
struct evmc_host_context* context,
enum evmc_revision rev,
const struct evmc_message* msg,
uint8_t const* code,
size_t code_size)
{
return instance->execute(instance, context, rev, msg, code, code_size);
return vm->execute(vm, context, rev, msg, code, code_size);
}
/// The evmc_result release function using free() for releasing the memory.

View File

@ -19,7 +19,7 @@ extern "C" {
#endif
/** The function pointer type for EVMC create functions. */
typedef struct evmc_instance* (*evmc_create_fn)(void);
typedef struct evmc_vm* (*evmc_create_fn)(void);
/** Error codes for the EVMC loader. */
enum evmc_loader_error_code
@ -37,7 +37,7 @@ enum evmc_loader_error_code
EVMC_LOADER_INVALID_ARGUMENT = 3,
/** The creation of a VM instance has failed. */
EVMC_LOADER_INSTANCE_CREATION_FAILURE = 4,
EVMC_LOADER_VM_CREATION_FAILURE = 4,
/** The ABI version of the VM instance has mismatched. */
EVMC_LOADER_ABI_VERSION_MISMATCH = 5,
@ -98,7 +98,7 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
*
* This is a macro for creating the VM instance with the function returned from evmc_load().
* The function signals the same errors as evmc_load() and additionally:
* - ::EVMC_LOADER_INSTANCE_CREATION_FAILURE when the create function returns NULL,
* - ::EVMC_LOADER_VM_CREATION_FAILURE when the create function returns NULL,
* - ::EVMC_LOADER_ABI_VERSION_MISMATCH when the created VM instance has ABI version different
* from the ABI version of this library (::EVMC_ABI_VERSION).
*
@ -114,8 +114,7 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
* ::EVMC_LOADER_SUCCESS on success or any other error code as described above.
* @return The pointer to the created VM or NULL in case of error.
*/
struct evmc_instance* evmc_load_and_create(const char* filename,
enum evmc_loader_error_code* error_code);
struct evmc_vm* evmc_load_and_create(const char* filename, enum evmc_loader_error_code* error_code);
/**
* Dynamically loads the EVMC module, then creates and configures the VM instance.
@ -151,8 +150,8 @@ struct evmc_instance* evmc_load_and_create(const char* filename,
* ::EVMC_LOADER_SUCCESS on success or any other error code as described above.
* @return The pointer to the created VM or NULL in case of error.
*/
struct evmc_instance* evmc_load_and_configure(const char* config,
enum evmc_loader_error_code* error_code);
struct evmc_vm* evmc_load_and_configure(const char* config,
enum evmc_loader_error_code* error_code);
/**
* Returns the human-readable message describing the most recent error

View File

@ -196,8 +196,7 @@ const char* evmc_last_error_msg()
return m;
}
struct evmc_instance* evmc_load_and_create(const char* filename,
enum evmc_loader_error_code* error_code)
struct evmc_vm* evmc_load_and_create(const char* filename, enum evmc_loader_error_code* error_code)
{
// First load the DLL. This also resets the last_error_msg;
evmc_create_fn create_fn = evmc_load(filename, error_code);
@ -207,21 +206,21 @@ struct evmc_instance* evmc_load_and_create(const char* filename,
enum evmc_loader_error_code ec = EVMC_LOADER_SUCCESS;
struct evmc_instance* instance = create_fn();
if (!instance)
struct evmc_vm* vm = create_fn();
if (!vm)
{
ec = set_error(EVMC_LOADER_INSTANCE_CREATION_FAILURE,
"creating EVMC instance of %s has failed", filename);
ec = set_error(EVMC_LOADER_VM_CREATION_FAILURE, "creating EVMC VM of %s has failed",
filename);
goto exit;
}
if (!evmc_is_abi_compatible(instance))
if (!evmc_is_abi_compatible(vm))
{
ec = set_error(EVMC_LOADER_ABI_VERSION_MISMATCH,
"EVMC ABI version %d of %s mismatches the expected version %d",
instance->abi_version, filename, EVMC_ABI_VERSION);
evmc_destroy(instance);
instance = NULL;
vm->abi_version, filename, EVMC_ABI_VERSION);
evmc_destroy(vm);
vm = NULL;
goto exit;
}
@ -229,7 +228,7 @@ exit:
if (error_code)
*error_code = ec;
return instance;
return vm;
}
/// Gets the token delimited by @p delim character of the string pointed by the @p str_ptr.
@ -255,11 +254,10 @@ static char* get_token(char** str_ptr, char delim)
return str;
}
struct evmc_instance* evmc_load_and_configure(const char* config,
enum evmc_loader_error_code* error_code)
struct evmc_vm* evmc_load_and_configure(const char* config, enum evmc_loader_error_code* error_code)
{
enum evmc_loader_error_code ec = EVMC_LOADER_SUCCESS;
struct evmc_instance* instance = NULL;
struct evmc_vm* vm = NULL;
char config_copy_buffer[PATH_MAX_LENGTH];
if (strcpy_sx(config_copy_buffer, sizeof(config_copy_buffer), config) != 0)
@ -273,14 +271,14 @@ struct evmc_instance* evmc_load_and_configure(const char* config,
char* options = config_copy_buffer;
const char* path = get_token(&options, ',');
instance = evmc_load_and_create(path, error_code);
if (!instance)
vm = evmc_load_and_create(path, error_code);
if (!vm)
return NULL;
if (instance->set_option == NULL && strlen(options) != 0)
if (vm->set_option == NULL && strlen(options) != 0)
{
ec = set_error(EVMC_LOADER_INVALID_OPTION_NAME, "%s (%s) does not support any options",
instance->name, path);
vm->name, path);
goto exit;
}
@ -293,18 +291,18 @@ struct evmc_instance* evmc_load_and_configure(const char* config,
// The option variable will have the value, can be empty.
const char* name = get_token(&option, '=');
enum evmc_set_option_result r = instance->set_option(instance, name, option);
enum evmc_set_option_result r = vm->set_option(vm, name, option);
switch (r)
{
case EVMC_SET_OPTION_SUCCESS:
break;
case EVMC_SET_OPTION_INVALID_NAME:
ec = set_error(EVMC_LOADER_INVALID_OPTION_NAME, "%s (%s): unknown option '%s'",
instance->name, path, name);
vm->name, path, name);
goto exit;
case EVMC_SET_OPTION_INVALID_VALUE:
ec = set_error(EVMC_LOADER_INVALID_OPTION_VALUE,
"%s (%s): unsupported value '%s' for option '%s'", instance->name, path,
"%s (%s): unsupported value '%s' for option '%s'", vm->name, path,
option, name);
goto exit;
}
@ -315,9 +313,9 @@ exit:
*error_code = ec;
if (ec == EVMC_LOADER_SUCCESS)
return instance;
return vm;
if (instance)
evmc_destroy(instance);
if (vm)
evmc_destroy(vm);
return NULL;
}

View File

@ -277,10 +277,10 @@ TEST(cpp, vm)
TEST(cpp, vm_set_option)
{
evmc_instance raw_instance = {EVMC_ABI_VERSION, "", "", nullptr, nullptr, nullptr, nullptr};
raw_instance.destroy = [](evmc_instance*) {};
evmc_vm raw = {EVMC_ABI_VERSION, "", "", nullptr, nullptr, nullptr, nullptr};
raw.destroy = [](evmc_vm*) {};
auto vm = evmc::VM{&raw_instance};
auto vm = evmc::VM{&raw};
EXPECT_EQ(vm.set_option("1", "2"), EVMC_SET_OPTION_INVALID_NAME);
}
@ -294,14 +294,13 @@ TEST(cpp, vm_null)
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};
const auto template_vm = evmc_vm{
EVMC_ABI_VERSION, "", "", [](evmc_vm*) { ++destroy_counter; }, nullptr, nullptr, nullptr};
EXPECT_EQ(destroy_counter, 0);
{
auto v1 = template_instance;
auto v2 = template_instance;
auto v1 = template_vm;
auto v2 = template_vm;
auto vm1 = evmc::VM{&v1};
EXPECT_TRUE(vm1);
@ -310,7 +309,7 @@ TEST(cpp, vm_move)
}
EXPECT_EQ(destroy_counter, 2);
{
auto v1 = template_instance;
auto v1 = template_vm;
auto vm1 = evmc::VM{&v1};
EXPECT_TRUE(vm1);
@ -319,7 +318,7 @@ TEST(cpp, vm_move)
}
EXPECT_EQ(destroy_counter, 3);
{
auto v1 = template_instance;
auto v1 = template_vm;
auto vm1 = evmc::VM{&v1};
EXPECT_TRUE(vm1);
@ -334,7 +333,7 @@ TEST(cpp, vm_move)
EXPECT_EQ(destroy_counter, 4);
{
// Moving to itself will destroy the VM and reset the evmc::vm.
auto v1 = template_instance;
auto v1 = template_vm;
auto vm1 = evmc::VM{&v1};
auto& vm1_ref = vm1;

View File

@ -11,7 +11,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_instance) <= 64, "evmc_instance does not fit cache line");
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");

View File

@ -53,11 +53,9 @@ protected:
evmc_test_create_fn = fn;
}
static void destroy(evmc_instance*) noexcept { ++destroy_count; }
static void destroy(evmc_vm*) noexcept { ++destroy_count; }
static evmc_set_option_result set_option(evmc_instance*,
const char* name,
const char* value) noexcept
static evmc_set_option_result set_option(evmc_vm*, const char* name, const char* value) noexcept
{
recorded_options.push_back({name, value}); // NOLINT
@ -71,29 +69,29 @@ protected:
}
/// Creates a VM mock with only destroy() method.
static evmc_instance* create_vm_barebone()
static evmc_vm* create_vm_barebone()
{
static auto instance =
evmc_instance{EVMC_ABI_VERSION, "vm_barebone", "", destroy, nullptr, nullptr, nullptr};
evmc_vm{EVMC_ABI_VERSION, "vm_barebone", "", destroy, nullptr, nullptr, nullptr};
++create_count;
return &instance;
}
/// Creates a VM mock with ABI version different than in this project.
static evmc_instance* create_vm_with_wrong_abi()
static evmc_vm* create_vm_with_wrong_abi()
{
constexpr auto wrong_abi_version = 1985;
static_assert(wrong_abi_version != EVMC_ABI_VERSION, "");
static auto instance =
evmc_instance{wrong_abi_version, "", "", destroy, nullptr, nullptr, nullptr};
evmc_vm{wrong_abi_version, "", "", destroy, nullptr, nullptr, nullptr};
++create_count;
return &instance;
}
/// Creates a VM mock with optional set_option() method.
static evmc_instance* create_vm_with_set_option() noexcept
static evmc_vm* create_vm_with_set_option() noexcept
{
static auto instance = evmc_instance{
static auto instance = evmc_vm{
EVMC_ABI_VERSION, "vm_with_set_option", "", destroy, nullptr, nullptr, set_option};
++create_count;
return &instance;
@ -105,17 +103,17 @@ int loader::destroy_count = 0;
std::unordered_map<std::string, std::vector<std::string>> loader::supported_options;
std::vector<std::pair<std::string, std::string>> loader::recorded_options;
static evmc_instance* create_aaa()
static evmc_vm* create_aaa()
{
return (evmc_instance*)0xaaa;
return (evmc_vm*)0xaaa;
}
static evmc_instance* create_eee_bbb()
static evmc_vm* create_eee_bbb()
{
return (evmc_instance*)0xeeebbb;
return (evmc_vm*)0xeeebbb;
}
static evmc_instance* create_failure()
static evmc_vm* create_failure()
{
return nullptr;
}
@ -200,7 +198,7 @@ TEST_F(loader, load_prefix_aaa)
"unittests/double_prefix_aaa.evm",
};
const auto expected_vm_ptr = reinterpret_cast<evmc_instance*>(0xaaa);
const auto expected_vm_ptr = reinterpret_cast<evmc_vm*>(0xaaa);
for (auto& path : paths)
{
@ -219,7 +217,7 @@ TEST_F(loader, load_eee_bbb)
setup("unittests/eee-bbb.dll", "evmc_create_eee_bbb", create_eee_bbb);
evmc_loader_error_code ec;
auto fn = evmc_load(evmc_test_library_path, &ec);
const auto expected_vm_ptr = reinterpret_cast<evmc_instance*>(0xeeebbb);
const auto expected_vm_ptr = reinterpret_cast<evmc_vm*>(0xeeebbb);
ASSERT_TRUE(fn != nullptr);
EXPECT_EQ(ec, EVMC_LOADER_SUCCESS);
EXPECT_EQ(fn(), expected_vm_ptr);
@ -297,13 +295,13 @@ TEST_F(loader, load_and_create_failure)
evmc_loader_error_code ec;
auto vm = evmc_load_and_create(evmc_test_library_path, &ec);
EXPECT_TRUE(vm == nullptr);
EXPECT_EQ(ec, EVMC_LOADER_INSTANCE_CREATION_FAILURE);
EXPECT_STREQ(evmc_last_error_msg(), "creating EVMC instance of failure.vm has failed");
EXPECT_EQ(ec, EVMC_LOADER_VM_CREATION_FAILURE);
EXPECT_STREQ(evmc_last_error_msg(), "creating EVMC VM of failure.vm has failed");
EXPECT_TRUE(evmc_last_error_msg() == nullptr);
vm = evmc_load_and_create(evmc_test_library_path, nullptr);
EXPECT_TRUE(vm == nullptr);
EXPECT_STREQ(evmc_last_error_msg(), "creating EVMC instance of failure.vm has failed");
EXPECT_STREQ(evmc_last_error_msg(), "creating EVMC VM of failure.vm has failed");
}
TEST_F(loader, load_and_create_abi_mismatch)

View File

@ -6,15 +6,14 @@
#include <evmc/evmc.hpp>
#include <evmc/loader.h>
#include <iostream>
#include <memory>
evmc_instance* evmc_vm_test::vm;
evmc_vm* evmc_vm_test::vm;
evmc::VM evmc_vm_test::owned_vm;
void evmc_vm_test::init_vm(evmc_instance* owned_vm_instance) noexcept
void evmc_vm_test::init_vm(evmc_vm* _owned_vm) noexcept
{
vm = owned_vm_instance;
owned_vm = evmc::VM{owned_vm_instance};
vm = _owned_vm;
owned_vm = evmc::VM{_owned_vm};
}
class cli_parser

View File

@ -9,12 +9,12 @@
class evmc_vm_test : public ::testing::Test
{
public:
static void init_vm(evmc_instance* owned_vm_instance) noexcept;
static void init_vm(evmc_vm* owned_vm) noexcept;
protected:
/// The raw pointer to the loaded VM instance.
/// The C API is used to allow more sophisticated unit tests.
static evmc_instance* vm;
static evmc_vm* vm;
/// The C++ RAII wrapper of the loaded VM instance.
static evmc::VM owned_vm;