Class BytecodeGenerationContext
java.lang.Object
org.ek9lang.compiler.backend.jvm.BytecodeGenerationContext
Context stack for bytecode generation control flow.
Mirrors IRGenerationContext pattern from IR generation phase.
Manages stack of control flow contexts (loop, switch, try-catch, if-chain) allowing nested generators to query enclosing context for label information.
Phase 1: Loop support only (fixes nested if in for-range bug).
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumDispatch case for FOR_RANGE_POLYMORPHIC three-way generation. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidenterDispatchCase(BytecodeGenerationContext.DispatchCase dispatchCase) Enter FOR_RANGE dispatch case BEFORE processing body for that case.voidEnter loop context BEFORE processing loop body.voidExit FOR_RANGE dispatch case AFTER processing body.voidexitLoop()Exit loop context AFTER processing loop body.findFrame(BytecodeFrameType frameType) Find nearest enclosing frame of specific type.Get all scope IDs in stack order (for debugging).Query: Which FOR_RANGE dispatch case are we in? Used by label generation to make names unique per dispatch case.Get current scope ID (top of stack).Optional<org.objectweb.asm.Label> Get enclosing loop's continue label.Optional<org.objectweb.asm.Label> Get enclosing loop's exit label.booleanisEmpty()Check if stack is empty (for validation).booleanisInside(BytecodeFrameType frameType) Query: Are we inside a specific frame type.booleanQuery: Are we currently inside a loop.
-
Constructor Details
-
BytecodeGenerationContext
public BytecodeGenerationContext()
-
-
Method Details
-
enterLoop
public void enterLoop(String scopeId, org.objectweb.asm.Label continueLabel, org.objectweb.asm.Label exitLabel) Enter loop context BEFORE processing loop body.- Parameters:
scopeId- Unique scope identifier (e.g., "for_loop_123")continueLabel- Where to jump for next iteration (increment point)exitLabel- Where to jump when loop exits naturally
-
exitLoop
public void exitLoop()Exit loop context AFTER processing loop body. Must be called in finally block to ensure cleanup. -
isInsideLoop
public boolean isInsideLoop()Query: Are we currently inside a loop.- Returns:
- true if any enclosing frame is a loop
-
getLoopContinueLabel
Get enclosing loop's continue label. Used by nested control flow (if statements) to determine where to jump after body.- Returns:
- Continue label of nearest enclosing loop, or empty if not in loop
-
getLoopExitLabel
Get enclosing loop's exit label. Used for early loop exit scenarios (future).- Returns:
- Exit label of nearest enclosing loop, or empty if not in loop
-
enterDispatchCase
Enter FOR_RANGE dispatch case BEFORE processing body for that case. Makes label names unique when same body IR is processed three times.- Parameters:
dispatchCase- Which dispatch case is being generated (EQUAL, ASCENDING, DESCENDING)
-
exitDispatchCase
public void exitDispatchCase()Exit FOR_RANGE dispatch case AFTER processing body. Must be called in finally block to ensure cleanup. -
getCurrentDispatchCase
Query: Which FOR_RANGE dispatch case are we in? Used by label generation to make names unique per dispatch case.- Returns:
- Current dispatch case, or empty if not in FOR_RANGE dispatch
-
isInside
Query: Are we inside a specific frame type.- Parameters:
frameType- Frame type to check for- Returns:
- true if any enclosing frame matches type
-
findFrame
Find nearest enclosing frame of specific type.- Parameters:
frameType- Frame type to search for- Returns:
- Nearest matching frame, or empty if not found
-
getCurrentScopeId
-
getAllScopeIds
-
isEmpty
public boolean isEmpty()Check if stack is empty (for validation).- Returns:
- true if no frames on stack
-