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).Get current scope ID (top of stack).Query: Get the full dispatch case path for label generation.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. Uses a stack to support nested for-range loops — each level pushes its dispatch case. Label names include the full dispatch path (e.g., "ascending_descending_") to ensure uniqueness at any nesting depth.- 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. -
getDispatchCasePath
Query: Get the full dispatch case path for label generation. Returns the concatenated path of all nested dispatch cases (e.g., "ascending_descending_") to ensure label uniqueness at any nesting depth.- Returns:
- Current dispatch path, or empty if not in any 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
-