尝试Wasm和WASI

WebAssembly不是一个局限在Web的东西,Wasm的目标就是使自己成为各个语言的编译目标。仿佛就像GraalVM?在Web以外,WASI使Wasm拥有和操作系统交互的能力,并且是沙盒化的。纯Wasm运行时通常很轻量级,容易想到一个合适的应用场景,即用于编写跨平台软件的可热插拔的插件。这种插件常见的做法是使用Lua或其他脚本,在软件中加入其解释器。而如果使用Wasm运行时+WASI,插件开发者可以自己选择语言编译到Wasm,同时由于沙盒的存在,插件安全性有保证。

尝试一下Wasm+WASI。先使Rust能编译到wasm32-wasi目标:

1
rustup target add wasm32-wasi

Wasm相关的还有另外两个目标,wasm32-unknown-unknownwasm32-unknown-emscripten,前者用于Web,自身不能做IO等与操作系统交互的功能。

Hello World

新建一个Rust项目,写一个Hello World测试标准输出:

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

编译时指定target,用cargo build --target=wasm32-wasi,然后就能在target/wasm32-wasi/debug目录下找到xxx.wasmxxx为项目名。

我这里用Wasmer作运行时,用其CLI直接执行:

1
wasmer run xxx.wasm

输出Hello, world!

文件系统、IO

1
2
3
4
5
6
7
8
use std::{fs::File, io::Write};

fn main() {
let mut f = File::create("/1.txt").unwrap();
let s = "Hello, world!";
f.write_all(s.as_bytes()).unwrap();
}

这里打开的是/下的文件,但是如果这样运行:

1
wasmer run --mapdir /:./ xxx.wasm

这里把VM的/映射到主机的./。于是可以在当前目录下看到1.txtcat之得到Hello world!

网络

对不起还没有,老老实实自行import function进去吧。