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 2bf2e87 commit 874b9ba
Showing 1 changed file with 116 additions and 0 deletions.
116 changes: 116 additions & 0 deletions test/unittests/api_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,122 @@ 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};
const 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));

const 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};
const 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));

const 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");

const 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");

const 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 874b9ba

Please sign in to comment.