From dc495408beaecff343a66ccc531d148a6a01b754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Sat, 8 Sep 2018 18:23:27 +0200 Subject: [PATCH] Improve EVMC capabilities --- examples/example_vm.c | 7 +++++++ include/evmc/evmc.h | 21 ++++++++++++++------- include/evmc/helpers.h | 11 +++++++++++ test/vmtester/tests.cpp | 7 +++++++ 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/examples/example_vm.c b/examples/example_vm.c index 622c26b..6af5841 100644 --- a/examples/example_vm.c +++ b/examples/example_vm.c @@ -28,6 +28,12 @@ static void destroy(struct evmc_instance* evm) free(evm); } +static evmc_capabilities_flagset get_capabilities(struct evmc_instance* vm) +{ + (void)vm; + return EVMC_CAPABILITY_EVM1 | EVMC_CAPABILITY_EWASM; +} + /// Example options. /// /// VMs are allowed to omit this function implementation. @@ -150,6 +156,7 @@ struct evmc_instance* evmc_create_example_vm() .version = STR(PROJECT_VERSION), .destroy = destroy, .execute = execute, + .get_capabilites = get_capabilities, .set_option = set_option, .set_tracer = set_tracer, }; diff --git a/include/evmc/evmc.h b/include/evmc/evmc.h index f7879c9..51496ef 100644 --- a/include/evmc/evmc.h +++ b/include/evmc/evmc.h @@ -768,20 +768,27 @@ typedef struct evmc_result (*evmc_execute_fn)(struct evmc_instance* instance, */ enum evmc_capabilities { - EVMC_CAPABILITY_EVM1 = 1, /**< The VM is capable of executing EVM1 bytecode. */ - EVMC_CAPABILITY_EWASM = 2 /**< The VM is capable of execution ewasm bytecode. */ + EVMC_CAPABILITY_EVM1 = (1u << 0), /**< The VM is capable of executing EVM1 bytecode. */ + EVMC_CAPABILITY_EWASM = (1u << 1) /**< The VM is capable of execution ewasm bytecode. */ }; +/** + * Alias for unsigned integer representing a set of bit flags of EVMC capabilities. + * + * @see evmc_capabilities + */ +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 set_option. + * and its value MAY be influenced by calls to evmc_instance::set_option. * - * @param instance The EVM instance. - * @return The supported capabilities of the VM, @see ::evmc_capabilities. + * @param instance The EVM instance. + * @return The supported capabilities of the VM. @see evmc_capabilities. */ -typedef int (*evmc_get_capabilities_fn)(struct evmc_instance* instance); +typedef evmc_capabilities_flagset (*evmc_get_capabilities_fn)(struct evmc_instance* instance); /** The opaque type representing a Client-side tracer object. */ struct evmc_tracer_context; @@ -890,7 +897,7 @@ struct evmc_instance evmc_execute_fn execute; /** - * Pointer to function returning capabilities supported by the EVM instance. + * Pointer to function returning capabilities supported by the VM instance. * * The value returned might change when different options are requested via set_option. * diff --git a/include/evmc/helpers.h b/include/evmc/helpers.h index a9ecd5f..601fa84 100644 --- a/include/evmc/helpers.h +++ b/include/evmc/helpers.h @@ -41,6 +41,17 @@ static inline const char* evmc_vm_version(struct evmc_instance* instance) return instance->version; } +/** + * Checks if the VM instance has the given capability. + * + * @see evmc_get_capabilities_fn + */ +static inline bool evmc_vm_has_capability(struct evmc_instance* vm, + enum evmc_capabilities capability) +{ + return (vm->get_capabilites(vm) & (evmc_capabilities_flagset)capability) != 0; +} + /** * Destroys the VM instance. * diff --git a/test/vmtester/tests.cpp b/test/vmtester/tests.cpp index c844394..cebcef6 100644 --- a/test/vmtester/tests.cpp +++ b/test/vmtester/tests.cpp @@ -117,3 +117,10 @@ TEST_F(evmc_vm_test, set_tracer) if (vm->set_tracer) vm->set_tracer(vm, tracer_callback, nullptr); } + +TEST_F(evmc_vm_test, capabilities) +{ + // The VM should have at least one of EVM1 or EWASM capabilities. + EXPECT_TRUE(evmc_vm_has_capability(vm, EVMC_CAPABILITY_EVM1) || + evmc_vm_has_capability(vm, EVMC_CAPABILITY_EWASM)); +}