Package serp.bytecode

Class Code

  • All Implemented Interfaces:
    BCEntity, VisitAcceptor

    public class Code
    extends Attribute
    Representation of a code block of a class. The methods of this class mimic those of the same name in the ListIterator class. Note that the size and index information of the code block will change as opcodes are added.

    Code blocks are usually obtained from a BCMethod, but can also be constructed via the default constructor. Blocks created this way can be used to provide template instructions to the various search/replace methods in this class.

    The code class contains methods named after most JVM instructions, each of which adds the matching opcode to the code block at the current iterator position. It also contains generic versions of various JVM instructions whose opcodes are not set until their properties are set with additional information. Almost all instruction types are able to 'morph' their opcode on the fly as the arguments to the instruction change. Thus the developer can initially call, for example, the aload opcode, but later change the type to load to int and the opcode will automatically morph to the iload opcode.

    Author:
    Abe White
    • Constructor Detail

      • Code

        public Code()
        The public constructor is for creating template code modules that produce Instructions used in matching through the various search and replace methods.
    • Method Detail

      • getMethod

        public BCMethod getMethod()
        The owning method.
      • getMaxStack

        public int getMaxStack()
        Return the maximum stack depth set for this code block.
      • setMaxStack

        public void setMaxStack​(int max)
        Set the maximum stack depth for this code block.
      • getMaxLocals

        public int getMaxLocals()
        Return the maximum number of local variables (including params) set for this method.
      • setMaxLocals

        public void setMaxLocals​(int max)
        Set the maximum number of local variables (including params) in this method.
      • getLocalsIndex

        public int getLocalsIndex​(int paramIndex)
        Return the local variable index for the paramIndex'th parameter to the method. Local variable indexes differ from parameter indexes because: a) non-static methods use the 0th local variable for the 'this' ptr, and b) double and long values occupy two spots in the local variable array. Returns -1 if the given index is not valid.
      • getParamsIndex

        public int getParamsIndex​(int localIndex)
        Return the parameter index for the given local index, or -1 if the given local does not reference a param.
        See Also:
        getLocalsIndex(int)
      • getNextLocalsIndex

        public int getNextLocalsIndex()
        Return the next available local variable index.
      • calculateMaxLocals

        public void calculateMaxLocals()
        Calculate and set the number of locals needed based on the instructions used and the parameters of the method this code block is a part of.
        See Also:
        setMaxLocals(int)
      • calculateMaxStack

        public void calculateMaxStack()
        Calculate and set the maximum stack depth needed for the instructions used.
        See Also:
        setMaxStack(int)
      • getExceptionHandlers

        public ExceptionHandler[] getExceptionHandlers()
        Return the exception handlers active in this code block, or an empty array if none.
      • getExceptionHandler

        public ExceptionHandler getExceptionHandler​(java.lang.String catchType)
        Return the exception handler that catches the given exception type; if multiple handlers catch the given type, which is returned is undefined.
      • getExceptionHandler

        public ExceptionHandler getExceptionHandler​(java.lang.Class catchType)
        Return the exception handler that catches the given exception type; if multiple handlers catch the given type, which is returned is undefined.
      • getExceptionHandler

        public ExceptionHandler getExceptionHandler​(BCClass catchType)
        Return the exception handler that catches the given exception type; if multiple handlers catch the given type, which is returned is undefined.
      • getExceptionHandlers

        public ExceptionHandler[] getExceptionHandlers​(java.lang.String catchType)
        Return all exception handlers that catch the given exception type, or an empty array if none.
      • getExceptionHandlers

        public ExceptionHandler[] getExceptionHandlers​(java.lang.Class catchType)
        Return all exception handlers that catch the given exception type, or an empty array if none.
      • getExceptionHandlers

        public ExceptionHandler[] getExceptionHandlers​(BCClass catchType)
        Return all exception handlers that catch the given exception type, or an empty array if none.
      • setExceptionHandlers

        public void setExceptionHandlers​(ExceptionHandler[] handlers)
        Set the exception handlers for this code block. This method is useful for importing all handlers from another code block. Set to null or empty array if none.
      • addExceptionHandler

        public ExceptionHandler addExceptionHandler()
        Add an exception handler to this code block.
      • addExceptionHandler

        public ExceptionHandler addExceptionHandler​(Instruction tryStart,
                                                    Instruction tryEnd,
                                                    Instruction handlerStart,
                                                    java.lang.String catchType)
        Add an exception handler to this code block.
        Parameters:
        tryStart - the first instruction of the try {} block
        tryEnd - the last instruction of the try {} block
        handlerStart - the first instruction of the catch {} block
        catchType - the type of exception being caught
      • addExceptionHandler

        public ExceptionHandler addExceptionHandler​(Instruction tryStart,
                                                    Instruction tryEnd,
                                                    Instruction handlerStart,
                                                    java.lang.Class catchType)
        Add an exception handler to this code block.
        Parameters:
        tryStart - the first instruction of the try {} block
        tryEnd - the last instruction of the try {} block
        handlerStart - the first instruction of the catch {} block
        catchType - the type of exception being caught
      • addExceptionHandler

        public ExceptionHandler addExceptionHandler​(Instruction tryStart,
                                                    Instruction tryEnd,
                                                    Instruction handlerStart,
                                                    BCClass catchType)
        Add an exception handler to this code block.
        Parameters:
        tryStart - the first instruction of the try {} block
        tryEnd - the last instruction of the try {} block
        handlerStart - the first instruction of the catch {} block
        catchType - the type of exception being caught
      • clearExceptionHandlers

        public void clearExceptionHandlers()
        Clear all exception handlers.
      • removeExceptionHandler

        public boolean removeExceptionHandler​(java.lang.String catchType)
        Remove the exception handler that catches the given type.
      • removeExceptionHandler

        public boolean removeExceptionHandler​(java.lang.Class catchType)
        Remove the exception handler that catches the given type.
        Returns:
        true if the handler was removed, false otherwise
      • removeExceptionHandler

        public boolean removeExceptionHandler​(BCClass catchType)
        Remove the exception handler that catches the given type.
        Returns:
        true if the handler was removed, false otherwise
      • removeExceptionHandler

        public boolean removeExceptionHandler​(ExceptionHandler handler)
        Remove an exception handler from this code block. The given handler must belong to this code block.
      • size

        public int size()
        Return the number of instructions in the method.
      • beforeFirst

        public void beforeFirst()
        Reset the position of the instruction iterator to the first opcode.
      • afterLast

        public void afterLast()
        Set the position of the instruction iterator to after the last opcode.
      • before

        public void before​(Instruction ins)
        Position the iterator just before the given instruction. The instruction must belong to this method.
      • after

        public void after​(Instruction ins)
        Position the iterator just after the given instruction. The instruction must belong to this method.
      • hasNext

        public boolean hasNext()
        Return true if a subsequent call to next() will return an instruction.
      • hasPrevious

        public boolean hasPrevious()
        Return true if a subsequent call to previous() will return an instruction.
      • next

        public Instruction next()
        Return the next instruction.
      • nextIndex

        public int nextIndex()
        Return the index of the next instruction, or size() if at end.
      • previous

        public Instruction previous()
        Return the previous instruction.
      • previousIndex

        public int previousIndex()
        Return the index of the previous instruction, or -1 if at beginning.
      • before

        public void before​(int index)
        Place the iterator before the given list index.
      • after

        public void after​(int index)
        Place the iterator after the given list index.
      • searchForward

        public boolean searchForward​(Instruction template)
        Find the next instruction from the current iterator position that matches the given one, according to the Object.equals(java.lang.Object) methods of the instruction types. This allows for matching based on template instructions, as the equals methods of most instructions return true if the information for the given instruction has not been filled in. If a match is found, the iterator is placed after the matching Instruction. If no match is found, moves the iterator to afterLast().
        Returns:
        true if match found
      • searchBackward

        public boolean searchBackward​(Instruction template)
        Find the closest previous instruction from the current iterator position that matches the given one, according to the Object.equals(java.lang.Object) methods of the instruction types. This allows for matching based on template instructions, as the equals methods of most instructions return true if the information for the given instruction has not been filled in. If a match is found, the iterator is placed before the matching Instruction. If no match is found, moves the iterator to beforeFirst().
        Returns:
        true if match found
      • add

        public Instruction add​(Instruction ins)
        Adds a copy of the given instruction.
        Returns:
        the newly added instruction
      • set

        public Instruction set​(Instruction ins)
        Replaces the last iterated instruction with a copy of the given one. This method will also make sure that all jump points that referenced the old opcode are updated correctly.
        Returns:
        the newly added instruction
        See Also:
        ListIterator.set(E)
      • replace

        public int replace​(Instruction template,
                           Instruction with)
        Replaces all the instructions in this code block that match the given template with the given instruction. After this method, the iterator will be afterLast().
        Returns:
        the number of substitutions made
      • remove

        public void remove()
        Remove the last iterated instruction.
        See Also:
        ListIterator.remove()
      • classconstant

        public ClassConstantInstruction classconstant()
        Load a class constant onto the stack. For primitive types, this translates into a getstatic for the TYPE field of the primitive's wrapper type. For non-primitives, things get much more complex. Suffice it to say that the operation involves adding synthetic static fields and even methods to the class. Note that this instruction requires up to 3 stack positions to execute.
      • constant

        public ConstantInstruction constant()
        Load some constant onto the stack. The ConstantInstruction type takes any constant and correctly translates it into the proper opcode, depending on the constant type and value. For example, if the constant value is set to 0L, the opcode will be set to lconst0.
      • xload

        public LoadInstruction xload()
        Load a local variable onto the stack. This instruction will result in a nop until its type and local index are set.
      • iload

        public LoadInstruction iload()
        Load an int local variable onto the stack. This instruction will result in a nop until its local index is set.
      • lload

        public LoadInstruction lload()
        Load a long local variable onto the stack. This instruction will result in a nop until its local index is set.
      • fload

        public LoadInstruction fload()
        Load a float local variable onto the stack. This instruction will result in a nop until its local index is set.
      • dload

        public LoadInstruction dload()
        Load a double local variable onto the stack. This instruction will result in a nop until its local index is set.
      • aload

        public LoadInstruction aload()
        Load an object local variable onto the stack. This instruction will result in a nop until its local index is set.
      • xstore

        public StoreInstruction xstore()
        Store a value from the stack into a local variable. This instruction will result in a nop until its type and local index are set.
      • istore

        public StoreInstruction istore()
        Store an int value from the stack into a local variable. This instruction will result in a nop until its local index is set.
      • lstore

        public StoreInstruction lstore()
        Store a long value from the stack into a local variable. This instruction will resultin a nop until its local index is set.
      • fstore

        public StoreInstruction fstore()
        Store a float value from the stack into a local variable. This instruction will result in a nop until its local index is set.
      • dstore

        public StoreInstruction dstore()
        Store a double value from the stack into a local variable. This instruction will result in a nop until its local index is set.
      • astore

        public StoreInstruction astore()
        Store an object value from the stack into a local variable. This instruction will result in a nop until its local index is set.
      • ret

        public RetInstruction ret()
        Add the ret opcode, used in implementing finally clauses.
      • xaload

        public ArrayLoadInstruction xaload()
        Load an array value onto the stack. This instruction will result in a nop until its type is set.
      • iaload

        public ArrayLoadInstruction iaload()
        Load an int array value onto the stack; the iaload opcode.
      • laload

        public ArrayLoadInstruction laload()
        Load a long array value onto the stack; the laload opcode.
      • faload

        public ArrayLoadInstruction faload()
        Load a float array value onto the stack; the faload opcode.
      • daload

        public ArrayLoadInstruction daload()
        Load a double array value onto the stack; the daload opcode.
      • aaload

        public ArrayLoadInstruction aaload()
        Load an object array value onto the stack; the aaload opcode.
      • baload

        public ArrayLoadInstruction baload()
        Load a byte array value onto the stack; the baload opcode.
      • caload

        public ArrayLoadInstruction caload()
        Load a char array value onto the stack; the caload opcode.
      • saload

        public ArrayLoadInstruction saload()
        Load a short array value onto the stack; the saload opcode.
      • xastore

        public ArrayStoreInstruction xastore()
        Store a value from the stack into an array. This instruction will result in a nop until its type is set.
      • iastore

        public ArrayStoreInstruction iastore()
        Store an int value from the stack into an array; the iastore opcode.
      • lastore

        public ArrayStoreInstruction lastore()
        Store a long value from the stack into an array; the lastore opcode.
      • fastore

        public ArrayStoreInstruction fastore()
        Store a float value from the stack into an array; the fastore opcode.
      • dastore

        public ArrayStoreInstruction dastore()
        Store a double value from the stack into an array; the dastore opcode.
      • aastore

        public ArrayStoreInstruction aastore()
        Store an object value from the stack into an array; the aastore opcode.
      • bastore

        public ArrayStoreInstruction bastore()
        Store a byte value from the stack into an array; the bastore opcode.
      • castore

        public ArrayStoreInstruction castore()
        Store a char value from the stack into an array; the castore opcode.
      • sastore

        public ArrayStoreInstruction sastore()
        Store a short value from the stack into an array; the sastore opcode.
      • math

        public MathInstruction math()
        Perform some math operation on the stack items. This instruction will result in a nop until its operation and type are set.
      • xadd

        public MathInstruction xadd()
        Add the top two stack values. This instruction will result in a nop until its type is set.
      • iadd

        public MathInstruction iadd()
        Add the top two stack int values; the iadd opcode.
      • ladd

        public MathInstruction ladd()
        Add the top two stack long values; the ladd opcode.
      • fadd

        public MathInstruction fadd()
        Add the top two stack float values; the fadd opcode.
      • dadd

        public MathInstruction dadd()
        Add the top two stack double values; the dadd opcode.
      • xsub

        public MathInstruction xsub()
        Subtract the top two stack values. This instruction will result in a nop until its type is set.
      • isub

        public MathInstruction isub()
        Subtract the top two stack int values; the isub opcode.
      • lsub

        public MathInstruction lsub()
        Subtract the top two stack long values; the lsub opcode.
      • fsub

        public MathInstruction fsub()
        Subtract the top two stack float values; the fsub opcode.
      • dsub

        public MathInstruction dsub()
        Subtract the top two stack double values; the dsub opcode.
      • xmul

        public MathInstruction xmul()
        Multiply the top two stack values. This instruction will result in a nop until its type is set.
      • imul

        public MathInstruction imul()
        Multiply the top two stack int values; the imul opcode.
      • lmul

        public MathInstruction lmul()
        Multiply the top two stack long values; the lmul opcode.
      • fmul

        public MathInstruction fmul()
        Multiply the top two stack float values; the fmul opcode.
      • dmul

        public MathInstruction dmul()
        Multiply the top two stack double values; the dmul opcode.
      • xdiv

        public MathInstruction xdiv()
        Divide the top two stack values. This instruction will result in a nop until its type is set.
      • idiv

        public MathInstruction idiv()
        Divide the top two stack int values; the idiv opcode.
      • ldiv

        public MathInstruction ldiv()
        Divide the top two stack long values; the ldiv opcode.
      • fdiv

        public MathInstruction fdiv()
        Divide the top two stack float values; the fdiv opcode.
      • ddiv

        public MathInstruction ddiv()
        Divide the top two stack double values; the ddiv opcode.
      • xrem

        public MathInstruction xrem()
        Take the remainder of the top two stack values. This instruction will result in a nop until its type is set.
      • irem

        public MathInstruction irem()
        Take the remainder of the top two int stack values; the irem opcode.
      • lrem

        public MathInstruction lrem()
        Take the remainder of the top two long stack values; the lrem opcode.
      • frem

        public MathInstruction frem()
        Take the remainder of the top two float stack values; the frem opcode.
      • drem

        public MathInstruction drem()
        Take the remainder of the top two double stack values; the drem opcode.
      • xneg

        public MathInstruction xneg()
        Negate the top stack value. This instruction will result in a nop until its type is set.
      • ineg

        public MathInstruction ineg()
        Negate the top stack int value; the ineg opcode.
      • lneg

        public MathInstruction lneg()
        Negate the top stack long value; the lneg opcode.
      • fneg

        public MathInstruction fneg()
        Negate the top stack float value; the fneg opcode.
      • dneg

        public MathInstruction dneg()
        Negate the top stack double value; the dneg opcode.
      • xshl

        public MathInstruction xshl()
        Shift the top stack values. This instruction will result in a nop until its type is set.
      • ishl

        public MathInstruction ishl()
        Shift the top stack int values; the ishl opcode.
      • lshl

        public MathInstruction lshl()
        Shift the top stack long values; the lshl opcode.
      • xshr

        public MathInstruction xshr()
        Shift the top stack values. This instruction will result in a nop until its type is set.
      • ishr

        public MathInstruction ishr()
        Shift the top stack int values; the ishr opcode.
      • lshr

        public MathInstruction lshr()
        Shift the top stack long values; the lshr opcode.
      • xushr

        public MathInstruction xushr()
        Shift the top stack values. This instruction will result in a nop until its type is set.
      • iushr

        public MathInstruction iushr()
        Shift the top stack int values; the iushr opcode.
      • lushr

        public MathInstruction lushr()
        Shift the top stack long values; the lushr opcode.
      • xand

        public MathInstruction xand()
        Take the mathematical and of the top two stack values. This instruction results in a nop until its type is set.
      • iand

        public MathInstruction iand()
        Take the mathematical and of the top two stack int values; the iand opcode.
      • land

        public MathInstruction land()
        Take the mathematical and of the top two stack long values; the land opcode.
      • xor

        public MathInstruction xor()
        Take the mathematical or of the top two stack values. This instruction results in a nop until its type is set.
      • ior

        public MathInstruction ior()
        Take the mathematical or of the top two stack int values; the ior opcode.
      • lor

        public MathInstruction lor()
        Take the mathematical or of the top two stack long values; the lor opcode.
      • xxor

        public MathInstruction xxor()
        Take the mathematical xor of the top two stack values. This instruction results in a nop until its type is set.
      • ixor

        public MathInstruction ixor()
        Take the mathematical xor of the top two stack int values; the ixor opcode.
      • lxor

        public MathInstruction lxor()
        Take the mathematical xor of the top two stack long values; the lxor opcode.
      • convert

        public ConvertInstruction convert()
        Convert the top stack value to another type. This instruction will result in a nop until the types to convert between are set.
      • xcmp

        public CmpInstruction xcmp()
        Compare the top two stack values. This instruction will result in a nop until its type is set.
      • lcmp

        public CmpInstruction lcmp()
        Compare the top two stack values; the lcmp opcode.
      • fcmpl

        public CmpInstruction fcmpl()
        Compare the top two stack values; the fcmpl opcode.
      • fcmpg

        public CmpInstruction fcmpg()
        Compare the top two stack values; the fcmpg opcode.
      • dcmpl

        public CmpInstruction dcmpl()
        Compare the top two stack values; the dcmpl opcode.
      • dcmpg

        public CmpInstruction dcmpg()
        Compare the top two stack values; the dcmpg opcode.
      • ificmpeq

        public IfInstruction ificmpeq()
        The ificmpeq opcode.
      • ificmpne

        public IfInstruction ificmpne()
        The ificmpne opcode.
      • ificmplt

        public IfInstruction ificmplt()
        The ificmplt opcode.
      • ificmpge

        public IfInstruction ificmpge()
        The ificmpge opcode.
      • ificmpgt

        public IfInstruction ificmpgt()
        The ificmpgt opcode.
      • ificmple

        public IfInstruction ificmple()
        The ificmple opcode.
      • ifacmpeq

        public IfInstruction ifacmpeq()
        The ifacmpeq opcode.
      • ifacmpne

        public IfInstruction ifacmpne()
        The ifacmpne opcode.
      • ifnonnull

        public IfInstruction ifnonnull()
        The ifnonnull opcode.
      • jsr

        public JumpInstruction jsr()
        The jsr opcode used in implementing finally clauses.
      • xreturn

        public ReturnInstruction xreturn()
        Return from a method. This method will result in a nop until its type is set.
      • vreturn

        public ReturnInstruction vreturn()
        Return void from a method; the return opcode.
      • ireturn

        public ReturnInstruction ireturn()
        Return an int from a method; the ireturn opcode.
      • lreturn

        public ReturnInstruction lreturn()
        Return a long from a method; the lreturn opcode.
      • freturn

        public ReturnInstruction freturn()
        Return a float from a method; the freturn opcode.
      • dreturn

        public ReturnInstruction dreturn()
        Return a double from a method; the dreturn opcode.
      • areturn

        public ReturnInstruction areturn()
        Return an object from a method; the areturn opcode.
      • getfield

        public GetFieldInstruction getfield()
        Load the value from a field onto the stack; the getfield opcode.
      • getstatic

        public GetFieldInstruction getstatic()
        Load the value from a static field onto the stack; the getstatic opcode.
      • putfield

        public PutFieldInstruction putfield()
        Place the value of a field onto the stack; the putfield opcode.
      • putstatic

        public PutFieldInstruction putstatic()
        Place the value of a static field onto the stack; the putstatic opcode.
      • invokevirtual

        public MethodInstruction invokevirtual()
        Invoke a virtual method; the invokevirtual opcode.
      • invokespecial

        public MethodInstruction invokespecial()
        Invoke a method non-virtually, as for constructors and superclass methods; the invokespecial opcode.
      • invokeinterface

        public MethodInstruction invokeinterface()
        Invoke a method on an interface; the invokeinterface opcode.
      • invokestatic

        public MethodInstruction invokestatic()
        Invoke a static method; the invokestatic opcode.
      • invokedynamic

        public MethodInstruction invokedynamic()
        Invoke a dynamic method; the invokedynamic opcode.
      • anew

        public ClassInstruction anew()
        Create a new instance of an object; the new opcode.
      • anewarray

        public ClassInstruction anewarray()
        Create a new instance of an object array; the anew opcode.
      • checkcast

        public ClassInstruction checkcast()
        Cast an object on the stack to another type; the checkcast opcode.
      • isinstance

        public ClassInstruction isinstance()
        Test if a stack object is an instance of a class; the instanceof opcode.
      • multianewarray

        public MultiANewArrayInstruction multianewarray()
        Create a new multidimensional array; the multianewarray opcode.
      • newarray

        public NewArrayInstruction newarray()
        Create a new array of a primitive type; the newarray opcode.
      • arraylength

        public Instruction arraylength()
        Get the length of an array on the stack; the arraylength opcode.
      • athrow

        public Instruction athrow()
        Throw an exception; the athrow opcode.
      • getInstructions

        public Instruction[] getInstructions()
        Return all the Instructions of this method.
      • acceptVisit

        public void acceptVisit​(BCVisitor visit)
        Description copied from interface: VisitAcceptor
        Accept a visit from a BCVisitor, calling the appropriate methods to notify the visitor that it has entered this entity, and to provide it with the proper callbacks for each sub-entity owned by this one.
      • getLineNumberTable

        public LineNumberTable getLineNumberTable​(boolean add)
        Return line number information for the code. Acts internally through the Attributes interface.
        Parameters:
        add - if true, a new line number table will be added if not already present
        Returns:
        the line number information, or null if none and the add param is set to false
      • removeLineNumberTable

        public boolean removeLineNumberTable()
        Remove the line number table for the code. Acts internally through the Attributes interface.
        Returns:
        true if there was a table to remove
      • getLocalVariableTable

        public LocalVariableTable getLocalVariableTable​(boolean add)
        Return local variable information for the code. Acts internally through the Attributes interface.
        Parameters:
        add - if true, a new local variable table will be added if not already present
        Returns:
        the local variable information, or null if none and the add param is set to false
      • removeLocalVariableTables

        public boolean removeLocalVariableTables()
        Remove the local variable table for the code. Acts internally through the Attributes interface.
        Returns:
        true if there was a table to remove
      • getLocalVariableTypeTable

        public LocalVariableTypeTable getLocalVariableTypeTable​(boolean add)
        Return local variable generics information for the code. Acts internally through the Attributes interface.
        Parameters:
        add - if true, a new local variable type table will be added if not already present
        Returns:
        the local variable type information, or null if none and the add param is set to false
      • removeLocalVariableTypeTables

        public boolean removeLocalVariableTypeTables()
        Remove the local variable type table for the code. Acts internally through the Attributes interface.
        Returns:
        true if there was a table to remove
      • listIterator

        public java.util.ListIterator listIterator()
        Returns another listIterator view of the Instructions in this code block. Useful for performing read-only searches through Instructions without effecting the pointer location of the main code block.