Hotdry.
compiler-design

Porffor 与 QuickJS:JS 字节码解释器的原生编译,实现运行时独立

通过 Porffor 和 QuickJS 等工具,将 JS 字节码解释器原生编译为无需 VM 依赖的独立可执行文件,提供优化性能参数与落地清单。

传统 JavaScript 运行时如 Node.js 或浏览器引擎,通常打包庞大的解释器或 JIT 编译器,导致独立可执行文件体积巨大(往往数十 MB),启动时间长,且高度依赖特定 VM 环境。这限制了 JS 在嵌入式设备、CLI 工具或边缘计算中的应用。Porffor 和 QuickJS 等项目通过原生编译(AOT)技术,将 JS 字节码解释器直接转化为 VM 独立的 standalone 可执行文件,实现 “运行时自由”,显著缩小体积并提升性能。

Porffor 是一个实验性 AOT 编译器,完全用 JS 编写,支持将 JS/TS 直接编译为 WebAssembly 或原生二进制。它不捆绑运行时,而是真正编译 JS 代码,通过 JS → Wasm → C → native 的链路生成文件。例如,传统 JS-to-native 方案体积约 90MB,而 Porffor 输出小于 100KB,缩小 1000 倍。该项目强调静态分析优化,支持 TypeScript 无需转译。

安装 Porffor 简单:npm install -g porffor@latest。基本使用:

  • REPL 模式:porf
  • 运行 JS:porf script.js
  • 编译 Wasm:porf wasm script.js out.wasm
  • 原生编译:porf native script.js out.exe

关键参数包括:

  • --compiler=clang|gcc|zig:选择 C 编译器,默认 clang。
  • --cO=Ofast|O3|O2|O1|O0:优化级别,默认 Ofast(最高性能)。
  • --valtype=i32|i64|f64:数值类型,默认 f64。
  • --opt-types:启用类型优化提示。

示例脚本 fib.js 计算斐波那契数:

function fib(n) { return n <= 1 ? n : fib(n-1) + fib(n-2); }
console.log(fib(30));

编译:porf native fib.js fib --cO=Ofast --compiler=clang。生成 exe 启动瞬间执行,无 Node 依赖,适用于 CLI 工具。

QuickJS 是另一个轻量级 JS 引擎,仅几百 KB,支持 ES2023 规范,包括模块、异步生成器。通过 qjsc 工具编译 JS 为独立字节码可执行文件:

./qjsc -o hello examples/hello.js
./hello  # 输出 Hello World

体积小(hello world 仅 367 KiB),启动 <300μs,垃圾回收用引用计数。参数:

  • -m:模块模式。
  • -fno-eval:禁用动态 eval。
  • --std:启用 std/os 模块(文件 I/O)。

落地清单:

  1. 环境准备:Node.js(Porffor)/C 编译器(QuickJS),目标平台 Clang/GCC。
  2. 代码规范:避免 eval/new Function;用类型注解 /** @type {number} */ 优化 Porffor;静态函数优先。
  3. 编译流程
    步骤 命令 输出体积阈值 性能阈值
    Wasm porf wasm script.js <10KB 启动 < 1ms
    Native porf native --cO=Ofast <100KB 接近 C
    QuickJS qjsc script.js out <500KB 启动 < 300μs
  4. 监控点:文件大小(strip 默认启用);冷启动时间(benchmark);Test262 兼容率(Porffor 持续测试)。
  5. 回滚策略:若不支持动态 JS,回退 Node;体积超阈值,禁用 BigInt 等扩展(QuickJS -fno-bigint)。

风险与限制:

  • Porffor 预 alpha,不支持异步 / 跨域变量,实验性强。
  • QuickJS 无尾调用优化,数学扩展可选。
  • 两者均静态,无法动态加载代码。

实际场景:CLI 工具(如 JSON 处理器),体积从 Node 90MB 缩至 <1MB;边缘计算,Wasm 沙箱安全执行。Porffor 适用于高性能嵌入式,QuickJS 适合脚本嵌入。

这些技术解放 JS 运行时,实现真正独立部署,推动 JS 向系统级语言演进。

资料来源

查看归档