#wasm-component #wasm-interface #run-time #model

wasm_component_layer

适用于任何后端的 WebAssembly 组件模型实现

19 个版本

0.1.18 2024 年 8 月 2 日
0.1.17 2024 年 5 月 24 日
0.1.16 2024 年 2 月 25 日
0.1.15 2024 年 1 月 5 日
0.1.7 2023 年 8 月 30 日

561WebAssembly 中排名

Download history 247/week @ 2024-04-23 173/week @ 2024-05-21 5/week @ 2024-05-28 1/week @ 2024-06-04 9/week @ 2024-07-02 169/week @ 2024-07-30 14/week @ 2024-08-06

每月 183 次下载
用于 模块化

Apache-2.0

345KB
7K SLoC

wasm_component_layer

Crates.io Docs.rs Unsafe Forbidden

wasm_component_layer 是一个与运行时无关的 WebAssembly 组件模型 实现。它支持在任何 WebAssembly 后端上加载和链接 WASM 组件,在运行时检查和生成组件接口类型等。实现基于 wasmtimejs-component-bindgenwit-parser 包。

使用方法

要使用 wasm_component_layer,需要一个运行时。 wasm_runtime_layer 包提供了用于 WebAssembly 运行时的通用接口,因此在使用此包时,还必须在 Cargo.toml 文件中添加此包,并选择合适的运行时。例如,此存储库中的示例使用 wasmi_runtime_layer 运行时

wasm_component_layer = "0.1.16"
wasmi_runtime_layer = "0.31.0"
# wasmtime_runtime_layer = "21.0.0"
# js_wasm_runtime_layer = "0.4.0"

以下是对 wasm_component_layer API 的小型概述。完整的示例可以在 示例文件夹 中找到。考虑以下 WIT 的 WASM 组件

package test:guest

interface foo {
    // Selects the item in position n within list x
    select-nth: func(x: list<string>, n: u32) -> string
}

world guest {
    export foo
}

该组件可以加载到 wasm_component_layer 中,并按以下方式调用

use wasm_component_layer::*;

// The bytes of the component.
const WASM: &[u8] = include_bytes!("single_component/component.wasm");

pub fn main() {
    // Create a new engine for instantiating a component.
    let engine = Engine::new(wasmi_runtime_layer::Engine::default());

    // Create a store for managing WASM data and any custom user-defined state.
    let mut store = Store::new(&engine, ());

    // Parse the component bytes and load its imports and exports.
    let component = Component::new(&engine, WASM).unwrap();
    // Create a linker that will be used to resolve the component's imports, if any.
    let linker = Linker::default();
    // Create an instance of the component using the linker.
    let instance = linker.instantiate(&mut store, &component).unwrap();

    // Get the interface that the interface exports.
    let interface = instance.exports().instance(&"test:guest/foo".try_into().unwrap()).unwrap();
    // Get the function for selecting a list element.
    let select_nth = interface.func("select-nth").unwrap().typed::<(Vec<String>, u32), String>().unwrap();

    // Create an example list to test upon.
    let example = ["a", "b", "c"].iter().map(ToString::to_string).collect::<Vec<_>>();

    println!("Calling select-nth({example:?}, 1) == {}", select_nth.call(&mut store, (example.clone(), 1)).unwrap());
    // Prints 'Calling select-nth(["a", "b", "c"], 1) == b'
}

支持的功能

wasm_component_layer 支持以下主要功能

  • 解析和实例化 WASM 组件二进制文件
  • 在运行时生成组件接口类型
  • 专门的列表类型以加快提升/降低速度
  • 组件接口类型的结构相等,如规范所规定
  • 支持客座资源
  • 支持具有析构函数的强类型主机资源

以下功能尚未实现

  • 字符串转码器
  • 用于生成主机绑定的宏
  • 更全面的测试
  • 子类型

可选特性

serde - 允许序列化标识符、类型和值。请注意,不允许序列化资源,因为资源可能绑定到特定的实例。

示例

# EXAMPLE_NAME: [single_component|resource|multilevel_resource|...]

# build example wasm file
cd examples/EXAMPLE_NAME # cd examples/single_component
rustup toolchain install nightly
rustup override set nightly
cargo build
wasm-tools component new target/wasm32-unknown-unknown/debug/component_example.wasm -o component.wasm
wasm-tools print component.wasm -o component.wat

# run example in host implementation
cd ../../
cargo run --example EXAMPLE_NAME # cargo run --example single_component

依赖

~13MB
~238K SLoC