Class ForRangePolymorphicAsmGenerator


final class ForRangePolymorphicAsmGenerator extends AbstractControlFlowAsmGenerator
JVM bytecode generator for FOR_RANGE_POLYMORPHIC IR instruction.

Generates three-way dispatch based on runtime direction detection (start <=> end):

  • Ascending: direction < 0 → loop with current <= end, current++
  • Descending: direction > 0 → loop with current >= end, current--
  • Equal: direction == 0 → single iteration with loopVariable = current

Bytecode Pattern:

; Initialization (includes ASSERT for start._isSet() and end._isSet())
[evaluate start, end, compute direction = start <=> end, current = start]

; Three-way dispatch
[check direction < 0]
ifne ascending_label
[check direction > 0]
ifne descending_label
; Fall through to equal

equal_label:
  loopVariable = current
  [body once]
  goto end_label

ascending_label:
asc_loop_start:
  [check current <= end]
  ifeq end_label              ; Exit if false
  loopVariable = current
  [body]
  current = current._inc()
  goto asc_loop_start

descending_label:
desc_loop_start:
  [check current >= end]
  ifeq end_label
  loopVariable = current
  [body]
  current = current._dec()
  goto desc_loop_start

end_label:

Stack Frame Invariant: Stack is empty before loop, after initialization, at loop start, after each iteration, and at loop end. All values stored in local variables.

ASSERT Handling: ASSERT instructions in initialization sequence (for start._isSet() and end._isSet() validation) are handled automatically by recursive delegation to BranchInstrAsmGenerator. No special handling needed.

Label Naming: Uses loopScopeId from ScopeMetadata to ensure uniqueness, preventing collisions in nested loops with same variable names.

  • Constructor Details

  • Method Details

    • generate

      public void generate(ForRangePolymorphicInstr instr)
      Generate JVM bytecode for polymorphic FOR_RANGE loop.

      Implementation Strategy:

      1. Emit initialization IR (evaluates start, end, direction, current)
      2. Create labels using loopScopeId (ensures uniqueness in nested loops)
      3. Generate three-way dispatch (ascending/descending/equal)
      4. Generate equal case (single iteration, fall through)
      5. Generate ascending case (loop with current++)
      6. Generate descending case (loop with current--)
      7. Place end label (all paths converge)

      All IR instructions are processed via recursive delegation to OutputVisitor, which routes them to specialized generators (Call, Literal, Memory, Branch, etc.).

      Stack Frame Invariant maintained throughout: Pre-condition: stack is empty Post-condition: stack is empty

      Parameters:
      instr - FOR_RANGE_POLYMORPHIC instruction with all dispatch cases and metadata