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 FizzyModule* wrap (fizzy::Module* module ) noexcept
15+ {
16+ return reinterpret_cast <FizzyModule*>(module );
17+ }
18+
19+ inline fizzy::Module* unwrap (FizzyModule* module ) noexcept
20+ {
21+ return reinterpret_cast <fizzy::Module*>(module );
22+ }
23+
24+ inline FizzyValue wrap (fizzy::Value value) noexcept
25+ {
26+ return fizzy::bit_cast<FizzyValue>(value);
27+ }
28+
29+ inline fizzy::Value unwrap (FizzyValue value) noexcept
30+ {
31+ return fizzy::bit_cast<fizzy::Value>(value);
32+ }
33+
34+ inline const FizzyValue* wrap (const fizzy::Value* values) noexcept
35+ {
36+ return reinterpret_cast <const FizzyValue*>(values);
37+ }
38+
39+ inline const fizzy::Value* unwrap (const FizzyValue* values) noexcept
40+ {
41+ return reinterpret_cast <const fizzy::Value*>(values);
42+ }
43+
44+ inline FizzyInstance* wrap (fizzy::Instance* instance) noexcept
45+ {
46+ return reinterpret_cast <FizzyInstance*>(instance);
47+ }
48+
49+ inline fizzy::Instance* unwrap (FizzyInstance* instance) noexcept
50+ {
51+ return reinterpret_cast <fizzy::Instance*>(instance);
52+ }
53+
54+ inline FizzyExecutionResult wrap (const fizzy::ExecutionResult& result) noexcept
55+ {
56+ return {result.trapped , result.has_value , wrap (result.value )};
57+ }
58+
59+ inline fizzy::ExecutionResult unwrap (FizzyExecutionResult result) noexcept
60+ {
61+ if (result.trapped )
62+ return fizzy::Trap;
63+ else if (!result.has_value )
64+ return fizzy::Void;
65+ else
66+ return unwrap (result.value );
67+ }
68+
69+ inline auto unwrap (FizzyExternalFn func, void * context) noexcept
70+ {
71+ return [func, context](fizzy::Instance& instance, fizzy::span<const fizzy::Value> args,
72+ int depth) noexcept -> fizzy::ExecutionResult {
73+ const auto result = func (context, wrap (&instance), wrap (args.data ()), args.size (), depth);
74+ return unwrap (result);
75+ };
76+ }
77+ } // namespace
778
879extern " C" {
980bool fizzy_validate (const uint8_t * wasm_binary, size_t wasm_binary_size)
@@ -18,4 +89,65 @@ 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 module = fizzy::parse ({wasm_binary, wasm_binary_size});
98+ return wrap (module .release ());
99+ }
100+ catch (...)
101+ {
102+ return nullptr ;
103+ }
104+ }
105+
106+ void fizzy_free_module (FizzyModule* module )
107+ {
108+ delete unwrap (module );
109+ }
110+
111+ FizzyInstance* fizzy_instantiate (FizzyModule* module ,
112+ const FizzyExternalFunction* imported_functions, size_t imported_functions_size)
113+ {
114+ try
115+ {
116+ // Convert fizzy_external_function to fizzy::ExternalFunction
117+ std::vector<fizzy::ExternalFunction> functions (imported_functions_size);
118+ for (size_t imported_func_idx = 0 ; imported_func_idx < imported_functions_size;
119+ ++imported_func_idx)
120+ {
121+ const auto & cfunc = imported_functions[imported_func_idx];
122+
123+ auto func = unwrap (cfunc.function , cfunc.context );
124+ // TODO get type from input array
125+ auto func_type = unwrap (module )->imported_function_types [imported_func_idx];
126+
127+ functions[imported_func_idx] =
128+ fizzy::ExternalFunction{std::move (func), std::move (func_type)};
129+ }
130+
131+ auto instance = fizzy::instantiate (
132+ std::unique_ptr<fizzy::Module>(unwrap (module )), std::move (functions));
133+
134+ return wrap (instance.release ());
135+ }
136+ catch (...)
137+ {
138+ return nullptr ;
139+ }
140+ }
141+
142+ void fizzy_free_instance (FizzyInstance* instance)
143+ {
144+ delete unwrap (instance);
145+ }
146+
147+ FizzyExecutionResult fizzy_execute (
148+ FizzyInstance* instance, uint32_t func_idx, const FizzyValue* args, int depth)
149+ {
150+ const auto result = fizzy::execute (*unwrap (instance), func_idx, unwrap (args), depth);
151+ return wrap (result);
152+ }
21153}
0 commit comments