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