diff --git a/examples/capi.c b/examples/capi.c index cb66ee0..1499c36 100644 --- a/examples/capi.c +++ b/examples/capi.c @@ -93,6 +93,6 @@ int main(int argc, char *argv[]) { printf("\n"); } - intf.release_result(&result); + result.release(&result); intf.destroy(jit); } diff --git a/examples/examplevm.c b/examples/examplevm.c index 4569fa4..c000dd9 100644 --- a/examples/examplevm.c +++ b/examples/examplevm.c @@ -40,6 +40,10 @@ int evm_set_option(struct evm_instance* evm, return 0; } +static void evm_release_result(struct evm_result const* result) +{ +} + static struct evm_result evm_execute(struct evm_instance* instance, struct evm_env* env, enum evm_mode mode, @@ -57,16 +61,13 @@ static struct evm_result evm_execute(struct evm_instance* instance, // Execute code and refer to callbacks: instance->query_fn() + ret.release = evm_release_result; ret.code = EVM_FAILURE; ret.gas_left = 0; return ret; } -static void evm_release_result(struct evm_result const* result) -{ -} - struct evm_interface examplevm_get_interface() { struct evm_interface intf; @@ -75,7 +76,6 @@ struct evm_interface examplevm_get_interface() intf.create = evm_create; intf.destroy = evm_destroy; intf.execute = evm_execute; - intf.release_result = evm_release_result; intf.set_option = evm_set_option; return intf; } \ No newline at end of file diff --git a/include/evm.h b/include/evm.h index d3d9880..2c15fea 100644 --- a/include/evm.h +++ b/include/evm.h @@ -55,6 +55,18 @@ enum evm_result_code { EVM_STACK_UNDERFLOW = 6, }; +struct evm_result; + +/// Releases resources assigned to an execution result. +/// +/// This function releases memory (and other resources, if any) assigned to the +/// specified execution result making the result object invalid. +/// +/// @param result The execution result which resource are to be released. The +/// result itself it not modified by this function, but becomes +/// invalid and user should discard it as well. +typedef void (*evm_release_result_fn)(struct evm_result const* result); + /// The EVM code execution result. struct evm_result { /// The execution result code. @@ -65,24 +77,44 @@ struct evm_result { /// The value is valid only if evm_result::code == ::EVM_SUCCESS. int64_t gas_left; - /// The reference to output data. The memory containing the output data - /// is owned by EVM and is freed with evm_release_result_fn(). - uint8_t const* output_data; + union + { + struct + { + /// The reference to output data. The memory containing the output + /// data is owned by EVM and is freed with evm_result::release(). + uint8_t const* output_data; - /// The size of the output data. - size_t output_size; + /// The size of the output data. + size_t output_size; + }; + + /// The address of the successfully created contract. + /// + /// This field has valid value only if the evm_result comes from a + /// successful CREATE opcode execution + /// (i.e. evm_call_fn(..., EVM_CREATE, ...)). + struct evm_uint160be create_address; + }; + + /// The pointer to the result release implementation. + /// + /// This function pointer must be set by the VM implementation and works + /// similary to C++ virtual destructor. Attaching the releaser to the result + /// itself allows VM composition. + evm_release_result_fn release; /// @name Optional /// The optional information that EVM is not required to provide. /// @{ + /// The error message explaining the result code. + char const* error_message; + /// The pointer to EVM-owned memory. For EVM internal use. /// @see output_data. void* internal_memory; - /// The error message explaining the result code. - char const* error_message; - /// @} }; @@ -370,15 +402,6 @@ typedef struct evm_result (*evm_execute_fn)(struct evm_instance* instance, size_t input_size, struct evm_uint256be value); -/// Releases resources assigned to an execution result. -/// -/// This function releases memory (and other resources, if any) assigned to the -/// specified execution result making the result object invalid. -/// -/// @param result The execution result which resource are to be released. The -/// result itself it not modified by this function, but becomes -/// invalid and user should discard it as well. -typedef void (*evm_release_result_fn)(struct evm_result const* result); /// Status of a code in VM. Useful for JIT-like implementations. enum evm_code_status { @@ -427,9 +450,6 @@ struct evm_interface { /// Pointer to function execuing a code in a VM. evm_execute_fn execute; - /// Pointer to function releasing an execution result. - evm_release_result_fn release_result; - /// Optional pointer to function returning a status of a code. /// /// If the VM does not support this feature the pointer can be NULL.