Class ElvisCoalescingOperatorAsmGenerator
java.lang.Object
org.ek9lang.compiler.backend.jvm.AbstractAsmGenerator
org.ek9lang.compiler.backend.jvm.AbstractControlFlowAsmGenerator
org.ek9lang.compiler.backend.jvm.ElvisCoalescingOperatorAsmGenerator
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).
-
Field Summary
Fields inherited from class AbstractControlFlowAsmGenerator
contextFields inherited from class AbstractAsmGenerator
classWriter, constructTargetTuple, outputVisitor -
Constructor Summary
ConstructorsConstructorDescriptionElvisCoalescingOperatorAsmGenerator(ConstructTargetTuple constructTargetTuple, OutputVisitor outputVisitor, org.objectweb.asm.ClassWriter classWriter, BytecodeGenerationContext context) -
Method Summary
Modifier and TypeMethodDescriptionvoidgenerate(ControlFlowChainInstr instr) Generate bytecode for Elvis coalescing operator (:?).Methods inherited from class AbstractControlFlowAsmGenerator
branchIfFalse, branchIfTrue, copyResultVariable, createControlFlowLabel, generateCoalescingPattern, jumpTo, placeLabel, processBodyEvaluation, processConditionCase, processConditionCaseWithoutLabelPlacement, processConditionEvaluation, processInstructions, processSequentialCaseChainMethods inherited from class AbstractAsmGenerator
convertToJvmDescriptor, convertToJvmName, extractFieldName, generateBooleanLiteral, generateCharacterLiteral, generateDebugInfo, generateFloatLiteral, generateIntegerLiteral, generateLoadVariable, generateLocalVariableTable, generateMethodDescriptor, generateObjectLiteral, generateStackOperation, generateStoreVariable, generateStoreVariableAsInt, generateStringLiteral, getCurrentMethodVisitor, getFieldDescriptor, getMethodContext, getOrCreateLabel, getOwnerClassName, getVariableIndex, isFieldAccess, isVariableAllocated, isVariableFieldAccess, setCurrentMethodVisitor, setSharedMethodContext, toJvmFieldName, trackTempVariableFromLiteral, trackTempVariableFromLoad
-
Constructor Details
-
ElvisCoalescingOperatorAsmGenerator
ElvisCoalescingOperatorAsmGenerator(ConstructTargetTuple constructTargetTuple, OutputVisitor outputVisitor, org.objectweb.asm.ClassWriter classWriter, BytecodeGenerationContext context)
-
-
Method Details
-
generate
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
-