2 个版本
0.0.2 | 2024 年 7 月 16 日 |
---|---|
0.0.1 | 2024 年 7 月 14 日 |
30 在 无标准库
每月 256 次下载
165KB
4K SLoC
nowasm
nowasm
是一个使用无 std、无不安全操作和无依赖实现的 WebAssembly 1.0 运行时。
目标是提供一种轻量级的 WebAssembly 运行时,可以嵌入到任何使用 Rust 的地方,特别关注 Wasm-in-Wasm 场景。
直到 v0.1.0 的 TODO 列表
- 添加验证阶段(待定)
- 添加文档注释
- 添加更多测试
支持的扩展
nowasm
支持以下扩展,这些扩展对于使用最新稳定版 Rust 编译器构建的 WebAssembly 二进制文件是必要的。
示例
请执行以下命令以构建以下 "Hello World!" 打印代码(examples/wasm/hello.rs)到一个 WebAssembly 二进制文件:
extern "C" {
fn print(s: *const u8, len: i32);
}
#[no_mangle]
pub fn hello() {
let msg = "Hello, World!\n";
unsafe {
print(msg.as_ptr(), msg.len() as i32);
}
}
然后,您可以通过以下命令执行 hello()
函数
$ cargo run --example call_hello
Hello, World!
examples/call_hello.rs 的代码如下
use nowasm::{Env, HostFunc, Module, Resolve, StdVectorFactory, Val};
pub fn main() {
let wasm_bytes = include_bytes!("../target/wasm32-unknown-unknown/debug/examples/hello.wasm");
let module = Module::<StdVectorFactory>::decode(wasm_bytes).expect("Failed to decode module");
let mut instance = module
.instantiate(Resolver)
.expect("Failed to instantiate module");
instance
.invoke("hello", &[])
.expect("Failed to invoke function");
}
struct Resolver;
impl Resolve for Resolver {
type HostFunc = Print;
fn resolve_func(&self, module: &str, name: &str) -> Option<Self::HostFunc> {
assert_eq!(module, "env");
assert_eq!(name, "print");
Some(Print)
}
}
struct Print;
impl HostFunc for Print {
fn invoke(&mut self, args: &[Val], env: &mut Env) -> Option<Val> {
let ptr = args[0].as_i32().expect("Not a i32") as usize;
let len = args[1].as_i32().expect("Not a i32") as usize;
let msg = std::str::from_utf8(&env.mem[ptr..ptr + len]).expect("Invalid utf8");
print!("{msg}");
None
}
}