Rust project promote the wasm32-wasip2 target to Tier 2

Rust project promote the wasm32-wasip2 target to Tier 2

The wasm32-wasip2 target is an extension to wasm32-wasip1 target, originally known as wasm32-wasi. It is the next evolution in the development of WASI (the WebAssembly System Interface) that uses the WebAssembly component model to allow for a standardized set of syscalls that are intended to empower WebAssembly binaries with native host capabilities. This target is cross-compiled. The target supports std fully.

On February 28, 2024, Rust merged the tier 3 target wasm32-wasip2; on July 17, 2024, the target wasm32-wasip2 was promoted to tier 2.

WASI has released two milestone versions, 0.1 and 0.2. They correspond to Rust targets wasm32-wasip1 and wasm32-wasip2 respectively.

WASI Preview 2 represents a major milestone for WASI. It marks the moment when WASI has fully rebased on the Wit IDL and the component model type system and semantics, making it modular, fully virtualizable, and accessible to a wide variety of source languages.

WASI Preview 2 is also known as “WASI 0.2”, and corresponds to versions numbered 0.2.x in Wit packages and related identifiers. It is also known as “WASIp2”, where the “p” stands for either “preview” or “point”.

WASI Preview 2 contains the following APIs:

Proposal Versions
wasi-io 0.2.0
wasi-clocks 0.2.0
wasi-random 0.2.0
wasi-filesystem 0.2.0
wasi-sockets 0.2.0
wasi-cli 0.2.0
wasi-http 0.2.0

What You Need

  • WASI SDK 23.0 or later
  • wasmtime 23.0.1 or later
  • WasmEdge 0.14.0 or later (wasm32-wasip1 only)
  • wasmer 4.3.5 or later (wasm32-wasip1 only)
  • wasmi 0.36.0 or later (No binary packages, requires rust 1.77.0 or newer to compile) (wasm32-wasip1 only)
  • wazero 1.7.3 or later (wasm32-wasip1 only)
  • WebAssembly Micro Runtime 2.1.1 or later (wasm32-wasip1 only)

WASI SDK

Let’s first use the classic Hello World program to test the each WASI implementation:

hello.c

1
2
3
4
5
6
#include <stdio.h>
int main(void)
{
fprintf(stdout, "Hello, World!\n");
return 0;
}

wasm32-wasip1

Generate WASM files for target wasm32-wasip1:

1
2
3
4
5
6
# /opt/wasi-sdk-23/bin/clang -v -Wl,--version --target=wasm32-wasip1

# /opt/wasi-sdk-23/bin/clang --target=wasm32-wasip1 -o hello-p1.wasm hello.c

# file hello-p1.wasm
hello-p1.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)

All 6 WASI implementations used in this article support the target wasm32-wasip1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# wasmtime hello-p1.wasm
Hello, World!

# wasmedge hello-p1.wasm
Hello, World!

# wasmer hello-p1.wasm
Hello, World!

# wasmi_cli hello-p1.wasm
Hello, World!

# wazero run hello-p1.wasm
Hello, World!

# iwasm hello-p1.wasm
Hello, World!

wasm32-wasip2

Generate WASM files for target wasm32-wasip2:

1
2
3
4
5
6
# /opt/wasi-sdk-23/bin/clang -v -Wl,--version --target=wasm32-wasip2

# /opt/wasi-sdk-23/bin/clang --target=wasm32-wasip2 -o hello-p2.wasm hello.c

# file hello-p2.wasm
hello-p2.wasm: WebAssembly (wasm) binary module version 0x1000d

wasmtime

Earlier versions of wasmtime would report an error:

1
2
# wasmtime hello-p2.wasm
Error: cannot execute a component without `--wasm component-model`

The new version of wasmtime has no problem:

1
2
# wasmtime hello-p1.wasm
Hello, World!

wasmedge

wasmedge runs with an error, requiring component model support to be enabled:

1
2
3
4
5
6
# wasmedge hello-p2.wasm
[error] loading failed: illegal opcode, Code: 0x117
[error] This instruction or syntax requires enabling Component Model proposal
[error] Bytecode offset: 0x00000004
[error] At AST node: component
[error] File name: "hello-p2.wasm"

In fact, it is still unsuccessful to enable support for the component model:

1
2
3
4
5
6
7
8
9
root@wsl2-leap:~# wasmedge --enable-component hello-p2.wasm
[warning] component model is enabled, this is experimental.
[warning] component model is an experimental proposal
[error] Might an invalid wasm file
[error] loading failed: magic header not detected, Code: 0x103
[error] Bytecode offset: 0x000410a9
[error] At AST node: component
[error] At AST node: component
[error] File name: "hello-p2.wasm"

wasmer

wasmer does not support WASI 0.2 yet:

1
2
3
# wasmer run hello-p2.wasm
error: Unable to compile "hello-p2.wasm"
╰─▶ 1: compile error

wasmi

wasmi does not support WASI 0.2 yet:

1
2
# wasmi_cli hello-p2.wasm
Error: failed to parse and validate Wasm module "hello-p2.wasm": unknown binary version: 0xd, note: the WebAssembly component model feature is not enabled (at offset 0x0)

wazero

wazero does not support WASI 0.2 yet:

1
2
# wazero run hello-p2.wasm
error compiling wasm binary: invalid version header

WebAssembly Micro Runtime

WebAssembly Micro Runtime does not support WASI 0.2 yet:

1
2
# iwasm hello-p2.wasm
WASM module load failed: unknown binary version

Rust

Let’s test each WASI implementation with a Rust implementation of the classic Hello World program:

hello.rs

1
2
3
fn main() {
println!("Hello, World!");
}

wasm32-wasip1

Generate WASM files for target wasm32-wasip1:

1
2
3
4
# rustc -v --target wasm32-wasip1 -o hello-p1.wasm hello.rs

# file hello-p1.wasm
hello-p1.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)

All 6 WASI implementations used in this article support the target wasm32-wasip1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# wasmtime hello-p1.wasm
Hello, World!

# wasmedge hello-p1.wasm
Hello, World!

# wasmer hello-p1.wasm
Hello, World!

# wasmi_cli hello-p1.wasm
Hello, World!

# wazero run hello-p1.wasm
Hello, World!

# iwasm hello-p1.wasm
Hello, World!

wasm32-wasip2

Generate WASM files for target wasm32-wasip2:

1
2
3
4
# rustc -v --target wasm32-wasip1 -o hello-p1.wasm hello.rs

# file hello-p1.wasm
hello-p1.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)

Wrapping Up

The component model is expected to add future and stream keywords, which will provide integrated and composable async functionality. WASI Preview 3 is planned to be a major revision of the Preview 2 APIs using these new features in place of wasi-io‘s streams and polling interfaces. It’s also expected to incorporate lessons learned from implementation and user experience with Preview 2.

When Preview 3 is launched, implementations may continue to support Preview 2, either by implementing Preview 3 along side it, or by virtualizing (polyfilling) Preview 2 in terms of Preview 3.

The release criteria of Preview 3 will include that performance will be measured and addressed.

Reference