Files
hakorune/docs/development/current/main/phases/phase-285/ret-py-phase3-boxification.md

5.0 KiB
Raw Blame History

ret.py Phase 3 Boxification ReportAppendix

Summary

Status: COMPLETE Date: 2025-12-27 Commits: 32aa0ddf6, 5a88c4eb2Phase 285 P4 Post-Completion

Metrics

  • File size: 250 → 352 lines (+102 lines)
  • Main function: 166 → 117 lines (-49 lines, -29% reduction)
  • New Boxes created: 2
  • Tests: All passing

Changes

New Boxes Created

1. StringBoxerBox (15 lines)

Responsibility: Box string pointers to handles

Extracted from: Lines 157-167 of original lower_return()

Justification:

  • Clear single responsibility
  • Can be tested independently
  • Eliminates 11 lines of inline function declaration logic

Code location: Lines 84-119

2. ReturnPhiSynthesizerBox (101 lines)

Responsibility: Synthesize PHI nodes for return values

Extracted from: Lines 190-243 of original lower_return()

Justification:

  • Complex logic (~50 lines) with clear boundaries
  • Respects _disable_phi_synthesis flag (Phase 131-4)
  • Can be tested independently
  • Two methods for separation of concerns:
    • should_synthesize_phi(): Decision logic (zero-like detection)
    • synthesize_phi(): PHI creation logic

Code location: Lines 122-233

What Was NOT Boxified (And Why)

1. Fast path vmap lookup (Lines 276-288)

Reason: Only ~13 lines of straightforward lookups Context dependency: Tightly coupled to vmap, value_id Verdict: More readable as inline code

2. Global vmap fallback (Lines 290-296)

Reason: Only ~7 lines of simple fallback logic Verdict: Too simple to warrant a Box

3. Resolver-based resolution (Lines 298-314)

Reason: Highly context-dependent, but extracted string boxing part Verdict: Partial boxification (StringBoxerBox extracted)

4. Vmap fallback + Default values (Lines 316-333)

Reason: Simple fallback logic (~18 lines) Verdict: Clear and readable as-is

Box-First Principles Applied

Single Responsibility

  • Each Box has one clear purpose
  • StringBoxerBox: String pointer → handle conversion
  • ReturnPhiSynthesizerBox: PHI synthesis for returns

Boundaries Clear

  • Clean interfaces with well-defined parameters
  • No internal state leakage
  • Caller provides all context via parameters

Fail-Fast

  • No unnecessary try/except in new Boxes
  • Exceptions propagate naturally to caller's existing try/except (line 345)

Testable

  • Both Boxes can be unit tested independently
  • StringBoxerBox: Pass builder + pointer → verify boxer call
  • ReturnPhiSynthesizerBox: Pass test data → verify PHI creation

Verification

Unit Test

NYASH_LLVM_USE_HARNESS=1 NYASH_DISABLE_PLUGINS=1 \
  ./target/release/hakorune --backend llvm \
  apps/tests/phase286_pattern5_return_min.hako
# Expected: exit code 7 ✅

Integration Test

bash tools/smokes/v2/profiles/integration/apps/phase284_p2_return_in_loop_llvm.sh
# Expected: PASS ✅

Code Structure After Refactoring

ret.py (352 lines)
├── UnreachableReturnHandlerBox (Phase 1-2)
├── ReturnTypeAdjusterBox (Phase 1-2)
├── StringBoxerBox (Phase 3) ⭐ NEW
├── ReturnPhiSynthesizerBox (Phase 3) ⭐ NEW
└── lower_return() (117 lines, -29%)
    ├── Context extraction (ctx → resolver/preds/etc)
    ├── Fast path vmap lookup (inline)
    ├── Global vmap fallback (inline)
    ├── Resolver-based resolution (inline + StringBoxerBox)
    ├── Vmap fallback + defaults (inline)
    ├── PHI synthesis (ReturnPhiSynthesizerBox) ⭐
    ├── Type adjustment (ReturnTypeAdjusterBox)
    └── Emit return

Decision Rationale

What to Boxify?

Criteria:

  1. Complex logic (>30 lines)
  2. Clear single responsibility
  3. Can be tested independently
  4. Improves readability

What NOT to Boxify?

Criteria:

  1. Too simple (<15 lines)
  2. Too context-dependent (needs 5+ parameters)
  3. Boxifying reduces readability

Conclusion

Successfully Boxified

  • StringBoxerBox: Clean extraction of string pointer boxing
  • ReturnPhiSynthesizerBox: Major complexity reduction in main function

Correctly Avoided Boxification

  • Fast path lookups: Too simple and context-dependent
  • Fallback logic: Clear and readable as inline code
  • Default value generation: Just 3 simple cases

Impact

  • Readability: Improved (main function -29% lines)
  • Testability: Improved (2 new independently testable units)
  • Maintainability: Improved (clear separation of concerns)
  • Complexity: Slightly increased (2 new classes, but justified)

Recommendation

Ready for commit:

This refactoring follows Box-First principles while avoiding unnecessary complexity. The balance between boxification and inline code is well-judged.

Next Steps (Optional)

If future complexity arises in the non-boxified sections, consider:

  1. ValueResolverBox: If resolution logic (lines 298-314) grows significantly
  2. DefaultValueGeneratorBox: If default value logic becomes more complex

For now, the current balance is optimal.