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};