Skip to content

Commit

Permalink
test: resolving imported globals
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed Nov 18, 2020
1 parent d25b5c2 commit 94fab2d
Showing 1 changed file with 120 additions and 0 deletions.
120 changes: 120 additions & 0 deletions test/unittests/api_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,126 @@ TEST(api, resolve_imported_function_duplicate)
EXPECT_THAT(execute(*instance, 1, {Value{0}}), Result(42));
}

TEST(api, resolve_imported_globals)
{
/* wat2wasm
(global (import "mod1" "g1") i32)
(global (import "mod1" "g2") (mut i32))
(global (import "mod2" "g1") i64)
(global (import "mod2" "g2") (mut i64))
(func (import "mod1" "foo1")
(param i32) (result i32)) ;; just to test combination with other import types
(func (result i32) (global.get 0))
(func (result i32) (global.get 1))
(func (result i64) (global.get 2))
(func (result i64) (global.get 3))
*/
const auto wasm = from_hex(
"0061736d01000000010e0360017f017f6000017f6000017e023905046d6f6431026731037f00046d6f64310267"
"32037f01046d6f6432026731037e00046d6f6432026732037e01046d6f643104666f6f31000003050401010202"
"0a1504040023000b040023010b040023020b040023030b");
const auto module = parse(wasm);

std::vector<ImportedFunction> imported_functions = {
{"mod1", "foo1", {ValType::i32}, ValType::i32, function_returning_value(1)},
};
const auto external_functions = resolve_imported_functions(*module, imported_functions);
EXPECT_EQ(external_functions.size(), 1);

Value global1{42};
Value global2{43};
Value global3{44};
Value global4{45};
std::vector<ImportedGlobal> imported_globals = {
{"mod1", "g1", &global1, ValType::i32, false},
{"mod1", "g2", &global2, ValType::i32, true},
{"mod2", "g1", &global3, ValType::i64, false},
{"mod2", "g2", &global4, ValType::i64, true},
};

const auto external_globals = resolve_imported_globals(*module, imported_globals);
EXPECT_EQ(external_globals.size(), 4);

auto instance = instantiate(*module, external_functions, {}, {}, external_globals);

EXPECT_THAT(execute(*instance, 1, nullptr), Result(42));
EXPECT_THAT(execute(*instance, 2, nullptr), Result(43));
EXPECT_THAT(execute(*instance, 3, nullptr), Result(44));
EXPECT_THAT(execute(*instance, 4, nullptr), Result(45));


std::vector<ImportedGlobal> imported_globals_reordered = {
{"mod2", "g1", &global3, ValType::i64, false},
{"mod1", "g2", &global2, ValType::i32, true},
{"mod1", "g1", &global1, ValType::i32, false},
{"mod2", "g2", &global4, ValType::i64, true},
};
const auto external_globals_reordered =
resolve_imported_globals(*module, imported_globals_reordered);
EXPECT_EQ(external_globals_reordered.size(), 4);

auto instance_reordered =
instantiate(*module, external_functions, {}, {}, external_globals_reordered);

EXPECT_THAT(execute(*instance_reordered, 1, nullptr), Result(42));
EXPECT_THAT(execute(*instance_reordered, 2, nullptr), Result(43));
EXPECT_THAT(execute(*instance_reordered, 3, nullptr), Result(44));
EXPECT_THAT(execute(*instance_reordered, 4, nullptr), Result(45));


Value global5{46};
Value global6{47};
std::vector<ImportedGlobal> imported_globals_extra = {
{"mod1", "g1", &global1, ValType::i32, false},
{"mod1", "g2", &global2, ValType::i32, true},
{"mod2", "g1", &global3, ValType::i64, false},
{"mod2", "g2", &global4, ValType::i64, true},
{"mod3", "g1", &global5, ValType::i32, false},
{"mod3", "g2", &global6, ValType::i32, true},
};

const auto external_globals_extra = resolve_imported_globals(*module, imported_globals_extra);
EXPECT_EQ(external_globals_extra.size(), 4);

auto instance_extra = instantiate(*module, external_functions, {}, {}, external_globals_extra);

EXPECT_THAT(execute(*instance_reordered, 1, nullptr), Result(42));
EXPECT_THAT(execute(*instance_reordered, 2, nullptr), Result(43));
EXPECT_THAT(execute(*instance_reordered, 3, nullptr), Result(44));
EXPECT_THAT(execute(*instance_reordered, 4, nullptr), Result(45));


std::vector<ImportedGlobal> imported_globals_missing = {
{"mod2", "g1", &global3, ValType::i64, false},
{"mod1", "g2", &global2, ValType::i32, true},
{"mod1", "g1", &global1, ValType::i32, false},
};

EXPECT_THROW_MESSAGE(resolve_imported_globals(*module, imported_globals_missing),
instantiate_error, "imported global mod2.g2 is required");


std::vector<ImportedGlobal> imported_globals_invalid_type1 = {
{"mod1", "g1", &global1, ValType::i64, false},
{"mod1", "g2", &global2, ValType::i32, true},
{"mod2", "g1", &global3, ValType::i64, false},
{"mod2", "g2", &global4, ValType::i64, true},
};

EXPECT_THROW_MESSAGE(resolve_imported_globals(*module, imported_globals_invalid_type1),
instantiate_error, "global mod1.g1 value type doesn't match imported global in module");

std::vector<ImportedGlobal> imported_globals_invalid_type2 = {
{"mod1", "g1", &global1, ValType::i32, true},
{"mod1", "g2", &global2, ValType::i32, true},
{"mod2", "g1", &global3, ValType::i64, false},
{"mod2", "g2", &global4, ValType::i64, true},
};

EXPECT_THROW_MESSAGE(resolve_imported_globals(*module, imported_globals_invalid_type2),
instantiate_error, "global mod1.g1 mutability doesn't match imported global in module");
}

TEST(api, find_exported_function_index)
{
Module module;
Expand Down

0 comments on commit 94fab2d

Please sign in to comment.