- 解释器
- 嵌入式
- 语言运行时
【免费下载链接】wasm3
🚀 A fast WebAssembly interpreter and the most universal WASM runtime
Wasm3 是一个以"通用性"著称的轻量级 WebAssembly 解释器(详见仓库根目录 README.md),其价值不仅体现在基准测试上,更体现在一个覆盖浏览器、桌面、游戏掌机与各类微控制器的庞大演示生态中。本文以 docs/Demos.md 为骨架,逐项解读这些演示项目背后的技术路径——包括浏览器端的 MetaWASI 支持、Python 绑定 pywasm3、ESP32/Arduino 等 MCU 上的 WASI 应用,以及"Wasm3 运行 Wasm3"的自托管能力,并结合本仓库源码说明它们各自对应的运行机制与复现方式。读完本文,你将能按图索骥地理解 Wasm3 在不同硬件层级上的集成方案,并知道如何在本仓库的 platforms 目录下找到对应的示例工程。
一、演示生态总览:一条从浏览器到 MCU 的完整链路
docs/Demos.md 列出的演示项目,恰好覆盖了 Wasm3 官方宣称的"最通用 WASM 运行时"定位:同一份解释器核心可以编译为浏览器里的 WebAssembly、打包为 Python 扩展、烧录进 Arduino/ESP32 开发板,甚至运行在任天堂 DS 掌机上。按运行环境归类如下:
| 运行环境 | 演示内容 | 仓库内对应参考 |
|---|---|---|
| 浏览器 | Webassembly.sh 上运行带 MetaWASI 支持的 wasm3 | platforms/emscripten/main.c、source/m3_api_meta_wasi.c |
| 桌面/Python | PyGame + pywasm3 示例、DOOM 编译为 WASI 后跑在 pywasm3 上 | platforms/python/README.md、test/wasi 下的 WASI 应用 |
| 掌机 | WebAssembly on Nintendo DS(AssemblyScript 编写的贪吃蛇) | 无仓库内实现,属第三方移植 |
| ESP32 | 每个像素由一个独立 WebAssembly 应用控制的 M5 Atom 面板 | platforms/embedded/esp32-idf |
| 自托管 | 使用 clang.wasm 实现 Wasm3 自编译 | 同目录下的 README.md 自托管特性说明 |
| MCU 游戏 | Dino 游戏(PyBadge/Arduino、Raspberry Pi Pico、ESP32 TTGO TDisplay) | platforms/embedded/arduino、platforms/embedded/bluepill 等 |
| 无线 IoT | WiFi/Gpio 访问 + 通过 OTA 更新 wasm 文件(ESP32/Web) | platforms/embedded/esp32-idf-wasi |
| 显示动画 | RGB 灯动画(nRF51/nRF52/ESP8266/ESP32)、LCD 渲染(M5Stack)、康威生命游戏(Maixduino/K210) | platforms/embedded/fomu 等嵌入式平台目录 |
| 边缘计算 | Losant Embedded Edge Agent(Python/ESP32) | extra/logos/losant.png 标识对应商业案例 |
需要说明的是,docs/Demos.md 中列出的多数演示项目(如 DOOM、Nintendo DS 移植、各 MCU 应用)由社区贡献者托管在外部仓库,本仓库内不包含其源码;本文只以原文档条目为准介绍其技术形态,而把仓库内可验证的示例工程作为理解这些演示底层原理的参照。
二、浏览器端:在 Webassembly.sh 中运行 Wasm3(MetaWASI 支持)
Demos.md 的第一条演示指向 Webassembly.sh —— 一个在线 WebAssembly 沙箱环境,在其中可以直接执行wasm3命令。这意味着 Wasm3 把自己编译成了 WebAssembly,并作为一个 WASI 应用运行在浏览器沙箱中,实现了"解释器本身被另一个宿主解释执行"的嵌套结构。
2.1 构建层面:Emscripten 目标
本仓库的 platforms/emscripten/README.md 给出了完整的构建步骤:
source /opt/emsdk/emsdk_env.sh --build=Release mkdir -p build cd build cmake -GNinja -DEMSCRIPTEN=1 .. ninja构建产物是wasm3.wasm。构建依赖 WebAssembly 的tail-call 提案,因此需要较新的宿主支持(该 README 注明 Chrome 112、Firefox 121、Safari 18.2 与 Node 22 起无需任何 flag 即可运行):
wasm2wat --enable-tail-call --enable-bulk-memory wasm3.wasm > wasm3.wat查看生成.wat即可直观观察解释器被编译成 WebAssembly 后的指令形态。运行方式有两种:用emrun启动本地 HTTP 服务后访问http://localhost:8080/wasm3.html,或直接node ./wasm3.js。这也是 Webassembly.sh 演示在本地复现的等价路径。
2.2 运行时层面:MetaWASI 的实现原理
浏览器里的 wasm3 需要与宿主(浏览器/Node)的文件系统、时钟等 WASI 系统调用打交道,这正是MetaWASI的职责。source/m3_api_meta_wasi.c 的注释写得很直白:"MetaWASI 主要是把 WASI 调用重定向到宿主 WASI 环境"(NOTE: MetaWASI mostly redirects WASI calls to the host WASI environment)。
从源码看其关键设计:
- 编译期开关:整个实现包裹在
#if defined(d_m3HasMetaWASI)中,且强制要求__wasi__目标(#error "MetaWASI is only supported on WASI target")——即 MetaWASI 只能用于"wasm3 自身被编译为 WASI 程序"的场景。 - 路径参数转换:WASI ABI 以
(指针, 长度)二元组传递路径且无\0结尾,而 wasi-libc 的__wasi_path_*包装函数要求 NUL 结尾字符串,因此每个路径都必须先从客户机内存拷贝出来再补终止符(见d_m3WasiPath宏与d_m3WasiPathMax上限,缺省 1024 字节)。 - iovec 拷贝:
copy_iov_to_host负责把 guest 内存中的__wasi_iovec_t数组批量拷贝到宿主侧,供fd_read/fd_write等调用使用。
在 source/CMakeLists.txt 中,BUILD_WASI选项有三个分支:wasi(编译进d_m3HasWASI)、metawasi(编译进d_m3HasMetaWASI)、uvwasi(编译进d_m3HasUVWASI,见 source/m3_api_uvwasi.c)。对浏览器场景而言,MetaWASI 是让 wasm3 在 WebAssembly 宿主上获得完整 WASI 能力的桥梁。
三、Python 与桌面:pywasm3、PyGame 与 DOOM
Demos.md 的第二、三条演示属于 Python 生态:
- PyGame + pywasm3 示例:pywasm3 是 Wasm3 的 Python 绑定模块,仓库内的 platforms/python/README.md 说明了它的定位("Python binding for Wasm3, a fast WebAssembly interpreter"),并注明其代码已迁移至独立仓库维护。
- DOOM 编译到 WASI 后在 pywasm3 上运行:这是一个极具说服力的"大型真实 WASI 应用"演示——DOOM 这种体量、依赖复杂系统调用的经典游戏,被编译为 WASI 模块后由 Wasm3 解释执行。
PyGame 本身是 Python 生态常用的 2D 游戏/图形框架,而 pywasm3 让 Python 程序能够加载执行.wasm模块。两者结合意味着:游戏逻辑可以以 WebAssembly 模块形式分发(工具链无关、沙箱隔离),而渲染与输入仍由宿主 Python 侧完成——这与本仓库 README.md 中"toolchain decoupling"(工具链解耦)的动机描述完全一致。
本仓库虽然没有 pywasm3 的完整源码,但提供了理解"Python 宿主如何驱动 wasm3"的替代参照:platforms/emscripten_lib/main.c 用EMSCRIPTEN_KEEPALIVE导出了init、new_runtime、load、call等函数,把 wasm3 的 C API(m3_NewEnvironment、m3_NewRuntime、m3_ParseModule、m3_LoadModule、m3_FindFunction、m3_CallV、m3_GetResultsV)暴露给脚本语言宿主。任何语言绑定(Python/Rust/Go 等)本质上都是对这组 API 的包装。
此外,仓库的 test/wasi 目录内置了一批可直接交给 wasm3 运行的 WASI 应用,包括:
mal/mal.wasm:一个完整的 Lisp 解释器(mal 项目)编译产物;c-ray、coremark、brotli、smallpt、raymarcher、mandelbrot等真实计算型程序;- 每个子目录下都附有 README.md 说明。
用 pywasm3 在 Python 中加载这些模块,即可复现"桌面端 Python + WebAssembly"的混合编程模式。
四、嵌入式 MCU 演示群:ESP32、Arduino、RPi Pico 与游戏
docs/Demos.md 的嵌入式演示占据了最大篇幅,覆盖 ESP32、Arduino/PyBadge、Raspberry Pi Pico、M5Stack、Maixduino、nRF51/nRF52、ESP8266 等硬件。这些演示共同指向一个主题:在资源极度受限的 MCU 上跑通用 WebAssembly 运行时。
4.1 各演示的技术形态
| 演示 | 硬件 | 技术要点 |
|---|---|---|
| Dino 游戏 | PyBadge/Arduino、Raspberry Pi Pico、ESP32 TTGO TDisplay | 同一份游戏逻辑编译为 wasm,跨三种差异极大的 MCU 平台运行 |
| WiFi/Gpio 访问 + OTA 更新 wasm | ESP32 / Web | wasm 文件可经网络远程下发更新,无需重新烧录固件 |
| RGB 灯动画 | nRF51 / nRF52 / ESP8266 / ESP32 | WebAssembly 控制 LED 动画 |
| LCD 渲染(AssemblyScript) | M5Stack / ESP32 | AssemblyScript 编写的渲染逻辑 |
| 康威生命游戏(AssemblyScript) | Maixduino / K210 | 计算密集型网格演算 |
| 每像素一个 wasm 应用 | ESP32(M5 Atom 面板) | 多模块并发执行的极端形态 |
这些演示的共性价值在于验证了 Wasm3 的两个核心卖点:极小的资源占用(README 标注"最低可用配置约 64KB 代码 + 10KB RAM")与跨架构可移植性(README 列出 x86、ARM、RISC-V、Xtensa、ARC32 等架构)。
4.2 仓库内对应的嵌入式示例工程
platforms/embedded 目录提供了可在本地直接编译的参考实现,与上述演示同构:
- Arduino:platforms/embedded/arduino/src/main.cpp 展示了最小化的完整调用链:
m3_NewEnvironment→m3_NewRuntime(env, 1024, NULL)→m3_ParseModule→m3_LoadModule→m3_FindFunction(&f, runtime, "fib")→m3_CallV(f, 24)→m3_GetResultsV。注意这里运行时内存仅分配1024 字节,足以运行fib32.wasm(该模块以 C 数组形式内嵌,见 source/extra/fib32.wasm.h)。 - ESP32-IDF:platforms/embedded/esp32-idf/main/main.cpp 使用相同的 API 序列,运行结束后
esp_restart()循环演示,配 platforms/embedded/esp32-idf/README.md 与sdkconfig.defaults配置。 - ESP32-IDF + WASI:platforms/embedded/esp32-idf-wasi 额外包含 m3_api_esp_wasi.c——这是为 ESP32 裁剪的 WASI 实现(
d_m3HasWASI编译进解释器),并内嵌wasi_test.wasm.h测试模块,是理解"MCU 上 WASI 如何映射到底层系统"的直接源码材料。 - 其他 MCU:bluepill(STM32)、hifive1(SiFive RISC-V)、particle、wm_w600、fomu(FPGA SoC,含完整 BSP 头文件与链接脚本),对应文档宣称的 ARM/RISC-V/Xtensa 架构覆盖。
4.3 "每像素一个 WebAssembly 应用"背后的多模块能力
M5 Atom 面板演示中,每个像素由一个独立 wasm 应用控制,这在运行时层面意味着:一个进程内需要同时加载、执行多个 WebAssembly 模块。Wasm3 的运行时模型天然支持这一点——m3_NewEnvironment创建共享环境,m3_NewRuntime可创建多个隔离运行时,每个模块通过m3_ParseModule+m3_LoadModule独立装载。这也是"完全沙箱化、定义良好、可预测的环境"(README 对 WebAssembly 在 MCU 上价值的描述)在工程上的直接体现。
五、自托管与自编译:Wasm3 运行 Wasm3
docs/Demos.md 中有一条极具技术含量的演示:Wasm3 自编译——用clang.wasm(被编译为 WebAssembly 的 Clang 编译器)在 Wasm3 解释器之上完成 wasm3 源码的自我编译。
这条演示与本仓库 README 中"wasm3 可以执行 wasm3(self-hosting)"的特性相互印证。它成立的前提是本仓库构建链路的两端都成立:
- Wasm3 能编译为 WebAssembly(platforms/emscripten 目标,见上文);
- Wasm3 能运行完整 WASI 程序(
test/wasi中mal、c-ray等已证明,source/m3_api_wasi.c 实现 WASI syscall 绑定)。
当解释器自身被编译成 wasm 后,理论上任何能把工具链(Clang、链接器等)也编译为 WASI 模块的宿主,都能形成"wasm 编译器 → wasm 解释器 → 宿主"的完整自举链。README 中"Browsers. Wasm3 can be compiled to WebAssembly itself!"与"wasm3 can execute wasm3 (self-hosting)"两条特性即为此事背书。此类演示的价值在于证明 WebAssembly 已经可以承载完整的开发工具链,而不再仅仅是"应用二进制格式"。
六、掌机移植:WebAssembly on Nintendo DS
docs/Demos.md 收录了在任天堂 DS 掌机上运行 WebAssembly 的第三方移植(AssemblyScript 编写的贪吃蛇)。这属于 Wasm3"最小体积、可嵌入任意平台"设计哲学的边缘案例:DS 的 ARM 处理器、KB 级内存限制与现代 MCU 相当,移植方法与本仓库 platforms/embedded 下的 MCU 工程同构——核心是把source/下的解释器 C 源码(source/m3_core.c、source/m3_exec.c、source/m3_compile.c 等)纳入目标平台工具链,并为平台实现m3_host_posix.h/m3_host_none.h等抽象层(见 source/m3_host.h)。这类移植的可行性已由仓库中 docs/Hardware.md 罗列的硬件矩阵从侧面印证。
七、边缘计算:Losant Embedded Edge Agent
最后一条演示是商业落地形态:Losant Embedded Edge Agent提供了 Python 与 ESP32 两套示例。它代表 Wasm3 在"边缘计算"场景中的典型用法——设备端运行轻量解释器,以 WebAssembly 形式下发/更新规则逻辑(这正是 README 动机一节列举的edge computing、scripting、plugin systems、IoT rules等实际用例之一)。
本仓库 extra/logos/losant.png 出现在 README 的 "Used by" 列表,印证其商业合作关系。从实现角度,ESP32 版边缘代理可复用 platforms/embedded/esp32-idf-wasi 的 WASI 绑定方式,Python 版则可基于 pywasm3 实现"Python 宿主 + wasm 规则模块"的结构。
八、在本地复现:安装、构建与运行
要将上述演示落地到本地环境,核心入口是 docs/Installation.md 与 platforms 下的各工程:
8.1 获取 wasm3 可执行文件
- Linux:下载静态 ELF 后
chmod +x直接运行;其他架构(Arm、MIPS、PowerPC、RISC-V、s390x、LoongArch、m68k、MicroBlaze、SH4 等)提供 musl 链接的归档包。 - macOS:
brew install wasm3。 - Windows / Cosmopolitan:提供
wasm3-win-x64.exe等静态可执行文件,以及运行于 Linux/Mac/Windows/FreeBSD/BSD/BIOS 的wasm3-cosmopolitan.com(实际可执行格式 APE)。 - Python:
pip3 install pywasm3,对应第四节中的 Python 演示。
8.2 用 C API 运行一个 wasm 模块
参考 platforms/app/main.c 与 platforms/app/README.md,标准流程为:
IM3Environment env = m3_NewEnvironment(); // 创建环境 IM3Runtime runtime = m3_NewRuntime(env, 64*1024, NULL); // 创建运行时(内存上限) IM3Module module; m3_ParseModule(env, &module, wasm_bytes, wasm_size); // 解析模块 m3_LoadModule(runtime, module); // 装载模块 m3_FindFunction(&f, runtime, "fib"); // 定位导出函数 m3_CallV(f, 40); // 传参调用 m3_GetResultsV(f, &value); // 读取返回值test/lang/目录提供了可直接编译为 wasm 的测试源(如 test/lang/fib.c)及已编译产物fib32.wasm/fib64.wasm,便于快速验证调用链。
8.3 运行 WASI 应用
test/wasi/下的每个子目录都包含README.md与现成.wasm文件(如mal/mal.wasm、coremark/coremark.wasm、smallpt/smallpt.wasm),可直接交给 wasm3 执行,复现"桌面端运行 WASI 应用"的演示形态。对应回归测试脚本见 test/run-wasi-test.py。
九、延伸阅读
docs/Demos.md 是理解 Wasm3 能力边界的窗口,若要深入其背后的实现,建议按以下顺序阅读本仓库文档:
- docs/Installation.md:各平台安装与预编译产物说明;
- docs/Hardware.md:受支持的 MCU/SBC 硬件清单(对应嵌入式演示的可行性);
- docs/Cookbook.md:C API 的典型用法与技巧;
- docs/Interpreter.md:解释器架构与执行模型;
- docs/Performance.md:CoreMark 等性能数据(README 亦强调"不同环境结果不同");
- docs/Development.md:从源码构建与开发环境配置;
- docs/Testing.md:规范测试套件与模糊测试(README 说明 wasm3 通过 WebAssembly 官方 spec testsuite)。
综上,Wasm3 的演示生态既是一份"能跑到哪"的实证清单,也是一张"如何集成"的路线图:浏览器端靠 MetaWASI 完成 WASI 桥接,Python 端靠语言绑定包装 C API,MCU 端靠裁剪型 WASI 与极小内存占用,而自编译演示则把 WebAssembly 的工具链价值展示到了极致。
- 解释器
- 嵌入式
- 语言运行时
【免费下载链接】wasm3
🚀 A fast WebAssembly interpreter and the most universal WASM runtime
相关推荐
群晖硬盘兼容性终极破解指南:6步解锁第三方硬盘完全教程
群晖硬盘兼容性终极破解指南:6步解锁第三方硬盘完全教程 您是否曾为群晖NAS拒绝识别第三方硬盘而烦恼?是否在存储管理器看到"不兼容硬盘"的警告而束手无策?Syn
运维存储CLIWAMR Samples 全览:Fluent Bit 内置 WebAssembly 微运行时的嵌入式示例与实战指南
WAMR Samples 全览:Fluent Bit 内置 WebAssembly 微运行时的嵌入式示例与实战指南 WAMR(WebAssembly Micro
可观测性日志分析云原生流处理TinyGo WebAssembly 实战指南:从 //export 导出到浏览器端运行
TinyGo WebAssembly 实战指南:从 //export 导出到浏览器端运行 导读 TinyGo 是面向微控制器、WebAssembly(WASM/
编译器嵌入式语言运行时WebAssembly
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考