soroban_wasmi/
lib.rs

1//! The Wasmi virtual machine definitions.
2//!
3//! These closely mirror the WebAssembly specification definitions.
4//! The overall structure is heavily inspired by the `wasmtime` virtual
5//! machine architecture.
6//!
7//! # Example
8//!
9//! The following example shows a "Hello, World!"-like example of creating
10//! a Wasm module from some initial `.wat` contents, defining a simple host
11//! function and calling the exported Wasm function.
12//!
13//! The example was inspired by
14//! [Wasmtime's API example](https://docs.rs/wasmtime/0.39.1/wasmtime/).
15//!
16//! ```
17//! use anyhow::{anyhow, Result};
18//! use wasmi::*;
19//!
20//! fn main() -> Result<()> {
21//!     // First step is to create the Wasm execution engine with some config.
22//!     // In this example we are using the default configuration.
23//!     let engine = Engine::default();
24//!     let wat = r#"
25//!         (module
26//!             (import "host" "hello" (func $host_hello (param i32)))
27//!             (func (export "hello")
28//!                 (call $host_hello (i32.const 3))
29//!             )
30//!         )
31//!     "#;
32//!     // Wasmi does not yet support parsing `.wat` so we have to convert
33//!     // out `.wat` into `.wasm` before we compile and validate it.
34//!     let wasm = wat::parse_str(&wat)?;
35//!     let module = Module::new(&engine, &mut &wasm[..])?;
36//!
37//!     // All Wasm objects operate within the context of a `Store`.
38//!     // Each `Store` has a type parameter to store host-specific data,
39//!     // which in this case we are using `42` for.
40//!     type HostState = u32;
41//!     let mut store = Store::new(&engine, 42);
42//!     let host_hello = Func::wrap(&mut store, |caller: Caller<'_, HostState>, param: i32| {
43//!         println!("Got {param} from WebAssembly");
44//!         println!("My host state is: {}", caller.data());
45//!     });
46//!
47//!     // In order to create Wasm module instances and link their imports
48//!     // and exports we require a `Linker`.
49//!     let mut linker = <Linker<HostState>>::new(&engine);
50//!     // Instantiation of a Wasm module requires defining its imports and then
51//!     // afterwards we can fetch exports by name, as well as asserting the
52//!     // type signature of the function with `get_typed_func`.
53//!     //
54//!     // Also before using an instance created this way we need to start it.
55//!     linker.define("host", "hello", host_hello)?;
56//!     let instance = linker
57//!         .instantiate(&mut store, &module)?
58//!         .start(&mut store)?;
59//!     let hello = instance.get_typed_func::<(), ()>(&store, "hello")?;
60//!
61//!     // And finally we can call the wasm!
62//!     hello.call(&mut store, ())?;
63//!
64//!     Ok(())
65//! }
66//! ```
67
68#![no_std]
69#![warn(
70    clippy::cast_lossless,
71    clippy::missing_errors_doc,
72    clippy::used_underscore_binding,
73    clippy::redundant_closure_for_method_calls,
74    clippy::type_repetition_in_bounds,
75    clippy::inconsistent_struct_constructor,
76    clippy::default_trait_access,
77    clippy::items_after_statements
78)]
79#![recursion_limit = "750"]
80
81#[cfg(not(feature = "std"))]
82extern crate alloc as std;
83
84#[cfg(feature = "std")]
85extern crate std;
86
87#[macro_use]
88mod foreach_tuple;
89
90mod engine;
91mod error;
92mod externref;
93mod func;
94mod global;
95mod instance;
96mod limits;
97mod linker;
98mod memory;
99mod module;
100mod reftype;
101mod store;
102mod table;
103mod value;
104
105/// Definitions from the `wasmi_core` crate.
106#[doc(inline)]
107pub use wasmi_core as core;
108
109/// Definitions from the `wasmi_collections` crate.
110#[doc(inline)]
111use wasmi_collections as collections;
112
113/// Defines some errors that may occur upon interaction with Wasmi.
114pub mod errors {
115    pub use super::{
116        engine::EnforcedLimitsError,
117        error::ErrorKind,
118        func::FuncError,
119        global::GlobalError,
120        linker::LinkerError,
121        memory::MemoryError,
122        module::{InstantiationError, ReadError},
123        store::FuelError,
124        table::TableError,
125    };
126}
127
128pub use self::{
129    engine::{
130        CompilationMode,
131        Config,
132        EnforcedLimits,
133        Engine,
134        EngineWeak,
135        FuelCosts,
136        ResumableCall,
137        ResumableInvocation,
138        StackLimits,
139        TypedResumableCall,
140        TypedResumableInvocation,
141    },
142    error::Error,
143    externref::ExternRef,
144    func::{
145        Caller,
146        Func,
147        FuncRef,
148        FuncType,
149        IntoFunc,
150        TypedFunc,
151        WasmParams,
152        WasmResults,
153        WasmRet,
154        WasmTy,
155        WasmTyList,
156    },
157    global::{Global, GlobalType, Mutability},
158    instance::{Export, ExportsIter, Extern, ExternType, Instance},
159    limits::{ResourceLimiter, StoreLimits, StoreLimitsBuilder},
160    linker::{state, Linker, LinkerBuilder},
161    memory::{Memory, MemoryType},
162    module::{
163        CustomSection,
164        CustomSectionsIter,
165        ExportType,
166        ImportType,
167        InstancePre,
168        Module,
169        ModuleExportsIter,
170        ModuleImportsIter,
171        Read,
172    },
173    store::{AsContext, AsContextMut, Store, StoreContext, StoreContextMut},
174    table::{Table, TableType},
175    value::Val,
176};
177use self::{
178    func::{FuncEntity, FuncIdx},
179    global::{GlobalEntity, GlobalIdx},
180    instance::{InstanceEntity, InstanceEntityBuilder, InstanceIdx},
181    memory::{DataSegmentEntity, DataSegmentIdx, MemoryEntity, MemoryIdx},
182    store::Stored,
183    table::{ElementSegment, ElementSegmentEntity, ElementSegmentIdx, TableEntity, TableIdx},
184};