diff --git a/examples/capi.c b/examples/capi.c index d5298d5..aa286aa 100644 --- a/examples/capi.c +++ b/examples/capi.c @@ -112,7 +112,7 @@ static void evm_log(struct evm_context* context, const struct evm_uint160be* add printf("EVM-C: LOG%d\n", (int)topics_count); } -static const struct evm_host example_host = { +static const struct evm_context_fn_table ctx_fn_table = { account_exists, get_storage, set_storage, @@ -139,11 +139,13 @@ int main(int argc, char *argv[]) { struct evm_uint160be addr = {{0, 1, 2,}}; int64_t gas = 200000; + struct evm_context ctx = {&ctx_fn_table}; + struct evm_message msg = {addr, addr, value, input, sizeof(input), code_hash, gas, 0}; struct evm_result result = - jit->execute(jit, NULL, EVM_HOMESTEAD, &msg, code, code_size); + jit->execute(jit, &ctx, EVM_HOMESTEAD, &msg, code, code_size); printf("Execution result:\n"); if (result.code != EVM_SUCCESS) { diff --git a/examples/examplevm.c b/examples/examplevm.c index 90c6202..27a5e3c 100644 --- a/examples/examplevm.c +++ b/examples/examplevm.c @@ -1,15 +1,15 @@ +#include + +#include +#include #include #include -#include -#include struct examplevm { struct evm_instance instance; - const struct evm_host* host; - - int example_option; + int verbose; }; static void evm_destroy(struct evm_instance* evm) @@ -25,11 +25,11 @@ int evm_set_option(struct evm_instance* instance, char const* value) { struct examplevm* vm = (struct examplevm*)instance; - if (strcmp(name, "example-option") == 0) { + if (strcmp(name, "verbose") == 0) { long int v = strtol(value, NULL, 0); if (v > INT_MAX || v < INT_MIN) return 0; - vm->example_option = (int)v; + vm->verbose = (int)v; return 1; } @@ -77,7 +77,7 @@ static struct evm_result execute(struct evm_instance* instance, const char counter[] = "600160005401600055"; if (code_size == strlen(return_address) && - strncmp((const char*)code, return_address, code_size)) { + strncmp((const char*)code, return_address, code_size) == 0) { static const size_t address_size = sizeof(msg->address); uint8_t* output_data = (uint8_t*)malloc(address_size); if (!output_data) { @@ -93,12 +93,12 @@ static struct evm_result execute(struct evm_instance* instance, return ret; } else if (code_size == strlen(counter) && - strncmp((const char*)code, counter, code_size)) { + strncmp((const char*)code, counter, code_size) == 0) { struct evm_uint256be value; const struct evm_uint256be index = {{0,}}; - vm->host->get_storage(&value, context, &msg->address, &index); + context->fn_table->get_storage(&value, context, &msg->address, &index); value.bytes[31] += 1; - vm->host->set_storage(context, &msg->address, &index, &value); + context->fn_table->set_storage(context, &msg->address, &index, &value); ret.code = EVM_SUCCESS; return ret; } @@ -107,6 +107,9 @@ static struct evm_result execute(struct evm_instance* instance, ret.code = EVM_FAILURE; ret.gas_left = 0; + if (vm->verbose) + printf("Execution done.\n"); + return ret; } diff --git a/include/evm.h b/include/evm.h index b607aeb..57af669 100644 --- a/include/evm.h +++ b/include/evm.h @@ -98,8 +98,8 @@ typedef void (*evm_get_block_hash_fn)(struct evm_uint256be* result, struct evm_context* context, int64_t number); -/// The execution result code. -enum evm_result_code { +/// The execution status code. +enum evm_status_code { EVM_SUCCESS = 0, ///< Execution finished with success. EVM_FAILURE = 1, ///< Generic execution failure. EVM_OUT_OF_GAS = 2, @@ -107,7 +107,7 @@ enum evm_result_code { EVM_BAD_JUMP_DESTINATION = 4, EVM_STACK_OVERFLOW = 5, EVM_STACK_UNDERFLOW = 6, - EVM_REVERT = 7, ///< Execution terminated with REVERT opcode. + EVM_REVERT = 7, ///< Execution terminated with REVERT opcode. /// EVM implementation internal error. /// @@ -132,7 +132,7 @@ typedef void (*evm_release_result_fn)(struct evm_result const* result); struct evm_result { /// The execution result code. /// FIXME: Rename to 'status' or 'status_code'. - enum evm_result_code code; + enum evm_status_code code; /// The amount of gas left after the execution. /// @@ -295,13 +295,13 @@ typedef void (*evm_call_fn)(struct evm_result* result, struct evm_context* context, const struct evm_message* msg); -/// The Host interface. +/// The context interface. /// /// The set of all callback functions expected by EVM instances. This is C -/// realisation of OOP interface (only virtual methods, no data). +/// realisation of vtable for OOP interface (only virtual methods, no data). /// Host implementations SHOULD create constant singletons of this (similarly /// to vtables) to lower the maintenance and memory management cost. -struct evm_host { +struct evm_context_fn_table { evm_account_exists_fn account_exists; evm_get_storage_fn get_storage; evm_set_storage_fn set_storage; @@ -325,8 +325,8 @@ struct evm_host { /// Optionally, The Host MAY include in the context additional data. struct evm_context { - /// Function table defining the context interface. - const struct evm_host* fn_table; + /// Function table defining the context interface (vtable). + const struct evm_context_fn_table* fn_table; }; @@ -434,6 +434,8 @@ struct evm_instance { /// /// For future use to detect ABI incompatibilities. The EVM-C ABI version /// represented by this file is in ::EVM_ABI_VERSION. + /// + /// @todo Consider removing this field. const int abi_version; /// Pointer to function destroying the EVM instance. @@ -467,7 +469,6 @@ struct evm_instance { /// /// @return EVM instance. /// @todo Specify if this function can return null pointer to indicate error. -/// @todo Can we return const pointer? struct evm_instance* examplevm_create(void);