wasm_bridge/sys/mod.rs
1use ref_cast::RefCast;
2
3pub use wasmtime::*;
4
5// DISCLAIMER: All annotations are directly copied from wasmtime.
6
7/// A compiled WebAssembly module, ready to be instantiated.
8///
9/// A `Module` is a compiled in-memory representation of an input WebAssembly
10/// binary. A `Module` is then used to create an [`Instance`](crate::Instance)
11/// through an instantiation process. You cannot call functions or fetch
12/// globals, for example, on a `Module` because it's purely a code
13/// representation. Instead you'll need to create an
14/// [`Instance`](crate::Instance) to interact with the wasm module.
15///
16/// A `Module` can be created by compiling WebAssembly code through APIs such as
17/// [`Module::new`]. This would be a JIT-style use case where code is compiled
18/// just before it's used. Alternatively a `Module` can be compiled in one
19/// process and [`Module::serialize`] can be used to save it to storage. A later
20/// call to [`Module::deserialize`] will quickly load the module to execute and
21/// does not need to compile any code, representing a more AOT-style use case.
22///
23/// Currently a `Module` does not implement any form of tiering or dynamic
24/// optimization of compiled code. Creation of a `Module` via [`Module::new`] or
25/// related APIs will perform the entire compilation step synchronously. When
26/// finished no further compilation will happen at runtime or later during
27/// execution of WebAssembly instances for example.
28///
29/// Compilation of WebAssembly by default goes through Cranelift and is
30/// recommended to be done once-per-module. The same WebAssembly binary need not
31/// be compiled multiple times and can instead used an embedder-cached result of
32/// the first call.
33///
34/// `Module` is thread-safe and safe to share across threads.
35///
36/// ## Modules and `Clone`
37///
38/// Using `clone` on a `Module` is a cheap operation. It will not create an
39/// entirely new module, but rather just a new reference to the existing module.
40/// In other words it's a shallow copy, not a deep copy.
41///
42/// ## Examples
43///
44/// There are a number of ways you can create a `Module`, for example pulling
45/// the bytes from a number of locations. One example is loading a module from
46/// the filesystem:
47///
48/// ```no_run
49/// # use wasmtime::*;
50/// # fn main() -> anyhow::Result<()> {
51/// let engine = Engine::default();
52/// let module = Module::from_file(&engine, "path/to/foo.wasm")?;
53/// # Ok(())
54/// # }
55/// ```
56///
57/// You can also load the wasm text format if more convenient too:
58///
59/// ```no_run
60/// # use wasmtime::*;
61/// # fn main() -> anyhow::Result<()> {
62/// let engine = Engine::default();
63/// // Now we're using the WebAssembly text extension: `.wat`!
64/// let module = Module::from_file(&engine, "path/to/foo.wat")?;
65/// # Ok(())
66/// # }
67/// ```
68///
69/// And if you've already got the bytes in-memory you can use the
70/// [`Module::new`] constructor:
71///
72/// ```no_run
73/// # use wasmtime::*;
74/// # fn main() -> anyhow::Result<()> {
75/// let engine = Engine::default();
76/// # let wasm_bytes: Vec<u8> = Vec::new();
77/// let module = Module::new(&engine, &wasm_bytes)?;
78///
79/// // It also works with the text format!
80/// let module = Module::new(&engine, "(module (func))")?;
81/// # Ok(())
82/// # }
83/// ```
84///
85/// Serializing and deserializing a module looks like:
86///
87/// ```no_run
88/// # use wasmtime::*;
89/// # fn main() -> anyhow::Result<()> {
90/// let engine = Engine::default();
91/// # let wasm_bytes: Vec<u8> = Vec::new();
92/// let module = Module::new(&engine, &wasm_bytes)?;
93/// let module_bytes = module.serialize()?;
94///
95/// // ... can save `module_bytes` to disk or other storage ...
96///
97/// // recreate the module from the serialized bytes. For the `unsafe` bits
98/// // see the documentation of `deserialize`.
99/// let module = unsafe { Module::deserialize(&engine, &module_bytes)? };
100/// # Ok(())
101/// # }
102/// ```
103///
104/// [`Config`]: crate::Config
105#[repr(transparent)]
106#[derive(RefCast, Clone)]
107pub struct Module(pub(crate) wasmtime::Module);
108
109impl Module {
110 #[deprecated(
111 since = "0.4.0",
112 note = "Compiling a module synchronously can panic on the web, please use `new_safe` instead."
113 )]
114 pub fn new(engine: &Engine, bytes: impl AsRef<[u8]>) -> Result<Self> {
115 Ok(Self(wasmtime::Module::new(engine, bytes)?))
116 }
117
118 /// Creates a new WebAssembly `Module` from the given in-memory `bytes`.
119 ///
120 /// The `bytes` provided must be in one of the following formats:
121 ///
122 /// * A [binary-encoded][binary] WebAssembly module. This is always supported.
123 /// * A [text-encoded][text] instance of the WebAssembly text format.
124 /// This is only supported when the `wat` feature of this crate is enabled.
125 /// If this is supplied then the text format will be parsed before validation.
126 /// Note that the `wat` feature is enabled by default.
127 ///
128 /// The data for the wasm module must be loaded in-memory if it's present
129 /// elsewhere, for example on disk. This requires that the entire binary is
130 /// loaded into memory all at once, this API does not support streaming
131 /// compilation of a module.
132 ///
133 /// The WebAssembly binary will be decoded and validated. It will also be
134 /// compiled according to the configuration of the provided `engine`.
135 ///
136 /// # Errors
137 ///
138 /// This function may fail and return an error. Errors may include
139 /// situations such as:
140 ///
141 /// * The binary provided could not be decoded because it's not a valid
142 /// WebAssembly binary
143 /// * The WebAssembly binary may not validate (e.g. contains type errors)
144 /// * Implementation-specific limits were exceeded with a valid binary (for
145 /// example too many locals)
146 /// * The wasm binary may use features that are not enabled in the
147 /// configuration of `engine`
148 /// * If the `wat` feature is enabled and the input is text, then it may be
149 /// rejected if it fails to parse.
150 ///
151 /// The error returned should contain full information about why module
152 /// creation failed if one is returned.
153 ///
154 /// [binary]: https://webassembly.github.io/spec/core/binary/index.html
155 /// [text]: https://webassembly.github.io/spec/core/text/index.html
156 ///
157 /// # Examples
158 ///
159 /// The `new` function can be invoked with a in-memory array of bytes:
160 ///
161 /// ```no_run
162 /// # use wasmtime::*;
163 /// # fn main() -> anyhow::Result<()> {
164 /// # let engine = Engine::default();
165 /// # let wasm_bytes: Vec<u8> = Vec::new();
166 /// let module = Module::new(&engine, &wasm_bytes)?;
167 /// # Ok(())
168 /// # }
169 /// ```
170 ///
171 /// Or you can also pass in a string to be parsed as the wasm text
172 /// format:
173 ///
174 /// ```
175 /// # use wasmtime::*;
176 /// # fn main() -> anyhow::Result<()> {
177 /// # let engine = Engine::default();
178 /// let module = Module::new(&engine, "(module (func))")?;
179 /// # Ok(())
180 /// # }
181 /// ```
182 pub async fn new_safe(engine: &Engine, bytes: impl AsRef<[u8]>) -> Result<Self> {
183 // This just calls `new` on sys, but uses proper async compilation on the web.
184 #[allow(deprecated)]
185 Self::new(engine, bytes)
186 }
187}
188
189/// An instantiated WebAssembly module.
190///
191/// This type represents the instantiation of a [`Module`]. Once instantiated
192/// you can access the [`exports`](Instance::exports) which are of type
193/// [`Extern`] and provide the ability to call functions, set globals, read
194/// memory, etc. When interacting with any wasm code you'll want to make an
195/// [`Instance`] to call any code or execute anything.
196///
197/// Instances are owned by a [`Store`](crate::Store) which is passed in at
198/// creation time. It's recommended to create instances with
199/// [`Linker::instantiate`](crate::Linker::instantiate) or similar
200/// [`Linker`](crate::Linker) methods, but a more low-level constructor is also
201/// available as [`Instance::new`].
202#[repr(transparent)]
203#[derive(RefCast, Clone, Debug)]
204pub struct Instance(pub(crate) wasmtime::Instance);
205
206impl Instance {
207 #[deprecated(
208 since = "0.4.0",
209 note = "Instantiating a module synchronously can panic on the web, please use `new_safe` instead."
210 )]
211 pub fn new(store: impl AsContextMut, module: &Module, imports: &[Extern]) -> Result<Self> {
212 Ok(Self(wasmtime::Instance::new(store, &module.0, imports)?))
213 }
214
215 /// Creates a new [`Instance`] from the previously compiled [`Module`] and
216 /// list of `imports` specified.
217 ///
218 /// This method instantiates the `module` provided with the `imports`,
219 /// following the procedure in the [core specification][inst] to
220 /// instantiate. Instantiation can fail for a number of reasons (many
221 /// specified below), but if successful the `start` function will be
222 /// automatically run (if specified in the `module`) and then the
223 /// [`Instance`] will be returned.
224 ///
225 /// Per the WebAssembly spec, instantiation includes running the module's
226 /// start function, if it has one (not to be confused with the `_start`
227 /// function, which is not run).
228 ///
229 /// Note that this is a low-level function that just performs an
230 /// instantiation. See the [`Linker`](crate::Linker) struct for an API which
231 /// provides a convenient way to link imports and provides automatic Command
232 /// and Reactor behavior.
233 ///
234 /// ## Providing Imports
235 ///
236 /// The entries in the list of `imports` are intended to correspond 1:1
237 /// with the list of imports returned by [`Module::imports`]. Before
238 /// calling [`Instance::new`] you'll want to inspect the return value of
239 /// [`Module::imports`] and, for each import type, create an [`Extern`]
240 /// which corresponds to that type. These [`Extern`] values are all then
241 /// collected into a list and passed to this function.
242 ///
243 /// Note that this function is intentionally relatively low level. For an
244 /// easier time passing imports by doing name-based resolution it's
245 /// recommended to instead use the [`Linker`](crate::Linker) type.
246 ///
247 /// ## Errors
248 ///
249 /// This function can fail for a number of reasons, including, but not
250 /// limited to:
251 ///
252 /// * The number of `imports` provided doesn't match the number of imports
253 /// returned by the `module`'s [`Module::imports`] method.
254 /// * The type of any [`Extern`] doesn't match the corresponding
255 /// [`ExternType`] entry that it maps to.
256 /// * The `start` function in the instance, if present, traps.
257 /// * Module/instance resource limits are exceeded.
258 ///
259 /// When instantiation fails it's recommended to inspect the return value to
260 /// see why it failed, or bubble it upwards. If you'd like to specifically
261 /// check for trap errors, you can use `error.downcast::<Trap>()`. For more
262 /// about error handling see the [`Trap`] documentation.
263 ///
264 /// [`Trap`]: crate::Trap
265 ///
266 /// # Panics
267 ///
268 /// This function will panic if called with a store associated with a
269 /// [`asynchronous config`](crate::Config::async_support). This function
270 /// will also panic if any [`Extern`] supplied is not owned by `store`.
271 ///
272 /// [inst]: https://webassembly.github.io/spec/core/exec/modules.html#exec-instantiation
273 /// [`ExternType`]: crate::ExternType
274 pub async fn new_safe(
275 store: impl AsContextMut,
276 module: &Module,
277 imports: &[Extern],
278 ) -> Result<Self> {
279 // This just calls `new` on sys, but uses proper async instantiation on the web.
280 #[allow(deprecated)]
281 Self::new(store, module, imports)
282 }
283
284 /// Same as [`Instance::new`], except for usage in [asynchronous stores].
285 ///
286 /// For more details about this function see the documentation on
287 /// [`Instance::new`]. The only difference between these two methods is that
288 /// this one will asynchronously invoke the wasm start function in case it
289 /// calls any imported function which is an asynchronous host function (e.g.
290 /// created with [`Func::new_async`](crate::Func::new_async).
291 ///
292 /// # Panics
293 ///
294 /// This function will panic if called with a store associated with a
295 /// [`synchronous config`](crate::Config::new). This is only compatible with
296 /// stores associated with an [`asynchronous
297 /// config`](crate::Config::async_support).
298 ///
299 /// This function will also panic, like [`Instance::new`], if any [`Extern`]
300 /// specified does not belong to `store`.
301 #[cfg(feature = "async")]
302 pub async fn new_async<T>(
303 store: impl AsContextMut<Data = T>,
304 module: &Module,
305 imports: &[Extern],
306 ) -> Result<Self>
307 where
308 T: Send,
309 {
310 Ok(Self(
311 wasmtime::Instance::new_async(store, &module.0, imports).await?,
312 ))
313 }
314
315 /// Looks up an exported [`Memory`] value by name.
316 ///
317 /// Returns `None` if there was no export named `name`, or if there was but
318 /// it wasn't a memory.
319 ///
320 /// # Panics
321 ///
322 /// Panics if `store` does not own this instance.
323 pub fn get_memory(&self, store: impl AsContextMut, name: &str) -> Option<Memory> {
324 self.0.get_memory(store, name)
325 }
326
327 /// Looks up an exported [`Func`] value by name.
328 ///
329 /// Returns `None` if there was no export named `name`, or if there was but
330 /// it wasn't a function.
331 ///
332 /// # Panics
333 ///
334 /// Panics if `store` does not own this instance.
335 pub fn get_func(&self, store: impl AsContextMut, name: &str) -> Option<Func> {
336 self.0.get_func(store, name)
337 }
338
339 /// Looks up an exported [`Func`] value by name and with its type.
340 ///
341 /// This function is a convenience wrapper over [`Instance::get_func`] and
342 /// [`Func::typed`]. For more information see the linked documentation.
343 ///
344 /// Returns an error if `name` isn't a function export or if the export's
345 /// type did not match `Params` or `Results`
346 ///
347 /// # Panics
348 ///
349 /// Panics if `store` does not own this instance.
350 pub fn get_typed_func<Params, Results>(
351 &self,
352 store: impl AsContextMut,
353 name: &str,
354 ) -> Result<TypedFunc<Params, Results>>
355 where
356 Params: WasmParams,
357 Results: WasmResults,
358 {
359 self.0.get_typed_func(store, name)
360 }
361}
362
363/// Structure used to link wasm modules/instances together.
364///
365/// This structure is used to assist in instantiating a [`Module`]. A [`Linker`]
366/// is a way of performing name resolution to make instantiating a module easier
367/// than specifying positional imports to [`Instance::new`]. [`Linker`] is a
368/// name-based resolver where names are dynamically defined and then used to
369/// instantiate a [`Module`].
370///
371/// An important method is [`Linker::instantiate`] which takes a module to
372/// instantiate into the provided store. This method will automatically select
373/// all the right imports for the [`Module`] to be instantiated, and will
374/// otherwise return an error if an import isn't satisfied.
375///
376/// ## Name Resolution
377///
378/// As mentioned previously, `Linker` is a form of name resolver. It will be
379/// using the string-based names of imports on a module to attempt to select a
380/// matching item to hook up to it. This name resolution has two-levels of
381/// namespaces, a module level and a name level. Each item is defined within a
382/// module and then has its own name. This basically follows the wasm standard
383/// for modularization.
384///
385/// Names in a `Linker` cannot be defined twice, but allowing duplicates by
386/// shadowing the previous definition can be controlled with the
387/// [`Linker::allow_shadowing`] method.
388///
389/// ## Commands and Reactors
390///
391/// The [`Linker`] type provides conveniences for working with WASI Commands and
392/// Reactors through the [`Linker::module`] method. This will automatically
393/// handle instantiation and calling `_start` and such as appropriate
394/// depending on the inferred type of module.
395///
396/// ## Type parameter `T`
397///
398/// It's worth pointing out that the type parameter `T` on [`Linker<T>`] does
399/// not represent that `T` is stored within a [`Linker`]. Rather the `T` is used
400/// to ensure that linker-defined functions and stores instantiated into all use
401/// the same matching `T` as host state.
402///
403/// ## Multiple `Store`s
404///
405/// The [`Linker`] type is designed to be compatible, in some scenarios, with
406/// instantiation in multiple [`Store`]s. Specifically host-defined functions
407/// created in [`Linker`] with [`Linker::func_new`], [`Linker::func_wrap`], and
408/// their async versions are compatible to instantiate into any [`Store`]. This
409/// enables programs which want to instantiate lots of modules to create one
410/// [`Linker`] value at program start up and use that continuously for each
411/// [`Store`] created over the lifetime of the program.
412///
413/// Note that once [`Store`]-owned items, such as [`Global`], are defined witin
414/// a [`Linker`] then it is no longer compatible with any [`Store`]. At that
415/// point only the [`Store`] that owns the [`Global`] can be used to instantiate
416/// modules.
417///
418/// ## Multiple `Engine`s
419///
420/// The [`Linker`] type is not compatible with usage between multiple [`Engine`]
421/// values. An [`Engine`] is provided when a [`Linker`] is created and only
422/// stores and items which originate from that [`Engine`] can be used with this
423/// [`Linker`]. If more than one [`Engine`] is used with a [`Linker`] then that
424/// may cause a panic at runtime, similar to how if a [`Func`] is used with the
425/// wrong [`Store`] that can also panic at runtime.
426///
427/// [`Store`]: crate::Store
428/// [`Global`]: crate::Global
429#[repr(transparent)]
430#[derive(RefCast, Clone)]
431pub struct Linker<T>(pub(crate) wasmtime::Linker<T>);
432
433impl<T> Linker<T> {
434 /// Creates a new [`Linker`].
435 ///
436 /// The linker will define functions within the context of the `engine`
437 /// provided and can only instantiate modules for a [`Store`][crate::Store]
438 /// that is also defined within the same [`Engine`]. Usage of stores with
439 /// different [`Engine`]s may cause a panic when used with this [`Linker`].
440 pub fn new(engine: &Engine) -> Self {
441 Self(wasmtime::Linker::new(engine))
442 }
443
444 #[deprecated(
445 since = "0.4.0",
446 note = "Instantiating a module synchronously can panic on the web, please use `instantiate_safe` instead."
447 )]
448 pub fn instantiate(
449 &self,
450 store: impl AsContextMut<Data = T>,
451 module: &Module,
452 ) -> Result<Instance, Error> {
453 Ok(Instance(self.0.instantiate(store, &module.0)?))
454 }
455
456 /// Attempts to instantiate the `module` provided.
457 ///
458 /// This method will attempt to assemble a list of imports that correspond
459 /// to the imports required by the [`Module`] provided. This list
460 /// of imports is then passed to [`Instance::new`] to continue the
461 /// instantiation process.
462 ///
463 /// Each import of `module` will be looked up in this [`Linker`] and must
464 /// have previously been defined. If it was previously defined with an
465 /// incorrect signature or if it was not previously defined then an error
466 /// will be returned because the import can not be satisfied.
467 ///
468 /// Per the WebAssembly spec, instantiation includes running the module's
469 /// start function, if it has one (not to be confused with the `_start`
470 /// function, which is not run).
471 ///
472 /// # Errors
473 ///
474 /// This method can fail because an import may not be found, or because
475 /// instantiation itself may fail. For information on instantiation
476 /// failures see [`Instance::new`]. If an import is not found, the error
477 /// may be downcast to an [`UnknownImportError`].
478 ///
479 ///
480 /// # Panics
481 ///
482 /// Panics if any item used to instantiate `module` is not owned by
483 /// `store`. Additionally this will panic if the [`Engine`] that the `store`
484 /// belongs to is different than this [`Linker`].
485 ///
486 /// # Examples
487 ///
488 /// ```
489 /// # use wasmtime::*;
490 /// # fn main() -> anyhow::Result<()> {
491 /// # let engine = Engine::default();
492 /// # let mut store = Store::new(&engine, ());
493 /// let mut linker = Linker::new(&engine);
494 /// linker.func_wrap("host", "double", |x: i32| x * 2)?;
495 ///
496 /// let wat = r#"
497 /// (module
498 /// (import "host" "double" (func (param i32) (result i32)))
499 /// )
500 /// "#;
501 /// let module = Module::new(&engine, wat)?;
502 /// linker.instantiate(&mut store, &module)?;
503 /// # Ok(())
504 /// # }
505 /// ```
506 pub async fn instantiate_safe(
507 &self,
508 store: impl AsContextMut<Data = T>,
509 module: &Module,
510 ) -> Result<Instance, Error> {
511 // This just calls `instantiate` on sys, but uses proper async instantiation on the web.
512 #[allow(deprecated)]
513 self.instantiate(store, module)
514 }
515
516 /// Attempts to instantiate the `module` provided. This is the same as
517 /// [`Linker::instantiate`], except for async `Store`s.
518 #[cfg(feature = "async")]
519 pub async fn instantiate_async(
520 &self,
521 store: impl AsContextMut<Data = T>,
522 module: &Module,
523 ) -> Result<Instance>
524 where
525 T: Send,
526 {
527 Ok(Instance(self.0.instantiate_async(store, &module.0).await?))
528 }
529
530 /// Creates a [`Func::new`]-style function named in this linker.
531 ///
532 /// For more information see [`Linker::func_wrap`].
533 ///
534 /// # Panics
535 ///
536 /// Panics if the given function type is not associated with the same engine
537 /// as this linker.
538 pub fn func_new(
539 &mut self,
540 module: &str,
541 name: &str,
542 ty: FuncType,
543 func: impl Fn(Caller<T>, &[Val], &mut [Val]) -> Result<()> + Send + Sync + 'static,
544 ) -> Result<&mut Self> {
545 Ok(Self::ref_cast_mut(self.0.func_new(module, name, ty, func)?))
546 }
547
548 /// Define a host function within this linker.
549 ///
550 /// For information about how the host function operates, see
551 /// [`Func::wrap`]. That includes information about translating Rust types
552 /// to WebAssembly native types.
553 ///
554 /// This method creates a host-provided function in this linker under the
555 /// provided name. This method is distinct in its capability to create a
556 /// [`Store`](crate::Store)-independent function. This means that the
557 /// function defined here can be used to instantiate instances in multiple
558 /// different stores, or in other words the function can be loaded into
559 /// different stores.
560 ///
561 /// Note that the capability mentioned here applies to all other
562 /// host-function-defining-methods on [`Linker`] as well. All of them can be
563 /// used to create instances of [`Func`] within multiple stores. In a
564 /// multithreaded program, for example, this means that the host functions
565 /// could be called concurrently if different stores are executing on
566 /// different threads.
567 ///
568 /// # Errors
569 ///
570 /// Returns an error if the `module` and `name` already identify an item
571 /// of the same type as the `item` provided and if shadowing is disallowed.
572 /// For more information see the documentation on [`Linker`].
573 ///
574 /// # Examples
575 ///
576 /// ```
577 /// # use wasmtime::*;
578 /// # fn main() -> anyhow::Result<()> {
579 /// # let engine = Engine::default();
580 /// let mut linker = Linker::new(&engine);
581 /// linker.func_wrap("host", "double", |x: i32| x * 2)?;
582 /// linker.func_wrap("host", "log_i32", |x: i32| println!("{}", x))?;
583 /// linker.func_wrap("host", "log_str", |caller: Caller<'_, ()>, ptr: i32, len: i32| {
584 /// // ...
585 /// })?;
586 ///
587 /// let wat = r#"
588 /// (module
589 /// (import "host" "double" (func (param i32) (result i32)))
590 /// (import "host" "log_i32" (func (param i32)))
591 /// (import "host" "log_str" (func (param i32 i32)))
592 /// )
593 /// "#;
594 /// let module = Module::new(&engine, wat)?;
595 ///
596 /// // instantiate in multiple different stores
597 /// for _ in 0..10 {
598 /// let mut store = Store::new(&engine, ());
599 /// linker.instantiate(&mut store, &module)?;
600 /// }
601 /// # Ok(())
602 /// # }
603 /// ```
604 pub fn func_wrap<Params, Results>(
605 &mut self,
606 module: &str,
607 name: &str,
608 func: impl IntoFunc<T, Params, Results>,
609 ) -> Result<&mut Self> {
610 Ok(Self::ref_cast_mut(self.0.func_wrap(module, name, func)?))
611 }
612}
613
614#[cfg(feature = "component-model")]
615pub mod component {
616 pub use wasmtime::component::*;
617
618 pub use wasm_bridge_macros::bindgen_sys as bindgen;
619 pub use wasm_bridge_macros::flags_sys as flags;
620 pub use wasm_bridge_macros::ComponentType;
621 pub use wasm_bridge_macros::Lift;
622 pub use wasm_bridge_macros::Lower;
623
624 use ref_cast::RefCast;
625 use wasmtime::{AsContextMut, Engine, Result};
626
627 /// A compiled WebAssembly Component.
628 ///
629 /// This structure represents a compiled component that is ready to be
630 /// instantiated. This owns a region of virtual memory which contains executable
631 /// code compiled from a WebAssembly binary originally. This is the analog of
632 /// [`Module`](crate::Module) in the component embedding API.
633 ///
634 /// A [`Component`] can be turned into an
635 /// [`Instance`](crate::component::Instance) through a
636 /// [`Linker`](crate::component::Linker). [`Component`]s are safe to share
637 /// across threads. The compilation model of a component is the same as that of
638 /// [a module](crate::Module) which is to say:
639 ///
640 /// * Compilation happens synchronously during [`Component::new`].
641 /// * The result of compilation can be saved into storage with
642 /// [`Component::serialize`].
643 /// * A previously compiled artifact can be parsed with
644 /// [`Component::deserialize`].
645 /// * No compilation happens at runtime for a component — everything is done
646 /// by the time [`Component::new`] returns.
647 ///
648 /// ## Components and `Clone`
649 ///
650 /// Using `clone` on a `Component` is a cheap operation. It will not create an
651 /// entirely new component, but rather just a new reference to the existing
652 /// component. In other words it's a shallow copy, not a deep copy.
653 ///
654 /// ## Examples
655 ///
656 /// For example usage see the documentation of [`Module`](crate::Module) as
657 /// [`Component`] has the same high-level API.
658 #[repr(transparent)]
659 #[derive(RefCast, Clone)]
660 pub struct Component(pub(crate) wasmtime::component::Component);
661
662 impl Component {
663 #[deprecated(
664 since = "0.4.0",
665 note = "Compiling a component synchronously can panic on the web, please use `new_safe` instead."
666 )]
667 pub fn new(engine: &Engine, bytes: impl AsRef<[u8]>) -> Result<Self> {
668 Ok(Self(wasmtime::component::Component::new(engine, bytes)?))
669 }
670
671 /// Compiles a new WebAssembly component from the in-memory list of bytes
672 /// provided.
673 ///
674 /// The `bytes` provided can either be the binary or text format of a
675 /// [WebAssembly component]. Note that the text format requires the `wat`
676 /// feature of this crate to be enabled. This API does not support
677 /// streaming compilation.
678 ///
679 /// This function will synchronously validate the entire component,
680 /// including all core modules, and then compile all components, modules,
681 /// etc., found within the provided bytes.
682 ///
683 /// [WebAssembly component]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md
684 ///
685 /// # Errors
686 ///
687 /// This function may fail and return an error. Errors may include
688 /// situations such as:
689 ///
690 /// * The binary provided could not be decoded because it's not a valid
691 /// WebAssembly binary
692 /// * The WebAssembly binary may not validate (e.g. contains type errors)
693 /// * Implementation-specific limits were exceeded with a valid binary (for
694 /// example too many locals)
695 /// * The wasm binary may use features that are not enabled in the
696 /// configuration of `engine`
697 /// * If the `wat` feature is enabled and the input is text, then it may be
698 /// rejected if it fails to parse.
699 ///
700 /// The error returned should contain full information about why compilation
701 /// failed.
702 ///
703 /// # Examples
704 ///
705 /// The `new` function can be invoked with a in-memory array of bytes:
706 ///
707 /// ```no_run
708 /// # use wasmtime::*;
709 /// # use wasmtime::component::Component;
710 /// # fn main() -> anyhow::Result<()> {
711 /// # let engine = Engine::default();
712 /// # let wasm_bytes: Vec<u8> = Vec::new();
713 /// let component = Component::new(&engine, &wasm_bytes)?;
714 /// # Ok(())
715 /// # }
716 /// ```
717 ///
718 /// Or you can also pass in a string to be parsed as the wasm text
719 /// format:
720 ///
721 /// ```
722 /// # use wasmtime::*;
723 /// # use wasmtime::component::Component;
724 /// # fn main() -> anyhow::Result<()> {
725 /// # let engine = Engine::default();
726 /// let component = Component::new(&engine, "(component (core module))")?;
727 /// # Ok(())
728 /// # }
729 pub async fn new_safe(engine: &Engine, bytes: impl AsRef<[u8]>) -> Result<Self> {
730 // This just calls `new` on sys, but uses proper async compilation on the web.
731 #[allow(deprecated)]
732 Self::new(engine, bytes)
733 }
734 }
735
736 /// A type used to instantiate [`Component`]s.
737 ///
738 /// This type is used to both link components together as well as supply host
739 /// functionality to components. Values are defined in a [`Linker`] by their
740 /// import name and then components are instantiated with a [`Linker`] using the
741 /// names provided for name resolution of the component's imports.
742 ///
743 /// # Names and Semver
744 ///
745 /// Names defined in a [`Linker`] correspond to import names in the Component
746 /// Model. Names in the Component Model are allowed to be semver-qualified, for
747 /// example:
748 ///
749 /// * `wasi:cli/stdout@0.2.0`
750 /// * `wasi:http/types@0.2.0-rc-2023-10-25`
751 /// * `my:custom/plugin@1.0.0-pre.2`
752 ///
753 /// These version strings are taken into account when looking up names within a
754 /// [`Linker`]. You're allowed to define any number of versions within a
755 /// [`Linker`] still, for example you can define `a:b/c@0.2.0`, `a:b/c@0.2.1`,
756 /// and `a:b/c@0.3.0` all at the same time.
757 ///
758 /// Specifically though when names are looked up within a linker, for example
759 /// during instantiation, semver-compatible names are automatically consulted.
760 /// This means that if you define `a:b/c@0.2.1` in a [`Linker`] but a component
761 /// imports `a:b/c@0.2.0` then that import will resolve to the `0.2.1` version.
762 ///
763 /// This lookup behavior relies on hosts being well-behaved when using Semver,
764 /// specifically that interfaces once defined are never changed. This reflects
765 /// how Semver works at the Component Model layer, and it's assumed that if
766 /// versions are present then hosts are respecting this.
767 ///
768 /// Note that this behavior goes the other direction, too. If a component
769 /// imports `a:b/c@0.2.1` and the host has provided `a:b/c@0.2.0` then that
770 /// will also resolve correctly. This is because if an API was defined at 0.2.0
771 /// and 0.2.1 then it must be the same API.
772 ///
773 /// This behavior is intended to make it easier for hosts to upgrade WASI and
774 /// for guests to upgrade WASI. So long as the actual "meat" of the
775 /// functionality is defined then it should align correctly and components can
776 /// be instantiated.
777 #[repr(transparent)]
778 #[derive(RefCast, Clone)]
779 pub struct Linker<T>(pub wasmtime::component::Linker<T>);
780
781 impl<T> Linker<T> {
782 /// Creates a new linker for the [`Engine`] specified with no items defined
783 /// within it.
784 pub fn new(engine: &Engine) -> Self {
785 Self(wasmtime::component::Linker::new(engine))
786 }
787
788 #[deprecated(
789 since = "0.4.0",
790 note = "Instantiating a component synchronously can panic on the web, please use `instantiate_safe` instead."
791 )]
792 pub fn instantiate(
793 &self,
794 store: impl AsContextMut<Data = T>,
795 component: &Component,
796 ) -> Result<Instance> {
797 self.0.instantiate(store, &component.0)
798 }
799
800 /// Instantiates the [`Component`] provided into the `store` specified.
801 ///
802 /// This function will use the items defined within this [`Linker`] to
803 /// satisfy the imports of the [`Component`] provided as necessary. For more
804 /// information about this see [`Linker::instantiate_pre`] as well.
805 ///
806 /// # Errors
807 ///
808 /// Returns an error if this [`Linker`] doesn't define an import that
809 /// `component` requires or if it is of the wrong type. Additionally this
810 /// can return an error if something goes wrong during instantiation such as
811 /// a runtime trap or a runtime limit being exceeded.
812 pub async fn instantiate_safe(
813 &self,
814 store: impl AsContextMut<Data = T>,
815 component: &Component,
816 ) -> Result<Instance> {
817 // This just calls `instantiate` on sys, but uses proper async instantiation on the web.
818 #[allow(deprecated)]
819 self.instantiate(store, component)
820 }
821
822 /// Instantiates the [`Component`] provided into the `store` specified.
823 ///
824 /// This is exactly like [`Linker::instantiate`] except for async stores.
825 ///
826 /// # Errors
827 ///
828 /// Returns an error if this [`Linker`] doesn't define an import that
829 /// `component` requires or if it is of the wrong type. Additionally this
830 /// can return an error if something goes wrong during instantiation such as
831 /// a runtime trap or a runtime limit being exceeded.:w
832 ///
833 #[cfg(feature = "async")]
834 pub async fn instantiate_async(
835 &self,
836 store: impl AsContextMut<Data = T>,
837 component: &Component,
838 ) -> Result<Instance>
839 where
840 T: Send,
841 {
842 self.0.instantiate_async(store, &component.0).await
843 }
844
845 /// Returns the "root instance" of this linker, used to define names into
846 /// the root namespace.
847 pub fn root(&mut self) -> LinkerInstance<T> {
848 self.0.root()
849 }
850
851 /// Returns a builder for the named instance specified.
852 ///
853 /// # Errors
854 ///
855 /// Returns an error if `name` is already defined within the linker.
856 pub fn instance(&mut self, name: &str) -> Result<LinkerInstance<T>> {
857 self.0.instance(name)
858 }
859 }
860}
861
862#[cfg(feature = "async")]
863pub use async_trait::async_trait;