Skip to content

Commit 34b9df3

Browse files
committed
capi: Instantiate with resolving host functions
1 parent 3ff631f commit 34b9df3

2 files changed

Lines changed: 67 additions & 0 deletions

File tree

include/fizzy/fizzy.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,17 @@ typedef struct FizzyExternalFunction
8080
void* context;
8181
} FizzyExternalFunction;
8282

83+
/// Imported function.
84+
typedef struct FizzyImportedFunction
85+
{
86+
/// Module name. NULL-terminated string. Cannot be NULL.
87+
const char* module;
88+
/// Function name. NULL-terminated string. Cannot be NULL.
89+
const char* name;
90+
/// External function, defining its type, pointer to function and context for calling it.
91+
FizzyExternalFunction external_function;
92+
} FizzyImportedFunction;
93+
8394
/// Validate binary module.
8495
bool fizzy_validate(const uint8_t* wasm_binary, size_t wasm_binary_size);
8596

@@ -130,6 +141,22 @@ bool fizzy_find_exported_function(
130141
FizzyInstance* fizzy_instantiate(const FizzyModule* module,
131142
const FizzyExternalFunction* imported_functions, size_t imported_functions_size);
132143

144+
/// Instantiate a module resolving imported functions.
145+
/// Takes ownership of module, i.e. @p module is invalidated after this call.
146+
///
147+
/// @param module Pointer to module.
148+
/// @param imported_functions Pointer to the imported function array. Can be NULL iff
149+
/// imported_functions_size equals 0.
150+
/// @param imported_functions_size Size of the imported function array. Can be zero.
151+
/// @returns non-NULL pointer to instance in case of success, NULL otherwise.
152+
///
153+
/// @note
154+
/// Functions in @a imported_functions are allowed to be in any order and allowed to include some
155+
/// functions not required by instantiated module.
156+
/// Functions are matched to module's imports based on their module and name strings.
157+
FizzyInstance* fizzy_resolve_instantiate(const FizzyModule* module,
158+
const FizzyImportedFunction* imported_functions, size_t imported_functions_size);
159+
133160
/// Free resources associated with the instance.
134161
/// If passed pointer is NULL, has no effect.
135162
void fizzy_free_instance(FizzyInstance* instance);

lib/fizzy/capi.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,23 @@ inline fizzy::ExternalFunction unwrap(const FizzyExternalFunction& external_func
115115
return fizzy::ExternalFunction{
116116
unwrap(external_func.function, external_func.context), unwrap(external_func.type)};
117117
}
118+
119+
inline fizzy::ImportedFunction unwrap(const FizzyImportedFunction& imported_func)
120+
{
121+
fizzy::ImportedFunction result;
122+
result.module = imported_func.module ? std::string{imported_func.module} : std::string{};
123+
result.name = imported_func.name ? std::string{imported_func.name} : std::string{};
124+
125+
fizzy::FuncType type = unwrap(imported_func.external_function.type);
126+
result.inputs = std::move(type.inputs);
127+
result.output = type.outputs.empty() ? std::nullopt : std::make_optional(type.outputs[0]);
128+
129+
result.function =
130+
unwrap(imported_func.external_function.function, imported_func.external_function.context);
131+
132+
return result;
133+
}
134+
118135
} // namespace
119136

120137
extern "C" {
@@ -186,6 +203,29 @@ FizzyInstance* fizzy_instantiate(const FizzyModule* module,
186203
}
187204
}
188205

206+
FizzyInstance* fizzy_resolve_instantiate(const FizzyModule* c_module,
207+
const FizzyImportedFunction* c_imported_functions, size_t imported_functions_size)
208+
{
209+
try
210+
{
211+
std::vector<fizzy::ImportedFunction> imported_functions(imported_functions_size);
212+
fizzy::ImportedFunction (*unwrap_imported_func_fn)(const FizzyImportedFunction&) = &unwrap;
213+
std::transform(c_imported_functions, c_imported_functions + imported_functions_size,
214+
imported_functions.begin(), unwrap_imported_func_fn);
215+
216+
std::unique_ptr<const fizzy::Module> module{unwrap(c_module)};
217+
auto resolved_imports = fizzy::resolve_imported_functions(*module, imported_functions);
218+
219+
auto instance = fizzy::instantiate(std::move(module), std::move(resolved_imports));
220+
221+
return wrap(instance.release());
222+
}
223+
catch (...)
224+
{
225+
return nullptr;
226+
}
227+
}
228+
189229
void fizzy_free_instance(FizzyInstance* instance)
190230
{
191231
delete unwrap(instance);

0 commit comments

Comments
 (0)