Class ElvisCoalescingOperatorAsmGenerator


final class ElvisCoalescingOperatorAsmGenerator extends AbstractControlFlowAsmGenerator
Specialized generator for EK9 Elvis coalescing operator (:?). Handles CONTROL_FLOW_CHAIN with chain_type: "ELVIS_COALESCING_OPERATOR".

EK9 Elvis Coalescing Operator Pattern: lhs :? rhs

  • If LHS is null → returns RHS
  • If LHS is not null BUT unset → returns RHS
  • If LHS is not null AND set → returns LHS

Key Difference from Null Coalescing (??):

  • ?? checks ONLY null (IS_NULL instruction) - 1 case
  • :? checks BOTH null AND set (the null-safe ?: IS_NULL, then IS_SET) - 1 case

IR Structure:

CONTROL_FLOW_CHAIN [chain_type: "ELVIS_COALESCING_OPERATOR"]
  condition_chain:
    [case 1: case_type: "EXPRESSION"]
      condition_evaluation: [LOAD lhs, lhs_set = QUESTION_OPERATOR(lhs), CALL lhs_set._false()]
      condition_result: lhs_set (EK9 Boolean)
      primitive_condition: lhs_not_set  // absent or not set
      body_evaluation: [LOAD rhs, RETAIN rhs]  // the RHS - generated ONCE, evaluated only here
      body_result: rhs
  default_body_evaluation: [RETAIN lhs]  // LHS already evaluated
  default_result: lhs

Safety: the null-safe ? (a nested QUESTION_OPERATOR chain) never calls _isSet() on an absent LHS. The RHS used to be returned by two cases - "absent" and "not set" - and generated for each, so a nested chain doubled n times.

Stack Frame Invariant: All paths arrive at 'end' label with empty stack. Result is stored in local variable (overall_result).

  • Constructor Details

  • Method Details

    • generate

      public void generate(ControlFlowChainInstr instr)
      Generate bytecode for Elvis coalescing operator (:?).

      Uses the common coalescing pattern from AbstractControlFlowAsmGenerator.

      Stack Frame Invariant: Pre-condition: stack is empty Post-condition: stack is empty (result in local variable)

      Parameters:
      instr - CONTROL_FLOW_CHAIN instruction with ELVIS_COALESCING_OPERATOR type