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.
Version 0.31.0
has been audited by SRLabs.
Announcement: Transfer of Ownership
As of 2024-02-01, the original owner and maintainer of the Wasmi project, Parity Technologies, has officially transferred ownership of the project to me, Robin Freyler. Read more about this transfer here.
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 | â | Since version 0.14.0 . |
saturating-float-to-int | â | Since version 0.14.0 . |
sign-extension | â | Since version 0.14.0 . |
multi-value | â | Since version 0.14.0 . |
bulk-memory | â | Since version 0.24.0 . (#628) |
reference-types | â | Since version 0.24.0 . (#635) |
simd | â | Unlikely to be supported. |
tail-calls | â | Since version 0.28.0 . (#683) |
extended-const | â | Since version 0.29.0 . (#707) |
function-references | ð | Planned but not yet implemented. (#774) |
gc | ð | Planned but not yet implemented. (#775) |
multi-memory | ð | Planned but not yet implemented. (#776) |
threads | ð | Planned but not yet implemented. (#777) |
relaxed-simd | â | Unlikely to be supported since simd is unlikely to be supported. |
component-model | ð | Planned but not yet implemented. (#897) |
exception-handling | ð | Planned but not yet implemented. (#1037) |
branch-hinting | ð | Planned but not yet implemented. (#1036) |
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
.
We maintain a timeline for benchmarks of every commit to master
that can be viewed here.
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