Class CompileStack

java.lang.Object
org.codehaus.groovy.classgen.asm.CompileStack
All Implemented Interfaces:
org.objectweb.asm.Opcodes

public class CompileStack
extends java.lang.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, ASM10_EXPERIMENTAL, ASM4, ASM5, ASM6, ASM7, ASM8, ASM9, 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, V16, V17, V18, V19, V20, V21, V22, V23, V9
  • Constructor Summary

    Constructors
    Constructor Description
    CompileStack​(WriterController controller)  
  • Method Summary

    Modifier and Type Method Description
    void addExceptionBlock​(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label goal, java.lang.String sig)  
    void applyBlockRecorder()  
    void applyFinallyBlocks​(org.objectweb.asm.Label label, boolean isBreakLabel)  
    void clear()
    Clears the state of the class.
    boolean containsVariable​(java.lang.String name)  
    org.objectweb.asm.Label createLocalLabel​(java.lang.String name)
    creates a new named label
    int defineTemporaryVariable​(java.lang.String name, boolean store)
    creates a temporary variable.
    int defineTemporaryVariable​(java.lang.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​(java.lang.String name)
    Returns the label for the given name
    org.objectweb.asm.Label getNamedBreakLabel​(java.lang.String name)
    Used for break foo inside a loop to end the execution of the marked loop.
    org.objectweb.asm.Label getNamedContinueLabel​(java.lang.String name)
    Used for continue foo inside a loop to continue the execution of the marked loop.
    VariableScope getScope()  
    BytecodeVariable getVariable​(java.lang.String variableName)  
    BytecodeVariable getVariable​(java.lang.String variableName, boolean mustExist)
    Returns a normal variable.
    boolean hasBlockRecorder()  
    void init​(VariableScope scope, 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 clean
    void pushImplicitThis​(boolean implicitThis)  
    void pushInSpecialConstructorCall()  
    void pushLHS​(boolean lhs)  
    void pushLoop​(java.lang.String labelName)
    Should be called when descending into a loop that does not define a scope.
    void pushLoop​(java.util.List<java.lang.String> labelNames)
    Should be called when descending into a loop that does not define a scope.
    void pushLoop​(VariableScope scope, java.lang.String labelName)
    Should be called when descending into a loop that defines also a scope.
    void pushLoop​(VariableScope el, java.util.List<java.lang.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 later
    void pushVariableScope​(VariableScope scope)
    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, java.lang.String sig)  

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

  • Method Details

    • getBreakLabel

      public org.objectweb.asm.Label getBreakLabel()
    • getContinueLabel

      public org.objectweb.asm.Label getContinueLabel()
    • getScope

      public VariableScope getScope()
    • pushState

      public void pushState()
    • removeVar

      public void removeVar​(int tempIndex)
    • pop

      public void pop()
    • defineTemporaryVariable

      public int defineTemporaryVariable​(Variable var, boolean store)
      creates a temporary variable.
      Parameters:
      var - defines type and name
      store - defines if the toplevel argument of the stack should be stored
      Returns:
      the index used for this temporary variable
    • getVariable

      public BytecodeVariable getVariable​(java.lang.String variableName)
    • getVariable

      public BytecodeVariable getVariable​(java.lang.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)
    • defineTemporaryVariable

      public int defineTemporaryVariable​(java.lang.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
    • defineTemporaryVariable

      public int defineTemporaryVariable​(java.lang.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
    • 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, java.lang.String sig)
    • init

      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().
    • pushVariableScope

      public void pushVariableScope​(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
    • pushLoop

      public void pushLoop​(VariableScope scope, java.lang.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, java.util.List<java.lang.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​(java.lang.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​(java.util.List<java.lang.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​(java.lang.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.
    • getNamedContinueLabel

      public org.objectweb.asm.Label getNamedContinueLabel​(java.lang.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.
    • 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​(java.lang.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​(java.lang.String name)
      Returns the label for the given name
    • createLocalLabel

      public org.objectweb.asm.Label createLocalLabel​(java.lang.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, java.lang.String sig)
    • isLHS

      public boolean isLHS()
    • pushLHS

      public void pushLHS​(boolean lhs)
    • popLHS

      public void popLHS()
    • isImplicitThis

      public boolean isImplicitThis()
    • pushImplicitThis

      public void pushImplicitThis​(boolean implicitThis)
    • popImplicitThis

      public void popImplicitThis()
    • isInSpecialConstructorCall

      public boolean isInSpecialConstructorCall()
    • pushInSpecialConstructorCall

      public void pushInSpecialConstructorCall()