substrate_wasmtime/
lib.rs

1//! Wasmtime's embedding API
2//!
3//! This crate contains an API used to interact with WebAssembly modules. For
4//! example you can compile modules, instantiate them, call them, etc. As an
5//! embedder of WebAssembly you can also provide WebAssembly modules
6//! functionality from the host by creating host-defined functions, memories,
7//! globals, etc, which can do things that WebAssembly cannot (such as print to
8//! the screen).
9//!
10//! The `wasmtime` crate draws inspiration from a number of sources, including
11//! the [JS WebAssembly
12//! API](https://developer.mozilla.org/en-US/docs/WebAssembly) as well as the
13//! [proposed C API](https://github.com/webassembly/wasm-c-api). As with all
14//! other Rust code you're guaranteed that programs will be safe (not have
15//! undefined behavior or segfault) so long as you don't use `unsafe` in your
16//! own program. With `wasmtime` you can easily and conveniently embed a
17//! WebAssembly runtime with confidence that the WebAssembly is safely
18//! sandboxed.
19//!
20//! An example of using Wasmtime looks like:
21//!
22//! ```
23//! use anyhow::Result;
24//! use wasmtime::*;
25//!
26//! fn main() -> Result<()> {
27//!     // All wasm objects operate within the context of a "store"
28//!     let store = Store::default();
29//!
30//!     // Modules can be compiled through either the text or binary format
31//!     let wat = r#"
32//!         (module
33//!             (import "" "" (func $host_hello (param i32)))
34//!
35//!             (func (export "hello")
36//!                 i32.const 3
37//!                 call $host_hello)
38//!         )
39//!     "#;
40//!     let module = Module::new(store.engine(), wat)?;
41//!
42//!     // Host functions can be defined which take/return wasm values and
43//!     // execute arbitrary code on the host.
44//!     let host_hello = Func::wrap(&store, |param: i32| {
45//!         println!("Got {} from WebAssembly", param);
46//!     });
47//!
48//!     // Instantiation of a module requires specifying its imports and then
49//!     // afterwards we can fetch exports by name, as well as asserting the
50//!     // type signature of the function with `get0`.
51//!     let instance = Instance::new(&store, &module, &[host_hello.into()])?;
52//!     let hello = instance
53//!         .get_func("hello")
54//!         .ok_or(anyhow::format_err!("failed to find `hello` function export"))?
55//!         .get0::<()>()?;
56//!
57//!     // And finally we can call the wasm as if it were a Rust function!
58//!     hello()?;
59//!
60//!     Ok(())
61//! }
62//! ```
63//!
64//! ## Core Concepts
65//!
66//! There are a number of core types and concepts that are important to be aware
67//! of when using the `wasmtime` crate:
68//!
69//! * Reference counting - almost all objects in this API are reference counted.
70//!   Most of the time when and object is `clone`d you're just bumping a
71//!   reference count. For example when you clone an [`Instance`] that is a
72//!   cheap operation, it doesn't create an entirely new instance.
73//!
74//! * [`Store`] - all WebAssembly object and host values will be "connected" to
75//!   a store. A [`Store`] is not threadsafe which means that itself and all
76//!   objects connected to it are pinned to a single thread (this happens
77//!   automatically through a lack of the `Send` and `Sync` traits). Similarly
78//!   `wasmtime` does not have a garbage collector so anything created within a
79//!   [`Store`] will not be deallocated until all references have gone away. See
80//!   the [`Store`] documentation for more information.
81//!
82//! * [`Module`] - a compiled WebAssembly module. This structure represents
83//!   in-memory JIT code which is ready to execute after being instantiated.
84//!   It's often important to cache instances of a [`Module`] because creation
85//!   (compilation) can be expensive. Note that [`Module`] is safe to share
86//!   across threads.
87//!
88//! * [`Instance`] - an instantiated WebAssembly module. An instance is where
89//!   you can actually acquire a [`Func`] from, for example, to call. Each
90//!   [`Instance`], like all other [`Store`]-connected objects, cannot be sent
91//!   across threads.
92//!
93//! There are other important types within the `wasmtime` crate but it's crucial
94//! to be familiar with the above types! Be sure to browse the API documentation
95//! to get a feeling for what other functionality is offered by this crate.
96//!
97//! ## Example Architecture
98//!
99//! To better understand how Wasmtime types interact with each other let's walk
100//! through, at a high-level, an example of how you might use WebAssembly. In
101//! our use case let's say we have a web server where we'd like to run some
102//! custom WebAssembly on each request. To ensure requests are isolated from
103//! each other, though, we'll be creating a new [`Instance`] for each request.
104//!
105//! When the server starts, we'll start off by creating an [`Engine`] (and maybe
106//! tweaking [`Config`] settings if necessary). This [`Engine`] will be the only
107//! engine for the lifetime of the server itself.
108//!
109//! Next, we can compile our WebAssembly. You'd create a [`Module`] through the
110//! [`Module::new`] API. This will generate JIT code and perform expensive
111//! compilation tasks up-front.
112//!
113//! After that setup, the server starts up as usual and is ready to receive
114//! requests. Upon receiving a request you'd then create a [`Store`] with
115//! [`Store::new`] referring to the original [`Engine`]. Using your [`Module`]
116//! from before you'd then call [`Instance::new`] to instantiate our module for
117//! the request. Both of these operations are designed to be as cheap as
118//! possible.
119//!
120//! With an [`Instance`] you can then invoke various exports and interact with
121//! the WebAssembly module. Once the request is finished the [`Store`],
122//! [`Instance`], and all other items loaded are dropped and everything will be
123//! deallocated. Note that it's crucial to create a [`Store`]-per-request to
124//! ensure that memory usage doesn't balloon accidentally by keeping a [`Store`]
125//! alive indefinitely.
126//!
127//! ## Advanced Linking
128//!
129//! Often WebAssembly modules are not entirely self-isolated. They might refer
130//! to quite a few pieces of host functionality, WASI, or maybe even a number of
131//! other wasm modules. To help juggling all this together this crate provides a
132//! [`Linker`] type which serves as an abstraction to assist in instantiating a
133//! module. The [`Linker`] type also transparently handles Commands and Reactors
134//! as defined by WASI.
135//!
136//! ## WASI
137//!
138//! The `wasmtime` crate does not natively provide support for WASI, but you can
139//! use the `wasmtime-wasi` crate for that purpose. With `wasmtime-wasi` you can
140//! create a "wasi instance" and then add all of its items into a [`Linker`],
141//! which can then be used to instantiate a [`Module`] that uses WASI.
142//!
143//! ## Examples
144//!
145//! In addition to the examples below be sure to check out the [online embedding
146//! documentation][rustdocs] as well as the [online list of examples][examples]
147//!
148//! [rustdocs]: https://bytecodealliance.github.io/wasmtime/lang-rust.html
149//! [examples]: https://bytecodealliance.github.io/wasmtime/examples-rust-embed.html
150//!
151//! An example of using WASI looks like:
152//!
153//! ```no_run
154//! # use anyhow::Result;
155//! # use wasmtime::*;
156//! use wasmtime_wasi::{Wasi, WasiCtx};
157//!
158//! # fn main() -> Result<()> {
159//! let store = Store::default();
160//! let mut linker = Linker::new(&store);
161//!
162//! // Create an instance of `Wasi` which contains a `WasiCtx`. Note that
163//! // `WasiCtx` provides a number of ways to configure what the target program
164//! // will have access to.
165//! let wasi = Wasi::new(&store, WasiCtx::new(std::env::args())?);
166//! wasi.add_to_linker(&mut linker)?;
167//!
168//! // Instantiate our module with the imports we've created, and run it.
169//! let module = Module::from_file(store.engine(), "foo.wasm")?;
170//! let instance = linker.instantiate(&module)?;
171//! // ...
172//!
173//! # Ok(())
174//! # }
175//! ```
176//!
177//! An example of reading a string from a wasm module:
178//!
179//! ```
180//! use std::str;
181//!
182//! # use wasmtime::*;
183//! # fn main() -> anyhow::Result<()> {
184//! let store = Store::default();
185//! let log_str = Func::wrap(&store, |caller: Caller<'_>, ptr: i32, len: i32| {
186//!     let mem = match caller.get_export("memory") {
187//!         Some(Extern::Memory(mem)) => mem,
188//!         _ => return Err(Trap::new("failed to find host memory")),
189//!     };
190//!
191//!     // We're reading raw wasm memory here so we need `unsafe`. Note
192//!     // though that this should be safe because we don't reenter wasm
193//!     // while we're reading wasm memory, nor should we clash with
194//!     // any other memory accessors (assuming they're well-behaved
195//!     // too).
196//!     unsafe {
197//!         let data = mem.data_unchecked()
198//!             .get(ptr as u32 as usize..)
199//!             .and_then(|arr| arr.get(..len as u32 as usize));
200//!         let string = match data {
201//!             Some(data) => match str::from_utf8(data) {
202//!                 Ok(s) => s,
203//!                 Err(_) => return Err(Trap::new("invalid utf-8")),
204//!             },
205//!             None => return Err(Trap::new("pointer/length out of bounds")),
206//!         };
207//!         assert_eq!(string, "Hello, world!");
208//!         println!("{}", string);
209//!     }
210//!     Ok(())
211//! });
212//! let module = Module::new(
213//!     store.engine(),
214//!     r#"
215//!         (module
216//!             (import "" "" (func $log_str (param i32 i32)))
217//!             (func (export "foo")
218//!                 i32.const 4   ;; ptr
219//!                 i32.const 13  ;; len
220//!                 call $log_str)
221//!             (memory (export "memory") 1)
222//!             (data (i32.const 4) "Hello, world!"))
223//!     "#,
224//! )?;
225//! let instance = Instance::new(&store, &module, &[log_str.into()])?;
226//! let foo = instance.get_func("foo").unwrap().get0::<()>()?;
227//! foo()?;
228//! # Ok(())
229//! # }
230//! ```
231
232#![deny(missing_docs, intra_doc_link_resolution_failure)]
233#![doc(test(attr(deny(warnings))))]
234#![doc(test(attr(allow(dead_code, unused_variables, unused_mut))))]
235
236mod externals;
237mod frame_info;
238mod func;
239mod instance;
240mod linker;
241mod module;
242mod r#ref;
243mod runtime;
244mod trampoline;
245mod trap;
246mod types;
247mod values;
248
249pub use crate::externals::*;
250pub use crate::frame_info::FrameInfo;
251pub use crate::func::*;
252pub use crate::instance::Instance;
253pub use crate::linker::*;
254pub use crate::module::Module;
255pub use crate::r#ref::ExternRef;
256pub use crate::runtime::*;
257pub use crate::trap::Trap;
258pub use crate::types::*;
259pub use crate::values::*;
260
261cfg_if::cfg_if! {
262    if #[cfg(unix)] {
263        pub mod unix;
264    } else if #[cfg(windows)] {
265        pub mod windows;
266    } else {
267        // ... unknown os!
268    }
269}