mirror of
https://github.com/status-im/evmc.git
synced 2025-02-23 08:28:15 +00:00
Merge pull request #38 from ethereum/create-fn-search
"Create" function name search heuristic
This commit is contained in:
commit
5ee6915250
4
Doxyfile
4
Doxyfile
@ -99,7 +99,7 @@ WARN_LOGFILE =
|
|||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the input files
|
# Configuration options related to the input files
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
INPUT = include/evmc/evmc.h
|
INPUT = include/evmc/
|
||||||
INPUT_ENCODING = UTF-8
|
INPUT_ENCODING = UTF-8
|
||||||
FILE_PATTERNS =
|
FILE_PATTERNS =
|
||||||
RECURSIVE = NO
|
RECURSIVE = NO
|
||||||
@ -264,7 +264,7 @@ EXPAND_ONLY_PREDEF = NO
|
|||||||
SEARCH_INCLUDES = YES
|
SEARCH_INCLUDES = YES
|
||||||
INCLUDE_PATH =
|
INCLUDE_PATH =
|
||||||
INCLUDE_FILE_PATTERNS =
|
INCLUDE_FILE_PATTERNS =
|
||||||
PREDEFINED =
|
PREDEFINED = EVMC_DOCUMENTATION=1
|
||||||
EXPAND_AS_DEFINED =
|
EXPAND_AS_DEFINED =
|
||||||
SKIP_FUNCTION_MACROS = YES
|
SKIP_FUNCTION_MACROS = YES
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# EVMC -- Ethereum Client-VM Connector API
|
# EVMC: Ethereum Client-VM Connector API
|
||||||
# Copyright 2018 Pawel Bylica.
|
# Copyright 2018 Pawel Bylica.
|
||||||
# Licensed under the MIT License. See the LICENSE file.
|
# Licensed under the MIT License. See the LICENSE file.
|
||||||
|
|
||||||
@ -6,9 +6,16 @@ include(GNUInstallDirs)
|
|||||||
|
|
||||||
add_library(evmc-examplevm examplevm.c)
|
add_library(evmc-examplevm examplevm.c)
|
||||||
target_link_libraries(evmc-examplevm PRIVATE evmc)
|
target_link_libraries(evmc-examplevm PRIVATE evmc)
|
||||||
set_target_properties(evmc-examplevm PROPERTIES DEBUG_POSTFIX "")
|
set_target_properties(
|
||||||
|
evmc-examplevm PROPERTIES
|
||||||
|
DEBUG_POSTFIX ""
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ..
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY ..
|
||||||
|
)
|
||||||
|
|
||||||
install(TARGETS evmc-examplevm
|
install(
|
||||||
|
TARGETS evmc-examplevm
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
)
|
||||||
|
@ -11,7 +11,7 @@ struct examplevm
|
|||||||
int verbose;
|
int verbose;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void evmc_destroy(struct evmc_instance* evm)
|
static void destroy(struct evmc_instance* evm)
|
||||||
{
|
{
|
||||||
free(evm);
|
free(evm);
|
||||||
}
|
}
|
||||||
@ -19,7 +19,7 @@ static void evmc_destroy(struct evmc_instance* evm)
|
|||||||
/// Example options.
|
/// Example options.
|
||||||
///
|
///
|
||||||
/// VMs are allowed to omit this function implementation.
|
/// VMs are allowed to omit this function implementation.
|
||||||
int evmc_set_option(struct evmc_instance* instance, char const* name, char const* value)
|
static int set_option(struct evmc_instance* instance, char const* name, char const* value)
|
||||||
{
|
{
|
||||||
struct examplevm* vm = (struct examplevm*)instance;
|
struct examplevm* vm = (struct examplevm*)instance;
|
||||||
if (strcmp(name, "verbose") == 0)
|
if (strcmp(name, "verbose") == 0)
|
||||||
@ -34,7 +34,7 @@ int evmc_set_option(struct evmc_instance* instance, char const* name, char const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void evmc_release_result(struct evmc_result const* result)
|
static void release_result(struct evmc_result const* result)
|
||||||
{
|
{
|
||||||
(void)result;
|
(void)result;
|
||||||
}
|
}
|
||||||
@ -103,7 +103,7 @@ static struct evmc_result execute(struct evmc_instance* instance,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.release = evmc_release_result;
|
ret.release = release_result;
|
||||||
ret.status_code = EVMC_FAILURE;
|
ret.status_code = EVMC_FAILURE;
|
||||||
ret.gas_left = 0;
|
ret.gas_left = 0;
|
||||||
|
|
||||||
@ -119,9 +119,9 @@ struct evmc_instance* evmc_create_examplevm()
|
|||||||
.abi_version = EVMC_ABI_VERSION,
|
.abi_version = EVMC_ABI_VERSION,
|
||||||
.name = "examplevm",
|
.name = "examplevm",
|
||||||
.version = "0.0.0",
|
.version = "0.0.0",
|
||||||
.destroy = evmc_destroy,
|
.destroy = destroy,
|
||||||
.execute = execute,
|
.execute = execute,
|
||||||
.set_option = evmc_set_option,
|
.set_option = set_option,
|
||||||
};
|
};
|
||||||
struct examplevm* vm = calloc(1, sizeof(struct examplevm));
|
struct examplevm* vm = calloc(1, sizeof(struct examplevm));
|
||||||
struct evmc_instance* interface = &vm->instance;
|
struct evmc_instance* interface = &vm->instance;
|
||||||
|
@ -732,16 +732,24 @@ struct evmc_instance
|
|||||||
|
|
||||||
/* END Python CFFI declarations */
|
/* END Python CFFI declarations */
|
||||||
|
|
||||||
|
#if EVMC_DOCUMENTATION
|
||||||
/**
|
/**
|
||||||
* Example of a function creating an instance of an example EVM implementation.
|
* Example of a function creating an instance of an example EVM implementation.
|
||||||
*
|
*
|
||||||
* Each EVM implementation MUST provide a function returning an EVM instance.
|
* Each EVM implementation MUST provide a function returning an EVM instance.
|
||||||
* The function SHOULD be named `evmc_create_<vm-name>(void)`.
|
* The function SHOULD be named `evmc_create_<vm-name>(void)`. If the VM name contains hyphens
|
||||||
|
* replaces them with underscores in the function names.
|
||||||
*
|
*
|
||||||
* @return EVM instance or NULL indicating instance creation failure.
|
* @par Binaries naming convention
|
||||||
|
* For VMs distributed as shared libraries, the name of the library SHOULD match the VM name.
|
||||||
|
* The convetional library filename prefixes and extensions SHOULD be ignored by the Client.
|
||||||
|
* For example, the shared library with the "beta-interpreter" implementation may be named
|
||||||
|
* `libbeta-interpreter.so`.
|
||||||
*
|
*
|
||||||
* struct evmc_instance* evmc_create_examplevm(void);
|
* @return EVM instance or NULL indicating instance creation failure.
|
||||||
*/
|
*/
|
||||||
|
struct evmc_instance* evmc_create_examplevm(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -8,5 +8,5 @@
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define EVMC_EXPORT __declspec(dllexport)
|
#define EVMC_EXPORT __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
#define EVMC_EXPORT __attribute__ ((visibility ("default")))
|
#define EVMC_EXPORT __attribute__((visibility("default")))
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,6 +8,7 @@ hunter_add_package(Boost COMPONENTS program_options filesystem system)
|
|||||||
find_package(Boost CONFIG REQUIRED program_options filesystem system)
|
find_package(Boost CONFIG REQUIRED program_options filesystem system)
|
||||||
|
|
||||||
add_executable(evmc-vmtester vmtester.hpp vmtester.cpp tests.cpp)
|
add_executable(evmc-vmtester vmtester.hpp vmtester.cpp tests.cpp)
|
||||||
|
set_target_properties(evmc-vmtester PROPERTIES RUNTIME_OUTPUT_DIRECTORY ..)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
evmc-vmtester
|
evmc-vmtester
|
||||||
|
@ -35,6 +35,38 @@ evmc_instance* get_vm_instance()
|
|||||||
return vm.get();
|
return vm.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> get_vm_names(const fs::path path)
|
||||||
|
{
|
||||||
|
std::vector<std::string> names;
|
||||||
|
|
||||||
|
// Get the filename without extension.
|
||||||
|
auto name = path.stem().string();
|
||||||
|
|
||||||
|
// Skip the optional library name prefix.
|
||||||
|
const std::string lib_name_prefix{"lib"};
|
||||||
|
if (name.find(lib_name_prefix) == 0)
|
||||||
|
name = name.substr(lib_name_prefix.size());
|
||||||
|
|
||||||
|
size_t hyphen_pos = 0;
|
||||||
|
const std::string hyphen{"-"};
|
||||||
|
if ((hyphen_pos = name.find(hyphen)) != std::string::npos)
|
||||||
|
{
|
||||||
|
// Replace the hyphen with underscore.
|
||||||
|
name.replace(hyphen_pos, hyphen.size(), "_");
|
||||||
|
names.emplace_back(name);
|
||||||
|
|
||||||
|
// Also add the name without the hyphen-separated prefix.
|
||||||
|
names.emplace_back(name.substr(hyphen_pos + hyphen.size()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add the filename as the name.
|
||||||
|
names.emplace_back(std::move(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -65,23 +97,37 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
opts::notify(variables_map);
|
opts::notify(variables_map);
|
||||||
|
|
||||||
auto symbols = dll::library_info{vm_path}.symbols();
|
std::cout << "Testing " << vm_path.filename().string() << "\n"
|
||||||
auto it = std::find_if(symbols.begin(), symbols.end(), [](const std::string& symbol) {
|
<< "Path: " << vm_path.string() << "\n";
|
||||||
return symbol.find("evmc_create_") == 0;
|
|
||||||
});
|
for (auto&& name : get_vm_names(vm_path))
|
||||||
if (it == symbols.end())
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const std::string create_fn_name = "evmc_create_" + name;
|
||||||
|
std::cout << "Seeking `" << create_fn_name << "`... ";
|
||||||
|
create_fn = dll::import<evmc_create_fn>(vm_path, create_fn_name);
|
||||||
|
std::cout << "found.\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (boost::system::system_error& err)
|
||||||
|
{
|
||||||
|
using namespace boost::system;
|
||||||
|
const error_code windows_error{127, system_category()};
|
||||||
|
constexpr auto posix_error = errc::invalid_seek;
|
||||||
|
if (err.code() != posix_error && err.code() != windows_error)
|
||||||
|
throw; // Error other than "symbol not found".
|
||||||
|
std::cout << "not found.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!create_fn)
|
||||||
{
|
{
|
||||||
std::cerr << "EVMC create function not found in " << vm_path.string() << "\n";
|
std::cerr << "EVMC create function not found in " << vm_path.string() << "\n";
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
const std::string& create_fn_name = *it;
|
|
||||||
|
|
||||||
std::cout << "Testing " << vm_path.filename().string() << "\n "
|
|
||||||
<< "Path: " << vm_path.string() << "\n "
|
|
||||||
<< "Create function: " << create_fn_name << "()\n\n";
|
|
||||||
|
|
||||||
create_fn = dll::import<evmc_create_fn>(vm_path, create_fn_name);
|
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user