diff --git a/lib/api/src/lib.rs b/lib/api/src/lib.rs index d5c054596..32b4a5de0 100644 --- a/lib/api/src/lib.rs +++ b/lib/api/src/lib.rs @@ -1,3 +1,342 @@ +#![doc( + html_logo_url = "https://github.com/wasmerio.png?size=200", + html_favicon_url = "https://wasmer.io/images/icons/favicon-32x32.png" +)] +#![deny( + missing_docs, + trivial_numeric_casts, + unused_extern_crates, + broken_intra_doc_links +)] +#![warn(unused_import_braces)] +#![cfg_attr( + feature = "cargo-clippy", + allow(clippy::new_without_default, vtable_address_comparisons) +)] +#![cfg_attr( + feature = "cargo-clippy", + warn( + clippy::float_arithmetic, + clippy::mut_mut, + clippy::nonminimal_bool, + clippy::option_map_unwrap_or, + clippy::option_map_unwrap_or_else, + clippy::print_stdout, + clippy::unicode_not_nfc, + clippy::use_self + ) +)] + +//! This crate contains the `wasmer` API. The `wasmer` API facilitates the efficient, +//! sandboxed execution of [WebAssembly (Wasm)][wasm] modules. +//! +//! Here's an example of the `wasmer` API in action: +//! +//! ``` +//! use wasmer::{Store, Module, Instance, Value, imports}; +//! +//! fn main() -> anyhow::Result<()> { +//! let module_wat = r#" +//! (module +//! (type $t0 (func (param i32) (result i32))) +//! (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) +//! get_local $p0 +//! i32.const 1 +//! i32.add)) +//! "#; +//! +//! let store = Store::default(); +//! let module = Module::new(&store, &module_wat)?; +//! // The module doesn't import anything, so we create an empty import object. +//! let import_object = imports! {}; +//! let instance = Instance::new(&module, &import_object)?; +//! +//! let add_one = instance.exports.get_function("add_one")?; +//! let result = add_one.call(&[Value::I32(42)])?; +//! assert_eq!(result[0], Value::I32(43)); +//! +//! Ok(()) +//! } +//! ``` +//! +//! For more examples of using the `wasmer` API, check out the +//! [Wasmer examples][wasmer-examples]. +//! +//! --------- +//! +//! # Table of Contents +//! +//! - [Wasm Primitives](#wasm-primitives) +//! - [Externs](#externs) +//! - [Functions](#functions) +//! - [Memories](#memories) +//! - [Globals](#globals) +//! - [Tables](#tables) +//! - [Project Layout](#project-layout) +//! - [Engines](#engines) +//! - [Compilers](#compilers) +//! - [Features](#features) +//! +//! +//! # Wasm Primitives +//! In order to make use of the power of the `wasmer` API, it's important +//! to understand the primitives around which the API is built. +//! +//! Wasm only deals with a small number of core data types, these data +//! types can be found in the [`Value`] type. +//! +//! In addition to the core Wasm types, the core types of the API are +//! referred to as "externs". +//! +//! ## Externs +//! An [`Extern`] is a type that can be imported or exported from a Wasm +//! module. +//! +//! To import an extern, simply give it a namespace and a name with the +//! [`imports`] macro: +//! +//! ``` +//! # use wasmer::{imports, Function, Memory, MemoryType, Store, ImportObject}; +//! # fn imports_example(store: &Store) -> ImportObject { +//! let memory = Memory::new(&store, MemoryType::new(1, None, false)).unwrap(); +//! imports! { +//! "env" => { +//! "my_function" => Function::new_native(store, || println!("Hello")), +//! "memory" => memory, +//! } +//! } +//! # } +//! ``` +//! +//! And to access an exported extern, see the [`Exports`] API, accessible +//! from any instance via `instance.exports`: +//! +//! ``` +//! # use wasmer::{imports, Instance, Function, Memory, NativeFunc}; +//! # fn exports_example(instance: &Instance) -> anyhow::Result<()> { +//! let memory = instance.exports.get_memory("memory")?; +//! let memory: &Memory = instance.exports.get("some_other_memory")?; +//! let add: NativeFunc<(i32, i32), i32> = instance.exports.get_native_function("add")?; +//! let result = add.call(5, 37)?; +//! assert_eq!(result, 42); +//! # Ok(()) +//! # } +//! ``` +//! +//! These are the primary types that the `wasmer` API uses. +//! +//! ### Functions +//! There are 2 types of functions in `wasmer`: +//! 1. Wasm functions, +//! 2. Host functions. +//! +//! A Wasm function is a function defined in a WebAssembly module that can +//! only perform computation without side effects and call other functions. +//! +//! Wasm functions take 0 or more arguments and return 0 or more results. +//! Wasm functions can only deal with the primitive types defined in +//! [`Value`]. +//! +//! A Host function is any function implemented on the host, in this case in +//! Rust. +//! +//! Host functions can optionally be created with an environment that +//! implements [`WasmerEnv`]. This environment is useful for maintaining +//! host state (for example the filesystem in WASI). +//! +//! Thus WebAssembly modules by themselves cannot do anything but computation +//! on the core types in [`Value`]. In order to make them more useful we +//! give them access to the outside world with [`imports`]. +//! +//! If you're looking for a sandboxed, POSIX-like environment to execute Wasm +//! in, check out the [`wasmer-wasi`][wasmer-wasi] crate for our implementation of WASI, +//! the WebAssembly System Interface. +//! +//! In the `wasmer` API we support functions which take their arguments and +//! return their results dynamically, [`Function`], and functions which +//! take their arguments and return their results statically, [`NativeFunc`]. +//! +//! ### Memories +//! Memories store data. +//! +//! In most Wasm programs, nearly all data will live in a [`Memory`]. +//! +//! This data can be shared between the host and guest to allow for more +//! interesting programs. +//! +//! ### Globals +//! A [`Global`] is a type that may be either mutable or immutable, and +//! contains one of the core Wasm types defined in [`Value`]. +//! +//! ### Tables +//! A [`Table`] is an indexed list of items. +//! +//! +//! ## Project Layout +//! +//! The Wasmer project is divided into a number of crates, below is a dependency +//! graph with transitive dependencies removed. +//! +//!
+//! +//!
+//! +//! While this crate is the top level API, we also publish crates built +//! on top of this API that you may be interested in using, including: +//! +//! - [wasmer-cache] for caching compiled Wasm modules, +//! - [wasmer-emscripten] for running Wasm modules compiled to the +//! Emscripten ABI, +//! - [wasmer-wasi] for running Wasm modules compiled to the WASI ABI. +//! +//! The Wasmer project has two major abstractions: +//! 1. [Engines][wasmer-engine], +//! 2. [Compilers][wasmer-compiler]. +//! +//! These two abstractions have multiple options that can be enabled +//! with features. +//! +//! ### Engines +//! +//! An engine is a system that uses a compiler to make a WebAssembly +//! module executable. +//! +//! ### Compilers +//! +//! A compiler is a system that handles the details of making a Wasm +//! module executable. For example, by generating native machine code +//! for each Wasm function. +//! +//! +//! ## Features +//! +//! This crate comes in 2 flavors: +//! +//! 1. `sys` +#![cfg_attr(feature = "sys", doc = "(enabled),")] +#![cfg_attr(not(feature = "sys"), doc = "(disabled),")] +//! where `wasmer` will be compiled to a native executable +//! which provides compilers, engines, a full VM etc. +//! 2. `js` +#![cfg_attr(feature = "js", doc = "(enabled),")] +#![cfg_attr(not(feature = "js"), doc = "(disabled),")] +//! where `wasmer` will be compiled to WebAssembly to run in a +//! JavaScript host. +//! +//! Consequently, we can group the features by the `sys` or `js` +//! features. +//! +#![cfg_attr( + feature = "sys", + doc = "### Features for the `sys` feature group (enabled)" +)] +#![cfg_attr( + not(feature = "sys"), + doc = "### Features for the `sys` feature group (disabled)" +)] +//! +//! The default features can be enabled with the `sys-default` feature. +//! +//! The features for the `sys` feature group can be broken down into 2 +//! kinds: features that enable new functionality and features that +//! set defaults. +//! +//! The features that enable new functionality are: +//! - `cranelift` +#![cfg_attr(feature = "cranelift", doc = "(enabled),")] +#![cfg_attr(not(feature = "cranelift"), doc = "(disabled),")] +//! enables Wasmer's [Cranelift compiler][wasmer-cranelift], +//! - `llvm` +#![cfg_attr(feature = "llvm", doc = "(enabled),")] +#![cfg_attr(not(feature = "llvm"), doc = "(disabled),")] +//! enables Wasmer's [LLVM compiler][wasmer-llvm], +//! - `singlepass` +#![cfg_attr(feature = "singlepass", doc = "(enabled),")] +#![cfg_attr(not(feature = "singlepass"), doc = "(disabled),")] +//! enables Wasmer's [Singlepass compiler][wasmer-singlepass], +//! - `wat` +#![cfg_attr(feature = "wat", doc = "(enabled),")] +#![cfg_attr(not(feature = "wat"), doc = "(disabled),")] +//! enables `wasmer` to parse the WebAssembly text format, +//! - `universal` +#![cfg_attr(feature = "universal", doc = "(enabled),")] +#![cfg_attr(not(feature = "universal"), doc = "(disabled),")] +//! enables [the Universal engine][wasmer-universal], +//! - `dylib` +#![cfg_attr(feature = "dylib", doc = "(enabled),")] +#![cfg_attr(not(feature = "dylib"), doc = "(disabled),")] +//! enables [the Dylib engine][wasmer-dylib]. +//! +//! The features that set defaults come in sets that are mutually exclusive. +//! +//! The first set is the default compiler set: +//! - `default-cranelift` +#![cfg_attr(feature = "default-cranelift", doc = "(enabled),")] +#![cfg_attr(not(feature = "default-cranelift"), doc = "(disabled),")] +//! set Wasmer's Cranelift compiler as the default, +//! - `default-llvm` +#![cfg_attr(feature = "default-llvm", doc = "(enabled),")] +#![cfg_attr(not(feature = "default-llvm"), doc = "(disabled),")] +//! set Wasmer's LLVM compiler as the default, +//! - `default-singlepass` +#![cfg_attr(feature = "default-singlepass", doc = "(enabled),")] +#![cfg_attr(not(feature = "default-singlepass"), doc = "(disabled),")] +//! set Wasmer's Singlepass compiler as the default. +//! +//! The next set is the default engine set: +//! - `default-universal` +#![cfg_attr(feature = "default-universal", doc = "(enabled),")] +#![cfg_attr(not(feature = "default-universal"), doc = "(disabled),")] +//! set the Universal engine as the default, +//! - `default-dylib` +#![cfg_attr(feature = "default-dylib", doc = "(enabled),")] +#![cfg_attr(not(feature = "default-dylib"), doc = "(disabled),")] +//! set the Dylib engine as the default. +//! +#![cfg_attr( + feature = "js", + doc = "### Features for the `js` feature group (enabled)" +)] +#![cfg_attr( + not(feature = "js"), + doc = "### Features for the `js` feature group (disabled)" +)] +//! +//! The default features can be enabled with the `js-default` feature. +//! +//! Here are the detailed list of features: +//! +//! - `wasm-types-polyfill` +#![cfg_attr(feature = "wasm-types-polyfill", doc = "(enabled),")] +#![cfg_attr(not(feature = "wasm-types-polyfill"), doc = "(disabled),")] +//! parses the Wasm file, allowing to do type reflection of the +//! inner Wasm types. It adds 100kb to the Wasm bundle (28kb +//! gzipped). It is possible to disable it and to use +//! `Module::set_type_hints` manually instead for a lightweight +//! alternative. This is needed until the [Wasm JS introspection API +//! proposal](https://github.com/WebAssembly/js-types/blob/master/proposals/js-types/Overview.md) +//! is adopted by browsers, +//! - `wat` +#![cfg_attr(feature = "wat", doc = "(enabled),")] +#![cfg_attr(not(feature = "wat"), doc = "(disabled),")] +//! allows to read a Wasm file in its text format. This feature is +//! normally used only in development environments. It will add +//! around 650kb to the Wasm bundle (120Kb gzipped). +//! +//! +//! [wasm]: https://webassembly.org/ +//! [wasmer-examples]: https://github.com/wasmerio/wasmer/tree/master/examples +//! [wasmer-cache]: https://docs.rs/wasmer-cache/*/wasmer_cache/ +//! [wasmer-compiler]: https://docs.rs/wasmer-compiler/*/wasmer_compiler/ +//! [wasmer-cranelift]: https://docs.rs/wasmer-compiler-cranelift/*/wasmer_compiler_cranelift/ +//! [wasmer-emscripten]: https://docs.rs/wasmer-emscripten/*/wasmer_emscripten/ +//! [wasmer-engine]: https://docs.rs/wasmer-engine/*/wasmer_engine/ +//! [wasmer-universal]: https://docs.rs/wasmer-engine-universal/*/wasmer_engine_universal/ +//! [wasmer-dylib]: https://docs.rs/wasmer-engine-dylib/*/wasmer_engine_dylib/ +//! [wasmer-singlepass]: https://docs.rs/wasmer-compiler-singlepass/*/wasmer_compiler_singlepass/ +//! [wasmer-llvm]: https://docs.rs/wasmer-compiler-llvm/*/wasmer_compiler_llvm/ +//! [wasmer-wasi]: https://docs.rs/wasmer-wasi/*/wasmer_wasi/ + #[cfg(all(not(feature = "sys"), not(feature = "js")))] compile_error!("At least the `sys` or the `js` feature must be enabled. Please, pick one."); diff --git a/lib/api/src/sys/externals/memory.rs b/lib/api/src/sys/externals/memory.rs index 0b3617930..b5b6ba5cc 100644 --- a/lib/api/src/sys/externals/memory.rs +++ b/lib/api/src/sys/externals/memory.rs @@ -34,7 +34,7 @@ impl Memory { /// Creates a new host `Memory` from the provided [`MemoryType`]. /// /// This function will construct the `Memory` using the store - /// [`BaseTunables`][crate::tunables::BaseTunables]. + /// [`BaseTunables`][crate::sys::BaseTunables]. /// /// # Example /// diff --git a/lib/api/src/sys/externals/table.rs b/lib/api/src/sys/externals/table.rs index b08917ca3..fd981ac4b 100644 --- a/lib/api/src/sys/externals/table.rs +++ b/lib/api/src/sys/externals/table.rs @@ -38,7 +38,7 @@ impl Table { /// All the elements in the table will be set to the `init` value. /// /// This function will construct the `Table` using the store - /// [`BaseTunables`][crate::tunables::BaseTunables]. + /// [`BaseTunables`][crate::sys::BaseTunables]. pub fn new(store: &Store, ty: TableType, init: Val) -> Result { let item = init.into_table_reference(store)?; let tunables = store.tunables(); diff --git a/lib/api/src/sys/mod.rs b/lib/api/src/sys/mod.rs index ca048b6af..157a26a4a 100644 --- a/lib/api/src/sys/mod.rs +++ b/lib/api/src/sys/mod.rs @@ -1,258 +1,3 @@ -#![doc( - html_logo_url = "https://github.com/wasmerio.png?size=200", - html_favicon_url = "https://wasmer.io/images/icons/favicon-32x32.png" -)] -#![deny( - missing_docs, - trivial_numeric_casts, - unused_extern_crates, - broken_intra_doc_links -)] -#![warn(unused_import_braces)] -#![cfg_attr( - feature = "cargo-clippy", - allow(clippy::new_without_default, vtable_address_comparisons) -)] -#![cfg_attr( - feature = "cargo-clippy", - warn( - clippy::float_arithmetic, - clippy::mut_mut, - clippy::nonminimal_bool, - clippy::option_map_unwrap_or, - clippy::option_map_unwrap_or_else, - clippy::print_stdout, - clippy::unicode_not_nfc, - clippy::use_self - ) -)] - -//! This crate contains the `wasmer` API. The `wasmer` API facilitates the efficient, -//! sandboxed execution of [WebAssembly (Wasm)][wasm] modules. -//! -//! Here's an example of the `wasmer` API in action: -//! ``` -//! use wasmer::{Store, Module, Instance, Value, imports}; -//! -//! fn main() -> anyhow::Result<()> { -//! let module_wat = r#" -//! (module -//! (type $t0 (func (param i32) (result i32))) -//! (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) -//! get_local $p0 -//! i32.const 1 -//! i32.add)) -//! "#; -//! -//! let store = Store::default(); -//! let module = Module::new(&store, &module_wat)?; -//! // The module doesn't import anything, so we create an empty import object. -//! let import_object = imports! {}; -//! let instance = Instance::new(&module, &import_object)?; -//! -//! let add_one = instance.exports.get_function("add_one")?; -//! let result = add_one.call(&[Value::I32(42)])?; -//! assert_eq!(result[0], Value::I32(43)); -//! -//! Ok(()) -//! } -//! ``` -//! -//! For more examples of using the `wasmer` API, check out the -//! [wasmer examples][wasmer-examples]. -//! -//! --------- -//! -//! # Table of Contents -//! -//! - [Wasm Primitives](#wasm-primitives) -//! - [Externs](#externs) -//! - [Functions](#functions) -//! - [Memories](#memories) -//! - [Globals](#globals) -//! - [Tables](#tables) -//! - [Project Layout](#project-layout) -//! - [Engines](#engines) -//! - [Compilers](#compilers) -//! - [Features](#features) -//! -//! -//! # Wasm Primitives -//! In order to make use of the power of the `wasmer` API, it's important -//! to understand the primitives around which the API is built. -//! -//! Wasm only deals with a small number of core data types, these data -//! types can be found in the [`Value`] type. -//! -//! In addition to the core Wasm types, the core types of the API are -//! referred to as "externs". -//! -//! ## Externs -//! An [`Extern`] is a type that can be imported or exported from a Wasm -//! module. -//! -//! To import an extern, simply give it a namespace and a name with the -//! [`imports`] macro: -//! -//! ``` -//! # use wasmer::{imports, Function, Memory, MemoryType, Store, ImportObject}; -//! # fn imports_example(store: &Store) -> ImportObject { -//! let memory = Memory::new(&store, MemoryType::new(1, None, false)).unwrap(); -//! imports! { -//! "env" => { -//! "my_function" => Function::new_native(store, || println!("Hello")), -//! "memory" => memory, -//! } -//! } -//! # } -//! ``` -//! -//! And to access an exported extern, see the [`Exports`] API, accessible -//! from any instance via `instance.exports`: -//! -//! ``` -//! # use wasmer::{imports, Instance, Function, Memory, NativeFunc}; -//! # fn exports_example(instance: &Instance) -> anyhow::Result<()> { -//! let memory = instance.exports.get_memory("memory")?; -//! let memory: &Memory = instance.exports.get("some_other_memory")?; -//! let add: NativeFunc<(i32, i32), i32> = instance.exports.get_native_function("add")?; -//! let result = add.call(5, 37)?; -//! assert_eq!(result, 42); -//! # Ok(()) -//! # } -//! ``` -//! -//! These are the primary types that the `wasmer` API uses. -//! -//! ### Functions -//! There are 2 types of functions in `wasmer`: -//! 1. Wasm functions -//! 2. Host functions -//! -//! A Wasm function is a function defined in a WebAssembly module that can -//! only perform computation without side effects and call other functions. -//! -//! Wasm functions take 0 or more arguments and return 0 or more results. -//! Wasm functions can only deal with the primitive types defined in -//! [`Value`]. -//! -//! A Host function is any function implemented on the host, in this case in -//! Rust. -//! -//! Host functions can optionally be created with an environment that -//! implements [`WasmerEnv`]. This environment is useful for maintaining -//! host state (for example the filesystem in WASI). -//! -//! Thus WebAssembly modules by themselves cannot do anything but computation -//! on the core types in [`Value`]. In order to make them more useful we -//! give them access to the outside world with [`imports`]. -//! -//! If you're looking for a sandboxed, POSIX-like environment to execute Wasm -//! in, check out the [`wasmer-wasi`][wasmer-wasi] crate for our implementation of WASI, -//! the WebAssembly System Interface. -//! -//! In the `wasmer` API we support functions which take their arguments and -//! return their results dynamically, [`Function`], and functions which -//! take their arguments and return their results statically, [`NativeFunc`]. -//! -//! ### Memories -//! Memories store data. -//! -//! In most Wasm programs, nearly all data will live in a [`Memory`]. -//! -//! This data can be shared between the host and guest to allow for more -//! interesting programs. -//! -//! ### Globals -//! A [`Global`] is a type that may be either mutable or immutable, and -//! contains one of the core Wasm types defined in [`Value`]. -//! -//! ### Tables -//! A [`Table`] is an indexed list of items. -//! -//! -//! ## Project Layout -//! -//! The Wasmer project is divided into a number of crates, below is a dependency -//! graph with transitive dependencies removed. -//! -//!
-//! -//!
-//! -//! While this crate is the top level API, we also publish crates built -//! on top of this API that you may be interested in using, including: -//! -//! - [wasmer-cache][] for caching compiled Wasm modules. -//! - [wasmer-emscripten][] for running Wasm modules compiled to the -//! Emscripten ABI. -//! - [wasmer-wasi][] for running Wasm modules compiled to the WASI ABI. -//! -//! -------- -//! -//! The Wasmer project has two major abstractions: -//! 1. [Engines][wasmer-engine] -//! 2. [Compilers][wasmer-compiler] -//! -//! These two abstractions have multiple options that can be enabled -//! with features. -//! -//! ### Engines -//! -//! An engine is a system that uses a compiler to make a WebAssembly -//! module executable. -//! -//! ### Compilers -//! -//! A compiler is a system that handles the details of making a Wasm -//! module executable. For example, by generating native machine code -//! for each Wasm function. -//! -//! -//! ## Features -//! -//! This crate's features can be broken down into 2 kinds, features that -//! enable new functionality and features that set defaults. -//! -//! The features that enable new functionality are: -//! - `universal` - enable the Universal engine. (See [wasmer-universal][]) -//! - `native` - enable the native engine. (See [wasmer-native][]) -//! - `cranelift` - enable Wasmer's Cranelift compiler. (See [wasmer-cranelift][]) -//! - `llvm` - enable Wasmer's LLVM compiler. (See [wasmer-llvm][]) -//! - `singlepass` - enable Wasmer's Singlepass compiler. (See [wasmer-singlepass][]) -//! - `wat` - enable `wasmer` to parse the WebAssembly text format. -//! -//! The features that set defaults come in sets that are mutually exclusive. -//! -//! The first set is the default compiler set: -//! - `default-cranelift` - set Wasmer's Cranelift compiler as the default. -//! - `default-llvm` - set Wasmer's LLVM compiler as the default. -//! - `default-singlepass` - set Wasmer's Singlepass compiler as the default. -//! -//! The next set is the default engine set: -//! - `default-universal` - set the Universal engine as the default. -//! - `default-native` - set the native engine as the default. -//! -//! -------- -//! -//! By default the `wat`, `default-cranelift`, and `default-universal` features -//! are enabled. -//! -//! -//! -//! [wasm]: https://webassembly.org/ -//! [wasmer-examples]: https://github.com/wasmerio/wasmer/tree/master/examples -//! [wasmer-cache]: https://docs.rs/wasmer-cache/*/wasmer_cache/ -//! [wasmer-compiler]: https://docs.rs/wasmer-compiler/*/wasmer_compiler/ -//! [wasmer-cranelift]: https://docs.rs/wasmer-compiler-cranelift/*/wasmer_compiler_cranelift/ -//! [wasmer-emscripten]: https://docs.rs/wasmer-emscripten/*/wasmer_emscripten/ -//! [wasmer-engine]: https://docs.rs/wasmer-engine/*/wasmer_engine/ -//! [wasmer-universal]: https://docs.rs/wasmer-engine-universal/*/wasmer_engine_universal/ -//! [wasmer-native]: https://docs.rs/wasmer-engine-dylib/*/wasmer_engine_dylib/ -//! [wasmer-singlepass]: https://docs.rs/wasmer-compiler-singlepass/*/wasmer_compiler_singlepass/ -//! [wasmer-llvm]: https://docs.rs/wasmer-compiler-llvm/*/wasmer_compiler_llvm/ -//! [wasmer-wasi]: https://docs.rs/wasmer-wasi/*/wasmer_wasi/ - mod cell; mod env; mod exports; @@ -324,7 +69,7 @@ pub use wasmer_types::{ // TODO: should those be moved into wasmer::vm as well? pub use wasmer_vm::{raise_user_trap, MemoryError}; pub mod vm { - //! The vm module re-exports wasmer-vm types. + //! The `vm` module re-exports wasmer-vm types. pub use wasmer_vm::{ Memory, MemoryError, MemoryStyle, Table, TableStyle, VMExtern, VMMemoryDefinition,