feat(llvm): Phase 285LLVM-0 - LLVM Conformance One-Pass
Step 0: SSOT/Reality Alignment - Update Feature Matrix (lifecycle.md): - WeakRef: "285A1" → "285LLVM-1" - Leak Report: "partial" → "Parent process roots only (285LLVM-0)" - Add detailed LLVM limitation explanation - Update SKIP reason (phase285_weak_basic_llvm.sh): "285A1" → "285LLVM-1" Step 1: LLVM Leak Report Implementation - Add emit_leak_report() calls to llvm.rs (success + error paths) - Create phase285_leak_report_llvm.sh smoke test (3 test cases PASS) - Add NYASH_LEAK_LOG documentation to environment-variables.md - Manual test: All 3 cases PASS (no-log, LEVEL=1, LEVEL=2) - Smoke test: 3/3 PASS Step 2: WeakRef Design Preparation - Create phase-285llvm-1-design.md - Runtime representation candidate (Option B with caveat) - FFI signatures definition - Implementation checklist - Test strategy - NO CODE IMPLEMENTATION (design-only phase) Implementation: - Minimal 10-20 line code change (as planned) - Reuses existing leak_tracker.rs infrastructure - LLVM limitation transparently documented - Exit codes unchanged (0/1 preserved) - Fixture SSOT: apps/tests/*.hako shared between VM/LLVM Test Results: - ✅ Manual test: 3/3 cases PASS - ✅ Smoke test: 3/3 cases PASS - ✅ No regressions Files Changed: - src/runner/modes/llvm.rs (2 emit_leak_report() calls) - docs/reference/language/lifecycle.md (Feature Matrix + LLVM limitation) - docs/reference/environment-variables.md (NYASH_LEAK_LOG entry) - tools/smokes/v2/profiles/quick/lifecycle/phase285_weak_basic_llvm.sh (SKIP reason) Files Added: - tools/smokes/v2/profiles/quick/lifecycle/phase285_leak_report_llvm.sh - docs/development/current/main/phases/phase-285/phase-285llvm-1-design.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,210 @@
|
||||
# Phase 285LLVM-1: WeakRef LLVM Implementation Design
|
||||
|
||||
**Status**: Design phase (no implementation yet)
|
||||
**Date**: 2025-12-24
|
||||
**Related**: Phase 285A0 (VM WeakRef implementation), Phase 285LLVM-0 (LLVM Leak Report)
|
||||
|
||||
## Goal
|
||||
|
||||
LLVM backendでWeakRefサポートを実装し、VM parityを達成する
|
||||
|
||||
## Background
|
||||
|
||||
### 現状
|
||||
- **VM**: WeakRef完全実装済み(Phase 285A0)
|
||||
- `VMValue::WeakBox(Weak<dyn NyashBox>)` 実装
|
||||
- 8テスト全てPASS
|
||||
- `apps/tests/phase285_weak_*.hako` にfixtureあり
|
||||
- **LLVM**: 完全未実装
|
||||
- `src/llvm_py/instruction_lower.py` に WeakNew/WeakLoad handler存在せず
|
||||
- fallback処理もなし(未知命令は無視される)
|
||||
|
||||
### 制約
|
||||
- **WeakRef field契約**: フロントエンド(parser/MIR builder)の責務
|
||||
- 全バックエンドで既に効いている
|
||||
- LLVM側で実装不要
|
||||
- **GC統合**: WeakRefはGC不要で動作(デザイン済み)
|
||||
|
||||
## Runtime表現(候補)
|
||||
|
||||
### 候補: Option B (i64 with convention, bit 63 = weak marker)
|
||||
|
||||
**理由**:
|
||||
- 最小FFI overhead(既存のhandle infrastructureを再利用)
|
||||
- 実装が単純
|
||||
- 後でtagged unionに変更可能
|
||||
|
||||
**注意**:
|
||||
⚠️ **Phase 285LLVM-1実装前に既存LLVM値表現との整合性確認が必要**
|
||||
- 既存のhandle/boxing方式と衝突しないか検証
|
||||
- i64の最上位ビット(bit 63)が他の目的で使われていないか確認
|
||||
|
||||
### 代替案
|
||||
|
||||
**Option A**: Tagged Pointer `{i32 tag, i64 handle}`
|
||||
- ✅ 型安全
|
||||
- ❌ 実装が複雑
|
||||
- ❌ FFI overhead増加
|
||||
|
||||
**Option C**: Opaque Pointer
|
||||
- ✅ Future-proof
|
||||
- ❌ Runtime support必要
|
||||
- ❌ より大きな変更が必要
|
||||
|
||||
## weak_to_strong() 返り値
|
||||
|
||||
**SSOT** (`docs/reference/language/lifecycle.md:179`):
|
||||
- 成功: Strong BoxRef (i64 handle > 0)
|
||||
- 失敗: null (i64(0) = Void)
|
||||
|
||||
## FFI API
|
||||
|
||||
Phase 285LLVM-1で実装する3つのFFI関数(`crates/nyash_kernel/src/lib.rs` または相当箇所):
|
||||
|
||||
```rust
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nyrt_weak_new(strong_handle: i64) -> i64 {
|
||||
// Convert strong handle to weak handle
|
||||
// Implementation: Phase 285LLVM-1
|
||||
unimplemented!("Phase 285LLVM-1")
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nyrt_weak_to_strong(weak_handle: i64) -> i64 {
|
||||
// Upgrade weak to strong
|
||||
// Returns: strong handle (>0) on success, 0 (Void) on failure
|
||||
unimplemented!("Phase 285LLVM-1")
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn nyrt_weak_drop(weak_handle: i64) {
|
||||
// Release weak reference
|
||||
unimplemented!("Phase 285LLVM-1")
|
||||
}
|
||||
```
|
||||
|
||||
## MIR Lowering
|
||||
|
||||
LLVM IR生成時の変換(`src/llvm_py/instruction_lower.py` で実装):
|
||||
|
||||
```python
|
||||
# WeakNew: strong → weak 変換
|
||||
# MIR: WeakNew(dst=ValueId(10), box_val=ValueId(5))
|
||||
# LLVM IR: %10 = call i64 @nyrt_weak_new(i64 %5)
|
||||
|
||||
elif op == "weak_new":
|
||||
box_val = lower_value(inst["box_val"])
|
||||
result = builder.call(nyrt_weak_new_fn, [box_val])
|
||||
store_value(inst["dst"], result)
|
||||
|
||||
# WeakLoad: weak → strong 変換(失敗時は0)
|
||||
# MIR: WeakLoad(dst=ValueId(20), weak_ref=ValueId(10))
|
||||
# LLVM IR: %20 = call i64 @nyrt_weak_to_strong(i64 %10)
|
||||
|
||||
elif op == "weak_load":
|
||||
weak_ref = lower_value(inst["weak_ref"])
|
||||
result = builder.call(nyrt_weak_to_strong_fn, [weak_ref])
|
||||
store_value(inst["dst"], result)
|
||||
```
|
||||
|
||||
## テスト戦略
|
||||
|
||||
### Fixture再利用
|
||||
VM fixtureを再利用(`apps/tests/phase285_weak_*.hako`):
|
||||
- `phase285_weak_basic.hako` - 基本動作
|
||||
- `phase285_weak_upgrade.hako` - weak_to_strong()成功/失敗
|
||||
- その他6ファイル(合計8 fixtures)
|
||||
|
||||
### Parity検証
|
||||
VM/LLVM出力parity検証:
|
||||
- stdout比較(同じ出力であることを確認)
|
||||
- exit code比較(同じ終了コードであることを確認)
|
||||
|
||||
### スモークテスト
|
||||
`tools/smokes/v2/profiles/quick/lifecycle/phase285_weak_basic_llvm.sh`:
|
||||
- 現在SKIP中(Phase 285LLVM-1 message)
|
||||
- 実装後にSKIP解除
|
||||
|
||||
## 実装チェックリスト
|
||||
|
||||
### ファイル変更/新規作成
|
||||
|
||||
- [ ] **新規**: `src/llvm_py/instructions/weak.py`
|
||||
- WeakNew/WeakLoad handler実装
|
||||
- `instruction_lower.py` から分離されたモジュール
|
||||
|
||||
- [ ] **変更**: `src/llvm_py/instruction_lower.py`
|
||||
- `elif op == "weak_new"` handler追加
|
||||
- `elif op == "weak_load"` handler追加
|
||||
- `weak.py` をimport
|
||||
|
||||
- [ ] **変更**: `crates/nyash_kernel/src/lib.rs` (または相当箇所)
|
||||
- `nyrt_weak_new()` 実装
|
||||
- `nyrt_weak_to_strong()` 実装
|
||||
- `nyrt_weak_drop()` 実装
|
||||
|
||||
- [ ] **変更**: `tools/smokes/v2/profiles/quick/lifecycle/phase285_weak_basic_llvm.sh`
|
||||
- `test_skip` 削除
|
||||
- 実際のテスト実装(VM版と同じパターン)
|
||||
|
||||
### 検証ステップ
|
||||
|
||||
1. [ ] **Runtime表現の整合性確認**
|
||||
- 既存LLVM値表現(handle/boxing方式)と衝突しないか検証
|
||||
- bit 63が他で使われていないか確認
|
||||
|
||||
2. [ ] **FFI関数単体テスト**
|
||||
- `nyrt_weak_new()` が正しいweak handleを返すか
|
||||
- `nyrt_weak_to_strong()` が成功時にstrong handle、失敗時に0を返すか
|
||||
- `nyrt_weak_drop()` が正しくリソースを解放するか
|
||||
|
||||
3. [ ] **MIR lowering検証**
|
||||
- WeakNew命令が正しくLLVM IRに変換されるか
|
||||
- WeakLoad命令が正しくLLVM IRに変換されるか
|
||||
- 生成されたLLVM IRが実行可能か
|
||||
|
||||
4. [ ] **VM/LLVM parity検証**
|
||||
- 8 fixtureでVM/LLVMの出力が一致するか
|
||||
- exit codeが一致するか
|
||||
|
||||
5. [ ] **スモークテスト**
|
||||
- `phase285_weak_basic_llvm.sh` PASS確認
|
||||
- 回帰テスト(既知FAIL以外増えないか)
|
||||
|
||||
## 前提条件
|
||||
|
||||
- ✅ VM WeakRef完全実装済み(Phase 285A1)
|
||||
- ⚠️ Runtime表現候補選定済み(Option B、実装前に既存LLVM値表現との整合性確認必要)
|
||||
- ✅ FFI signatures定義済み(本ドキュメント)
|
||||
- ✅ Phase 285LLVM-0完了(LLVM Leak Report実装済み)
|
||||
|
||||
## 実装時の注意点
|
||||
|
||||
1. **Fail-Fast原則**: エラーは早期に明示的に失敗させる
|
||||
- weak_to_strong()失敗時はnull (i64(0))を返す
|
||||
- フォールバック処理は入れない
|
||||
|
||||
2. **SSOT準拠**: `docs/reference/language/lifecycle.md` の仕様に厳密に従う
|
||||
- weak_to_strong()の返り値は仕様通り
|
||||
- WeakRef semanticsは変更しない
|
||||
|
||||
3. **テスト駆動**: VM fixtureで動作確認してから進める
|
||||
- 実装→テスト→修正のサイクルを回す
|
||||
- VM parityを常に確認
|
||||
|
||||
## 成功基準
|
||||
|
||||
**Phase 285LLVM-1 完了時**:
|
||||
- ✅ WeakNew/WeakLoad命令のLLVM IR生成が動作
|
||||
- ✅ FFI関数3つ(nyrt_weak_new, nyrt_weak_to_strong, nyrt_weak_drop)実装済み
|
||||
- ✅ 8 fixtureでVM/LLVM parity達成(stdout + exit code一致)
|
||||
- ✅ `phase285_weak_basic_llvm.sh` スモークテストPASS
|
||||
- ✅ 回帰なし(既知FAIL以外増えない)
|
||||
|
||||
## 参考資料
|
||||
|
||||
- VM実装: `src/runtime/execution/vm/value.rs` (`VMValue::WeakBox`)
|
||||
- WeakRef SSOT: `docs/reference/language/lifecycle.md:170-180`
|
||||
- Fixtures: `apps/tests/phase285_weak_*.hako`
|
||||
- Phase 285A0: VM WeakRef実装(完了)
|
||||
- Phase 285LLVM-0: LLVM Leak Report実装(完了)
|
||||
Reference in New Issue
Block a user