tinywasm/
lib.rs

1#![no_std]
2#![doc(test(
3    no_crate_inject,
4    attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_assignments, unused_variables))
5))]
6#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
7#![cfg_attr(feature = "nightly", feature(portable_simd))]
8#![forbid(unsafe_code)]
9
10//! A tiny WebAssembly Runtime written in Rust
11//!
12//! `TinyWasm` provides a minimal WebAssembly runtime for executing WebAssembly modules.
13//! It currently supports all features of the WebAssembly MVP specification and is
14//! designed to be easy to use and integrate in other projects.
15//!
16//! ## Features
17//!- **`std`**\
18//!  Enables the use of `std` and `std::io` for parsing from files and streams. This is enabled by default.
19//!- **`logging`**\
20//!  Enables logging using the `log` crate. This is enabled by default.
21//!- **`parser`**\
22//!  Enables the `tinywasm-parser` crate. This is enabled by default.
23//!- **`archive`**\
24//!  Enables pre-parsing of archives. This is enabled by default.
25//!
26//! With all these features disabled, `TinyWasm` only depends on `core`, `alloc` and `libm`.
27//! By disabling `std`, you can use `TinyWasm` in `no_std` environments. This requires
28//! a custom allocator and removes support for parsing from files and streams, but otherwise the API is the same.
29//! Additionally, to have proper error types in `no_std`, you currently need a `nightly` compiler to use the unstable error trait in `core`.
30//!
31//! ## Getting Started
32//! The easiest way to get started is to use the [`Module::parse_bytes`] function to load a
33//! WebAssembly module from bytes. This will parse the module and validate it, returning
34//! a [`Module`] that can be used to instantiate the module.
35//!
36//!
37//! ```rust
38//! use tinywasm::{Store, Module};
39//!
40//! // Load a module from bytes
41//! let wasm = include_bytes!("../../../examples/wasm/add.wasm");
42//! let module = Module::parse_bytes(wasm)?;
43//!
44//! // Create a new store
45//! // Stores are used to allocate objects like functions and globals
46//! let mut store = Store::default();
47//!
48//! // Instantiate the module
49//! // This will allocate the module and its globals into the store
50//! // and execute the module's start function.
51//! // Every ModuleInstance has its own ID space for functions, globals, etc.
52//! let instance = module.instantiate(&mut store, None)?;
53//!
54//! // Get a typed handle to the exported "add" function
55//! // Alternatively, you can use `instance.get_func` to get an untyped handle
56//! // that takes and returns [`WasmValue`]s
57//! let func = instance.exported_func::<(i32, i32), i32>(&mut store, "add")?;
58//! let res = func.call(&mut store, (1, 2))?;
59//!
60//! assert_eq!(res, 3);
61//! # Ok::<(), tinywasm::Error>(())
62//! ```
63//!
64//! For more examples, see the [`examples`](https://github.com/explodingcamera/tinywasm/tree/main/examples) directory.
65//!
66//! ## Imports
67//!
68//! To provide imports to a module, you can use the [`Imports`] struct.
69//! This struct allows you to register custom functions, globals, memories, tables,
70//! and other modules to be linked into the module when it is instantiated.
71//!
72//! See the [`Imports`] documentation for more information.
73
74mod std;
75extern crate alloc;
76
77// log for logging (optional).
78#[cfg(feature = "logging")]
79#[allow(clippy::single_component_path_imports)]
80use log;
81
82// noop fallback if logging is disabled.
83#[cfg(not(feature = "logging"))]
84#[allow(unused_imports, unused_macros)]
85pub(crate) mod log {
86    macro_rules! debug    ( ($($tt:tt)*) => {{}} );
87    macro_rules! info    ( ($($tt:tt)*) => {{}} );
88    macro_rules! error    ( ($($tt:tt)*) => {{}} );
89    pub(crate) use debug;
90    pub(crate) use error;
91    pub(crate) use info;
92}
93
94mod error;
95pub use error::*;
96pub use func::{FuncHandle, FuncHandleTyped};
97pub use imports::*;
98pub use instance::ModuleInstance;
99pub use module::Module;
100pub use reference::*;
101pub use store::*;
102
103mod func;
104mod imports;
105mod instance;
106mod module;
107mod reference;
108mod store;
109
110/// Runtime for executing WebAssembly modules.
111pub mod interpreter;
112pub use interpreter::InterpreterRuntime;
113
114#[cfg(feature = "parser")]
115/// Re-export of [`tinywasm_parser`]. Requires `parser` feature.
116pub mod parser {
117    pub use tinywasm_parser::*;
118}
119
120/// Re-export of [`tinywasm_types`].
121pub mod types {
122    pub use tinywasm_types::*;
123}
124
125#[cold]
126pub(crate) fn cold() {}
127
128pub(crate) fn unlikely(b: bool) -> bool {
129    if b {
130        cold();
131    };
132    b
133}