25 个版本 (9 个重大更新)

0.9.2 2020 年 10 月 6 日
0.9.1 2020 年 4 月 10 日
0.8.0 2020 年 4 月 4 日
0.1.0 2020 年 3 月 31 日

#819 in WebAssembly


用于 wq

MIT/Apache

230KB
4K SLoC

watson

docs.rs docs

一个基于 官方规范 的,基于 Rust 的极简 no_std + alloc WebAssembly 解析器/编译器

  • 支持所有节类型
  • 查找内容的辅助函数
  • 支持编译为 wasm
  • .wast 解析和断言
  • 通过核心 WebAssembly 规范测试
  • 解释器
  • WASI 模拟器
  • lofi wasm 模式(即 i32 只支持)
[dependencies]
watson = "0.9"

解析 WebAssembly 模块

use  watson::*;

let program = watons::parse(&bytes_of_wasm)?;
for s in program.sections.iter() {
   match s {
      CodeSection(code)=> ...,
      ...
   }
}
...

编写解释器

正在进行中

async fn run(program: impl InterpretableProgram) -> Result<Vec<WasmValue>, &'static str> {
    let mut interpreter = Interpreter::new(program)?;
    let mut executor = interpreter.call("main", &[])?;
    loop {
        let execution_unit = executor.next_operation()?;
        let response = match execution_unit {
            // if an import is called, figure out what to do
            ExecutionUnit::CallImport(x) => {
                if x.name == "print" {
                    let start = x.params[0].to_i32() as usize;
                    let mem = match executor.memory() {
                        Some(m) => m,
                        None => return Err("there should be memory"),
                    };
                    let mem = mem.borrow();
                    let mut chars = vec![];
                    let mut i = 0;
                    loop {
                        if mem[start + i] == 0 {
                            break;
                        }
                        chars.push(mem[start + i]);
                        i += 1;
                    }
                    let text = from_utf8(&chars).unwrap();
                    println!("{}", text);
                    ExecutionResponse::DoNothing
                } else if x.name == "sleep" {
                    let millis = x.params[0].to_i32();
                    task::sleep(Duration::from_millis(millis as u64)).await;
                    ExecutionResponse::DoNothing
                } else {
                    panic!("unknown import call")
                }
            }
            // if there's nothing left to do, break out of loop
            ExecutionUnit::Complete(v) => break Ok(v),
            // handle other execution units with default behavior
            mut x @ _ => x.evaluate()?,
        };
        executor.execute(response)?;
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    let args: Vec<String> = env::args().collect();
    if args.len() == 2 {
        let buffer = fs::read(&args[1])?;
        let program = watson::parse(&buffer)?;
        task::block_on(run(program))?;
    } else {
        eprintln!("sleepyprint <app.wasm>");
        exit(1);
    }
    Ok(())
}

许可证

本项目采用 Apache License 2.0 或 MIT 许可证。

任选其一。

贡献

除非你明确表示,否则任何有意提交给 watson 的贡献,根据 Apache-2.0 许可证定义,均将采用上述双重许可,无需附加条款或条件。

依赖关系

~0.6–1.2MB
~26K SLoC