Files
hakorune/docs/development/current/main/phase134b_stringbox_bridge.md
nyash-codex 5dec862686 docs(phase134-b): StringBox bridge 分離(指示書作成)
- 目標: boxcall.py:130-282の StringBox メソッド処理を分離
- 箱化: StringBoxBridge箱化モジュール実装
- 削減: boxcall.py 481→301行 (37%削減予定)
- パターン: Phase 133 ConsoleLlvmBridge を継承
- 6タスク: 設計doc、棚卸し、bridge実装、削除・委譲、テスト、doc更新

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 12:14:41 +09:00

12 KiB
Raw Blame History

Phase 134-B: StringBox bridge 分離

🎯 ゴール

StringBox メソッド処理の分散・重複ロジックを統合モジュール化 する。

目的:

  • boxcall.py:130-282 の StringBox メソッド処理length/substring/lastIndexOfを分離
  • 180行の重い処理stringbox.py に集約
  • boxcall.py から 1行の委譲呼び出し に削減
  • Phase 133 ConsoleLlvmBridge / Phase 134-A mir_call パターンを継承
Phase 134-A: mir_call.py unified 設計完成 ✅
        ↓
Phase 134-B: StringBox bridge 分離 ← ← ここ!
        ↓
Phase 134-C: CollectionBox bridge 分離

📋 スコープ(やること・やらないこと)

やること

  • boxcall.py:130-282 の StringBox メソッド処理を分析・抽出
  • StringBoxBridge 箱化モジュール を実装src/llvm_py/instructions/stringbox.py
  • StringBox メソッドlength, substring, lastIndexOfの LLVM IR lowering を統一
  • 複雑な最適化パスNYASH_LLVM_FAST, NYASH_STR_CPを stringbox.py に集約
  • boxcall.py の分岐を削除、1行委譲に削減
  • 既存テスト全て通過

やらないこと

  • StringBox の仕様・セマンティクス変更
  • 他の Box 処理Console/Array/Map等への影響
  • LLVM backend 全体の最適化StringBox 処理に限定)

🏗️ 6 つのタスク

Task 1: 設計ドキュメント作成

ファイル: docs/development/current/main/phase134b_stringbox_bridge.md(このファイル)

書く内容:

現状整理

boxcall.py 内の StringBox 処理:

  • 行 130-220: length/len メソッド約90行
    • NYASH_LLVM_FAST パス(最適化版)
    • literal folding"hello".length()5 定数)
    • length_cache 管理
  • 行 231-282: substring メソッド約51行
    • NYASH_STR_CP フラグcode point vs UTF-8 byte選択
    • 文字列スライシング処理
  • 行 284-323: lastIndexOf メソッド約39行
    • 文字列検索処理

問題点:

  1. ハードコードされたブリッジ: nyash.string.* への直接 call
  2. 複雑な最適化パス: 複数の環境変数フラグで制御
  3. キャッシュ・状態管理: length_cache, newbox_string_args の管理
  4. 他の Box 処理と混在: Console, Array, Map 処理と一緒

目指す構造

Phase 133 ConsoleLlvmBridge パターンを参考:

BoxCall(StringBox, method)
    ↓
StringBoxBridge 箱化モジュール
    ↓
StringBox メソッド種別判定length, substring, lastIndexOf
    ↓
対応する LLVM runtime 関数群に lowering
    (@nyash.string.length, @nyash.string.substring, etc.)

ファイル構成:

src/llvm_py/instructions/
  ├── stringbox.py 新規、180行
  │   ├── class StringBoxBridge
  │   ├── emit_stringbox_call()
  │   ├── _literal_fold_length()
  │   ├── _fast_strlen()
  │   └── _codepoint_mode()
  │
  └── boxcall.py (修正、-180行
      └── StringBox判定 → stringbox.emit_stringbox_call() に委譲

Task 2: 既存 boxcall.py の StringBox 部分の詳細棚卸し

対象ファイル: src/llvm_py/instructions/boxcall.py

やること:

  1. StringBox 処理の行数別カウント:

    sed -n '130,323p' src/llvm_py/instructions/boxcall.py | wc -l
    
    • length/len: ~90行
    • substring: ~51行
    • lastIndexOf: ~39行
    • 合計: ~180行
  2. 複雑な最適化パスの確認:

    • NYASH_LLVM_FAST の使用箇所
    • NYASH_STR_CP の使用箇所
    • literal folding のロジック
    • キャッシュ管理length_cache, newbox_string_args
  3. 内部依存関係の確認:

    • StringBox メソッドが他のメソッドを呼んでいるか
    • 他の Box メソッドが StringBox を参照しているか
  4. 既存テスト確認:

    rg "StringBox|string.*length|substring" src/llvm_py/tests/ --type python
    

結果記録: phase134b ドキュメントの「実装計画」に記載


Task 3: StringBoxBridge 箱化モジュールの実装

実装方針: Phase 133 ConsoleLlvmBridge パターンを継承

ファイル: src/llvm_py/instructions/stringbox.py(新規、~180行

責務:

  1. StringBox メソッド種別を判定length, substring, lastIndexOf等
  2. 文字列引数を LLVM IR 形式に変換
  3. 対応する LLVM runtime 関数呼び出しを生成

実装パターン:

# src/llvm_py/instructions/stringbox.py

class StringBoxBridge:
    """
    StringBox メソッド処理を箱化した専用モジュール

    Phase 133 ConsoleLlvmBridge パターンを継承
    """

    STRINGBOX_METHODS = {
        "length": 410,        # TypeRegistry slot
        "len": 410,           # alias
        "substring": 411,
        "lastIndexOf": 412,
        # ... etc
    }

    @staticmethod
    def emit_stringbox_call(builder, module, method_name, receiver, args):
        """
        StringBox メソッド呼び出しを LLVM IR に lowering

        Args:
            builder: LLVM IRBuilder
            module: LLVM Module
            method_name: メソッド名("length", "substring" etc.
            receiver: StringBox インスタンスi64 handle または i8* pointer
            args: メソッド引数リスト

        Returns:
            LLVM Valueメソッド戻り値
        """

        if method_name in ("length", "len"):
            return StringBoxBridge._emit_length(builder, module, receiver, args)

        elif method_name == "substring":
            return StringBoxBridge._emit_substring(builder, module, receiver, args)

        elif method_name == "lastIndexOf":
            return StringBoxBridge._emit_lastindexof(builder, module, receiver, args)

        else:
            raise ValueError(f"Unknown StringBox method: {method_name}")


    @staticmethod
    def _emit_length(builder, module, receiver, args):
        """
        StringBox.length() / StringBox.len() を LLVM IR に lowering

        Supports:
        - NYASH_LLVM_FAST: Fast path optimization
        - literal folding: "hello".length() → 5
        """

        # Phase 134-A より移動: boxcall.py:130-220 のロジック
        # - literal 判定
        # - length_cache 参照
        # - fast path vs normal path

        pass


    @staticmethod
    def _emit_substring(builder, module, receiver, args):
        """
        StringBox.substring(start, end) を LLVM IR に lowering

        Supports:
        - NYASH_STR_CP: Code point vs UTF-8 byte mode
        """

        # Phase 134-A より移動: boxcall.py:231-282 のロジック
        pass


    @staticmethod
    def _emit_lastindexof(builder, module, receiver, args):
        """
        StringBox.lastIndexOf(needle) を LLVM IR に lowering
        """

        # Phase 134-A より移動: boxcall.py:284-323 のロジック
        pass


    @staticmethod
    def _literal_fold_length(literal_str):
        """
        Literal StringBox の length を compile-time に計算

        例: "hello".length() → 5
        """

        # literal folding ロジック抽出
        pass


    @staticmethod
    def _fast_strlen(builder, module, receiver):
        """
        NYASH_LLVM_FAST パスでの高速 strlen 実装
        """

        # fast path 抽出
        pass


    @staticmethod
    def _codepoint_mode():
        """
        NYASH_STR_CP フラグから code point / UTF-8 byte モードを判定
        """

        # フラグ判定ロジック抽出
        pass

Task 4: boxcall.py から StringBox 処理を削除・委譲に変更

やること:

  1. 現在の分岐を確認:

    # boxcall.py 内のStringBox判定 (例)
    if box_id == CoreBoxId::StringBox or box_name == "StringBox":
        # 行 130-323: StringBox メソッド処理
        ...
    
  2. 分岐を1行委譲に置き換え:

    if box_id == CoreBoxId::StringBox:
        # Phase 134-B: StringBoxBridge に委譲
        return stringbox.StringBoxBridge.emit_stringbox_call(
            builder, module, method_name, receiver, args
        )
    
  3. import 追加:

    from .stringbox import StringBoxBridge
    
  4. 既存コードの削除:

    • 行 130-323 の StringBox 処理ブロックを削除

Task 5: 既存テスト実行・確認

やること:

  1. 既存テスト実行:

    cargo test --release 2>&1 | grep -E "StringBox|string.*length"
    
  2. stringbox.py のテスト:

    • 新規 src/llvm_py/tests/test_stringbox.py を追加(オプション)
    • または既存テストで動作確認
  3. 全テスト PASS 確認:

    cargo test --release 2>&1 | tail -5
    

Task 6: ドキュメント & CURRENT_TASK 更新

やること:

  1. phase134b_stringbox_bridge.md に追記:

    ## Phase 134-B 実装結果
    
    ### 修正ファイル
    - `src/llvm_py/instructions/stringbox.py`: StringBoxBridge 新規作成
    - `src/llvm_py/instructions/boxcall.py`: StringBox 処理を委譲に変更
    
    ### テスト結果
    - StringBox 関連テスト: ✅ PASS
    - 全テスト: ✅ PASS
    
    ### 成果
    - boxcall.py: 481 → 301行 (37%削減)
    - StringBox メソッド処理を stringbox.py に一元化
    - Phase 134-C CollectionBox 分離の準備完了
    
  2. CURRENT_TASK.md 更新:

    ### Phase 134-B: StringBox bridge 分離 ✅
    
    **完了内容**:
    - boxcall.py:130-282 の StringBox メソッド処理を分離
    - StringBoxBridge 箱化モジュール実装
    - 複雑な最適化パス (NYASH_LLVM_FAST, NYASH_STR_CP) を集約
    
    **修正箇所**:
    - src/llvm_py/instructions/stringbox.py (新規、180行)
    - src/llvm_py/instructions/boxcall.py (-180行)
    
    **テスト結果**: 全テスト PASS
    
    **成果**:
    - boxcall.py: 481 → 301行 (37%削減)
    - StringBox メソッド処理を stringbox.py に一元化
    - 次分割での拡張が容易に
    
    **次フェーズ**: Phase 134-C - CollectionBox bridge 分離
    

完成チェックリストPhase 134-B

  • boxcall.py の StringBox 処理の詳細棚卸し
  • 複雑な最適化パスNYASH_LLVM_FAST, NYASH_STR_CPの確認
  • StringBoxBridge 箱化モジュール実装
  • StringBox メソッド別の lowering 関数実装
    • _emit_length()
    • _emit_substring()
    • _emit_lastindexof()
  • 最適化ヘルパー実装
    • _literal_fold_length()
    • _fast_strlen()
    • _codepoint_mode()
  • boxcall.py から StringBox 処理を削除
  • StringBox判定 → stringbox.emit_stringbox_call() に委譲
  • import 追加確認
  • 既存テスト実行 & 全て PASS 確認
  • phase134b_stringbox_bridge.md に実装結果追記
  • CURRENT_TASK.md 更新
  • git commit で記録

所要時間

4〜5 時間程度

  • Task 1-2 (設計 & 棚卸し): 45分
  • Task 3 (StringBoxBridge 実装): 1.5時間
  • Task 4 (boxcall.py 修正): 45分
  • Task 5-6 (テスト・ドキュメント): 1.5時間

次のステップ

Phase 134-C: CollectionBox bridge 分離

  • boxcall.py:325-375 の Array/Map メソッド処理を collectionbox.py に分離
  • Phase 133/134-A/134-B の箱化パターンを継承

進捗

  • Phase 130-133: JoinIR → LLVM 第3章完全クローズ
  • Phase 134-A: mir_call.py unified 設計完成
  • 🎯 Phase 134-B: StringBox bridge 分離(← 現在のフェーズ
  • 📋 Phase 134-C: CollectionBox bridge 分離(予定)
  • 📋 Phase 135: LLVM フラグカタログ化(予定)