1579ec46bSAlex Crichton /**
2579ec46bSAlex Crichton  * \file wasmtime/component/component.hh
3579ec46bSAlex Crichton  */
4579ec46bSAlex Crichton 
5cde2e04fSAlex Crichton #ifndef WASMTIME_COMPONENT_COMPONENT_HH
6cde2e04fSAlex Crichton #define WASMTIME_COMPONENT_COMPONENT_HH
7579ec46bSAlex Crichton 
8579ec46bSAlex Crichton #include <wasmtime/conf.h>
9579ec46bSAlex Crichton 
10579ec46bSAlex Crichton #ifdef WASMTIME_FEATURE_COMPONENT_MODEL
11579ec46bSAlex Crichton 
12579ec46bSAlex Crichton #include <memory>
13579ec46bSAlex Crichton #include <optional>
14579ec46bSAlex Crichton #include <string_view>
15579ec46bSAlex Crichton #include <vector>
16579ec46bSAlex Crichton #include <wasmtime/component/component.h>
1739ec36caSAlex Crichton #include <wasmtime/component/types/component.hh>
18579ec46bSAlex Crichton #include <wasmtime/engine.hh>
19579ec46bSAlex Crichton #include <wasmtime/error.hh>
20579ec46bSAlex Crichton #include <wasmtime/span.hh>
21579ec46bSAlex Crichton #include <wasmtime/wat.hh>
22579ec46bSAlex Crichton 
23579ec46bSAlex Crichton namespace wasmtime {
24579ec46bSAlex Crichton namespace component {
25579ec46bSAlex Crichton 
26579ec46bSAlex Crichton /**
27579ec46bSAlex Crichton  * \brief An index to an exported item within a particular component.
28579ec46bSAlex Crichton  *
29579ec46bSAlex Crichton  * This structure is acquired from a `Component` and used to lookup exports on
30579ec46bSAlex Crichton  * instances.
31579ec46bSAlex Crichton  */
32579ec46bSAlex Crichton class ExportIndex {
33311d023aSAlex Crichton   WASMTIME_CLONE_WRAPPER(ExportIndex, wasmtime_component_export_index);
34579ec46bSAlex Crichton };
35579ec46bSAlex Crichton 
36579ec46bSAlex Crichton /**
37579ec46bSAlex Crichton  * \brief Representation of a compiled WebAssembly component.
38579ec46bSAlex Crichton  */
39579ec46bSAlex Crichton class Component {
40311d023aSAlex Crichton   WASMTIME_CLONE_WRAPPER(Component, wasmtime_component);
41579ec46bSAlex Crichton 
42579ec46bSAlex Crichton #ifdef WASMTIME_FEATURE_COMPILER
43*7a4f53a3SPiotr Sikora 
44*7a4f53a3SPiotr Sikora #ifdef WASMTIME_FEATURE_WAT
45579ec46bSAlex Crichton   /**
46579ec46bSAlex Crichton    * \brief Compiles a component from the WebAssembly text format.
47579ec46bSAlex Crichton    *
48579ec46bSAlex Crichton    * This function will automatically use `wat2wasm` on the input and then
49579ec46bSAlex Crichton    * delegate to the #compile function.
50579ec46bSAlex Crichton    */
compile(Engine & engine,std::string_view wat)51579ec46bSAlex Crichton   static Result<Component> compile(Engine &engine, std::string_view wat) {
52579ec46bSAlex Crichton     auto wasm = wat2wasm(wat);
53579ec46bSAlex Crichton     if (!wasm) {
54579ec46bSAlex Crichton       return wasm.err();
55579ec46bSAlex Crichton     }
56579ec46bSAlex Crichton     auto bytes = wasm.ok();
57579ec46bSAlex Crichton     return compile(engine, bytes);
58579ec46bSAlex Crichton   }
59*7a4f53a3SPiotr Sikora #endif // WASMTIME_FEATURE_WAT
60579ec46bSAlex Crichton 
61579ec46bSAlex Crichton   /**
62579ec46bSAlex Crichton    * \brief Compiles a component from the WebAssembly binary format.
63579ec46bSAlex Crichton    *
64579ec46bSAlex Crichton    * This function compiles the provided WebAssembly binary specified by `wasm`
65579ec46bSAlex Crichton    * within the compilation settings configured by `engine`. This method is
66579ec46bSAlex Crichton    * synchronous and will not return until the component has finished compiling.
67579ec46bSAlex Crichton    *
68579ec46bSAlex Crichton    * This function can fail if the WebAssembly binary is invalid or doesn't
69579ec46bSAlex Crichton    * validate (or similar). Note that this API does not compile WebAssembly
70579ec46bSAlex Crichton    * modules, which is done with `Module` instead of `Component`.
71579ec46bSAlex Crichton    */
compile(Engine & engine,Span<uint8_t> wasm)72579ec46bSAlex Crichton   static Result<Component> compile(Engine &engine, Span<uint8_t> wasm) {
73579ec46bSAlex Crichton     wasmtime_component_t *ret = nullptr;
74579ec46bSAlex Crichton     auto *error =
75579ec46bSAlex Crichton         wasmtime_component_new(engine.capi(), wasm.data(), wasm.size(), &ret);
76579ec46bSAlex Crichton     if (error != nullptr) {
77579ec46bSAlex Crichton       return Error(error);
78579ec46bSAlex Crichton     }
79579ec46bSAlex Crichton     return Component(ret);
80579ec46bSAlex Crichton   }
81579ec46bSAlex Crichton #endif // WASMTIME_FEATURE_COMPILER
82579ec46bSAlex Crichton 
83579ec46bSAlex Crichton   /**
84579ec46bSAlex Crichton    * \brief Deserializes a previous list of bytes created with `serialize`.
85579ec46bSAlex Crichton    *
86579ec46bSAlex Crichton    * This function is intended to be much faster than `compile` where it uses
87579ec46bSAlex Crichton    * the artifacts of a previous compilation to quickly create an in-memory
88579ec46bSAlex Crichton    * component ready for instantiation.
89579ec46bSAlex Crichton    *
90579ec46bSAlex Crichton    * It is not safe to pass arbitrary input to this function, it is only safe to
91579ec46bSAlex Crichton    * pass in output from previous calls to `serialize`. For more information see
92579ec46bSAlex Crichton    * the Rust documentation -
93579ec46bSAlex Crichton    * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize
94579ec46bSAlex Crichton    */
deserialize(Engine & engine,Span<uint8_t> wasm)95579ec46bSAlex Crichton   static Result<Component> deserialize(Engine &engine, Span<uint8_t> wasm) {
96579ec46bSAlex Crichton     wasmtime_component_t *ret = nullptr;
97579ec46bSAlex Crichton     auto *error = wasmtime_component_deserialize(engine.capi(), wasm.data(),
98579ec46bSAlex Crichton                                                  wasm.size(), &ret);
99579ec46bSAlex Crichton     if (error != nullptr) {
100579ec46bSAlex Crichton       return Error(error);
101579ec46bSAlex Crichton     }
102579ec46bSAlex Crichton     return Component(ret);
103579ec46bSAlex Crichton   }
104579ec46bSAlex Crichton 
105579ec46bSAlex Crichton   /**
106579ec46bSAlex Crichton    * \brief Deserializes a component from an on-disk file.
107579ec46bSAlex Crichton    *
108579ec46bSAlex Crichton    * This function is the same as `deserialize` except that it reads the data
109579ec46bSAlex Crichton    * for the serialized component from the path on disk. This can be faster than
110579ec46bSAlex Crichton    * the alternative which may require copying the data around.
111579ec46bSAlex Crichton    *
112579ec46bSAlex Crichton    * It is not safe to pass arbitrary input to this function, it is only safe to
113579ec46bSAlex Crichton    * pass in output from previous calls to `serialize`. For more information see
114579ec46bSAlex Crichton    * the Rust documentation -
115579ec46bSAlex Crichton    * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize
116579ec46bSAlex Crichton    */
deserialize_file(Engine & engine,const std::string & path)117579ec46bSAlex Crichton   static Result<Component> deserialize_file(Engine &engine,
118579ec46bSAlex Crichton                                             const std::string &path) {
119579ec46bSAlex Crichton     wasmtime_component_t *ret = nullptr;
120579ec46bSAlex Crichton     auto *error =
121579ec46bSAlex Crichton         wasmtime_component_deserialize_file(engine.capi(), path.c_str(), &ret);
122579ec46bSAlex Crichton     if (error != nullptr) {
123579ec46bSAlex Crichton       return Error(error);
124579ec46bSAlex Crichton     }
125579ec46bSAlex Crichton     return Component(ret);
126579ec46bSAlex Crichton   }
127579ec46bSAlex Crichton 
128579ec46bSAlex Crichton #ifdef WASMTIME_FEATURE_COMPILER
129579ec46bSAlex Crichton   /**
130579ec46bSAlex Crichton    * \brief Serializes this component to a list of bytes.
131579ec46bSAlex Crichton    *
132579ec46bSAlex Crichton    * The returned bytes can then be used to later pass to `deserialize` to
133579ec46bSAlex Crichton    * quickly recreate this component in a different process perhaps.
134579ec46bSAlex Crichton    */
serialize() const135579ec46bSAlex Crichton   Result<std::vector<uint8_t>> serialize() const {
136579ec46bSAlex Crichton     wasm_byte_vec_t bytes;
137579ec46bSAlex Crichton     auto *error = wasmtime_component_serialize(ptr.get(), &bytes);
138579ec46bSAlex Crichton     if (error != nullptr) {
139579ec46bSAlex Crichton       return Error(error);
140579ec46bSAlex Crichton     }
141579ec46bSAlex Crichton     std::vector<uint8_t> ret;
142579ec46bSAlex Crichton     Span<uint8_t> raw(reinterpret_cast<uint8_t *>(bytes.data), bytes.size);
143579ec46bSAlex Crichton     ret.assign(raw.begin(), raw.end());
144579ec46bSAlex Crichton     wasm_byte_vec_delete(&bytes);
145579ec46bSAlex Crichton     return ret;
146579ec46bSAlex Crichton   }
147579ec46bSAlex Crichton #endif // WASMTIME_FEATURE_COMPILER
148579ec46bSAlex Crichton 
149579ec46bSAlex Crichton   /**
150579ec46bSAlex Crichton    * \brief Returns the export index for the export named `name` in this
151579ec46bSAlex Crichton    * component.
152579ec46bSAlex Crichton    *
153579ec46bSAlex Crichton    * The `instance` argument is an optionally provided index which is the
154579ec46bSAlex Crichton    * instance under which the `name` should be looked up.
155579ec46bSAlex Crichton    */
export_index(ExportIndex * instance,std::string_view name)156579ec46bSAlex Crichton   std::optional<ExportIndex> export_index(ExportIndex *instance,
157579ec46bSAlex Crichton                                           std::string_view name) {
158579ec46bSAlex Crichton     auto ret = wasmtime_component_get_export_index(
159579ec46bSAlex Crichton         capi(), instance ? instance->capi() : nullptr, name.data(),
160579ec46bSAlex Crichton         name.size());
161579ec46bSAlex Crichton     if (ret) {
162579ec46bSAlex Crichton       return ExportIndex(ret);
163579ec46bSAlex Crichton     }
164579ec46bSAlex Crichton     return std::nullopt;
165579ec46bSAlex Crichton   };
16639ec36caSAlex Crichton 
16739ec36caSAlex Crichton   /// \brief Returns the type of this component.
type() const16839ec36caSAlex Crichton   ComponentType type() const {
16939ec36caSAlex Crichton     return ComponentType(wasmtime_component_type(ptr.get()));
17039ec36caSAlex Crichton   }
171579ec46bSAlex Crichton };
172579ec46bSAlex Crichton 
173579ec46bSAlex Crichton } // namespace component
174579ec46bSAlex Crichton } // namespace wasmtime
175579ec46bSAlex Crichton 
176579ec46bSAlex Crichton #endif // WASMTIME_FEATURE_COMPONENT_MODEL
177579ec46bSAlex Crichton 
178cde2e04fSAlex Crichton #endif // WASMTIME_COMPONENT_COMPONENT_HH
179