22// Copyright 2020 The Fizzy Authors.
33// SPDX-License-Identifier: Apache-2.0
44
5+ #include " cxx20/bit.hpp"
6+ #include " execute.hpp"
7+ #include " instantiate.hpp"
58#include " parser.hpp"
69#include < fizzy/fizzy.h>
10+ #include < memory>
11+
12+ namespace
13+ {
14+ inline FizzyValue wrap (fizzy::Value value) noexcept
15+ {
16+ return fizzy::bit_cast<FizzyValue>(value);
17+ }
18+
19+ inline fizzy::Value unwrap (FizzyValue value) noexcept
20+ {
21+ return fizzy::bit_cast<fizzy::Value>(value);
22+ }
23+
24+ inline const FizzyValue* wrap (const fizzy::Value* values) noexcept
25+ {
26+ return reinterpret_cast <const FizzyValue*>(values);
27+ }
28+
29+ inline const fizzy::Value* unwrap (const FizzyValue* values) noexcept
30+ {
31+ return reinterpret_cast <const fizzy::Value*>(values);
32+ }
33+
34+ inline FizzyInstance* wrap (fizzy::Instance* instance) noexcept
35+ {
36+ return reinterpret_cast <FizzyInstance*>(instance);
37+ }
38+
39+ inline fizzy::Instance* unwrap (FizzyInstance* instance) noexcept
40+ {
41+ return reinterpret_cast <fizzy::Instance*>(instance);
42+ }
43+
44+ inline FizzyExecutionResult wrap (const fizzy::ExecutionResult& result) noexcept
45+ {
46+ return {result.trapped , result.has_value , wrap (result.value )};
47+ }
48+
49+ inline fizzy::ExecutionResult unwrap (FizzyExecutionResult result) noexcept
50+ {
51+ if (result.trapped )
52+ return fizzy::Trap;
53+ else if (!result.has_value )
54+ return fizzy::Void;
55+ else
56+ return unwrap (result.value );
57+ }
58+
59+ inline auto unwrap (FizzyExternalFn func, void * context) noexcept
60+ {
61+ return [func, context](fizzy::Instance& instance, fizzy::span<const fizzy::Value> args,
62+ int depth) noexcept -> fizzy::ExecutionResult {
63+ const auto result = func (context, wrap (&instance), wrap (args.data ()), args.size (), depth);
64+ return unwrap (result);
65+ };
66+ }
67+ } // namespace
768
869extern " C" {
70+ struct FizzyModule
71+ {
72+ fizzy::Module module ;
73+ };
74+
75+ struct FizzyInstance
76+ {
77+ fizzy::Instance* instance;
78+ };
79+
980bool fizzy_validate (const uint8_t * wasm_binary, size_t wasm_binary_size)
1081{
1182 try
@@ -18,4 +89,70 @@ bool fizzy_validate(const uint8_t* wasm_binary, size_t wasm_binary_size)
1889 return false ;
1990 }
2091}
92+
93+ FizzyModule* fizzy_parse (const uint8_t * wasm_binary, size_t wasm_binary_size)
94+ {
95+ try
96+ {
97+ auto cmodule = std::make_unique<FizzyModule>();
98+ cmodule->module = fizzy::parse ({wasm_binary, wasm_binary_size});
99+ return cmodule.release ();
100+ }
101+ catch (...)
102+ {
103+ return nullptr ;
104+ }
105+ }
106+
107+ void fizzy_free_module (FizzyModule* module )
108+ {
109+ delete module ;
110+ }
111+
112+ FizzyInstance* fizzy_instantiate (FizzyModule* module ,
113+ const FizzyExternalFunction* imported_functions, size_t imported_functions_size)
114+ {
115+ try
116+ {
117+ // Convert fizzy_external_function to fizzy::ExternalFunction
118+ std::vector<fizzy::ExternalFunction> functions (imported_functions_size);
119+ for (size_t imported_func_idx = 0 ; imported_func_idx < imported_functions_size;
120+ ++imported_func_idx)
121+ {
122+ const auto & cfunc = imported_functions[imported_func_idx];
123+
124+ auto func = unwrap (cfunc.function , cfunc.context );
125+ // TODO get type from input array
126+ auto func_type = module ->module .imported_function_types [imported_func_idx];
127+
128+ functions[imported_func_idx] =
129+ fizzy::ExternalFunction{std::move (func), std::move (func_type)};
130+ }
131+
132+ auto instance = fizzy::instantiate (std::move (module ->module ), std::move (functions));
133+
134+ fizzy_free_module (module );
135+ return wrap (instance.release ());
136+ }
137+ catch (...)
138+ {
139+ fizzy_free_module (module );
140+ return nullptr ;
141+ }
142+ }
143+
144+ void fizzy_free_instance (FizzyInstance* instance)
145+ {
146+ delete unwrap (instance);
147+ }
148+
149+ FizzyExecutionResult fizzy_execute (
150+ FizzyInstance* instance, uint32_t func_idx, const FizzyValue* args, size_t args_size, int depth)
151+ {
152+ auto * unwrapped_instance = unwrap (instance);
153+ assert (unwrapped_instance->module .get_function_type (func_idx).inputs .size () == args_size);
154+
155+ const auto result = fizzy::execute (*unwrapped_instance, func_idx, unwrap (args), depth);
156+ return wrap (result);
157+ }
21158}
0 commit comments