Files
hakorune/docs/development/current/main/phases/phase-274
tomoaki 757193891f feat(llvm/phi): Phase 277 P1 - fail-fast validation for PHI strict mode
## Summary
Implemented fail-fast validation for PHI ordering and value resolution in strict mode.

## Changes

### P1-1: Strict mode for "PHI after terminator"
- File: `src/llvm_py/phi_wiring/wiring.py::ensure_phi`
- Behavior: `NYASH_LLVM_PHI_STRICT=1` → RuntimeError if PHI created after terminator
- Default: Warning only (no regression)

### P1-2: Strict mode for "fallback 0"
- File: `src/llvm_py/phi_wiring/wiring.py::wire_incomings`
- Behavior: Strict mode forbids silent fallback to 0 (2 locations)
  - Location 1: Unresolvable incoming value
  - Location 2: Type coercion failure
- Error messages point to next debug file: `llvm_builder.py::_value_at_end_i64`

### P1-3: Connect verify_phi_ordering() to execution path
- File: `src/llvm_py/builders/function_lower.py`
- Behavior: Verify PHI ordering after all instructions emitted
- Debug mode: Shows " All N blocks have correct PHI ordering"
- Strict mode: Raises RuntimeError with block list if violations found

## Testing
 Test 1: strict=OFF - passes without errors
 Test 2: strict=ON - passes without errors (no violations in test fixtures)
 Test 3: debug mode - verify_phi_ordering() connected and running

## Scope
- LLVM harness (Python) changes only
- No new environment variables (uses existing 3 from Phase 277 P2)
- No JoinIR/Rust changes (root fix is Phase 279)
- Default behavior unchanged (strict mode opt-in)

## Next Steps
- Phase 278: Remove deprecated env var support
- Phase 279: Root fix - unify "2本のコンパイラ" pipelines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 14:48:37 +09:00
..

Phase 274 (active): Type SSOT Alignment (local + dynamic runtime)

Status: active / design-first

Goal: make the language-level type semantics and the runtime behavior consistent and easy to reason about, without turning Nyash into a statically typed language.

This phase is about:

  • clarifying SSOT docs,
  • closing “frontend emits it but VM cant run it” gaps,
  • and preventing “type facts / resolver guessing” from silently becoming language semantics.

Background (why this exists)

Current state:

  • Nyash is dynamic at runtime (VM executes tagged values).
  • MIR builder attaches type metadata (value_types, value_origin_newbox) for routing/optimization.
  • Some docs describe stricter semantics than the VM actually implements.
  • TypeOp is emitted by the frontend for is/as.

Problems:

  • Spec drift: quick docs vs runtime behavior differ (truthiness / equality / compare / +).
  • Capability drift across backends: “VM is correct” but “LLVM harness differs” (TypeOp).
  • Type metadata risks becoming implicit semantics via resolver fallback chains.

SSOT decisions should be expressed in:

  • language docs (meaning),
  • runtime (execution),
  • and only then optimization facts (rewrite / routing).

SSOT references

  • Language type semantics (SSOT): docs/reference/language/types.md
  • VM semantics source: src/backend/abi_util.rs, src/backend/mir_interpreter/helpers.rs
  • MIR type vocabulary: src/mir/types.rs
  • Call certainty vocabulary: src/mir/definitions/call_unified.rs

Scope (P0/P1/P2/P3)

P0 (docs-only): establish SSOT and remove contradictions

Deliverables:

  • docs/reference/language/types.md (SSOT)
  • Quick-reference points to SSOT and stops contradicting runtime

Acceptance:

  • docs no longer claim semantics that the Rust VM clearly violates.

P1 (impl): make TypeOp runnable on Rust VM

Goal:

  • x.is("T") / x.as("T") lowering exists already; make it executable on the primary backend (Rust VM).

Acceptance (minimum):

  • Rust VM implements MirInstruction::TypeOp { op: Check|Cast, value, ty }
  • Add a small executable fixture/smoke that exercises is/as
  • No new env vars; fail-fast errors on unsupported casts/checks

Implementation guide:

  • docs/development/current/main/phases/phase-274/P1-INSTRUCTIONS.md

Status: done (2025-12-22)

Artifacts:

  • Fixture: apps/tests/phase274_p1_typeop_is_as_min.hako
  • Smoke: tools/smokes/v2/profiles/integration/apps/phase274_p1_typeop_is_as_vm.sh
  • VM handler: src/backend/mir_interpreter/handlers/type_ops.rs

P2 (impl): align LLVM (llvmlite harness) TypeOp to SSOT

Goal:

  • Make LLVM harness behavior match Rust VM (SSOT) for TypeOp(Check/Cast).

Current mismatch:

  • src/llvm_py/instructions/typeop.py is stubbed:
    • is returns 0 for most types (special-cases IntegerBox as “non-zero”)
    • cast/as are pass-through

Acceptance (minimum):

  • With NYASH_LLVM_USE_HARNESS=1 + --backend llvm, the P1 fixture has the same observable result as Rust VM.
  • Unsupported cases fail-fast (TypeError), not silent 0/“passthrough”.
  • No new environment-variable toggles; differences must be fixed or explicitly documented.

Implementation guide:

  • docs/development/current/main/phases/phase-274/P2-INSTRUCTIONS.md

Status: done (2025-12-22)

Artifacts:

  • Kernel type check helper: crates/nyash_kernel/src/lib.rs (nyash.any.is_type_h)
  • LLVM TypeOp lowering: src/llvm_py/instructions/typeop.py
  • MIR JSON emission fix (bin): src/runner/mir_json_emit.rs (emit op:"typeop")
  • Fixture (LLVM-safe): apps/tests/phase274_p2_typeop_primitives_only.hako
  • Smoke (LLVM): tools/smokes/v2/profiles/integration/apps/phase274_p2_typeop_is_as_llvm.sh

P3 (decision + optional impl): tighten or document coercions

Decision points to settle (SSOT):

  • Truthiness for arbitrary BoxRef (allow “any object is truthy” vs fail-fast)
  • Equality cross-coercions (int↔bool, int↔float) — keep, restrict, or gate behind a profile
  • + mixed numeric types (int+float) — keep TypeError or add explicit conversions

Acceptance:

  • whichever behavior is chosen becomes consistent across backends and docs.

Decision memo (P3):

  • docs/development/current/main/phases/phase-274/P3-DECISIONS.md

Status:

  • P3 decisions are accepted; implementation is tracked in Phase 275.

Non-goals

  • Full static typing / inference engine
  • Widening the language surface area (new keywords) as the first move
  • Adding more environment-variable toggles as a long-term solution