docs: restore docs/private/roadmap from 7b4908f9 (Phase 20.31)
This commit is contained in:
@ -0,0 +1,193 @@
|
||||
# Design - 設計ドキュメント
|
||||
|
||||
## 📋 概要
|
||||
|
||||
Python-Hakorune統合の設計ドキュメント集です。
|
||||
|
||||
## 📁 ファイル一覧
|
||||
|
||||
### 🌟 最新設計(2025-10-02追加)
|
||||
- **[enhanced-architecture-v2.md](enhanced-architecture-v2.md)** ⭐必読 - ChatGPT Pro UltraThink強化版アーキテクチャ
|
||||
- **[meta-config-examples.md](meta-config-examples.md)** - hako.toml設定リファレンス
|
||||
- **[risks-and-mitigations.md](risks-and-mitigations.md)** - リスク管理ドキュメント
|
||||
|
||||
### ABI・FFI設計
|
||||
- **[abi-design.md](abi-design.md)** - Python-Hakorune ABI設計
|
||||
- **[handle-first-plugininvoke-plan.md](handle-first-plugininvoke-plan.md)** - Handle-First PluginInvoke設計
|
||||
|
||||
### ビルド・実行
|
||||
- **[native-build-consolidation.md](native-build-consolidation.md)** - ネイティブビルド基盤設計
|
||||
|
||||
## 🎯 設計の核心
|
||||
|
||||
### 1. ABI設計方針
|
||||
|
||||
#### ハンドル管理
|
||||
- **TLV tag=8**: Python object handle
|
||||
- **type_id + instance_id**: 箱の識別
|
||||
- **Arc<PyObject>**: Rust側での管理
|
||||
|
||||
#### 型変換
|
||||
|
||||
| Hakorune | Python | 備考 |
|
||||
|---------|--------|------|
|
||||
| BoolBox | bool | 真偽値 |
|
||||
| IntegerBox | int | 整数 |
|
||||
| StringBox | str | 文字列 |
|
||||
| ArrayBox | list | 配列 |
|
||||
| MapBox | dict | 辞書 |
|
||||
| PyObjectBox | object | 任意のPythonオブジェクト |
|
||||
|
||||
### 2. Handle-First 設計
|
||||
|
||||
#### 原則
|
||||
- 第一引数(a0)は常にハンドル
|
||||
- `nyash.handle.of(receiver)` で変換
|
||||
- TLV統一: String/Integer以外はHandle(tag=8)
|
||||
|
||||
#### メリット
|
||||
- 型安全性の向上
|
||||
- 統一されたインターフェース
|
||||
- デバッグの容易さ
|
||||
|
||||
### 3. GIL管理戦略
|
||||
|
||||
#### 基本方針
|
||||
- **birth/invoke/decRef中はGIL確保**
|
||||
- **AOTでも同等の処理**
|
||||
- **ネスト呼び出しの安全性保証**
|
||||
|
||||
#### 実装パターン
|
||||
```rust
|
||||
pub fn invoke_python_method(handle: Handle, method: &str, args: &[Value]) -> Result<Value> {
|
||||
// GIL獲得
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
// Pythonオブジェクト取得
|
||||
let obj = get_pyobject_from_handle(handle)?;
|
||||
|
||||
// メソッド呼び出し
|
||||
let result = obj.call_method(py, method, args, None)?;
|
||||
|
||||
// 結果を変換
|
||||
let value = pyobject_to_value(result)?;
|
||||
|
||||
Ok(value)
|
||||
// GILは自動解放
|
||||
}
|
||||
```
|
||||
|
||||
## 🏗️ アーキテクチャ概要
|
||||
|
||||
### レイヤー構造
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ Hakorune Application │
|
||||
├─────────────────────────────────┤
|
||||
│ Python Integration Layer │
|
||||
│ - PyRuntimeBox │
|
||||
│ - PyObjectBox │
|
||||
├─────────────────────────────────┤
|
||||
│ FFI/Plugin Interface │
|
||||
│ - Handle-First design │
|
||||
│ - TLV type system │
|
||||
├─────────────────────────────────┤
|
||||
│ CPython C API │
|
||||
├─────────────────────────────────┤
|
||||
│ CPython Runtime │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
### プラグイン構成
|
||||
|
||||
```
|
||||
hakorune-python-plugin/
|
||||
├── src/
|
||||
│ ├── lib.rs # FFI entry point
|
||||
│ ├── runtime.rs # PyRuntimeBox
|
||||
│ ├── object.rs # PyObjectBox
|
||||
│ ├── conversion.rs # 型変換
|
||||
│ └── gil.rs # GIL管理
|
||||
├── Cargo.toml
|
||||
└── build.rs
|
||||
```
|
||||
|
||||
## 🔧 ネイティブビルド戦略
|
||||
|
||||
### AOT/EXEパイプライン
|
||||
|
||||
```
|
||||
Hakorune Source (.hkr)
|
||||
↓ Parse
|
||||
AST
|
||||
↓ Lower
|
||||
MIR
|
||||
↓ JIT Compile
|
||||
CLIF IR
|
||||
↓ Object Generation
|
||||
Object File (.o)
|
||||
↓ Link (with libhakorunert.a + Python libs)
|
||||
Native Executable
|
||||
```
|
||||
|
||||
### クロスプラットフォーム対応
|
||||
|
||||
| Platform | Python Library | 備考 |
|
||||
|----------|---------------|------|
|
||||
| Linux | libpython3.X.so | 動的リンク |
|
||||
| macOS | libpython3.X.dylib | 動的リンク |
|
||||
| Windows | python3X.dll | 動的リンク |
|
||||
|
||||
## 📊 設計決定事項
|
||||
|
||||
### 1. Embedding vs Extending
|
||||
|
||||
**決定**: Embedding優先
|
||||
|
||||
理由:
|
||||
- HakoruneからPythonを制御
|
||||
- デプロイが簡単
|
||||
- ユーザー体験が良い
|
||||
|
||||
### 2. 静的 vs 動的リンク
|
||||
|
||||
**決定**: 動的リンク優先、静的リンクはオプション
|
||||
|
||||
理由:
|
||||
- Python標準の配布方法
|
||||
- ライセンス問題の回避
|
||||
- 柔軟性の確保
|
||||
|
||||
### 3. サポート対象Python
|
||||
|
||||
**決定**: Python 3.8以降
|
||||
|
||||
理由:
|
||||
- 型ヒントの充実
|
||||
- 十分な普及
|
||||
- メンテナンス負荷
|
||||
|
||||
## ⚠️ リスク要因
|
||||
|
||||
### 1. CPython依存
|
||||
- バージョン互換性
|
||||
- プラットフォーム差異
|
||||
- ビルド環境の複雑さ
|
||||
|
||||
### 2. パフォーマンス
|
||||
- FFIオーバーヘッド
|
||||
- GIL待機時間
|
||||
- メモリコピーコスト
|
||||
|
||||
### 3. デバッグ困難性
|
||||
- 言語境界を越えるエラー
|
||||
- スタックトレースの複雑さ
|
||||
- メモリリークの追跡
|
||||
|
||||
## 🔗 関連ドキュメント
|
||||
|
||||
- [Phase 20 メインREADME](../README.md)
|
||||
- [Planning](../planning/)
|
||||
- [Core Implementation](../core-implementation/)
|
||||
@ -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)。
|
||||
@ -0,0 +1,543 @@
|
||||
# Python-Hakorune統合 強化版アーキテクチャ v2
|
||||
|
||||
**作成**: 2025-10-02
|
||||
**ソース**: ChatGPT Pro UltraThink Mode
|
||||
**ステータス**: 設計提案
|
||||
|
||||
---
|
||||
|
||||
## 📋 概要
|
||||
|
||||
Phase 10.5の「Active」設計を踏まえつつ、**強化版Hakorune**(Effect/Capability/Contract/Policy・PHI検証・BlockVMap等)の上に載せる、**安全で境界に問題を閉じ込めたPythonブリッジ**の設計書です。
|
||||
|
||||
---
|
||||
|
||||
## 🎯 ねらい(Phase 10.5の「Active」意図との整合)
|
||||
|
||||
- 最小コアで **"箱(Box)に閉じ込めたPython実行環境"** を提供
|
||||
- VM/LLVM/AOTラインから同じ呼び出し規約で扱える
|
||||
- **当面はVMハーネス(llvmlite側)を使って決定実行とスモークの安定性を優先**、AOT/EXEは段階導入
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 1. Box階層(木構造)の基本セット
|
||||
|
||||
### PyRuntimeBox(ルート・単一 or 少数)
|
||||
|
||||
**役割**:
|
||||
- Pythonランタイム(CPython埋め込み)
|
||||
- `import` 解決
|
||||
- GIL管理
|
||||
- モジュールキャッシュ
|
||||
|
||||
**ライフサイクル**:
|
||||
- `init`: インタプリタ起動
|
||||
- `fini`: 停止
|
||||
- **Capability**で"import可能モジュール/FS/NET/ENV"を限定
|
||||
|
||||
**実装指針**:
|
||||
- まずは既存 **Plugin-First**(C ABI・TLV)でブリッジ
|
||||
- 後段で **Hakorune ABI(vtable)** に段階移行
|
||||
- `HAKO_ABI_VTABLE` 等のgateを活用
|
||||
|
||||
```hakorune
|
||||
box PyRuntimeBox {
|
||||
// 初期化・終了
|
||||
init()
|
||||
fini()
|
||||
|
||||
// モジュール
|
||||
import(name: StringBox) -> PyModuleBox
|
||||
reflect(module_name: StringBox) -> PyModuleBox
|
||||
|
||||
// 実行
|
||||
eval(code: StringBox) -> PyObjectBox
|
||||
exec(code: StringBox)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PyModuleBox
|
||||
|
||||
**役割**:
|
||||
- `import "pkg.mod"` の結果をBoxとして公開
|
||||
- 属性 = フィールド
|
||||
- 関数 = MethodBox
|
||||
|
||||
**ライフサイクル**:
|
||||
- `PyRuntimeBox` が所有
|
||||
- `fini` で参照解除(refcnt を減らす)
|
||||
|
||||
```hakorune
|
||||
box PyModuleBox {
|
||||
// 属性アクセス
|
||||
get(name: StringBox) -> PyObjectBox
|
||||
set(name: StringBox, value: PyObjectBox)
|
||||
|
||||
// 列挙
|
||||
list_attributes() -> ArrayBox
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PyTypeBox / PyInstanceBox
|
||||
|
||||
**役割**:
|
||||
- Pythonのクラス定義とインスタンスをBox化
|
||||
- `get/setField` と `call_method` を統一導線に
|
||||
|
||||
**所有権タグ**:
|
||||
- **shared**(CPython RC前提)
|
||||
- `unique` が必要な場合は"借用トークン"で一時的に排他操作を許可
|
||||
|
||||
```hakorune
|
||||
box PyTypeBox {
|
||||
// クラス情報
|
||||
get_name() -> StringBox
|
||||
get_bases() -> ArrayBox
|
||||
get_methods() -> ArrayBox
|
||||
|
||||
// インスタンス化
|
||||
new_instance(args: ArrayBox) -> PyInstanceBox
|
||||
}
|
||||
|
||||
box PyInstanceBox {
|
||||
// フィールドアクセス
|
||||
get_field(name: StringBox) -> PyObjectBox
|
||||
set_field(name: StringBox, value: PyObjectBox)
|
||||
|
||||
// メソッド呼び出し
|
||||
call_method(name: StringBox, args: ArrayBox) -> PyObjectBox
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PyFunctionBox / PyCallableBox
|
||||
|
||||
**役割**:
|
||||
- 呼出しを `exec(args)->result`(Pulse的)に落として**最小ライフサイクル**で扱える
|
||||
|
||||
```hakorune
|
||||
box PyFunctionBox {
|
||||
// Pulse: 完全な一発実行
|
||||
exec(args: ArrayBox) -> PyObjectBox
|
||||
|
||||
// メタ情報
|
||||
get_name() -> StringBox
|
||||
get_signature() -> StringBox
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PyIteratorBox / PyGeneratorBox(必要に応じて)
|
||||
|
||||
**役割**:
|
||||
- `__iter__`/`__next__` をBox化
|
||||
- flow実行と相性を取る
|
||||
|
||||
```hakorune
|
||||
box PyIteratorBox {
|
||||
next() -> PyObjectBox
|
||||
has_next() -> BoolBox
|
||||
}
|
||||
|
||||
box PyGeneratorBox {
|
||||
send(value: PyObjectBox) -> PyObjectBox
|
||||
throw(error: ErrorBox)
|
||||
}
|
||||
```
|
||||
|
||||
> **Phase 10.5の設計メモと整合**:"最小の箱から着手 → 後から拡張"
|
||||
|
||||
---
|
||||
|
||||
## 🔄 2. ライフサイクル対応(Hakorune流)
|
||||
|
||||
### init/fini
|
||||
|
||||
**PyRuntimeBox.init()**:
|
||||
```rust
|
||||
fn init() {
|
||||
Py_Initialize();
|
||||
// import policyのロード
|
||||
// キャッシュ構築
|
||||
}
|
||||
```
|
||||
|
||||
**PyRuntimeBox.fini()**:
|
||||
```rust
|
||||
fn fini() {
|
||||
// weakref.finalize併用で安全解放(循環対策)
|
||||
Py_Finalize();
|
||||
}
|
||||
```
|
||||
|
||||
### Pulse
|
||||
|
||||
**PyFunctionBox.exec** は完全Pulse(init/fini不要):
|
||||
- **作用範囲はmetaのCapabilityに閉じ込め**
|
||||
- 副作用は明示的にEffect宣言
|
||||
|
||||
### 所有権タグ
|
||||
|
||||
- 既定: **shared**(RC準拠)
|
||||
- **unique** が必要な経路: `BorrowMutToken` を発行して**単発処理中のみ**排他
|
||||
|
||||
> これらは **管理棟のトグル**とも親和性が高い(dev: 緩める / prod: 厳格)
|
||||
|
||||
---
|
||||
|
||||
## 🎭 3. Effect / Capability / Contract の外付け(meta)
|
||||
|
||||
### Effect(論理的効果名)
|
||||
|
||||
```toml
|
||||
[box.PyRuntimeBox.effects]
|
||||
available = [
|
||||
"py.import",
|
||||
"py.fs",
|
||||
"py.net",
|
||||
"py.env",
|
||||
"py.time",
|
||||
"py.random",
|
||||
"py.subprocess"
|
||||
]
|
||||
```
|
||||
|
||||
### Capability(許可リスト)
|
||||
|
||||
```toml
|
||||
[box.PyRuntimeBox.capabilities]
|
||||
allow = [
|
||||
"py.import:math",
|
||||
"py.import:json",
|
||||
"py.time:monotonic"
|
||||
]
|
||||
deny = [
|
||||
"py.subprocess",
|
||||
"py.net"
|
||||
]
|
||||
enforce = true # devではfalse→観測のみ
|
||||
```
|
||||
|
||||
### Contract
|
||||
|
||||
**Pre条件**:
|
||||
```toml
|
||||
[contracts.PyFunctionBox.exec]
|
||||
pre = [
|
||||
"args.len <= 8",
|
||||
"bytes_total <= 1_000_000"
|
||||
]
|
||||
```
|
||||
|
||||
**Post条件**:
|
||||
```toml
|
||||
[contracts.PyFunctionBox.exec]
|
||||
post = [
|
||||
"result.size <= 1_000_000",
|
||||
"no_exception",
|
||||
"allow_none = true"
|
||||
]
|
||||
```
|
||||
|
||||
### 監査トグル
|
||||
|
||||
```bash
|
||||
# Dev/CI
|
||||
HAKO_PLUGIN_CAPS_ENFORCE=1
|
||||
HAKO_CHECK_CONTRACTS=1
|
||||
|
||||
# Prod
|
||||
HAKO_PLUGIN_CAPS_ENFORCE=1
|
||||
HAKO_CHECK_CONTRACTS=0 # 警告のみ
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔁 4. Deterministic / Repro の扱い
|
||||
|
||||
### Deterministic モード
|
||||
|
||||
**問題**:
|
||||
- `random`, `time`, `os.urandom` 等は非決定的
|
||||
|
||||
**解決策**:
|
||||
- **Capability トークン経由**で提供するshimsを使用
|
||||
|
||||
**実装例**:
|
||||
|
||||
```python
|
||||
# py.random shim
|
||||
class DeterministicRandom:
|
||||
def __init__(self, seed):
|
||||
self._rng = random.Random(seed)
|
||||
|
||||
def random(self):
|
||||
return self._rng.random()
|
||||
|
||||
# py.time shim
|
||||
class LogicalClock:
|
||||
def __init__(self):
|
||||
self._tick = 0
|
||||
|
||||
def monotonic(self):
|
||||
self._tick += 1
|
||||
return float(self._tick)
|
||||
```
|
||||
|
||||
**トグル**:
|
||||
```bash
|
||||
# Deterministic モード有効化
|
||||
HAKO_DETERMINISTIC=1
|
||||
HAKO_TRACE_EFFECTS=1 # 効果ログ収集
|
||||
```
|
||||
|
||||
**メリット**:
|
||||
- **flow Main.main** 実行のスナップショット再現が可能
|
||||
- デバッグ容易性向上
|
||||
- テストの再現性保証
|
||||
|
||||
---
|
||||
|
||||
## 🌳 5. 木構造への「落とし方」(反射 → Box化)
|
||||
|
||||
### ビルダー(反射)
|
||||
|
||||
**PyRuntimeBox.reflect(module_name: String) -> PyModuleBox**:
|
||||
|
||||
1. `dir(module)` と `inspect` で**属性ツリーを走査**
|
||||
2. **Box**を生成
|
||||
3. **規約**:
|
||||
- 公開対象は `__all__` 優先
|
||||
- ない場合は `_` 先頭を除外
|
||||
- `@hako_export` デコレータがあれば優先で `FunctionBox` 化
|
||||
|
||||
**実装擬似コード**:
|
||||
|
||||
```python
|
||||
# Python側(リフレクションヘルパー)
|
||||
def reflect_module(module_name):
|
||||
mod = importlib.import_module(module_name)
|
||||
|
||||
# 属性リスト取得
|
||||
if hasattr(mod, '__all__'):
|
||||
attrs = mod.__all__
|
||||
else:
|
||||
attrs = [a for a in dir(mod) if not a.startswith('_')]
|
||||
|
||||
# Box化
|
||||
boxes = {}
|
||||
for attr_name in attrs:
|
||||
attr = getattr(mod, attr_name)
|
||||
|
||||
if callable(attr):
|
||||
boxes[attr_name] = create_function_box(attr)
|
||||
elif inspect.isclass(attr):
|
||||
boxes[attr_name] = create_type_box(attr)
|
||||
else:
|
||||
boxes[attr_name] = create_object_box(attr)
|
||||
|
||||
return boxes
|
||||
```
|
||||
|
||||
### 使用例
|
||||
|
||||
```hakorune
|
||||
using "python"
|
||||
|
||||
box Main {
|
||||
flow main() {
|
||||
// init: CPython起動
|
||||
let py = PyRuntimeBox();
|
||||
|
||||
// PyModuleBox
|
||||
let m = py.reflect("math");
|
||||
|
||||
// PyFunctionBox
|
||||
let sqrt = m.get("sqrt");
|
||||
|
||||
// 実行
|
||||
let r = sqrt.exec([2.0]);
|
||||
print(r); // -> 1.4142...
|
||||
|
||||
// 正常停止
|
||||
py.fini();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 反射で"木"を作り、**Box統一API(get/set/call)で走る** — Phase 10.5の「Activeは最小の箱から導入」を踏襲
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 6. 例外とエラー境界
|
||||
|
||||
### Python例外 → ErrorBox
|
||||
|
||||
```hakorune
|
||||
box ErrorBox {
|
||||
type: StringBox // "ZeroDivisionError"
|
||||
message: StringBox // "division by zero"
|
||||
traceback: StringBox // フルトレースバック
|
||||
}
|
||||
```
|
||||
|
||||
**変換例**:
|
||||
```python
|
||||
# Python側
|
||||
try:
|
||||
result = some_function()
|
||||
except Exception as e:
|
||||
return ErrorBox(
|
||||
type=type(e).__name__,
|
||||
message=str(e),
|
||||
traceback=traceback.format_exc()
|
||||
)
|
||||
```
|
||||
|
||||
### Contract違反
|
||||
|
||||
**Strict モード**:
|
||||
```bash
|
||||
HAKO_EXTERN_STRICT=1 # fail-fast
|
||||
```
|
||||
|
||||
**通常モード**:
|
||||
```bash
|
||||
HAKO_EXTERN_STRICT=0 # 警告 + ErrorBox返却
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎛️ 7. 実行ポリシーとトグル(管理棟)
|
||||
|
||||
### ハーネス
|
||||
|
||||
```bash
|
||||
# 既定でPythonハーネス使用
|
||||
HAKO_LLVM_USE_HARNESS=1 # デフォルトON
|
||||
```
|
||||
|
||||
### PHIオプション
|
||||
|
||||
**ブリッジ互換**(PHI-off):
|
||||
```bash
|
||||
HAKO_VERIFY_ALLOW_NO_PHI=1 # 互換用途のみ
|
||||
```
|
||||
|
||||
**統一**(PHI-on):
|
||||
```bash
|
||||
HAKO_VERIFY_ALLOW_NO_PHI=0 # 推奨
|
||||
# Verifierを**PHI直後に常時実行**
|
||||
```
|
||||
|
||||
**モード設定**:
|
||||
- Dev: fail-fast
|
||||
- Prod: 警告
|
||||
|
||||
### ABI
|
||||
|
||||
**初期**(C ABI - TLV):
|
||||
```bash
|
||||
HAKO_ABI_VTABLE=0 # C ABI使用
|
||||
```
|
||||
|
||||
**段階移行**(Hakorune ABI - vtable):
|
||||
```bash
|
||||
HAKO_ABI_VTABLE=1
|
||||
HAKO_ABI_STRICT=1 # フォールバック禁止
|
||||
```
|
||||
|
||||
### Plugin観測
|
||||
|
||||
```bash
|
||||
# CI/Dev
|
||||
HAKO_TRACE_EFFECTS=1
|
||||
HAKO_PLUGIN_META=1
|
||||
HAKO_PLUGIN_CAPS_ENFORCE=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 強化版Hakoruneでの設計図アップデート
|
||||
|
||||
### 1. 境界検証を"必須フェーズ"に
|
||||
|
||||
**実装**:
|
||||
- `finalize_phis()` の直後で **SSA/支配関係/到達性**を検証
|
||||
- Dev: 例外
|
||||
- Prod: 警告+トレース保全
|
||||
|
||||
**効果**:
|
||||
- Pythonブリッジ有無に関わらず**毎回**回る
|
||||
- IR品質を境界に閉じ込める
|
||||
|
||||
### 2. BlockVMap型でvmap/_current_vmapを統合
|
||||
|
||||
**実装**:
|
||||
- 参照は必ず `BlockVMap::at(block)` 経由
|
||||
- 呼び出し側から**どの視点が"真"か**を隠蔽
|
||||
|
||||
**効果**:
|
||||
- Python連携でもブロック境界で値がぶれない
|
||||
- 事故防止
|
||||
|
||||
### 3. InstructionContextを必須引数化
|
||||
|
||||
**実装**:
|
||||
- すべての `lower_*` に統一コンテキストを渡す
|
||||
- **ログ/例外に命令位置・BB名を強制添付**
|
||||
|
||||
**効果**:
|
||||
- 原因追跡が一気に楽に
|
||||
|
||||
### 4. flow Main.main を"仕様"として固定
|
||||
|
||||
**実装**:
|
||||
- Phase 10.5のActive方針と揃えて **flow優先**
|
||||
- staticを覚える必要なし
|
||||
|
||||
**効果**:
|
||||
- 入口の一意化
|
||||
- セルフホストの再現ビルド検証にも効く
|
||||
|
||||
### 5. 開発→本番の昇格パスを明確化
|
||||
|
||||
**Dev**:
|
||||
```bash
|
||||
HAKO_*_ENFORCE=0
|
||||
HAKO_TRACE=1
|
||||
# fail-fast ON
|
||||
```
|
||||
|
||||
**Prod**:
|
||||
```bash
|
||||
HAKO_*_ENFORCE=1
|
||||
HAKO_TRACE=0
|
||||
# fail-fast OFF(ErrorBox+警告)
|
||||
```
|
||||
|
||||
**効果**:
|
||||
- **管理棟env**にすでに集約されている設計
|
||||
- 運用で迷わない
|
||||
|
||||
---
|
||||
|
||||
## 🔗 関連ドキュメント
|
||||
|
||||
- [マイルストーン](../planning/milestones.md) - M0〜M6の詳細計画
|
||||
- [メタ設定例](meta-config-examples.md) - hako.toml設定例
|
||||
- [リスクと対策](risks-and-mitigations.md) - 既知のリスクと対策
|
||||
- [Phase 20 README](../README.md) - 全体概要
|
||||
|
||||
---
|
||||
|
||||
**最終更新**: 2025-10-02
|
||||
**作成者**: ChatGPT Pro (UltraThink Mode)
|
||||
**レビュー**: 未実施
|
||||
**ステータス**: 設計提案・Phase 15完了後に実装予定
|
||||
@ -0,0 +1,46 @@
|
||||
# Phase 10.5c — Handle-First PluginInvoke 設計(最優先計画)
|
||||
|
||||
目的: Python専用の型伝搬を撤廃し、プラグイン呼び出しを「Everything is Handle」で統一。Lowererは箱名や戻り型に依存しない最小知識で `PluginInvoke` を実Emitし、型解決は実行時(TLV/Handle)に委譲する。
|
||||
|
||||
## 背景と問題
|
||||
- 現状のLowererに「import/getattr/call の戻りを PyObjectBox とみなす」暫定コードが混入。これは Python 特化のハードコーディングで、将来のプラグイン拡張(File/Net/DB 等)にブレーキとなる。
|
||||
- すでに ABI/VM は TLV tag=8(Handle)を標準化。戻り値を Handle として受け取り、タイプ情報(type_id)は実行時に判明する。
|
||||
|
||||
## 原則(Handle-First)
|
||||
- すべてのプラグインメソッドの戻りは Handle(TLV: tag=8)またはプリミティブ(i64/f64/bool/string/bytes)。
|
||||
- Lowerer は「戻り型が box かどうか」だけを気にすればよい。個々の箱名(PyObjectBox 等)を前提にしない。
|
||||
- 型の詳細は `type_id` によって実行時に解決される。JIT/AOT は型非依存の汎用コード生成を行う。
|
||||
|
||||
## 設計
|
||||
1) メタデータ駆動
|
||||
- `nyash_box.toml` の `methods.*.returns = { type = "box" | "i64" | "f64" | "string" | "void" | ... }` を単一の参照源に。
|
||||
- `PluginHost.resolve_method` に `returns.type` を含む情報を公開(Lowerer から参照)。
|
||||
|
||||
2) Lowerer の汎用化
|
||||
- `PluginInvoke` を常に `emit_plugin_invoke(type_id, method_id, argc, has_ret)` に落とす。
|
||||
- 「戻りが box のときに特定箱名を記録する」実装を撤去。必要なら「dst は Handle(box)」のヒントのみ保持。
|
||||
- 受け手箱名が未確定の場合に備え、by-name 経路(後述)を用意。
|
||||
|
||||
3) by-name シム(任意→推奨)
|
||||
- `nyrt`/builder に `nyash_plugin_invoke_by_name_{i64,f64}(box_type_name?, method_name, a0, a1, a2)` を追加。
|
||||
- 受け手の箱名が Lowerer 時点で特定できない場合、by-name シムを使用して実行時に `method_id` を解決。
|
||||
|
||||
4) 実行時の統一
|
||||
- 既存の `nyash_plugin_invoke3_{i64,f64}` と同様に、TLVで引数を構築。Handle/プリミティブ変換(StringBox/IntegerBoxの自動プリミティブ化)を継続。
|
||||
- 戻りTLVの tag を見て i64/f64 経由の値化(`NYASH_JIT_NATIVE_F64`)またはハンドル登録を行う。
|
||||
|
||||
## マイルストーン
|
||||
- M1: Lowerer から Python特化の型伝搬を除去(dst=Handle ヒントのみ)。
|
||||
- M2: `PluginHost.resolve_method` 拡張で `returns.type` を取得可能に。
|
||||
- M3: by-name シムの追加と Lowerer 配線(箱名未確定時)。
|
||||
- M4: AOT 最小ケース(import→getattr→call)を Handle-First で Green。
|
||||
- M5: ドキュメントと CURRENT_TASK を刷新。
|
||||
|
||||
## 受け入れ条件(DoD)
|
||||
- VM: `py.import("math"); (math.getattr("sqrt")).call(9)` が Green(autodecode=1 で 3)。
|
||||
- AOT(strict): 上記チェーン最小例で unsupported=0。Console 出力経路は PluginInvoke または extern 経由で表示。
|
||||
- Lowerer に Python 固有の型分岐が存在しない(grepで検出不可)。
|
||||
|
||||
## 運用メモ
|
||||
- 将来的な最適化(箱名が静的に分かる場面での特殊化)は、Handle-First を壊さない範囲で「分岐の1箇所」に限定して導入する。
|
||||
|
||||
@ -0,0 +1,531 @@
|
||||
# hako.toml メタ設定例
|
||||
|
||||
**作成**: 2025-10-02
|
||||
**ソース**: ChatGPT Pro UltraThink Mode
|
||||
**用途**: Python統合のメタデータ設定リファレンス
|
||||
|
||||
---
|
||||
|
||||
## 📋 概要
|
||||
|
||||
Python-Hakorune統合における`hako.toml`の設定例集です。
|
||||
Effect/Capability/Contract/Policyの具体的な設定方法を示します。
|
||||
|
||||
---
|
||||
|
||||
## 🎯 基本設定
|
||||
|
||||
### 最小構成
|
||||
|
||||
```toml
|
||||
# hako.toml (minimal)
|
||||
[box.PyRuntimeBox]
|
||||
effects.allow = ["py.import:math"]
|
||||
```
|
||||
|
||||
### 標準構成
|
||||
|
||||
```toml
|
||||
# hako.toml (standard)
|
||||
[box.PyRuntimeBox]
|
||||
effects.allow = [
|
||||
"py.import:math",
|
||||
"py.import:json",
|
||||
"py.time:monotonic"
|
||||
]
|
||||
capabilities.enforce = true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎭 Effect設定
|
||||
|
||||
### 利用可能なEffect一覧
|
||||
|
||||
```toml
|
||||
[box.PyRuntimeBox.effects]
|
||||
available = [
|
||||
# モジュールインポート
|
||||
"py.import",
|
||||
|
||||
# ファイルシステム
|
||||
"py.fs.read",
|
||||
"py.fs.write",
|
||||
|
||||
# ネットワーク
|
||||
"py.net.http",
|
||||
"py.net.socket",
|
||||
|
||||
# 環境変数
|
||||
"py.env.read",
|
||||
"py.env.write",
|
||||
|
||||
# 時刻
|
||||
"py.time.monotonic",
|
||||
"py.time.real",
|
||||
|
||||
# ランダム
|
||||
"py.random",
|
||||
|
||||
# プロセス
|
||||
"py.subprocess"
|
||||
]
|
||||
```
|
||||
|
||||
### Effect許可例
|
||||
|
||||
```toml
|
||||
[box.PyRuntimeBox.effects]
|
||||
allow = [
|
||||
"py.import:math",
|
||||
"py.import:json",
|
||||
"py.import:re",
|
||||
"py.time:monotonic",
|
||||
"py.fs.read:/tmp/**"
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Capability設定
|
||||
|
||||
### 基本Capability
|
||||
|
||||
```toml
|
||||
[box.PyRuntimeBox.capabilities]
|
||||
# 許可リスト
|
||||
allow = [
|
||||
"py.import:math",
|
||||
"py.import:json"
|
||||
]
|
||||
|
||||
# 拒否リスト
|
||||
deny = [
|
||||
"py.subprocess",
|
||||
"py.net"
|
||||
]
|
||||
|
||||
# 厳格モード
|
||||
enforce = true
|
||||
```
|
||||
|
||||
### 詳細Capability(モジュール別)
|
||||
|
||||
```toml
|
||||
[box.PyRuntimeBox.capabilities.import]
|
||||
# 標準ライブラリ
|
||||
stdlib = [
|
||||
"math",
|
||||
"json",
|
||||
"re",
|
||||
"datetime",
|
||||
"collections"
|
||||
]
|
||||
|
||||
# サードパーティ(ホワイトリスト)
|
||||
allow_third_party = [
|
||||
"numpy",
|
||||
"pandas"
|
||||
]
|
||||
|
||||
# 拒否(ブラックリスト)
|
||||
deny = [
|
||||
"os",
|
||||
"subprocess",
|
||||
"socket"
|
||||
]
|
||||
```
|
||||
|
||||
### ファイルシステムCapability
|
||||
|
||||
```toml
|
||||
[box.PyRuntimeBox.capabilities.fs]
|
||||
# 読み取り許可
|
||||
read_paths = [
|
||||
"/tmp/**",
|
||||
"/data/input/**",
|
||||
"~/.config/app/**"
|
||||
]
|
||||
|
||||
# 書き込み許可
|
||||
write_paths = [
|
||||
"/tmp/**",
|
||||
"/data/output/**"
|
||||
]
|
||||
|
||||
# 拒否
|
||||
deny_paths = [
|
||||
"/etc/**",
|
||||
"/sys/**",
|
||||
"~/.ssh/**"
|
||||
]
|
||||
```
|
||||
|
||||
### ネットワークCapability
|
||||
|
||||
```toml
|
||||
[box.PyRuntimeBox.capabilities.net]
|
||||
# HTTP許可
|
||||
http_allow = [
|
||||
"https://api.example.com/**",
|
||||
"https://data.example.org/api/**"
|
||||
]
|
||||
|
||||
# Socket許可(ホスト:ポート)
|
||||
socket_allow = [
|
||||
"localhost:8080",
|
||||
"127.0.0.1:5432"
|
||||
]
|
||||
|
||||
# 拒否
|
||||
deny = [
|
||||
"0.0.0.0:*", # すべてのインターフェース
|
||||
"*:22", # SSH
|
||||
"*:3389" # RDP
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Contract設定
|
||||
|
||||
### PyFunctionBox Contract
|
||||
|
||||
```toml
|
||||
[contracts.PyFunctionBox.exec]
|
||||
# Pre条件(引数チェック)
|
||||
pre = [
|
||||
"args.len <= 8", # 引数は8個まで
|
||||
"bytes_total <= 1_000_000", # 合計1MB以下
|
||||
"no_file_descriptors" # ファイルディスクリプタ禁止
|
||||
]
|
||||
|
||||
# Post条件(返り値チェック)
|
||||
post = [
|
||||
"result.size <= 1_000_000", # 返り値1MB以下
|
||||
"no_exception", # 例外禁止
|
||||
"allow_none = true", # None許可
|
||||
"execution_time <= 5.0" # 5秒以内
|
||||
]
|
||||
|
||||
# 違反時の挙動
|
||||
on_violation = "error" # "error" | "warn" | "ignore"
|
||||
```
|
||||
|
||||
### PyModuleBox Contract
|
||||
|
||||
```toml
|
||||
[contracts.PyModuleBox.import]
|
||||
pre = [
|
||||
"module_name.len <= 100", # モジュール名100文字以内
|
||||
"no_relative_import" # 相対インポート禁止
|
||||
]
|
||||
|
||||
post = [
|
||||
"module_size <= 10_000_000", # モジュールサイズ10MB以下
|
||||
"no_native_code" # ネイティブコード禁止(オプション)
|
||||
]
|
||||
```
|
||||
|
||||
### PyInstanceBox Contract
|
||||
|
||||
```toml
|
||||
[contracts.PyInstanceBox.call_method]
|
||||
pre = [
|
||||
"method_name.len <= 50", # メソッド名50文字以内
|
||||
"args.len <= 16" # 引数16個まで
|
||||
]
|
||||
|
||||
post = [
|
||||
"result.size <= 1_000_000", # 返り値1MB以下
|
||||
"no_side_effects" # 副作用禁止(Pure)
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎛️ Policy設定
|
||||
|
||||
### 開発モード(Dev)
|
||||
|
||||
```toml
|
||||
[policy.dev]
|
||||
# Capability
|
||||
capabilities.enforce = false # 観測のみ
|
||||
capabilities.log = true # ログ記録
|
||||
|
||||
# Contract
|
||||
contracts.enforce = true # 厳格チェック
|
||||
contracts.on_violation = "error" # 違反時エラー
|
||||
|
||||
# Deterministic
|
||||
deterministic = false # 非決定的許可
|
||||
|
||||
# Trace
|
||||
trace.effects = true # 効果トレース
|
||||
trace.calls = true # 呼び出しトレース
|
||||
trace.errors = true # エラートレース
|
||||
|
||||
# Verifier
|
||||
verify.phi = true # PHI検証
|
||||
verify.ssa = true # SSA検証
|
||||
verify.on_fail = "error" # 検証失敗時エラー
|
||||
```
|
||||
|
||||
### 本番モード(Prod)
|
||||
|
||||
```toml
|
||||
[policy.prod]
|
||||
# Capability
|
||||
capabilities.enforce = true # 厳格適用
|
||||
capabilities.log = false # ログなし
|
||||
|
||||
# Contract
|
||||
contracts.enforce = true # 厳格チェック
|
||||
contracts.on_violation = "warn" # 違反時警告
|
||||
|
||||
# Deterministic
|
||||
deterministic = true # 決定的実行
|
||||
|
||||
# Trace
|
||||
trace.effects = false # トレースなし
|
||||
trace.calls = false
|
||||
trace.errors = true # エラーのみ
|
||||
|
||||
# Verifier
|
||||
verify.phi = true # PHI検証
|
||||
verify.ssa = true # SSA検証
|
||||
verify.on_fail = "warn" # 検証失敗時警告
|
||||
```
|
||||
|
||||
### テストモード(Test)
|
||||
|
||||
```toml
|
||||
[policy.test]
|
||||
# Capability
|
||||
capabilities.enforce = true # 厳格適用
|
||||
capabilities.log = true # ログ記録
|
||||
|
||||
# Contract
|
||||
contracts.enforce = true # 厳格チェック
|
||||
contracts.on_violation = "error" # 違反時エラー
|
||||
|
||||
# Deterministic
|
||||
deterministic = true # 決定的実行(再現性)
|
||||
|
||||
# Trace
|
||||
trace.effects = true # 全トレース
|
||||
trace.calls = true
|
||||
trace.errors = true
|
||||
|
||||
# Verifier
|
||||
verify.phi = true # 全検証
|
||||
verify.ssa = true
|
||||
verify.on_fail = "error" # 検証失敗時エラー
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 環境変数によるオーバーライド
|
||||
|
||||
### 優先順位
|
||||
|
||||
1. 環境変数(最優先)
|
||||
2. hako.toml
|
||||
3. hakorune.toml
|
||||
4. デフォルト値
|
||||
|
||||
### 環境変数例
|
||||
|
||||
```bash
|
||||
# Capability
|
||||
export HAKO_PLUGIN_CAPS_ENFORCE=1
|
||||
export HAKO_TRACE_EFFECTS=1
|
||||
|
||||
# Contract
|
||||
export HAKO_CHECK_CONTRACTS=1
|
||||
export HAKO_CONTRACT_VIOLATION=error
|
||||
|
||||
# Deterministic
|
||||
export HAKO_DETERMINISTIC=1
|
||||
|
||||
# ABI
|
||||
export HAKO_ABI_VTABLE=1
|
||||
export HAKO_ABI_STRICT=1
|
||||
|
||||
# Verifier
|
||||
export HAKO_VERIFY_ALLOW_NO_PHI=0
|
||||
export HAKO_VERIFY_ON_FAIL=error
|
||||
|
||||
# LLVM
|
||||
export HAKO_LLVM_USE_HARNESS=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 実用例
|
||||
|
||||
### 例1: 数学計算のみ許可
|
||||
|
||||
```toml
|
||||
# hako.toml
|
||||
[box.PyRuntimeBox]
|
||||
effects.allow = ["py.import:math"]
|
||||
capabilities.enforce = true
|
||||
|
||||
[contracts.PyFunctionBox.exec]
|
||||
pre = ["args.len <= 4"]
|
||||
post = ["no_exception", "execution_time <= 1.0"]
|
||||
```
|
||||
|
||||
```hakorune
|
||||
using "python"
|
||||
|
||||
box Main {
|
||||
flow main() {
|
||||
let py = PyRuntimeBox();
|
||||
let math = py.import("math");
|
||||
let sqrt = math.get("sqrt");
|
||||
let r = sqrt.exec([2.0]);
|
||||
print(r); // OK
|
||||
py.fini();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 例2: データ処理(ファイル読み取り)
|
||||
|
||||
```toml
|
||||
# hako.toml
|
||||
[box.PyRuntimeBox]
|
||||
effects.allow = [
|
||||
"py.import:json",
|
||||
"py.fs.read:/data/input/**"
|
||||
]
|
||||
|
||||
[box.PyRuntimeBox.capabilities.fs]
|
||||
read_paths = ["/data/input/**"]
|
||||
write_paths = [] # 書き込み禁止
|
||||
```
|
||||
|
||||
```hakorune
|
||||
using "python"
|
||||
|
||||
box Main {
|
||||
flow main() {
|
||||
let py = PyRuntimeBox();
|
||||
let json = py.import("json");
|
||||
|
||||
// ファイル読み取り(許可)
|
||||
let data = py.eval("open('/data/input/test.json').read()");
|
||||
let parsed = json.get("loads").exec([data]);
|
||||
|
||||
print(parsed);
|
||||
py.fini();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 例3: API呼び出し(ネットワーク)
|
||||
|
||||
```toml
|
||||
# hako.toml
|
||||
[box.PyRuntimeBox]
|
||||
effects.allow = [
|
||||
"py.import:urllib",
|
||||
"py.net.http"
|
||||
]
|
||||
|
||||
[box.PyRuntimeBox.capabilities.net]
|
||||
http_allow = [
|
||||
"https://api.example.com/**"
|
||||
]
|
||||
|
||||
[contracts.PyFunctionBox.exec]
|
||||
pre = ["args.len <= 2"]
|
||||
post = [
|
||||
"result.size <= 1_000_000",
|
||||
"execution_time <= 10.0"
|
||||
]
|
||||
```
|
||||
|
||||
```hakorune
|
||||
using "python"
|
||||
|
||||
box Main {
|
||||
flow main() {
|
||||
let py = PyRuntimeBox();
|
||||
|
||||
let code = "
|
||||
import urllib.request
|
||||
def fetch(url):
|
||||
with urllib.request.urlopen(url) as r:
|
||||
return r.read()
|
||||
";
|
||||
py.exec(code);
|
||||
let fetch = py.get("fetch");
|
||||
|
||||
// API呼び出し(許可)
|
||||
let result = fetch.exec(["https://api.example.com/data"]);
|
||||
print(result);
|
||||
|
||||
py.fini();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 デバッグ設定
|
||||
|
||||
### 詳細ログ
|
||||
|
||||
```toml
|
||||
[debug]
|
||||
# すべてのトレース有効化
|
||||
trace.all = true
|
||||
|
||||
# 個別トレース
|
||||
trace.effects = true
|
||||
trace.capabilities = true
|
||||
trace.contracts = true
|
||||
trace.python_calls = true
|
||||
trace.gil = true
|
||||
|
||||
# ログレベル
|
||||
log_level = "debug"
|
||||
|
||||
# ログ出力先
|
||||
log_file = "/tmp/hakorune-python-debug.log"
|
||||
```
|
||||
|
||||
### パフォーマンスプロファイル
|
||||
|
||||
```toml
|
||||
[profile]
|
||||
# タイミング記録
|
||||
timing.enabled = true
|
||||
timing.threshold = 0.1 # 100ms以上
|
||||
|
||||
# メモリ使用量
|
||||
memory.track = true
|
||||
memory.threshold = 10_000_000 # 10MB以上
|
||||
|
||||
# GC統計
|
||||
gc.enabled = true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔗 関連ドキュメント
|
||||
|
||||
- [強化版アーキテクチャv2](enhanced-architecture-v2.md) - 設計詳細
|
||||
- [マイルストーン](../planning/milestones.md) - 実装計画
|
||||
- [リスクと対策](risks-and-mitigations.md) - リスク管理
|
||||
- [Phase 20 README](../README.md) - 全体概要
|
||||
|
||||
---
|
||||
|
||||
**最終更新**: 2025-10-02
|
||||
**作成者**: ChatGPT Pro (UltraThink Mode)
|
||||
**ステータス**: 設定リファレンス
|
||||
@ -0,0 +1,37 @@
|
||||
# 10.5b – ネイティブビルド基盤の固め(AOT/EXE)
|
||||
|
||||
Python統合を本格化する前に、配布可能なネイティブ実行ファイル(EXE)の足回りを先に完成させる。JITは実行エンジンから外し、EXE生成専用のコンパイラとして運用する。
|
||||
|
||||
## 🎯 目的
|
||||
- VM=実行、JIT=EXE(AOT)の二系統を明確化(フォールバックなし/Fail-Fast)
|
||||
- CLIF→.o→`libnyrt`リンク→EXEのパイプラインを実効化
|
||||
- プラグイン解決をクロスプラットフォームに(.so/.dll/.dylib、自動lib剥がし、検索パス)
|
||||
- Windowsを含む実用的な配布体験を整備
|
||||
|
||||
## 🧩 範囲
|
||||
- JIT分離・Strict運用(Fail-Fast/No-fallback)
|
||||
- AOTパイプライン: `--compile-native` と `tools/build_aot.{sh,ps1}`
|
||||
- プラグインローダの拡張: 拡張子変換/`lib`剥がし、`plugin_paths`+`NYASH_PLUGIN_PATHS`
|
||||
- Windowsリンク: clang優先(`nyrt.lib`/`libnyrt.a`両対応)、bash+cc fallback
|
||||
- 観測/EXE出力の統一: `Result: <val>`、終了コード=<val>
|
||||
|
||||
## ✅ 成果(DoD)
|
||||
- `cargo build --release --features cranelift-jit` の後、
|
||||
- Linux: `./tools/build_aot.sh examples/aot_min_string_len.nyash -o app && ./app`
|
||||
- Windows: `powershell -ExecutionPolicy Bypass -File tools\build_aot.ps1 -Input examples\aot_min_string_len.nyash -Out app.exe && .\app.exe`
|
||||
- プラグインは `.so` 記述でも各OSで自動解決(.dll/.dylib へ変換、lib剥がし)
|
||||
- `tools/smoke_aot_vs_vm.sh` で VM/EXE の `Result:` 行比較が可能(差異は警告表示)
|
||||
|
||||
## 🔧 実装メモ
|
||||
- `src/runtime/plugin_loader_v2.rs` に `resolve_library_path()` を追加:
|
||||
- OS別拡張子、Windowsの`lib`剥がし、`plugin_paths`探索
|
||||
- `src/config/nyash_toml_v2.rs` に `NYASH_PLUGIN_PATHS` を追加(`;`/`:`区切り)
|
||||
- `AotConfigBox` に `set_plugin_paths()` 追加(env同期)
|
||||
- `crates/nyrt` の EXE出力統一(`Result:`/exit code)
|
||||
- Windows: `tools/build_aot.ps1`(clang→bash fallback)、Linux: `tools/build_aot.sh`
|
||||
|
||||
## 📌 次(10.5c 以降)
|
||||
- PyRuntimeBox/PyObjectBox(RO優先)
|
||||
- Python ABIルータを `libnyrt` に同梱(type_id→invokeディスパッチ)
|
||||
- 配布用パッケージ整備(nyash.toml/プラグイン配置ガイドの最終化)
|
||||
|
||||
@ -0,0 +1,441 @@
|
||||
# リスクと対策
|
||||
|
||||
**作成**: 2025-10-02
|
||||
**ソース**: ChatGPT Pro UltraThink Mode
|
||||
**用途**: Python統合における既知のリスクと対策
|
||||
|
||||
---
|
||||
|
||||
## 📋 概要
|
||||
|
||||
Python-Hakorune統合における技術的リスク、運用リスク、およびその対策をまとめます。
|
||||
|
||||
---
|
||||
|
||||
## 🔥 高リスク項目
|
||||
|
||||
### 1. GILデッドロック
|
||||
|
||||
#### リスク詳細
|
||||
- **問題**: Hakorune並列実行とPython GILのズレ
|
||||
- **発生条件**: Hakorune側マルチスレッド + Python呼び出しのネスト
|
||||
- **影響**: プログラム全体がハング、デバッグ困難
|
||||
|
||||
#### 対策
|
||||
|
||||
**アーキテクチャレベル**:
|
||||
```rust
|
||||
// PyRuntimeBoxを専用スレッドで実行
|
||||
pub struct PyRuntimeBox {
|
||||
thread: JoinHandle<()>,
|
||||
tx: Sender<PyCommand>,
|
||||
rx: Receiver<PyResult>,
|
||||
}
|
||||
|
||||
impl PyRuntimeBox {
|
||||
pub fn init() -> Self {
|
||||
let (tx, rx_cmd) = channel();
|
||||
let (tx_result, rx) = channel();
|
||||
|
||||
let thread = thread::spawn(move || {
|
||||
// このスレッドでGILを保持
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
loop {
|
||||
match rx_cmd.recv() {
|
||||
Ok(PyCommand::Import(name)) => {
|
||||
let result = py.import(&name);
|
||||
tx_result.send(PyResult::Module(result)).unwrap();
|
||||
}
|
||||
Ok(PyCommand::Shutdown) => break,
|
||||
Err(_) => break,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
PyRuntimeBox { thread, tx, rx }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**ガードレール**:
|
||||
```toml
|
||||
[debug.gil]
|
||||
# GIL獲得・解放のログ
|
||||
trace = true
|
||||
|
||||
# タイムアウト検出
|
||||
timeout = 5.0 # 5秒
|
||||
|
||||
# デッドロック検出
|
||||
detect_deadlock = true
|
||||
```
|
||||
|
||||
**モニタリング**:
|
||||
```bash
|
||||
# GILトレース有効化
|
||||
export HAKO_TRACE_GIL=1
|
||||
|
||||
# タイムアウト設定
|
||||
export HAKO_GIL_TIMEOUT=5.0
|
||||
```
|
||||
|
||||
#### 回避策
|
||||
1. **専用スレッド**でPython実行を隔離
|
||||
2. **メッセージパッシング**でHakorune-Python間通信
|
||||
3. **タイムアウト**で異常検出
|
||||
4. **ログ**で原因追跡
|
||||
|
||||
---
|
||||
|
||||
### 2. メモリリーク
|
||||
|
||||
#### リスク詳細
|
||||
- **問題**: Python参照カウント管理ミス
|
||||
- **発生条件**: `Py_INCREF`/`Py_DECREF`の不一致
|
||||
- **影響**: メモリ使用量増大、最悪OOM
|
||||
|
||||
#### 対策
|
||||
|
||||
**Arc管理**:
|
||||
```rust
|
||||
// PythonオブジェクトをArcでラップ
|
||||
pub struct PyObjectBox {
|
||||
inner: Arc<PyObjectInner>,
|
||||
}
|
||||
|
||||
struct PyObjectInner {
|
||||
py_obj: Py<PyAny>,
|
||||
}
|
||||
|
||||
impl Drop for PyObjectInner {
|
||||
fn drop(&mut self) {
|
||||
// 確実にDECREF
|
||||
Python::with_gil(|py| {
|
||||
self.py_obj.as_ref(py);
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**weakref.finalize**:
|
||||
```python
|
||||
# Python側で自動クリーンアップ
|
||||
import weakref
|
||||
|
||||
def create_hakorune_object(obj):
|
||||
# finalizer登録
|
||||
finalizer = weakref.finalize(obj, cleanup_callback, obj_id)
|
||||
return obj
|
||||
```
|
||||
|
||||
**リーク検出**:
|
||||
```toml
|
||||
[debug.memory]
|
||||
# メモリトラッキング
|
||||
track = true
|
||||
|
||||
# リーク検出
|
||||
detect_leaks = true
|
||||
|
||||
# 定期チェック
|
||||
check_interval = 10.0 # 10秒
|
||||
```
|
||||
|
||||
**ツール**:
|
||||
```bash
|
||||
# Valgrind
|
||||
valgrind --leak-check=full ./hakorune script.hkr
|
||||
|
||||
# AddressSanitizer
|
||||
RUSTFLAGS="-Z sanitizer=address" cargo build
|
||||
|
||||
# Python memory profiler
|
||||
export PYTHONTRACEMALLOC=1
|
||||
```
|
||||
|
||||
#### 回避策
|
||||
1. **Arc/Drop**で自動管理
|
||||
2. **weakref.finalize**で循環参照対策
|
||||
3. **定期チェック**で早期発見
|
||||
4. **テスト**で継続監視
|
||||
|
||||
---
|
||||
|
||||
### 3. C拡張モジュールの扱い
|
||||
|
||||
#### リスク詳細
|
||||
- **問題**: numpy等のC拡張は特殊な扱いが必要
|
||||
- **発生条件**: ネイティブコードの直接呼び出し
|
||||
- **影響**: セグフォ、未定義動作
|
||||
|
||||
#### 対策
|
||||
|
||||
**Capability制御**:
|
||||
```toml
|
||||
[box.PyRuntimeBox.capabilities.native]
|
||||
# C拡張の許可
|
||||
allow_native = true
|
||||
|
||||
# ホワイトリスト
|
||||
allow_modules = [
|
||||
"numpy",
|
||||
"pandas",
|
||||
"_ctypes"
|
||||
]
|
||||
|
||||
# ブラックリスト
|
||||
deny_modules = [
|
||||
"ctypes", # 任意ネイティブコード実行
|
||||
"cffi"
|
||||
]
|
||||
```
|
||||
|
||||
**サンドボックス**(将来):
|
||||
```toml
|
||||
[sandbox]
|
||||
# ネイティブコードをサンドボックスで実行
|
||||
enable = true
|
||||
mode = "seccomp" # Linux
|
||||
```
|
||||
|
||||
**検証**:
|
||||
```rust
|
||||
// ロード前に検証
|
||||
fn verify_module_safety(module_name: &str) -> Result<()> {
|
||||
// シグネチャ確認
|
||||
// 既知の安全なモジュールか
|
||||
// ブラックリスト確認
|
||||
}
|
||||
```
|
||||
|
||||
#### 回避策
|
||||
1. **ホワイトリスト**で既知の安全なモジュールのみ許可
|
||||
2. **サンドボックス**で隔離実行(将来)
|
||||
3. **検証**でロード前チェック
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 中リスク項目
|
||||
|
||||
### 4. パフォーマンスオーバーヘッド
|
||||
|
||||
#### リスク詳細
|
||||
- **問題**: FFI境界・GIL・型変換のコスト
|
||||
- **影響**: 性能劣化
|
||||
|
||||
#### 対策
|
||||
|
||||
**最適化**:
|
||||
```rust
|
||||
// 型変換キャッシュ
|
||||
struct TypeCache {
|
||||
string_to_pyobject: HashMap<String, Py<PyString>>,
|
||||
int_to_pyobject: HashMap<i64, Py<PyLong>>,
|
||||
}
|
||||
|
||||
impl TypeCache {
|
||||
fn get_or_create_string(&mut self, py: Python, s: &str) -> Py<PyString> {
|
||||
self.string_to_pyobject
|
||||
.entry(s.to_string())
|
||||
.or_insert_with(|| PyString::new(py, s).into())
|
||||
.clone()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**バッチ処理**:
|
||||
```rust
|
||||
// 複数呼び出しをまとめる
|
||||
fn batch_call(funcs: Vec<PyFunctionBox>, args: Vec<Vec<Value>>) -> Vec<Value> {
|
||||
Python::with_gil(|py| {
|
||||
funcs.iter().zip(args.iter())
|
||||
.map(|(f, a)| f.exec_with_gil(py, a))
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
**ベンチマーク**:
|
||||
```bash
|
||||
# パフォーマンステスト
|
||||
cargo bench --features python-integration
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. プラットフォーム固有問題
|
||||
|
||||
#### リスク詳細
|
||||
- **問題**: Python配布形態の違い(Linux/macOS/Windows)
|
||||
- **影響**: ビルド・実行時エラー
|
||||
|
||||
#### 対策
|
||||
|
||||
**プラットフォーム別設定**:
|
||||
```toml
|
||||
# Linux
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
python-lib = "python3.11"
|
||||
python-path = "/usr/lib/python3.11"
|
||||
|
||||
# macOS
|
||||
[target.x86_64-apple-darwin]
|
||||
python-lib = "python3.11"
|
||||
python-path = "/usr/local/opt/python@3.11"
|
||||
|
||||
# Windows
|
||||
[target.x86_64-pc-windows-msvc]
|
||||
python-lib = "python311"
|
||||
python-path = "C:/Python311"
|
||||
```
|
||||
|
||||
**CI/CD**:
|
||||
```yaml
|
||||
# .github/workflows/python-integration.yml
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
python-version: ['3.8', '3.9', '3.10', '3.11']
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. 例外伝播の複雑さ
|
||||
|
||||
#### リスク詳細
|
||||
- **問題**: Python例外とHakoruneエラーの境界
|
||||
- **影響**: エラーハンドリングの困難さ
|
||||
|
||||
#### 対策
|
||||
|
||||
**統一ErrorBox**:
|
||||
```hakorune
|
||||
box ErrorBox {
|
||||
type: StringBox // "ZeroDivisionError"
|
||||
message: StringBox // "division by zero"
|
||||
traceback: StringBox // フルスタックトレース
|
||||
source: StringBox // "python" | "hakorune"
|
||||
}
|
||||
```
|
||||
|
||||
**変換層**:
|
||||
```rust
|
||||
fn convert_py_exception(py_err: &PyErr) -> ErrorBox {
|
||||
ErrorBox {
|
||||
type_: py_err.get_type().name().to_string(),
|
||||
message: py_err.to_string(),
|
||||
traceback: format_traceback(py_err),
|
||||
source: "python".to_string(),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 低リスク項目
|
||||
|
||||
### 7. ドキュメント不足
|
||||
|
||||
#### 対策
|
||||
- 段階的にドキュメント整備
|
||||
- コードサンプル充実
|
||||
- チュートリアル作成
|
||||
|
||||
### 8. テストカバレッジ
|
||||
|
||||
#### 対策
|
||||
- ユニットテスト追加
|
||||
- 統合テスト充実
|
||||
- E2Eテスト自動化
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ リスク管理マトリックス
|
||||
|
||||
| リスク | 深刻度 | 発生確率 | 優先度 | 対策状況 |
|
||||
|-------|-------|---------|-------|---------|
|
||||
| GILデッドロック | 高 | 中 | 最優先 | 設計段階で対策 |
|
||||
| メモリリーク | 高 | 中 | 最優先 | Arc/Drop自動化 |
|
||||
| C拡張問題 | 高 | 低 | 高 | ホワイトリスト |
|
||||
| パフォーマンス | 中 | 高 | 中 | 最適化計画 |
|
||||
| プラットフォーム | 中 | 中 | 中 | CI/CD網羅 |
|
||||
| 例外伝播 | 中 | 低 | 低 | ErrorBox統一 |
|
||||
| ドキュメント | 低 | 高 | 低 | 段階的整備 |
|
||||
| テストカバレッジ | 低 | 中 | 低 | 継続改善 |
|
||||
|
||||
---
|
||||
|
||||
## 🔍 監視・検出
|
||||
|
||||
### 自動検出
|
||||
|
||||
```toml
|
||||
[monitoring]
|
||||
# GIL監視
|
||||
gil.timeout = 5.0
|
||||
gil.alert_on_timeout = true
|
||||
|
||||
# メモリ監視
|
||||
memory.threshold = 100_000_000 # 100MB
|
||||
memory.alert_on_threshold = true
|
||||
|
||||
# パフォーマンス監視
|
||||
performance.slow_call_threshold = 1.0 # 1秒
|
||||
performance.alert_on_slow = true
|
||||
```
|
||||
|
||||
### ログ
|
||||
|
||||
```bash
|
||||
# すべての監視ログ
|
||||
export HAKO_TRACE_GIL=1
|
||||
export HAKO_TRACE_MEMORY=1
|
||||
export HAKO_TRACE_PERFORMANCE=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 インシデント対応
|
||||
|
||||
### 1. GILデッドロック発生時
|
||||
|
||||
```bash
|
||||
# 1. ログ確認
|
||||
cat /tmp/hakorune-debug.log | grep GIL
|
||||
|
||||
# 2. スタックトレース取得
|
||||
kill -QUIT <pid>
|
||||
|
||||
# 3. デバッガー接続
|
||||
gdb -p <pid>
|
||||
```
|
||||
|
||||
### 2. メモリリーク発生時
|
||||
|
||||
```bash
|
||||
# 1. メモリ使用量確認
|
||||
ps aux | grep hakorune
|
||||
|
||||
# 2. Valgrind実行
|
||||
valgrind --leak-check=full ./hakorune script.hkr
|
||||
|
||||
# 3. Python側確認
|
||||
export PYTHONTRACEMALLOC=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔗 関連ドキュメント
|
||||
|
||||
- [強化版アーキテクチャv2](enhanced-architecture-v2.md) - 設計詳細
|
||||
- [マイルストーン](../planning/milestones.md) - 実装計画
|
||||
- [メタ設定例](meta-config-examples.md) - 設定例
|
||||
- [Phase 20 README](../README.md) - 全体概要
|
||||
|
||||
---
|
||||
|
||||
**最終更新**: 2025-10-02
|
||||
**作成者**: ChatGPT Pro (UltraThink Mode)
|
||||
**ステータス**: リスク管理ドキュメント
|
||||
Reference in New Issue
Block a user