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:
| Modifiers | Name | Description |
|---|---|---|
static class |
CompileStack.BlockRecorder |
Records a block for finally or other special handling. |
protected static class |
CompileStack.LabelRange |
Represents a label range for exception handling or other scoping. |
| Constructor and description |
|---|
CompileStack(WriterController controller)Creates a CompileStack managed by the given controller. |
| 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)Adds a typed or untyped exception handler to the exception table for the current method. |
|
public void |
applyBlockRecorder()Applies all currently active finally blocks for a normal (non-jump) fall-through. |
|
public void |
applyFinallyBlocks(org.objectweb.asm.Label label, boolean isBreakLabel)Applies any pending finally blocks on the path to label.
|
|
public void |
clear()Clears the state of the class. |
|
public boolean |
containsVariable(String name)
|
|
public org.objectweb.asm.Label |
createLocalLabel(String name)Creates or returns the label for the given name. |
|
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 type, 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)Defines a variable for the given AST variable using an explicitly specified bytecode type (which may differ from the declared type, e.g. when widening for closure-shared variables). |
|
public org.objectweb.asm.Label |
getBreakLabel()Returns the current break label, or null if not inside a breakable construct. |
|
public org.objectweb.asm.Label |
getContinueLabel()Returns the current continue label, or null if not inside a loop. |
|
public org.objectweb.asm.Label |
getLabel(String name)Returns the label for the given name. |
|
public org.objectweb.asm.Label |
getNamedBreakLabel(String name)
|
|
public org.objectweb.asm.Label |
getNamedContinueLabel(String name)
|
|
public VariableScope |
getScope()Returns the current variable scope. |
|
public BytecodeVariable |
getVariable(String variableName)Returns a variable by name, throwing a GroovyBugError if it does not exist. |
|
public BytecodeVariable |
getVariable(String variableName, boolean mustExist)Returns a normal variable. |
|
public boolean |
hasBlockRecorder()Returns true if there are any active finally/synchronized blocks on the stack. |
|
public void |
init(VariableScope scope, Parameter[] parameters)initializes this class for a MethodNode. |
|
public boolean |
isImplicitThis()Returns true if the current this reference is implicit (no explicit qualifier). |
|
public boolean |
isInSpecialConstructorCall()Returns true if the current context is inside a special constructor call
(super(...) or this(...)). |
|
public boolean |
isLHS()Returns true if the current expression is being compiled as a left-hand side. |
|
public void |
pop()Restores the compilation state that was saved by the matching push* call,
and emits end-labels for all local variables declared within the scope that
is being popped. |
|
public void |
popBlockRecorderVisit(CompileStack.BlockRecorder finallyBlock)Removes finallyBlock from the visited-block set after its inline
emission is complete. |
|
public void |
popImplicitThis()Pops the top implicit-this flag, restoring the previous state. |
|
public void |
popLHS()Pops the top left-hand-side flag, restoring the previous LHS state. |
|
public void |
pushBlockRecorder(CompileStack.BlockRecorder recorder)Pushes a new BlockRecorder (finally or synchronized guard) onto the block-recorder stack and saves state so that pop() will remove it. |
|
public void |
pushBlockRecorderVisit(CompileStack.BlockRecorder finallyBlock)Marks finallyBlock as currently being visited so that recursive
finally-block application does not re-enter it. |
|
public void |
pushBooleanExpression()Because a boolean Expression may not be evaluated completely it is important to keep the registers clean. |
|
public org.objectweb.asm.Label |
pushBreakable(List<String> labelNames)Creates a new break label and an element for the state stack so pop has to be called later. |
|
public void |
pushImplicitThis(boolean implicitThis)Pushes a new implicit-this flag onto the stack. |
|
public void |
pushInSpecialConstructorCall()Enters a special constructor call context ( super(...) or this(...)).
|
|
public void |
pushLHS(boolean lhs)Pushes a new left-hand-side flag onto the LHS stack. |
|
public void |
pushLoop(VariableScope scope, List<String> labelNames)Should be called when descending into a loop that defines also a scope. |
|
public void |
pushLoop(VariableScope scope, String labelName)Should be called when descending into a loop that defines also a scope. |
|
public void |
pushLoop(List<String> labelNames)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. |
|
public void |
pushLoop(String labelName)Should be called when descending into a loop that does not define a scope. |
|
public void |
pushState()Saves the current compilation state onto an internal stack so that it can be restored by a later call to pop(). |
|
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 org.objectweb.asm.Label |
pushSwitch(List<String> labelNames)Creates a new break label, registers it as the named break target for each label name, and pushes an element onto the state stack so that a later call to pop() restores the previous state. |
|
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. |
Creates a CompileStack managed by the given controller.
controller - the writer controller for the current compilation Adds a typed or untyped exception handler to the exception table for
the current method. Typed entries (non-null sig) are emitted
before untyped ones to ensure correct handler ordering in the bytecode.
start - the start label of the guarded rangeend - the end label of the guarded rangegoal - the label of the handler blocksig - the internal name of the caught exception type, or null
for a catch-all handlerApplies all currently active finally blocks for a normal (non-jump) fall-through.
Applies any pending finally blocks on the path to label.
Walks the state stack to determine which finally blocks are between the
current position and the target label and inlines their bytecode.
label - the target label (break or continue destination)isBreakLabel - true for a break label, false for continueClears 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
name - the name of the variable of interestCreates or returns the label for the given name.
Creates a temporary variable.
var - specifies name and typestore - defines if the toplevel argument of the stack should be storedCreates a temporary variable.
name - defines type and namestore - defines if the top-level argument of the stack should be storedCreates a temporary variable.
name - the variable nametype - the variable typestore - indicates if the top-level argument of the stack should be storedDefines a new Variable using an AST variable.
initFromStack - if true the last element of the
stack will be used to initialize
the new variable. If false null
will be used.Defines a variable for the given AST variable using an explicitly specified bytecode type (which may differ from the declared type, e.g. when widening for closure-shared variables).
v - the AST variable to definevariableType - the bytecode type to assign to the slotinitFromStack - if true the top of the operand stack is stored
into the new slot; otherwise a default/null value is used Returns the current break label, or null if not inside a breakable construct.
Returns the current continue label, or null if not inside a loop.
Returns the label for the given name.
break label for name
continue label for nameReturns the current variable scope.
Returns a variable by name, throwing a GroovyBugError
if it does not exist. Convenience overload of
getVariable(String, boolean) with mustExist = true.
variableName - the name to look upReturns 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.
variableName - name of the variablemustExist - throw exception if variable does not existmustExist not true) Returns true if there are any active finally/synchronized blocks on the stack.
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().
Returns true if the current this reference is implicit (no explicit qualifier).
Returns true if the current context is inside a special constructor call
(super(...) or this(...)).
Returns true if the current expression is being compiled as a left-hand side.
Restores the compilation state that was saved by the matching push* call,
and emits end-labels for all local variables declared within the scope that
is being popped.
Removes finallyBlock from the visited-block set after its inline
emission is complete.
finallyBlock - the block that finished being visitedPops the top implicit-this flag, restoring the previous state.
Pops the top left-hand-side flag, restoring the previous LHS state.
Pushes a new BlockRecorder (finally or synchronized guard) onto the block-recorder stack and saves state so that pop() will remove it.
recorder - the recorder to push Marks finallyBlock as currently being visited so that recursive
finally-block application does not re-enter it.
finallyBlock - the block being visitedBecause a boolean Expression may not be evaluated completely it is important to keep the registers clean.
Creates a new break label and an element for the state stack so pop has to be called later.
Pushes a new implicit-this flag onto the stack.
implicitThis - true if this is used implicitly in the current context Enters a special constructor call context (super(...) or this(...)).
Pushes state so that pop() will restore the previous context.
Pushes a new left-hand-side flag onto the LHS stack.
lhs - true if the next expression is compiled as an assignment targetShould 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
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.
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.
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.
Saves the current compilation state onto an internal stack so that it can
be restored by a later call to pop(). Every push* method
calls this internally; it is also exposed for callers that need a bare
state snapshot without additional label setup.
Creates a new break label and an element for the state stack so pop has to be called later.
Creates a new break label, registers it as the named break target for each label name, and pushes an element onto the state stack so that a later call to pop() restores the previous state.
labelNames - the statement labels on the switch (may be null)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
Indicates that the specified temporary variable is no longer used.
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).
recorder - the block recorder being visitedvisit - emits the finally body Writes the exception-table entries for all label ranges recorded in block.
block - the block recorder containing the try-range labelsgoal - the handler labelsig - the internal name of the caught type, or null for catch-allCopyright © 2003-2026 The Apache Software Foundation. All rights reserved.