mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add evmc.
This commit is contained in:
parent
9955c51769
commit
7401fbabd9
@ -27,6 +27,10 @@
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
#include <test/evmc/evmc.hpp>
|
||||
#include <test/evmc/loader.h>
|
||||
#include <test/evmc/helpers.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <chrono>
|
||||
|
@ -974,12 +974,12 @@ struct evmc_instance
|
||||
evmc_execute_fn execute;
|
||||
|
||||
/**
|
||||
* Pointer to function returning capabilities supported by the VM instance.
|
||||
* A method returning capabilities supported by the VM instance.
|
||||
*
|
||||
* The value returned might change when different options are requested via set_option.
|
||||
* The value returned MAY change when different options are set via the set_option() method.
|
||||
*
|
||||
* A Client SHOULD only rely on the value returned here if it has queried it after
|
||||
* it has called set_option.
|
||||
* A Client SHOULD only rely on the value returned if it has queried it after
|
||||
* it has called the set_option().
|
||||
*
|
||||
* This is a mandatory method and MUST NOT be set to NULL.
|
||||
*/
|
||||
|
@ -2,6 +2,7 @@
|
||||
* Copyright 2018-2019 The EVMC Authors.
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <evmc/evmc.h>
|
||||
#include <evmc/helpers.h>
|
||||
@ -104,6 +105,12 @@ public:
|
||||
/// @copydoc evmc_instance::version
|
||||
char const* version() const noexcept { return m_instance->version; }
|
||||
|
||||
/// @copydoc evmc::instance::get_capabilities
|
||||
evmc_capabilities_flagset get_capabilities() const noexcept
|
||||
{
|
||||
return m_instance->get_capabilities(m_instance);
|
||||
}
|
||||
|
||||
/// @copydoc evmc_set_option()
|
||||
evmc_set_option_result set_option(const char name[], const char value[]) noexcept
|
||||
{
|
||||
|
@ -42,18 +42,33 @@
|
||||
#define ATTR_FORMAT(...)
|
||||
#endif
|
||||
|
||||
#if !_WIN32
|
||||
#if _WIN32
|
||||
#define strcpy_sx strcpy_s
|
||||
#else
|
||||
/*
|
||||
* Provide strcpy_s() for GNU libc.
|
||||
* Limited variant of strcpy_s().
|
||||
*
|
||||
* Provided for C standard libraries where strcpy_s() is not available.
|
||||
* The availability check might need to adjusted for other C standard library implementations.
|
||||
*/
|
||||
static void strcpy_s(char* dest, size_t destsz, const char* src)
|
||||
#if !defined(EVMC_LOADER_MOCK)
|
||||
static
|
||||
#endif
|
||||
int
|
||||
strcpy_sx(char* restrict dest, size_t destsz, const char* restrict src)
|
||||
{
|
||||
size_t len = strlen(src);
|
||||
if (len > destsz - 1)
|
||||
len = destsz - 1;
|
||||
if (len >= destsz)
|
||||
{
|
||||
// The input src will not fit into the dest buffer.
|
||||
// Set the first byte of the dest to null to make it effectively empty string
|
||||
// and return error.
|
||||
dest[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -124,7 +139,7 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
|
||||
const char prefix[] = "evmc_create_";
|
||||
const size_t prefix_length = strlen(prefix);
|
||||
char prefixed_name[sizeof(prefix) + PATH_MAX_LENGTH];
|
||||
strcpy_s(prefixed_name, sizeof(prefixed_name), prefix);
|
||||
strcpy_sx(prefixed_name, sizeof(prefixed_name), prefix);
|
||||
|
||||
// Find filename in the path.
|
||||
const char* sep_pos = strrchr(filename, '/');
|
||||
@ -142,7 +157,7 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
|
||||
name_pos += lib_prefix_length;
|
||||
|
||||
char* base_name = prefixed_name + prefix_length;
|
||||
strcpy_s(base_name, PATH_MAX_LENGTH, name_pos);
|
||||
strcpy_sx(base_name, PATH_MAX_LENGTH, name_pos);
|
||||
|
||||
// Trim the file extension.
|
||||
char* ext_pos = strrchr(prefixed_name, '.');
|
||||
@ -197,21 +212,29 @@ struct evmc_instance* evmc_load_and_create(const char* filename,
|
||||
if (!create_fn)
|
||||
return NULL;
|
||||
|
||||
enum evmc_loader_error_code ec = EVMC_LOADER_SUCCESS;
|
||||
|
||||
struct evmc_instance* instance = create_fn();
|
||||
if (!instance)
|
||||
{
|
||||
*error_code = set_error(EVMC_LOADER_INSTANCE_CREATION_FAILURE,
|
||||
"creating EVMC instance of %s has failed", filename);
|
||||
return NULL;
|
||||
ec = set_error(EVMC_LOADER_INSTANCE_CREATION_FAILURE,
|
||||
"creating EVMC instance of %s has failed", filename);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!evmc_is_abi_compatible(instance))
|
||||
{
|
||||
*error_code = 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);
|
||||
return NULL;
|
||||
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;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (error_code)
|
||||
*error_code = ec;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
@ -44,10 +44,10 @@ enum evmc_loader_error_code
|
||||
};
|
||||
|
||||
/**
|
||||
* Dynamically loads the shared object (DLL) with an EVM implementation.
|
||||
* Dynamically loads the EVMC module with a VM implementation.
|
||||
*
|
||||
* 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.
|
||||
* This function tries to open a dynamically loaded library (DLL) at the given `filename`.
|
||||
* On UNIX-like systems dlopen() function is used. On Windows LoadLibrary() function is used.
|
||||
*
|
||||
* 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.
|
||||
@ -77,28 +77,36 @@ enum evmc_loader_error_code
|
||||
* 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
|
||||
* containing the EVM implementation. If the value is NULL, an empty C-string
|
||||
* or longer than the path maximum length the ::EVMC_LOADER_INVALID_ARGUMENT is
|
||||
* signaled.
|
||||
* @param filename The null terminated path (absolute or relative) to an EVMC module
|
||||
* (dynamically loaded library) containing the VM implementation.
|
||||
* If the value is NULL, an empty C-string or longer than the path maximum length
|
||||
* the ::EVMC_LOADER_INVALID_ARGUMENT is signaled.
|
||||
* @param error_code The pointer to the error code. If not NULL the value is set to
|
||||
* ::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 in case of error.
|
||||
*/
|
||||
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.
|
||||
* Dynamically loads the EVMC module 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).
|
||||
* - ::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.
|
||||
*
|
||||
* @param filename The null terminated path (absolute or relative) to an EVMC module
|
||||
* (dynamically loaded library) containing the VM implementation.
|
||||
* If the value is NULL, an empty C-string or longer than the path maximum length
|
||||
* the ::EVMC_LOADER_INVALID_ARGUMENT is signaled.
|
||||
* @param error_code The pointer to the error code. If not NULL the value is set to
|
||||
* ::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);
|
||||
|
Loading…
Reference in New Issue
Block a user