mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #7655 from ethereum/evmc7
Update to EVMC7 and evmone 0.3.0
This commit is contained in:
		
						commit
						e383b2bbba
					
				| @ -11,7 +11,7 @@ docker build -t ethereum/solidity-buildpack-deps:ubuntu1904-<revision> -f Docker | ||||
| docker push ethereum/solidity-buildpack-deps:ubuntu1904-<revision> | ||||
| ``` | ||||
| 
 | ||||
| The current revision is `1`. | ||||
| The current revision is `2`. | ||||
| 
 | ||||
| Once the docker image has been built and pushed to Dockerhub, you can find it at: | ||||
| 
 | ||||
|  | ||||
| @ -106,7 +106,7 @@ defaults: | ||||
| 
 | ||||
|   - test_ubuntu1904_clang: &test_ubuntu1904_clang | ||||
|       docker: | ||||
|         - image: ethereum/solidity-buildpack-deps:ubuntu1904-clang-1 | ||||
|         - image: ethereum/solidity-buildpack-deps:ubuntu1904-clang-2 | ||||
|       steps: | ||||
|         - checkout | ||||
|         - attach_workspace: | ||||
| @ -117,7 +117,7 @@ defaults: | ||||
| 
 | ||||
|   - test_ubuntu1904: &test_ubuntu1904 | ||||
|       docker: | ||||
|         - image: ethereum/solidity-buildpack-deps:ubuntu1904-1 | ||||
|         - image: ethereum/solidity-buildpack-deps:ubuntu1904-2 | ||||
|       steps: | ||||
|         - checkout | ||||
|         - attach_workspace: | ||||
| @ -287,7 +287,7 @@ jobs: | ||||
| 
 | ||||
|   b_ubu_clang: &build_ubuntu1904_clang | ||||
|     docker: | ||||
|       - image: ethereum/solidity-buildpack-deps:ubuntu1904-clang-1 | ||||
|       - image: ethereum/solidity-buildpack-deps:ubuntu1904-clang-2 | ||||
|     environment: | ||||
|       CC: clang | ||||
|       CXX: clang++ | ||||
| @ -299,7 +299,7 @@ jobs: | ||||
| 
 | ||||
|   b_ubu: &build_ubuntu1904 | ||||
|     docker: | ||||
|       - image: ethereum/solidity-buildpack-deps:ubuntu1904-1 | ||||
|       - image: ethereum/solidity-buildpack-deps:ubuntu1904-2 | ||||
|     steps: | ||||
|       - checkout | ||||
|       - run: *run_build | ||||
| @ -313,7 +313,7 @@ jobs: | ||||
| 
 | ||||
|   b_ubu18: &build_ubuntu1804 | ||||
|     docker: | ||||
|       - image: ethereum/solidity-buildpack-deps:ubuntu1804-1 | ||||
|       - image: ethereum/solidity-buildpack-deps:ubuntu1804-2 | ||||
|     environment: | ||||
|       CMAKE_OPTIONS: -DCMAKE_CXX_FLAGS=-O2 | ||||
|       CMAKE_BUILD_TYPE: RelWithDebugInfo | ||||
| @ -519,7 +519,7 @@ jobs: | ||||
| 
 | ||||
|   b_docs: | ||||
|     docker: | ||||
|       - image: ethereum/solidity-buildpack-deps:ubuntu1904-1 | ||||
|       - image: ethereum/solidity-buildpack-deps:ubuntu1904-2 | ||||
|     steps: | ||||
|       - checkout | ||||
|       - run: *setup_prerelease_commit_hash | ||||
| @ -544,7 +544,7 @@ jobs: | ||||
| 
 | ||||
|   t_ubu_cli: &t_ubu_cli | ||||
|     docker: | ||||
|       - image: ethereum/solidity-buildpack-deps:ubuntu1904-1 | ||||
|       - image: ethereum/solidity-buildpack-deps:ubuntu1904-2 | ||||
|     environment: | ||||
|       TERM: xterm | ||||
|     steps: | ||||
|  | ||||
| @ -92,7 +92,7 @@ RUN set -ex; \ | ||||
| # EVMONE | ||||
| RUN set -ex; \ | ||||
| 	cd /usr/src; \ | ||||
| 	git clone --branch="v0.2.0" --recurse-submodules https://github.com/ethereum/evmone.git; \ | ||||
| 	git clone --branch="v0.3.0" --recurse-submodules https://github.com/ethereum/evmone.git; \ | ||||
| 	cd evmone; \ | ||||
| 	mkdir build; \ | ||||
| 	cd build; \ | ||||
| @ -109,4 +109,4 @@ RUN set -ex; \ | ||||
| FROM base | ||||
| COPY --from=libraries /usr/lib /usr/lib | ||||
| COPY --from=libraries /usr/bin /usr/bin | ||||
| COPY --from=libraries /usr/include /usr/include | ||||
| COPY --from=libraries /usr/include /usr/include | ||||
|  | ||||
| @ -75,9 +75,9 @@ RUN set -ex; \ | ||||
| 	rm -rf /var/lib/libfuzzer | ||||
| 
 | ||||
| # EVMONE | ||||
| ARG EVMONE_HASH="81488656a53ae1bbf186d33fc69a4f5c59d3d7419b1ba1b4832a0d409b1a33bf" | ||||
| ARG EVMONE_HASH="fa4f40daf7cf9ccbcca6c78345977e084ea2136a8eae661e4d19471be852b15b" | ||||
| ARG EVMONE_MAJOR="0" | ||||
| ARG EVMONE_MINOR="2" | ||||
| ARG EVMONE_MINOR="3" | ||||
| ARG EVMONE_MICRO="0" | ||||
| RUN set -ex; \ | ||||
| 	EVMONE_VERSION="$EVMONE_MAJOR.$EVMONE_MINOR.$EVMONE_MICRO"; \ | ||||
|  | ||||
| @ -77,7 +77,7 @@ RUN set -ex; \ | ||||
| # EVMONE | ||||
| RUN set -ex; \ | ||||
| 	cd /usr/src; \ | ||||
| 	git clone --branch="v0.2.0" --recurse-submodules https://github.com/ethereum/evmone.git; \ | ||||
| 	git clone --branch="v0.3.0" --recurse-submodules https://github.com/ethereum/evmone.git; \ | ||||
| 	cd evmone; \ | ||||
| 	mkdir build; \ | ||||
| 	cd build; \ | ||||
|  | ||||
| @ -35,17 +35,17 @@ using namespace dev; | ||||
| using namespace dev::test; | ||||
| 
 | ||||
| 
 | ||||
| evmc::vm* EVMHost::getVM(string const& _path) | ||||
| evmc::VM* EVMHost::getVM(string const& _path) | ||||
| { | ||||
| 	static unique_ptr<evmc::vm> theVM; | ||||
| 	static unique_ptr<evmc::VM> theVM; | ||||
| 	if (!theVM && !_path.empty()) | ||||
| 	{ | ||||
| 		evmc_loader_error_code errorCode = {}; | ||||
| 		evmc_instance* vm = evmc_load_and_configure(_path.c_str(), &errorCode); | ||||
| 		evmc_vm* vm = evmc_load_and_configure(_path.c_str(), &errorCode); | ||||
| 		if (vm && errorCode == EVMC_LOADER_SUCCESS) | ||||
| 		{ | ||||
| 			if (evmc_vm_has_capability(vm, EVMC_CAPABILITY_EVM1)) | ||||
| 				theVM = make_unique<evmc::vm>(vm); | ||||
| 				theVM = make_unique<evmc::VM>(vm); | ||||
| 			else | ||||
| 			{ | ||||
| 				evmc_destroy(vm); | ||||
| @ -63,7 +63,7 @@ evmc::vm* EVMHost::getVM(string const& _path) | ||||
| 	return theVM.get(); | ||||
| } | ||||
| 
 | ||||
| EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::vm* _vm): | ||||
| EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM* _vm): | ||||
| 	m_vm(_vm) | ||||
| { | ||||
| 	if (!m_vm) | ||||
| @ -83,7 +83,7 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::vm* _vm): | ||||
| 	else if (_evmVersion == langutil::EVMVersion::constantinople()) | ||||
| 		m_evmVersion = EVMC_CONSTANTINOPLE; | ||||
| 	else if (_evmVersion == langutil::EVMVersion::istanbul()) | ||||
| 		assertThrow(false, Exception, "Istanbul is not supported yet."); | ||||
| 		m_evmVersion = EVMC_ISTANBUL; | ||||
| 	else if (_evmVersion == langutil::EVMVersion::berlin()) | ||||
| 		assertThrow(false, Exception, "Berlin is not supported yet."); | ||||
| 	else //if (_evmVersion == langutil::EVMVersion::petersburg())
 | ||||
| @ -227,6 +227,8 @@ evmc_tx_context EVMHost::get_tx_context() noexcept | ||||
| 	ctx.block_gas_limit = 20000000; | ||||
| 	ctx.tx_gas_price = convertToEVMC(u256("3000000000")); | ||||
| 	ctx.tx_origin = convertToEVMC(Address("0x9292929292929292929292929292929292929292")); | ||||
| 	// Mainnet according to EIP-155
 | ||||
| 	ctx.chain_id = convertToEVMC(u256(1)); | ||||
| 	return ctx; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -40,9 +40,9 @@ public: | ||||
| 	/// Tries to dynamically load libevmone. @returns nullptr on failure.
 | ||||
| 	/// The path has to be provided for the first successful run and will be ignored
 | ||||
| 	/// afterwards.
 | ||||
| 	static evmc::vm* getVM(std::string const& _path = {}); | ||||
| 	static evmc::VM* getVM(std::string const& _path = {}); | ||||
| 
 | ||||
| 	explicit EVMHost(langutil::EVMVersion _evmVersion, evmc::vm* _vm = getVM()); | ||||
| 	explicit EVMHost(langutil::EVMVersion _evmVersion, evmc::VM* _vm = getVM()); | ||||
| 
 | ||||
| 	struct Account | ||||
| 	{ | ||||
| @ -179,7 +179,7 @@ private: | ||||
| 	/// @note The return value is only valid as long as @a _data is alive!
 | ||||
| 	static evmc::result resultWithGas(evmc_message const& _message, bytes const& _data) noexcept; | ||||
| 
 | ||||
| 	evmc::vm* m_vm = nullptr; | ||||
| 	evmc::VM* m_vm = nullptr; | ||||
| 	evmc_revision m_evmVersion; | ||||
| }; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										291
									
								
								test/evmc/evmc.h
									
									
									
									
									
								
							
							
						
						
									
										291
									
								
								test/evmc/evmc.h
									
									
									
									
									
								
							| @ -44,7 +44,7 @@ enum | ||||
|      * | ||||
|      * @see @ref versioning | ||||
|      */ | ||||
|     EVMC_ABI_VERSION = 6 | ||||
|     EVMC_ABI_VERSION = 7 | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| @ -153,9 +153,15 @@ struct evmc_tx_context | ||||
|     int64_t block_timestamp;         /**< The block timestamp. */ | ||||
|     int64_t block_gas_limit;         /**< The block gas limit. */ | ||||
|     evmc_uint256be block_difficulty; /**< The block difficulty. */ | ||||
|     evmc_uint256be chain_id;         /**< The blockchain's ChainID. */ | ||||
| }; | ||||
| 
 | ||||
| struct evmc_context; | ||||
| /**
 | ||||
|  * @struct evmc_host_context | ||||
|  * The opaque data type representing the Host execution context. | ||||
|  * @see evmc_execute_fn(). | ||||
|  */ | ||||
| struct evmc_host_context; | ||||
| 
 | ||||
| /**
 | ||||
|  * Get transaction context callback function. | ||||
| @ -166,7 +172,7 @@ struct evmc_context; | ||||
|  *  @param      context  The pointer to the Host execution context. | ||||
|  *  @return              The transaction context. | ||||
|  */ | ||||
| typedef struct evmc_tx_context (*evmc_get_tx_context_fn)(struct evmc_context* context); | ||||
| typedef struct evmc_tx_context (*evmc_get_tx_context_fn)(struct evmc_host_context* context); | ||||
| 
 | ||||
| /**
 | ||||
|  * Get block hash callback function. | ||||
| @ -180,7 +186,7 @@ typedef struct evmc_tx_context (*evmc_get_tx_context_fn)(struct evmc_context* co | ||||
|  * @return         The block hash or null bytes | ||||
|  *                 if the information about the block is not available. | ||||
|  */ | ||||
| typedef evmc_bytes32 (*evmc_get_block_hash_fn)(struct evmc_context* context, int64_t number); | ||||
| typedef evmc_bytes32 (*evmc_get_block_hash_fn)(struct evmc_host_context* context, int64_t number); | ||||
| 
 | ||||
| /**
 | ||||
|  * The execution status code. | ||||
| @ -420,7 +426,8 @@ struct evmc_result | ||||
|  * @param address  The address of the account the query is about. | ||||
|  * @return         true if exists, false otherwise. | ||||
|  */ | ||||
| typedef bool (*evmc_account_exists_fn)(struct evmc_context* context, const evmc_address* address); | ||||
| typedef bool (*evmc_account_exists_fn)(struct evmc_host_context* context, | ||||
|                                        const evmc_address* address); | ||||
| 
 | ||||
| /**
 | ||||
|  * Get storage callback function. | ||||
| @ -433,7 +440,7 @@ typedef bool (*evmc_account_exists_fn)(struct evmc_context* context, const evmc_ | ||||
|  * @return         The storage value at the given storage key or null bytes | ||||
|  *                 if the account does not exist. | ||||
|  */ | ||||
| typedef evmc_bytes32 (*evmc_get_storage_fn)(struct evmc_context* context, | ||||
| typedef evmc_bytes32 (*evmc_get_storage_fn)(struct evmc_host_context* context, | ||||
|                                             const evmc_address* address, | ||||
|                                             const evmc_bytes32* key); | ||||
| 
 | ||||
| @ -492,7 +499,7 @@ enum evmc_storage_status | ||||
|  * @param value    The value to be stored. | ||||
|  * @return         The effect on the storage item. | ||||
|  */ | ||||
| typedef enum evmc_storage_status (*evmc_set_storage_fn)(struct evmc_context* context, | ||||
| typedef enum evmc_storage_status (*evmc_set_storage_fn)(struct evmc_host_context* context, | ||||
|                                                         const evmc_address* address, | ||||
|                                                         const evmc_bytes32* key, | ||||
|                                                         const evmc_bytes32* value); | ||||
| @ -506,7 +513,7 @@ typedef enum evmc_storage_status (*evmc_set_storage_fn)(struct evmc_context* con | ||||
|  * @param address  The address of the account. | ||||
|  * @return         The balance of the given account or 0 if the account does not exist. | ||||
|  */ | ||||
| typedef evmc_uint256be (*evmc_get_balance_fn)(struct evmc_context* context, | ||||
| typedef evmc_uint256be (*evmc_get_balance_fn)(struct evmc_host_context* context, | ||||
|                                               const evmc_address* address); | ||||
| 
 | ||||
| /**
 | ||||
| @ -519,7 +526,8 @@ typedef evmc_uint256be (*evmc_get_balance_fn)(struct evmc_context* context, | ||||
|  * @param address  The address of the account. | ||||
|  * @return         The size of the code in the account or 0 if the account does not exist. | ||||
|  */ | ||||
| typedef size_t (*evmc_get_code_size_fn)(struct evmc_context* context, const evmc_address* address); | ||||
| typedef size_t (*evmc_get_code_size_fn)(struct evmc_host_context* context, | ||||
|                                         const evmc_address* address); | ||||
| 
 | ||||
| /**
 | ||||
|  * Get code size callback function. | ||||
| @ -532,28 +540,27 @@ typedef size_t (*evmc_get_code_size_fn)(struct evmc_context* context, const evmc | ||||
|  * @param address  The address of the account. | ||||
|  * @return         The hash of the code in the account or null bytes if the account does not exist. | ||||
|  */ | ||||
| typedef evmc_bytes32 (*evmc_get_code_hash_fn)(struct evmc_context* context, | ||||
| typedef evmc_bytes32 (*evmc_get_code_hash_fn)(struct evmc_host_context* context, | ||||
|                                               const evmc_address* address); | ||||
| 
 | ||||
| /**
 | ||||
|  * Copy code callback function. | ||||
|  * | ||||
|  *  This callback function is used by an EVM to request a copy of the code | ||||
|  *  of the given account to the memory buffer provided by the EVM. | ||||
|  *  The Client MUST copy the requested code, starting with the given offset, | ||||
|  *  to the provided memory buffer up to the size of the buffer or the size of | ||||
|  *  the code, whichever is smaller. | ||||
|  * This callback function is used by an EVM to request a copy of the code | ||||
|  * of the given account to the memory buffer provided by the EVM. | ||||
|  * The Client MUST copy the requested code, starting with the given offset, | ||||
|  * to the provided memory buffer up to the size of the buffer or the size of | ||||
|  * the code, whichever is smaller. | ||||
|  * | ||||
|  *  @param context      The pointer to the Client execution context. | ||||
|  *                           @see ::evmc_context. | ||||
|  *  @param address      The address of the account. | ||||
|  *  @param code_offset  The offset of the code to copy. | ||||
|  *  @param buffer_data  The pointer to the memory buffer allocated by the EVM | ||||
|  *                      to store a copy of the requested code. | ||||
|  *  @param buffer_size  The size of the memory buffer. | ||||
|  *  @return             The number of bytes copied to the buffer by the Client. | ||||
|  * @param context      The pointer to the Host execution context. See ::evmc_host_context. | ||||
|  * @param address      The address of the account. | ||||
|  * @param code_offset  The offset of the code to copy. | ||||
|  * @param buffer_data  The pointer to the memory buffer allocated by the EVM | ||||
|  *                     to store a copy of the requested code. | ||||
|  * @param buffer_size  The size of the memory buffer. | ||||
|  * @return             The number of bytes copied to the buffer by the Client. | ||||
|  */ | ||||
| typedef size_t (*evmc_copy_code_fn)(struct evmc_context* context, | ||||
| typedef size_t (*evmc_copy_code_fn)(struct evmc_host_context* context, | ||||
|                                     const evmc_address* address, | ||||
|                                     size_t code_offset, | ||||
|                                     uint8_t* buffer_data, | ||||
| @ -562,34 +569,31 @@ typedef size_t (*evmc_copy_code_fn)(struct evmc_context* context, | ||||
| /**
 | ||||
|  * Selfdestruct callback function. | ||||
|  * | ||||
|  *  This callback function is used by an EVM to SELFDESTRUCT given contract. | ||||
|  *  The execution of the contract will not be stopped, that is up to the EVM. | ||||
|  * This callback function is used by an EVM to SELFDESTRUCT given contract. | ||||
|  * The execution of the contract will not be stopped, that is up to the EVM. | ||||
|  * | ||||
|  *  @param context      The pointer to the Host execution context. | ||||
|  *                      @see ::evmc_context. | ||||
|  *  @param address      The address of the contract to be selfdestructed. | ||||
|  *  @param beneficiary  The address where the remaining ETH is going to be | ||||
|  *                      transferred. | ||||
|  * @param context      The pointer to the Host execution context. See ::evmc_host_context. | ||||
|  * @param address      The address of the contract to be selfdestructed. | ||||
|  * @param beneficiary  The address where the remaining ETH is going to be transferred. | ||||
|  */ | ||||
| typedef void (*evmc_selfdestruct_fn)(struct evmc_context* context, | ||||
| typedef void (*evmc_selfdestruct_fn)(struct evmc_host_context* context, | ||||
|                                      const evmc_address* address, | ||||
|                                      const evmc_address* beneficiary); | ||||
| 
 | ||||
| /**
 | ||||
|  * Log callback function. | ||||
|  * | ||||
|  *  This callback function is used by an EVM to inform about a LOG that happened | ||||
|  *  during an EVM bytecode execution. | ||||
|  *  @param context       The pointer to the Host execution context. | ||||
|  *                       @see ::evmc_context. | ||||
|  *  @param address       The address of the contract that generated the log. | ||||
|  *  @param data          The pointer to unindexed data attached to the log. | ||||
|  *  @param data_size     The length of the data. | ||||
|  *  @param topics        The pointer to the array of topics attached to the log. | ||||
|  *  @param topics_count  The number of the topics. Valid values are between | ||||
|  *                       0 and 4 inclusively. | ||||
|  * This callback function is used by an EVM to inform about a LOG that happened | ||||
|  * during an EVM bytecode execution. | ||||
|  * | ||||
|  * @param context       The pointer to the Host execution context. See ::evmc_host_context. | ||||
|  * @param address       The address of the contract that generated the log. | ||||
|  * @param data          The pointer to unindexed data attached to the log. | ||||
|  * @param data_size     The length of the data. | ||||
|  * @param topics        The pointer to the array of topics attached to the log. | ||||
|  * @param topics_count  The number of the topics. Valid values are between 0 and 4 inclusively. | ||||
|  */ | ||||
| typedef void (*evmc_emit_log_fn)(struct evmc_context* context, | ||||
| typedef void (*evmc_emit_log_fn)(struct evmc_host_context* context, | ||||
|                                  const evmc_address* address, | ||||
|                                  const uint8_t* data, | ||||
|                                  size_t data_size, | ||||
| @ -599,11 +603,11 @@ typedef void (*evmc_emit_log_fn)(struct evmc_context* context, | ||||
| /**
 | ||||
|  * Pointer to the callback function supporting EVM calls. | ||||
|  * | ||||
|  * @param  context The pointer to the Host execution context. | ||||
|  * @param  msg     The call parameters. | ||||
|  * @param context  The pointer to the Host execution context. | ||||
|  * @param msg      The call parameters. | ||||
|  * @return         The result of the call. | ||||
|  */ | ||||
| typedef struct evmc_result (*evmc_call_fn)(struct evmc_context* context, | ||||
| typedef struct evmc_result (*evmc_call_fn)(struct evmc_host_context* context, | ||||
|                                            const struct evmc_message* msg); | ||||
| 
 | ||||
| /**
 | ||||
| @ -654,31 +658,15 @@ struct evmc_host_interface | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Execution context managed by the Host. | ||||
|  * | ||||
|  * The Host MUST pass the pointer to the execution context to ::evmc_execute_fn. | ||||
|  * The VM MUST pass the same pointer back to the Host in every callback function. | ||||
|  * The context MUST contain at least the function table defining | ||||
|  * the context callback interface. | ||||
|  * Optionally, the Host MAY include in the context additional data. | ||||
|  */ | ||||
| struct evmc_context | ||||
| { | ||||
|     /** The Host interface. */ | ||||
|     const struct evmc_host_interface* host; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /* 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. | ||||
| @ -691,19 +679,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); | ||||
| 
 | ||||
| @ -762,6 +750,7 @@ enum evmc_revision | ||||
|      * The Petersburg revision. | ||||
|      * | ||||
|      * Other names: Constantinople2, ConstantinopleFix. | ||||
|      * | ||||
|      * https://eips.ethereum.org/EIPS/eip-1716
 | ||||
|      */ | ||||
|     EVMC_PETERSBURG = 6, | ||||
| @ -773,23 +762,15 @@ enum evmc_revision | ||||
|      */ | ||||
|     EVMC_ISTANBUL = 7, | ||||
| 
 | ||||
|     /**
 | ||||
|      * The Berlin revision. | ||||
|      * | ||||
|      * The spec draft: https://eips.ethereum.org/EIPS/eip-2070.
 | ||||
|      */ | ||||
|     EVMC_BERLIN = 8, | ||||
| 
 | ||||
|     /** The maximum EVM revision supported. */ | ||||
|     EVMC_MAX_REVISION = EVMC_ISTANBUL, | ||||
| 
 | ||||
| 
 | ||||
|     /**
 | ||||
|      * Reserved for the post-Constantinople upgrade. | ||||
|      * | ||||
|      * @deprecated Replaced with ::EVMC_PETERSBURG. | ||||
|      */ | ||||
|     EVMC_CONSTANTINOPLE2 EVMC_DEPRECATED = EVMC_PETERSBURG, | ||||
| 
 | ||||
|     /**
 | ||||
|      * The latests EVM revision supported. | ||||
|      * | ||||
|      * @deprecated Replaced with ::EVMC_MAX_REVISION. | ||||
|      */ | ||||
|     EVMC_LATEST_REVISION EVMC_DEPRECATED = EVMC_MAX_REVISION | ||||
|     EVMC_MAX_REVISION = EVMC_BERLIN | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| @ -798,19 +779,22 @@ 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 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. | ||||
|  * @param vm         The VM instance. This argument MUST NOT be NULL. | ||||
|  * @param host       The Host interface. This argument MUST NOT be NULL unless | ||||
|  *                   the @p vm has the ::EVMC_CAPABILITY_PRECOMPILES capability. | ||||
|  * @param context    The opaque pointer to the Host execution context. | ||||
|  *                   This argument MAY be NULL. The VM MUST pass the same | ||||
|  *                   pointer to the methods of the @p host interface. | ||||
|  *                   The VM MUST NOT dereference the pointer. | ||||
|  * @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, | ||||
|                                               struct evmc_context* context, | ||||
| typedef struct evmc_result (*evmc_execute_fn)(struct evmc_vm* vm, | ||||
|                                               const struct evmc_host_interface* host, | ||||
|                                               struct evmc_host_context* context, | ||||
|                                               enum evmc_revision rev, | ||||
|                                               const struct evmc_message* msg, | ||||
|                                               uint8_t const* code, | ||||
| @ -855,98 +839,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); | ||||
| 
 | ||||
| /**
 | ||||
|  * The opaque type representing a Client-side tracer object. | ||||
|  * | ||||
|  * @deprecated Deprecated since EVMC 6.3, see evmc_instance::set_tracer(). | ||||
|  */ | ||||
| struct evmc_tracer_context; | ||||
| 
 | ||||
| /**
 | ||||
|  * The callback to trace instructions execution in an EVM. | ||||
|  * | ||||
|  * This function informs the Client what instruction has been executed in the EVM implementation | ||||
|  * and what are the results of executing this particular instruction. | ||||
|  * The message level information (like call depth, destination address, etc.) are not provided here. | ||||
|  * This piece of information can be acquired by inspecting messages being sent to the EVM in | ||||
|  * ::evmc_execute_fn and the results of the messages execution. | ||||
|  * | ||||
|  * @deprecated Deprecated since EVMC 6.3, see evmc_instance::set_tracer(). | ||||
|  * | ||||
|  * @param context                The pointer to the Client-side tracing context. This allows to | ||||
|  *                               implement the tracer in OOP manner. | ||||
|  * @param code_offset            The current instruction position in the code. | ||||
|  * @param status_code            The status code of the instruction execution. | ||||
|  * @param gas_left               The amount of the gas left after the instruction execution. | ||||
|  * @param stack_num_items        The current EVM stack height after the instruction execution. | ||||
|  * @param pushed_stack_item      The top EVM stack item pushed as the result of the instruction | ||||
|  *                               execution. This value is null when the instruction does not push | ||||
|  *                               anything to the stack. | ||||
|  * @param memory_size            The size of the EVM memory after the instruction execution. | ||||
|  * @param changed_memory_offset  The offset in number of bytes of the beginning of the memory area | ||||
|  *                               modified as the result of the instruction execution. | ||||
|  *                               The Client MAY use this information together with | ||||
|  *                               @p changed_memory_size and @p changed_memory to incrementally | ||||
|  *                               update the copy of the full VM's memory. | ||||
|  * @param changed_memory_size    The size of the memory area modified as the result of | ||||
|  *                               the instruction execution. | ||||
|  * @param changed_memory         The pointer to the memory area modified as the result of | ||||
|  *                               the instruction execution. | ||||
|  *                               The Client MAY access the pointed memory area | ||||
|  *                               (limited by the @p changed_memory_size) only during the current | ||||
|  *                               execution of the evmc_trace_callback(). | ||||
|  *                               The pointer MUST NOT be stored by the Client. | ||||
|  *                               The Client MUST NOT assume that | ||||
|  *                               `changed_memory - changed_memory_offset` is a valid base pointer | ||||
|  *                               of the VM memory. | ||||
|  */ | ||||
| typedef void (*evmc_trace_callback)(struct evmc_tracer_context* context, | ||||
|                                     size_t code_offset, | ||||
|                                     enum evmc_status_code status_code, | ||||
|                                     int64_t gas_left, | ||||
|                                     size_t stack_num_items, | ||||
|                                     const evmc_uint256be* pushed_stack_item, | ||||
|                                     size_t memory_size, | ||||
|                                     size_t changed_memory_offset, | ||||
|                                     size_t changed_memory_size, | ||||
|                                     const uint8_t* changed_memory); | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets the EVM instruction tracer. | ||||
|  * | ||||
|  * When the tracer is set in the EVM instance, the EVM SHOULD call back the tracer with information | ||||
|  * about instructions execution in the EVM. | ||||
|  * @see ::evmc_trace_callback. | ||||
|  * | ||||
|  * This will overwrite the previous settings (the callback and the context). | ||||
|  * | ||||
|  * @deprecated Deprecated since EVMC 6.3, see evmc_instance::set_tracer(). | ||||
|  * | ||||
|  * @param instance    The EVM instance. | ||||
|  * @param callback    The tracer callback function. This argument MAY be NULL to disable previously | ||||
|  *                    set tracer. | ||||
|  * @param context     The Client-side tracer context. This argument MAY be NULL in case the tracer | ||||
|  *                    does not require any context. This argument MUST be NULL if the callback | ||||
|  *                    argument is NULL. | ||||
|  */ | ||||
| typedef void (*evmc_set_tracer_fn)(struct evmc_instance* instance, | ||||
|                                    evmc_trace_callback callback, | ||||
|                                    struct evmc_tracer_context* context); | ||||
| 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. | ||||
| @ -973,14 +879,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. | ||||
|      */ | ||||
| @ -998,17 +904,6 @@ struct evmc_instance | ||||
|      */ | ||||
|     evmc_get_capabilities_fn get_capabilities; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Optional pointer to function setting the EVM instruction tracer. | ||||
|      * | ||||
|      * If the EVM does not support this feature the pointer can be NULL. | ||||
|      * | ||||
|      * @deprecated | ||||
|      * Since EVMC 6.3, the tracing API has been deprecated as there have been some | ||||
|      * design flaws discovered. New API is expected to be introduced in future. | ||||
|      */ | ||||
|     evmc_set_tracer_fn set_tracer; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Optional pointer to function modifying VM's options. | ||||
|      * | ||||
| @ -1033,9 +928,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 | ||||
|  | ||||
| @ -334,49 +334,46 @@ public: | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| /// @copybrief evmc_instance
 | ||||
| class Host; | ||||
| 
 | ||||
| /// @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 | ||||
| class VM | ||||
| { | ||||
| public: | ||||
|     vm() noexcept = default; | ||||
|     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 | ||||
|     ~VM() noexcept | ||||
|     { | ||||
|         if (m_instance) | ||||
|             m_instance->destroy(m_instance); | ||||
|     } | ||||
| 
 | ||||
|     vm(const vm&) = delete; | ||||
|     vm& operator=(const vm&) = delete; | ||||
|     VM(const VM&) = delete; | ||||
|     VM& operator=(const VM&) = delete; | ||||
| 
 | ||||
|     /// Move constructor.
 | ||||
|     vm(vm&& other) noexcept : m_instance{other.m_instance} { other.m_instance = nullptr; } | ||||
|     VM(VM&& other) noexcept : m_instance{other.m_instance} { other.m_instance = nullptr; } | ||||
| 
 | ||||
|     /// Move assignment operator.
 | ||||
|     vm& operator=(vm&& other) noexcept | ||||
|     VM& operator=(VM&& other) noexcept | ||||
|     { | ||||
|         this->~vm(); | ||||
|         this->~VM(); | ||||
|         m_instance = other.m_instance; | ||||
|         other.m_instance = nullptr; | ||||
|         return *this; | ||||
|     } | ||||
| 
 | ||||
|     /// The constructor that captures a VM instance and configures the instance
 | ||||
|     /// with provided list of options.
 | ||||
|     vm(evmc_instance* instance, | ||||
|        std::initializer_list<std::pair<const char*, const char*>> options) noexcept | ||||
|       : m_instance{instance} | ||||
|     { | ||||
|         for (auto option : options) | ||||
|             set_option(option.first, option.second); | ||||
|     } | ||||
|     /// 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.
 | ||||
|     explicit operator bool() const noexcept { return m_instance != nullptr; } | ||||
| @ -384,13 +381,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); | ||||
| @ -403,19 +400,53 @@ public: | ||||
|     } | ||||
| 
 | ||||
|     /// @copydoc evmc_execute()
 | ||||
|     result execute(evmc_context& ctx, | ||||
|     result execute(const evmc_host_interface& host, | ||||
|                    evmc_host_context* ctx, | ||||
|                    evmc_revision rev, | ||||
|                    const evmc_message& msg, | ||||
|                    const uint8_t* code, | ||||
|                    size_t code_size) noexcept | ||||
|     { | ||||
|         return result{m_instance->execute(m_instance, &ctx, rev, &msg, code, code_size)}; | ||||
|         return result{m_instance->execute(m_instance, &host, ctx, rev, &msg, code, code_size)}; | ||||
|     } | ||||
| 
 | ||||
|     /// Convenient variant of the VM::execute() that takes reference to evmc::Host class.
 | ||||
|     inline result execute(Host& host, | ||||
|                           evmc_revision rev, | ||||
|                           const evmc_message& msg, | ||||
|                           const uint8_t* code, | ||||
|                           size_t code_size) noexcept; | ||||
| 
 | ||||
|     /// Executes code without the Host context.
 | ||||
|     ///
 | ||||
|     /// The same as
 | ||||
|     /// execute(const evmc_host_interface&, evmc_host_context*, evmc_revision,
 | ||||
|     ///         const evmc_message&, const uint8_t*, size_t),
 | ||||
|     /// but without providing the Host context and interface.
 | ||||
|     /// This method is for experimental precompiles support where execution is
 | ||||
|     /// guaranteed not to require any Host access.
 | ||||
|     result execute(evmc_revision rev, | ||||
|                    const evmc_message& msg, | ||||
|                    const uint8_t* code, | ||||
|                    size_t code_size) noexcept | ||||
|     { | ||||
|         return result{ | ||||
|             m_instance->execute(m_instance, nullptr, nullptr, rev, &msg, code, code_size)}; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     evmc_instance* m_instance = nullptr; | ||||
|     evmc_vm* m_instance = nullptr; | ||||
| }; | ||||
| 
 | ||||
| inline VM::VM(evmc_vm* vm, | ||||
|               std::initializer_list<std::pair<const char*, const char*>> options) noexcept | ||||
|   : m_instance{vm} | ||||
| { | ||||
|     for (const auto& option : options) | ||||
|         set_option(option.first, option.second); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /// The EVMC Host interface
 | ||||
| class HostInterface | ||||
| { | ||||
| @ -471,46 +502,52 @@ public: | ||||
| 
 | ||||
| /// Wrapper around EVMC host context / host interface.
 | ||||
| ///
 | ||||
| /// To be used by VM implementations as better alternative to using ::evmc_context directly.
 | ||||
| /// To be used by VM implementations as better alternative to using ::evmc_host_context directly.
 | ||||
| class HostContext : public HostInterface | ||||
| { | ||||
|     evmc_context* context = nullptr; | ||||
|     const evmc_host_interface* host = nullptr; | ||||
|     evmc_host_context* context = nullptr; | ||||
|     evmc_tx_context tx_context = {}; | ||||
| 
 | ||||
| public: | ||||
|     /// Implicit converting constructor from evmc_context.
 | ||||
|     HostContext(evmc_context* ctx) noexcept : context{ctx} {}  // NOLINT
 | ||||
|     /// Default constructor for null Host context.
 | ||||
|     HostContext() = default; | ||||
| 
 | ||||
|     /// Constructor from the EVMC Host primitives.
 | ||||
|     HostContext(const evmc_host_interface* interface, evmc_host_context* ctx) noexcept | ||||
|       : host{interface}, context{ctx} | ||||
|     {} | ||||
| 
 | ||||
|     bool account_exists(const address& address) noexcept final | ||||
|     { | ||||
|         return context->host->account_exists(context, &address); | ||||
|         return host->account_exists(context, &address); | ||||
|     } | ||||
| 
 | ||||
|     bytes32 get_storage(const address& address, const bytes32& key) noexcept final | ||||
|     { | ||||
|         return context->host->get_storage(context, &address, &key); | ||||
|         return host->get_storage(context, &address, &key); | ||||
|     } | ||||
| 
 | ||||
|     evmc_storage_status set_storage(const address& address, | ||||
|                                     const bytes32& key, | ||||
|                                     const bytes32& value) noexcept final | ||||
|     { | ||||
|         return context->host->set_storage(context, &address, &key, &value); | ||||
|         return host->set_storage(context, &address, &key, &value); | ||||
|     } | ||||
| 
 | ||||
|     uint256be get_balance(const address& address) noexcept final | ||||
|     { | ||||
|         return context->host->get_balance(context, &address); | ||||
|         return host->get_balance(context, &address); | ||||
|     } | ||||
| 
 | ||||
|     size_t get_code_size(const address& address) noexcept final | ||||
|     { | ||||
|         return context->host->get_code_size(context, &address); | ||||
|         return host->get_code_size(context, &address); | ||||
|     } | ||||
| 
 | ||||
|     bytes32 get_code_hash(const address& address) noexcept final | ||||
|     { | ||||
|         return context->host->get_code_hash(context, &address); | ||||
|         return host->get_code_hash(context, &address); | ||||
|     } | ||||
| 
 | ||||
|     size_t copy_code(const address& address, | ||||
| @ -518,17 +555,17 @@ public: | ||||
|                      uint8_t* buffer_data, | ||||
|                      size_t buffer_size) noexcept final | ||||
|     { | ||||
|         return context->host->copy_code(context, &address, code_offset, buffer_data, buffer_size); | ||||
|         return host->copy_code(context, &address, code_offset, buffer_data, buffer_size); | ||||
|     } | ||||
| 
 | ||||
|     void selfdestruct(const address& addr, const address& beneficiary) noexcept final | ||||
|     { | ||||
|         context->host->selfdestruct(context, &addr, &beneficiary); | ||||
|         host->selfdestruct(context, &addr, &beneficiary); | ||||
|     } | ||||
| 
 | ||||
|     result call(const evmc_message& message) noexcept final | ||||
|     { | ||||
|         return result{context->host->call(context, &message)}; | ||||
|         return result{host->call(context, &message)}; | ||||
|     } | ||||
| 
 | ||||
|     /// @copydoc HostInterface::get_tx_context()
 | ||||
| @ -540,13 +577,13 @@ public: | ||||
|     evmc_tx_context get_tx_context() noexcept final | ||||
|     { | ||||
|         if (tx_context.block_timestamp == 0) | ||||
|             tx_context = context->host->get_tx_context(context); | ||||
|             tx_context = host->get_tx_context(context); | ||||
|         return tx_context; | ||||
|     } | ||||
| 
 | ||||
|     bytes32 get_block_hash(int64_t number) noexcept final | ||||
|     { | ||||
|         return context->host->get_block_hash(context, number); | ||||
|         return host->get_block_hash(context, number); | ||||
|     } | ||||
| 
 | ||||
|     void emit_log(const address& addr, | ||||
| @ -555,7 +592,7 @@ public: | ||||
|                   const bytes32 topics[], | ||||
|                   size_t topics_count) noexcept final | ||||
|     { | ||||
|         context->host->emit_log(context, &addr, data, data_size, topics, topics_count); | ||||
|         host->emit_log(context, &addr, data, data_size, topics, topics_count); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| @ -563,89 +600,135 @@ public: | ||||
| ///
 | ||||
| /// When implementing EVMC Host, you can directly inherit from the evmc::Host class.
 | ||||
| /// This way your implementation will be simpler by avoiding manual handling
 | ||||
| /// of the ::evmc_context and the ::evmc_context::host.
 | ||||
| class Host : public HostInterface, public evmc_context | ||||
| /// of the ::evmc_host_context and the ::evmc_host_interface.
 | ||||
| class Host : public HostInterface | ||||
| { | ||||
| public: | ||||
|     inline Host() noexcept; | ||||
|     /// Provides access to the global host interface.
 | ||||
|     /// @returns  Reference to the host interface object.
 | ||||
|     static const evmc_host_interface& get_interface() noexcept; | ||||
| 
 | ||||
|     /// Converts the Host object to the opaque host context pointer.
 | ||||
|     /// @returns  Pointer to evmc_host_context.
 | ||||
|     evmc_host_context* to_context() noexcept { return reinterpret_cast<evmc_host_context*>(this); } | ||||
| 
 | ||||
|     /// Converts the opaque host context pointer back to the original Host object.
 | ||||
|     /// @tparam DerivedClass  The class derived from the Host class.
 | ||||
|     /// @param context        The opaque host context pointer.
 | ||||
|     /// @returns              The pointer to DerivedClass.
 | ||||
|     template <typename DerivedClass = Host> | ||||
|     static DerivedClass* from_context(evmc_host_context* context) noexcept | ||||
|     { | ||||
|         // Get pointer of the Host base class.
 | ||||
|         auto* h = reinterpret_cast<Host*>(context); | ||||
| 
 | ||||
|         // Additional downcast, only possible if DerivedClass inherits from Host.
 | ||||
|         return static_cast<DerivedClass*>(h); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| inline result VM::execute(Host& host, | ||||
|                           evmc_revision rev, | ||||
|                           const evmc_message& msg, | ||||
|                           const uint8_t* code, | ||||
|                           size_t code_size) noexcept | ||||
| { | ||||
|     return execute(Host::get_interface(), host.to_context(), rev, msg, code, code_size); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| namespace internal | ||||
| { | ||||
| inline bool account_exists(evmc_context* h, const evmc_address* addr) noexcept | ||||
| inline bool account_exists(evmc_host_context* h, const evmc_address* addr) noexcept | ||||
| { | ||||
|     return static_cast<Host*>(h)->account_exists(*addr); | ||||
|     return Host::from_context(h)->account_exists(*addr); | ||||
| } | ||||
| inline evmc_bytes32 get_storage(evmc_context* h, | ||||
| 
 | ||||
| inline evmc_bytes32 get_storage(evmc_host_context* h, | ||||
|                                 const evmc_address* addr, | ||||
|                                 const evmc_bytes32* key) noexcept | ||||
| { | ||||
|     return static_cast<Host*>(h)->get_storage(*addr, *key); | ||||
|     return Host::from_context(h)->get_storage(*addr, *key); | ||||
| } | ||||
| inline evmc_storage_status set_storage(evmc_context* h, | ||||
| 
 | ||||
| inline evmc_storage_status set_storage(evmc_host_context* h, | ||||
|                                        const evmc_address* addr, | ||||
|                                        const evmc_bytes32* key, | ||||
|                                        const evmc_bytes32* value) noexcept | ||||
| { | ||||
|     return static_cast<Host*>(h)->set_storage(*addr, *key, *value); | ||||
|     return Host::from_context(h)->set_storage(*addr, *key, *value); | ||||
| } | ||||
| inline evmc_uint256be get_balance(evmc_context* h, const evmc_address* addr) noexcept | ||||
| 
 | ||||
| inline evmc_uint256be get_balance(evmc_host_context* h, const evmc_address* addr) noexcept | ||||
| { | ||||
|     return static_cast<Host*>(h)->get_balance(*addr); | ||||
|     return Host::from_context(h)->get_balance(*addr); | ||||
| } | ||||
| inline size_t get_code_size(evmc_context* h, const evmc_address* addr) noexcept | ||||
| 
 | ||||
| inline size_t get_code_size(evmc_host_context* h, const evmc_address* addr) noexcept | ||||
| { | ||||
|     return static_cast<Host*>(h)->get_code_size(*addr); | ||||
|     return Host::from_context(h)->get_code_size(*addr); | ||||
| } | ||||
| inline evmc_bytes32 get_code_hash(evmc_context* h, const evmc_address* addr) noexcept | ||||
| 
 | ||||
| inline evmc_bytes32 get_code_hash(evmc_host_context* h, const evmc_address* addr) noexcept | ||||
| { | ||||
|     return static_cast<Host*>(h)->get_code_hash(*addr); | ||||
|     return Host::from_context(h)->get_code_hash(*addr); | ||||
| } | ||||
| inline size_t copy_code(evmc_context* h, | ||||
| 
 | ||||
| inline size_t copy_code(evmc_host_context* h, | ||||
|                         const evmc_address* addr, | ||||
|                         size_t code_offset, | ||||
|                         uint8_t* buffer_data, | ||||
|                         size_t buffer_size) noexcept | ||||
| { | ||||
|     return static_cast<Host*>(h)->copy_code(*addr, code_offset, buffer_data, buffer_size); | ||||
|     return Host::from_context(h)->copy_code(*addr, code_offset, buffer_data, buffer_size); | ||||
| } | ||||
| inline void selfdestruct(evmc_context* h, | ||||
| 
 | ||||
| inline void selfdestruct(evmc_host_context* h, | ||||
|                          const evmc_address* addr, | ||||
|                          const evmc_address* beneficiary) noexcept | ||||
| { | ||||
|     static_cast<Host*>(h)->selfdestruct(*addr, *beneficiary); | ||||
|     Host::from_context(h)->selfdestruct(*addr, *beneficiary); | ||||
| } | ||||
| inline evmc_result call(evmc_context* h, const evmc_message* msg) noexcept | ||||
| 
 | ||||
| inline evmc_result call(evmc_host_context* h, const evmc_message* msg) noexcept | ||||
| { | ||||
|     return static_cast<Host*>(h)->call(*msg).release_raw(); | ||||
|     return Host::from_context(h)->call(*msg).release_raw(); | ||||
| } | ||||
| inline evmc_tx_context get_tx_context(evmc_context* h) noexcept | ||||
| 
 | ||||
| inline evmc_tx_context get_tx_context(evmc_host_context* h) noexcept | ||||
| { | ||||
|     return static_cast<Host*>(h)->get_tx_context(); | ||||
|     return Host::from_context(h)->get_tx_context(); | ||||
| } | ||||
| inline evmc_bytes32 get_block_hash(evmc_context* h, int64_t block_number) noexcept | ||||
| 
 | ||||
| inline evmc_bytes32 get_block_hash(evmc_host_context* h, int64_t block_number) noexcept | ||||
| { | ||||
|     return static_cast<Host*>(h)->get_block_hash(block_number); | ||||
|     return Host::from_context(h)->get_block_hash(block_number); | ||||
| } | ||||
| inline void emit_log(evmc_context* h, | ||||
| 
 | ||||
| inline void emit_log(evmc_host_context* h, | ||||
|                      const evmc_address* addr, | ||||
|                      const uint8_t* data, | ||||
|                      size_t data_size, | ||||
|                      const evmc_bytes32 topics[], | ||||
|                      size_t num_topics) noexcept | ||||
| { | ||||
|     static_cast<Host*>(h)->emit_log(*addr, data, data_size, static_cast<const bytes32*>(topics), | ||||
|     Host::from_context(h)->emit_log(*addr, data, data_size, static_cast<const bytes32*>(topics), | ||||
|                                     num_topics); | ||||
| } | ||||
| 
 | ||||
| constexpr evmc_host_interface interface{ | ||||
|     account_exists, get_storage,  set_storage, get_balance,    get_code_size,  get_code_hash, | ||||
|     copy_code,      selfdestruct, call,        get_tx_context, get_block_hash, emit_log, | ||||
| }; | ||||
| }  // namespace internal
 | ||||
| 
 | ||||
| inline Host::Host() noexcept : evmc_context{&evmc::internal::interface} {} | ||||
| 
 | ||||
| inline const evmc_host_interface& Host::get_interface() noexcept | ||||
| { | ||||
|     static constexpr evmc_host_interface interface{ | ||||
|         ::evmc::internal::account_exists, ::evmc::internal::get_storage, | ||||
|         ::evmc::internal::set_storage,    ::evmc::internal::get_balance, | ||||
|         ::evmc::internal::get_code_size,  ::evmc::internal::get_code_hash, | ||||
|         ::evmc::internal::copy_code,      ::evmc::internal::selfdestruct, | ||||
|         ::evmc::internal::call,           ::evmc::internal::get_tx_context, | ||||
|         ::evmc::internal::get_block_hash, ::evmc::internal::emit_log}; | ||||
|     return interface; | ||||
| } | ||||
| }  // namespace evmc
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -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 bool 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,52 +60,39 @@ 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; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Sets the tracer callback for the VM instance, if the feature is supported by the VM. | ||||
|  * | ||||
|  * @see evmc_set_tracer_fn | ||||
|  */ | ||||
| EVMC_DEPRECATED | ||||
| static inline void evmc_set_tracer(struct evmc_instance* instance, | ||||
|                                    evmc_trace_callback callback, | ||||
|                                    struct evmc_tracer_context* context) | ||||
| { | ||||
|     if (instance->set_tracer) | ||||
|         instance->set_tracer(instance, callback, context); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Executes code in the VM instance. | ||||
|  * | ||||
|  * @see evmc_execute_fn. | ||||
|  */ | ||||
| static inline struct evmc_result evmc_execute(struct evmc_instance* instance, | ||||
|                                               struct evmc_context* context, | ||||
| static inline struct evmc_result evmc_execute(struct evmc_vm* vm, | ||||
|                                               const struct evmc_host_interface* host, | ||||
|                                               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, host, context, rev, msg, code, code_size); | ||||
| } | ||||
| 
 | ||||
| /// The evmc_result release function using free() for releasing the memory.
 | ||||
|  | ||||
| @ -152,8 +152,8 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro | ||||
|     char* base_name = prefixed_name + prefix_length; | ||||
|     strcpy_sx(base_name, PATH_MAX_LENGTH, name_pos); | ||||
| 
 | ||||
|     // Trim the file extension.
 | ||||
|     char* ext_pos = strrchr(prefixed_name, '.'); | ||||
|     // Trim all file extensions.
 | ||||
|     char* ext_pos = strchr(prefixed_name, '.'); | ||||
|     if (ext_pos) | ||||
|         *ext_pos = 0; | ||||
| 
 | ||||
| @ -163,15 +163,7 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro | ||||
|         *dash_pos++ = '_'; | ||||
| 
 | ||||
|     // Search for the built function name.
 | ||||
|     while ((create_fn = DLL_GET_CREATE_FN(handle, prefixed_name)) == NULL) | ||||
|     { | ||||
|         // Shorten the base name by skipping the `word_` segment.
 | ||||
|         const char* shorter_name_pos = strchr(base_name, '_'); | ||||
|         if (!shorter_name_pos) | ||||
|             break; | ||||
| 
 | ||||
|         memmove(base_name, shorter_name_pos + 1, strlen(shorter_name_pos) + 1); | ||||
|     } | ||||
|     create_fn = DLL_GET_CREATE_FN(handle, prefixed_name); | ||||
| 
 | ||||
|     if (!create_fn) | ||||
|         create_fn = DLL_GET_CREATE_FN(handle, "evmc_create"); | ||||
| @ -196,8 +188,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 +198,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 +220,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 +246,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 +263,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 +283,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 +305,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; | ||||
| } | ||||
|  | ||||
| @ -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, | ||||
| @ -61,21 +61,16 @@ enum evmc_loader_error_code | ||||
|  * After the DLL is successfully loaded the function tries to find the EVM create function in the | ||||
|  * library. The `filename` is used to guess the EVM name and the name of the create function. | ||||
|  * The create function name is constructed by the following rules. Consider example path: | ||||
|  * "/ethereum/libexample-interpreter.so". | ||||
|  * "/ethereum/libexample-interpreter.so.1.0". | ||||
|  * - the filename is taken from the path: | ||||
|  *   "libexample-interpreter.so", | ||||
|  * - the "lib" prefix and file extension are stripped from the name: | ||||
|  *   "libexample-interpreter.so.1.0", | ||||
|  * - the "lib" prefix and all file extensions are stripped from the name: | ||||
|  *   "example-interpreter" | ||||
|  * - all "-" are replaced with "_" to construct _base name_: | ||||
|  *   "example_interpreter", | ||||
|  * - the function name "evmc_create_" + _base name_ is searched in the library: | ||||
|  *   "evmc_create_example_interpreter", | ||||
|  * - if function not found, the _base name_ is shorten by skipping the first word separated by "_": | ||||
|  *   "interpreter", | ||||
|  * - then, the function of the shorter name "evmc_create_" + _base name_ is searched in the library: | ||||
|  *   "evmc_create_interpreter", | ||||
|  * - the name shortening continues until a function is found or the name cannot be shorten more, | ||||
|  * - lastly, when no function found, the function name "evmc_create" is searched in the library. | ||||
|  * - if the function is not found, the function name "evmc_create" is searched in the library. | ||||
|  * | ||||
|  * If the create function is found in the library, the pointer to the function is returned. | ||||
|  * Otherwise, the ::EVMC_LOADER_SYMBOL_NOT_FOUND error code is signaled and NULL is returned. | ||||
| @ -98,7 +93,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 +109,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 +145,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 | ||||
|  | ||||
| @ -24,7 +24,7 @@ | ||||
| 
 | ||||
| #include <fstream> | ||||
| 
 | ||||
| static evmc::vm evmone = evmc::vm{evmc_create_evmone()}; | ||||
| static evmc::VM evmone = evmc::VM{evmc_create_evmone()}; | ||||
| 
 | ||||
| using namespace dev::test::abiv2fuzzer; | ||||
| using namespace dev::test; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user