Top Related Projects
A fast and secure runtime for WebAssembly
WebAssembly System Interface
The WebAssembly Binary Toolkit
Facilitating high-level interactions between Wasm modules and JavaScript
Quick Overview
The wasmi-labs/wasmi
repository is a WebAssembly interpreter written in Rust. It provides a lightweight and efficient way to execute WebAssembly modules within a Rust-based application.
Pros
- Lightweight and Efficient: The Rust-based implementation of the WebAssembly interpreter is designed to be lightweight and efficient, making it suitable for use in resource-constrained environments.
- Extensible: The project is designed to be extensible, allowing developers to add custom host functions and integrate the interpreter into their own applications.
- Cross-platform: The WebAssembly interpreter can be used on a variety of platforms, including Windows, macOS, and Linux.
- Active Development: The project is actively maintained and developed, with regular updates and improvements.
Cons
- Limited Documentation: The project's documentation could be more comprehensive, making it potentially challenging for new users to get started.
- Narrow Scope: The project is focused solely on the WebAssembly interpreter, and does not provide additional features or tools for working with WebAssembly.
- Dependency on Rust: The project is written in Rust, which may be a barrier for developers who are more familiar with other programming languages.
- Potential Performance Overhead: While the Rust-based implementation is designed to be efficient, there may be some performance overhead compared to a native WebAssembly implementation.
Code Examples
Here are a few examples of how to use the wasmi
library:
- Executing a WebAssembly Module:
use wasmi::{ModuleInstance, ModuleRef, NopExternals, RuntimeValue, Trap};
fn main() -> Result<(), Trap> {
let module = wasmi::Module::from_buffer(&[
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60,
0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x04, 0x04, 0x01,
0x70, 0x00, 0x00, 0x05, 0x03, 0x01, 0x00, 0x01, 0x07, 0x0a, 0x01, 0x06,
0x61, 0x64, 0x64, 0x65, 0x72, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00,
0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b,
]);
let instance = ModuleInstance::new(&module, &NopExternals)?.run_start(&mut NopExternals)?;
let adder = instance.export_by_name("adder")?.as_global()?;
let result = adder.get();
println!("Result: {:?}", result);
Ok(())
}
This example demonstrates how to load a WebAssembly module, create an instance of the module, and execute a function within the module.
- Defining Custom Host Functions:
use wasmi::{
Error, Externals, FuncRef, ModuleImportResolver, ModuleInstance, ModuleRef, NopExternals,
RuntimeArgs, RuntimeValue, Trap,
};
struct CustomExternals;
impl Externals for CustomExternals {
fn invoke_index(
&mut self,
index: usize,
args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Trap> {
match index {
0 => {
let a: i32 = args.get(0)?;
let b: i32 = args.get(1)?;
Ok(Some(RuntimeValue::I32(a + b)))
}
Competitor Comparisons
A fast and secure runtime for WebAssembly
Pros of Wasmtime
- Performance: Wasmtime is designed to be a high-performance WebAssembly runtime, with a focus on efficient execution and low overhead.
- Modularity: Wasmtime is built with a modular architecture, allowing for easy integration with other components and the ability to customize the runtime.
- Ecosystem: Wasmtime is part of the Bytecode Alliance, a collaboration of companies and individuals working to improve the WebAssembly ecosystem.
Cons of Wasmtime
- Complexity: Wasmtime is a more complex and feature-rich runtime compared to Wasmi, which may make it more challenging to set up and configure.
- Learning Curve: Developers new to WebAssembly may find the Wasmtime ecosystem and documentation more daunting than the simpler Wasmi.
- Overhead: Wasmtime's focus on performance and features may come with some additional overhead compared to the more lightweight Wasmi.
Code Comparison
Wasmi:
let mut store = Store::new();
let module = Module::from_bytes(&store, &wasm_bytes)?;
let instance = Instance::new(&store, &module, &[])?;
let result = instance.get_export("add")?.get_func().unwrap()(&[42.into(), 24.into()])?;
Wasmtime:
let mut config = Config::new();
let engine = Engine::new(&config);
let module = Module::from_binary(&engine, &wasm_bytes)?;
let mut store = Store::new(&engine);
let instance = Instance::new(&mut store, &module, &[])?;
let result = instance.get_export("add")?.get_func().unwrap()(&mut store, &[42.into(), 24.into()])?;
WebAssembly System Interface
Pros of WebAssembly/WASI
- Provides a standardized interface for WebAssembly modules to interact with the host environment, making it easier to write portable and secure WebAssembly applications.
- Supports a wide range of host environments, including the web, servers, and embedded systems.
- Offers a rich set of system APIs, including file I/O, networking, and process management, allowing WebAssembly modules to perform a wide range of tasks.
Cons of WebAssembly/WASI
- The WASI specification is still evolving, and there may be some inconsistencies or missing features compared to more mature system APIs.
- Adoption of WASI may be slower than some other WebAssembly-related projects, as it requires coordination and agreement among various stakeholders.
- The learning curve for developers who are new to WebAssembly and WASI may be steeper compared to more established technologies.
Code Comparison
wasmi-labs/wasmi
fn execute_module(
module: &Module,
imports: &ModuleImportResolver,
params: &[RuntimeValue],
) -> Result<Vec<RuntimeValue>, Error> {
let mut instance = ModuleInstance::new(module, imports)?;
instance.run_start_function()?;
instance.invoke_export("_start", params)
}
WebAssembly/WASI
fn run_wasm(wasm_bytes: &[u8]) -> Result<(), anyhow::Error> {
let mut store = Store::new(&Engine::default());
let module = Module::new(&store, wasm_bytes)?;
let instance = Instance::new(&module, &imports(&mut store))?;
let start = instance.get_export("_start").unwrap().into_func().unwrap();
start.call(&mut store, &[])?;
Ok(())
}
The WebAssembly Binary Toolkit
Pros of WebAssembly/wabt
- Provides a comprehensive set of tools for working with WebAssembly, including a disassembler, assembler, and interpreter.
- Supports a wide range of WebAssembly features, including the latest version of the specification.
- Offers a well-documented and actively maintained codebase.
Cons of WebAssembly/wabt
- May have a larger codebase and dependencies compared to wasmi-labs/wasmi, which could make it less suitable for certain use cases.
- May have a steeper learning curve for developers unfamiliar with the WebAssembly ecosystem.
Code Comparison
WebAssembly/wabt (wabt_wasm2wat.cc):
void WasmBinaryReader::OnFunctionBody(uint32_t index) {
if (options_->read_debug_names) {
ReadLocalNames(index);
}
stream_->WriteMemoryDump(data_, end_ - data_, "code", index);
ReadFunctionBody(index);
}
wasmi-labs/wasmi (lib.rs):
pub fn execute_module(
module: &Module,
args: &[RuntimeValue],
) -> Result<Vec<RuntimeValue>, Error> {
let mut instance = ModuleInstance::new(module)?;
let main_function = instance.find_export_by_name("main")
.ok_or(Error::Function("main"))?
.as_func()
.ok_or(Error::Function("main"))?;
main_function.invoke(args)
}
Facilitating high-level interactions between Wasm modules and JavaScript
Pros of wasm-bindgen
- Easier Interoperability: wasm-bindgen provides a more seamless integration between Rust and JavaScript, making it easier to call Rust functions from JavaScript and vice versa.
- Automatic Bindings Generation: wasm-bindgen can automatically generate the necessary bindings, reducing the amount of boilerplate code you need to write.
- Improved Developer Experience: wasm-bindgen comes with a set of tools and utilities that enhance the developer experience, such as the ability to generate TypeScript definitions.
Cons of wasm-bindgen
- Increased Complexity: wasm-bindgen adds an additional layer of complexity to the build process, which may be a drawback for some users.
- Potential Performance Impact: The additional abstractions and tooling provided by wasm-bindgen may introduce a small performance overhead compared to a more low-level approach like wasmi.
- Limited Scope: wasm-bindgen is primarily focused on the integration between Rust and JavaScript, while wasmi is a more general-purpose WebAssembly interpreter.
Code Comparison
Here's a brief code comparison between wasm-bindgen and wasmi:
wasm-bindgen (Rust):
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
wasmi (Rust):
fn add(a: i32, b: i32) -> i32 {
a + b
}
The main difference is that wasm-bindgen requires the use of the #[wasm_bindgen]
attribute, which generates the necessary boilerplate code for interoperability with JavaScript. In contrast, wasmi provides a more low-level and flexible approach, allowing you to define your WebAssembly functions directly.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Continuous Integration | Test Coverage | Documentation | Crates.io |
---|---|---|---|
Wasmi - WebAssembly (Wasm) Interpreter
Wasmi is an efficient and lightweight WebAssembly interpreter with a focus on constrained and embedded systems.
Security Audits
Wasmi is suitable for safety critical use cases and has been audited several times already.
Wasmi Version(s) | Auditor | Contractor | Report |
---|---|---|---|
0.36.0 -0.38.0 | Runtime Verification Inc. | Stellar Development Foundation | |
0.31.0 | SRLabs | Parity Technologies |
Distinct Features
The following list states some of the distinct features of Wasmi.
- Simple, correct and deterministic execution of WebAssembly.
- Low-overhead and cross-platform WebAssembly runtime for embedded environments.
- JIT bomb resisting translation.
- Loosely mirrors the Wasmtime API.
- 100% WebAssembly spec testsuite compliance.
- Built-in support for fuel metering.
- Supports the official Wasm C-API.
Usage
Refer to the Wasmi usage guide to learn how properly to use Wasmi.
WebAssembly Proposals
The new Wasmi engine supports a variety of WebAssembly proposals and will support even more of them in the future.
WebAssembly Proposal | Status | Comment |
---|---|---|
mutable-global | â | ⥠0.14.0 . |
saturating-float-to-int | â | ⥠0.14.0 . |
sign-extension | â | ⥠0.14.0 . |
multi-value | â | ⥠0.14.0 . |
bulk-memory | â | ⥠0.24.0 . (#628) |
reference-types | â | ⥠0.24.0 . (#635) |
tail-calls | â | ⥠0.28.0 . (#683) |
extended-const | â | ⥠0.29.0 . (#707) |
multi-memory | â | ⥠0.37.0 . (#1191) |
simd | â | Unlikely to be supported. |
relaxed-simd | â | Unlikely to be supported. Depends on simd . |
function-references | ð | Not yet implemented. (#774) |
gc | ð | Not yet implemented. (#775) |
threads | ð | Not yet implemented. (#777) |
exception-handling | ð | Not yet implemented. (#1037) |
custom-page-sizes | ð | Not yet implemented. (#1197) |
WASI | ð¨âð¬ | Experimental support for WASI (wasip1 ) via the wasmi_wasi crate. |
C-API | ð¨âð¬ | Experimental support for the official Wasm C-API via the wasmi_c_api_impl crate. |
Development
Build & Test
Clone the Wasmi repository and build using cargo
:
git clone https://github.com/wasmi-labs/wasmi.git --recursive
cd wasmi
cargo build
cargo test
Benchmarks
In order to benchmark Wasmi use the following command:
cargo bench
Use translate
, instantiate
, execute
or overhead
filters to only run benchmarks that test performance of Wasm translation, instantiation, execution or miscellaneous overhead respectively, e.g. cargo bench execute
.
Supported Platforms
Wasmi supports a wide variety of architectures and platforms.
- Fore more details see this list of supported platforms for Rust.
- Note: Wasmi can be used in
no_std
embedded environments, thus not requiring the standard library (std
). - Only some platforms are checked in CI and guaranteed to be fully working by the Wasmi maintainers.
License
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Top Related Projects
A fast and secure runtime for WebAssembly
WebAssembly System Interface
The WebAssembly Binary Toolkit
Facilitating high-level interactions between Wasm modules and JavaScript
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot