7 个版本

0.3.0 2024 年 7 月 23 日
0.2.0 2024 年 2 月 27 日
0.1.4 2023 年 10 月 27 日
0.1.3 2023 年 9 月 25 日
0.1.1 2023 年 3 月 28 日

#533 in WebAssembly

Download history 113/week @ 2024-04-21 11/week @ 2024-04-28 112/week @ 2024-07-21 102/week @ 2024-07-28

每月 214 次下载
用于 wasefire-scheduler

Apache-2.0 协议

160KB
4K SLoC

具有可自定义的大小和性能之间权衡的 WebAssembly 解释器。

该包的主要概念包括

  • Store 包含实例化的模块并允许执行。请注意,在同一存储器中执行必须遵循堆栈行为。可以在运行函数 "foo" 时调用函数 "bar":"bar" 将暂时中断 "foo" 直到 "bar" 返回,此时 "foo" 将恢复。这是为了避免在同一实例中破坏堆栈。一旦 WebAssembly 线程提议落地,此限制可能被取消。

  • Module 代表一个有效的模块。只有有效的模块才能被实例化。模块只是一个包含 WebAssembly 模块二进制格式的字节切片。

  • RunResult 代表了(可能为部分)执行的结果。当从一个存储器中的实例调用导出函数,或者当在调用宿主程序后恢复执行时,会返回一个 RunResult,提供下一个调用宿主程序或最近调用的函数是否终止及其结果。

示例

有关具体的 "hello" 示例,请参阅 examples/hello.rs,它概述了使用此包的最重要的步骤。否则,这里有一些简短的摘录

可以使用 Default 特性创建存储器

let mut store = Store::default();

在存储器中链接宿主函数使用 [Store::link_func()]

store.link_func("env", "add", 2, 1)?;

在存储中实例化一个有效的模块使用 [Store::instantiate()]

let inst = store.instantiate(module, memory)?;

调用实例导出的函数使用 [Store::invoke()]

let mut result = store.invoke(inst, "mul", vec![Val::I32(13), Val::I32(29)])?;

处理对主机的调用使用 CallRunResult::Host

loop {
    let mut call = match result {
        RunResult::Done(results) => return Ok(results),
        RunResult::Host(call) => call,
    };
    let results = process(&mut call)?;
    result = call.resume(&results)?;
}

原子支持

此crate使用原子操作,并依赖于 portable-atomic crate 以支持没有原子操作的架构。根据您的架构,您可能需要以下之一

  • 启用 portable-atomic/critical-section 功能(可能需要添加对 portable-atomic 的直接依赖)。

  • 设置 rustc 标志 --cfg=portable_atomic_unsafe_assume_single_core

您可以在 portable-atomic文档 中找到更多信息。

依赖项

~1.1–1.7MB
~36K SLoC