An open API service indexing awesome lists of open source software.

https://github.com/sile/nowasm

No-std, no-unsafe and no-dependencies WebAssembly 1.0 runtime for Rust
https://github.com/sile/nowasm

nostd rust webassembly webassembly-runtime

Last synced: 6 months ago
JSON representation

No-std, no-unsafe and no-dependencies WebAssembly 1.0 runtime for Rust

Awesome Lists containing this project

README

          

nowasm
======

[![nowasm](https://img.shields.io/crates/v/nowasm.svg)](https://crates.io/crates/nowasm)
[![Documentation](https://docs.rs/nowasm/badge.svg)](https://docs.rs/nowasm)
[![Actions Status](https://github.com/sile/nowasm/workflows/CI/badge.svg)](https://github.com/sile/nowasm/actions)
![License](https://img.shields.io/crates/l/nowasm)

`nowasm` is a [WebAssembly 1.0][wasm-core-1] runtime that is implemented with no-std, no-unsafe and no-dependencies.

The goal is to provide a lightweight WebAssembly runtime that can be embedded wherever Rust is used, with a particular focus on Wasm-in-Wasm scenarios.

[wasm-core-1]: https://www.w3.org/TR/wasm-core-1/

TODO list until v0.1.0
----------------------

- [ ] Add validation phase (TBD)
- [ ] Add doc comments
- [ ] Add more tests

Supported Extensions
--------------------

`nowasm` supports the following extensions necessary to run WebAssembly binaries built with the latest stable Rust compiler.
- [sign-extension]

[sign-extension]: https://github.com/WebAssembly/sign-extension-ops/blob/master/proposals/sign-extension-ops/Overview.md

Examples
--------

Please execute the command `$ cargo build --target wasm32-unknown-unknown --example hello` to build the following "Hello World!" printing code ([examples/wasm/hello.rs](examples/wasm/hello.rs)) into a WebAssembly binary:

```rust
extern "C" {
fn print(s: *const u8, len: i32);
}

#[no_mangle]
pub fn hello() {
let msg = "Hello, World!\n";
unsafe {
print(msg.as_ptr(), msg.len() as i32);
}
}
```

Then, you can execute the `hello()` function via the following command:
```console
$ cargo run --example call_hello
Hello, World!
```

The code of [examples/call_hello.rs](examples/call_hello.rs) is as follows:
```rust
use nowasm::{Env, HostFunc, Module, Resolve, StdVectorFactory, Val};

pub fn main() {
let wasm_bytes = include_bytes!("../target/wasm32-unknown-unknown/debug/examples/hello.wasm");

let module = Module::::decode(wasm_bytes).expect("Failed to decode module");

let mut instance = module
.instantiate(Resolver)
.expect("Failed to instantiate module");

instance
.invoke("hello", &[])
.expect("Failed to invoke function");
}

struct Resolver;

impl Resolve for Resolver {
type HostFunc = Print;

fn resolve_func(&self, module: &str, name: &str) -> Option {
assert_eq!(module, "env");
assert_eq!(name, "print");
Some(Print)
}
}

struct Print;

impl HostFunc for Print {
fn invoke(&mut self, args: &[Val], env: &mut Env) -> Option {
let ptr = args[0].as_i32().expect("Not a i32") as usize;
let len = args[1].as_i32().expect("Not a i32") as usize;
let msg = std::str::from_utf8(&env.mem[ptr..ptr + len]).expect("Invalid utf8");
print!("{msg}");
None
}
}
```