luna
v3.0.0 · MIT / Apache-2.0

純粋な Rust による Lua ランタイム

5 つの Lua ダイアレクトと MacroLua を 1 つのバイナリに。依存ゼロのインタプリタコア、Cranelift ベースのトレース JIT、ネイティブへの事前コンパイル、そして信頼できないスクリプトを埋め込むために設計されたサンドボックス。

5.1 – 5.5
種のダイアレクトと MacroLua
0
コアの外部依存
514
個の fixture が PUC とバイト単位で一致
~33 KB
コールドスタート時のヒープ

埋め込みたいすべての Lua を、1 つのランタイムで

luna は Lua 言語ファミリを安全な Rust だけで一から実装しています。C はなく、埋め込み側が触れる表層に unsafe もありません。必要な依存量を選び、ワークロードの要求に応じて JIT と AOT の各層へ育てていけます。

5.1 – 5.5 + MacroLua

主要な Lua ダイアレクトすべてを 1 つのビルドに収め、Vm 構築時にダイアレクトを選択します。1 つのプロセスが複数のダイアレクトを干渉なく同時にホストできます。MacroLua は 5.4 の表層にコンパイル時 @macro 展開を加えます。

依存ゼロのコア

luna-core が引き込む crate は、それ自身ただ 1 つ。cargo deny ゲートがコミットごとにこれを保証します。監査面は極小、ビルドは数秒、そして mmap RWX を要さないクリーンな wasm32 ターゲットが得られます。

Cranelift トレース JIT

LuaJIT 系譜のトレースベースコンパイラ。ホットループは型付き IR に記録され、Cranelift を通じて降格され、ネイティブ機械語として実行されます。トレイト越しに差し込まれるため、インタプリタ経路はバックエンドに依存しません。

事前コンパイルされたバイナリ

luna-aot は Lua ソースを自己完結型のネイティブ実行ファイルに変換します。バイトコード、温めたトレース、静的ランタイムが 1 つのバイナリにリンクされ、ホストに 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、5 ダイアレクト

各ダイアレクトの参照バイナリに対して stdout・stderr・終了コードで比較します。CI は 5.5 インタプリタが厳密に 5.5.1 であることも表明するため、基準が runner イメージとともに漂流することはありません。

PUC 自身のテスト

上流 Lua テストスイートを 5 ダイアレクト全てでエンドツーエンドに実行し、アサーション数も突き合わせます。PUC が自身のリリース検証に使うのと同じファイルです。

ASAN・Miri・fuzz・soak

毎晩 AddressSanitizer で公式スイート全体を、Miri で provenance と UB を検査。7 つの fuzz ターゲットを毎週実行し、crash artifact が出たら失敗するゲートで守ります。長時間 soak の RSS ドリフトは 1% 未満に抑えます。

各ダイアレクトで何ができるか

機能の可否は src/version.rs の能力判定で決まります。luna はダイアレクトごとに PUC コンパイラ形式と一致するバイトコードを出力するため、PUC でコンパイルした .luac がそのまま読み込めます。

機能5.15.25.35.45.5MacroLua
数値
整数サブタイプ Int
// 切り捨て除算
ビット演算 & | ~ << >>
16 進浮動小数 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 は 7 つの公開済み crate からなる Cargo ワークスペースとして提供されます。うち 3 つが直接依存するものです。インタプリタコアは単独で成立し、JIT と AOT の各層はトレイト境界越しに積み上がるため、バックエンドの削除や差し替えがコア API に触れることはありません。

インタプリタ

レキサ、パーサ、ダイアレクト別コンパイラ、ディスパッチャ、ランタイム、標準ライブラリ、NaN ボックス値、侵入型 mark-sweep GC、PUC パターンエンジン、そして JIT トレイト表層。第三者 crate はゼロ。

JIT + C ABI

Cranelift ベースのバックエンド、cdylib / staticlib として提供する lua.h 互換 C ABI、luna CLI、Lua 埋め込みファサード。

AOT コンパイラ

ビルド時ツール:Lua ソース → 単独ネイティブバイナリ。生成物のランタイム依存ではありません。

JIT パイプライン

  1. インタプリタ・ディスパッチャ

    カウンタを増やし、閾値を確認。

  2. トレースレコーダ

    オペコードを型付き IR に再生。

  3. Cranelift バックエンド

    IR を降格し、レジスタ割付、発行。

  4. ネイティブ機械語

    サイドイグジットまで実行。

4 行で埋め込む

必要な依存量に合う 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、サンドボックス制御、ダイアレクトマトリクスを網羅しています。