Class SwitchExpressionAsmGenerator
EK9 Switch Expression Pattern:
result <- switch value
<- rtn as String: "Unknown"
case 1
rtn: "One"
case 2
rtn: "Two"
default
rtn: "Other"
Key Differences from Switch Statement:
- Has return variable declared with returningParam (
<- rtn as Type: defaultValue) - Each case body stores result into return variable
- Default case also stores into return variable
- Return variable transferred to result variable after switch completes
IR Structure:
CONTROL_FLOW_CHAIN [chain_type: "SWITCH_EXPRESSION"]
return_variable: rtn
return_variable_type: org.ek9.lang::String
return_variable_setup:
[REFERENCE rtn, LOAD_LITERAL "Unknown", RETAIN, SCOPE_REGISTER, STORE rtn, RETAIN rtn]
evaluation_variable: _temp3 (switch value)
condition_chain:
[case 1: LITERAL check]
condition_evaluation: [load value, compare with 1]
body_evaluation: [SCOPE_ENTER, LOAD_LITERAL "One", RELEASE rtn, STORE rtn, RETAIN rtn, SCOPE_EXIT]
body_result: rtn
[case 2: LITERAL check]
...
default_body_evaluation:
[SCOPE_ENTER, LOAD_LITERAL "Other", RELEASE rtn, STORE rtn, RETAIN rtn, SCOPE_EXIT]
default_result: rtn
result: rtn (overall result variable)
Bytecode Pattern (Sequential Evaluation):
; Return variable setup (initialize with default value)
[return_variable_setup instructions]
; Evaluation variable setup (switch expression)
[evaluation variable already loaded by AssignmentExprInstrGenerator]
; Case 1
[condition evaluation]
iload primitive_condition
ifeq case_2 ; Branch if false
[case 1 body - stores into rtn]
goto end ; Exit switch
case_2:
[condition evaluation]
iload primitive_condition
ifeq default_label ; Branch if false
[case 2 body - stores into rtn]
goto end
default_label:
[default body - stores into rtn]
; Fall through to end
end:
; rtn now holds the result value
; Ownership transfer happens in AssignmentExprInstrGenerator:
; STORE _temp1, rtn
; RELEASE rtn
; RETAIN _temp1
; SCOPE_REGISTER _temp1
Stack Frame Invariant: All paths arrive at 'end' label with empty stack. Result is in the return variable (rtn), ready for ownership transfer.
Design Note: Like switch statement, uses sequential evaluation (if/else-if pattern) rather than JVM tableswitch/lookupswitch for rich operator semantics and type flexibility.
-
Nested Class Summary
Nested classes/interfaces inherited from class AbstractAsmGenerator
AbstractAsmGenerator.LocalVariableInfo, AbstractAsmGenerator.MethodContext, AbstractAsmGenerator.ScopeInfo, AbstractAsmGenerator.TempVariableSource -
Field Summary
Fields inherited from class AbstractControlFlowAsmGenerator
contextFields inherited from class AbstractAsmGenerator
classWriter, constructTargetTuple, outputVisitor -
Constructor Summary
ConstructorsConstructorDescriptionSwitchExpressionAsmGenerator(ConstructTargetTuple constructTargetTuple, OutputVisitor outputVisitor, org.objectweb.asm.ClassWriter classWriter, BytecodeGenerationContext context) -
Method Summary
Modifier and TypeMethodDescriptionvoidgenerate(ControlFlowChainInstr instr) Generate bytecode for switch expression.Methods inherited from class AbstractControlFlowAsmGenerator
branchIfFalse, branchIfTrue, copyResultVariable, createControlFlowLabel, jumpTo, placeLabel, processBodyEvaluation, processConditionCase, processConditionCaseWithoutLabelPlacement, processConditionEvaluation, processInstructionsMethods inherited from class AbstractAsmGenerator
convertToJvmDescriptor, convertToJvmName, extractFieldName, generateBooleanLiteral, generateCharacterLiteral, generateDebugInfo, generateFloatLiteral, generateIntegerLiteral, generateLoadVariable, generateLocalVariableTable, generateMethodDescriptor, generateObjectLiteral, generateStackOperation, generateStoreVariable, generateStringLiteral, getCurrentMethodVisitor, getFieldDescriptor, getMethodContext, getOrCreateLabel, getOwnerClassName, getVariableIndex, isFieldAccess, isVariableAllocated, setCurrentMethodVisitor, setSharedMethodContext, trackTempVariableFromLiteral, trackTempVariableFromLoad
-
Constructor Details
-
SwitchExpressionAsmGenerator
SwitchExpressionAsmGenerator(ConstructTargetTuple constructTargetTuple, OutputVisitor outputVisitor, org.objectweb.asm.ClassWriter classWriter, BytecodeGenerationContext context)
-
-
Method Details
-
generate
Generate bytecode for switch expression.Control Flow:
- Return variable setup already processed (happens before CONTROL_FLOW_CHAIN)
- For each case: evaluate condition, branch if false, execute body, jump to end
- Process default case (updates return variable)
- Place end label where all paths converge
Stack Frame Invariant: Pre-condition: stack is empty Post-condition: stack is empty (result in return variable)
NOTE: Return variable setup (rtn initialization with default value) happens in IR generation before this CONTROL_FLOW_CHAIN instruction. Those instructions are already processed by the time we reach this generator. See AssignmentExprInstrGenerator where processSwitchExpression() calls the switch statement generator.
- Parameters:
instr- CONTROL_FLOW_CHAIN instruction with SWITCH_EXPRESSION type
-