Top Description Inners Fields Constructors Methods
org.codehaus.groovy.classgen.asm

public Class CompileStack

extends Object
implements Opcodes
Class Inheritance
All Implemented Interfaces
org.objectweb.asm.Opcodes
Imports
org.codehaus.groovy.GroovyBugError, org.codehaus.groovy.ast.ClassHelper, .ClassNode, .MethodNode, .Parameter, .Variable, .VariableScope, org.codehaus.groovy.classgen.AsmClassGenerator, org.objectweb.asm.Label, .MethodVisitor, .Opcodes, java.util.Collection, .Deque, .HashMap, .Iterator, .LinkedList, .List, .Map

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:

See Also
org.codehaus.groovy.classgen.AsmClassGenerator

Nested and Inner Type Summary

Modifier and TypeClass and Description
public static class
private static class
protected static class
private class

Field Summary

Modifier and TypeField and Description
private Label
breakLabel

current label for break

private String
private boolean
clear

state flag

private Label
continueLabel

current label for continue

private final WriterController
private Map<String, Label>
currentBlockNamedLabels

map containing named labels of current block

private int
currentVariableIndex

index of the last variable on stack

private LinkedList<CompileStack.BlockRecorder>
finallyBlocks

list containing finally blocks

such a block is created by synchronized or finally and must be called for break/continue/return

private boolean
implicitThis

stores if implicit or explicit this is used.

private final Deque<Boolean>
implicitThisStack

handle different states for the implicit "this"

private boolean
private boolean
lhs

stores if on left-hand-side during compilation

private final Deque<Boolean>
lhsStack

handle different states for being on the left hand side

private int
localVariableOffset

first variable index usable after all parameters of a method

private final Map<String, Label>
namedLoopBreakLabel

goals for a "break foo" call in a loop where foo is a label.

private final Map<String, Label>
namedLoopContinueLabel

goals for a "continue foo" call in a loop where foo is a label.

private int
nextVariableIndex

index for the next variable on stack

private VariableScope
scope

current scope

private Map<String, BytecodeVariable>
stackVariables

available variables on stack

private final Deque<CompileStack.StateStackElement>
stateStack

helper to handle different stack based variables

private Map<String, Label>
superBlockNamedLabels

map containing named labels of parenting blocks

private final Deque<BytecodeVariable>
temporaryVariables

currently temporary variables in use

private Label
private Label
private final Deque<CompileStack.ExceptionTableEntry>
private final Deque<CompileStack.ExceptionTableEntry>
private final Deque<BytecodeVariable>
usedVariables

overall used variables for a method/constructor

private final List<CompileStack.BlockRecorder>

Constructor Summary

AccessConstructor and Description
public
CompileStack(final WriterController controller)

Method Summary

Modifier and TypeMethod and Description
public void
addExceptionBlock(final Label start, final Label end, final Label goal, final String sig)

private void
public void
public void
applyFinallyBlocks(final Label label, final boolean isBreakLabel)

public void
clear()

Clears the state of the class.

public boolean

Returns:

true if a variable is already defined
containsVariable
(final String
the name of the variable of interest
name
)

public Label
createLocalLabel(final String name)

creates a new named label

private void
private void
defineMethodVariables(final Parameter[] params, final boolean isInStaticContext)

public int

Returns:

the index used for this temporary variable
defineTemporaryVariable
(final Variable
defines type and name
var
,
final boolean
defines if the toplevel argument of the stack should be stored
store
)

creates a temporary variable.

public int

Returns:

the index used for this temporary variable
defineTemporaryVariable
(final String
defines type and name
name
,
final boolean
defines if the top-level argument of the stack should be stored
store
)

creates a temporary variable.

public int

Returns:

the index used for this temporary variable
defineTemporaryVariable
(final String
defines the name
name
,
final ClassNode
defines the node
node
,
final boolean
defines if the top-level argument of the stack should be stored
store
)

creates a temporary variable.

private BytecodeVariable
defineVar(final String name, final ClassNode type, final boolean holder, final boolean useReferenceDirectly)

public BytecodeVariable
defineVariable(final Variable v, final boolean
if true the last element of the stack will be used to initialize the new variable. If false null will be used.
initFromStack
)

Defines a new Variable using an AST variable.

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

public Label
public Label
public Label
getLabel(final String name)

Returns the label for the given name

public Label
getNamedBreakLabel(final String name)

Used for break foo inside a loop to end the execution of the marked loop.

public Label
getNamedContinueLabel(final String name)

Used for continue foo inside a loop to continue the execution of the marked loop.

public VariableScope
public BytecodeVariable
getVariable(final String variableName)

public BytecodeVariable

Returns:

the normal variable or null if not found (and mustExist not true)
getVariable
(final String
name of the variable
variableName
,
final boolean
throw exception if variable does not exist
mustExist
)

Returns a normal variable.

public boolean
public void
init(final VariableScope scope, final Parameter[] parameters)

initializes this class for a MethodNode.

private void
initLoopLabels(final String labelName)

public boolean
public boolean
public boolean
private void
makeLocalVariablesOffset(final Parameter[] paras, final boolean isInStaticContext)

private void
makeNextVariableID(final ClassNode type, final boolean useReferenceDirectly)

Calculates the index of the next free register stores it and sets the current variable index to the old value

public void
pop()

public void
public void
public void
private void
public void
public void
public void
pushBooleanExpression()

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

public void
pushImplicitThis(final boolean implicitThis)

private static void
pushInitValue(final ClassNode type, final MethodVisitor mv)

public void
public void
pushLHS(final boolean lhs)

public void
pushLoop(final VariableScope scope, final String labelName)

Should be called when descending into a loop that defines also a scope.

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

Should be called when descending into a loop that defines also a scope.

public void
pushLoop(final String labelName)

Should be called when descending into a loop that does not define a scope.

public void
pushLoop(final List<String> labelNames)

Should be called when descending into a loop that does not define a scope.

public void
public Label
pushSwitch()

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

public void
pushVariableScope(final VariableScope scope)

Causes the state-stack to add an element and sets the given scope as new current variable scope.

public void
removeVar(final int tempIndex)

private void
resetVariableIndex(final boolean isStatic)

private void
public void
writeExceptionTable(final CompileStack.BlockRecorder block, final Label goal, final String sig)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

breakLabelback to summary
private Label breakLabel

current label for break

classNameback to summary
private String className
clearback to summary
private boolean clear

state flag

continueLabelback to summary
private Label continueLabel

current label for continue

controllerback to summary
private final WriterController controller
currentBlockNamedLabelsback to summary
private Map<String, Label> currentBlockNamedLabels

map containing named labels of current block

currentVariableIndexback to summary
private int currentVariableIndex

index of the last variable on stack

finallyBlocksback to summary
private LinkedList<CompileStack.BlockRecorder> finallyBlocks

list containing finally blocks

such a block is created by synchronized or finally and must be called for break/continue/return

implicitThisback to summary
private boolean implicitThis

stores if implicit or explicit this is used.

implicitThisStackback to summary
private final Deque<Boolean> implicitThisStack

handle different states for the implicit "this"

inSpecialConstructorCallback to summary
private boolean inSpecialConstructorCall
lhsback to summary
private boolean lhs

stores if on left-hand-side during compilation

lhsStackback to summary
private final Deque<Boolean> lhsStack

handle different states for being on the left hand side

localVariableOffsetback to summary
private int localVariableOffset

first variable index usable after all parameters of a method

namedLoopBreakLabelback to summary
private final Map<String, Label> namedLoopBreakLabel

goals for a "break foo" call in a loop where foo is a label.

namedLoopContinueLabelback to summary
private final Map<String, Label> namedLoopContinueLabel

goals for a "continue foo" call in a loop where foo is a label.

nextVariableIndexback to summary
private int nextVariableIndex

index for the next variable on stack

scopeback to summary
private VariableScope scope

current scope

stackVariablesback to summary
private Map<String, BytecodeVariable> stackVariables

available variables on stack

stateStackback to summary
private final Deque<CompileStack.StateStackElement> stateStack

helper to handle different stack based variables

superBlockNamedLabelsback to summary
private Map<String, Label> superBlockNamedLabels

map containing named labels of parenting blocks

temporaryVariablesback to summary
private final Deque<BytecodeVariable> temporaryVariables

currently temporary variables in use

thisEndLabelback to summary
private Label thisEndLabel
thisStartLabelback to summary
private Label thisStartLabel
typedExceptionsback to summary
private final Deque<CompileStack.ExceptionTableEntry> typedExceptions
untypedExceptionsback to summary
private final Deque<CompileStack.ExceptionTableEntry> untypedExceptions
usedVariablesback to summary
private final Deque<BytecodeVariable> usedVariables

overall used variables for a method/constructor

visitedBlocksback to summary
private final List<CompileStack.BlockRecorder> visitedBlocks

Constructor Detail

CompileStackback to summary
public CompileStack(final WriterController controller)

Method Detail

addExceptionBlockback to summary
public void addExceptionBlock(final Label start, final Label end, final Label goal, final String sig)
applyBlockRecorderback to summary
private void applyBlockRecorder(final Collection<CompileStack.BlockRecorder> blockRecorders)
applyBlockRecorderback to summary
public void applyBlockRecorder()
applyFinallyBlocksback to summary
public void applyFinallyBlocks(final Label label, final boolean isBreakLabel)
clearback to summary
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

containsVariableback to summary
public boolean containsVariable(final String name)
Parameters
name:String

the name of the variable of interest

Returns:boolean

true if a variable is already defined

createLocalLabelback to summary
public Label createLocalLabel(final String name)

creates a new named label

createReferenceback to summary
private void createReference(final BytecodeVariable reference)
defineMethodVariablesback to summary
private void defineMethodVariables(final Parameter[] params, final boolean isInStaticContext)
defineTemporaryVariableback to summary
public int defineTemporaryVariable(final Variable var, final boolean store)

creates a temporary variable.

Parameters
var:Variable

defines type and name

store:boolean

defines if the toplevel argument of the stack should be stored

Returns:int

the index used for this temporary variable

defineTemporaryVariableback to summary
public int defineTemporaryVariable(final String name, final boolean store)

creates a temporary variable.

Parameters
name:String

defines type and name

store:boolean

defines if the top-level argument of the stack should be stored

Returns:int

the index used for this temporary variable

defineTemporaryVariableback to summary
public int defineTemporaryVariable(final String name, final ClassNode node, final boolean store)

creates a temporary variable.

Parameters
name:String

defines the name

node:ClassNode

defines the node

store:boolean

defines if the top-level argument of the stack should be stored

Returns:int

the index used for this temporary variable

defineVarback to summary
private BytecodeVariable defineVar(final String name, final ClassNode type, final boolean holder, final boolean useReferenceDirectly)
defineVariableback to summary
public BytecodeVariable defineVariable(final Variable v, final boolean initFromStack)

Defines a new Variable using an AST variable.

Parameters
initFromStack:boolean

if true the last element of the stack will be used to initialize the new variable. If false null will be used.

defineVariableback to summary
public BytecodeVariable defineVariable(final Variable v, final ClassNode variableType, final boolean initFromStack)
getBreakLabelback to summary
public Label getBreakLabel()
getContinueLabelback to summary
public Label getContinueLabel()
getLabelback to summary
public Label getLabel(final String name)

Returns the label for the given name

getNamedBreakLabelback to summary
public Label getNamedBreakLabel(final 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.

getNamedContinueLabelback to summary
public Label getNamedContinueLabel(final 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.

getScopeback to summary
public VariableScope getScope()
getVariableback to summary
public BytecodeVariable getVariable(final String variableName)
getVariableback to summary
public BytecodeVariable getVariable(final String variableName, final 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:String

name of the variable

mustExist:boolean

throw exception if variable does not exist

Returns:BytecodeVariable

the normal variable or null if not found (and mustExist not true)

hasBlockRecorderback to summary
public boolean hasBlockRecorder()
initback to summary
public void init(final VariableScope scope, final 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().

initLoopLabelsback to summary
private void initLoopLabels(final String labelName)
isImplicitThisback to summary
public boolean isImplicitThis()
isInSpecialConstructorCallback to summary
public boolean isInSpecialConstructorCall()
isLHSback to summary
public boolean isLHS()
makeLocalVariablesOffsetback to summary
private void makeLocalVariablesOffset(final Parameter[] paras, final boolean isInStaticContext)
makeNextVariableIDback to summary
private void makeNextVariableID(final ClassNode type, final boolean useReferenceDirectly)

Calculates the index of the next free register stores it and sets the current variable index to the old value

popback to summary
public void pop()
popBlockRecorderVisitback to summary
public void popBlockRecorderVisit(final CompileStack.BlockRecorder finallyBlock)
popImplicitThisback to summary
public void popImplicitThis()
popLHSback to summary
public void popLHS()
popStateback to summary
private void popState()
pushBlockRecorderback to summary
public void pushBlockRecorder(final CompileStack.BlockRecorder recorder)
pushBlockRecorderVisitback to summary
public void pushBlockRecorderVisit(final CompileStack.BlockRecorder finallyBlock)
pushBooleanExpressionback to summary
public void pushBooleanExpression()

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

pushImplicitThisback to summary
public void pushImplicitThis(final boolean implicitThis)
pushInitValueback to summary
private static void pushInitValue(final ClassNode type, final MethodVisitor mv)
pushInSpecialConstructorCallback to summary
public void pushInSpecialConstructorCall()
pushLHSback to summary
public void pushLHS(final boolean lhs)
pushLoopback to summary
public void pushLoop(final VariableScope scope, final 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

pushLoopback to summary
public void pushLoop(final VariableScope el, final 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 a element for the state stack so pop has to be called later

pushLoopback to summary
public void pushLoop(final 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

pushLoopback to summary
public void pushLoop(final 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

pushStateback to summary
public void pushState()
pushSwitchback to summary
public Label pushSwitch()

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

pushVariableScopeback to summary
public void pushVariableScope(final VariableScope scope)

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

removeVarback to summary
public void removeVar(final int tempIndex)
resetVariableIndexback to summary
private void resetVariableIndex(final boolean isStatic)
setEndLabelsback to summary
private void setEndLabels()
writeExceptionTableback to summary
public void writeExceptionTable(final CompileStack.BlockRecorder block, final Label goal, final String sig)
org.codehaus.groovy.classgen.asm back to summary

public Class CompileStack.BlockRecorder

extends Object
Class Inheritance

Field Summary

Modifier and TypeField and Description
public Runnable
private boolean
public final LinkedList<CompileStack.LabelRange>

Constructor Summary

AccessConstructor and Description
public
public
BlockRecorder(final Runnable excludedStatement)

Method Summary

Modifier and TypeMethod and Description
public void
closeRange(final Label end)

public void
startRange(final Label start)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

excludedStatementback to summary
public Runnable excludedStatement
isEmptyback to summary
private boolean isEmpty
rangesback to summary
public final LinkedList<CompileStack.LabelRange> ranges

Constructor Detail

BlockRecorderback to summary
public BlockRecorder()
BlockRecorderback to summary
public BlockRecorder(final Runnable excludedStatement)

Method Detail

closeRangeback to summary
public void closeRange(final Label end)
startRangeback to summary
public void startRange(final Label start)
org.codehaus.groovy.classgen.asm back to summary

private Class CompileStack.ExceptionTableEntry

extends Object
Class Inheritance
  • java.lang.Object
  • org.codehaus.groovy.classgen.asm.CompileStack.ExceptionTableEntry

Field Summary

Modifier and TypeField and Description
pack-priv Label
pack-priv Label
pack-priv String
pack-priv Label

Constructor Summary

AccessConstructor and Description
private

Method Summary

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

endback to summary
pack-priv Label end
goalback to summary
pack-priv Label goal
sigback to summary
pack-priv String sig
startback to summary
pack-priv Label start

Constructor Detail

ExceptionTableEntryback to summary
private ExceptionTableEntry()
org.codehaus.groovy.classgen.asm back to summary

protected Class CompileStack.LabelRange

extends Object
Class Inheritance

Field Summary

Modifier and TypeField and Description
public Label
public Label

Constructor Summary

AccessConstructor and Description
protected

Method Summary

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

endback to summary
public Label end
startback to summary
public Label start

Constructor Detail

LabelRangeback to summary
protected LabelRange()
org.codehaus.groovy.classgen.asm back to summary

private Class CompileStack.StateStackElement

extends Object
Class Inheritance
  • java.lang.Object
  • org.codehaus.groovy.classgen.asm.CompileStack.StateStackElement

Field Summary

Modifier and TypeField and Description
pack-priv final Label
pack-priv final Label
pack-priv final Map<String, Label>
pack-priv final LinkedList<CompileStack.BlockRecorder>
pack-priv final boolean
pack-priv final VariableScope
pack-priv final Map<String, BytecodeVariable>

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

breakLabelback to summary
pack-priv final Label breakLabel
continueLabelback to summary
pack-priv final Label continueLabel
currentBlockNamedLabelsback to summary
pack-priv final Map<String, Label> currentBlockNamedLabels
finallyBlocksback to summary
pack-priv final LinkedList<CompileStack.BlockRecorder> finallyBlocks
inSpecialConstructorCallback to summary
pack-priv final boolean inSpecialConstructorCall
scopeback to summary
pack-priv final VariableScope scope
stackVariablesback to summary
pack-priv final Map<String, BytecodeVariable> stackVariables

Constructor Detail

StateStackElementback to summary
pack-priv StateStackElement()