Avatar

WebAssembly (WASM) 的确定性分析

Oct 13, 2025 · 5min

#Deterministic #WASM

WASM (WebAssembly) 本身并不完全保证确定性行为(deterministic behavior)。它是一种平台无关、沙箱安全的字节码格式,可作为多语言的编译目标。

WASM 的确定性分析

特性是否 deterministic说明
数学运算(整数)✅ 是行为固定、无副作用
浮点运算(默认)❌ 可能不是因为 IEEE 754 中如 NaN 表现、舍入方式在不同平台可能略有差异
内存访问✅ 是线性内存、边界检查明确
I/O 操作❌ 不是原生 Wasm 没有 I/O,依赖宿主环境(如 JS/操作系统)提供接口,因此不确定
多线程、并发执行❌ 不是线程调度可能非确定性,除非显式同步或禁用线程
外部函数调用(imports)❌ 依赖宿主外部函数的行为由宿主定义,不受 Wasm 控制

实现确定性的方向

针对上述情况,可以从以下几个方向着手:

  1. 禁用浮点或使用软浮点实现 替代平台相关的硬件浮点操作,保证跨平台一致性。

  2. 不允许非确定性系统调用 比如 Date.now()、随机数、文件系统访问,这些必须从宿主侧显式注入。

  3. 限制外部导入函数(imports)

    Note

    WARM 中已经解决。 所有导入函数必须有严格的接口定义和行为规范。

  4. 运行在特定的 deterministic runtime 中 例如,区块链中的 deterministic wasm VM(如 Polkadot 的 wasmi,EOS 的 eos-vm)。

  5. 编译器层面控制 比如使用 Rust 编译成 Wasm 时,可以启用 --deterministic 或关闭不稳定特性。

IWASM (Interpreter for WebAssembly)

特性是否 deterministic说明
整数运算、内存访问✅ 是严格遵循 Wasm 规范,行为一致
浮点支持⚠️ 否(部分平台可能有差异)虽然 iwasm 遵循 IEEE 754,但不同硬件浮点实现仍可能有微差异,尤其是 NaN 表现
I/O 操作❌ 否通过 Host functions 提供,可能依赖主机环境
Host imports❌ 否开发者自定义,必须小心保证行为一致
多线程❌ 否WAMR 支持多实例运行,但不是为了并发线程设计
可配置性✅ 是可配置以屏蔽或禁用不确定行为,比如关闭浮点支持、限制 imports

如何让 iwasm 更 deterministic?

  1. 禁止/禁用浮点操作
    • 编译时用 -disable-fp 或禁止浮点指令集。
  2. 不允许使用系统随机数、时间等非确定性功能
    • 不要引入如 clock_gettime, rand, gettimeofday 等。
  3. Host functions 明确定义并强制规范化行为
    • 不允许不同平台表现不一致。
  4. 使用 AOT 模式编译为统一平台的中间代码
    • 防止解释器行为偏差。
  5. 使用内置的 sandbox host 环境
    • 比如通过 iwasm 的 WASI 支持,仅允许有限功能。
>