File: examples-rust-wasi.md

package info (click to toggle)
rust-wasmtime 27.0.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 53,064 kB
  • sloc: ansic: 4,020; sh: 562; javascript: 542; cpp: 254; asm: 175; ml: 96; makefile: 55
file content (101 lines) | stat: -rw-r--r-- 3,634 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# WASI

You can also [browse this source code online][code] and clone the wasmtime
repository to run the example locally.

[code]: https://github.com/bytecodealliance/wasmtime/blob/main/examples/wasi/main.rs

This example shows how to use the [`wasi-common`] crate to define WASI
functions within a [`Linker`] which can then be used to instantiate a
WebAssembly module.

[`wasi-common`]: https://crates.io/crates/wasi-common
[`Linker`]: https://docs.rs/wasmtime/*/wasmtime/struct.Linker.html

### WebAssembly module source code

For this WASI example, this Hello World program is compiled to a WebAssembly module using the WASI Preview 1 API.

`wasi.rs`
```rust
{{#include ../examples/wasi/wasm/wasi.rs}}
```

Building this program generates `target/wasm32-wasip1/debug/wasi.wasm`, used below.

### Invoke the WASM module

This example shows adding and configuring the WASI imports to invoke the above WASM module.

`main.rs`
```rust,ignore
{{#include ../examples/wasi/main.rs}}
```

## WASI state with other custom host state

The [`add_to_linker`] takes a second argument which is a closure to access `&mut
WasiCtx` from within the `T` stored in the `Store<T>` itself. In the above
example this is trivial because the `T` in `Store<T>` is `WasiCtx` itself, but
you can also store other state in `Store` like so:

[`add_to_linker`]: https://docs.rs/wasi-common/*/wasi_common/sync/fn.add_to_linker.html
[`Store`]: https://docs.rs/wasmtime/*/wasmtime/struct.Store.html
[`BorrowMut<WasiCtx>`]: https://doc.rust-lang.org/stable/std/borrow/trait.BorrowMut.html
[`WasiCtx`]: https://docs.rs/wasi-common/*/wasi_common/struct.WasiCtx.html

```rust
# extern crate wasmtime;
# extern crate wasi_common;
# extern crate anyhow;
use anyhow::Result;
use std::borrow::{Borrow, BorrowMut};
use wasmtime::*;
use wasi_common::{WasiCtx, sync::WasiCtxBuilder};

struct MyState {
    message: String,
    wasi: WasiCtx,
}

fn main() -> Result<()> {
    let engine = Engine::default();
    let mut linker = Linker::new(&engine);
    wasi_common::sync::add_to_linker(&mut linker, |state: &mut MyState| &mut state.wasi)?;

    let wasi = WasiCtxBuilder::new()
        .inherit_stdio()
        .inherit_args()?
        .build();
    let mut store = Store::new(&engine, MyState {
        message: format!("hello!"),
        wasi,
    });

    // ...

# let _linker: Linker<MyState> = linker;
    Ok(())
}
```

## WASI Preview 2

An experimental implementation of the WASI Preview 2 API is also available, along with an adapter layer for  WASI Preview 1 WebAssembly modules. In future this `preview2` API will become the default. There are some features which are currently only accessible through the `preview2` API such as async support and overriding the clock and random implementations.

### Async example

This [async example code][code2] shows how to use the [wasmtime-wasi::preview2][`preview2`] module to
execute the same WASI Preview 1 WebAssembly module from the example above. This example requires the `wasmtime` crate `async` feature to be enabled.

This does not require any change to the WebAssembly module, it's just the WASI API host functions which are implemented to be async. See [wasmtime async support](https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.async_support).

[code2]: https://github.com/bytecodealliance/wasmtime/blob/main/examples/wasi-async/main.rs
[`preview2`]: https://docs.rs/wasmtime-wasi/*/wasmtime_wasi/preview2/index.html

```rust,ignore
{{#include ../examples/wasi-async/main.rs}}
```

You can also [browse this source code online][code2] and clone the wasmtime
repository to run the example locally.