Skip to content

Commit 1f02f40

Browse files
committed
API for instantiation with imported functions referred by import name
1 parent 565bfbf commit 1f02f40

6 files changed

Lines changed: 157 additions & 81 deletions

File tree

lib/fizzy/execute.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,40 @@ std::unique_ptr<Instance> instantiate(Module module,
626626
return instance;
627627
}
628628

629+
std::unique_ptr<Instance> instantiate(Module module,
630+
std::vector<ImportedFunction> imported_functions, std::vector<ExternalTable> imported_tables,
631+
std::vector<ExternalMemory> imported_memories, std::vector<ExternalGlobal> imported_globals)
632+
{
633+
std::vector<ExternalFunction> external_functions;
634+
for (const auto& import : module.importsec)
635+
{
636+
if (import.kind != ExternalKind::Function)
637+
continue;
638+
639+
const auto it = std::find_if(
640+
imported_functions.begin(), imported_functions.end(), [&import](const auto& func) {
641+
return import.module == func.module && import.name == func.name;
642+
});
643+
644+
if (it == imported_functions.end())
645+
{
646+
throw instantiate_error(
647+
"imported function " + import.module + "." + import.name + " is required");
648+
}
649+
650+
assert(import.desc.function_type_index < module.typesec.size());
651+
external_functions.emplace_back(ExternalFunction{
652+
std::move(it->function), module.typesec[import.desc.function_type_index]});
653+
}
654+
655+
if (external_functions.size() != imported_functions.size())
656+
throw instantiate_error("some imported functions are not required by the module");
657+
658+
return instantiate(std::move(module), std::move(external_functions), std::move(imported_tables),
659+
std::move(imported_memories), std::move(imported_globals));
660+
}
661+
662+
629663
execution_result execute(
630664
Instance& instance, FuncIdx func_idx, std::vector<uint64_t> args, int depth)
631665
{

lib/fizzy/execute.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,21 @@ std::unique_ptr<Instance> instantiate(Module module,
9393
std::vector<ExternalMemory> imported_memories = {},
9494
std::vector<ExternalGlobal> imported_globals = {});
9595

96+
struct ImportedFunction
97+
{
98+
std::string module;
99+
std::string name;
100+
std::function<execution_result(Instance&, std::vector<uint64_t>, int depth)> function;
101+
};
102+
103+
// Instantiate a module.
104+
std::unique_ptr<Instance> instantiate(Module module,
105+
std::vector<ImportedFunction> imported_functions,
106+
std::vector<ExternalTable> imported_tables = {},
107+
std::vector<ExternalMemory> imported_memories = {},
108+
std::vector<ExternalGlobal> imported_globals = {});
109+
110+
96111
// Execute a function on an instance.
97112
execution_result execute(
98113
Instance& instance, FuncIdx func_idx, std::vector<uint64_t> args, int depth = 0);

test/unittests/api_test.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ TEST(api, find_exported_global)
171171
"017f0141010b071b050267310300026732030103746162010001660000036d656d02000a05010300010b");
172172

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

177177
opt_global = find_exported_global(*instance_reexported_global, "g1");
178178
ASSERT_TRUE(opt_global);
@@ -247,8 +247,8 @@ TEST(api, find_exported_table)
247247
"017f0041000b071604037461620100016600000267310300036d656d02000a09020300010b0300010b");
248248

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

253253
opt_table = find_exported_table(*instance_reexported_table, "tab");
254254
ASSERT_TRUE(opt_table);
@@ -288,7 +288,8 @@ TEST(api, find_exported_table_reimport)
288288

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

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

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

313314
TEST(api, find_exported_memory)
@@ -349,8 +350,8 @@ TEST(api, find_exported_memory)
349350
"017f0041000b071604036d656d02000166000002673103000374616201000a05010300010b");
350351

351352
bytes memory(PageSize, 0);
352-
auto instance_reexported_memory =
353-
instantiate(parse(wasm_reexported_memory), {}, {}, {ExternalMemory{&memory, {1, 4}}});
353+
auto instance_reexported_memory = instantiate(parse(wasm_reexported_memory),
354+
std::vector<ExternalFunction>{}, {}, {ExternalMemory{&memory, {1, 4}}});
354355

355356
opt_memory = find_exported_memory(*instance_reexported_memory, "mem");
356357
ASSERT_TRUE(opt_memory);
@@ -390,7 +391,8 @@ TEST(api, find_exported_memory_reimport)
390391

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

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

411413
// importing the same table into the module with equal limits, instantiate should succeed
412-
instantiate(parse(wasm_reimported_memory), {}, {}, {*opt_memory});
414+
instantiate(parse(wasm_reimported_memory), std::vector<ExternalFunction>{}, {}, {*opt_memory});
413415
}

test/unittests/execute_call_test.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ TEST(execute_call, call_indirect_imported_table)
157157
table_elements table{
158158
{{f3, out_i32}}, {{f2, out_i32}}, {{f1, out_i32}}, {{f4, out_i64}}, {{f5, out_i32}}};
159159

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

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

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

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

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

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

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

565565
EXPECT_THAT(execute(*instance1, 0, {}), Traps());
566566
}

test/unittests/execute_test.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ TEST(execute, global_get_imported)
138138
const auto module = parse(wasm);
139139

140140
uint64_t global_value = 42;
141-
auto instance = instantiate(module, {}, {}, {}, {ExternalGlobal{&global_value, false}});
141+
auto instance = instantiate(
142+
module, std::vector<ExternalFunction>{}, {}, {}, {ExternalGlobal{&global_value, false}});
142143

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

@@ -170,8 +171,8 @@ TEST(execute, global_get_imported_and_internal)
170171

171172
uint64_t g1 = 40;
172173
uint64_t g2 = 41;
173-
auto instance =
174-
instantiate(module, {}, {}, {}, {ExternalGlobal{&g1, false}, ExternalGlobal{&g2, false}});
174+
auto instance = instantiate(module, std::vector<ExternalFunction>{}, {}, {},
175+
{ExternalGlobal{&g1, false}, ExternalGlobal{&g2, false}});
175176

176177
EXPECT_THAT(execute(*instance, 0, {}), Result(40));
177178
EXPECT_THAT(execute(*instance, 1, {}), Result(41));
@@ -231,7 +232,8 @@ TEST(execute, global_set_imported)
231232
"0061736d01000000010401600000020d01036d6f6404676c6f62037f01030201000a08010600412a24000b");
232233

233234
uint64_t global_value = 41;
234-
auto instance = instantiate(parse(wasm), {}, {}, {}, {ExternalGlobal{&global_value, true}});
235+
auto instance = instantiate(parse(wasm), std::vector<ExternalFunction>{}, {}, {},
236+
{ExternalGlobal{&global_value, true}});
235237
EXPECT_THAT(execute(*instance, 0, {}), Result());
236238
EXPECT_EQ(global_value, 42);
237239
}
@@ -249,7 +251,8 @@ TEST(execute, i32_load_imported_memory)
249251
"0061736d0100000001060160017f017f020b01036d6f64016d02010101030201000a0901070020002802000b");
250252

251253
bytes memory(PageSize, 0);
252-
auto instance = instantiate(parse(wasm), {}, {}, {{&memory, {1, 1}}});
254+
auto instance =
255+
instantiate(parse(wasm), std::vector<ExternalFunction>{}, {}, {{&memory, {1, 1}}});
253256
memory[1] = 42;
254257
EXPECT_THAT(execute(*instance, 0, {1}), Result(42));
255258

@@ -393,7 +396,8 @@ TEST(execute, i32_store_imported_memory)
393396
"0b");
394397

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

0 commit comments

Comments
 (0)