xref: /wasmtime-44.0.1/crates/wasmtime/src/lib.rs (revision d3e7548e)
1 //! # Wasmtime's embedding API
2 //!
3 //! Wasmtime is a WebAssembly engine for JIT-compiled or ahead-of-time compiled
4 //! WebAssembly modules and components. More information about the Wasmtime
5 //! project as a whole can be found [in the documentation
6 //! book](https://docs.wasmtime.dev) whereas this documentation mostly focuses
7 //! on the API reference of the `wasmtime` crate itself.
8 //!
9 //! This crate contains an API used to interact with [WebAssembly modules] or
10 //! [WebAssembly components]. For example you can compile WebAssembly, create
11 //! instances, call functions, etc. As an embedder of WebAssembly you can also
12 //! provide guests functionality from the host by creating host-defined
13 //! functions, memories, globals, etc, which can do things that WebAssembly
14 //! cannot (such as print to the screen).
15 //!
16 //! [WebAssembly modules]: https://webassembly.github.io/spec
17 //! [WebAssembly components]: https://component-model.bytecodealliance.org
18 //!
19 //! The `wasmtime` crate is designed to be safe, efficient, and ergonomic.
20 //! This enables executing WebAssembly without the embedder needing to use
21 //! `unsafe` code, meaning that you're guaranteed there is no undefined behavior
22 //! or segfaults in either the WebAssembly guest or the host itself.
23 //!
24 //! The `wasmtime` crate can roughly be thought of as being split into two
25 //! halves:
26 //!
27 //! * One half of the crate is similar to the [JS WebAssembly
28 //!   API](https://developer.mozilla.org/en-US/docs/WebAssembly) as well as the
29 //!   [proposed C API](https://github.com/webassembly/wasm-c-api) and is
30 //!   intended for working with [WebAssembly modules]. This API resides in the
31 //!   root of the `wasmtime` crate's namespace, for example
32 //!   [`wasmtime::Module`](`Module`).
33 //!
34 //! * The second half of the crate is for use with the [WebAssembly Component
35 //!   Model]. The implementation of the component model is present in
36 //!   [`wasmtime::component`](`component`) and roughly mirrors the structure for
37 //!   core WebAssembly, for example [`component::Func`] mirrors [`Func`].
38 //!
39 //! [WebAssembly Component Model]: https://component-model.bytecodealliance.org
40 //!
41 //! An example of using Wasmtime to run a core WebAssembly module looks like:
42 //!
43 //! ```
44 //! use wasmtime::*;
45 //!
46 //! fn main() -> wasmtime::Result<()> {
47 //!     let engine = Engine::default();
48 //!
49 //!     // Modules can be compiled through either the text or binary format
50 //!     let wat = r#"
51 //!         (module
52 //!             (import "host" "host_func" (func $host_hello (param i32)))
53 //!
54 //!             (func (export "hello")
55 //!                 i32.const 3
56 //!                 call $host_hello)
57 //!         )
58 //!     "#;
59 //!     let module = Module::new(&engine, wat)?;
60 //!
61 //!     // Host functionality can be arbitrary Rust functions and is provided
62 //!     // to guests through a `Linker`.
63 //!     let mut linker = Linker::new(&engine);
64 //!     linker.func_wrap("host", "host_func", |caller: Caller<'_, u32>, param: i32| {
65 //!         println!("Got {} from WebAssembly", param);
66 //!         println!("my host state is: {}", caller.data());
67 //!     })?;
68 //!
69 //!     // All wasm objects operate within the context of a "store". Each
70 //!     // `Store` has a type parameter to store host-specific data, which in
71 //!     // this case we're using `4` for.
72 //!     let mut store: Store<u32> = Store::new(&engine, 4);
73 //!
74 //!     // Instantiation of a module requires specifying its imports and then
75 //!     // afterwards we can fetch exports by name, as well as asserting the
76 //!     // type signature of the function with `get_typed_func`.
77 //!     let instance = linker.instantiate(&mut store, &module)?;
78 //!     let hello = instance.get_typed_func::<(), ()>(&mut store, "hello")?;
79 //!
80 //!     // And finally we can call the wasm!
81 //!     hello.call(&mut store, ())?;
82 //!
83 //!     Ok(())
84 //! }
85 //! ```
86 //!
87 //! ## Core Concepts
88 //!
89 //! There are a number of core types and concepts that are important to be aware
90 //! of when using the `wasmtime` crate:
91 //!
92 //! * [`Engine`] - a global compilation and runtime environment for WebAssembly.
93 //!   An [`Engine`] is an object that can be shared concurrently across threads
94 //!   and is created with a [`Config`] with many knobs for configuring
95 //!   behavior. Compiling or executing any WebAssembly requires first
96 //!   configuring and creating an [`Engine`]. All [`Module`]s and
97 //!   [`Component`](component::Component)s belong to an [`Engine`], and
98 //!   typically there's one [`Engine`] per process.
99 //!
100 //! * [`Store`] - container for all information related to WebAssembly objects
101 //!   such as functions, instances, memories, etc. A [`Store<T>`][`Store`]
102 //!   allows customization of the `T` to store arbitrary host data within a
103 //!   [`Store`]. This host data can be accessed through host functions via the
104 //!   [`Caller`] function parameter in host-defined functions. A [`Store`] is
105 //!   required for all WebAssembly operations, such as calling a wasm function.
106 //!   The [`Store`] is passed in as a "context" to methods like [`Func::call`].
107 //!   Dropping a [`Store`] will deallocate all memory associated with
108 //!   WebAssembly objects within the [`Store`]. A [`Store`] is cheap to create
109 //!   and destroy and does not GC objects such as unused instances internally,
110 //!   so it's intended to be short-lived (or no longer than the instances it
111 //!   contains).
112 //!
113 //! * [`Linker`] (or [`component::Linker`]) - host functions are defined within
114 //!   a linker to provide them a string-based name which can be looked up when
115 //!   instantiating a WebAssembly module or component. Linkers are traditionally
116 //!   populated at startup and then reused for all future instantiations of all
117 //!   instances, assuming the set of host functions does not change over time.
118 //!   Host functions are `Fn(..) + Send + Sync` and typically do not close over
119 //!   mutable state. Instead it's recommended to store mutable state in the `T`
120 //!   of [`Store<T>`] which is accessed through [`Caller<'_,
121 //!   T>`](crate::Caller) provided to host functions.
122 //!
123 //! * [`Module`] (or [`Component`](component::Component)) - a compiled
124 //!   WebAssembly module or component. These structures contain compiled
125 //!   executable code from a WebAssembly binary which is ready to execute after
126 //!   being instantiated. These are expensive to create as they require
127 //!   compilation of the input WebAssembly. Modules and components are safe to
128 //!   share across threads, however. Modules and components can additionally be
129 //!   [serialized into a list of bytes](crate::Module::serialize) to later be
130 //!   [deserialized](crate::Module::deserialize) quickly. This enables JIT-style
131 //!   compilation through constructors such as [`Module::new`] and AOT-style
132 //!   compilation by having the compilation process use [`Module::serialize`]
133 //!   and the execution process use [`Module::deserialize`].
134 //!
135 //! * [`Instance`] (or [`component::Instance`]) - an instantiated WebAssembly
136 //!   module or component. An instance is where you can actually acquire a
137 //!   [`Func`] (or [`component::Func`]) from, for example, to call.
138 //!
139 //! * [`Func`] (or [`component::Func`]) - a WebAssembly function. This can be
140 //!   acquired as the export of an [`Instance`] to call WebAssembly functions,
141 //!   or it can be created via functions like [`Func::wrap`] to wrap
142 //!   host-defined functionality and give it to WebAssembly. Functions also have
143 //!   typed views as [`TypedFunc`] or [`component::TypedFunc`] for a more
144 //!   efficient calling convention.
145 //!
146 //! * [`Table`], [`Global`], [`Memory`], [`component::Resource`] - other
147 //!   WebAssembly objects which can either be defined on the host or in wasm
148 //!   itself (via instances). These all have various ways of being interacted
149 //!   with like [`Func`].
150 //!
151 //! All "store-connected" types such as [`Func`], [`Memory`], etc, require the
152 //! store to be passed in as a context to each method. Methods in wasmtime
153 //! frequently have their first parameter as either [`impl
154 //! AsContext`][`AsContext`] or [`impl AsContextMut`][`AsContextMut`]. These
155 //! traits are implemented for a variety of types, allowing you to, for example,
156 //! pass the following types into methods:
157 //!
158 //! * `&Store<T>`
159 //! * `&mut Store<T>`
160 //! * `&Caller<'_, T>`
161 //! * `&mut Caller<'_, T>`
162 //! * `StoreContext<'_, T>`
163 //! * `StoreContextMut<'_, T>`
164 //!
165 //! A [`Store`] is the sole owner of all WebAssembly internals. Types like
166 //! [`Func`] point within the [`Store`] and require the [`Store`] to be provided
167 //! to actually access the internals of the WebAssembly function, for instance.
168 //!
169 //! ## WASI
170 //!
171 //! The `wasmtime` crate does not natively provide support for WASI, but you can
172 //! use the [`wasmtime-wasi`] crate for that purpose. With [`wasmtime-wasi`] all
173 //! WASI functions can be added to a [`Linker`] and then used to instantiate
174 //! WASI-using modules. For more information see the [WASI example in the
175 //! documentation](https://docs.wasmtime.dev/examples-rust-wasi.html).
176 //!
177 //! [`wasmtime-wasi`]: https://crates.io/crates/wasmtime-wasi
178 //!
179 //! ## Crate Features
180 //!
181 //! The `wasmtime` crate comes with a number of compile-time features that can
182 //! be used to customize what features it supports. Some of these features are
183 //! just internal details, but some affect the public API of the `wasmtime`
184 //! crate. Wasmtime APIs gated behind a Cargo feature should be indicated as
185 //! such in the documentation.
186 //!
187 //! * `runtime` - Enabled by default, this feature enables executing
188 //!   WebAssembly modules and components. If a compiler is not available (such
189 //!   as `cranelift`) then [`Module::deserialize`] must be used, for example, to
190 //!   provide an ahead-of-time compiled artifact to execute WebAssembly.
191 //!
192 //! * `cranelift` - Enabled by default, this features enables using Cranelift at
193 //!   runtime to compile a WebAssembly module to native code. This feature is
194 //!   required to process and compile new WebAssembly modules and components.
195 //!
196 //! * `cache` - Enabled by default, this feature adds support for wasmtime to
197 //!   perform internal caching of modules in a global location. This must still
198 //!   be enabled explicitly through [`Config::cache_config_load`] or
199 //!   [`Config::cache_config_load_default`].
200 //!
201 //! * `wat` - Enabled by default, this feature adds support for accepting the
202 //!   text format of WebAssembly in [`Module::new`] and
203 //!   [`Component::new`](component::Component::new). The text format will be
204 //!   automatically recognized and translated to binary when compiling a
205 //!   module.
206 //!
207 //! * `parallel-compilation` - Enabled by default, this feature enables support
208 //!   for compiling functions in parallel with `rayon`.
209 //!
210 //! * `async` - Enabled by default, this feature enables APIs and runtime
211 //!   support for defining asynchronous host functions and calling WebAssembly
212 //!   asynchronously. For more information see [`Config::async_support`].
213 //!
214 //! * `profiling` - Enabled by default, this feature compiles in support for
215 //!   profiling guest code via a number of possible strategies. See
216 //!   [`Config::profiler`] for more information.
217 //!
218 //! * `all-arch` - Not enabled by default. This feature compiles in support for
219 //!   all architectures for both the JIT compiler and the `wasmtime compile` CLI
220 //!   command. This can be combined with [`Config::target`] to precompile
221 //!   modules for a different platform than the host.
222 //!
223 //! * `pooling-allocator` - Enabled by default, this feature adds support for
224 //!   [`PoolingAllocationConfig`] to pass to [`Config::allocation_strategy`].
225 //!   The pooling allocator can enable efficient reuse of resources for
226 //!   high-concurrency and high-instantiation-count scenarios.
227 //!
228 //! * `demangle` - Enabled by default, this will affect how backtraces are
229 //!   printed and whether symbol names from WebAssembly are attempted to be
230 //!   demangled. Rust and C++ demanglings are currently supported.
231 //!
232 //! * `coredump` - Enabled by default, this will provide support for generating
233 //!   a core dump when a trap happens. This can be configured via
234 //!   [`Config::coredump_on_trap`].
235 //!
236 //! * `addr2line` - Enabled by default, this feature configures whether traps
237 //!   will attempt to parse DWARF debug information and convert WebAssembly
238 //!   addresses to source filenames and line numbers.
239 //!
240 //! * `debug-builtins` - Enabled by default, this feature includes some built-in
241 //!   debugging utilities and symbols for native debuggers such as GDB and LLDB
242 //!   to attach to the process Wasmtime is used within. The intrinsics provided
243 //!   will enable debugging guest code compiled to WebAssembly. This must also
244 //!   be enabled via [`Config::debug_info`] as well for guests.
245 //!
246 //! * `component-model` - Enabled by default, this enables support for the
247 //!   [`wasmtime::component`](component) API for working with components.
248 //!
249 //! * `gc` - Enabled by default, this enables support for a number of
250 //!   WebAssembly proposals such as `reference-types`, `function-references`,
251 //!   and `gc`. Note that the implementation of the `gc` proposal itself is not
252 //!   yet complete at this time.
253 //!
254 //! * `threads` - Enabled by default, this enables compile-time support for the
255 //!   WebAssembly `threads` proposal, notably shared memories.
256 //!
257 //! * `call-hook` - Disabled by default, this enables support for the
258 //!   [`Store::call_hook`] API. This incurs a small overhead on all
259 //!   entries/exits from WebAssembly and may want to be disabled by some
260 //!   embedders.
261 //!
262 //! * `memory-protection-keys` - Disabled by default, this enables support for
263 //!   the [`PoolingAllocationConfig::memory_protection_keys`] API. This feature
264 //!   currently only works on x64 Linux and can enable compacting the virtual
265 //!   memory allocation for linear memories in the pooling allocator. This comes
266 //!   with the same overhead as the `call-hook` feature where entries/exits into
267 //!   WebAssembly will have more overhead than before.
268 //!
269 //! * `signals-based-traps` - Enabled by default, this enables support for using
270 //!   host signal handlers to implement WebAssembly traps. For example virtual
271 //!   memory is used to catch out-of-bounds accesses in WebAssembly that result
272 //!   in segfaults. This is implicitly enabled by the `std` feature and is the
273 //!   best way to get high-performance WebAssembly.
274 //!
275 //! More crate features can be found in the [manifest] of Wasmtime itself for
276 //! seeing what can be enabled and disabled.
277 //!
278 //! [manifest]: https://github.com/bytecodealliance/wasmtime/blob/main/crates/wasmtime/Cargo.toml
279 
280 #![deny(missing_docs)]
281 #![doc(test(attr(deny(warnings))))]
282 #![doc(test(attr(allow(dead_code, unused_variables, unused_mut))))]
283 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
284 // NB: this list is currently being burned down to remove all features listed
285 // here to get warnings in all configurations of Wasmtime.
286 #![cfg_attr(
287     any(not(feature = "runtime"), not(feature = "std")),
288     allow(dead_code, unused_imports)
289 )]
290 // Allow broken links when the default features is disabled because most of our
291 // documentation is written for the "one build" of the `main` branch which has
292 // most features enabled. This will present warnings in stripped-down doc builds
293 // and will prevent the doc build from failing.
294 #![cfg_attr(feature = "default", warn(rustdoc::broken_intra_doc_links))]
295 #![no_std]
296 #![expect(clippy::allow_attributes_without_reason, reason = "crate not migrated")]
297 #![expect(unsafe_op_in_unsafe_fn, reason = "crate isn't migrated yet")]
298 
299 #[cfg(any(feature = "std", unix, windows))]
300 #[macro_use]
301 extern crate std;
302 extern crate alloc;
303 
304 pub(crate) mod prelude {
305     pub use crate::{Error, Result};
306     pub use anyhow::{Context, anyhow, bail, ensure, format_err};
307     pub use wasmtime_environ::prelude::*;
308 }
309 
310 pub(crate) use hashbrown::{hash_map, hash_set};
311 
312 /// A helper macro to safely map `MaybeUninit<T>` to `MaybeUninit<U>` where `U`
313 /// is a field projection within `T`.
314 ///
315 /// This is intended to be invoked as:
316 ///
317 /// ```ignore
318 /// struct MyType {
319 ///     field: u32,
320 /// }
321 ///
322 /// let initial: &mut MaybeUninit<MyType> = ...;
323 /// let field: &mut MaybeUninit<u32> = map_maybe_uninit!(initial.field);
324 /// ```
325 ///
326 /// Note that array accesses are also supported:
327 ///
328 /// ```ignore
329 ///
330 /// let initial: &mut MaybeUninit<[u32; 2]> = ...;
331 /// let element: &mut MaybeUninit<u32> = map_maybe_uninit!(initial[1]);
332 /// ```
333 #[doc(hidden)]
334 #[macro_export]
335 macro_rules! map_maybe_uninit {
336     ($maybe_uninit:ident $($field:tt)*) => ({
337         #[allow(unused_unsafe)]
338         {
339             unsafe {
340                 use $crate::MaybeUninitExt;
341 
342                 let m: &mut core::mem::MaybeUninit<_> = $maybe_uninit;
343                 // Note the usage of `&raw` here which is an attempt to "stay
344                 // safe" here where we never accidentally create `&mut T` where `T` is
345                 // actually uninitialized, hopefully appeasing the Rust unsafe
346                 // guidelines gods.
347                 m.map(|p| &raw mut (*p)$($field)*)
348             }
349         }
350     })
351 }
352 
353 #[doc(hidden)]
354 pub trait MaybeUninitExt<T> {
355     /// Maps `MaybeUninit<T>` to `MaybeUninit<U>` using the closure provided.
356     ///
357     /// Note that this is `unsafe` as there is no guarantee that `U` comes from
358     /// `T`.
359     unsafe fn map<U>(&mut self, f: impl FnOnce(*mut T) -> *mut U)
360     -> &mut core::mem::MaybeUninit<U>;
361 }
362 
363 impl<T> MaybeUninitExt<T> for core::mem::MaybeUninit<T> {
364     unsafe fn map<U>(
365         &mut self,
366         f: impl FnOnce(*mut T) -> *mut U,
367     ) -> &mut core::mem::MaybeUninit<U> {
368         let new_ptr = f(self.as_mut_ptr());
369         core::mem::transmute::<*mut U, &mut core::mem::MaybeUninit<U>>(new_ptr)
370     }
371 }
372 
373 #[cfg(feature = "runtime")]
374 mod runtime;
375 #[cfg(feature = "runtime")]
376 pub use runtime::*;
377 
378 #[cfg(any(feature = "cranelift", feature = "winch"))]
379 mod compile;
380 #[cfg(any(feature = "cranelift", feature = "winch"))]
381 pub use compile::{CodeBuilder, CodeHint};
382 
383 mod config;
384 mod engine;
385 mod profiling_agent;
386 
387 pub use crate::config::*;
388 pub use crate::engine::*;
389 
390 #[cfg(feature = "std")]
391 mod sync_std;
392 #[cfg(feature = "std")]
393 use sync_std as sync;
394 
395 #[cfg_attr(feature = "std", allow(dead_code))]
396 mod sync_nostd;
397 #[cfg(not(feature = "std"))]
398 use sync_nostd as sync;
399 
400 /// A convenience wrapper for `Result<T, anyhow::Error>`.
401 ///
402 /// This type can be used to interact with `wasmtimes`'s extensive use
403 /// of `anyhow::Error` while still not directly depending on `anyhow`.
404 ///
405 /// This type alias is identical to `anyhow::Result`.
406 #[doc(no_inline)]
407 pub use anyhow::{Error, Result};
408 
409 /// A re-exported instance of Wasmtime's `wasmparser` dependency.
410 ///
411 /// This may be useful for embedders that also use `wasmparser`
412 /// directly: it allows embedders to ensure that they are using the same
413 /// version as Wasmtime, both to eliminate redundant dependencies on
414 /// multiple versions of the library, and to ensure compatibility in
415 /// validation and feature support.
416 ///
417 /// Note that this re-export is *not subject to semver*: we reserve the
418 /// right to make patch releases of Wasmtime that bump the version of
419 /// wasmparser used, and hence the version re-exported, in
420 /// semver-incompatible ways. This is the tradeoff that the embedder
421 /// needs to opt into: in order to stay exactly in sync with an internal
422 /// detail of Wasmtime, the cost is visibility into potential internal
423 /// version changes.
424 #[cfg(feature = "reexport-wasmparser")]
425 pub use wasmparser;
426 
427 fn _assert_send_and_sync<T: Send + Sync>() {}
428 
429 fn _assertions_lib() {
430     _assert_send_and_sync::<Engine>();
431     _assert_send_and_sync::<Config>();
432 }
433 
434 #[cfg(feature = "runtime")]
435 #[doc(hidden)]
436 pub mod _internal {
437     // Exported just for the CLI.
438     pub use crate::runtime::vm::MmapVec;
439 }
440