Skip to content

Commit

Permalink
API for instantiation with imported functions referred by import name
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed May 18, 2020
1 parent 565bfbf commit 1f02f40
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 81 deletions.
34 changes: 34 additions & 0 deletions lib/fizzy/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,40 @@ std::unique_ptr<Instance> instantiate(Module module,
return instance;
}

std::unique_ptr<Instance> instantiate(Module module,
std::vector<ImportedFunction> imported_functions, std::vector<ExternalTable> imported_tables,
std::vector<ExternalMemory> imported_memories, std::vector<ExternalGlobal> imported_globals)
{
std::vector<ExternalFunction> external_functions;
for (const auto& import : module.importsec)
{
if (import.kind != ExternalKind::Function)
continue;

const auto it = std::find_if(
imported_functions.begin(), imported_functions.end(), [&import](const auto& func) {
return import.module == func.module && import.name == func.name;
});

if (it == imported_functions.end())
{
throw instantiate_error(
"imported function " + import.module + "." + import.name + " is required");
}

assert(import.desc.function_type_index < module.typesec.size());
external_functions.emplace_back(ExternalFunction{
std::move(it->function), module.typesec[import.desc.function_type_index]});
}

if (external_functions.size() != imported_functions.size())
throw instantiate_error("some imported functions are not required by the module");

return instantiate(std::move(module), std::move(external_functions), std::move(imported_tables),
std::move(imported_memories), std::move(imported_globals));
}


execution_result execute(
Instance& instance, FuncIdx func_idx, std::vector<uint64_t> args, int depth)
{
Expand Down
15 changes: 15 additions & 0 deletions lib/fizzy/execute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ std::unique_ptr<Instance> instantiate(Module module,
std::vector<ExternalMemory> imported_memories = {},
std::vector<ExternalGlobal> imported_globals = {});

struct ImportedFunction
{
std::string module;
std::string name;
std::function<execution_result(Instance&, std::vector<uint64_t>, int depth)> function;
};

// Instantiate a module.
std::unique_ptr<Instance> instantiate(Module module,
std::vector<ImportedFunction> imported_functions,
std::vector<ExternalTable> imported_tables = {},
std::vector<ExternalMemory> imported_memories = {},
std::vector<ExternalGlobal> imported_globals = {});


// Execute a function on an instance.
execution_result execute(
Instance& instance, FuncIdx func_idx, std::vector<uint64_t> args, int depth = 0);
Expand Down
22 changes: 12 additions & 10 deletions test/unittests/api_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ TEST(api, find_exported_global)
"017f0141010b071b050267310300026732030103746162010001660000036d656d02000a05010300010b");

uint64_t g1 = 42;
auto instance_reexported_global =
instantiate(parse(wasm_reexported_global), {}, {}, {}, {ExternalGlobal{&g1, false}});
auto instance_reexported_global = instantiate(parse(wasm_reexported_global),
std::vector<ExternalFunction>{}, {}, {}, {ExternalGlobal{&g1, false}});

opt_global = find_exported_global(*instance_reexported_global, "g1");
ASSERT_TRUE(opt_global);
Expand Down Expand Up @@ -247,8 +247,8 @@ TEST(api, find_exported_table)
"017f0041000b071604037461620100016600000267310300036d656d02000a09020300010b0300010b");

table_elements table(2);
auto instance_reexported_table =
instantiate(parse(wasm_reexported_table), {}, {ExternalTable{&table, {2, 20}}});
auto instance_reexported_table = instantiate(parse(wasm_reexported_table),
std::vector<ExternalFunction>{}, {ExternalTable{&table, {2, 20}}});

opt_table = find_exported_table(*instance_reexported_table, "tab");
ASSERT_TRUE(opt_table);
Expand Down Expand Up @@ -288,7 +288,8 @@ TEST(api, find_exported_table_reimport)

// importing the table with limits narrower than defined in the module
table_elements table(5);
auto instance = instantiate(parse(wasm), {}, {ExternalTable{&table, {5, 10}}});
auto instance =
instantiate(parse(wasm), std::vector<ExternalFunction>{}, {ExternalTable{&table, {5, 10}}});

auto opt_table = find_exported_table(*instance, "tab");
ASSERT_TRUE(opt_table);
Expand All @@ -307,7 +308,7 @@ TEST(api, find_exported_table_reimport)
from_hex("0061736d010000000211010474657374057461626c65017001050a");

// importing the same table into the module with equal limits, instantiate should succeed
instantiate(parse(wasm_reimported_table), {}, {*opt_table});
instantiate(parse(wasm_reimported_table), std::vector<ExternalFunction>{}, {*opt_table});
}

TEST(api, find_exported_memory)
Expand Down Expand Up @@ -349,8 +350,8 @@ TEST(api, find_exported_memory)
"017f0041000b071604036d656d02000166000002673103000374616201000a05010300010b");

bytes memory(PageSize, 0);
auto instance_reexported_memory =
instantiate(parse(wasm_reexported_memory), {}, {}, {ExternalMemory{&memory, {1, 4}}});
auto instance_reexported_memory = instantiate(parse(wasm_reexported_memory),
std::vector<ExternalFunction>{}, {}, {ExternalMemory{&memory, {1, 4}}});

opt_memory = find_exported_memory(*instance_reexported_memory, "mem");
ASSERT_TRUE(opt_memory);
Expand Down Expand Up @@ -390,7 +391,8 @@ TEST(api, find_exported_memory_reimport)

// importing the memory with limits narrower than defined in the module
bytes memory(2 * PageSize, 0);
auto instance = instantiate(parse(wasm), {}, {}, {ExternalMemory{&memory, {2, 5}}});
auto instance = instantiate(
parse(wasm), std::vector<ExternalFunction>{}, {}, {ExternalMemory{&memory, {2, 5}}});

auto opt_memory = find_exported_memory(*instance, "mem");
ASSERT_TRUE(opt_memory);
Expand All @@ -409,5 +411,5 @@ TEST(api, find_exported_memory_reimport)
from_hex("0061736d010000000211010474657374066d656d6f727902010205");

// importing the same table into the module with equal limits, instantiate should succeed
instantiate(parse(wasm_reimported_memory), {}, {}, {*opt_memory});
instantiate(parse(wasm_reimported_memory), std::vector<ExternalFunction>{}, {}, {*opt_memory});
}
10 changes: 5 additions & 5 deletions test/unittests/execute_call_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ TEST(execute_call, call_indirect_imported_table)
table_elements table{
{{f3, out_i32}}, {{f2, out_i32}}, {{f1, out_i32}}, {{f4, out_i64}}, {{f5, out_i32}}};

auto instance = instantiate(module, {}, {{&table, {5, 20}}});
auto instance = instantiate(module, std::vector<ExternalFunction>{}, {{&table, {5, 20}}});

for (const auto param : {0u, 1u, 2u})
{
Expand Down Expand Up @@ -383,7 +383,7 @@ TEST(execute_call, imported_table_from_another_module)
const auto table = fizzy::find_exported_table(*instance1, "tab");
ASSERT_TRUE(table.has_value());

auto instance2 = instantiate(module2, {}, {*table});
auto instance2 = instantiate(module2, std::vector<ExternalFunction>{}, {*table});

EXPECT_THAT(execute(*instance2, 0, {44, 2}), Result(42));
}
Expand Down Expand Up @@ -427,8 +427,8 @@ TEST(execute_call, imported_table_modified_by_uninstantiable_module)
const auto table = fizzy::find_exported_table(*instance1, "tab");
ASSERT_TRUE(table.has_value());

EXPECT_THROW_MESSAGE(
instantiate(module2, {}, {*table}), instantiate_error, "Start function failed to execute");
EXPECT_THROW_MESSAGE(instantiate(module2, std::vector<ExternalFunction>{}, {*table}),
instantiate_error, "Start function failed to execute");

EXPECT_THAT(execute(*instance1, 0, {44, 2}), Result(42));
}
Expand Down Expand Up @@ -560,7 +560,7 @@ TEST(execute_call, call_indirect_imported_table_infinite_recursion)
const auto table = fizzy::find_exported_table(*instance1, "tab");
ASSERT_TRUE(table.has_value());

auto instance2 = instantiate(module2, {}, {*table});
auto instance2 = instantiate(module2, std::vector<ExternalFunction>{}, {*table});

EXPECT_THAT(execute(*instance1, 0, {}), Traps());
}
16 changes: 10 additions & 6 deletions test/unittests/execute_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ TEST(execute, global_get_imported)
const auto module = parse(wasm);

uint64_t global_value = 42;
auto instance = instantiate(module, {}, {}, {}, {ExternalGlobal{&global_value, false}});
auto instance = instantiate(
module, std::vector<ExternalFunction>{}, {}, {}, {ExternalGlobal{&global_value, false}});

EXPECT_THAT(execute(*instance, 0, {}), Result(42));

Expand Down Expand Up @@ -170,8 +171,8 @@ TEST(execute, global_get_imported_and_internal)

uint64_t g1 = 40;
uint64_t g2 = 41;
auto instance =
instantiate(module, {}, {}, {}, {ExternalGlobal{&g1, false}, ExternalGlobal{&g2, false}});
auto instance = instantiate(module, std::vector<ExternalFunction>{}, {}, {},
{ExternalGlobal{&g1, false}, ExternalGlobal{&g2, false}});

EXPECT_THAT(execute(*instance, 0, {}), Result(40));
EXPECT_THAT(execute(*instance, 1, {}), Result(41));
Expand Down Expand Up @@ -231,7 +232,8 @@ TEST(execute, global_set_imported)
"0061736d01000000010401600000020d01036d6f6404676c6f62037f01030201000a08010600412a24000b");

uint64_t global_value = 41;
auto instance = instantiate(parse(wasm), {}, {}, {}, {ExternalGlobal{&global_value, true}});
auto instance = instantiate(parse(wasm), std::vector<ExternalFunction>{}, {}, {},
{ExternalGlobal{&global_value, true}});
EXPECT_THAT(execute(*instance, 0, {}), Result());
EXPECT_EQ(global_value, 42);
}
Expand All @@ -249,7 +251,8 @@ TEST(execute, i32_load_imported_memory)
"0061736d0100000001060160017f017f020b01036d6f64016d02010101030201000a0901070020002802000b");

bytes memory(PageSize, 0);
auto instance = instantiate(parse(wasm), {}, {}, {{&memory, {1, 1}}});
auto instance =
instantiate(parse(wasm), std::vector<ExternalFunction>{}, {}, {{&memory, {1, 1}}});
memory[1] = 42;
EXPECT_THAT(execute(*instance, 0, {1}), Result(42));

Expand Down Expand Up @@ -393,7 +396,8 @@ TEST(execute, i32_store_imported_memory)
"0b");

bytes memory(PageSize, 0);
auto instance = instantiate(parse(wasm), {}, {}, {{&memory, {1, 1}}});
auto instance =
instantiate(parse(wasm), std::vector<ExternalFunction>{}, {}, {{&memory, {1, 1}}});
EXPECT_THAT(execute(*instance, 0, {42, 0}), Result());
EXPECT_EQ(memory.substr(0, 4), from_hex("2a000000"));

Expand Down
Loading

0 comments on commit 1f02f40

Please sign in to comment.