wasmtime/lib.rs
1//! Wasmtime's embedding API
2//!
3//! Wasmtime is a WebAssembly engine for JIT-complied or ahead-of-time compiled
4//! WebAssembly modules. More information about the Wasmtime project as a whole
5//! can be found [in the documentation book](https://docs.wasmtime.dev) whereas
6//! this documentation mostly focuses on the API reference of the `wasmtime`
7//! crate itself.
8//!
9//! This crate contains an API used to interact with WebAssembly modules. For
10//! example you can compile modules, instantiate them, call them, etc. As an
11//! embedder of WebAssembly you can also provide WebAssembly modules
12//! functionality from the host by creating host-defined functions, memories,
13//! globals, etc, which can do things that WebAssembly cannot (such as print to
14//! the screen).
15//!
16//! The `wasmtime` crate has similar concepts to the
17//! the [JS WebAssembly
18//! API](https://developer.mozilla.org/en-US/docs/WebAssembly) as well as the
19//! [proposed C API](https://github.com/webassembly/wasm-c-api), but the Rust
20//! API is designed for efficiency, ergonomics, and expressivity in Rust. As
21//! with all other Rust code you're guaranteed that programs will be safe (not
22//! have undefined behavior or segfault) so long as you don't use `unsafe` in
23//! your own program. With `wasmtime` you can easily and conveniently embed a
24//! WebAssembly runtime with confidence that the WebAssembly is safely
25//! sandboxed.
26//!
27//! An example of using Wasmtime looks like:
28//!
29//! ```
30//! use wasmtime::*;
31//!
32//! fn main() -> wasmtime::Result<()> {
33//! // Modules can be compiled through either the text or binary format
34//! let engine = Engine::default();
35//! let wat = r#"
36//! (module
37//! (import "host" "hello" (func $host_hello (param i32)))
38//!
39//! (func (export "hello")
40//! i32.const 3
41//! call $host_hello)
42//! )
43//! "#;
44//! let module = Module::new(&engine, wat)?;
45//!
46//! // All wasm objects operate within the context of a "store". Each
47//! // `Store` has a type parameter to store host-specific data, which in
48//! // this case we're using `4` for.
49//! let mut store = Store::new(&engine, 4);
50//! let host_hello = Func::wrap(&mut store, |caller: Caller<'_, u32>, param: i32| {
51//! println!("Got {} from WebAssembly", param);
52//! println!("my host state is: {}", caller.data());
53//! });
54//!
55//! // Instantiation of a module requires specifying its imports and then
56//! // afterwards we can fetch exports by name, as well as asserting the
57//! // type signature of the function with `get_typed_func`.
58//! let instance = Instance::new(&mut store, &module, &[host_hello.into()])?;
59//! let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?;
60//!
61//! // And finally we can call the wasm!
62//! hello.call(&mut store, ())?;
63//!
64//! Ok(())
65//! }
66//! ```
67//!
68//! ## Core Concepts
69//!
70//! There are a number of core types and concepts that are important to be aware
71//! of when using the `wasmtime` crate:
72//!
73//! * [`Engine`] - a global compilation environment for WebAssembly. An
74//! [`Engine`] is an object that can be shared concurrently across threads and
75//! is created with a [`Config`] to tweak various settings. Compilation of any
76//! WebAssembly requires first configuring and creating an [`Engine`].
77//!
78//! * [`Module`] - a compiled WebAssembly module. This structure represents
79//! in-memory JIT code which is ready to execute after being instantiated.
80//! It's often important to cache instances of a [`Module`] because creation
81//! (compilation) can be expensive. Note that [`Module`] is safe to share
82//! across threads, and can be created from a WebAssembly binary and an
83//! [`Engine`] with [`Module::new`]. Caching can either happen with
84//! [`Engine::precompile_module`] or [`Module::serialize`], feeding those
85//! bytes back into [`Module::deserialize`].
86//!
87//! * [`Store`] - container for all information related to WebAssembly objects
88//! such as functions, instances, memories, etc. A [`Store<T>`][`Store`]
89//! allows customization of the `T` to store arbitrary host data within a
90//! [`Store`]. This host data can be accessed through host functions via the
91//! [`Caller`] function parameter in host-defined functions. A [`Store`] is
92//! required for all WebAssembly operations, such as calling a wasm function.
93//! The [`Store`] is passed in as a "context" to methods like [`Func::call`].
94//! Dropping a [`Store`] will deallocate all memory associated with
95//! WebAssembly objects within the [`Store`].
96//!
97//! * [`Instance`] - an instantiated WebAssembly module. An instance is where
98//! you can actually acquire a [`Func`] from, for example, to call.
99//!
100//! * [`Func`] - a WebAssembly (or host) function. This can be acquired as the
101//! export of an [`Instance`] to call WebAssembly functions, or it can be
102//! created via functions like [`Func::wrap`] to wrap host-defined
103//! functionality and give it to WebAssembly.
104//!
105//! * [`Table`], [`Global`], [`Memory`] - other WebAssembly objects which can
106//! either be defined on the host or in wasm itself (via instances). These all
107//! have various ways of being interacted with like [`Func`].
108//!
109//! All "store-connected" types such as [`Func`], [`Memory`], etc, require the
110//! store to be passed in as a context to each method. Methods in wasmtime
111//! frequently have their first parameter as either [`impl
112//! AsContext`][`AsContext`] or [`impl AsContextMut`][`AsContextMut`]. These
113//! traits are implemented for a variety of types, allowing you to, for example,
114//! pass the following types into methods:
115//!
116//! * `&Store<T>`
117//! * `&mut Store<T>`
118//! * `&Caller<'_, T>`
119//! * `&mut Caller<'_, T>`
120//! * `StoreContext<'_, T>`
121//! * `StoreContextMut<'_, T>`
122//!
123//! A [`Store`] is the sole owner of all WebAssembly internals. Types like
124//! [`Func`] point within the [`Store`] and require the [`Store`] to be provided
125//! to actually access the internals of the WebAssembly function, for instance.
126//!
127//! ## Linking
128//!
129//! WebAssembly modules almost always require functionality from the host to
130//! perform I/O-like tasks. They might refer to quite a few pieces of host
131//! functionality, WASI, or maybe even a number of other wasm modules. To assist
132//! with managing this a [`Linker`] type is provided to instantiate modules.
133//!
134//! A [`Linker`] performs name-based resolution of the imports of a WebAssembly
135//! module so the [`Linker::instantiate`] method does not take an `imports`
136//! argument like [`Instance::new`] does. Methods like [`Linker::define`] or
137//! [`Linker::func_wrap`] can be used to define names within a [`Linker`] to
138//! later be used for instantiation.
139//!
140//! For example we can reimplement the above example with a `Linker`:
141//!
142//! ```
143//! use wasmtime::*;
144//!
145//! fn main() -> wasmtime::Result<()> {
146//! let engine = Engine::default();
147//! let wat = r#"
148//! (module
149//! (import "host" "hello" (func $host_hello (param i32)))
150//!
151//! (func (export "hello")
152//! i32.const 3
153//! call $host_hello)
154//! )
155//! "#;
156//! let module = Module::new(&engine, wat)?;
157//!
158//! // Create a `Linker` and define our host function in it:
159//! let mut linker = Linker::new(&engine);
160//! linker.func_wrap("host", "hello", |caller: Caller<'_, u32>, param: i32| {
161//! println!("Got {} from WebAssembly", param);
162//! println!("my host state is: {}", caller.data());
163//! })?;
164//!
165//! // Use the `linker` to instantiate the module, which will automatically
166//! // resolve the imports of the module using name-based resolution.
167//! let mut store = Store::new(&engine, 0);
168//! let instance = linker.instantiate(&mut store, &module)?;
169//! let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?;
170//! hello.call(&mut store, ())?;
171//!
172//! Ok(())
173//! }
174//! ```
175//!
176//! The [`Linker`] type also transparently handles Commands and Reactors
177//! as defined by WASI.
178//!
179//! ## Example Architecture
180//!
181//! To better understand how Wasmtime types interact with each other let's walk
182//! through, at a high-level, an example of how you might use WebAssembly. In
183//! our use case let's say we have a web server where we'd like to run some
184//! custom WebAssembly on each request. To ensure requests are entirely isolated
185//! from each other, though, we'll be creating a new [`Store`] for each
186//! request.
187//!
188//! When the server starts, we'll start off by creating an [`Engine`] (and maybe
189//! tweaking [`Config`] settings if necessary). This [`Engine`] will be the only
190//! engine for the lifetime of the server itself. Next, we can compile our
191//! WebAssembly. You'd create a [`Module`] through the [`Module::new`] API.
192//! This will generate JIT code and perform expensive compilation tasks
193//! up-front. Finally the last step of initialization would be to create a
194//! [`Linker`] which will later be used to instantiate modules, adding
195//! functionality like WASI to the linker too.
196//!
197//! After that setup, the server starts up as usual and is ready to receive
198//! requests. Upon receiving a request you'd then create a [`Store`] with
199//! [`Store::new`] referring to the original [`Engine`]. Using your [`Module`]
200//! and [`Linker`] from before you'd then call [`Linker::instantiate`] to
201//! instantiate our module for the request. Both of these operations are
202//! designed to be as cheap as possible.
203//!
204//! With an [`Instance`] you can then invoke various exports and interact with
205//! the WebAssembly module. Once the request is finished, the [`Store`]
206//! is dropped and everything will be deallocated. Note that if the same
207//! [`Store`] were used for every request then that would have all requests
208//! sharing resources and nothing would ever get deallocated, causing memory
209//! usage to baloon and would achive less isolation between requests.
210//!
211//! ## WASI
212//!
213//! The `wasmtime` crate does not natively provide support for WASI, but you can
214//! use the [`wasmtime-wasi`] crate for that purpose. With [`wasmtime-wasi`] all
215//! WASI functions can be added to a [`Linker`] and then used to instantiate
216//! WASI-using modules. For more information see the [WASI example in the
217//! documentation](https://docs.wasmtime.dev/examples-rust-wasi.html).
218//!
219//! [`wasmtime-wasi`]: https://crates.io/crates/wasmtime-wasi
220//!
221//! ## Cross-store usage of items
222//!
223//! In `wasmtime` wasm items such as [`Global`] and [`Memory`] "belong" to a
224//! [`Store`]. The store they belong to is the one they were created with
225//! (passed in as a parameter) or instantiated with. This store is the only
226//! store that can be used to interact with wasm items after they're created.
227//!
228//! The `wasmtime` crate will panic if the [`Store`] argument passed in to these
229//! operations is incorrect. In other words it's considered a programmer error
230//! rather than a recoverable error for the wrong [`Store`] to be used when
231//! calling APIs.
232//!
233//! ## Crate Features
234//!
235//! The `wasmtime` crate comes with a number of compile-time features that can
236//! be used to customize what features it supports. Some of these features are
237//! just internal details, but some affect the public API of the `wasmtime`
238//! crate. Be sure to check the API you're using to see if any crate features
239//! are enabled.
240//!
241//! * `cranelift` - Enabled by default, this features enables using Cranelift at
242//! runtime to compile a WebAssembly module to native code. This feature is
243//! required to process and compile new WebAssembly modules. If this feature
244//! is disabled then the only way to create a [`Module`] is to use the
245//! [`Module::deserialize`] function with a precompiled artifact (typically
246//! compiled with the same version of Wasmtime, just somewhere else).
247//!
248//! * `cache` - Enabled by default, this feature adds support for wasmtime to
249//! perform internal caching of modules in a global location. This must still
250//! be enabled explicitly through [`Config::cache_config_load`] or
251//! [`Config::cache_config_load_default`].
252//!
253//! * `wat` - Enabled by default, this feature adds support for accepting the
254//! text format of WebAssembly in [`Module::new`]. The text format will be
255//! automatically recognized and translated to binary when compiling a
256//! module.
257//!
258//! * `parallel-compilation` - Enabled by default, this feature enables support
259//! for compiling functions of a module in parallel with `rayon`.
260//!
261//! * `async` - Enabled by default, this feature enables APIs and runtime
262//! support for defining asynchronous host functions and calling WebAssembly
263//! asynchronously.
264//!
265//! * `jitdump` - Enabled by default, this feature compiles in support for the
266//! jitdump runtime profiling format. The profiler can be selected with
267//! [`Config::profiler`].
268//!
269//! * `vtune` - Enabled by default, this feature compiles in support for VTune
270//! profiling of JIT code.
271//!
272//! * `all-arch` - Not enabled by default. This feature compiles in support for
273//! all architectures for both the JIT compiler and the `wasmtime compile` CLI
274//! command.
275//!
276//! * `pooling-allocator` - Enabled by default, this feature adds support for
277//! the pooling allocation strategy enabled via
278//! [`Config::allocation_strategy`]. The pooling allocator can enable more
279//! efficient reuse of resources for high-concurrency and
280//! high-instantiation-count scenarios.
281//!
282//! * `memory-init-cow` - Enabled by default, this feature builds in support
283//! for, on supported platforms, initializing wasm linear memories with
284//! copy-on-write heap mappings. This makes instantiation much faster by
285//! `mmap`-ing the initial memory image into place instead of copying memory
286//! into place, allowing sharing pages that end up only getting read. Note
287//! that this is simply compile-time support and this must also be enabled at
288//! run-time via [`Config::memory_init_cow`] (which is also enabled by
289//! default).
290//!
291//! ## Examples
292//!
293//! In addition to the examples below be sure to check out the [online embedding
294//! documentation][rustdocs] as well as the [online list of examples][examples]
295//!
296//! [rustdocs]: https://bytecodealliance.github.io/wasmtime/lang-rust.html
297//! [examples]: https://bytecodealliance.github.io/wasmtime/examples-rust-embed.html
298//!
299//! An example of using WASI looks like:
300//!
301//! ```no_run
302//! # use wasmtime::*;
303//! use wasmtime_wasi::sync::WasiCtxBuilder;
304//!
305//! # fn main() -> wasmtime::Result<()> {
306//! // Compile our module and create a `Linker` which has WASI functions defined
307//! // within it.
308//! let engine = Engine::default();
309//! let module = Module::from_file(&engine, "foo.wasm")?;
310//! let mut linker = Linker::new(&engine);
311//! wasmtime_wasi::add_to_linker(&mut linker, |cx| cx)?;
312//!
313//! // Configure and create a `WasiCtx`, which WASI functions need access to
314//! // through the host state of the store (which in this case is the host state
315//! // of the store)
316//! let wasi_ctx = WasiCtxBuilder::new().inherit_stdio().build();
317//! let mut store = Store::new(&engine, wasi_ctx);
318//!
319//! // Instantiate our module with the imports we've created, and run it.
320//! let instance = linker.instantiate(&mut store, &module)?;
321//! // ...
322//!
323//! # Ok(())
324//! # }
325//! ```
326//!
327//! An example of reading a string from a wasm module:
328//!
329//! ```
330//! use std::str;
331//!
332//! # use wasmtime::*;
333//! # fn main() -> wasmtime::Result<()> {
334//! let mut store = Store::default();
335//! let log_str = Func::wrap(&mut store, |mut caller: Caller<'_, ()>, ptr: i32, len: i32| {
336//! // Use our `caller` context to learn about the memory export of the
337//! // module which called this host function.
338//! let mem = match caller.get_export("memory") {
339//! Some(Extern::Memory(mem)) => mem,
340//! _ => anyhow::bail!("failed to find host memory"),
341//! };
342//!
343//! // Use the `ptr` and `len` values to get a subslice of the wasm-memory
344//! // which we'll attempt to interpret as utf-8.
345//! let data = mem.data(&caller)
346//! .get(ptr as u32 as usize..)
347//! .and_then(|arr| arr.get(..len as u32 as usize));
348//! let string = match data {
349//! Some(data) => match str::from_utf8(data) {
350//! Ok(s) => s,
351//! Err(_) => anyhow::bail!("invalid utf-8"),
352//! },
353//! None => anyhow::bail!("pointer/length out of bounds"),
354//! };
355//! assert_eq!(string, "Hello, world!");
356//! println!("{}", string);
357//! Ok(())
358//! });
359//! let module = Module::new(
360//! store.engine(),
361//! r#"
362//! (module
363//! (import "" "" (func $log_str (param i32 i32)))
364//! (func (export "foo")
365//! i32.const 4 ;; ptr
366//! i32.const 13 ;; len
367//! call $log_str)
368//! (memory (export "memory") 1)
369//! (data (i32.const 4) "Hello, world!"))
370//! "#,
371//! )?;
372//! let instance = Instance::new(&mut store, &module, &[log_str.into()])?;
373//! let foo = instance.get_typed_func::<(), ()>(&mut store, "foo")?;
374//! foo.call(&mut store, ())?;
375//! # Ok(())
376//! # }
377//! ```
378
379#![deny(missing_docs)]
380#![doc(test(attr(deny(warnings))))]
381#![doc(test(attr(allow(dead_code, unused_variables, unused_mut))))]
382#![cfg_attr(nightlydoc, feature(doc_cfg))]
383#![cfg_attr(not(feature = "default"), allow(dead_code, unused_imports))]
384// Allow broken links when the default features is disabled because most of our
385// documentation is written for the "one build" of the `main` branch which has
386// most features enabled. This will present warnings in stripped-down doc builds
387// and will prevent the doc build from failing.
388#![cfg_attr(feature = "default", deny(rustdoc::broken_intra_doc_links))]
389
390#[macro_use]
391mod func;
392
393mod code;
394mod config;
395mod engine;
396mod externals;
397mod instance;
398mod limits;
399mod linker;
400mod memory;
401mod module;
402mod r#ref;
403mod signatures;
404mod store;
405mod trampoline;
406mod trap;
407mod types;
408mod values;
409
410pub use crate::config::*;
411pub use crate::engine::*;
412pub use crate::externals::*;
413pub use crate::func::*;
414pub use crate::instance::{Instance, InstancePre};
415pub use crate::limits::*;
416pub use crate::linker::*;
417pub use crate::memory::*;
418pub use crate::module::Module;
419pub use crate::r#ref::ExternRef;
420#[cfg(feature = "async")]
421pub use crate::store::CallHookHandler;
422pub use crate::store::{AsContext, AsContextMut, CallHook, Store, StoreContext, StoreContextMut};
423pub use crate::trap::*;
424pub use crate::types::*;
425pub use crate::values::*;
426
427/// A convenience wrapper for `Result<T, anyhow::Error>`.
428///
429/// This type can be used to interact with `wasmtimes`'s extensive use
430/// of `anyhow::Error` while still not directly depending on `anyhow`.
431/// This type alias is identical to `anyhow::Result`.
432pub use anyhow::{Error, Result};
433
434#[cfg(feature = "component-model")]
435pub mod component;
436
437cfg_if::cfg_if! {
438 if #[cfg(all(target_os = "macos", not(feature = "posix-signals-on-macos")))] {
439 // no extensions for macOS at this time
440 } else if #[cfg(unix)] {
441 pub mod unix;
442 } else if #[cfg(windows)] {
443 pub mod windows;
444 } else {
445 // ... unknown os!
446 }
447}
448
449fn _assert_send_sync() {
450 fn _assert<T: Send + Sync>() {}
451 fn _assert_send<T: Send>(_t: T) {}
452 _assert::<Engine>();
453 _assert::<Config>();
454 _assert::<(Func, TypedFunc<(), ()>, Global, Table, Memory)>();
455 _assert::<Instance>();
456 _assert::<Module>();
457 _assert::<Store<()>>();
458 _assert::<StoreContext<'_, ()>>();
459 _assert::<StoreContextMut<'_, ()>>();
460 _assert::<Caller<'_, ()>>();
461 _assert::<Linker<()>>();
462 _assert::<Linker<*mut u8>>();
463 _assert::<ExternRef>();
464 _assert::<InstancePre<()>>();
465 _assert::<InstancePre<*mut u8>>();
466
467 #[cfg(feature = "async")]
468 fn _call_async(s: &mut Store<()>, f: Func) {
469 _assert_send(f.call_async(&mut *s, &[], &mut []))
470 }
471 #[cfg(feature = "async")]
472 fn _typed_call_async(s: &mut Store<()>, f: TypedFunc<(), ()>) {
473 _assert_send(f.call_async(&mut *s, ()))
474 }
475 #[cfg(feature = "async")]
476 fn _instantiate_async(s: &mut Store<()>, m: &Module) {
477 _assert_send(Instance::new_async(s, m, &[]))
478 }
479}