feat: Phase 10.5 Python統合プラグインとAOTビルド対応

- Pythonプラグイン(PyRuntimeBox/PyObjectBox)を追加
  - eval, import, getattr, call, callKw, strメソッド実装
  - math.sqrtデモ等のサンプルコード追加
- AOTビルドサポート追加
  - libnyrtランタイムライブラリ
  - build_aot.shビルドスクリプト
- .gitignore改善
  - JSONLとDOTファイル除外
  - プラグインのビルド成果物除外
- 不要ファイル削除
  - nekocode-temp, zenn_articles
  - 一時的なログファイル類

Phase 10.1の新計画に基づいて、プラグインBox統一化を推進
This commit is contained in:
Moe Charm
2025-08-29 10:22:44 +09:00
parent 12adde9477
commit d24149d0a1
24 changed files with 1057 additions and 867 deletions

View File

@ -21,14 +21,14 @@ Phase 10.10 は完了DoD確認済。**重大な発見**:プラグイン
- JitPolicyBoxallowlist/presets/ HostCallのRO運用events連携
- CIスモーク導入runtime/compile-events/ 代表サンプル整備
- 🔧 DoingPhase 10.1 新計画)
- ArrayBoxのプラグイン化PoC開始
- JIT lowering層の統一設計
- NewBox→birthのJIT loweringString/Integer、handleベース
- AOT最小EXE: libnyrt.aシム + ny_main ドライバ + build_aot.sh 整備
- リファクタリング作業は継続core_hostcall.rs完了
- ⏭️ NextPhase 10.1 実装)
- Week1: ArrayBoxプラグイン化と性能測定
- Week2: 主要ビルトインBoxの移行
- Week3: スタティックリンク基盤構築
- Week4: EXE生成実証
- Week1: 主要ビルトインBoxの移行RO中心
- Week2: 静的同梱基盤の設計type_id→nyplug_*_invoke ディスパッチ)
- Week3: ベンチ/観測性整備JIT fallback理由の粒度
- Week4: AOT配布体験の改善nyash.toml/soの探索・ガイド
## リファクタリング計画(機能差分なし)
1) core_hostcall 分割イベントloweremit_host_call周辺
@ -60,6 +60,29 @@ Phase 10.10 は完了DoD確認済。**重大な発見**:プラグイン
- 参照: `docs/development/roadmap/phases/phase-10.5/` 移動済み
- ChatGPT5の当初計画を後段フェーズへ
### 進捗10.5a→10.5b 最小実装)
- 新規: `plugins/nyash-python-plugin/` 追加ABI v1動的 `libpython3.x` ローダ
- Box: `PyRuntimeBox(type_id=40)`, `PyObjectBox(type_id=41)` `nyash.toml` に登録
- 実装: `birth/fini`Runtime, `eval/import`Handle返却, `getattr`Handle返却, `call`int/string/bool/handle対応 `callKw`kwargs対応key:stringと値のペア , `str`String返却
- 設計ドキュメント: `docs/development/roadmap/phases/phase-10.5/10.5a-ABI-DESIGN.md`
### ビルド/テスト結果2025-08-29
- Pythonプラグインビルド成功警告ありだが動作問題なし
- 本体ビルド成功Cranelift JIT有効
- プラグインロード成功`libnyash_python_plugin.so` 初期化OK
- `PyRuntimeBox.birth()` 正常実行instance_id=1
- VM側委譲: `PluginBoxV2` メソッドを `PluginHost.invoke_instance_method` に委譲BoxCallでも実体plugin_invoke実行
- E2Eデモ: `py.import("math").getattr("sqrt").call(9).str()` がVM経路で実行`examples/py_math_sqrt_demo.nyash`
### 方針決定Built-inとの関係
- いまはビルトインBoxを削除しない余計な変更を避けプラグイン優先の運用で干渉を止める
- テストCIをプラグイン経路に寄せ十分に安定してから段階的に外す
### 次アクション(小さく通す)
1) Loaderのエンコード強化v2: Bool/F64/BytesArray<u8>)を正式サポート → kwargsや一般引数を堅牢化
2) 戻り値自動デコード(オプトイン): `NYASH_PY_AUTODECODE=1` 設計(数値/文字列/bytesのTLV変換。段階的に導入。
3) 例外のResult化: returns_resultの扱い整理成功文字列とエラー文字列の判別手段の仕様化
## すぐ試せるコマンド(現状維持の確認)
```bash
# BuildCranelift込み推奨
@ -88,6 +111,38 @@ NYASH_CLI_VERBOSE=1 ./target/release/nyash --backend vm examples/array_plugin_de
NYASH_CLI_VERBOSE=1 ./target/release/nyash --backend vm examples/array_plugin_set_demo.nyash
NYASH_CLI_VERBOSE=1 ./target/release/nyash --backend vm examples/map_plugin_ro_demo.nyash
# Python plugin demoPhase 10.5
(cd plugins/nyash-python-plugin && cargo build --release)
NYASH_CLI_VERBOSE=1 ./target/release/nyash --backend vm examples/py_eval_demo.nyash
# 追加デバッグTLVダンプ
NYASH_DEBUG_PLUGIN=1 NYASH_CLI_VERBOSE=1 ./target/release/nyash --backend vm examples/py_eval_demo.nyash
# math.sqrtデモimport→getattr→call→str
NYASH_CLI_VERBOSE=1 ./target/release/nyash --backend vm examples/py_math_sqrt_demo.nyash
# kwargsデモbuiltins.int
NYASH_CLI_VERBOSE=1 ./target/release/nyash --backend vm examples/py_kw_round_demo.nyash
# kwargsデモbuiltins.int
NYASH_CLI_VERBOSE=1 ./target/release/nyash --backend vm examples/py_kw_round_demo.nyash
## AOT最小EXENew!
```bash
# 1) .o生成Cranelift必須
NYASH_AOT_OBJECT_OUT=target/aot_objects \
NYASH_USE_PLUGIN_BUILTINS=1 NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 \
./target/release/nyash --backend vm examples/aot_min_string_len.nyash
# 2) libnyrtビルド + リンク + 実行Linux例
(cd crates/nyrt && cargo build --release)
cc target/aot_objects/main.o -L crates/nyrt/target/release \
-Wl,--whole-archive -lnyrt -Wl,--no-whole-archive -lpthread -ldl -lm -o app
./app
# 3) ワンコマンド
bash tools/build_aot.sh examples/aot_min_string_len.nyash -o app
```
## ⏭️ NextPhase 10.2: JIT実呼び出しの実体化
- 目的: Craneliftの `emit_plugin_invoke` を実装し、JITでも実体のプラグインAPIを呼ぶ
- 方針:

View File

@ -0,0 +1,53 @@
# Phase 10.5a Python 統合 ABI 設計Draft
目的: Everything is Plugin/AOT の既存基盤上に Python を最小リスクで統合するための ABI と型・メソッド定義を固定する。
## スコープ10.5a
- v2 プラグイン ABI 準拠(`nyash_plugin_abi/init/invoke`)の Python プラグイン雛形を作成
- 2 Box を定義: `PyRuntimeBox(type_id=40)`, `PyObjectBox(type_id=41)`
- メソッド ID の割り当てと TLV 方針を文書化(実装は 10.5b 以降)
## TLV マッピング(現行運用)
- 1 = Bool (1 byte)
- 2 = I32 (4 bytes, LE)
- 3 = I64 (8 bytes, LE)
- 4 = F32 (4 bytes, LE)
- 5 = F64 (8 bytes, LE)
- 6 = String (UTF-8, n bytes)
- 7 = Bytes (opaque, n bytes)
- 8 = Handle/BoxRef (`u32 type_id || u32 instance_id`)
備考: 既存ドキュメントには古い表記の混在があるため、VM_README 準拠で統一。
## Box とメソッド設計
### PyRuntimeBox (type_id=40)
- birth(0): ランタイムの生成(後続で GIL 初期化などを担当)。戻り値: `instance_id`(非 TLV, u32 LE
- eval(1, code: String): Python コードを評価して `PyObjectBox` を返す。戻り値: `Handle(tag=8)`
- import(2, name: String): `__import__(name)` または `importlib.import_module`。戻り値: `Handle(tag=8)`
- fini(MAX): ランタイム破棄GIL 終了・クリーンアップ)
### PyObjectBox (type_id=41)
- birth(0): 予約(通常は runtime 側から生まれる)
- getattr(1, name: String): 属性取得 → `Handle(tag=8)`
- call(2, args: TLV...): 可変長引数。初期段は I64/String/Bool/Bytes/Handle のサブセットに限定。戻り値: `Handle(tag=8)`
- str(3): Python 側で `PyObject_Str` → String へ。戻り値: `String(tag=6)`
- fini(MAX): 参照カウント `Py_DECREF` に対応(後続)
## 参照管理・GIL概要
- GIL: birth/invoke/fini の入口で確保し、出口で解放(再入を許容)。
- 参照: `PyObjectBox` は生成時に `INCREF``fini``DECREF`。ランタイム終了時に孤立検知の簡易テストを導入。
## 設定ファイルnyash.toml
- `libnyash_python_plugin.so` を 2 Box 含む形で登録path/type_id/method_id を固定)
- JIT/VM 側は既存の `plugin_invoke` 経由で呼び出しAOT は 10.5d で `libnyrt.a` にシム追加)
## 次フェーズ10.5b 以降)
- 10.5b: `PyRuntimeBox`/`PyObjectBox` 実装CPython 埋め込み、最小 RO 経路)
- 10.5c: Python→Nyash 方向CPython 拡張 `nyashrt`
- 10.5d: JIT/AOT 連携(`emit_plugin_invoke` 対応・静的リンクシム)
- 10.5e: サンプル・テスト・ドキュメント
---
補足: 本ドキュメントは「設計の固定」を目的とし、実装は段階的に進める。タグ/ID は既存と衝突しない値を選定した40/41

View File

@ -1,80 +1,60 @@
# Phase 10.5 - PythonParserBox実装
*(旧Phase 10.1 - プラグインBox統一化の発見により番号変更)*
# Phase 10.5 Python ネイティブ統合Embedding & FFI
*(旧10.1の一部を後段フェーズに再編。Everything is Plugin/AOTの基盤上で実現)*
見ただけで実装手順が分かる!順番通りに進めてください
NyashとPythonを双方向に“ネイティブ”接続する。第一段はNyash→Python呼び出しEmbedding、続いてPython→NyashExtending。JIT/AOT/Pluginの統一面を活かし、最小のC ABIで着地する
## 📂 サブフェーズ構成(順番に実行
## 📂 サブフェーズ構成(10.5a → 10.5e
### 📋 Phase 10.1a - 計画と設計
最初にここから!全体像を理解する。
- 統合実装計画を読む
- エキスパート評価を確認
- 5つの核心戦略を把握
### 10.5a 設計・ABI整合12日
- ルート選択:
- Embedding: NyashプロセスにCPythonを埋め込み、PyObject*をハンドル管理
- Extending: Python拡張モジュールnyashrtを提供し、PythonからNyashを呼ぶ
- ABI方針:
- ハンドル: TLV tag=8type_id+instance_id。Pythonオブジェクトは `PyObjectBox` として格納
- 変換: Nyash ⇄ Python で Bool/I64/String/Bytes/Handle を相互変換
- GIL: birth/invoke/decRef中はGIL確保。AOTでも同等
### ⚙️ Phase 10.1b - 環境設定
開発環境を整える。
- Python 3.11.9をインストール
- Cargo.tomlに依存関係追加
- ディレクトリ構造準備
### 10.5b PyRuntimeBox / PyObjectBox 実装35日
- `PyRuntimeBox`(シングルトン): `eval(code) -> Handle` / `import(name) -> Handle`
- `PyObjectBox`: `getattr(name) -> Handle` / `call(args...) -> Handle` / `str() -> String`
- 参照管理: `Py_INCREF`/`Py_DECREF` をBoxライフサイクルfiniに接続
- プラグイン化: `nyash-python-plugin`cdylib/staticlib`nyplug_python_invoke` を提供(将来の静的同梱に対応)
### 🔧 Phase 10.1c - パーサー統合
CPythonパーサーをNyashに統合。
- PythonParserBox実装
- GIL管理の実装
- JSON中間表現への変換
### 10.5c 境界の双方向化35日
- Nyash→Python: BoxCall→plugin_invokeでCPython C-APIに橋渡し
- Python→Nyash: `nyashrt`CPython拡張`nyash.call(func, args)` を提供
- エラーハンドリング: 例外は文字列化tag=6でNyashに返却、またはResult化
### 💻 Phase 10.1d - Core実装
基本的なPython構文の変換。
- Phase 1機能def/if/for/while
- 意味論の正確な実装
- 70%コンパイル率達成
### 10.5d JIT/AOT 統合35日
- JIT: `emit_plugin_invoke` で Pythonメソッド呼びを許可ROから開始
- AOT: libnyrt.a に `nyash.python.*` シムbirth_hなどを追加し、ObjectModuleの未解決を解決
- 静的同梱経路: `nyrt` に type_id→`nyplug_python_invoke` ディスパッチテーブルを実装(または各プラグイン名ごとのルータ)。第一段は動的ロード優先
### 🔄 Phase 10.1e - トランスパイラー
Python→Nyashソース変換。
- AST→Nyashソース生成
- フォーマッター実装
- コマンドラインツール
### 10.5e サンプル/テスト/ドキュメント1週間
- サンプル: `py.eval("'hello' * 3").str()``numpy`の軽量ケースimport/shape参照などRO中心
- テスト: GILの再入・参照カウントリーク検知・例外伝搬・多プラットフォーム
- ドキュメント: 使用例、制約GIL/スレッド、AOT時のリンク・ランタイム要件
### 🧪 Phase 10.1f - テスト
Differential Testingでバグ発見。
- CPython vs Nyash比較
- ベンチマーク実行
- バグ修正とCI統合
## 🎯 DoD定義
- NyashからPythonコードを評価し、PyObjectをHandleで往復できる
- 代表的なプロパティ取得/呼び出しROがJIT/VMで動作
- AOTリンク後のEXEで `py.eval()` 代表例が起動できる(動的ロード前提)
### 📚 Phase 10.1g - ドキュメント
使い方を文書化してリリース。
- ユーザーガイド作成
- APIリファレンス
- サンプルプロジェクト
## ⌛ 目安
| サブフェーズ | 目安 |
|---|---|
| 10.5a 設計 | 12日 |
| 10.5b 実装 | 35日 |
| 10.5c 双方向 | 35日 |
| 10.5d JIT/AOT | 35日 |
| 10.5e 仕上げ | 1週間 |
## 🎯 各フェーズの目安時間
| フェーズ | 内容 | 目安時間 |
|---------|------|----------|
| 10.1a | 計画理解 | 2-3時間 |
| 10.1b | 環境設定 | 1-2時間 |
| 10.1c | パーサー統合 | 3-5日 |
| 10.1d | Core実装 | 1-2週間 |
| 10.1e | トランスパイラー | 3-5日 |
| 10.1f | テスト | 1週間 |
| 10.1g | ドキュメント | 3-5日 |
**合計**: 約1ヶ月
## 🌟 最終目標
- **70%以上**の関数がコンパイル可能
- **2-10倍**の性能向上
- **10件以上**のNyashバグ発見
- **実用的な**Python→Nyash移行ツール
## 💡 Tips
- 各フェーズのREADME.mdを必ず読む
- 完了条件をチェックしながら進める
- テレメトリーで進捗を確認
- 困ったらarchive/の資料も参照
## ⚠️ リスクと対策
- GILデッドロック: 入口/出口で厳格に確保/解放。ネスト呼び出しの方針を文書化
- 参照カウント漏れ: BoxライフサイクルでDECREFを必ず実施、リークテストを追加
- リンク/配布: Linux/macOS優先。WindowsのPythonリンクは後段で対応
- 性能: RO先行でJITに寄せ、ミューテーションはポリシー制御
---
**さあ、Phase 10.1a から始めましょう!**
次は 10.5a設計・ABI整合から着手。Everything is Plugin / libnyrt シムの成功パターンをPythonにも適用し、最小リスクで“Pythonネイティブ”を実現する。