Skip to content

feat(ILO-401): VM/JIT codegen for Value::Variant (sum types)#640

Merged
danieljohnmorris merged 1 commit into
feature/sum-types-mvpfrom
feature/sum-types-jit
May 22, 2026
Merged

feat(ILO-401): VM/JIT codegen for Value::Variant (sum types)#640
danieljohnmorris merged 1 commit into
feature/sum-types-mvpfrom
feature/sum-types-jit

Conversation

@danieljohnmorris
Copy link
Copy Markdown
Collaborator

Summary

  • Removes the ILO-E803 SumTypeNotSupported bailout that forced all sum-type programs to fall back to the tree interpreter
  • Implements variant construction and pattern-matching in the bytecode VM using standard record opcodes (OP_RECNEW, OP_RECFLD, OP_EQ, OP_LOADK)
  • Cranelift AOT/JIT works without any changes — it already handles all emitted opcodes

Codegen strategy

Each variant is stored as a 2-field heap record of type __variant_<typename>:

  • Field 0: tag — numeric ordinal (0-based) of the variant within the sum type
  • Field 1: payload — constructor argument for payload variants, or Nil

Construction (circle 5 → payload variant, point → no-payload variant):

  • emit_variant_record(type_id, tag_idx, payload_reg) emits OP_LOADK (tag constant) + OP_RECNEW
  • Intercepted in Expr::Call (before user-function lookup) and Expr::Ref

Pattern matching (?s{circle(r):...}):

  • Pattern::Variant emits OP_RECFLD sub_reg, 0OP_EQOP_JMPF, then optionally OP_RECFLD sub_reg, 1 to bind payload

Test plan

  • examples/sum-types.ilo produces correct output under --vm and --jit
  • vm::tests::sum_type_vm_zero_payload_variant — no-payload variant constructs and matches
  • vm::tests::sum_type_vm_payload_variant_match — payload variant carries value through match
  • vm::tests::sum_type_vm_matches_interpreter — VM result equals tree interpreter result
  • vm::tests::sum_type_vm_no_e803_bailout — compile no longer returns ILO-E803
  • compile_cranelift::tests::codegen_sum_type_variants_emit_object — Cranelift accepts bytecode
  • compile_cranelift::tests::codegen_sum_type_zero_payload_variant_emit_object — zero-payload variant codegen

🤖 Generated with Claude Code

…RECFLD

Eliminates the ILO-E803 SumTypeNotSupported bailout that previously caused
any program containing a sum-type declaration to fall back to the tree
interpreter.  The VM compiler now lowers variant construction and
pattern-matching using standard record opcodes that Cranelift already handles.

Representation: each variant is a 2-field heap record of type
`__variant_<typename>` with fields ["tag" (numeric ordinal), "payload"].

- Construction: Expr::Call on a payload variant / Expr::Ref on a no-payload
  variant both emit emit_variant_record() → OP_LOADK tag + OP_RECNEW.
- Pattern matching: Pattern::Variant extracts field 0 (OP_RECFLD), compares
  to the expected ordinal (OP_EQ + OP_JMPF), and optionally binds field 1.
- Cranelift AOT/JIT: no changes needed — it already handles OP_RECNEW,
  OP_RECFLD, OP_EQ, OP_LOADK.

Tests: 4 new vm::tests (zero-payload, payload, VM-vs-interpreter parity,
no-E803) and 2 new compile_cranelift::tests (object codegen for both variant
shapes).  examples/sum-types.ilo verified under --vm and --jit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@danieljohnmorris danieljohnmorris merged commit a97cd46 into feature/sum-types-mvp May 22, 2026
@danieljohnmorris danieljohnmorris deleted the feature/sum-types-jit branch May 22, 2026 01:39
danieljohnmorris added a commit that referenced this pull request May 22, 2026
feat(ILO-401): VM/JIT codegen for Value::Variant (sum types)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant