luna
v3.0.0 · MIT / Apache-2.0

纯 Rust 打造的 Lua 运行时

单个二进制里容纳五种 Lua 方言与 MacroLua。一个零依赖的解释器核心、一个基于 Cranelift 的 trace JIT、提前编译成原生二进制,以及一个为嵌入不受信任脚本而设计的沙箱。

5.1 – 5.5
种方言,外加 MacroLua
0
核心的第三方依赖
514
个 fixture 与 PUC 逐字节相等
~33 KB
冷启动堆占用

一个运行时,覆盖你要嵌入的每一种 Lua

luna 用安全的 Rust 从头实现了整个 Lua 语言家族——没有 C,嵌入方接触到的表层也没有 unsafe。按需选择依赖体量,再随工作负载增长逐步用上 JIT 与 AOT 两层。

5.1 – 5.5 + MacroLua

所有主线 Lua 方言都在同一构建里,在构造 Vm 时逐一选定。同一进程可并发承载多种方言而互不干扰。MacroLua 在 5.4 表层之上加入编译期 @macro 展开。

零依赖核心

luna-core 只引入一个 crate——它自己。每次提交都由 cargo deny 关卡强制保证。这意味着极小的审计面、以秒计的构建,以及无需 mmap RWX 的干净 wasm32 目标。

Cranelift trace JIT

一个 LuaJIT 血统的 trace 式编译器。热循环被记录成带类型的 IR,经 Cranelift 降级后作为原生机器码运行——通过 trait 接入,使解释器路径永不依赖具体后端。

提前编译的二进制

luna-aot 把一份 Lua 源码变成自包含的原生可执行文件——字节码、预热的 trace、静态运行时全部链接进同一个二进制,宿主上无需安装 luna 即可运行。

顺手的嵌入体验

一个 mlua 风格的 Lua 门面、自动解析参数的类型化原生函数、表构造器、通过 derive 宏暴露的 userdata、Rust 侧的协程与调试钩子,以及结构化的 LuaError

为约束脚本而建

安全边界由宿主掌握。精选的标准库白名单、指令预算、近似内存上限,以及默认关闭的字节码加载——脚本能看到的每一项能力,都是 Rust 主动放行的。

对照参考 Lua 逐字节相等,每次推送都验

兼容性在这里是量出来的,不是声称的。一份 514 个 fixture 的私有语料库,对照从源码构建的原版 PUC 解释器——5.1.5、5.2.4、5.3.6、5.4.8 与 5.5.1——每一个都必须逐字节一致、零 skip,提交才算绿。

514 个 fixture,五种方言

按 stdout、stderr 与退出码对照每种方言的参考二进制。CI 还会断言 5.5 解释器恰好是 5.5.1,使基准不会随 runner 镜像漂移。

PUC 自己的测试集

上游 Lua 测试套件在全部五种方言上端到端运行,并带断言计数校验——就是 PUC 用来验证自己发布的那些文件。

ASAN、Miri、fuzz、soak

每晚用 AddressSanitizer 跑完整官方套件,Miri 检查 provenance 与 UB,七个 fuzz target 每周运行且由一道遇到 crash artifact 就失败的关卡把守,长跑 soak 的 RSS 漂移上限低于 1%。

每种方言能做什么

特性的可用性由 src/version.rs 中的能力判定驱动。luna 生成的按方言字节码与 PUC 编译器格式一致,因此 PUC 编译出的 .luac 文件可直接加载。

特性5.15.25.35.45.5MacroLua
数值
整数子类型 Int
// 向下取整除
位运算 & | ~ << >>
十六进制浮点 0x1p4
语法
goto / ::label::
空语句 ;
字符串
\xXX / \z 转义
\u{XXXX} unicode 转义
5.4+ 属性
local <const>
local <close>
5.5 独有
global 关键字
具名变长参数 function f(...name)
MacroLua 独有
@name(args) 编译期宏

完整矩阵、标准库覆盖与 C API 表层见兼容性参考

自己决定依赖表面

luna 以一个含七个已发布 crate 的 Cargo 工作区形式交付,其中三个是你直接依赖的。解释器核心独立成立;JIT 与 AOT 两层通过 trait 边界叠加其上,因此移除或替换后端不会触及核心 API。

解释器

词法、语法、逐方言编译器、dispatcher、运行时、标准库、NaN-boxed 值、侵入式 mark-sweep GC、PUC 模式引擎,以及 JIT trait 表层。零第三方 crate。

JIT + C ABI

基于 Cranelift 的后端、以 cdylib / staticlib 形式提供的 lua.h 兼容 C ABI、luna 命令行,以及 Lua 嵌入门面。

AOT 编译器

一个构建期工具:Lua 源码 → 独立原生二进制。它不是产物的运行时依赖。

JIT 流水线

  1. 解释器 dispatcher

    计数器自增,检查阈值。

  2. Trace 记录器

    把 opcode 重放成带类型的 IR。

  3. Cranelift 后端

    降级 IR、分配寄存器、发射。

  4. 原生机器码

    一直运行到 side-exit。

四行就能嵌入

加入符合你所需体量的 crate,为目标方言构造一个 Vm,然后求值。

Rust
// Cargo.toml → luna-jit = "3"

use luna_jit::{Vm, LuaVersion};

let mut vm = Vm::new(LuaVersion::Lua54);
let v = vm.eval("return 6 * 7")?;   // [Int(42)]

若想要完全没有第三方依赖的解释器,改为依赖 luna-core。要产出独立原生二进制,把 luna-aot 当作构建期工具使用。文档完整覆盖嵌入 API、沙箱控制与方言矩阵。