Package: org.codehaus.groovy.classgen.asm

## [Java] Class CompileStack

- org.codehaus.groovy.classgen.asm.CompileStack

-     public class CompileStack
      extends Object

  Manages different aspects of the code of a code block like handling labels, defining variables, and scopes. After a MethodNode is visited clear should be called, for initialization the method init should be used.

  Some Notes:

  - every push method will require a later pop call
  - method parameters may define a category 2 variable, so don't ignore the type stored in the variable object
  - the index of the variable may not be as assumed when the variable is a parameter of a method because the parameter may be used in a closure, so don't ignore the stored variable index
  - the names of temporary variables can be ignored. The names are only used for debugging and do not conflict with each other or normal variables. For accessing, the index of the variable must be used.
  - never mix temporary and normal variables by changes to this class. While the name is very important for a normal variable, it is only a helper construct for temporary variables. That means for example a name for a temporary variable can be used multiple times without conflict. So mixing them both may lead to the problem that a normal or temporary variable is hidden or even removed. That must not happen!
  See Also:
    AsmClassGenerator

- - ### Nested Class Summary

    Nested classes
    Modifiers | Name | Description
    --- | --- | ---
    `static class` | `CompileStack.BlockRecorder` |
    `protected static class` | `CompileStack.LabelRange` |

  - ### Constructor Summary

    Constructors
    Constructor and description
    `CompileStack(WriterController controller)`

  - ### Methods Summary

    Methods
    Type Params | Return Type | Name and description
    --- | --- | ---
    `` | `public void` | `addExceptionBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label goal, String sig)`
    `` | `public void` | `applyBlockRecorder()`
    `` | `public void` | `applyFinallyBlocks(org.objectweb.asm.Label label, boolean isBreakLabel)`
    `` | `public void` | `clear()` Clears the state of the class.
    `` | `public boolean` | `containsVariable(String name)` Parameters: `name` - the name of the variable of interest
    `` | `public org.objectweb.asm.Label` | `createLocalLabel(String name)` creates a new named label
    `` | `public int` | `defineTemporaryVariable(Variable var, boolean store)` Creates a temporary variable.
    `` | `public int` | `defineTemporaryVariable(String name, boolean store)` creates a temporary variable.
    `` | `public int` | `defineTemporaryVariable(String name, ClassNode node, boolean store)` creates a temporary variable.
    `` | `public BytecodeVariable` | `defineVariable(Variable v, boolean initFromStack)` Defines a new Variable using an AST variable.
    `` | `public BytecodeVariable` | `defineVariable(Variable v, ClassNode variableType, boolean initFromStack)`
    `` | `public org.objectweb.asm.Label` | `getBreakLabel()`
    `` | `public org.objectweb.asm.Label` | `getContinueLabel()`
    `` | `public org.objectweb.asm.Label` | `getLabel(String name)` Returns the label for the given name
    `` | `public org.objectweb.asm.Label` | `getNamedBreakLabel(String name)` Used for `break foo` inside a loop to end the execution of the marked loop.
    `` | `public org.objectweb.asm.Label` | `getNamedContinueLabel(String name)` Used for `continue foo` inside a loop to continue the execution of the marked loop.
    `` | `public VariableScope` | `getScope()`
    `` | `public BytecodeVariable` | `getVariable(String variableName)`
    `` | `public BytecodeVariable` | `getVariable(String variableName, boolean mustExist)` Returns a normal variable.
    `` | `public boolean` | `hasBlockRecorder()`
    `` | `public void` | `init(VariableScope scope, Parameter[] parameters)` initializes this class for a MethodNode.
    `` | `public boolean` | `isImplicitThis()`
    `` | `public boolean` | `isInSpecialConstructorCall()`
    `` | `public boolean` | `isLHS()`
    `` | `public void` | `pop()`
    `` | `public void` | `popBlockRecorderVisit(CompileStack.BlockRecorder finallyBlock)`
    `` | `public void` | `popImplicitThis()`
    `` | `public void` | `popLHS()`
    `` | `public void` | `pushBlockRecorder(CompileStack.BlockRecorder recorder)`
    `` | `public void` | `pushBlockRecorderVisit(CompileStack.BlockRecorder finallyBlock)`
    `` | `public void` | `pushBooleanExpression()` Because a boolean Expression may not be evaluated completely it is important to keep the registers clean.
    `` | `public void` | `pushImplicitThis(boolean implicitThis)`
    `` | `public void` | `pushInSpecialConstructorCall()`
    `` | `public void` | `pushLHS(boolean lhs)`
    `` | `public void` | `pushLoop(VariableScope scope, String labelName)` Should be called when descending into a loop that defines also a scope.
    `` | `public void` | `pushLoop(VariableScope el, List<String> labelNames)` Should be called when descending into a loop that defines also a scope.
    `` | `public void` | `pushLoop(String labelName)` Should be called when descending into a loop that does not define a scope.
    `` | `public void` | `pushLoop(List<String> labelNames)` Should be called when descending into a loop that does not define a scope.
    `` | `public void` | `pushState()`
    `` | `public org.objectweb.asm.Label` | `pushSwitch()` Creates a new break label and an element for the state stack so pop has to be called later
    `` | `public void` | `pushVariableScope(VariableScope scope)` Causes the state-stack to add an element and sets the given scope as new current variable scope.
    `` | `public void` | `removeVar(int variableIndex)` Indicates that the specified temporary variable is no longer used.
    `` | `public void` | `visitExcludedFinally(CompileStack.BlockRecorder recorder, Runnable visit)` Inlines an excluded finally block via `visit` while hiding the variables of the current (try) scope, then fully restores that scope — including its variables.
    `` | `public void` | `writeExceptionTable(CompileStack.BlockRecorder block, org.objectweb.asm.Label goal, String sig)` Writes the exception-table entries for all label ranges recorded in `block`.

  - ### Inherited Methods Summary

    Inherited Methods
    Methods inherited from class | Name
    --- | ---
    `class Object` | `equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### public CompileStack(WriterController controller)

  - ### Method Detail

    - #### public void addExceptionBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label goal, String sig)

    - #### public void applyBlockRecorder()

    - #### public void applyFinallyBlocks(org.objectweb.asm.Label label, boolean isBreakLabel)

    - #### public void clear()

      Clears the state of the class. This method should be called after a MethodNode is visited. Note that a call to init will fail if clear is not called before

    - #### public boolean containsVariable(String name)

      Parameters:
        `name` - the name of the variable of interest
      Returns:
        true if a variable is already defined

    - #### public org.objectweb.asm.Label createLocalLabel(String name)

      creates a new named label

    - #### public int defineTemporaryVariable(Variable var, boolean store)

      Creates a temporary variable.

      Parameters:
        `var` - specifies name and type
        `store` - defines if the toplevel argument of the stack should be stored
      Returns:
        the index used for this temporary variable

    - #### public int defineTemporaryVariable(String name, boolean store)

      creates a temporary variable.

      Parameters:
        `name` - defines type and name
        `store` - defines if the top-level argument of the stack should be stored
      Returns:
        the index used for this temporary variable

    - #### public int defineTemporaryVariable(String name, ClassNode node, boolean store)

      creates a temporary variable.

      Parameters:
        `name` - defines the name
        `node` - defines the node
        `store` - defines if the top-level argument of the stack should be stored
      Returns:
        the index used for this temporary variable

    - #### public BytecodeVariable defineVariable(Variable v, boolean initFromStack)

      Defines a new Variable using an AST variable.

      Parameters:
        `initFromStack` - if true the last element of the stack will be used to initialize the new variable. If false null will be used.

    - #### public BytecodeVariable defineVariable(Variable v, ClassNode variableType, boolean initFromStack)

    - #### public org.objectweb.asm.Label getBreakLabel()

    - #### public org.objectweb.asm.Label getContinueLabel()

    - #### public org.objectweb.asm.Label getLabel(String name)

      Returns the label for the given name

    - #### public org.objectweb.asm.Label getNamedBreakLabel(String name)

      Used for `break foo` inside a loop to end the execution of the marked loop. This method will return the break label of the loop if there is one found for the name. If not, the current break label is returned.

    - #### public org.objectweb.asm.Label getNamedContinueLabel(String name)

      Used for `continue foo` inside a loop to continue the execution of the marked loop. This method will return the break label of the loop if there is one found for the name. If not, getLabel is used.

    - #### public VariableScope getScope()

    - #### public BytecodeVariable getVariable(String variableName)

    - #### public BytecodeVariable getVariable(String variableName, boolean mustExist)

      Returns a normal variable.

      If `mustExist` is true and the normal variable doesn't exist, then this method will throw a GroovyBugError. It is not the intention of this method to let this happen! And the exception should not be used for flow control - it is just acting as an assertion. If the exception is thrown then it indicates a bug in the class using CompileStack. This method can also not be used to return a temporary variable. Temporary variables are not normal variables.

      Parameters:
        `variableName` - name of the variable
        `mustExist` - throw exception if variable does not exist
      Returns:
        the normal variable or null if not found (and `mustExist` not true)

    - #### public boolean hasBlockRecorder()

    - #### public void init(VariableScope scope, Parameter[] parameters)

      initializes this class for a MethodNode. This method will automatically define variables for the method parameters and will create references if needed. The created variables can be accessed by calling getVariable().

    - #### public boolean isImplicitThis()

    - #### public boolean isInSpecialConstructorCall()

    - #### public boolean isLHS()

    - #### public void pop()

    - #### public void popBlockRecorderVisit(CompileStack.BlockRecorder finallyBlock)

    - #### public void popImplicitThis()

    - #### public void popLHS()

    - #### public void pushBlockRecorder(CompileStack.BlockRecorder recorder)

    - #### public void pushBlockRecorderVisit(CompileStack.BlockRecorder finallyBlock)

    - #### @Deprecated(since = "5.0.0")
      public void pushBooleanExpression()

      Because a boolean Expression may not be evaluated completely it is important to keep the registers clean.

      deprecated:
        Use pushState() directly.

    - #### public void pushImplicitThis(boolean implicitThis)

    - #### public void pushInSpecialConstructorCall()

    - #### public void pushLHS(boolean lhs)

    - #### public void pushLoop(VariableScope scope, String labelName)

      Should be called when descending into a loop that defines also a scope. Calls pushVariableScope and prepares labels for a loop structure. Creates a element for the state stack so pop has to be called later, TODO:

      Deprecate:

    - #### public void pushLoop(VariableScope el, List<String> labelNames)

      Should be called when descending into a loop that defines also a scope. Calls pushVariableScope and prepares labels for a loop structure. Creates an element for the state stack so pop has to be called later

    - #### public void pushLoop(String labelName)

      Should be called when descending into a loop that does not define a scope. Creates a element for the state stack so pop has to be called later, TODO:

      Deprecate:

    - #### public void pushLoop(List<String> labelNames)

      Should be called when descending into a loop that does not define a scope. Creates an element for the state stack so pop has to be called later

    - #### public void pushState()

    - #### public org.objectweb.asm.Label pushSwitch()

      Creates a new break label and an element for the state stack so pop has to be called later

    - #### public void pushVariableScope(VariableScope scope)

      Causes the state-stack to add an element and sets the given scope as new current variable scope. Creates an element for the state stack so pop has to be called later

    - #### public void removeVar(int variableIndex)

      Indicates that the specified temporary variable is no longer used.

    - #### public void visitExcludedFinally(CompileStack.BlockRecorder recorder, Runnable visit)

      Inlines an excluded finally block via `visit` while hiding the variables of the current (try) scope, then fully restores that scope — including its variables.

      Popping the current scope keeps try-block locals out of scope in the finally body (GROOVY-4721); restoring the saved variables afterwards ensures any subsequent re-emission of the same statement (e.g. the OptimizingStatementWriter fast/slow fork) still resolves those locals rather than falling back to property access (GROOVY-12062).

      Parameters:
        `recorder` - the block recorder being visited
        `visit` - emits the finally body

    - #### public void writeExceptionTable(CompileStack.BlockRecorder block, org.objectweb.asm.Label goal, String sig)

      Writes the exception-table entries for all label ranges recorded in `block`.

      Parameters:
        `block` - the block recorder containing the try-range labels
        `goal` - the handler label
        `sig` - the internal name of the caught type, or `null` for catch-all