Package org.codehaus.groovy.classgen.asm
Class CompileStack
- java.lang.Object
-
- org.codehaus.groovy.classgen.asm.CompileStack
-
- All Implemented Interfaces:
org.objectweb.asm.Opcodes
public class CompileStack extends Object implements org.objectweb.asm.Opcodes
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 Modifier and Type Class Description static class
CompileStack.BlockRecorder
protected static class
CompileStack.LabelRange
-
Field Summary
-
Fields inherited from interface org.objectweb.asm.Opcodes
AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_DEPRECATED, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_MANDATED, ACC_MODULE, ACC_NATIVE, ACC_OPEN, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_RECORD, ACC_STATIC, ACC_STATIC_PHASE, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_TRANSITIVE, ACC_VARARGS, ACC_VOLATILE, ACONST_NULL, ALOAD, ANEWARRAY, ARETURN, ARRAYLENGTH, ASM4, ASM5, ASM6, ASM7, ASM8, ASM9_EXPERIMENTAL, ASTORE, ATHROW, BALOAD, BASTORE, BIPUSH, CALOAD, CASTORE, CHECKCAST, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DMUL, DNEG, DOUBLE, DREM, DRETURN, DSTORE, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F_APPEND, F_CHOP, F_FULL, F_NEW, F_SAME, F_SAME1, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAT, FMUL, FNEG, FREM, FRETURN, FSTORE, FSUB, GETFIELD, GETSTATIC, GOTO, H_GETFIELD, H_GETSTATIC, H_INVOKEINTERFACE, H_INVOKESPECIAL, H_INVOKESTATIC, H_INVOKEVIRTUAL, H_NEWINVOKESPECIAL, H_PUTFIELD, H_PUTSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILOAD, IMUL, INEG, INSTANCEOF, INTEGER, INVOKEDYNAMIC, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISUB, IUSHR, IXOR, JSR, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDIV, LLOAD, LMUL, LNEG, LONG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSUB, LUSHR, LXOR, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, NEW, NEWARRAY, NOP, NULL, POP, POP2, PUTFIELD, PUTSTATIC, RET, RETURN, SALOAD, SASTORE, SIPUSH, SOURCE_DEPRECATED, SOURCE_MASK, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, TOP, UNINITIALIZED_THIS, V_PREVIEW, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8, V10, V11, V12, V13, V14, V15, V9
-
-
Constructor Summary
Constructors Constructor Description CompileStack(WriterController wc)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addExceptionBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label goal, String sig)
void
applyBlockRecorder()
void
applyFinallyBlocks(org.objectweb.asm.Label label, boolean isBreakLabel)
void
clear()
Clears the state of the class.boolean
containsVariable(String name)
org.objectweb.asm.Label
createLocalLabel(String name)
creates a new named labelint
defineTemporaryVariable(String name, boolean store)
creates a temporary variable.int
defineTemporaryVariable(String name, ClassNode node, boolean store)
creates a temporary variable.int
defineTemporaryVariable(Variable var, boolean store)
creates a temporary variable.BytecodeVariable
defineVariable(Variable v, boolean initFromStack)
Defines a new Variable using an AST variable.BytecodeVariable
defineVariable(Variable v, ClassNode variableType, boolean initFromStack)
org.objectweb.asm.Label
getBreakLabel()
org.objectweb.asm.Label
getContinueLabel()
org.objectweb.asm.Label
getLabel(String name)
Returns the label for the given nameorg.objectweb.asm.Label
getNamedBreakLabel(String name)
Used forbreak foo
inside a loop to end the execution of the marked loop.org.objectweb.asm.Label
getNamedContinueLabel(String name)
Used forcontinue foo
inside a loop to continue the execution of the marked loop.VariableScope
getScope()
BytecodeVariable
getVariable(String variableName)
BytecodeVariable
getVariable(String variableName, boolean mustExist)
Returns a normal variable.boolean
hasBlockRecorder()
void
init(VariableScope el, Parameter[] parameters)
initializes this class for a MethodNode.boolean
isImplicitThis()
boolean
isInSpecialConstructorCall()
boolean
isLHS()
void
pop()
void
popBlockRecorderVisit(CompileStack.BlockRecorder finallyBlock)
void
popImplicitThis()
void
popLHS()
void
pushBlockRecorder(CompileStack.BlockRecorder recorder)
void
pushBlockRecorderVisit(CompileStack.BlockRecorder finallyBlock)
void
pushBooleanExpression()
because a boolean Expression may not be evaluated completely it is important to keep the registers cleanvoid
pushImplicitThis(boolean implicitThis)
void
pushInSpecialConstructorCall()
void
pushLHS(boolean lhs)
void
pushLoop(String labelName)
Should be called when descending into a loop that does not define a scope.void
pushLoop(List<String> labelNames)
Should be called when descending into a loop that does not define a scope.void
pushLoop(VariableScope el, String labelName)
Should be called when descending into a loop that defines also a scope.void
pushLoop(VariableScope el, List<String> labelNames)
Should be called when descending into a loop that defines also a scope.void
pushState()
org.objectweb.asm.Label
pushSwitch()
Creates a new break label and a element for the state stack so pop has to be called latervoid
pushVariableScope(VariableScope el)
Causes the state-stack to add an element and sets the given scope as new current variable scope.void
removeVar(int tempIndex)
void
writeExceptionTable(CompileStack.BlockRecorder block, org.objectweb.asm.Label goal, String sig)
-
-
-
Constructor Detail
-
CompileStack
public CompileStack(WriterController wc)
-
-
Method Detail
-
pushState
public void pushState()
-
getContinueLabel
public org.objectweb.asm.Label getContinueLabel()
-
getBreakLabel
public org.objectweb.asm.Label getBreakLabel()
-
removeVar
public void removeVar(int tempIndex)
-
pop
public void pop()
-
getScope
public VariableScope getScope()
-
defineTemporaryVariable
public int defineTemporaryVariable(Variable var, boolean store)
creates a temporary variable.- Parameters:
var
- defines type and namestore
- defines if the toplevel argument of the stack should be stored- Returns:
- the index used for this temporary variable
-
getVariable
public BytecodeVariable getVariable(String variableName)
-
getVariable
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 variablemustExist
- throw exception if variable does not exist- Returns:
- the normal variable or null if not found (and
mustExist
not true)
-
defineTemporaryVariable
public int defineTemporaryVariable(String name, boolean store)
creates a temporary variable.- Parameters:
name
- defines type and namestore
- defines if the top-level argument of the stack should be stored- Returns:
- the index used for this temporary variable
-
defineTemporaryVariable
public int defineTemporaryVariable(String name, ClassNode node, boolean store)
creates a temporary variable.- Parameters:
name
- defines the namenode
- defines the nodestore
- defines if the top-level argument of the stack should be stored- Returns:
- the index used for this temporary variable
-
clear
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
-
addExceptionBlock
public void addExceptionBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label goal, String sig)
-
init
public void init(VariableScope el, 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().
-
pushVariableScope
public void pushVariableScope(VariableScope el)
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
-
pushLoop
public void pushLoop(VariableScope el, 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
-
pushLoop
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 a element for the state stack so pop has to be called later
-
pushLoop
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
-
pushLoop
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
-
getNamedBreakLabel
public org.objectweb.asm.Label getNamedBreakLabel(String name)
Used forbreak 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.
-
getNamedContinueLabel
public org.objectweb.asm.Label getNamedContinueLabel(String name)
Used forcontinue 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.
-
pushSwitch
public org.objectweb.asm.Label pushSwitch()
Creates a new break label and a element for the state stack so pop has to be called later
-
pushBooleanExpression
public void pushBooleanExpression()
because a boolean Expression may not be evaluated completely it is important to keep the registers clean
-
defineVariable
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.
-
defineVariable
public BytecodeVariable defineVariable(Variable v, ClassNode variableType, boolean initFromStack)
-
containsVariable
public boolean containsVariable(String name)
- Parameters:
name
- the name of the variable of interest- Returns:
- true if a variable is already defined
-
getLabel
public org.objectweb.asm.Label getLabel(String name)
Returns the label for the given name
-
createLocalLabel
public org.objectweb.asm.Label createLocalLabel(String name)
creates a new named label
-
applyFinallyBlocks
public void applyFinallyBlocks(org.objectweb.asm.Label label, boolean isBreakLabel)
-
applyBlockRecorder
public void applyBlockRecorder()
-
hasBlockRecorder
public boolean hasBlockRecorder()
-
pushBlockRecorder
public void pushBlockRecorder(CompileStack.BlockRecorder recorder)
-
pushBlockRecorderVisit
public void pushBlockRecorderVisit(CompileStack.BlockRecorder finallyBlock)
-
popBlockRecorderVisit
public void popBlockRecorderVisit(CompileStack.BlockRecorder finallyBlock)
-
writeExceptionTable
public void writeExceptionTable(CompileStack.BlockRecorder block, org.objectweb.asm.Label goal, String sig)
-
isLHS
public boolean isLHS()
-
pushLHS
public void pushLHS(boolean lhs)
-
popLHS
public void popLHS()
-
pushImplicitThis
public void pushImplicitThis(boolean implicitThis)
-
isImplicitThis
public boolean isImplicitThis()
-
popImplicitThis
public void popImplicitThis()
-
isInSpecialConstructorCall
public boolean isInSpecialConstructorCall()
-
pushInSpecialConstructorCall
public void pushInSpecialConstructorCall()
-
-