Class BytecodeGenerationContext

java.lang.Object
org.ek9lang.compiler.backend.jvm.BytecodeGenerationContext

public class BytecodeGenerationContext extends Object
Context for bytecode-generation control flow.

Tracks the FOR_RANGE_POLYMORPHIC dispatch-case path on a stack so that label names are unique at any nesting depth: the for-range body IR is emitted THREE times (equal / ascending / descending), and for-ranges nest arbitrarily, so getDispatchCasePath() prefixes every control-flow label with the full case path (e.g. "ascending_descending_"). Combined with the per-construct scope id in createControlFlowLabel, this is the sole mechanism control-flow generators need for correct, infinitely-nestable label uniqueness.

A previous parallel "loop frame" stack (enterLoop/getLoopContinueLabel) existed only to let an if reuse the enclosing loop's continue label as its own end — an unsound shortcut (it assumed the if was the last statement in the loop body, dropping any statement after it; F11). It has been removed: an if/else chain always uses its own local if_end label via the path mechanism above.

  • Constructor Details

    • BytecodeGenerationContext

      public BytecodeGenerationContext()
  • Method Details

    • enterDispatchCase

      public void enterDispatchCase(BytecodeGenerationContext.DispatchCase dispatchCase)
      Enter a FOR_RANGE dispatch case BEFORE processing the 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 a FOR_RANGE dispatch case AFTER processing the body. Must be called in a finally block to ensure cleanup.
    • getDispatchCasePath

      public Optional<String> getDispatchCasePath()
      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
    • dispatchQualified

      public String dispatchQualified(String labelName)
      Qualify a raw IR label name with the current dispatch-case path so that a named LABEL / BRANCH pair emitted from the IR (e.g. a require / for-range set-check skip label) is unique across the three duplicated for-range body copies. A no-op outside any FOR_RANGE dispatch (empty path), so labels emitted in ordinary code are unchanged. The label definition and every branch that targets it must both pass through here so they resolve to the same JVM label.
      Parameters:
      labelName - the raw IR label name
      Returns:
      the dispatch-qualified label name (path-prefixed inside a dispatch case, else unchanged)