純粋な Rust による Lua ランタイム。
5 つの Lua ダイアレクトと MacroLua を 1 つのバイナリに。依存ゼロのインタプリタコア、Cranelift ベースのトレース JIT、ネイティブへの事前コンパイル、そして信頼できないスクリプトを埋め込むために設計されたサンドボックス。
埋め込みたいすべての 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 が明示的に許可したものです。
各ダイアレクトができること。
機能の有無は src/version.rs の能力述語で決まります。luna が生成するダイアレクト別バイトコードは PUC のコンパイラ形式に一致するため、PUC でコンパイルした .luac ファイルをそのままロードできます。
| 機能 | 5.1 | 5.2 | 5.3 | 5.4 | 5.5 | MacroLua |
|---|---|---|---|---|---|---|
| 数値 | ||||||
| 整数サブタイプ 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 は 5 つの公開可能な crate からなる Cargo ワークスペースとして提供されます。インタプリタコアは単独で成立し、JIT と AOT の各層はトレイト境界を介してその上に重なります。バックエンドの削除や差し替えがコア API に触れることはありません。
インタプリタ
字句・構文解析、ダイアレクト別コンパイラ、ディスパッチャ、ランタイム、標準ライブラリ、NaN ボックス化された値、侵入的マーク&スイープ GC、PUC パターンエンジン、そして JIT トレイト表面。第三者 crate ゼロ。
JIT と C ABI
Cranelift バックエンド、cdylib / staticlib として公開される lua.h 互換 C ABI、luna CLI、そして Lua 埋め込みファサード。
AOT コンパイラ
ビルド時ツール。Lua ソース → 単独ネイティブバイナリ。生成物のランタイム依存ではありません。
JIT パイプライン
ソースの分類
各ファイルは 3 つの層のいずれかに属し、それぞれ変更規律とレビュー深度が異なります:
- Stone(石) — 業務非依存の基盤(パターンエンジン、ヒープ、値レイアウト)。fuzz とベンチを施し、semver は厳格。
- Steel(鋼) — Lua ドメインのプリミティブ(コンパイラ、ディスパッチャ、JIT バックエンド)。ダイアレクトごとに PUC と相互検証。
- Cement(コンクリート) — ホストのグルー(CLI、C ABI、標準ライブラリ束縛、AOT)。埋め込み側の要求に応じて自由に進化。
誠実な数字を、さもなくば出さない。
luna は、都合よく選んだ見出しの比率をあえて出しません。たまたま勝つマイクロベンチの 1 セルはマーケティングの産物にすぎず、追う価値のあるシグナルは、負ける外れ値のほうです。私たちが公開するのは、再現可能なベースラインと、それを生んだ方法論です。
方法論、チューニングノブ、ホット経路カウンタは パフォーマンスリファレンスで解説しています。
3 行で埋め込む。
crate を 1 つ追加し、必要なライブラリを開き、評価するだけ。サンドボックス、ネイティブ関数、userdata は必要になったときに。
# 完全なインタプリタ + Cranelift JIT + C ABI
[dependencies]
luna-jit = "2"# 最小の表面 —— 純インタプリタ、依存ゼロ、wasm フレンドリー
[dependencies]
luna-core = "2"cargo install luna-jit # `luna` REPL とスクリプトランナー
luna -e "print('hello, world')"
luna path/to/script.luause luna_jit::vm::Vm;
use luna_jit::version::LuaVersion;
let mut vm = Vm::new(LuaVersion::Lua55);
let out = vm.eval("return 1 + 2")?;
// out[0] == Value::Int(3)use luna_jit::Lua;
use luna_jit::version::LuaVersion;
let mut lua = Lua::sandbox(LuaVersion::Lua54)
.open_base().open_math().open_string()
.with_instr_budget(1_000_000)
.with_memory_cap(8 * 1024 * 1024)
.build();
let add = lua.create_function(|a: i64, b: i64| a + b);
lua.set_global("add", add)?;
let r: i64 = lua.eval("return add(40, 2)")?;