MicroQuickJS(也称 MQuickJS)是一款专为资源受限的嵌入式环境设计的 JavaScript 引擎。它由传奇程序员、QEMU 与 FFmpeg 的作者 Fabrice Bellard 推出,其核心优势在于极低的内存开销——能够在仅有 10KB RAM 的条件下编译和运行 JavaScript 程序。
整个引擎(包含必要的 C 标准库)的体积大约为 100KB ROM(针对 ARM Thumb-2 指令集)。虽然精简,但其执行性能与 Bellard 的另一个知名项目 QuickJS 相当。
值得注意的是,MicroQuickJS 支持的是接近 ES5 规范的 JavaScript 子集。为了实现高效与安全,它采用了一种更严格的模式,主动禁止了一些在嵌入式环境中容易出错或效率低下的语法结构。尽管它共享了 QuickJS 的部分代码,但其内部架构已针对低内存场景重新设计,关键改进包括采用了追踪式垃圾回收器,虚拟机不使用 CPU 栈,并且字符串以 UTF-8 格式存储。对于想在 M0、M3 等微控制器上运行脚本逻辑的开发者来说,这无疑是一个极具吸引力的选择。
由于采用了极简设计,其源码中的数学库 libm.c 和一些独立的字符处理函数实现也颇具学习价值,完全不依赖其他 C 库,非常适合开发者提取出来用于自己的低资源项目中。
项目开源地址:https://github.com/bellard/mquickjs
核心特性与使用
引擎初始化
与许多需要动态分配系统内存的引擎不同,MicroQuickJS 要求开发者预先提供一块静态内存缓冲区,引擎的所有内存操作都在此缓冲区内进行。
JSContext *ctx;
uint8_t mem_buf[8192];
ctx = JS_NewContext(mem_buf, sizeof(mem_buf), &js_stdlib);
// ... 使用上下文执行脚本
JS_FreeContext(ctx);
内存管理
其内存管理与 QuickJS 类似,但由于采用了压缩式垃圾回收器(Compacting GC),存在几个关键区别,开发时需特别注意:
- 不需要显式调用
JS_FreeValue 来释放 JSValue。
- 对象地址可能在内存分配时发生移动。
- 应避免在 C 变量中直接存储
JSValue,而是存储指向 JSValue 的指针。
- 对于需要长期保持引用的对象,需使用
JS_PushGCRef() 和 JS_PopGCRef() 进行手动管理。
为了方便调试因对象移动导致的问题,可以通过定义 DEBUG_GC 宏来强制垃圾回收器移动对象。
标准库
MicroQuickJS 的标准库通过一个专用工具 mquickjs_build.c 被编译为 C 语言数据结构,从而可以常驻在 ROM 中,无需占用宝贵的 RAM。这种设计使得标准库的实例化速度极快,且内存占用极低。相关示例文件包括 mqjs_stdlib.c、mqjs_stdlib.h 和 example.c。
数学库与浮点模拟
项目自带一个高度精简的数学库 libm.c。此外,如果目标 CPU 不具备硬件浮点运算单元(FPU),MicroQuickJS 还提供了一个浮点模拟器,其代码体积可能比 GCC 等编译器提供的通用版本更小,这对于深入了解计算机基础中的数值运算实现很有帮助。
编译器
MicroQuickJS 的解析器部分与 QuickJS 接近,但在编译流程上做了极致优化以减少内存占用:
- 避免递归:整个流程避免深度递归,严格控制 C 语言调用栈的使用。
- 无抽象语法树(AST):不生成中间表示层,直接生成目标代码。
- 单遍编译:一次性完成解析并直接生成字节码。

关于作者 Fabrice Bellard
提到 Fabrice Bellard,他无疑是开源实战领域的一座丰碑,其作品以极高的工程技巧和创造力著称。除了广为人知的 QEMU 和 FFmpeg,他还创造了众多令人惊叹的项目,例如:
- QuickJS:一个完整且小巧的 ES2020 规范 JavaScript 引擎。
- Tiny C Compiler (TCC):号称世界上最小、最快的 C 编译器。
- TinyEMU:一个小巧的 RISC-V 与 x86 模拟器。
- JSLinux:首个能在浏览器中运行完整 Linux 系统的模拟器。
- BPG 图像格式:基于 HEVC 的高效图像压缩格式。
- 甚至还包括用软件实现的 4G/5G 基站、计算万亿位圆周率的程序等。
MicroQuickJS 的诞生,再次体现了他将强大功能塞入极其有限资源中的超凡能力。对于嵌入式开发者或对底层系统、编程语言实现感兴趣的学习者而言,深入研究这个项目的源代码无疑是一次宝贵的学习之旅。你可以在 云栈社区 找到更多关于系统底层、编译原理和嵌入式开发的深度讨论与资源分享。
|