Major changes: - LLVM backend initial implementation (compiler.rs, llvm mode) - Semantics layer integration in interpreter (operators.rs) - Phase 12 plugin architecture revision (3-layer system) - Builtin box removal preparation - MIR instruction set documentation (26→Core-15 migration) - Cross-backend testing infrastructure - Await/nowait syntax support New features: - LLVM AOT compilation support (--backend llvm) - Semantics layer for interpreter→VM flow - Tri-backend smoke tests - Plugin-only registry mode Bug fixes: - Interpreter plugin box arithmetic operations - Branch test returns incorrect values Documentation: - Phase 12 README.md updated with new plugin architecture - Removed obsolete NYIR proposals - Added LLVM test programs documentation Co-Authored-By: Claude <noreply@anthropic.com>
9.5 KiB
9.5 KiB
Codex先生の技術提案:Nyashスクリプトプラグインシステム実装
エグゼクティブサマリー
Nyashスクリプトをプラグインとして使用する提案は、技術的に極めて実現可能であり、Nyashエコシステムに革命的な価値をもたらします。「Everything is Box」哲学の究極の実現として、実装言語に依存しない統一インターフェースを提供することで、開発の民主化とエコシステムの爆発的成長が期待できます。
技術アーキテクチャ提案
1. 統一Box ABIの詳細設計
// コアインターフェース定義
pub trait UnifiedBoxInterface: Send + Sync {
// 基本メソッド
fn invoke(&self, ctx: &mut Context, method_id: u32, args: &[NyashValue]) -> Result<NyashValue, BoxError>;
fn get_metadata(&self) -> BoxMetadata;
// ライフサイクル管理
fn initialize(&mut self, config: &BoxConfig) -> Result<(), BoxError>;
fn shutdown(&mut self) -> Result<(), BoxError>;
// 動的機能(オプション)
fn hot_reload(&mut self, new_code: &str) -> Result<(), BoxError> {
Err(BoxError::NotSupported)
}
}
// メタデータ構造
pub struct BoxMetadata {
pub name: String,
pub version: String,
pub methods: Vec<MethodInfo>,
pub capabilities: Vec<Capability>,
pub dependencies: Vec<Dependency>,
}
2. プラグインレジストリアーキテクチャ
pub struct PluginRegistry {
// ネイティブプラグイン
native_plugins: HashMap<u32, Arc<dyn UnifiedBoxInterface>>,
// スクリプトプラグイン
script_plugins: HashMap<u32, ScriptPlugin>,
// 動的ID管理
id_allocator: IdAllocator,
// 依存関係グラフ
dependency_graph: DependencyGraph,
}
impl PluginRegistry {
pub fn register_native(&mut self, plugin: impl UnifiedBoxInterface + 'static) -> u32 {
let id = self.id_allocator.allocate();
self.native_plugins.insert(id, Arc::new(plugin));
id
}
pub fn register_script(&mut self, source: &str) -> Result<u32, RegistryError> {
let plugin = ScriptPlugin::compile(source)?;
let id = self.id_allocator.allocate();
self.script_plugins.insert(id, plugin);
Ok(id)
}
}
3. スクリプトプラグインラッパー実装
pub struct ScriptPlugin {
vm: NyashVM,
box_instance: NyashValue,
method_cache: HashMap<u32, MethodHandle>,
}
impl UnifiedBoxInterface for ScriptPlugin {
fn invoke(&self, ctx: &mut Context, method_id: u32, args: &[NyashValue]) -> Result<NyashValue, BoxError> {
// メソッドキャッシュから高速検索
if let Some(handle) = self.method_cache.get(&method_id) {
return self.vm.call_cached(handle, args);
}
// 動的メソッド解決
let method = self.resolve_method(method_id)?;
self.vm.call_method(&self.box_instance, &method, args)
}
}
実装戦略
Phase 1: MVP実装(2-3週間)
-
基本インターフェース実装
- UnifiedBoxInterfaceトレイトの実装
- 既存FFIプラグイン1つを移行(MathBox推奨)
- ScriptPluginラッパーの基本実装
-
export box構文の実装
export box MyPlugin { init { _version = "1.0.0" } // 必須:プラグインメタデータ get_metadata() { return { name: "MyPlugin", version: me._version, methods: ["process", "transform"] } } // ビジネスロジック process(data) { ... } transform(input) { ... } } -
基本的なレジストリ
- 静的登録のみ
- 依存関係解決なし
Phase 2: 動的機能(3-4週間)
-
動的ロード/アンロード
local registry = new PluginRegistry() local id = registry.load_script("path/to/plugin.ny") registry.unload(id) -
ホットリロード
registry.enable_hot_reload("path/to/plugin.ny") // ファイル変更時に自動リロード -
依存関係管理
- 循環依存検出
- バージョン互換性チェック
Phase 3: 最適化とセキュリティ(4-6週間)
-
パフォーマンス最適化
- メソッドキャッシング
- JITコンパイル統合
- プリコンパイルオプション
-
セキュリティサンドボックス
pub struct Sandbox { memory_limit: usize, cpu_quota: Duration, allowed_capabilities: HashSet<Capability>, } -
ケイパビリティベースセキュリティ
- ファイルアクセス制限
- ネットワーク制限
- システムコール制限
パフォーマンス考察
ベンチマーク予測
操作 | ネイティブ | スクリプト | 比率
--------------------|-----------|-----------|-----
単純メソッド呼び出し | 10ns | 100ns | 10x
複雑な計算(1000ops) | 1μs | 5μs | 5x
I/O操作 | 100μs | 102μs | 1.02x
最適化戦略
-
ホットパスの識別
- 頻繁に呼ばれるメソッドを自動検出
- JITコンパイル優先度付け
-
ハイブリッドアプローチ
- コア機能:ネイティブ実装
- カスタマイズ層:スクリプト実装
エコシステムへの影響
開発者体験の革新
-
即座のフィードバックループ
# 編集 vim my_plugin.ny # 即座にテスト(ビルド不要) nyash test_plugin.ny -
プラグインマーケットプレイス
- GitHubから直接インストール
- バージョン管理統合
- 自動更新機能
コミュニティ成長予測
- 現在: 10-20人のコアコントリビューター(Rust必須)
- 1年後: 100-500人のプラグイン開発者(Nyashのみ)
- 3年後: 1000+のプラグインエコシステム
リスクと緩和策
技術的リスク
-
パフォーマンス劣化
- 緩和策:重要部分のネイティブ実装維持
- プロファイリングツール提供
-
セキュリティ脆弱性
- 緩和策:デフォルトサンドボックス
- 署名付きプラグイン
エコシステムリスク
-
品質のばらつき
- 緩和策:公式プラグインガイドライン
- 自動品質チェックツール
-
互換性問題
- 緩和策:セマンティックバージョニング強制
- 自動互換性テスト
結論と推奨事項
即時実行すべきアクション
- Box ABI仕様書の作成(1週間)
- export box構文の実装(2週間)
- MathBoxの統一インターフェース移行(1週間)
長期ビジョン
Nyashスクリプトプラグインシステムは、単なる機能追加ではなく、Nyashをプログラミング言語から拡張可能なプラットフォームへと進化させる革命的な一歩です。
「Everything is Box」の哲学が、実装言語の壁を超えて真に実現される時、Nyashは次世代のプログラミングエコシステムのモデルケースとなるでしょう。
付録:実装例
A. 完全なスクリプトプラグイン例
# advanced_math_plugin.ny
export box AdvancedMathPlugin {
init {
_math = new MathBox()
_cache = new MapBox()
_stats = new MapBox()
}
// プラグインメタデータ(必須)
get_metadata() {
return {
name: "AdvancedMathPlugin",
version: "1.0.0",
methods: ["cached_sin", "cached_cos", "fibonacci", "factorial"],
capabilities: ["compute"],
dependencies: [{
name: "MathBox",
version: ">=1.0.0"
}]
}
}
// キャッシュ付き三角関数
cached_sin(x) {
local key = "sin:" + x.toString()
if me._cache.has(key) {
me._update_stats("cache_hit")
return me._cache.get(key)
}
local result = me._math.sin(x)
me._cache.set(key, result)
me._update_stats("cache_miss")
return result
}
// 再帰的フィボナッチ(メモ化)
fibonacci(n) {
if n <= 1 { return n }
local key = "fib:" + n.toString()
if me._cache.has(key) {
return me._cache.get(key)
}
local result = me.fibonacci(n-1) + me.fibonacci(n-2)
me._cache.set(key, result)
return result
}
// 統計情報
get_stats() {
return me._stats
}
// プライベートメソッド
_update_stats(event) {
local count = me._stats.get(event) or 0
me._stats.set(event, count + 1)
}
}
B. ネイティブとスクリプトの透過的利用
// 使用側のコード(プラグインの実装言語を意識しない)
local math1 = new MathBox() // ネイティブプラグイン
local math2 = include("advanced_math_plugin.ny") // スクリプトプラグイン
// 同じインターフェースで利用
print(math1.sin(3.14)) // ネイティブ実装
print(math2.cached_sin(3.14)) // スクリプト実装
// 動的に切り替え可能
local math = get_config("use_cached") ? math2 : math1
print(math.sin(1.57))
"Write plugins in Nyash, for Nyash, by Nyash!"