WebAssembly 是一个portablesandboxed具有有限、局部、不确定性的平台。
- 有限的非确定性执行只能发生在少数定义明确的情况下(如下所述),在这些情况下,实现可以从有限的一组可能的行为中进行选择。
- 本地的:当非确定性执行发生时,效果是局部的,不存在“远距离的幽灵般的动作”。
该rationale文档详细说明了 WebAssembly 设计的原因。
以下是 WebAssembly 规范当前允许非确定性的位置列表:
- 新功能将添加到 WebAssembly 中,这意味着不同的实现将对每个功能提供不同的支持。这可以检测到
has_feature
,但仍然是执行之间差异的来源。 - [当线程作为一个特性:unicorn:被添加时][未来线程],即使没有共享内存,通过 API 调用的全局序列,不确定性也将是可见的。对于共享内存,加载操作符的结果是不确定的。
- 除非另有指定,否则当算术运算符返回 Nan 时,在确定 Nan 的特定位时存在不确定性。但是,WASM 仍然保证从操作返回的 NaN 值在其分数字段中不会有未在输入操作数的任何 NaN 值中设置的 1 位,但分数字段的最高有效位(大多数运算符将其设置为 1)除外。
- 除非另有指定,否则当具有浮点结果类型的算术运算符未接收到 Nan 输入值而产生 Nan 结果值时,Nan 结果值的符号位是不确定的。
- [固定宽度 SIMD 可能需要一些灵活性:unicorn:][未来 SIMD]
- 在 SIMD.JS 中,浮点值可能会也可能不会将次法线刷新为零。
- 在 SIMD.JS 中,以“近似值”结尾的运算符返回的近似值可能因平台而异。
- 依赖于环境的资源限制可能会耗尽。举几个例子:
- 内存分配可能失败。
- 当第一次访问内存位置(例如,通过加载或存储)时,运行时可能无法分配物理页,即使该内存已由的最大大小属性虚拟保留存储器部分。
- 程序堆栈可能耗尽(例如,因为函数调用深度太大,或函数具有太多局部变量,或无限递归)。请注意,此堆栈并不位于程序可访问的线性内存中。
- 资源(如句柄)可能会耗尽。
- 任何其他资源都可能在任何时候耗尽。“买者自负”。
C、C++ 和类似语言的用户应该意识到,在 WebAssembly 本身中定义或约束行为的操作符可能仍然具有未定义的行为在源代码级别。