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