Files
hakorune/docs/development/cleanup/CLEANUP_SUMMARY_2025-11-06.md
nyash-codex 0455307418 refactor(phase-a): remove Cranelift/JIT backend legacy code (~373 lines)
Phase A cleanup - Safe deletions with zero risk:

## Deleted Files (6 files, 373 lines total)
1. Cranelift/JIT Backend (321 lines):
   - src/runner/modes/cranelift.rs (45 lines)
   - src/runner/modes/aot.rs (55 lines)
   - src/runner/jit_direct.rs (152 lines)
   - src/tests/core13_smoke_jit.rs (42 lines)
   - src/tests/core13_smoke_jit_map.rs (27 lines)

2. Legacy MIR Builder (52 lines):
   - src/mir/builder/exprs_legacy.rs
   - Functionality inlined into exprs.rs (control flow constructs)

## Module Reference Cleanup
- src/backend/mod.rs: Removed cranelift feature gate exports
- src/runner/mod.rs: Removed jit_direct module reference
- src/runner/modes/mod.rs: Removed aot module reference
- src/mir/builder.rs: Removed exprs_legacy module

## Impact Analysis
- Build: Success (cargo build --release)
- Tests: All passing
- Risk Level: None (feature already archived, code unused)
- Related: Phase 15 JIT archival (archive/jit-cranelift/)

## BID Copilot Status
- Already removed in previous cleanup
- Not part of this commit

Total Reduction: 373 lines (~0.4% of codebase)
Next: Phase B - Dead code investigation

Related: #phase-21.0-cleanup
Part of: Legacy Code Cleanup Initiative
2025-11-06 22:34:18 +09:00

11 KiB
Raw Blame History

Hakorune コードベース重複・共通化調査 - 実行サマリー

調査日: 2025-11-06 調査実施: Claude Code Agent


クイックサマリー

主要発見

  • 重複パターン総数: 260箇所以上
  • 削減可能行数: 500-800行全体の15-20%
  • 即効対応可能: Phase 1で270-380行削減実装時間5-8時間

優先度トップ3

  1. Destination書き込み: 49箇所 → ヘルパー関数化
  2. 引数検証: 55箇所 → 統一検証関数
  3. エラー生成: 95箇所 → エラービルダー

ドキュメント構成

1. 詳細分析レポート

ファイル: DUPLICATION_ANALYSIS_REPORT.md

内容:

  • 9章構成の包括的レポート
  • 全重複パターンの詳細分析
  • 3段階のアクションプランPhase 1-3
  • リスク評価と期待効果

主要セクション:

  1. MIR Interpreter Handlers の重複パターン5種類
  2. MIR Builder の重複パターンPHI挿入など
  3. 統合可能なモジュールBox Handler群
  4. 優先度付きアクションプラン
  5. 実装ガイドライン
  6. 期待される効果(定量・定性)
  7. リスク評価
  8. 追加調査項目
  9. 結論と推奨事項

2. Phase 1実装ガイド

ファイル: PHASE1_IMPLEMENTATION_GUIDE.md

内容:

  • Step-by-Step実装手順
  • コード例Before/After
  • テスト戦略
  • トラブルシューティング

実装項目:

  1. utils/register_ops.rs - Destination書き込みヘルパー
  2. utils/validation.rs - 引数検証ヘルパー
  3. utils/conversions.rs - Receiver変換ヘルパー

数値で見る重複の実態

パターン別重複数

パターン 箇所数 削減見込み行数 優先度
Destination書き込み 49 150-200 最高
引数検証 55 100-150
エラー生成 95 200-300 最高
Receiver変換 5 20-30
PHI挿入 13 50-100
Box downcast 57 将来検討
合計 274 520-780 -

ファイル別行数上位10

   907行  handlers/calls.rs              ← 最大ファイル
   399行  handlers/boxes_object_fields.rs
   307行  handlers/boxes.rs
   298行  handlers/extern_provider.rs
   218行  handlers/externals.rs
   217行  handlers/boxes_plugin.rs
   208行  handlers/boxes_string.rs
   153行  handlers/boxes_instance.rs
   136行  handlers/arithmetic.rs
   134行  handlers/boxes_map.rs
-------
 3,335行  handlers/ 合計

アクションプラン概要

Phase 1: 即効対応(推奨: 即時実施)

目標: 低リスク・高効果のヘルパー関数実装 期間: 5-8時間 削減: 270-380行

実装項目:

  1. Destination書き込みヘルパー

    // Before (4行)
    if let Some(d) = dst {
        this.regs.insert(d, VMValue::from_nyash_box(ret));
    }
    
    // After (1行)
    this.write_box_result(dst, ret);
    
  2. 引数検証ヘルパー

    // Before (3行)
    if args.len() != 1 {
        return Err(VMError::InvalidInstruction("push expects 1 arg".into()));
    }
    
    // After (1行)
    this.validate_args_exact("push", args, 1)?;
    
  3. Receiver変換ヘルパー

    // Before (4行)
    let recv_box = match recv.clone() {
        VMValue::BoxRef(b) => b.share_box(),
        other => other.to_nyash_box(),
    };
    
    // After (1行)
    let recv_box = this.convert_to_box(&recv);
    

Phase 2: 基盤整備Phase 1完了後

目標: エラー処理とPHI挿入の統一 期間: 5-7時間 削減: 250-400行

実装項目:

  • エラー生成ヘルパー95箇所
  • PHI挿入ヘルパー13箇所

Phase 3: 抜本改革(将来課題)

目標: Box Handler群の統合 期間: 1-2週間 削減: 300-400行 リスク: 中-高

備考: Phase 1-2の効果を見てから判断


期待される効果

定量的効果

指標 現状 Phase 1後 Phase 2後 Phase 3後
Handler総行数 3,335 2,965 (-11%) 2,715 (-19%) 2,415 (-28%)
重複パターン 260箇所 109箇所 (-58%) 46箇所 (-82%) <20箇所 (-92%)
保守対象箇所 散在 3ヶ所集約 5ヶ所集約 統一API

定性的効果

保守性向上: ロジック変更が1箇所で完結 可読性向上: 意図が明確な関数名 バグ削減: 共通ロジックのバグ修正が全体に波及 開発速度向上: 新機能追加時のボイラープレート削減 テスト容易性: ユーティリティ関数の単体テストで広範囲カバー 一貫性: エラーメッセージの統一


リスクと対策

Phase 1リスク: 極めて低

リスク 確率 影響 対策
ヘルパー関数のバグ 単体テスト、段階的移行
パフォーマンス劣化 極低 インライン化、ベンチマーク
既存動作の変更 1ファイルずつ、回帰テスト

推奨移行戦略

  1. テストファースト: ユーティリティ関数のテストを先に書く
  2. 並行期間: 新旧コードを共存させる
  3. 段階的移行: 1ファイルずつ確実に
  4. 回帰テスト: 各ファイル移行後にスモークテスト実行

実装の流れPhase 1

Week 1: インフラ構築1-2時間

1. utils/ ディレクトリ作成
2. register_ops.rs, validation.rs, conversions.rs 実装
3. ユニットテスト追加
4. 全テスト確認

Week 1-2: Handler更新3-5時間

小さいファイルから順番に:
1. boxes_array.rs (63行 → 50行)
2. boxes_map.rs (134行 → 110行)
3. boxes_string.rs (208行 → 170行)
4. boxes_plugin.rs (217行 → 180行)
5. boxes_instance.rs (153行 → 125行)
6. boxes_object_fields.rs (399行 → 330行)
7. boxes.rs (307行 → 250行)
8. calls.rs (907行 → 750行)

各ファイル更新後:
- コンパイル確認
- テスト実行
- コミット小さなPR

Week 2: 検証・ドキュメント1時間

1. 全ハンドラーで古いパターン検索
2. スモークテスト実行
3. ドキュメント更新
4. Phase 2計画開始

コード例Before/After

Example 1: ArrayBox.push

Before (6行):

"push" => {
    if args.len() != 1 {
        return Err(VMError::InvalidInstruction("push expects 1 arg".into()));
    }
    let val = this.reg_load(args[0])?.to_nyash_box();
    let _ = ab.push(val);
    if let Some(d) = dst {
        this.regs.insert(d, VMValue::Void);
    }
    return Ok(true);
}

After (4行, 33%削減):

"push" => {
    this.validate_args_exact("push", args, 1)?;
    let val = this.reg_load(args[0])?.to_nyash_box();
    let _ = ab.push(val);
    this.write_void(dst);
    return Ok(true);
}

Example 2: StringBox.indexOf

Before (19行):

"indexOf" => {
    let (needle, from_index) = match args.len() {
        1 => {
            let n = this.reg_load(args[0])?.to_string();
            (n, 0)
        }
        2 => {
            let n = this.reg_load(args[0])?.to_string();
            let from = this.reg_load(args[1])?.as_integer().unwrap_or(0);
            (n, from.max(0) as usize)
        }
        _ => {
            return Err(VMError::InvalidInstruction(
                "indexOf expects 1 or 2 args (search [, fromIndex])".into(),
            ));
        }
    };
    // ... implementation
    if let Some(d) = dst {
        this.regs.insert(d, VMValue::Integer(idx));
    }
    return Ok(true);
}

After (14行, 26%削減):

"indexOf" => {
    this.validate_args_range("indexOf", args, 1, 2)?;

    let needle = this.reg_load(args[0])?.to_string();
    let from_index = if args.len() >= 2 {
        this.reg_load(args[1])?.as_integer().unwrap_or(0).max(0) as usize
    } else {
        0
    };

    // ... implementation

    this.write_integer(dst, idx);
    return Ok(true);
}

推奨事項

🚀 即時実施推奨

Phase 1の実装: 低リスク・高効果・短時間で完了可能

理由

  1. 投資対効果が極めて高い: 5-8時間で270-380行削減
  2. リスクが低い: 既存パターンの単純な抽出
  3. 即効性がある: 実装後すぐに効果が現れる
  4. 基盤になる: Phase 2-3の土台

実施手順

  1. PHASE1_IMPLEMENTATION_GUIDE.md を読む
  2. Step 1-3でユーティリティ関数を実装1-2時間
  3. Step 6で1ファイルずつ更新3-5時間
  4. 完了後、効果測定とPhase 2計画

参考資料

調査で作成したドキュメント

  1. 詳細分析レポート: DUPLICATION_ANALYSIS_REPORT.md

    • 全重複パターンの詳細分析
    • リスク評価と期待効果
    • 付録(ファイルサイズ一覧など)
  2. Phase 1実装ガイド: PHASE1_IMPLEMENTATION_GUIDE.md

    • コピペで使えるコード例
    • トラブルシューティング
    • テスト戦略
  3. このサマリー: CLEANUP_SUMMARY_2025-11-06.md

    • 全体像の把握
    • クイックリファレンス

調査実行コマンド

# 重複パターン確認
grep -rn "if let Some(d) = dst { this.regs.insert" src/backend/mir_interpreter/handlers/
grep -rn "args.len()" src/backend/mir_interpreter/handlers/
grep -rn "match recv.clone()" src/backend/mir_interpreter/handlers/

# ファイルサイズ確認
wc -l src/backend/mir_interpreter/handlers/*.rs | sort -rn

# Phase 1実装後の確認
git diff --stat  # 変更行数確認
./tools/jit_smoke.sh  # 回帰テスト

Q&A

Q1: なぜPhase 1を優先

A: 低リスク・高効果・短時間で、Phase 2-3の土台になるため。

Q2: 既存テストは通る?

A: はい。ヘルパー関数は既存ロジックの抽出なので、動作は同一です。

Q3: パフォーマンスへの影響は?

A: ほぼゼロ。コンパイラの最適化でインライン化されます。

Q4: Phase 2-3はいつ実施

A: Phase 1完了後、効果を測定してから判断します。

Q5: 他のメンバーへの影響は?

A: 最小限。小さなPRに分割し、1ファイルずつレビューします。


次のステップ

  1. 調査完了 - このドキュメント
  2. ⏭️ Phase 1実装開始 - PHASE1_IMPLEMENTATION_GUIDE.md 参照
  3. Phase 2計画 - Phase 1完了後
  4. Phase 3検討 - Phase 1-2の効果測定後

作成者: Claude Code Agent 最終更新: 2025-11-06 次回更新: Phase 1完了時