mirror of https://github.com/status-im/evmc.git
commit
97221d2db7
|
@ -0,0 +1,54 @@
|
||||||
|
/* EVMC: Ethereum Client-VM Connector API.
|
||||||
|
* Copyright 2018 Pawel Bylica.
|
||||||
|
* Licensed under the MIT License. See the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EVMC Helpers
|
||||||
|
*
|
||||||
|
* A collection of helper functions for invoking a VM instance methods.
|
||||||
|
* These are convenient for languages where invoking function pointers
|
||||||
|
* is "ugly" or impossible (such as Go).
|
||||||
|
*
|
||||||
|
* @defgroup helpers EVMC Helpers
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <evmc/evmc.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the VM instance.
|
||||||
|
*
|
||||||
|
* @see evmc_destroy_fn
|
||||||
|
*/
|
||||||
|
static inline void evmc_destroy(struct evmc_instance* instance)
|
||||||
|
{
|
||||||
|
instance->destroy(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the option for the VM instance, if the feature is supported by the VM.
|
||||||
|
*
|
||||||
|
* @see evmc_set_option_fn
|
||||||
|
*/
|
||||||
|
static inline int evmc_set_option(struct evmc_instance* instance,
|
||||||
|
char const* name,
|
||||||
|
char const* value)
|
||||||
|
{
|
||||||
|
if (instance->set_option)
|
||||||
|
return instance->set_option(instance, name, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases the resources allocated to the execution result.
|
||||||
|
*
|
||||||
|
* @see evmc_release_result_fn
|
||||||
|
*/
|
||||||
|
static inline void evmc_release_result(struct evmc_result* result)
|
||||||
|
{
|
||||||
|
result->release(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -3,13 +3,19 @@
|
||||||
* Licensed under the MIT License. See the LICENSE file.
|
* Licensed under the MIT License. See the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EVM Instruction Tables
|
||||||
|
*
|
||||||
|
* A collection of metrics for EVM1 instruction set.
|
||||||
|
*
|
||||||
|
* @defgroup instructions EVM Instructions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <evmc/evmc.h>
|
#include <evmc/evmc.h>
|
||||||
#include <evmc/utils.h>
|
#include <evmc/utils.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -209,3 +215,5 @@ EVMC_EXPORT const char* const* evmc_get_instruction_names_table(enum evmc_revisi
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -3,6 +3,15 @@
|
||||||
* Licensed under the MIT License. See the LICENSE file.
|
* Licensed under the MIT License. See the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EVMC Loader Library
|
||||||
|
*
|
||||||
|
* The EVMC Loader Library supports loading VMs implemented as Dynamically Loaded Libraries
|
||||||
|
* (DLLs, shared objects).
|
||||||
|
*
|
||||||
|
* @defgroup loader EVMC Loader
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
@ -15,10 +24,23 @@ typedef struct evmc_instance* (*evmc_create_fn)(void);
|
||||||
/** Error codes for the EVMC loader. */
|
/** Error codes for the EVMC loader. */
|
||||||
enum evmc_loader_error_code
|
enum evmc_loader_error_code
|
||||||
{
|
{
|
||||||
|
/** The loader succeeded. */
|
||||||
EVMC_LOADER_SUCCESS = 0,
|
EVMC_LOADER_SUCCESS = 0,
|
||||||
EVMC_LOADER_CANNOT_OPEN,
|
|
||||||
EVMC_LOADER_SYMBOL_NOT_FOUND,
|
/** The loader cannot open the given file name. */
|
||||||
EVMC_LOADER_INVALID_ARGUMENT,
|
EVMC_LOADER_CANNOT_OPEN = 1,
|
||||||
|
|
||||||
|
/** The VM create function not found. */
|
||||||
|
EVMC_LOADER_SYMBOL_NOT_FOUND = 2,
|
||||||
|
|
||||||
|
/** The invalid argument value provided. */
|
||||||
|
EVMC_LOADER_INVALID_ARGUMENT = 3,
|
||||||
|
|
||||||
|
/** The creation of a VM instance has failed. */
|
||||||
|
EVMC_LOADER_INSTANCE_CREATION_FAILURE = 4,
|
||||||
|
|
||||||
|
/** The ABI version of the VM instance has mismatched. */
|
||||||
|
EVMC_LOADER_ABI_VERSION_MISMATCH = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +49,7 @@ enum evmc_loader_error_code
|
||||||
* This function tries to open a DLL at the given `filename`. On UNIX-like systems dlopen() function
|
* This function tries to open a DLL at the given `filename`. On UNIX-like systems dlopen() function
|
||||||
* is used. On Windows LoadLibrary() function is used.
|
* is used. On Windows LoadLibrary() function is used.
|
||||||
*
|
*
|
||||||
* If the file does not exist or is not a valid shared library the ::EVMC_ERRC_CANNOT_OPEN error
|
* If the file does not exist or is not a valid shared library the ::EVMC_LOADER_CANNOT_OPEN error
|
||||||
* code is signaled and NULL is returned.
|
* code is signaled and NULL is returned.
|
||||||
*
|
*
|
||||||
* After the DLL is successfully loaded the function tries to find the EVM create function in the
|
* After the DLL is successfully loaded the function tries to find the EVM create function in the
|
||||||
|
@ -48,18 +70,38 @@ enum evmc_loader_error_code
|
||||||
* "evmc_create_interpreter".
|
* "evmc_create_interpreter".
|
||||||
*
|
*
|
||||||
* If the create function is found in the library, the pointer to the function is returned.
|
* If the create function is found in the library, the pointer to the function is returned.
|
||||||
* Otherwise, the ::EVMC_ERRC_SYMBOL_NOT_FOUND error code is signaled and NULL is returned.
|
* Otherwise, the ::EVMC_LOADER_SYMBOL_NOT_FOUND error code is signaled and NULL is returned.
|
||||||
|
*
|
||||||
|
* It is safe to call this function with the same filename argument multiple times
|
||||||
|
* (the DLL is not going to be loaded multiple times).
|
||||||
*
|
*
|
||||||
* @param filename The null terminated path (absolute or relative) to the shared library
|
* @param filename The null terminated path (absolute or relative) to the shared library
|
||||||
* containing the EVM implementation. If the value is NULL, an empty C-string
|
* containing the EVM implementation. If the value is NULL, an empty C-string
|
||||||
* or longer than the path maximum length the ::EVMC_ERRC_INVALID_ARGUMENT is
|
* or longer than the path maximum length the ::EVMC_LOADER_INVALID_ARGUMENT is
|
||||||
* signaled.
|
* signaled.
|
||||||
* @param error_code The pointer to the error code. If not NULL the value is set to
|
* @param error_code The pointer to the error code. If not NULL the value is set to
|
||||||
* ::EVMC_ERRC_SUCCESS on success or any other error code as described above.
|
* ::EVMC_LOADER_SUCCESS on success or any other error code as described above.
|
||||||
* @return The pointer to the EVM create function or NULL.
|
* @return The pointer to the EVM create function or NULL.
|
||||||
*/
|
*/
|
||||||
evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* error_code);
|
evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* error_code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamically loads the VM DLL and creates the VM instance.
|
||||||
|
*
|
||||||
|
* 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_ABI_VERSION_MISMATCH when the created VM instance has ABI version different
|
||||||
|
* from the ABI version of this library (::EVMC_ABI_VERSION).
|
||||||
|
*
|
||||||
|
* It is safe to call this function with the same filename argument multiple times:
|
||||||
|
* the DLL is not going to be loaded multiple times, but the function will return new VM instance
|
||||||
|
* each time.
|
||||||
|
*/
|
||||||
|
struct evmc_instance* evmc_load_and_create(const char* filename, enum evmc_loader_error_code* error_code);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <evmc/loader.h>
|
#include <evmc/loader.h>
|
||||||
|
#include <evmc/evmc.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -121,3 +122,26 @@ exit:
|
||||||
*error_code = ec;
|
*error_code = ec;
|
||||||
return create_fn;
|
return create_fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct evmc_instance* evmc_load_and_create(const char* filename, enum evmc_loader_error_code* error_code)
|
||||||
|
{
|
||||||
|
evmc_create_fn create_fn = evmc_load(filename, error_code);
|
||||||
|
|
||||||
|
if (!create_fn)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct evmc_instance* instance = create_fn();
|
||||||
|
if (!instance)
|
||||||
|
{
|
||||||
|
*error_code = EVMC_LOADER_INSTANCE_CREATION_FAILURE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance->abi_version != EVMC_ABI_VERSION)
|
||||||
|
{
|
||||||
|
*error_code = EVMC_LOADER_ABI_VERSION_MISMATCH;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ add_custom_command(
|
||||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> _
|
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> _
|
||||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> lib_.so
|
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> lib_.so
|
||||||
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> ../aaa.evm
|
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> ../aaa.evm
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> failure.vm
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E ${cmd} $<TARGET_FILE:vm-mock> abi42.vm
|
||||||
COMMAND ${CMAKE_COMMAND} -E touch empty.file
|
COMMAND ${CMAKE_COMMAND} -E touch empty.file
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -244,3 +244,19 @@ TEST(loader, lib_)
|
||||||
x = evmc_load(path, nullptr);
|
x = evmc_load(path, nullptr);
|
||||||
EXPECT_EQ(x, nullptr);
|
EXPECT_EQ(x, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(loader, load_and_create_failure)
|
||||||
|
{
|
||||||
|
evmc_loader_error_code ec;
|
||||||
|
auto vm = evmc_load_and_create("unittests/failure.vm", &ec);
|
||||||
|
EXPECT_EQ(vm, nullptr);
|
||||||
|
EXPECT_EQ(ec, EVMC_LOADER_INSTANCE_CREATION_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(loader, load_and_create_abi_mismatch)
|
||||||
|
{
|
||||||
|
evmc_loader_error_code ec;
|
||||||
|
auto vm = evmc_load_and_create("unittests/abi42.vm", &ec);
|
||||||
|
EXPECT_EQ(vm, nullptr);
|
||||||
|
EXPECT_EQ(ec, EVMC_LOADER_ABI_VERSION_MISMATCH);
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* Licensed under the MIT License. See the LICENSE file.
|
* Licensed under the MIT License. See the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <evmc/evmc.h>
|
||||||
#include <evmc/utils.h>
|
#include <evmc/utils.h>
|
||||||
|
|
||||||
EVMC_EXPORT void* evmc_create_aaa()
|
EVMC_EXPORT void* evmc_create_aaa()
|
||||||
|
@ -14,3 +15,16 @@ EVMC_EXPORT void* evmc_create_eee_bbb()
|
||||||
{
|
{
|
||||||
return (void*)0xeeebbb;
|
return (void*)0xeeebbb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EVMC_EXPORT void* evmc_create_failure()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVMC_EXPORT struct evmc_instance* evmc_create_abi42()
|
||||||
|
{
|
||||||
|
static struct evmc_instance instance = {
|
||||||
|
.abi_version = 42,
|
||||||
|
};
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue