SpaceWASM:NASA/JPL 用于航天器序列化的 WebAssembly 解释器
摘要
SpaceWASM 是一个来自 NASA/JPL 的开源 WebAssembly 解释器,专为航天器机载序列化设计,注重确定性内存使用和在资源受限环境下的流式处理能力。
查看缓存全文
缓存时间: 2026/07/09 07:41
nasa/spacewasm
来源:https://github.com/nasa/spacewasm
SpaceWASM
CI(https://github.com/nasa/spacewasm/actions/workflows/ci.yml) codecov(https://codecov.io/gh/nasa/spacewasm)
SpaceWASM 是 WASM 1.0(https://webassembly.github.io/spec/versions/core/WebAssembly-1.0.pdf)规范的一种实现,用于在航天器上解释执行 WASM 二进制代码。该软件包含两大主要组件:
-
解码器/验证器:
以块的形式读取 WASM 二进制代码,并将其解码为可执行形式。解码器使用固定大小的内存,其用量可通过在轨执行前使用
spacewasm-check可执行程序测量。WebAssembly 的解码与验证同时进行,无需对字节码进行额外遍历。
-
解释器:
一个 WASM 解释器,可操作线性内存,并与嵌入环境提供的钩子对接。
SpaceWASM 不直接执行 WebAssembly 字节码。Wasm 字节码本身体积小、结构适合快速验证,但因此直接执行效率较低。在解码 Wasm 指令的过程中,SpaceWASM 将字节码转换为另一种更适合解释执行的中间表示(IR)。IR 的更多信息请参见规范文档。
嵌入
嵌入解释器指的是实例化它,并为模块导入的函数提供实现。通常,模块导入的函数集合是固定的,应在编译时为 WASM 模块及嵌入方共同指定。
动态分配
SpaceWASM 采用独特的动态内存分配模型。其设计均源于常见飞行软件标准所提出的要求。动态分配遵循以下规则:
- 所有分配基于固定大小的块(称为_页_)进行离散分配。
- 释放操作不能在分配之前进行。
- 页内的子区域不能增长或缩小,大小需提前固定。
- 内存使用必须是确定性的。
- 任何分配失败_不得_导致程序 panic。
即使使用自定义分配器,标准 Rust 分配(https://doc.rust-lang.org/alloc/)也无法满足上述约束。因此,SpaceWASM 提供了自己的数据结构来保证这些性质。你会发现这些数据结构是唯一使用 unsafe Rust 语义的地方。
流式处理
_峰值_内存使用量通常是航天器小型系统的重要约束。许多 WASM 解释器要求一次性将整个 WASM 二进制文件以线性块形式提供给解释器。对于可以复用相同内存区域用于不同目的的系统来说,这通常没问题。但航天器上的飞行软件通常为特定用途分配固定的内存区域,因此要求整个 WASM 二进制文件适配单个内存块不可行。
SpaceWASM 高度优化以降低峰值内存使用,并且不要求在流式处理所需的分配之后进行释放。为此,我们对 WebAssembly 规范施加了某些约束。
SpaceWASM 支持通过流式机制在单次遍历中解码和编译 WASM 二进制代码。当从文件系统读取/请求 WASM 二进制数据块时,可以逐步提供给解释器。流必须以同步方式提供数据块。
解释器限制
该 WASM 解释器在 WebAssembly 1.0 规范之外施加了额外约束,以支持资源受限的航天器环境:
模块与存储限制
- 存储中的模块:最多 256 个模块
- 宿主模块:最多 256 个宿主模块
- 函数参数:最多 255 个 32 位字
- 局部变量:每个函数总共最多 65,535 个 32 位字
IR 代码页
- 代码页:可通过泛型参数
MAX_PAGES配置,通常在模块实例化时设置 - 页大小:256 个 16 位字(512 字节)
- 最大页地址:24 位(16,777,216 页)
- 页内字偏移:8 位(0-255)
控制流
- 嵌套深度:可通过泛型参数
MAX_CONTROL_FRAMES配置(块/循环/if-else) - 值栈:可通过泛型参数
MAX_STACK_DEPTH配置,每个函数的数值数量 - 标签跳转:22 位有符号偏移(±2,097,151 条指令)
- 栈截断深度:每次标签跳转最多 255 个 32 位字
- br_table 分支数:最多 256 个分支目标
指令编码
- 8 位或 16 位索引:0-65,535
- 8 位或 32 位立即数:0-254 内联,255+ 扩展
- 8 位或 64 位立即数:0-254 内联,255+ 扩展
这些约束使得在资源受限环境中能够实现确定性的内存使用和高效执行,同时保持与大多数标准 WebAssembly 模块的兼容性。
基准测试
SpaceWASM 使用 Coremark 基准测试进行性能回归测试。更多信息请参见 coremark。
测试
单元测试与集成测试
cargo test
单元测试用于检查 SpaceWASM 提供的 unsafe 容器抽象因独特的 alloc 使用而产生的回归问题。此外还有覆盖所有 WASM 指令的简单单元测试,无需完整 WAST 执行。
集成测试来自 WASM 1.0 MVP 套件的 spectests,该套件由 https://github.com/WasmEdge/wasmedge-spectest 整理。这些测试用于验证 WASM 解释器与规范的一致性。
模糊测试
SpaceWASM 包含全面的模糊测试基础设施,使用 libfuzzer 和 wasm-smith(https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-smith)。
# 运行模糊测试
make fuzz
# 使用执行跟踪分析崩溃
make trace CRASH=fuzz/artifacts/no_traps/crash-xxx
提案
目前 SpaceWASM 精确实现了 WebAssembly 1.0,即:
- WASM MVP
- 可变全局变量
未来可开发其他 WASM 扩展/提案。
版权
版权所有 (c) 2026 加利福尼亚理工学院(“Caltech”)。美国政府的赞助已被认可。 保留所有权利。 以源代码和二进制形式进行再发布和使用(无论是否修改),只要满足以下条件即可:
- 源代码的再发布必须保留上述版权声明、本条件列表及以下免责声明。
- 二进制形式的再发布必须在发布的文档和/或其他材料中复制上述版权声明、本条件列表及以下免责声明。
- 未经事先书面许可,不得使用 Caltech 或其运营部门喷气推进实验室的名称,或其贡献者的名称来认可或推广从本软件衍生的产品。
本软件由版权持有人和贡献者“按原样”提供,任何明示或暗示的保证,包括但不限于对适销性和特定用途适用性的暗示保证,均被否认。在任何情况下,版权所有者或贡献者均不对任何直接、间接、附带、特殊、惩罚性或后果性损害(包括但不限于替代商品或服务的采购、使用、数据或利润的损失或业务中断)承担责任,无论这些损害是如何引起的,也不论是基于合同、严格责任还是侵权行为(包括疏忽或其他),即使已被告知这些损害的可能性。
相似文章
@huihoo: NASA 开源 Rust 开发的符合航空标准的 WebAssembly 解释器 https://github.com/nasa/spacewasm 最近,#Rust 重构、重新实现的开源项目有些多,要挺住
NASA开源了SpaceWasm,这是一个用Rust编写的、符合航空标准的WebAssembly解释器,专为航天器机载环境设计,支持流式解码和确定性内存分配。
weblings:在 WASM 内部将 Rust 编译为 WASM
Weblings 是一个编译为 WebAssembly 的 Rust 编译器工具链,通过带有 playground 和 Rustlings 练习的网页 UI,支持在浏览器中直接编译和执行 Rust 代码。
WATaBoy:将Game Boy指令即时编译为Wasm,性能超越原生解释器
本文介绍了WATaBoy,一个Game Boy模拟器,它使用即时编译到WebAssembly的方式,实现了超越原生解释器的性能,是JIT到Wasm在模拟领域的一个概念验证。
最好的WebAssembly运行时可能仍然是根本没有运行时
本文使用支持宽算术的wasm2c对WebAssembly-to-C方法进行了基准测试,证明其在速度和内存使用方面仍然与专门的WebAssembly运行时(如Wasmer和Wasmtime)具有竞争力。
Show HN: 运行于 WebAssembly 的 Firefox
Firefox 被编译为在 WebAssembly 中运行,采用基于 WebGL 的渲染和实验性的 JS 到 WASM JIT,网页内容通过 Puter 托管的 Wisp 服务器进行代理。