Major additions:
- Phase 11.8 MIR cleanup specification (Core-15→14→13 roadmap)
- Nyash ABI unified design document (3×u64 structure)
- TaskGroupBox foundation with cancelAll/joinAll methods
- Enhanced async/await with checkpoint auto-insertion
- Structured concurrency preparation (parent-child task relationships)
Documentation:
- docs/development/roadmap/phases/phase-11.8_mir_cleanup/: Complete Core-13 path
- docs/development/roadmap/phases/phase-12/NYASH-ABI-DESIGN.md: Unified ABI spec
- Updated Phase 12 README with AOT/JIT explanation for script performance
- Added async_task_system/ design docs
Implementation progress:
- FutureBox spawn tracking with weak/strong reference management
- VM checkpoint integration before/after await
- LLVM backend async support preparation
- Verifier rules for await-checkpoint enforcement
- Result<T,E> normalization for timeout/cancellation
Technical insights:
- MIR as 'atomic instructions', Box as 'molecules' philosophy
- 'Everything is Box' enables full-stack with minimal instructions
- Unified BoxCall for array/plugin/async operations future consolidation
Next steps:
- Complete TaskGroupBox implementation
- Migrate from global to scoped task management
- Implement LIFO cleanup on scope exit
- Continue Core-13 instruction consolidation
🚀 'From 15 atoms to infinite programs: The Nyash Box Theory'
7.1 KiB
7.1 KiB
Nyash ABI 統合設計図 v1.0 (2025-09-01)
🎯 概要
Nyash ABIは、既存のC ABIプラグインを維持しながら、より型安全で拡張性の高いプラグインシステムを実現する統一ブリッジ規格です。
設計原則
- 後方互換性: 既存のC ABIプラグインはそのまま動作
- 最小侵襲: MIR層の変更を最小限に
- 段階的移行: nyash.tomlで個別に移行可能
- ゼロコスト抽象化: インライン値で不要なボクシング回避
📐 基本構造
NyashValue - 3×u64統一表現
// nyash_abi.h
typedef struct NyashValue {
uint64_t type_id; // 型識別子(上位16bit: カテゴリ、下位48bit: ID)
uint64_t box_handle; // Arc<dyn NyashBox>のポインタ or インライン値
uint64_t metadata; // フラグ・メソッドID・追加データ
} NyashValue;
// メタデータフラグ(上位16bit)
#define NYASH_META_INLINE 0x0001 // box_handleがインライン値
#define NYASH_META_ASYNC 0x0002 // 非同期結果
#define NYASH_META_WEAK 0x0004 // 弱参照
#define NYASH_META_BORROWED 0x0008 // 借用(参照カウント不要)
#define NYASH_META_ERROR 0x0010 // エラー値
// 型カテゴリ(type_idの上位16bit)
#define NYASH_TYPE_PRIMITIVE 0x0001 // i64/f64/bool/null
#define NYASH_TYPE_STRING 0x0002 // 文字列
#define NYASH_TYPE_ARRAY 0x0003 // 配列
#define NYASH_TYPE_MAP 0x0004 // マップ
#define NYASH_TYPE_CUSTOM 0x1000 // ユーザー定義Box
#define NYASH_TYPE_PLUGIN 0x2000 // プラグインBox
NyashFunc - 統一関数シグネチャ
typedef NyashValue (*NyashFunc)(
uint32_t argc, // 引数の数
NyashValue* args, // 引数配列(args[0]はレシーバー)
void* context // ランタイムコンテキスト
);
// プラグインエントリーポイント
typedef struct NyashPlugin {
const char* name; // プラグイン名
const char* version; // バージョン
uint32_t method_count; // メソッド数
const char** method_names; // メソッド名配列
NyashFunc* method_funcs; // メソッド関数配列
NyashFunc init; // 初期化関数
NyashFunc drop; // 破棄関数
} NyashPlugin;
// エクスポート関数
extern "C" const NyashPlugin* nyash_plugin_init(void);
🔄 既存C ABIとの共存
トランポリン戦略
// src/runtime/abi_bridge.rs
// 既存のC ABI関数シグネチャ
type OldCFunc = extern "C" fn(*mut c_void, *const c_void) -> *mut c_void;
// 自動生成トランポリン
fn create_c_abi_trampoline(old_func: OldCFunc) -> NyashFunc {
Box::into_raw(Box::new(move |argc, args, ctx| {
// NyashValue → 旧C ABI形式に変換
let old_args = convert_to_old_format(args);
let old_result = old_func(old_args.as_ptr(), ctx);
// 旧C ABI形式 → NyashValueに変換
convert_from_old_format(old_result)
})) as NyashFunc
}
nyash.toml設定
# nyash.toml v2.1
[plugin.math]
path = "plugins/math.so"
abi = "c" # 既存C ABI(デフォルト)
[plugin.advanced_math]
path = "plugins/advanced_math.so"
abi = "nyash" # 新Nyash ABI
[plugin.hybrid]
path = "plugins/hybrid.so"
abi = "auto" # 自動検出(シンボル名で判定)
💨 インライン最適化
基本型のインライン表現
// インライン値のエンコーディング(metadataにINLINEフラグ必須)
// 整数(i64): box_handleに直接格納
NyashValue inline_i64(int64_t val) {
return (NyashValue){
.type_id = NYASH_TYPE_PRIMITIVE | (1 << 16), // subtype=1 (i64)
.box_handle = (uint64_t)val,
.metadata = NYASH_META_INLINE
};
}
// 浮動小数点(f64): ビットパターンをbox_handleに
NyashValue inline_f64(double val) {
union { double d; uint64_t u; } conv = { .d = val };
return (NyashValue){
.type_id = NYASH_TYPE_PRIMITIVE | (2 << 16), // subtype=2 (f64)
.box_handle = conv.u,
.metadata = NYASH_META_INLINE
};
}
// Bool: box_handleの最下位ビット
NyashValue inline_bool(bool val) {
return (NyashValue){
.type_id = NYASH_TYPE_PRIMITIVE | (3 << 16), // subtype=3 (bool)
.box_handle = val ? 1 : 0,
.metadata = NYASH_META_INLINE
};
}
🏗️ 実装フェーズ
Phase 1: 基盤整備(1週間)
- nyash_abi.h ヘッダー定義
- NyashValue ↔ Arc 変換関数
- C ABIトランポリン自動生成
- nyash.toml v2.1パーサー拡張
Phase 2: ランタイム統合(2週間)
- 統一レジストリ実装(abi種別管理)
- VM層でのNyashFunc呼び出し
- インライン値の高速パス
- エラーハンドリング統一
Phase 3: プラグイン移行(3週間)
- 既存プラグイン1つをNyash ABIに移行
- パフォーマンスベンチマーク
- 移行ガイドライン作成
- デバッグツール整備
Phase 4: バインディング生成(4週間)
- Rust: #[nyash_abi]マクロ
- C++: NYASH_PLUGIN()マクロ
- Python: @nyash_plugin デコレータ
- JavaScript: NyashPlugin基底クラス
🔍 型レジストリ設計
型IDの生成戦略
// 型ID = カテゴリ(16bit) + ハッシュ(48bit)
fn generate_type_id(category: u16, type_name: &str) -> u64 {
let hash = xxhash64(type_name.as_bytes());
((category as u64) << 48) | (hash & 0xFFFF_FFFF_FFFF)
}
// 既知の型は事前定義
const TYPE_ID_STRING: u64 = 0x0002_0000_0000_0001;
const TYPE_ID_ARRAY: u64 = 0x0003_0000_0000_0002;
const TYPE_ID_MAP: u64 = 0x0004_0000_0000_0003;
⚡ 最適化戦略
JIT/AOT統合
// JIT時の特殊化
if method_id == KNOWN_METHOD_ADD && is_inline_i64(arg1) && is_inline_i64(arg2) {
// 直接的な整数加算にコンパイル
emit_add_i64(arg1.box_handle, arg2.box_handle);
} else {
// 通常のNyashFunc呼び出し
emit_nyash_func_call(func_ptr, args);
}
メモリ管理
// 参照カウント最適化
if metadata & NYASH_META_BORROWED != 0 {
// 借用フラグ付き → Arc::clone不要
use_without_clone(box_handle);
} else {
// 通常の参照カウント
Arc::clone(box_handle);
}
📊 互換性マトリックス
| 機能 | C ABI | Nyash ABI | 自動変換 |
|---|---|---|---|
| 基本型引数 | ✅ | ✅ | 自動 |
| Box引数 | ポインタ | ハンドル | トランポリン |
| 戻り値 | malloc | NyashValue | トランポリン |
| エラー処理 | NULL | ERRORフラグ | 変換可能 |
| 非同期 | ❌ | ASYNCフラグ | - |
| メソッドID | 文字列 | u32 | ハッシュ |
🚀 次のステップ
- nyash_abi.hの作成(crates/nyrt/include/)
- 最小実装プラグイン作成(SimpleMathの両ABI版)
- ベンチマーク測定(オーバーヘッド評価)
- 移行判断(データに基づく方向性決定)
既存を壊さず、新しい世界を開く - これがNyash ABIの道