wasmer/
lib.rs

1#![doc(
2    html_logo_url = "https://github.com/wasmerio.png?size=200",
3    html_favicon_url = "https://wasmer.io/images/icons/favicon-32x32.png"
4)]
5#![deny(
6    missing_docs,
7    trivial_numeric_casts,
8    unused_extern_crates,
9    rustdoc::broken_intra_doc_links
10)]
11#![warn(unused_import_braces)]
12#![allow(clippy::new_without_default, ambiguous_wide_pointer_comparisons)]
13#![warn(
14    clippy::float_arithmetic,
15    clippy::mut_mut,
16    clippy::nonminimal_bool,
17    clippy::map_unwrap_or,
18    clippy::print_stdout,
19    clippy::unicode_not_nfc,
20    clippy::use_self
21)]
22
23//! [`Wasmer`](https://wasmer.io/) is the most popular
24//! [WebAssembly](https://webassembly.org/) runtime for Rust. It supports
25//! JIT (Just In Time) and AOT (Ahead Of Time) compilation as well as
26//! pluggable compilers suited to your needs.
27//!
28//! It's designed to be safe and secure, and runnable in any kind of environment.
29//!
30//! # Usage
31//!
32//! Here is a small example of using Wasmer to run a WebAssembly module
33//! written with its WAT format (textual format):
34//!
35//! ```rust
36//! use wasmer::{Store, Module, Instance, Value, imports};
37//!
38//! fn main() -> anyhow::Result<()> {
39//!     let module_wat = r#"
40//!     (module
41//!       (type $t0 (func (param i32) (result i32)))
42//!       (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32)
43//!         local.get $p0
44//!         i32.const 1
45//!         i32.add))
46//!     "#;
47//!
48//!     let mut store = Store::default();
49//!     let module = Module::new(&store, &module_wat)?;
50//!     // The module doesn't import anything, so we create an empty import object.
51//!     let import_object = imports! {};
52//!     let instance = Instance::new(&mut store, &module, &import_object)?;
53//!
54//!     let add_one = instance.exports.get_function("add_one")?;
55//!     let result = add_one.call(&mut store, &[Value::I32(42)])?;
56//!     assert_eq!(result[0], Value::I32(43));
57//!
58//!     Ok(())
59//! }
60//! ```
61//!
62//! [Discover the full collection of examples](https://github.com/wasmerio/wasmer/tree/main/examples).
63//!
64//! # Overview of the Features
65//!
66//! Wasmer is not only fast, but also designed to be *highly customizable*:
67//!
68//! * **Pluggable compilers** — A compiler is used by the engine to
69//!   transform WebAssembly into executable code:
70//!   * [`wasmer-compiler-singlepass`] provides a fast compilation-time
71//!     but an unoptimized runtime speed,
72//!   * [`wasmer-compiler-cranelift`] provides the right balance between
73//!     compilation-time and runtime performance, useful for development,
74//!   * [`wasmer-compiler-llvm`] provides a deeply optimized executable
75//!     code with the fastest runtime speed, ideal for production.
76//!
77//! * **Headless mode** — Once a WebAssembly module has been compiled, it
78//!   is possible to serialize it in a file for example, and later execute
79//!   it with Wasmer with headless mode turned on. Headless Wasmer has no
80//!   compiler, which makes it more portable and faster to load. It's
81//!   ideal for constrainted environments.
82//!
83//! * **Cross-compilation** — Most compilers support cross-compilation. It
84//!   means it possible to pre-compile a WebAssembly module targetting a
85//!   different architecture or platform and serialize it, to then run it
86//!   on the targetted architecture and platform later.
87//!
88//! * **Run Wasmer in a JavaScript environment** — With the `js` Cargo
89//!   feature, it is possible to compile a Rust program using Wasmer to
90//!   WebAssembly. In this context, the resulting WebAssembly module will
91//!   expect to run in a JavaScript environment, like a browser, Node.js,
92//!   Deno and so on. In this specific scenario, there is no engines or
93//!   compilers available, it's the one available in the JavaScript
94//!   environment that will be used.
95//!
96//! Wasmer ships by default with the Cranelift compiler as its great for
97//! development purposes.  However, we strongly encourage to use the LLVM
98//! compiler in production as it performs about 50% faster, achieving
99//! near-native speeds.
100//!
101//! Note: if one wants to use multiple compilers at the same time, it's
102//! also possible! One will need to import them directly via each of the
103//! compiler crates.
104//!
105//! # Table of Contents
106//!
107//! - [WebAssembly Primitives](#webassembly-primitives)
108//!   - [Externs](#externs)
109//!     - [Functions](#functions)
110//!     - [Memories](#memories)
111//!     - [Globals](#globals)
112//!     - [Tables](#tables)
113//! - [Project Layout](#project-layout)
114//!   - [Engines](#engines)
115//!   - [Compilers](#compilers)
116//! - [Cargo Features](#cargo-features)
117//! - [Using Wasmer in a JavaScript environment](#using-wasmer-in-a-javascript-environment)
118//!
119//!
120//! # WebAssembly Primitives
121//!
122//! In order to make use of the power of the `wasmer` API, it's important
123//! to understand the primitives around which the API is built.
124//!
125//! Wasm only deals with a small number of core data types, these data
126//! types can be found in the [`Value`] type.
127//!
128//! In addition to the core Wasm types, the core types of the API are
129//! referred to as "externs".
130//!
131//! ## Externs
132//!
133//! An [`Extern`] is a type that can be imported or exported from a Wasm
134//! module.
135//!
136//! To import an extern, simply give it a namespace and a name with the
137//! [`imports!`] macro:
138//!
139//! ```
140//! # use wasmer::{imports, Function, FunctionEnv, FunctionEnvMut, Memory, MemoryType, Store, Imports};
141//! # fn imports_example(mut store: &mut Store) -> Imports {
142//! let memory = Memory::new(&mut store, MemoryType::new(1, None, false)).unwrap();
143//! imports! {
144//!     "env" => {
145//!          "my_function" => Function::new_typed(&mut store, || println!("Hello")),
146//!          "memory" => memory,
147//!     }
148//! }
149//! # }
150//! ```
151//!
152//! And to access an exported extern, see the [`Exports`] API, accessible
153//! from any instance via `instance.exports`:
154//!
155//! ```
156//! # use wasmer::{imports, Instance, FunctionEnv, Memory, TypedFunction, Store};
157//! # fn exports_example(mut env: FunctionEnv<()>, mut store: &mut Store, instance: &Instance) -> anyhow::Result<()> {
158//! let memory = instance.exports.get_memory("memory")?;
159//! let memory: &Memory = instance.exports.get("some_other_memory")?;
160//! let add: TypedFunction<(i32, i32), i32> = instance.exports.get_typed_function(&mut store, "add")?;
161//! let result = add.call(&mut store, 5, 37)?;
162//! assert_eq!(result, 42);
163//! # Ok(())
164//! # }
165//! ```
166//!
167//! These are the primary types that the `wasmer` API uses.
168//!
169//! ### Functions
170//!
171//! There are 2 types of functions in `wasmer`:
172//! 1. Wasm functions,
173//! 2. Host functions.
174//!
175//! A Wasm function is a function defined in a WebAssembly module that can
176//! only perform computation without side effects and call other functions.
177//!
178//! Wasm functions take 0 or more arguments and return 0 or more results.
179//! Wasm functions can only deal with the primitive types defined in
180//! [`Value`].
181//!
182//! A Host function is any function implemented on the host, in this case in
183//! Rust.
184//!
185//! Thus WebAssembly modules by themselves cannot do anything but computation
186//! on the core types in [`Value`]. In order to make them more useful we
187//! give them access to the outside world with [`imports!`].
188//!
189//! If you're looking for a sandboxed, POSIX-like environment to execute Wasm
190//! in, check out the [`wasmer-wasix`] crate for our implementation of WASI,
191//! the WebAssembly System Interface, and WASIX, the Extended version of WASI.
192//!
193//! In the `wasmer` API we support functions which take their arguments and
194//! return their results dynamically, [`Function`], and functions which
195//! take their arguments and return their results statically, [`TypedFunction`].
196//!
197//! ### Memories
198//!
199//! Memories store data.
200//!
201//! In most Wasm programs, nearly all data will live in a [`Memory`].
202//!
203//! This data can be shared between the host and guest to allow for more
204//! interesting programs.
205//!
206//! ### Globals
207//!
208//! A [`Global`] is a type that may be either mutable or immutable, and
209//! contains one of the core Wasm types defined in [`Value`].
210//!
211//! ### Tables
212//!
213//! A [`Table`] is an indexed list of items.
214//!
215//! # Project Layout
216//!
217//! The Wasmer project is divided into a number of crates, below is a dependency
218//! graph with transitive dependencies removed.
219//!
220//! <div>
221//! <img src="https://raw.githubusercontent.com/wasmerio/wasmer/master/docs/deps_dedup.svg" />
222//! </div>
223//!
224//! While this crate is the top level API, we also publish crates built
225//! on top of this API that you may be interested in using, including:
226//!
227//! - [`wasmer-cache`] for caching compiled Wasm modules,
228//! - [`wasmer-wasix`] for running Wasm modules compiled to the WASI ABI.
229//!
230//! The Wasmer project has two major abstractions:
231//! 1. [Engine][wasmer-compiler],
232//! 2. [Compilers][wasmer-compiler].
233//!
234//! These two abstractions have multiple options that can be enabled
235//! with features.
236//!
237//! ## Engine
238//!
239//! The engine is a system that uses a compiler to make a WebAssembly
240//! module executable.
241//!
242//! ## Compilers
243//!
244//! A compiler is a system that handles the details of making a Wasm
245//! module executable. For example, by generating native machine code
246//! for each Wasm function.
247//!
248//! # Cargo Features
249//!
250//! This crate comes in 2 flavors:
251//!
252//! 1. `sys`
253#![cfg_attr(feature = "sys", doc = "(enabled),")]
254#![cfg_attr(not(feature = "sys"), doc = "(disabled),")]
255//!    where `wasmer` will be compiled to a native executable
256//!    which provides compilers, engines, a full VM etc.
257//! 2. `js`
258#![cfg_attr(feature = "js", doc = "(enabled),")]
259#![cfg_attr(not(feature = "js"), doc = "(disabled),")]
260//!    where `wasmer` will be compiled to WebAssembly to run in a
261//!    JavaScript host (see [Using Wasmer in a JavaScript
262//!    environment](#using-wasmer-in-a-javascript-environment)).
263//!
264//! Consequently, we can group the features by the `sys` or `js`
265//! features.
266//!
267#![cfg_attr(
268    feature = "sys",
269    doc = "## Features for the `sys` feature group (enabled)"
270)]
271#![cfg_attr(
272    not(feature = "sys"),
273    doc = "## Features for the `sys` feature group (disabled)"
274)]
275//!
276//! The default features can be enabled with the `sys-default` feature.
277//!
278//! The features for the `sys` feature group can be broken down into 2
279//! kinds: features that enable new functionality and features that
280//! set defaults.
281//!
282//! The features that enable new functionality are:
283//! - `cranelift`
284#![cfg_attr(feature = "cranelift", doc = "(enabled),")]
285#![cfg_attr(not(feature = "cranelift"), doc = "(disabled),")]
286//!   enables Wasmer's [Cranelift compiler][wasmer-compiler-cranelift],
287//! - `llvm`
288#![cfg_attr(feature = "llvm", doc = "(enabled),")]
289#![cfg_attr(not(feature = "llvm"), doc = "(disabled),")]
290//!   enables Wasmer's [LLVM compiler][wasmer-compiler-lvm],
291//! - `singlepass`
292#![cfg_attr(feature = "singlepass", doc = "(enabled),")]
293#![cfg_attr(not(feature = "singlepass"), doc = "(disabled),")]
294//!   enables Wasmer's [Singlepass compiler][wasmer-compiler-singlepass],
295//! - `wat`
296#![cfg_attr(feature = "wat", doc = "(enabled),")]
297#![cfg_attr(not(feature = "wat"), doc = "(disabled),")]
298//!   enables `wasmer` to parse the WebAssembly text format,
299//! - `compilation`
300#![cfg_attr(feature = "compiler", doc = "(enabled),")]
301#![cfg_attr(not(feature = "compiler"), doc = "(disabled),")]
302//!   enables compilation with the wasmer engine.
303//!
304#![cfg_attr(
305    feature = "js",
306    doc = "## Features for the `js` feature group (enabled)"
307)]
308#![cfg_attr(
309    not(feature = "js"),
310    doc = "## Features for the `js` feature group (disabled)"
311)]
312//!
313//! The default features can be enabled with the `js-default` feature.
314//!
315//! Here are the detailed list of features:
316//!
317//! - `wasm-types-polyfill`
318#![cfg_attr(feature = "wasm-types-polyfill", doc = "(enabled),")]
319#![cfg_attr(not(feature = "wasm-types-polyfill"), doc = "(disabled),")]
320//!   parses the Wasm file, allowing to do type reflection of the
321//!   inner Wasm types. It adds 100kb to the Wasm bundle (28kb
322//!   gzipped). It is possible to disable it and to use
323//!   `Module::set_type_hints` manually instead for a lightweight
324//!   alternative. This is needed until the [Wasm JS introspection API
325//!   proposal](https://github.com/WebAssembly/js-types/blob/master/proposals/js-types/Overview.md)
326//!   is adopted by browsers,
327//! - `wat`
328#![cfg_attr(feature = "wat", doc = "(enabled),")]
329#![cfg_attr(not(feature = "wat"), doc = "(disabled),")]
330//!  allows to read a Wasm file in its text format. This feature is
331//!  normally used only in development environments. It will add
332//!  around 650kb to the Wasm bundle (120Kb gzipped).
333//!
334//! # Using Wasmer in a JavaScript environment
335//!
336//! Imagine a Rust program that uses this `wasmer` crate to execute a
337//! WebAssembly module. It is possible to compile this Rust progam to
338//! WebAssembly by turning on the `js` Cargo feature of this `wasmer`
339//! crate.
340//!
341//! Here is a small example illustrating such a Rust program, and how
342//! to compile it with [`wasm-pack`] and [`wasm-bindgen`]:
343//!
344//! ```ignore
345//! use wasm_bindgen::prelude::*;
346//! use wasmer::{imports, Instance, Module, Store, Value};
347//!
348//! #[wasm_bindgen]
349//! pub extern fn do_add_one_in_wasmer() -> i32 {
350//!     let module_wat = r#"
351//!     (module
352//!       (type $t0 (func (param i32) (result i32)))
353//!       (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32)
354//!         local.get $p0
355//!         i32.const 1
356//!         i32.add))
357//!     "#;
358//!     let mut store = Store::default();
359//!     let module = Module::new(&store, &module_wat).unwrap();
360//!     // The module doesn't import anything, so we create an empty import object.
361//!     let import_object = imports! {};
362//!     let instance = Instance::new(&mut store, &module, &import_object).unwrap();
363//!
364//!     let add_one = instance.exports.get_function("add_one").unwrap();
365//!     let result = add_one.call(&mut store, &[Value::I32(42)]).unwrap();
366//!     assert_eq!(result[0], Value::I32(43));
367//!
368//!     result[0].unwrap_i32()
369//! }
370//! ```
371//!
372//! Note that it's the same code as above with the former example. The
373//! API is the same!
374//!
375//! Then, compile with `wasm-pack build`. Take care of using the `js`
376//! or `js-default` Cargo features.
377//!
378//! [wasm]: https://webassembly.org/
379//! [wasmer-examples]: https://github.com/wasmerio/wasmer/tree/main/examples
380//! [`wasmer-cache`]: https://docs.rs/wasmer-cache/
381//! [wasmer-compiler]: https://docs.rs/wasmer-compiler/
382//! [`wasmer-compiler-singlepass`]: https://docs.rs/wasmer-compiler-singlepass/
383//! [`wasmer-compiler-llvm`]: https://docs.rs/wasmer-compiler-llvm/
384//! [`wasmer-compiler-cranelift`]: https://docs.rs/wasmer-compiler-cranelift/
385//! [`wasmer-wasix`]: https://docs.rs/wasmer-wasix/
386//! [`wasm-pack`]: https://github.com/rustwasm/wasm-pack/
387//! [`wasm-bindgen`]: https://github.com/rustwasm/wasm-bindgen
388
389#[cfg(all(
390    not(feature = "sys"),
391    not(feature = "js"),
392    not(feature = "jsc"),
393    not(feature = "wasm-c-api")
394))]
395compile_error!(
396    "One of: `sys`, `js`, `jsc` or `wasm-c-api` features must be enabled. Please, pick one."
397);
398
399#[cfg(all(feature = "sys", feature = "js"))]
400compile_error!(
401    "Cannot have both `sys` and `js` features enabled at the same time. Please, pick one."
402);
403
404#[cfg(all(feature = "js", feature = "jsc"))]
405compile_error!(
406    "Cannot have both `js` and `jsc` features enabled at the same time. Please, pick one."
407);
408
409#[cfg(all(feature = "js", feature = "wasm-c-api"))]
410compile_error!(
411    "Cannot have both `js` and `wasm-c-api` features enabled at the same time. Please, pick one."
412);
413
414#[cfg(all(feature = "jsc", feature = "wasm-c-api"))]
415compile_error!(
416    "Cannot have both `jsc` and `wasm-c-api` features enabled at the same time. Please, pick one."
417);
418
419#[cfg(all(feature = "sys", feature = "jsc"))]
420compile_error!(
421    "Cannot have both `sys` and `jsc` features enabled at the same time. Please, pick one."
422);
423
424#[cfg(all(feature = "sys", feature = "wasm-c-api"))]
425compile_error!(
426    "Cannot have both `sys` and `wasm-c-api` features enabled at the same time. Please, pick one."
427);
428
429#[cfg(all(feature = "sys", target_arch = "wasm32"))]
430compile_error!("The `sys` feature must be enabled only for non-`wasm32` target.");
431
432#[cfg(all(feature = "jsc", target_arch = "wasm32"))]
433compile_error!("The `jsc` feature must be enabled only for non-`wasm32` target.");
434
435#[cfg(all(feature = "js", not(target_arch = "wasm32")))]
436compile_error!(
437    "The `js` feature must be enabled only for the `wasm32` target (either `wasm32-unknown-unknown` or `wasm32-wasi`)."
438);
439
440mod access;
441mod engine;
442mod errors;
443mod exports;
444mod extern_ref;
445mod externals;
446mod function_env;
447mod imports;
448mod instance;
449mod into_bytes;
450mod mem_access;
451mod module;
452mod native_type;
453mod ptr;
454mod store;
455mod typed_function;
456mod value;
457pub mod vm;
458
459#[cfg(any(feature = "wasm-types-polyfill", feature = "jsc"))]
460mod module_info_polyfill;
461
462#[cfg(feature = "sys")]
463/// The `sys` engine.
464pub mod sys;
465#[cfg(feature = "sys")]
466/// Re-export `sys` definitions.
467pub use sys::*;
468
469#[cfg(feature = "js")]
470/// The `js` engine.
471mod js;
472#[cfg(feature = "js")]
473/// Re-export `js` definitions.
474pub use js::*;
475
476#[cfg(feature = "jsc")]
477/// The `jsc` engine.
478mod jsc;
479#[cfg(feature = "jsc")]
480/// Re-export `jsc` definitions.
481pub use jsc::*;
482
483#[cfg(feature = "wasm-c-api")]
484/// The `c-api` engine.
485mod c_api;
486#[cfg(feature = "wasm-c-api")]
487/// Re-export `c-api` definitions.
488#[allow(unused_imports)]
489pub use c_api::*;
490
491pub use crate::externals::{
492    Extern, Function, Global, HostFunction, Memory, MemoryLocation, MemoryView, SharedMemory, Table,
493};
494pub use access::WasmSliceAccess;
495pub use engine::{AsEngineRef, Engine, EngineRef};
496pub use errors::{AtomicsError, InstantiationError, LinkError, RuntimeError};
497pub use exports::{ExportError, Exportable, Exports, ExportsIterator};
498pub use extern_ref::ExternRef;
499pub use function_env::{FunctionEnv, FunctionEnvMut};
500pub use imports::Imports;
501pub use instance::Instance;
502pub use into_bytes::IntoBytes;
503pub use mem_access::{MemoryAccessError, WasmRef, WasmSlice, WasmSliceIter};
504pub use module::{IoCompileError, Module};
505pub use native_type::{FromToNativeWasmType, NativeWasmTypeInto, WasmTypeList};
506pub use ptr::{Memory32, Memory64, MemorySize, WasmPtr, WasmPtr64};
507pub use store::{
508    AsStoreMut, AsStoreRef, OnCalledHandler, Store, StoreId, StoreMut, StoreObjects, StoreRef,
509};
510#[cfg(feature = "sys")]
511pub use store::{TrapHandlerFn, Tunables};
512#[cfg(any(feature = "sys", feature = "jsc", feature = "wasm-c-api"))]
513pub use target_lexicon::{Architecture, CallingConvention, OperatingSystem, Triple, HOST};
514pub use typed_function::TypedFunction;
515pub use value::Value;
516
517// Reexport from other modules
518
519pub use wasmer_derive::ValueType;
520
521#[cfg(any(feature = "sys", feature = "jsc", feature = "wasm-c-api"))]
522pub use wasmer_compiler::types::target::{CpuFeature, Target};
523
524// TODO: OnCalledAction is needed for asyncify. It will be refactored with https://github.com/wasmerio/wasmer/issues/3451
525pub use wasmer_types::{
526    is_wasm, Bytes, CompileError, DeserializeError, ExportIndex, ExportType, ExternType, FrameInfo,
527    FunctionType, GlobalInit, GlobalType, ImportType, LocalFunctionIndex, MemoryError, MemoryType,
528    MiddlewareError, Mutability, OnCalledAction, Pages, ParseCpuFeatureError, SerializeError,
529    TableType, Type, ValueType, WasmError, WasmResult, WASM_MAX_PAGES, WASM_MIN_PAGES,
530    WASM_PAGE_SIZE,
531};
532#[cfg(feature = "wat")]
533pub use wat::parse_bytes as wat2wasm;
534
535#[cfg(feature = "wasmparser")]
536pub use wasmparser;
537
538/// Version number of this crate.
539pub const VERSION: &str = env!("CARGO_PKG_VERSION");