WebAssembly 运行时 可视化实验室

用交互式 SVG 呈现 WASM 指令集、编译流程、内存模型、WASI 接口、JIT 编译等 WebAssembly 核心技术。八个模块,纯原生实现,可直接在浏览器中探索 WASM 运行时的核心结构。

zero-deps HTML / CSS / JS + SVG requestAnimationFrame prefers-reduced-motion
MODULE 01

WASM 指令集:栈式虚拟机

WebAssembly 采用栈式虚拟机,指令操作隐式栈顶。i32/i64/f32/f64 四种值类型。逐步执行一段加法与乘法程序,观察操作数 push/pop 与执行过程。

stack-vm.svg
i32 值 i64 值 f64 值 当前指令

栈式执行模型

点击“单步”逐步执行 WASM 字节码。每条指令从栈顶弹出操作数、计算后压回结果。栈式设计让编码紧凑(无寄存器字段),但需要更多指令完成同一运算。

当前指令
—
栈深度
0
已执行
0 / 9
结果
—
MODULE 02

编译到 WASM

C/C++/Rust 源码经 LLVM 前端生成 LLVM IR,再由 LLVM WASM 后端或 Wasm-ld 产出 .wasm 字节码。逐步观察从源码到字节码的编译流水线。

compile-pipeline.svg
源码 LLVM IR WASM 字节码 当前阶段

编译阶段

点击“单步”推进编译流水线。Clang/rustc 把源码解析为 AST 并生成 LLVM IR(SSA 形式);LLVM 经过优化 pass 后由 WASM 后端 lowering 为字节码;wasm-ld 链接多个模块并产出最终 .wasm。

当前阶段
source
前端
clang
优化级
O2
产物
app.wasm
MODULE 03

内存模型:线性内存

WASM 使用一段连续可增长的 Linear Memory(默认 1 页=64KB)。栈向下生长、堆向上分配,i32/i64 load/store 通过基址+偏移访问。触发 memory.grow 观察扩容。

linear-memory.svg
已用内存 栈区 堆区 空闲页

线性内存说明

Linear Memory 是一段 ArrayBuffer,最大 4GB(i32 索引)。WASM 模块不直接管理堆,由嵌入语言或 WASI libc malloc 分配。memory.grow 申请追加整数页,返回旧大小(页数)。

当前页数
1
总容量
64 KB
栈指针
0xFFC0
堆指针
0x0400
MODULE 04

WASI 接口

WebAssembly System Interface 为 WASM 提供能力化(capability)系统调用抽象。fd/path/sock 三类接口通过预开放句柄访问,杜绝全局文件系统。切换接口观察调用链。

wasi-interface.svg
WASM 模块 WASI 接口 能力句柄 禁止访问

WASI 接口说明

WASI 采用 capability-based 安全模型:模块只能通过显式传入的 preopened fd 访问文件,无全局 root。fd_read/fd_write 处理 I/O;path_open 在已授权目录下打开;sock_accept 处理网络。

当前接口
fd
已授权句柄
3
访问模式
capability
全局 FS
禁用
MODULE 05

模块加载与链接

WASM 模块生命周期:fetch 字节码 → WebAssembly.compile 编译为 Module → instantiate 实例化(绑定 import)→ 获得 export 调用。逐步观察 import/export 表链接。

module-loading.svg
字节码 Module Instance import/export 链接

加载阶段

compile 阶段做验证与编译(同步或 WebAssembly.compileStreaming 流式);instantiate 阶段把 import 表(函数/内存/表/全局)绑定到宿主提供的对象,再执行 start 函数初始化;导出的函数可被 JS 调用。

当前阶段
fetch
import 数
2
export 数
3
状态
uncompiled
MODULE 06

JIT 编译:分层 tier-up

浏览器 WASM 引擎采用分层编译:解释器 / 基线编译器(Liftoff/Tier-1)快速产出机器码;热点函数由优化编译器(TurboFan/Maglev/Tier-2)重编译。触发热点观察 tier-up。

tiered-jit.svg
解释器 基线编译 (Tier-1) 优化编译 (Tier-2) 调用计数

分层编译策略

函数首次调用走解释器;调用计数达阈值后 Liftoff 快速生成未优化机器码(启动快);累计更多调用后 TurboFan 基于类型反馈重编译,内联与寄存器分配使性能接近原生。

当前 tier
interp
调用次数
0
编译耗时
0 ms
相对性能
30%
MODULE 07

安全沙箱模型

WASM 默认运行在零信任沙箱:默认无 I/O、无网络、无文件系统。能力(capability)必须显式授予;同源策略与 CSP 限制模块来源;线性内存隔离。切换能力观察边界。

security-sandbox.svg
WASM 沙箱 已授予能力 禁止操作 同源/CSP

安全机制

WASM 模块只能调用宿主显式提供的 import 函数——默认无任何系统访问。线性内存与执行栈独立、控制流验证保证安全;CSP 限制可加载的 .wasm 来源;COOP/COEP 启用后可使用 SharedArrayBuffer 多线程。

已授予能力
0 / 5
默认 I/O
禁用
默认网络
禁用
隔离强度
强
MODULE 08

性能对比:JS vs WASM vs Native

不同运行时在不同负载下表现差异:JS 依赖 JIT 与 GC;WASM 接近原生但跨边界有开销;Native 直接受益于 SIMD 与缓存。切换基准测试观察相对性能。

perf-comparison.svg
JavaScript WebAssembly Native (C) AOT vs JIT

基准测试

数值密集负载下 WASM 比 JS 快 1.5-3 倍(无 GC、可预测类型);与 Native 差距约 10-30%(边界开销、缺少自动 SIMD)。DOM/字符串操作 JS 更优(已有优化)。AOT 编译消除启动 JIT 开销。

JS 相对
—
WASM 相对
—
Native 基准
100%
当前测试
fibonacci