Level 4 有什么新东西

接口全部是 async func

Level 2/3 的宿主接口长这样:

arch: func() -> future<string>;

插件侧要配合一整套 wit_future::new() + wit_bindgen::spawn 的样板,还得小心 「spawn 出去的任务没人 drain」这类坑。

Level 4 直接是:

arch: async func() -> string;

Rust 侧就是普通的 .await

let arch = os::arch().await;

on-load 也是 async func可以直接 await 宿主接口,不必再 block_on

为什么必须这么改

组件模型把 async 记在函数类型上,宿主运行时据此决定一个任务是否允许阻塞 (wasmtime 的规则是 may_block = 函数类型是 async || 已经返回)。如果导出声明成普通 func,插件在里面 await 任何宿主调用都会被直接 trap 掉(CannotBlockSyncTask)。

反过来,只要类型是 async,即使某些语言的工具链只会做同步 lift/lower,也依然被 允许阻塞等待宿主返回——这正是让更多语言能接进来的前提。

WASI Preview 3

Level 4 插件运行在 WASI p3 环境里。宿主同时提供 p2 接口,因为大多数语言的运行时 (wasi-libc、CPython 等)目前仍按 p2 链接标准库,两边都装齐才不会缺导入。

manifest 里声明:

"wasi_version": 3,
"api_level": 4

双运行时共存

Level 2/3 的插件继续跑在原来的 wasmtime 上,Level 4 用新版,两者在同一个进程内共存。 升级 Level 4 不会影响已有插件的行为。

错误信息不再丢失

Level 2/3 里失败是裸 result(Rust 侧 Result<(), ()>),拿不到原因。Level 4 统一成 result<_, string>

match transport::send(&addr, &data).await {
    Ok(()) => {}
    Err(reason) => tracing::warn!("send failed: {reason}"),
}

新增能力

大纲