Skip to content

Commit

Permalink
Add support for WASI based on Wasmtime's implementation (#557)
Browse files Browse the repository at this point in the history
* implemented wasm-wasi based on wasmtimes impl

* made suggested changes

* renamed arguments to funcs in the impl_add_to_linker_for_funcs macro and added docs

* fixed ci failures

* modified rust.yml and removed dep wasmi_core

* modified rust.yml
  • Loading branch information
OLUWAMUYIWA authored Nov 12, 2022
1 parent 53eac5c commit 23df536
Show file tree
Hide file tree
Showing 10 changed files with 625 additions and 4 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --lib --no-default-features --target thumbv7em-none-eabi --exclude wasmi_cli
args: --workspace --lib --no-default-features --target thumbv7em-none-eabi --exclude wasmi_cli --exclude wasmi_wasi
- name: Build (wasm32)
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --no-default-features --target wasm32-unknown-unknown
args: --workspace --no-default-features --target wasm32-unknown-unknown --exclude wasmi_wasi

test:
name: Test
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["crates/arena", "crates/cli", "crates/core", "crates/wasmi"]
members = ["crates/arena", "crates/cli", "crates/core", "crates/wasmi", "crates/wasi"]
exclude = []
resolver = "2"

Expand Down
16 changes: 16 additions & 0 deletions crates/wasi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "wasmi_wasi"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

wasi-common = "2.0.1"
wasi-cap-std-sync = "2.0.1"
wiggle = "2.0.0"
wasmi = { version = "0.20.0", path = "../wasmi" }

[dev-dependencies]
wat = "1.0.50"
14 changes: 14 additions & 0 deletions crates/wasi/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub mod snapshots;

pub use snapshots::preview_1::define_wasi;
pub use wasi_cap_std_sync::{
clocks,
dir::Dir,
file::{filetype_from, get_fd_flags, File},
net,
sched,
stdio,
WasiCtxBuilder,
};
pub use wasi_common::{Error, WasiCtx, WasiDir, WasiFile};
pub use wasmi::Linker;
1 change: 1 addition & 0 deletions crates/wasi/src/snapshots/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod preview_1;
513 changes: 513 additions & 0 deletions crates/wasi/src/snapshots/preview_1.rs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions crates/wasi/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod wasi_wat;
47 changes: 47 additions & 0 deletions crates/wasi/tests/wasi_wat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use wasi_cap_std_sync::WasiCtxBuilder;
use wasmi::{Config, Extern, Instance, Store};
use wasmi_wasi::{define_wasi, WasiCtx};

pub fn load_instance_from_wat(wat_bytes: &[u8]) -> (wasmi::Store<WasiCtx>, wasmi::Instance) {
let wasm = wat2wasm(wat_bytes);
let config = Config::default();
let engine = wasmi::Engine::new(&config);
let module = wasmi::Module::new(&engine, &wasm[..]).unwrap();
let mut linker = <wasmi::Linker<WasiCtx>>::default();
// add wasi to linker
let wasi = WasiCtxBuilder::new()
.inherit_stdio()
.inherit_args()
.unwrap()
.build();
let mut store = wasmi::Store::new(&engine, wasi);

define_wasi(&mut linker, &mut store, |ctx| ctx).unwrap();
let instance = linker
.instantiate(&mut store, &module)
.unwrap()
.start(&mut store)
.unwrap();
(store, instance)
}

/// Converts the `.wat` encoded `bytes` into `.wasm` encoded bytes.
pub fn wat2wasm(bytes: &[u8]) -> Vec<u8> {
wat::parse_bytes(bytes).unwrap().into_owned()
}

fn load() -> (Store<WasiCtx>, Instance) {
let bytes = include_bytes!("wat/hello_world.wat");
load_instance_from_wat(bytes)
}

#[test]
fn test_hello_world() {
let (mut store, instance) = load();
let f = instance
.get_export(&store, "_start")
.and_then(Extern::into_func)
.unwrap();
let mut result = [];
f.call(&mut store, &[], &mut result).unwrap();
}
29 changes: 29 additions & 0 deletions crates/wasi/tests/wat/hello_world.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
;; copied (and slightly adapted) from [wasmtime tutorial](https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-tutorial.md)

(module
;; Import the required fd_write WASI function which will write the given io vectors to stdout
;; The function signature for fd_write is:
;; (File Descriptor, *iovs, iovs_len, nwritten) -> Returns number of bytes written
(import "wasi_snapshot_preview1" "fd_write" (func $fd_write (param i32 i32 i32 i32) (result i32)))

(memory 1)
(export "memory" (memory 0))

;; Write 'hello world\n' to memory at an offset of 8 bytes
;; Note the trailing newline which is required for the text to appear
(data (i32.const 8) "hello world\n")

(func $main (export "_start")
;; Creating a new io vector within linear memory
(i32.store (i32.const 0) (i32.const 8)) ;; iov.iov_base - This is a pointer to the start of the 'hello world\n' string
(i32.store (i32.const 4) (i32.const 12)) ;; iov.iov_len - The length of the 'hello world\n' string

(call $fd_write
(i32.const 1) ;; file_descriptor - 1 for stdout
(i32.const 0) ;; *iovs - The pointer to the iov array, which is stored at memory location 0
(i32.const 1) ;; iovs_len - We're printing 1 string stored in an iov - so one.
(i32.const 20) ;; nwritten - A place in memory to store the number of bytes written
)
drop ;; Discard the number of bytes written from the top of the stack
)
)
2 changes: 1 addition & 1 deletion scripts/run-local-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cargo +nightly fmt &&
echo " Building ..." &&
cargo +stable build --workspace &&
echo " Building no_std ..." &&
cargo +stable build --workspace --exclude wasmi_cli --no-default-features --target thumbv7em-none-eabi &&
cargo +stable build --workspace --exclude wasmi_cli --exclude wasmi_wasi --no-default-features --target thumbv7em-none-eabi &&
echo " Clippy ..." &&
cargo +stable clippy --workspace -- -D warnings &&
echo " Docs ..." &&
Expand Down

0 comments on commit 23df536

Please sign in to comment.