22 #include <libaleth-interpreter/interpreter.h>
24 #include <evmc/loader.h>
26 namespace po = boost::program_options;
40 std::unique_ptr<EVMC> g_evmcDll;
46 struct VMKindTableEntry
56 VMKindTableEntry vmKindsTable[] = {
61 void setVMKind(
const std::string& _name)
63 for (
auto& entry : vmKindsTable)
66 if (_name == entry.name)
79 evmc_loader_error_code ec;
80 evmc_instance *instance = evmc_load_and_create(_name.c_str(), &ec);
81 assert(ec == EVMC_LOADER_SUCCESS || instance ==
nullptr);
85 case EVMC_LOADER_SUCCESS:
87 case EVMC_LOADER_CANNOT_OPEN:
88 BOOST_THROW_EXCEPTION(
89 po::validation_error(po::validation_error::invalid_option_value,
"vm", _name, 1));
90 case EVMC_LOADER_SYMBOL_NOT_FOUND:
91 BOOST_THROW_EXCEPTION(std::system_error(std::make_error_code(std::errc::invalid_seek),
92 "loading " + _name +
" failed: EVMC create function not found"));
93 case EVMC_LOADER_ABI_VERSION_MISMATCH:
94 BOOST_THROW_EXCEPTION(std::system_error(std::make_error_code(std::errc::invalid_argument),
95 "loading " + _name +
" failed: EVMC ABI version mismatch"));
97 BOOST_THROW_EXCEPTION(
98 std::system_error(std::error_code(
static_cast<int>(ec), std::generic_category()),
99 "loading " + _name +
" failed"));
102 g_evmcDll.reset(
new EVMC{instance});
104 cnote <<
"Loaded EVMC module: " << g_evmcDll->name() <<
" " << g_evmcDll->version() <<
" ("
113 const char c_evmcPrefix[] =
"evmc ";
116 std::vector<std::pair<std::string, std::string>> s_evmcOptions;
122 void parseEvmcOptions(
const std::vector<std::string>& _opts)
124 for (
auto& s : _opts)
126 auto separatorPos = s.find(
'=');
127 if (separatorPos == s.npos)
128 throw po::invalid_syntax{po::invalid_syntax::missing_parameter, c_evmcPrefix + s};
129 auto name = s.substr(0, separatorPos);
130 auto value = s.substr(separatorPos + 1);
131 s_evmcOptions.emplace_back(std::move(
name), std::move(value));
136 std::vector<std::pair<std::string, std::string>>&
evmcOptions() noexcept
138 return s_evmcOptions;
144 static const std::string description = [] {
146 for (
auto& entry : vmKindsTable)
153 return "Select VM implementation. Available options are: " + names +
".";
156 po::options_description opts(
"VM OPTIONS", _lineLength);
157 auto add = opts.add_options();
160 po::value<std::string>()
161 ->value_name(
"<name>|<path>")
162 ->default_value(
"legacy")
163 ->notifier(setVMKind),
167 po::value<std::vector<std::string>>()
169 ->value_name(
"<option>=<value>")
170 ->notifier(parseEvmcOptions),
184 static const auto default_delete = [](
VMFace * _vm) noexcept {
delete _vm; };
185 static const auto null_delete = [](
VMFace*) noexcept {};
190 return {
new EVMC{evmc_create_interpreter()}, default_delete};
192 assert(g_evmcDll !=
nullptr);
194 return {g_evmcDll.get(), null_delete};
197 return {
new LegacyVM, default_delete};