wasmtime/runtime/component/mod.rs
1//! # Embedding API for the Component Model
2//!
3//! This module contains the embedding API for the [Component Model] in
4//! Wasmtime. This module requires the `component-model` feature to be enabled,
5//! which is enabled by default. The embedding API here is mirrored after the
6//! core wasm embedding API at the crate root and is intended to have the same
7//! look-and-feel while handling concepts of the component model.
8//!
9//! [Component Model]: https://component-model.bytecodealliance.org
10//!
11//! The component model is a broad topic which can't be explained here fully, so
12//! it's recommended to read over individual items' documentation to see more
13//! about the capabilities of the embedding API. At a high-level, however,
14//! perhaps the most interesting items in this module are:
15//!
16//! * [`Component`] - a compiled component ready to be instantiated. Similar to
17//! a [`Module`](crate::Module) for core wasm.
18//!
19//! * [`Linker`] - a component-style location for defining host functions. This
20//! is not the same as [`wasmtime::Linker`](crate::Linker) for core wasm
21//! modules.
22//!
23//! * [`bindgen!`] - a macro to generate Rust bindings for a [WIT] [world]. This
24//! maps all WIT types into Rust automatically and generates traits for
25//! embedders to implement.
26//!
27//! [WIT]: https://component-model.bytecodealliance.org/design/wit.html
28//! [world]: https://component-model.bytecodealliance.org/design/worlds.html
29//!
30//! Embedders of the component model will typically start by defining their API
31//! in [WIT]. This describes what will be available to guests and what needs to
32//! be provided to the embedder by the guest. This [`world`][world] that was
33//! created is then fed into [`bindgen!`] to generate types and traits for the
34//! embedder to use. The embedder then implements these traits, adds
35//! functionality via the generated `add_to_linker` method (see [`bindgen!`] for
36//! more info), and then instantiates/executes a component.
37//!
38//! It's recommended to read over the [documentation for the Component
39//! Model][Component Model] to get an overview about how to build components
40//! from various languages.
41//!
42//! ## Example Usage
43//!
44//! Imagine you have the following WIT package definition in a file called world.wit
45//! along with a component (my_component.wasm) that targets `my-world`:
46//!
47//! ```text,ignore
48//! package component:my-package;
49//!
50//! world my-world {
51//! import name: func() -> string;
52//! export greet: func() -> string;
53//! }
54//! ```
55//!
56//! You can instantiate and call the component like so:
57//!
58//! ```
59//! fn main() -> wasmtime::Result<()> {
60//! # if true { return Ok(()) }
61//! // Instantiate the engine and store
62//! let engine = wasmtime::Engine::default();
63//! let mut store = wasmtime::Store::new(&engine, ());
64//!
65//! // Load the component from disk
66//! let bytes = std::fs::read("my_component.wasm")?;
67//! let component = wasmtime::component::Component::new(&engine, bytes)?;
68//!
69//! // Configure the linker
70//! let mut linker = wasmtime::component::Linker::new(&engine);
71//! // The component expects one import `name` that
72//! // takes no params and returns a string
73//! linker
74//! .root()
75//! .func_wrap("name", |_store, _params: ()| {
76//! Ok((String::from("Alice"),))
77//! })?;
78//!
79//! // Instantiate the component
80//! let instance = linker.instantiate(&mut store, &component)?;
81//!
82//! // Call the `greet` function
83//! let func = instance.get_func(&mut store, "greet").expect("greet export not found");
84//! let mut result = [wasmtime::component::Val::String("".into())];
85//! func.call(&mut store, &[], &mut result)?;
86//!
87//! // This should print out `Greeting: [String("Hello, Alice!")]`
88//! println!("Greeting: {:?}", result);
89//!
90//! Ok(())
91//! }
92//! ```
93//!
94//! Manually configuring the linker and calling untyped component exports is
95//! a bit tedious and error prone. The [`bindgen!`] macro can be used to
96//! generate bindings eliminating much of this boilerplate.
97//!
98//! See the docs for [`bindgen!`] for more information on how to use it.
99
100// rustdoc appears to lie about a warning above, so squelch it for now.
101#![allow(rustdoc::redundant_explicit_links)]
102
103mod component;
104#[cfg(feature = "component-model-async")]
105pub(crate) mod concurrent;
106mod func;
107mod instance;
108mod linker;
109mod matching;
110mod resource_table;
111mod resources;
112mod storage;
113mod store;
114pub mod types;
115mod values;
116pub use self::component::{Component, ComponentExportIndex};
117#[cfg(feature = "component-model-async")]
118pub use self::concurrent::{ErrorContext, FutureReader, Promise, PromisesUnordered, StreamReader};
119pub use self::func::{
120 ComponentNamedList, ComponentType, Func, Lift, Lower, TypedFunc, WasmList, WasmStr,
121};
122pub use self::instance::{Instance, InstanceExportLookup, InstancePre};
123pub use self::linker::{Linker, LinkerInstance};
124pub use self::resource_table::{ResourceTable, ResourceTableError};
125pub use self::resources::{Resource, ResourceAny};
126pub use self::types::{ResourceType, Type};
127pub use self::values::Val;
128
129pub(crate) use self::resources::HostResourceData;
130
131// Re-export wasm_wave crate so the compatible version of this dep doesn't have to be
132// tracked separately from wasmtime.
133#[cfg(feature = "wave")]
134pub use wasm_wave;
135
136// These items are used by `#[derive(ComponentType, Lift, Lower)]`, but they are not part of
137// Wasmtime's API stability guarantees
138#[doc(hidden)]
139pub mod __internal {
140 pub use super::func::{
141 bad_type_info, format_flags, lower_payload, typecheck_enum, typecheck_flags,
142 typecheck_record, typecheck_variant, ComponentVariant, LiftContext, LowerContext, Options,
143 };
144 pub use super::matching::InstanceType;
145 pub use crate::map_maybe_uninit;
146 pub use crate::store::StoreOpaque;
147 pub use crate::MaybeUninitExt;
148 pub use alloc::boxed::Box;
149 pub use alloc::string::String;
150 pub use alloc::vec::Vec;
151 pub use anyhow;
152 pub use core::mem::transmute;
153 #[cfg(feature = "async")]
154 pub use trait_variant::make as trait_variant_make;
155 pub use wasmtime_environ;
156 pub use wasmtime_environ::component::{CanonicalAbiInfo, ComponentTypes, InterfaceType};
157}
158
159pub(crate) use self::store::ComponentStoreData;
160
161/// Generate bindings for a [WIT world].
162///
163/// [WIT world]: https://component-model.bytecodealliance.org/design/worlds.html
164/// [WIT package]: https://component-model.bytecodealliance.org/design/packages.html
165///
166/// This macro ingests a [WIT world] and will generate all the necessary
167/// bindings for instantiating components that ascribe to the `world`. This
168/// provides a higher-level representation of working with a component than the
169/// raw [`Instance`] type which must be manually-type-checked and manually have
170/// its imports provided via the [`Linker`] type.
171///
172/// # Examples
173///
174/// Examples for this macro can be found in the [`bindgen_examples`] module
175/// documentation. That module has a submodule-per-example which includes the
176/// source code, with WIT, used to generate the structures along with the
177/// generated code itself in documentation.
178///
179/// # Debugging and Exploring
180///
181/// If you need to debug the output of `bindgen!` you can try using the
182/// `WASMTIME_DEBUG_BINDGEN=1` environment variable. This will write the
183/// generated code to a file on disk so rustc can produce better error messages
184/// against the actual generated source instead of the macro invocation itself.
185/// This additionally can enable opening up the generated code in an editor and
186/// exploring it (through an error message).
187///
188/// The generated bindings can additionally be explored with `cargo doc` to see
189/// what's generated. It's also recommended to browse the [`bindgen_examples`]
190/// for example generated structures and example generated code.
191///
192/// # Syntax
193///
194/// This procedural macro accepts a few different syntaxes. The primary purpose
195/// of this macro is to locate a WIT package, parse it, and then extract a
196/// `world` from the parsed package. There are then codegen-specific options to
197/// the bindings themselves which can additionally be specified.
198///
199/// Usage of this macro looks like:
200///
201/// ```rust
202/// # macro_rules! bindgen { ($($t:tt)*) => () }
203/// // Parse the `wit/` folder adjacent to this crate's `Cargo.toml` and look
204/// // for a single `world` in it. There must be exactly one for this to
205/// // succeed.
206/// bindgen!();
207///
208/// // Parse the `wit/` folder adjacent to this crate's `Cargo.toml` and look
209/// // for the world `foo` contained in it.
210/// bindgen!("foo");
211///
212/// // Parse the folder `other/wit/folder` adjacent to `Cargo.toml`.
213/// bindgen!(in "other/wit/folder");
214/// bindgen!("foo" in "other/wit/folder");
215///
216/// // Parse the file `foo.wit` as a single-file WIT package with no
217/// // dependencies.
218/// bindgen!("foo" in "foo.wit");
219///
220/// // Specify a suite of options to the bindings generation, documented below
221/// bindgen!({
222/// world: "foo",
223/// path: "other/path/to/wit",
224/// // ...
225/// });
226/// ```
227///
228/// # Options Reference
229///
230/// This is an example listing of all options that this macro supports along
231/// with documentation for each option and example syntax for each option.
232///
233/// ```rust
234/// # macro_rules! bindgen { ($($t:tt)*) => () }
235/// bindgen!({
236/// world: "foo", // not needed if `path` has one `world`
237///
238/// // same as in `bindgen!(in "other/wit/folder")
239/// path: "other/wit/folder",
240///
241/// // Instead of `path` the WIT document can be provided inline if
242/// // desired.
243/// inline: "
244/// package my:inline;
245///
246/// world foo {
247/// // ...
248/// }
249/// ",
250///
251/// // Add calls to `tracing::span!` before each import or export is called
252/// // to log most arguments and return values. By default values
253/// // containing lists are excluded; enable `verbose_tracing` to include
254/// // them.
255/// //
256/// // This option defaults to `false`.
257/// tracing: true,
258///
259/// // Include all arguments and return values in the tracing output,
260/// // including values containing lists, which may be very large.
261/// //
262/// // This option defaults to `false`.
263/// verbose_tracing: false,
264///
265/// // Imports will be async functions and exports
266/// // are also invoked as async functions. Requires `Config::async_support`
267/// // to be `true`.
268/// //
269/// // Note that this is only async for the host as the guest will still
270/// // appear as if it's invoking blocking functions.
271/// //
272/// // This option defaults to `false`.
273/// async: true,
274///
275/// // Alternative mode of async configuration where this still implies
276/// // async instantiation happens, for example, but more control is
277/// // provided over which imports are async and which aren't.
278/// //
279/// // Note that in this mode all exports are still async.
280/// async: {
281/// // All imports are async except for functions with these names
282/// except_imports: ["foo", "bar"],
283///
284/// // All imports are synchronous except for functions with these names
285/// //
286/// // Note that this key cannot be specified with `except_imports`,
287/// // only one or the other is accepted.
288/// only_imports: ["foo", "bar"],
289/// },
290///
291/// // This option is used to indicate whether imports can trap.
292/// //
293/// // Imports that may trap have their return types wrapped in
294/// // `wasmtime::Result<T>` where the `Err` variant indicates that a
295/// // trap will be raised in the guest.
296/// //
297/// // By default imports cannot trap and the return value is the return
298/// // value from the WIT bindings itself. This value can be set to `true`
299/// // to indicate that any import can trap. This value can also be set to
300/// // an array-of-strings to indicate that only a set list of imports
301/// // can trap.
302/// trappable_imports: false, // no imports can trap (default)
303/// // trappable_imports: true, // all imports can trap
304/// // trappable_imports: ["foo", "bar"], // only these can trap
305///
306/// // This can be used to translate WIT return values of the form
307/// // `result<T, error-type>` into `Result<T, RustErrorType>` in Rust.
308/// // Users must define `RustErrorType` and the `Host` trait for the
309/// // interface which defines `error-type` will have a method
310/// // called `convert_error_type` which converts `RustErrorType`
311/// // into `wasmtime::Result<ErrorType>`. This conversion can either
312/// // return the raw WIT error (`ErrorType` here) or a trap.
313/// //
314/// // By default this option is not specified. This option only takes
315/// // effect when `trappable_imports` is set for some imports.
316/// trappable_error_type: {
317/// "wasi:io/streams/stream-error" => RustErrorType,
318/// },
319///
320/// // All generated bindgen types are "owned" meaning types like `String`
321/// // are used instead of `&str`, for example. This is the default and
322/// // ensures that the same type used in both imports and exports uses the
323/// // same generated type.
324/// ownership: Owning,
325///
326/// // Alternative to `Owning` above where borrowed types attempt to be used
327/// // instead. The `duplicate_if_necessary` configures whether duplicate
328/// // Rust types will be generated for the same WIT type if necessary, for
329/// // example when a type is used both as an import and an export.
330/// ownership: Borrowing {
331/// duplicate_if_necessary: true
332/// },
333///
334/// // Restrict the code generated to what's needed for the interface
335/// // imports in the inlined WIT document fragment.
336/// interfaces: "
337/// import wasi:cli/command;
338/// ",
339///
340/// // Remap imported interfaces or resources to types defined in Rust
341/// // elsewhere. Using this option will prevent any code from being
342/// // generated for interfaces mentioned here. Resources named here will
343/// // not have a type generated to represent the resource.
344/// //
345/// // Interfaces mapped with this option should be previously generated
346/// // with an invocation of this macro. Resources need to be mapped to a
347/// // Rust type name.
348/// with: {
349/// // This can be used to indicate that entire interfaces have
350/// // bindings generated elsewhere with a path pointing to the
351/// // bindinges-generated module.
352/// "wasi:random/random": wasmtime_wasi::bindings::random::random,
353///
354/// // Similarly entire packages can also be specified.
355/// "wasi:cli": wasmtime_wasi::bindings::cli,
356///
357/// // Or, if applicable, entire namespaces can additionally be mapped.
358/// "wasi": wasmtime_wasi::bindings,
359///
360/// // Versions are supported if multiple versions are in play:
361/// "wasi:http/types@0.2.0": wasmtime_wasi_http::bindings::http::types,
362/// "wasi:http@0.2.0": wasmtime_wasi_http::bindings::http,
363///
364/// // The `with` key can also be used to specify the `T` used in
365/// // import bindings of `Resource<T>`. This can be done to configure
366/// // which typed resource shows up in generated bindings and can be
367/// // useful when working with the typed methods of `ResourceTable`.
368/// "wasi:filesystem/types/descriptor": MyDescriptorType,
369/// },
370///
371/// // Additional derive attributes to include on generated types (structs or enums).
372/// //
373/// // These are deduplicated and attached in a deterministic order.
374/// additional_derives: [
375/// Hash,
376/// serde::Deserialize,
377/// serde::Serialize,
378/// ],
379///
380/// // An niche configuration option to require that the `T` in `Store<T>`
381/// // is always `Send` in the generated bindings. Typically not needed
382/// // but if synchronous bindings depend on asynchronous bindings using
383/// // the `with` key then this may be required.
384/// require_store_data_send: false,
385///
386/// // If the `wasmtime` crate is depended on at a nonstandard location
387/// // or is renamed then this is the path to the root of the `wasmtime`
388/// // crate. Much of the generated code needs to refer to `wasmtime` so
389/// // this should be used if the `wasmtime` name is not wasmtime itself.
390/// //
391/// // By default this is `wasmtime`.
392/// wasmtime_crate: path::to::wasmtime,
393///
394/// // This is an in-source alternative to using `WASMTIME_DEBUG_BINDGEN`.
395/// //
396/// // Note that if this option is specified then the compiler will always
397/// // recompile your bindings. Cargo records the start time of when rustc
398/// // is spawned by this will write a file during compilation. To Cargo
399/// // that looks like a file was modified after `rustc` was spawned,
400/// // so Cargo will always think your project is "dirty" and thus always
401/// // recompile it. Recompiling will then overwrite the file again,
402/// // starting the cycle anew. This is only recommended for debugging.
403/// //
404/// // This option defaults to false.
405/// include_generated_code_from_file: false,
406/// });
407/// ```
408pub use wasmtime_component_macro::bindgen;
409
410/// Derive macro to generate implementations of the [`ComponentType`] trait.
411///
412/// This derive macro can be applied to `struct` and `enum` definitions and is
413/// used to bind either a `record`, `enum`, or `variant` in the component model.
414///
415/// Note you might be looking for [`bindgen!`] rather than this macro as that
416/// will generate the entire type for you rather than just a trait
417/// implementation.
418///
419/// This macro supports a `#[component]` attribute which is used to customize
420/// how the type is bound to the component model. A top-level `#[component]`
421/// attribute is required to specify either `record`, `enum`, or `variant`.
422///
423/// ## Records
424///
425/// `record`s in the component model correspond to `struct`s in Rust. An example
426/// is:
427///
428/// ```rust
429/// use wasmtime::component::ComponentType;
430///
431/// #[derive(ComponentType)]
432/// #[component(record)]
433/// struct Color {
434/// r: u8,
435/// g: u8,
436/// b: u8,
437/// }
438/// ```
439///
440/// which corresponds to the WIT type:
441///
442/// ```wit
443/// record color {
444/// r: u8,
445/// g: u8,
446/// b: u8,
447/// }
448/// ```
449///
450/// Note that the name `Color` here does not need to match the name in WIT.
451/// That's purely used as a name in Rust of what to refer to. The field names
452/// must match that in WIT, however. Field names can be customized with the
453/// `#[component]` attribute though.
454///
455/// ```rust
456/// use wasmtime::component::ComponentType;
457///
458/// #[derive(ComponentType)]
459/// #[component(record)]
460/// struct VerboseColor {
461/// #[component(name = "r")]
462/// red: u8,
463/// #[component(name = "g")]
464/// green: u8,
465/// #[component(name = "b")]
466/// blue: u8,
467/// }
468/// ```
469///
470/// Also note that field ordering is significant at this time and must match
471/// WIT.
472///
473/// ## Variants
474///
475/// `variant`s in the component model correspond to a subset of shapes of a Rust
476/// `enum`. Variants in the component model have a single optional payload type
477/// which means that not all Rust `enum`s correspond to component model
478/// `variant`s. An example variant is:
479///
480/// ```rust
481/// use wasmtime::component::ComponentType;
482///
483/// #[derive(ComponentType)]
484/// #[component(variant)]
485/// enum Filter {
486/// #[component(name = "none")]
487/// None,
488/// #[component(name = "all")]
489/// All,
490/// #[component(name = "some")]
491/// Some(Vec<String>),
492/// }
493/// ```
494///
495/// which corresponds to the WIT type:
496///
497/// ```wit
498/// variant filter {
499/// none,
500/// all,
501/// some(list<string>),
502/// }
503/// ```
504///
505/// The `variant` style of derive allows an optional payload on Rust `enum`
506/// variants but it must be a single unnamed field. Variants of the form `Foo(T,
507/// U)` or `Foo { name: T }` are not supported at this time.
508///
509/// Note that the order of variants in Rust must match the order of variants in
510/// WIT. Additionally it's likely that `#[component(name = "...")]` is required
511/// on all Rust `enum` variants because the name currently defaults to the Rust
512/// name which is typically UpperCamelCase whereas WIT uses kebab-case.
513///
514/// ## Enums
515///
516/// `enum`s in the component model correspond to C-like `enum`s in Rust. Note
517/// that a component model `enum` does not allow any payloads so the Rust `enum`
518/// must additionally have no payloads.
519///
520/// ```rust
521/// use wasmtime::component::ComponentType;
522///
523/// #[derive(ComponentType)]
524/// #[component(enum)]
525/// #[repr(u8)]
526/// enum Setting {
527/// #[component(name = "yes")]
528/// Yes,
529/// #[component(name = "no")]
530/// No,
531/// #[component(name = "auto")]
532/// Auto,
533/// }
534/// ```
535///
536/// which corresponds to the WIT type:
537///
538/// ```wit
539/// enum setting {
540/// yes,
541/// no,
542/// auto,
543/// }
544/// ```
545///
546/// Note that the order of variants in Rust must match the order of variants in
547/// WIT. Additionally it's likely that `#[component(name = "...")]` is required
548/// on all Rust `enum` variants because the name currently defaults to the Rust
549/// name which is typically UpperCamelCase whereas WIT uses kebab-case.
550pub use wasmtime_component_macro::ComponentType;
551
552/// A derive macro for generating implementations of the [`Lift`] trait.
553///
554/// This macro will likely be applied in conjunction with the
555/// [`#[derive(ComponentType)]`](macro@ComponentType) macro along the lines
556/// of `#[derive(ComponentType, Lift)]`. This trait enables reading values from
557/// WebAssembly.
558///
559/// Note you might be looking for [`bindgen!`] rather than this macro as that
560/// will generate the entire type for you rather than just a trait
561/// implementation.
562///
563/// At this time this derive macro has no configuration.
564///
565/// ## Examples
566///
567/// ```rust
568/// use wasmtime::component::{ComponentType, Lift};
569///
570/// #[derive(ComponentType, Lift)]
571/// #[component(record)]
572/// struct Color {
573/// r: u8,
574/// g: u8,
575/// b: u8,
576/// }
577/// ```
578pub use wasmtime_component_macro::Lift;
579
580/// A derive macro for generating implementations of the [`Lower`] trait.
581///
582/// This macro will likely be applied in conjunction with the
583/// [`#[derive(ComponentType)]`](macro@ComponentType) macro along the lines
584/// of `#[derive(ComponentType, Lower)]`. This trait enables passing values to
585/// WebAssembly.
586///
587/// Note you might be looking for [`bindgen!`] rather than this macro as that
588/// will generate the entire type for you rather than just a trait
589/// implementation.
590///
591/// At this time this derive macro has no configuration.
592///
593/// ## Examples
594///
595/// ```rust
596/// use wasmtime::component::{ComponentType, Lower};
597///
598/// #[derive(ComponentType, Lower)]
599/// #[component(record)]
600/// struct Color {
601/// r: u8,
602/// g: u8,
603/// b: u8,
604/// }
605/// ```
606pub use wasmtime_component_macro::Lower;
607
608/// A macro to generate a Rust type corresponding to WIT `flags`
609///
610/// This macro generates a type that implements the [`ComponentType`], [`Lift`],
611/// and [`Lower`] traits. The generated Rust type corresponds to the `flags`
612/// type in WIT.
613///
614/// Example usage of this looks like:
615///
616/// ```rust
617/// use wasmtime::component::flags;
618///
619/// flags! {
620/// Permissions {
621/// #[component(name = "read")]
622/// const READ;
623/// #[component(name = "write")]
624/// const WRITE;
625/// #[component(name = "execute")]
626/// const EXECUTE;
627/// }
628/// }
629///
630/// fn validate_permissions(permissions: &mut Permissions) {
631/// if permissions.contains(Permissions::EXECUTE | Permissions::WRITE) {
632/// panic!("cannot enable both writable and executable at the same time");
633/// }
634///
635/// if permissions.contains(Permissions::READ) {
636/// panic!("permissions must at least contain read");
637/// }
638/// }
639/// ```
640///
641/// which corresponds to the WIT type:
642///
643/// ```wit
644/// flags permissions {
645/// read,
646/// write,
647/// execute,
648/// }
649/// ```
650///
651/// This generates a structure which is similar to/inspired by the [`bitflags`
652/// crate](https://crates.io/crates/bitflags). The `Permissions` structure
653/// generated implements the [`PartialEq`], [`Eq`], [`Debug`], [`BitOr`],
654/// [`BitOrAssign`], [`BitAnd`], [`BitAndAssign`], [`BitXor`], [`BitXorAssign`],
655/// and [`Not`] traits - in addition to the Wasmtime-specific component ones
656/// [`ComponentType`], [`Lift`], and [`Lower`].
657///
658/// [`BitOr`]: std::ops::BitOr
659/// [`BitOrAssign`]: std::ops::BitOrAssign
660/// [`BitAnd`]: std::ops::BitAnd
661/// [`BitAndAssign`]: std::ops::BitAndAssign
662/// [`BitXor`]: std::ops::BitXor
663/// [`BitXorAssign`]: std::ops::BitXorAssign
664/// [`Not`]: std::ops::Not
665pub use wasmtime_component_macro::flags;
666
667#[cfg(any(docsrs, test, doctest))]
668pub mod bindgen_examples;
669
670// NB: needed for the links in the docs above to work in all `cargo doc`
671// configurations and avoid errors.
672#[cfg(not(any(docsrs, test, doctest)))]
673#[doc(hidden)]
674pub mod bindgen_examples {}