Skip to content

Commit

Permalink
Merge pull request #617 from ethereum/loader_error
Browse files Browse the repository at this point in the history
loader: Introduce error code for initialization
  • Loading branch information
chfast authored Dec 22, 2021
2 parents 0ef6371 + 427a300 commit 9f9d4d8
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 30 deletions.
4 changes: 2 additions & 2 deletions bindings/go/evmc/evmc.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ type VM struct {

func Load(filename string) (vm *VM, err error) {
cfilename := C.CString(filename)
var loaderErr C.enum_evmc_loader_error_code
loaderErr := C.enum_evmc_loader_error_code(C.EVMC_LOADER_UNSPECIFIED_ERROR)
handle := C.evmc_load_and_create(cfilename, &loaderErr)
C.free(unsafe.Pointer(cfilename))

Expand All @@ -136,7 +136,7 @@ func Load(filename string) (vm *VM, err error) {

func LoadAndConfigure(config string) (vm *VM, err error) {
cconfig := C.CString(config)
var loaderErr C.enum_evmc_loader_error_code
loaderErr := C.enum_evmc_loader_error_code(C.EVMC_LOADER_UNSPECIFIED_ERROR)
handle := C.evmc_load_and_configure(cconfig, &loaderErr)
C.free(unsafe.Pointer(cconfig))

Expand Down
2 changes: 1 addition & 1 deletion bindings/java/c/evmc-vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ JNIEXPORT jobject JNICALL Java_org_ethereum_evmc_EvmcVm_load_1and_1create(JNIEnv
// load the EVM
const char* filename = (*jenv)->GetStringUTFChars(jenv, jfilename, NULL);
assert(filename != NULL);
enum evmc_loader_error_code loader_error;
enum evmc_loader_error_code loader_error = EVMC_LOADER_UNSPECIFIED_ERROR;
evm = evmc_load_and_create(filename, &loader_error);
(*jenv)->ReleaseStringUTFChars(jenv, jfilename, filename);
if (loader_error != EVMC_LOADER_SUCCESS)
Expand Down
11 changes: 9 additions & 2 deletions include/evmc/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ extern "C" {
/** The function pointer type for EVMC create functions. */
typedef struct evmc_vm* (*evmc_create_fn)(void);

/** Error codes for the EVMC loader. */
/// Error codes for the EVMC loader.
///
/// Objects of this type SHOULD be initialized with ::EVMC_LOADER_UNSPECIFIED_ERROR
/// before passing to the EVMC loader.
enum evmc_loader_error_code
{
/** The loader succeeded. */
Expand All @@ -46,7 +49,11 @@ enum evmc_loader_error_code
EVMC_LOADER_INVALID_OPTION_NAME = 6,

/** The VM option value is invalid. */
EVMC_LOADER_INVALID_OPTION_VALUE = 7
EVMC_LOADER_INVALID_OPTION_VALUE = 7,

/// This error value will be never returned by the EVMC loader,
/// but can be used by users to init evmc_loader_error_code objects.
EVMC_LOADER_UNSPECIFIED_ERROR = -1
};

/**
Expand Down
46 changes: 23 additions & 23 deletions test/unittests/loader_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ TEST_F(loader, strcpy_sx)
TEST_F(loader, load_nonexistent)
{
constexpr auto path = "nonexistent";
evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
EXPECT_TRUE(evmc_load(path, &ec) == nullptr);
EXPECT_EQ(ec, EVMC_LOADER_CANNOT_OPEN);
EXPECT_TRUE(evmc_load(path, nullptr) == nullptr);
Expand All @@ -165,7 +165,7 @@ TEST_F(loader, load_nonexistent)
TEST_F(loader, load_long_path)
{
const std::string path(5000, 'a');
evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
EXPECT_TRUE(evmc_load(path.c_str(), &ec) == nullptr);
EXPECT_STREQ(evmc_last_error_msg(),
"invalid argument: file name is too long (5000, maximum allowed length is 4096)");
Expand All @@ -179,7 +179,7 @@ TEST_F(loader, load_long_path)

TEST_F(loader, load_null_path)
{
evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
EXPECT_TRUE(evmc_load(nullptr, &ec) == nullptr);
EXPECT_EQ(ec, EVMC_LOADER_INVALID_ARGUMENT);
EXPECT_STREQ(evmc_last_error_msg(), "invalid argument: file name cannot be null");
Expand All @@ -191,7 +191,7 @@ TEST_F(loader, load_null_path)

TEST_F(loader, load_empty_path)
{
evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
EXPECT_TRUE(evmc_load("", &ec) == nullptr);
EXPECT_STREQ(evmc_last_error_msg(), "invalid argument: file name cannot be empty");
EXPECT_TRUE(evmc_last_error_msg() == nullptr);
Expand All @@ -214,7 +214,7 @@ TEST_F(loader, load_aaa)
for (auto& path : paths)
{
setup(path, "evmc_create_aaa", create_aaa);
evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
const auto fn = evmc_load(path, &ec);
EXPECT_EQ(ec, EVMC_LOADER_SUCCESS);
ASSERT_TRUE(fn != nullptr);
Expand All @@ -239,7 +239,7 @@ TEST_F(loader, load_file_with_multiple_extensions)
for (auto& path : paths)
{
setup(path, "evmc_create_aaa", create_aaa);
evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
const auto fn = evmc_load(path, &ec);
EXPECT_EQ(ec, EVMC_LOADER_SUCCESS);
ASSERT_TRUE(fn != nullptr);
Expand All @@ -251,7 +251,7 @@ TEST_F(loader, load_file_with_multiple_extensions)
TEST_F(loader, load_eee_bbb)
{
setup("unittests/eee-bbb.dll", "evmc_create_eee_bbb", create_eee_bbb);
evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto fn = evmc_load(evmc_test_library_path, &ec);
const auto expected_vm_ptr = reinterpret_cast<evmc_vm*>(0xeeebbb);
ASSERT_TRUE(fn != nullptr);
Expand All @@ -278,7 +278,7 @@ TEST_F(loader, load_windows_path)
bool should_open = is_windows || std::strchr(path, '\\') == nullptr;
setup(should_open ? path : nullptr, "evmc_create_eee_bbb", create_eee_bbb);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
evmc_load(path, &ec);
if (should_open)
{
Expand Down Expand Up @@ -311,7 +311,7 @@ TEST_F(loader, load_symbol_not_found)
{
setup(path, "evmc_create_aaa", create_aaa);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
EXPECT_TRUE(evmc_load(evmc_test_library_path, &ec) == nullptr);
EXPECT_EQ(ec, EVMC_LOADER_SYMBOL_NOT_FOUND);
EXPECT_EQ(evmc_last_error_msg(), "EVMC create function not found in " + std::string(path));
Expand All @@ -324,7 +324,7 @@ TEST_F(loader, load_default_symbol)
{
setup("default.evmc", "evmc_create", create_aaa);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto fn = evmc_load(evmc_test_library_path, &ec);
EXPECT_EQ(ec, EVMC_LOADER_SUCCESS);
EXPECT_EQ(fn, &create_aaa);
Expand All @@ -337,7 +337,7 @@ TEST_F(loader, load_and_create_failure)
{
setup("failure.vm", "evmc_create", create_failure);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc_load_and_create(evmc_test_library_path, &ec);
EXPECT_TRUE(vm == nullptr);
EXPECT_EQ(ec, EVMC_LOADER_VM_CREATION_FAILURE);
Expand All @@ -353,7 +353,7 @@ TEST_F(loader, load_and_create_abi_mismatch)
{
setup("abi1985.vm", "evmc_create", create_vm_with_wrong_abi);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc_load_and_create(evmc_test_library_path, &ec);
EXPECT_TRUE(vm == nullptr);
EXPECT_EQ(ec, EVMC_LOADER_ABI_VERSION_MISMATCH);
Expand All @@ -374,7 +374,7 @@ TEST_F(loader, load_and_configure_no_options)
{
setup("path", "evmc_create", create_vm_with_set_option);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc_load_and_configure("path", &ec);
EXPECT_TRUE(vm);
EXPECT_TRUE(recorded_options.empty());
Expand All @@ -395,7 +395,7 @@ TEST_F(loader, load_and_configure_single_option)

setup("path", "evmc_create", create_vm_with_set_option);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc_load_and_configure("path,o=1", &ec);
EXPECT_TRUE(vm);
ASSERT_EQ(recorded_options.size(), size_t{1});
Expand All @@ -418,7 +418,7 @@ TEST_F(loader, load_and_configure_uknown_option)

setup("path", "evmc_create", create_vm_with_set_option);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc_load_and_configure("path,z=1", &ec);
EXPECT_FALSE(vm);
ASSERT_EQ(recorded_options.size(), size_t{1});
Expand Down Expand Up @@ -448,7 +448,7 @@ TEST_F(loader, load_and_configure_multiple_options)

setup("path", "evmc_create", create_vm_with_set_option);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc_load_and_configure("path,a=_a,b=_b1,c=_c,b=_b2", &ec);
EXPECT_TRUE(vm);
ASSERT_EQ(recorded_options.size(), size_t{4});
Expand Down Expand Up @@ -483,7 +483,7 @@ TEST_F(loader, load_and_configure_uknown_option_in_sequence)

setup("path", "evmc_create", create_vm_with_set_option);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc_load_and_configure("path,a=_a,b=_b,c=_b,", &ec);
EXPECT_FALSE(vm);
ASSERT_EQ(recorded_options.size(), size_t{3});
Expand Down Expand Up @@ -518,7 +518,7 @@ TEST_F(loader, load_and_configure_empty_values)

setup("path", "evmc_create", create_vm_with_set_option);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc_load_and_configure("path,flag,e=,flag=,e", &ec);
EXPECT_TRUE(vm);
ASSERT_EQ(recorded_options.size(), size_t{4});
Expand All @@ -541,7 +541,7 @@ TEST_F(loader, load_and_configure_degenerated_names)

setup("path", "evmc_create", create_vm_with_set_option);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc_load_and_configure("path,,,=,,=xxx", &ec);
EXPECT_TRUE(vm);
ASSERT_EQ(recorded_options.size(), size_t{5});
Expand All @@ -568,7 +568,7 @@ TEST_F(loader, load_and_configure_comma_at_the_end)

setup("path", "evmc_create", create_vm_with_set_option);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc_load_and_configure("path,x=x,", &ec);
EXPECT_TRUE(vm);
ASSERT_EQ(recorded_options.size(), size_t{1});
Expand All @@ -586,7 +586,7 @@ TEST_F(loader, load_and_configure_vm_without_set_option)

setup("path", "evmc_create", create_vm_barebone);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc_load_and_configure("path,a=0,b=1", &ec);
EXPECT_FALSE(vm);
EXPECT_TRUE(recorded_options.empty());
Expand Down Expand Up @@ -614,7 +614,7 @@ TEST_F(loader, load_and_configure_config_too_long)
{
setup("path", "evmc_create", create_vm_barebone);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto config = std::string{"path,"};
config.append(10000, 'x');
auto vm = evmc_load_and_configure(config.c_str(), &ec);
Expand Down Expand Up @@ -647,7 +647,7 @@ TEST_F(loader, load_and_configure_unknown_set_option_error_code)

setup("path", "evmc_create", create_vm_with_set_option);

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
const auto config_str = "path," + option_name_causing_unknown_error + "=1";
auto vm = evmc_load_and_configure(config_str.c_str(), &ec);
EXPECT_FALSE(vm);
Expand Down
2 changes: 1 addition & 1 deletion tools/evmc/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ int main(int argc, const char** argv)
evmc::VM vm;
if (vm_option.count() != 0)
{
evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
vm = VM{evmc_load_and_configure(vm_config.c_str(), &ec)};
if (ec != EVMC_LOADER_SUCCESS)
{
Expand Down
2 changes: 1 addition & 1 deletion tools/vmtester/vmtester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ int main(int argc, char* argv[])
const auto& evmc_module = cli.arguments[0];
std::cout << "Testing " << evmc_module << "\n";

evmc_loader_error_code ec;
evmc_loader_error_code ec = EVMC_LOADER_UNSPECIFIED_ERROR;
auto vm = evmc::VM{evmc_load_and_configure(evmc_module.c_str(), &ec)};
if (ec != EVMC_LOADER_SUCCESS)
{
Expand Down

0 comments on commit 9f9d4d8

Please sign in to comment.