Skip to content

Commit

Permalink
capi: Add imported globals to instantiate
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed Oct 26, 2020
1 parent 0dbf5ed commit aea94af
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 28 deletions.
20 changes: 18 additions & 2 deletions include/fizzy/fizzy.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ typedef struct FizzyExternalFunction
void* context;
} FizzyExternalFunction;

/// Global type.
typedef struct FizzyGlobalType
{
FizzyValueType value_type;
bool is_mutable;
} FizzyGlobalType;

/// External global.
typedef struct FizzyExternalGlobal
{
FizzyValue* value;
FizzyGlobalType type;
} FizzyExternalGlobal;

/// Imported function.
typedef struct FizzyImportedFunction
{
Expand Down Expand Up @@ -139,7 +153,8 @@ bool fizzy_find_exported_function(
/// When number of passed functions or their order is different from the one defined by the
/// module, behaviour is undefined.
FizzyInstance* fizzy_instantiate(const FizzyModule* module,
const FizzyExternalFunction* imported_functions, size_t imported_functions_size);
const FizzyExternalFunction* imported_functions, size_t imported_functions_size,
const FizzyExternalGlobal* imported_globals, size_t imported_globals_size);

/// Instantiate a module resolving imported functions.
/// Takes ownership of module, i.e. @p module is invalidated after this call.
Expand All @@ -155,7 +170,8 @@ FizzyInstance* fizzy_instantiate(const FizzyModule* module,
/// functions not required by the module.
/// Functions are matched to module's imports based on their module and name strings.
FizzyInstance* fizzy_resolve_instantiate(const FizzyModule* module,
const FizzyImportedFunction* imported_functions, size_t imported_functions_size);
const FizzyImportedFunction* imported_functions, size_t imported_functions_size,
const FizzyExternalGlobal* imported_globals, size_t imported_globals_size);

/// Free resources associated with the instance.
/// If passed pointer is NULL, has no effect.
Expand Down
37 changes: 32 additions & 5 deletions lib/fizzy/capi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ inline const fizzy::Value* unwrap(const FizzyValue* values) noexcept
return reinterpret_cast<const fizzy::Value*>(values);
}

inline fizzy::Value* unwrap(FizzyValue* value) noexcept
{
return reinterpret_cast<fizzy::Value*>(value);
}

inline FizzyInstance* wrap(fizzy::Instance* instance) noexcept
{
return reinterpret_cast<FizzyInstance*>(instance);
Expand Down Expand Up @@ -138,6 +143,15 @@ inline fizzy::ImportedFunction unwrap(const FizzyImportedFunction& c_imported_fu
return imported_func;
}

inline fizzy::GlobalType unwrap(const FizzyGlobalType& global_type) noexcept
{
return {unwrap(global_type.value_type), global_type.is_mutable};
}

inline fizzy::ExternalGlobal unwrap(const FizzyExternalGlobal& external_global) noexcept
{
return fizzy::ExternalGlobal{unwrap(external_global.value), unwrap(external_global.type)};
}
} // namespace

extern "C" {
Expand Down Expand Up @@ -189,7 +203,8 @@ bool fizzy_find_exported_function(
}

FizzyInstance* fizzy_instantiate(const FizzyModule* module,
const FizzyExternalFunction* imported_functions, size_t imported_functions_size)
const FizzyExternalFunction* imported_functions, size_t imported_functions_size,
const FizzyExternalGlobal* imported_globals, size_t imported_globals_size)
{
try
{
Expand All @@ -198,8 +213,13 @@ FizzyInstance* fizzy_instantiate(const FizzyModule* module,
std::transform(imported_functions, imported_functions + imported_functions_size,
functions.begin(), unwrap_external_func_fn);

auto instance = fizzy::instantiate(
std::unique_ptr<const fizzy::Module>(unwrap(module)), std::move(functions));
std::vector<fizzy::ExternalGlobal> globals(imported_globals_size);
fizzy::ExternalGlobal (*unwrap_external_global_fn)(const FizzyExternalGlobal&) = &unwrap;
std::transform(imported_globals, imported_globals + imported_globals_size, globals.begin(),
unwrap_external_global_fn);

auto instance = fizzy::instantiate(std::unique_ptr<const fizzy::Module>(unwrap(module)),
std::move(functions), {}, {}, std::move(globals));

return wrap(instance.release());
}
Expand All @@ -210,7 +230,8 @@ FizzyInstance* fizzy_instantiate(const FizzyModule* module,
}

FizzyInstance* fizzy_resolve_instantiate(const FizzyModule* c_module,
const FizzyImportedFunction* c_imported_functions, size_t imported_functions_size)
const FizzyImportedFunction* c_imported_functions, size_t imported_functions_size,
const FizzyExternalGlobal* imported_globals, size_t imported_globals_size)
{
try
{
Expand All @@ -219,10 +240,16 @@ FizzyInstance* fizzy_resolve_instantiate(const FizzyModule* c_module,
std::transform(c_imported_functions, c_imported_functions + imported_functions_size,
imported_functions.begin(), unwrap_imported_func_fn);

std::vector<fizzy::ExternalGlobal> globals(imported_globals_size);
fizzy::ExternalGlobal (*unwrap_external_global_fn)(const FizzyExternalGlobal&) = &unwrap;
std::transform(imported_globals, imported_globals + imported_globals_size, globals.begin(),
unwrap_external_global_fn);

std::unique_ptr<const fizzy::Module> module{unwrap(c_module)};
auto resolved_imports = fizzy::resolve_imported_functions(*module, imported_functions);

auto instance = fizzy::instantiate(std::move(module), std::move(resolved_imports));
auto instance = fizzy::instantiate(
std::move(module), std::move(resolved_imports), {}, {}, std::move(globals));

return wrap(instance.release());
}
Expand Down
40 changes: 20 additions & 20 deletions test/unittests/capi_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ TEST(capi, instantiate)
auto module = fizzy_parse(wasm_prefix, sizeof(wasm_prefix));
ASSERT_NE(module, nullptr);

auto instance = fizzy_instantiate(module, nullptr, 0);
auto instance = fizzy_instantiate(module, nullptr, 0, nullptr, 0);
EXPECT_NE(instance, nullptr);

fizzy_free_instance(instance);
Expand All @@ -119,7 +119,7 @@ TEST(capi, instantiate_imported_function)
auto module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);

EXPECT_EQ(fizzy_instantiate(module, nullptr, 0), nullptr);
EXPECT_EQ(fizzy_instantiate(module, nullptr, 0, nullptr, 0), nullptr);

module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);
Expand All @@ -130,7 +130,7 @@ TEST(capi, instantiate_imported_function)
},
nullptr}};

auto instance = fizzy_instantiate(module, host_funcs, 1);
auto instance = fizzy_instantiate(module, host_funcs, 1, nullptr, 0);
EXPECT_NE(instance, nullptr);

fizzy_free_instance(instance);
Expand All @@ -145,7 +145,7 @@ TEST(capi, resolve_instantiate_no_imports)
auto module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);

auto instance = fizzy_resolve_instantiate(module, nullptr, 0);
auto instance = fizzy_resolve_instantiate(module, nullptr, 0, nullptr, 0);
EXPECT_NE(instance, nullptr);

fizzy_free_instance(instance);
Expand All @@ -158,7 +158,7 @@ TEST(capi, resolve_instantiate_no_imports)
[](void*, FizzyInstance*, const FizzyValue*, int) { return FizzyExecutionResult{}; },
nullptr}}};

instance = fizzy_resolve_instantiate(module, host_funcs, 1);
instance = fizzy_resolve_instantiate(module, host_funcs, 1, nullptr, 0);
EXPECT_NE(instance, nullptr);

fizzy_free_instance(instance);
Expand All @@ -178,7 +178,7 @@ TEST(capi, resolve_instantiate)
auto module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);

EXPECT_EQ(fizzy_instantiate(module, nullptr, 0), nullptr);
EXPECT_EQ(fizzy_instantiate(module, nullptr, 0, nullptr, 0), nullptr);

module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);
Expand All @@ -201,7 +201,7 @@ TEST(capi, resolve_instantiate)
FizzyImportedFunction host_funcs[] = {{"mod1", "foo1", mod1foo1}, {"mod1", "foo2", mod1foo2},
{"mod2", "foo1", mod2foo1}, {"mod2", "foo2", mod2foo2}};

auto instance = fizzy_resolve_instantiate(module, host_funcs, 4);
auto instance = fizzy_resolve_instantiate(module, host_funcs, 4, nullptr, 0);
EXPECT_NE(instance, nullptr);
fizzy_free_instance(instance);

Expand All @@ -210,7 +210,7 @@ TEST(capi, resolve_instantiate)
ASSERT_NE(module, nullptr);
FizzyImportedFunction host_funcs_reordered[] = {{"mod1", "foo2", mod1foo2},
{"mod2", "foo1", mod2foo1}, {"mod2", "foo2", mod2foo2}, {"mod1", "foo1", mod1foo1}};
instance = fizzy_resolve_instantiate(module, host_funcs_reordered, 4);
instance = fizzy_resolve_instantiate(module, host_funcs_reordered, 4, nullptr, 0);
EXPECT_NE(instance, nullptr);
fizzy_free_instance(instance);

Expand All @@ -220,14 +220,14 @@ TEST(capi, resolve_instantiate)
FizzyImportedFunction host_funcs_extra[] = {{"mod1", "foo1", mod1foo1},
{"mod1", "foo2", mod1foo2}, {"mod2", "foo1", mod2foo1}, {"mod2", "foo2", mod2foo2},
{"mod3", "foo1", mod1foo1}};
instance = fizzy_resolve_instantiate(module, host_funcs_extra, 4);
instance = fizzy_resolve_instantiate(module, host_funcs_extra, 4, nullptr, 0);
EXPECT_NE(instance, nullptr);
fizzy_free_instance(instance);

// not enough functions
module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);
EXPECT_EQ(fizzy_resolve_instantiate(module, host_funcs, 3), nullptr);
EXPECT_EQ(fizzy_resolve_instantiate(module, host_funcs, 3, nullptr, 0), nullptr);
}

TEST(capi, free_instance_null)
Expand All @@ -244,7 +244,7 @@ TEST(capi, get_instance_module)
auto module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);

auto instance = fizzy_instantiate(module, nullptr, 0);
auto instance = fizzy_instantiate(module, nullptr, 0, nullptr, 0);
ASSERT_NE(instance, nullptr);

auto instance_module = fizzy_get_instance_module(instance);
Expand All @@ -264,7 +264,7 @@ TEST(capi, memory_access_no_memory)
auto module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);

auto instance = fizzy_instantiate(module, nullptr, 0);
auto instance = fizzy_instantiate(module, nullptr, 0, nullptr, 0);
ASSERT_NE(instance, nullptr);

EXPECT_EQ(fizzy_get_instance_memory_data(instance), nullptr);
Expand All @@ -289,7 +289,7 @@ TEST(capi, memory_access)
auto module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);

auto instance = fizzy_instantiate(module, nullptr, 0);
auto instance = fizzy_instantiate(module, nullptr, 0, nullptr, 0);
ASSERT_NE(instance, nullptr);

uint8_t* memory = fizzy_get_instance_memory_data(instance);
Expand All @@ -316,7 +316,7 @@ TEST(capi, imported_memory_access)
auto module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);

auto instance = fizzy_instantiate(module, nullptr, 0);
auto instance = fizzy_instantiate(module, nullptr, 0, nullptr, 0);
EXPECT_EQ(instance, nullptr);
}

Expand All @@ -337,7 +337,7 @@ TEST(capi, execute)
auto module = fizzy_parse(wasm.data(), wasm.size());
ASSERT_NE(module, nullptr);

auto instance = fizzy_instantiate(module, nullptr, 0);
auto instance = fizzy_instantiate(module, nullptr, 0, nullptr, 0);
ASSERT_NE(instance, nullptr);

EXPECT_THAT(fizzy_execute(instance, 0, nullptr, 0), Result());
Expand Down Expand Up @@ -374,7 +374,7 @@ TEST(capi, execute_with_host_function)
},
nullptr}};

auto instance = fizzy_instantiate(module, host_funcs, 2);
auto instance = fizzy_instantiate(module, host_funcs, 2, nullptr, 0);
ASSERT_NE(instance, nullptr);

EXPECT_THAT(fizzy_execute(instance, 0, nullptr, 0), Result(42));
Expand Down Expand Up @@ -404,7 +404,7 @@ TEST(capi, imported_function_traps)
},
nullptr}};

auto instance = fizzy_instantiate(module, host_funcs, 1);
auto instance = fizzy_instantiate(module, host_funcs, 1, nullptr, 0);
ASSERT_NE(instance, nullptr);

EXPECT_THAT(fizzy_execute(instance, 1, nullptr, 0), Traps());
Expand Down Expand Up @@ -433,7 +433,7 @@ TEST(capi, imported_function_void)
},
&called}};

auto instance = fizzy_instantiate(module, host_funcs, 1);
auto instance = fizzy_instantiate(module, host_funcs, 1, nullptr, 0);
ASSERT_NE(instance, nullptr);

EXPECT_THAT(fizzy_execute(instance, 1, nullptr, 0), Result());
Expand All @@ -457,7 +457,7 @@ TEST(capi, imported_function_from_another_module)
"0061736d0100000001070160027f7f017f030201000707010373756200000a09010700200020016b0b");
auto module1 = fizzy_parse(bin1.data(), bin1.size());
ASSERT_NE(module1, nullptr);
auto instance1 = fizzy_instantiate(module1, nullptr, 0);
auto instance1 = fizzy_instantiate(module1, nullptr, 0, nullptr, 0);
ASSERT_NE(instance1, nullptr);

/* wat2wasm
Expand Down Expand Up @@ -494,7 +494,7 @@ TEST(capi, imported_function_from_another_module)

FizzyExternalFunction host_funcs[] = {{{FizzyValueTypeI32, &inputs[0], 2}, sub, &host_context}};

auto instance2 = fizzy_instantiate(module2, host_funcs, 1);
auto instance2 = fizzy_instantiate(module2, host_funcs, 1, nullptr, 0);
ASSERT_NE(instance2, nullptr);

FizzyValue args[] = {{44}, {2}};
Expand Down
2 changes: 1 addition & 1 deletion test/utils/fizzy_c_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ bool FizzyCEngine::instantiate(bytes_view wasm_binary)
FizzyValueType inputs[] = {FizzyValueTypeI32, FizzyValueTypeI32};
FizzyImportedFunction imports[] = {
{"env", "adler32", {{FizzyValueTypeI32, inputs, 2}, env_adler32, nullptr}}};
m_instance.reset(fizzy_resolve_instantiate(module, imports, 1));
m_instance.reset(fizzy_resolve_instantiate(module, imports, 1, nullptr, 0));

return (m_instance != nullptr);
}
Expand Down

0 comments on commit aea94af

Please sign in to comment.