xref: /wasmtime-44.0.1/crates/wasmtime/src/lib.rs (revision ca5a9db0)
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" "host_func" (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_func = 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_func.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" "host_func" (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", "host_func", |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]
391 mod func;
392 
393 #[cfg(any(feature = "cranelift", feature = "winch"))]
394 mod compiler;
395 
396 mod code;
397 mod config;
398 mod coredump;
399 mod engine;
400 mod externals;
401 mod instance;
402 mod limits;
403 mod linker;
404 mod memory;
405 mod module;
406 mod profiling;
407 mod r#ref;
408 mod resources;
409 mod signatures;
410 mod store;
411 mod trampoline;
412 mod trap;
413 mod types;
414 mod values;
415 
416 pub use crate::config::*;
417 pub use crate::coredump::*;
418 pub use crate::engine::*;
419 pub use crate::externals::*;
420 pub use crate::func::*;
421 pub use crate::instance::{Instance, InstancePre};
422 pub use crate::limits::*;
423 pub use crate::linker::*;
424 pub use crate::memory::*;
425 pub use crate::module::Module;
426 pub use crate::profiling::GuestProfiler;
427 pub use crate::r#ref::ExternRef;
428 pub use crate::resources::*;
429 #[cfg(feature = "async")]
430 pub use crate::store::CallHookHandler;
431 pub use crate::store::{
432     AsContext, AsContextMut, CallHook, Store, StoreContext, StoreContextMut, UpdateDeadline,
433 };
434 pub use crate::trap::*;
435 pub use crate::types::*;
436 pub use crate::values::*;
437 
438 /// A convenience wrapper for `Result<T, anyhow::Error>`.
439 ///
440 /// This type can be used to interact with `wasmtimes`'s extensive use
441 /// of `anyhow::Error` while still not directly depending on `anyhow`.
442 /// This type alias is identical to `anyhow::Result`.
443 pub use anyhow::{Error, Result};
444 
445 #[cfg(feature = "component-model")]
446 pub mod component;
447 
448 cfg_if::cfg_if! {
449     if #[cfg(all(target_os = "macos", not(feature = "posix-signals-on-macos")))] {
450         // no extensions for macOS at this time
451     } else if #[cfg(unix)] {
452         pub mod unix;
453     } else if #[cfg(windows)] {
454         pub mod windows;
455     } else {
456         // ... unknown os!
457     }
458 }
459 
460 fn _assert_send_sync() {
461     fn _assert<T: Send + Sync>() {}
462     fn _assert_send<T: Send>(_t: T) {}
463     _assert::<Engine>();
464     _assert::<Config>();
465     _assert::<(Func, TypedFunc<(), ()>, Global, Table, Memory)>();
466     _assert::<Instance>();
467     _assert::<Module>();
468     _assert::<Store<()>>();
469     _assert::<StoreContext<'_, ()>>();
470     _assert::<StoreContextMut<'_, ()>>();
471     _assert::<Caller<'_, ()>>();
472     _assert::<Linker<()>>();
473     _assert::<Linker<*mut u8>>();
474     _assert::<ExternRef>();
475     _assert::<InstancePre<()>>();
476     _assert::<InstancePre<*mut u8>>();
477 
478     #[cfg(feature = "async")]
479     fn _call_async(s: &mut Store<()>, f: Func) {
480         _assert_send(f.call_async(&mut *s, &[], &mut []))
481     }
482     #[cfg(feature = "async")]
483     fn _typed_call_async(s: &mut Store<()>, f: TypedFunc<(), ()>) {
484         _assert_send(f.call_async(&mut *s, ()))
485     }
486     #[cfg(feature = "async")]
487     fn _instantiate_async(s: &mut Store<()>, m: &Module) {
488         _assert_send(Instance::new_async(s, m, &[]))
489     }
490 }
491