@ -1,37 +1,52 @@
//! Wasmtime's embedding API
//! # Wasmtime's embedding API
//!
//! Wasmtime is a WebAssembly engine for JIT-compiled or ahead-of-time compiled
//! WebAssembly modules. More information about the Wasmtime project as a whole
//! can be found [in the documentation book](https://docs.wasmtime.dev) whereas
//! this documentation mostly focuses on the API reference of the `wasmtime`
//! crate itself.
//!
//! This crate contains an API used to interact with WebAssembly modules. For
//! example you can compile modules, instantiate them, call them, etc. As an
//! embedder of WebAssembly you can also provide WebAssembly modules
//! functionality from the host by creating host-defined functions, memories,
//! globals, etc, which can do things that WebAssembly cannot (such as print to
//! the screen).
//!
//! The `wasmtime` crate has similar concepts to the
//! the [JS WebAssembly
//! WebAssembly modules and components. More information about the Wasmtime
//! project as a whole can be found [in the documentation
//! book](https://docs.wasmtime.dev) whereas this documentation mostly focuses
//! on the API reference of the `wasmtime` crate itself.
//!
//! This crate contains an API used to interact with [WebAssembly modules] or
//! [WebAssembly components]. For example you can compile WebAssembly, create
//! instances, call functions, etc. As an embedder of WebAssembly you can also
//! provide guests functionality from the host by creating host-defined
//! functions, memories, globals, etc, which can do things that WebAssembly
//! cannot (such as print to the screen).
//!
//! [WebAssembly modules]: https://webassembly.github.io/spec
//! [WebAssembly components]: https://component-model.bytecodealliance.org
//!
//! The `wasmtime` crate is designed to be safe, efficient, and ergonomic.
//! This enables executing WebAssembly without the embedder needing to use
//! `unsafe` code, meaning that you're guaranteed there is no undefined behavior
//! or segfaults in either the WebAssembly guest or the host itself.
//!
//! The `wasmtime` crate can roughly be thought of as being split into two
//! halves:
//!
//! * One half of the crate is similar to the [JS WebAssembly
//! API](https://developer.mozilla.org/en-US/docs/WebAssembly) as well as the
//! [proposed C API](https://github.com/webassembly/wasm-c-api), but the Rust
//! API is designed for efficiency, ergonomics, and expressivity in Rust. As
//! with all other Rust code you're guaranteed that programs will be safe (not
//! have undefined behavior or segfault) so long as you don't use `unsafe` in
//! your own program. With `wasmtime` you can easily and conveniently embed a
//! WebAssembly runtime with confidence that the WebAssembly is safely
//! sandboxed.
//! [proposed C API](https://github.com/webassembly/wasm-c-api) and is
//! intended for working with [WebAssembly modules]. This API resides in the
//! root of the `wasmtime` crate's namespace, for example
//! [`wasmtime::Module`](`Module`).
//!
//! An example of using Wasmtime looks like:
//! * The second half of the crate is for use with the [WebAssembly Component
//! Model]. The implementation of the component model is present in
//! [`wasmtime::component`](`component`) and roughly mirrors the structure for
//! core WebAssembly, for example [`component::Func`] mirrors [`Func`].
//!
//! [WebAssembly Component Model]: https://component-model.bytecodealliance.org
//!
//! An example of using Wasmtime to run a core WebAssembly module looks like:
//!
//! ```
//! use wasmtime::*;
//!
//! fn main() -> wasmtime::Result<()> {
//! // Modules can be compiled through either the text or binary format
//! let engine = Engine::default();
//!
//! // Modules can be compiled through either the text or binary format
//! let wat = r#"
//! (module
//! (import "host" "host_func" (func $host_hello (param i32)))
@ -43,19 +58,23 @@
//! "#;
//! let module = Module::new(&engine, wat)?;
//!
//! // Host functionality can be arbitrary Rust functions and is provided
//! // to guests through a `Linker`.
//! let mut linker = Linker::new(&engine);
//! linker.func_wrap("host", "host_func", |caller: Caller<'_, u32>, param: i32| {
//! println!("Got {} from WebAssembly", param);
//! println!("my host state is: {}", caller.data());
//! })?;
//!
//! // All wasm objects operate within the context of a "store". Each
//! // `Store` has a type parameter to store host-specific data, which in
//! // this case we're using `4` for.
//! let mut store = Store::new(&engine, 4);
//! let host_func = Func::wrap(&mut store, |caller: Caller<'_, u32>, param: i32| {
//! println!("Got {} from WebAssembly", param);
//! println!("my host state is: {}", caller.data());
//! });
//! let mut store: Store<u32> = Store::new(&engine, 4);
//!
//! // Instantiation of a module requires specifying its imports and then
//! // afterwards we can fetch exports by name, as well as asserting the
//! // type signature of the function with `get_typed_func`.
//! let instance = Instance::new(&mut store, &module, &[host_func.into()] )?;
//! let instance = linker.instantiate(&mut store, &module )?;
//! let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?;
//!
//! // And finally we can call the wasm!
@ -70,19 +89,13 @@
//! There are a number of core types and concepts that are important to be aware
//! of when using the `wasmtime` crate:
//!
//! * [`Engine`] - a global compilation environment for WebAssembly. An
//! [`Engine`] is an object that can be shared concurrently across threads and
//! is created with a [`Config`] to tweak various settings. Compilation of any
//! WebAssembly requires first configuring and creating an [`Engine`].
//!
//! * [`Module`] - a compiled WebAssembly module. This structure represents
//! in-memory JIT code which is ready to execute after being instantiated.
//! It's often important to cache instances of a [`Module`] because creation
//! (compilation) can be expensive. Note that [`Module`] is safe to share
//! across threads, and can be created from a WebAssembly binary and an
//! [`Engine`] with [`Module::new`]. Caching can either happen with
//! [`Engine::precompile_module`] or [`Module::serialize`], feeding those
//! bytes back into [`Module::deserialize`].
//! * [`Engine`] - a global compilation and runtime environment for WebAssembly.
//! An [`Engine`] is an object that can be shared concurrently across threads
//! and is created with a [`Config`] with many knobs for configuring
//! behavior. Compiling or executing any WebAssembly requires first
//! configuring and creating an [`Engine`]. All [`Module`]s and
//! [`Component`](component::Component)s belong to an [`Engine`], and
//! typically there's one [`Engine`] per process.
//!
//! * [`Store`] - container for all information related to WebAssembly objects
//! such as functions, instances, memories, etc. A [`Store<T>`][`Store`]
@ -92,19 +105,48 @@
//! required for all WebAssembly operations, such as calling a wasm function.
//! The [`Store`] is passed in as a "context" to methods like [`Func::call`].
//! Dropping a [`Store`] will deallocate all memory associated with
//! WebAssembly objects within the [`Store`].
//!
//! * [`Instance`] - an instantiated WebAssembly module. An instance is where
//! you can actually acquire a [`Func`] from, for example, to call.
//!
//! * [`Func`] - a WebAssembly (or host) function. This can be acquired as the
//! export of an [`Instance`] to call WebAssembly functions, or it can be
//! created via functions like [`Func::wrap`] to wrap host-defined
//! functionality and give it to WebAssembly.
//!
//! * [`Table`], [`Global`], [`Memory`] - other WebAssembly objects which can
//! either be defined on the host or in wasm itself (via instances). These all
//! have various ways of being interacted with like [`Func`].
//! WebAssembly objects within the [`Store`]. A [`Store`] is cheap to create
//! and destroy and does not GC objects such as unused instances internally,
//! so it's intended to be short-lived (or no longer than the instances it
//! contains).
//!
//! * [`Linker`] (or [`component::Linker`]) - host functions are defined within
//! a linker to provide them a string-based name which can be looked up when
//! instantiating a WebAssembly module or component. Linkers are traditionally
//! populated at startup and then reused for all future instantiations of all
//! instances, assuming the set of host functions does not change over time.
//! Host functions are `Fn(..) + Send + Sync` and typically do not close over
//! mutable state. Instead it's recommended to store mutable state in the `T`
//! of [`Store<T>`] which is accessed through [`Caller<'_,
//! T>`](crate::Caller) provided to host functions.
//!
//! * [`Module`] (or [`Component`](component::Component)) - a compiled
//! WebAssembly module or component. These structures contain compiled
//! executable code from a WebAssembly binary which is ready to execute after
//! being instantiated. These are expensive to create as they require
//! compilation of the input WebAssembly. Modules and components are safe to
//! share across threads, however. Modules and components can additionally be
//! [serialized into a list of bytes](crate::Module::serialize) to later be
//! [deserialized](crate::Module::deserialize) quickly. This enables JIT-style
//! compilation through constructors such as [`Module::new`] and AOT-style
//! compilation by having the compilation process use [`Module::serialize`]
//! and the execution process use [`Module::deserialize`].
//!
//! * [`Instance`] (or [`component::Instance`]) - an instantiated WebAssembly
//! module or component. An instance is where you can actually acquire a
//! [`Func`] (or [`component::Func`]) from, for example, to call.
//!
//! * [`Func`] (or [`component::Func`]) - a WebAssembly function. This can be
//! acquired as the export of an [`Instance`] to call WebAssembly functions,
//! or it can be created via functions like [`Func::wrap`] to wrap
//! host-defined functionality and give it to WebAssembly. Functions also have
//! typed views as [`TypedFunc`] or [`component::TypedFunc`] for a more
//! efficient calling convention.
//!
//! * [`Table`], [`Global`], [`Memory`], [`component::Resource`] - other
//! WebAssembly objects which can either be defined on the host or in wasm
//! itself (via instances). These all have various ways of being interacted
//! with like [`Func`].
//!
//! All "store-connected" types such as [`Func`], [`Memory`], etc, require the
//! store to be passed in as a context to each method. Methods in wasmtime
@ -124,90 +166,6 @@
//! [`Func`] point within the [`Store`] and require the [`Store`] to be provided
//! to actually access the internals of the WebAssembly function, for instance.
//!
//! ## Linking
//!
//! WebAssembly modules almost always require functionality from the host to
//! perform I/O-like tasks. They might refer to quite a few pieces of host
//! functionality, WASI, or maybe even a number of other wasm modules. To assist
//! with managing this a [`Linker`] type is provided to instantiate modules.
//!
//! A [`Linker`] performs name-based resolution of the imports of a WebAssembly
//! module so the [`Linker::instantiate`] method does not take an `imports`
//! argument like [`Instance::new`] does. Methods like [`Linker::define`] or
//! [`Linker::func_wrap`] can be used to define names within a [`Linker`] to
//! later be used for instantiation.
//!
//! For example we can reimplement the above example with a `Linker`:
//!
//! ```
//! use wasmtime::*;
//!
//! fn main() -> wasmtime::Result<()> {
//! let engine = Engine::default();
//! let wat = r#"
//! (module
//! (import "host" "host_func" (func $host_hello (param i32)))
//!
//! (func (export "hello")
//! i32.const 3
//! call $host_hello)
//! )
//! "#;
//! let module = Module::new(&engine, wat)?;
//!
//! // Create a `Linker` and define our host function in it:
//! let mut linker = Linker::new(&engine);
//! linker.func_wrap("host", "host_func", |caller: Caller<'_, u32>, param: i32| {
//! println!("Got {} from WebAssembly", param);
//! println!("my host state is: {}", caller.data());
//! })?;
//!
//! // Use the `linker` to instantiate the module, which will automatically
//! // resolve the imports of the module using name-based resolution.
//! let mut store = Store::new(&engine, 0);
//! let instance = linker.instantiate(&mut store, &module)?;
//! let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?;
//! hello.call(&mut store, ())?;
//!
//! Ok(())
//! }
//! ```
//!
//! The [`Linker`] type also transparently handles Commands and Reactors
//! as defined by WASI.
//!
//! ## Example Architecture
//!
//! To better understand how Wasmtime types interact with each other let's walk
//! through, at a high-level, an example of how you might use WebAssembly. In
//! our use case let's say we have a web server where we'd like to run some
//! custom WebAssembly on each request. To ensure requests are entirely isolated
//! from each other, though, we'll be creating a new [`Store`] for each
//! request.
//!
//! When the server starts, we'll start off by creating an [`Engine`] (and maybe
//! tweaking [`Config`] settings if necessary). This [`Engine`] will be the only
//! engine for the lifetime of the server itself. Next, we can compile our
//! WebAssembly. You'd create a [`Module`] through the [`Module::new`] API.
//! This will generate JIT code and perform expensive compilation tasks
//! up-front. Finally the last step of initialization would be to create a
//! [`Linker`] which will later be used to instantiate modules, adding
//! functionality like WASI to the linker too.
//!
//! After that setup, the server starts up as usual and is ready to receive
//! requests. Upon receiving a request you'd then create a [`Store`] with
//! [`Store::new`] referring to the original [`Engine`]. Using your [`Module`]
//! and [`Linker`] from before you'd then call [`Linker::instantiate`] to
//! instantiate our module for the request. Both of these operations are
//! designed to be as cheap as possible.
//!
//! With an [`Instance`] you can then invoke various exports and interact with
//! the WebAssembly module. Once the request is finished, the [`Store`]
//! is dropped and everything will be deallocated. Note that if the same
//! [`Store`] were used for every request then that would have all requests
//! sharing resources and nothing would ever get deallocated, causing memory
//! usage to baloon and would achive less isolation between requests.
//!
//! ## WASI
//!
//! The `wasmtime` crate does not natively provide support for WASI, but you can
@ -218,36 +176,22 @@
//!
//! [`wasmtime-wasi`]: https://crates.io/crates/wasmtime-wasi
//!
//! ## Cross-store usage of items
//!
//! In `wasmtime` wasm items such as [`Global`] and [`Memory`] "belong" to a
//! [`Store`]. The store they belong to is the one they were created with
//! (passed in as a parameter) or instantiated with. This store is the only
//! store that can be used to interact with wasm items after they're created.
//!
//! The `wasmtime` crate will panic if the [`Store`] argument passed in to these
//! operations is incorrect. In other words it's considered a programmer error
//! rather than a recoverable error for the wrong [`Store`] to be used when
//! calling APIs.
//!
//! ## Crate Features
//!
//! The `wasmtime` crate comes with a number of compile-time features that can
//! be used to customize what features it supports. Some of these features are
//! just internal details, but some affect the public API of the `wasmtime`
//! crate. Be sure to check the API you're using to see if any crate feature s
//! are enabled .
//! crate. Wasmtime APIs gated behind a Cargo feature should be indicated as
//! such in the documentation.
//!
//! * `runtime` - Enabled by default, this feature enables executing
//! WebAssembly modules. If modules are only compiled, however, this feature
//! can be disabled.
//! WebAssembly modules and components. If a compiler is not available (such
//! as `cranelift`) then [`Module::deserialize`] must be used, for example, to
//! provide an ahead-of-time compiled artifact to execute WebAssembly.
//!
//! * `cranelift` - Enabled by default, this features enables using Cranelift at
//! runtime to compile a WebAssembly module to native code. This feature is
//! required to process and compile new WebAssembly modules. If this feature
//! is disabled then the only way to create a [`Module`] is to use the
//! [`Module::deserialize`] function with a precompiled artifact (typically
//! compiled with the same version of Wasmtime, just somewhere else).
//! required to process and compile new WebAssembly modules and components.
//!
//! * `cache` - Enabled by default, this feature adds support for wasmtime to
//! perform internal caching of modules in a global location. This must still
@ -255,42 +199,31 @@
//! [`Config::cache_config_load_default`].
//!
//! * `wat` - Enabled by default, this feature adds support for accepting the
//! text format of WebAssembly in [`Module::new`]. The text format will be
//! text format of WebAssembly in [`Module::new`] and
//! [`Component::new`](component::Component::new). The text format will be
//! automatically recognized and translated to binary when compiling a
//! module.
//!
//! * `parallel-compilation` - Enabled by default, this feature enables support
//! for compiling functions of a module in parallel with `rayon`.
//! for compiling functions in parallel with `rayon`.
//!
//! * `async` - Enabled by default, this feature enables APIs and runtime
//! support for defining asynchronous host functions and calling WebAssembly
//! asynchronously.
//! asynchronously. For more information see [`Config::async_support`].
//!
//! * `jitdump` - Enabled by default, this feature compiles in support for the
//! jitdump runtime profiling format. The profiler can be selected with
//! [`Config::profiler`].
//!
//! * `vtune` - Enabled by default, this feature compiles in support for VTune
//! profiling of JIT code.
//! * `profiling` - Enabled by default, this feature compiles in support for
//! profiling guest code via a number of possible strategies. See
//! [`Config::profiler`] for more information.
//!
//! * `all-arch` - Not enabled by default. This feature compiles in support for
//! all architectures for both the JIT compiler and the `wasmtime compile` CLI
//! command.
//! command. This can be combined with [`Config::target`] to precompile
//! modules for a different platform than the host.
//!
//! * `pooling-allocator` - Enabled by default, this feature adds support for
//! the pooling allocation strategy enabled via
//! [`Config::allocation_strategy`]. The pooling allocator can enable more
//! efficient reuse of resources for high-concurrency and
//! high-instantiation-count scenarios.
//!
//! * `memory-init-cow` - Enabled by default, this feature builds in support
//! for, on supported platforms, initializing wasm linear memories with
//! copy-on-write heap mappings. This makes instantiation much faster by
//! `mmap`-ing the initial memory image into place instead of copying memory
//! into place, allowing sharing pages that end up only getting read. Note
//! that this is simply compile-time support and this must also be enabled at
//! run-time via [`Config::memory_init_cow`] (which is also enabled by
//! default).
//! [`PoolingAllocationConfig`] to pass to [`Config::allocation_strategy`].
//! The pooling allocator can enable efficient reuse of resources for
//! high-concurrency and high-instantiation-count scenarios.
//!
//! * `demangle` - Enabled by default, this will affect how backtraces are
//! printed and whether symbol names from WebAssembly are attempted to be
@ -310,98 +243,13 @@
//! will enable debugging guest code compiled to WebAssembly. This must also
//! be enabled via [`Config::debug_info`] as well for guests.
//!
//! * `component-model` - Enabled by default, this enables support for the
//! [`wasmtime::component`](component) API for working with components.
//!
//! More crate features can be found in the [manifest] of Wasmtime itself for
//! seeing what can be enabled and disabled.
//!
//! [manifest]: https://github.com/bytecodealliance/wasmtime/blob/main/crates/wasmtime/Cargo.toml
//!
//! ## Examples
//!
//! In addition to the examples below be sure to check out the [online embedding
//! documentation][rustdocs] as well as the [online list of examples][examples]
//!
//! [rustdocs]: https://bytecodealliance.github.io/wasmtime/lang-rust.html
//! [examples]: https://bytecodealliance.github.io/wasmtime/examples-rust-embed.html
//!
//! An example of using WASI looks like:
//!
//! ```no_run
//! # use wasmtime::*;
//! use wasmtime_wasi::sync::WasiCtxBuilder;
//!
//! # fn main() -> wasmtime::Result<()> {
//! // Compile our module and create a `Linker` which has WASI functions defined
//! // within it.
//! let engine = Engine::default();
//! let module = Module::from_file(&engine, "foo.wasm")?;
//! let mut linker = Linker::new(&engine);
//! wasmtime_wasi::add_to_linker(&mut linker, |cx| cx)?;
//!
//! // Configure and create a `WasiCtx`, which WASI functions need access to
//! // through the host state of the store (which in this case is the host state
//! // of the store)
//! let wasi_ctx = WasiCtxBuilder::new().inherit_stdio().build();
//! let mut store = Store::new(&engine, wasi_ctx);
//!
//! // Instantiate our module with the imports we've created, and run it.
//! let instance = linker.instantiate(&mut store, &module)?;
//! // ...
//!
//! # Ok(())
//! # }
//! ```
//!
//! An example of reading a string from a wasm module:
//!
//! ```
//! use std::str;
//!
//! # use wasmtime::*;
//! # fn main() -> wasmtime::Result<()> {
//! let mut store = Store::default();
//! let log_str = Func::wrap(&mut store, |mut caller: Caller<'_, ()>, ptr: i32, len: i32| {
//! // Use our `caller` context to learn about the memory export of the
//! // module which called this host function.
//! let mem = match caller.get_export("memory") {
//! Some(Extern::Memory(mem)) => mem,
//! _ => anyhow::bail!("failed to find host memory"),
//! };
//!
//! // Use the `ptr` and `len` values to get a subslice of the wasm-memory
//! // which we'll attempt to interpret as utf-8.
//! let data = mem.data(&caller)
//! .get(ptr as u32 as usize..)
//! .and_then(|arr| arr.get(..len as u32 as usize));
//! let string = match data {
//! Some(data) => match str::from_utf8(data) {
//! Ok(s) => s,
//! Err(_) => anyhow::bail!("invalid utf-8"),
//! },
//! None => anyhow::bail!("pointer/length out of bounds"),
//! };
//! assert_eq!(string, "Hello, world!");
//! println!("{}", string);
//! Ok(())
//! });
//! let module = Module::new(
//! store.engine(),
//! r#"
//! (module
//! (import "" "" (func $log_str (param i32 i32)))
//! (func (export "foo")
//! i32.const 4 ;; ptr
//! i32.const 13 ;; len
//! call $log_str)
//! (memory (export "memory") 1)
//! (data (i32.const 4) "Hello, world!"))
//! "#,
//! )?;
//! let instance = Instance::new(&mut store, &module, &[log_str.into()])?;
//! let foo = instance.get_typed_func::<(), ()>(&mut store, "foo")?;
//! foo.call(&mut store, ())?;
//! # Ok(())
//! # }
//! ```
#![ deny(missing_docs) ]
#![ doc(test(attr(deny(warnings)))) ]
@ -434,6 +282,7 @@ pub use crate::engine::*;
/// This type can be used to interact with `wasmtimes`'s extensive use
/// of `anyhow::Error` while still not directly depending on `anyhow`.
/// This type alias is identical to `anyhow::Result`.
#[ doc(no_inline) ]
pub use anyhow ::{ Error , Result } ;
fn _assert_send_and_sync < T : Send + Sync > ( ) { }