Class Bytecode

  • All Implemented Interfaces:
    java.lang.Cloneable, Opcode

    public class Bytecode
    extends java.lang.Object
    implements java.lang.Cloneable, Opcode
    A utility class for producing a bytecode sequence.

    A Bytecode object is an unbounded array containing bytecode. For example,

     ConstPool cp = ...;    // constant pool table
     Bytecode b = new Bytecode(cp, 1, 0);
     b.addIconst(3);
     b.addReturn(CtClass.intType);
     CodeAttribute ca = b.toCodeAttribute();

    This program produces a Code attribute including a bytecode sequence:

     iconst_3
     ireturn
    See Also:
    ConstPool, CodeAttribute
    • Field Detail

      • THIS

        public static final CtClass THIS
        Represents the CtClass file using the constant pool table given to this Bytecode object.
    • Constructor Detail

      • Bytecode

        public Bytecode​(ConstPool cp,
                        int stacksize,
                        int localvars)
        Constructs a Bytecode object with an empty bytecode sequence.

        The parameters stacksize and localvars specify initial values of max_stack and max_locals. They can be changed later.

        Parameters:
        cp - constant pool table.
        stacksize - max_stack.
        localvars - max_locals.
      • Bytecode

        public Bytecode​(ConstPool cp)
        Constructs a Bytecode object with an empty bytecode sequence. The initial values of max_stack and max_locals are zero.
        Parameters:
        cp - constant pool table.
        See Also:
        setMaxStack(int), setMaxLocals(int)
    • Method Detail

      • clone

        public java.lang.Object clone()
        Creates and returns a copy of this object. The constant pool object is shared between this object and the cloned object.
      • getConstPool

        public ConstPool getConstPool()
        Gets a constant pool table.
      • getExceptionTable

        public ExceptionTable getExceptionTable()
        Returns exception_table.
      • toCodeAttribute

        public CodeAttribute toCodeAttribute()
        Converts to a CodeAttribute.
      • length

        public int length()
        Returns the length of the bytecode sequence.
      • get

        public byte[] get()
        Returns the produced bytecode sequence.
      • getMaxStack

        public int getMaxStack()
        Gets max_stack.
      • setMaxStack

        public void setMaxStack​(int size)
        Sets max_stack.

        This value may be automatically updated when an instruction is appended. A Bytecode object maintains the current stack depth whenever an instruction is added by addOpcode(). For example, if DUP is appended, the current stack depth is increased by one. If the new stack depth is more than max_stack, then it is assigned to max_stack. However, if branch instructions are appended, the current stack depth may not be correctly maintained.

        See Also:
        addOpcode(int)
      • getMaxLocals

        public int getMaxLocals()
        Gets max_locals.
      • setMaxLocals

        public void setMaxLocals​(int size)
        Sets max_locals.
      • setMaxLocals

        public void setMaxLocals​(boolean isStatic,
                                 CtClass[] params,
                                 int locals)
        Sets max_locals.

        This computes the number of local variables used to pass method parameters and sets max_locals to that number plus locals.

        Parameters:
        isStatic - true if params must be interpreted as parameters to a static method.
        params - parameter types.
        locals - the number of local variables excluding ones used to pass parameters.
      • incMaxLocals

        public void incMaxLocals​(int diff)
        Increments max_locals.
      • addExceptionHandler

        public void addExceptionHandler​(int start,
                                        int end,
                                        int handler,
                                        CtClass type)
        Adds a new entry of exception_table.
      • addExceptionHandler

        public void addExceptionHandler​(int start,
                                        int end,
                                        int handler,
                                        java.lang.String type)
        Adds a new entry of exception_table.
        Parameters:
        type - the fully-qualified name of a throwable class.
      • addExceptionHandler

        public void addExceptionHandler​(int start,
                                        int end,
                                        int handler,
                                        int type)
        Adds a new entry of exception_table.
      • currentPc

        public int currentPc()
        Returns the length of bytecode sequence that have been added so far.
      • read

        public int read​(int offset)
        Reads a signed 8bit value at the offset from the beginning of the bytecode sequence.
        Throws:
        java.lang.ArrayIndexOutOfBoundsException - if offset is invalid.
      • read16bit

        public int read16bit​(int offset)
        Reads a signed 16bit value at the offset from the beginning of the bytecode sequence.
      • read32bit

        public int read32bit​(int offset)
        Reads a signed 32bit value at the offset from the beginning of the bytecode sequence.
      • write

        public void write​(int offset,
                          int value)
        Writes an 8bit value at the offset from the beginning of the bytecode sequence.
        Throws:
        java.lang.ArrayIndexOutOfBoundsException - if offset is invalid.
      • write16bit

        public void write16bit​(int offset,
                               int value)
        Writes an 16bit value at the offset from the beginning of the bytecode sequence.
      • write32bit

        public void write32bit​(int offset,
                               int value)
        Writes an 32bit value at the offset from the beginning of the bytecode sequence.
      • add

        public void add​(int code)
        Appends an 8bit value to the end of the bytecode sequence.
      • add32bit

        public void add32bit​(int value)
        Appends a 32bit value to the end of the bytecode sequence.
      • addGap

        public void addGap​(int length)
        Appends the length-byte gap to the end of the bytecode sequence.
        Parameters:
        length - the gap length in byte.
      • addOpcode

        public void addOpcode​(int code)
        Appends an 8bit opcode to the end of the bytecode sequence. The current stack depth is updated. max_stack is updated if the current stack depth is the deepest so far.

        Note: some instructions such as INVOKEVIRTUAL does not update the current stack depth since the increment depends on the method signature. growStack() must be explicitly called.

      • growStack

        public void growStack​(int diff)
        Increases the current stack depth. It also updates max_stack if the current stack depth is the deepest so far.
        Parameters:
        diff - the number added to the current stack depth.
      • getStackDepth

        public int getStackDepth()
        Returns the current stack depth.
      • setStackDepth

        public void setStackDepth​(int depth)
        Sets the current stack depth. It also updates max_stack if the current stack depth is the deepest so far.
        Parameters:
        depth - new value.
      • addIndex

        public void addIndex​(int index)
        Appends a 16bit value to the end of the bytecode sequence. It never changes the current stack depth.
      • addAload

        public void addAload​(int n)
        Appends ALOAD or (WIDE) ALOAD_<n>
        Parameters:
        n - an index into the local variable array.
      • addAstore

        public void addAstore​(int n)
        Appends ASTORE or (WIDE) ASTORE_<n>
        Parameters:
        n - an index into the local variable array.
      • addIconst

        public void addIconst​(int n)
        Appends ICONST or ICONST_<n>
        Parameters:
        n - the pushed integer constant.
      • addConstZero

        public void addConstZero​(CtClass type)
        Appends an instruction for pushing zero or null on the stack. If the type is void, this method does not append any instruction.
        Parameters:
        type - the type of the zero value (or null).
      • addIload

        public void addIload​(int n)
        Appends ILOAD or (WIDE) ILOAD_<n>
        Parameters:
        n - an index into the local variable array.
      • addIstore

        public void addIstore​(int n)
        Appends ISTORE or (WIDE) ISTORE_<n>
        Parameters:
        n - an index into the local variable array.
      • addLconst

        public void addLconst​(long n)
        Appends LCONST or LCONST_<n>
        Parameters:
        n - the pushed long integer constant.
      • addLload

        public void addLload​(int n)
        Appends LLOAD or (WIDE) LLOAD_<n>
        Parameters:
        n - an index into the local variable array.
      • addLstore

        public void addLstore​(int n)
        Appends LSTORE or LSTORE_<n>
        Parameters:
        n - an index into the local variable array.
      • addDconst

        public void addDconst​(double d)
        Appends DCONST or DCONST_<n>
        Parameters:
        d - the pushed double constant.
      • addDload

        public void addDload​(int n)
        Appends DLOAD or (WIDE) DLOAD_<n>
        Parameters:
        n - an index into the local variable array.
      • addDstore

        public void addDstore​(int n)
        Appends DSTORE or (WIDE) DSTORE_<n>
        Parameters:
        n - an index into the local variable array.
      • addFconst

        public void addFconst​(float f)
        Appends FCONST or FCONST_<n>
        Parameters:
        f - the pushed float constant.
      • addFload

        public void addFload​(int n)
        Appends FLOAD or (WIDE) FLOAD_<n>
        Parameters:
        n - an index into the local variable array.
      • addFstore

        public void addFstore​(int n)
        Appends FSTORE or FSTORE_<n>
        Parameters:
        n - an index into the local variable array.
      • addLoad

        public int addLoad​(int n,
                           CtClass type)
        Appends an instruction for loading a value from the local variable at the index n.
        Parameters:
        n - the index.
        type - the type of the loaded value.
        Returns:
        the size of the value (1 or 2 word).
      • addStore

        public int addStore​(int n,
                            CtClass type)
        Appends an instruction for storing a value into the local variable at the index n.
        Parameters:
        n - the index.
        type - the type of the stored value.
        Returns:
        2 if the type is long or double. Otherwise 1.
      • addLoadParameters

        public int addLoadParameters​(CtClass[] params,
                                     int offset)
        Appends instructions for loading all the parameters onto the operand stack.
        Parameters:
        offset - the index of the first parameter. It is 0 if the method is static. Otherwise, it is 1.
      • addCheckcast

        public void addCheckcast​(CtClass c)
        Appends CHECKCAST.
        Parameters:
        c - the type.
      • addCheckcast

        public void addCheckcast​(java.lang.String classname)
        Appends CHECKCAST.
        Parameters:
        classname - a fully-qualified class name.
      • addInstanceof

        public void addInstanceof​(java.lang.String classname)
        Appends INSTANCEOF.
        Parameters:
        classname - the class name.
      • addGetfield

        public void addGetfield​(CtClass c,
                                java.lang.String name,
                                java.lang.String type)
        Appends GETFIELD.
        Parameters:
        c - the class.
        name - the field name.
        type - the descriptor of the field type.
        See Also:
        Descriptor.of(CtClass)
      • addGetfield

        public void addGetfield​(java.lang.String c,
                                java.lang.String name,
                                java.lang.String type)
        Appends GETFIELD.
        Parameters:
        c - the fully-qualified class name.
        name - the field name.
        type - the descriptor of the field type.
        See Also:
        Descriptor.of(CtClass)
      • addGetstatic

        public void addGetstatic​(CtClass c,
                                 java.lang.String name,
                                 java.lang.String type)
        Appends GETSTATIC.
        Parameters:
        c - the class
        name - the field name
        type - the descriptor of the field type.
        See Also:
        Descriptor.of(CtClass)
      • addGetstatic

        public void addGetstatic​(java.lang.String c,
                                 java.lang.String name,
                                 java.lang.String type)
        Appends GETSTATIC.
        Parameters:
        c - the fully-qualified class name
        name - the field name
        type - the descriptor of the field type.
        See Also:
        Descriptor.of(CtClass)
      • addInvokespecial

        public void addInvokespecial​(CtClass clazz,
                                     java.lang.String name,
                                     CtClass returnType,
                                     CtClass[] paramTypes)
        Appends INVOKESPECIAL.
        Parameters:
        clazz - the target class.
        name - the method name.
        returnType - the return type.
        paramTypes - the parameter types.
      • addInvokespecial

        public void addInvokespecial​(java.lang.String clazz,
                                     java.lang.String name,
                                     java.lang.String desc)
        Appends INVOKESPECIAL. The invoked method must not be a default method declared in an interface.
        Parameters:
        clazz - the fully-qualified class name.
        name - the method name
        desc - the descriptor of the method signature.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[]), Descriptor.ofConstructor(CtClass[])
      • addInvokespecial

        public void addInvokespecial​(int clazz,
                                     java.lang.String name,
                                     java.lang.String desc)
        Appends INVOKESPECIAL. The invoked method must not be a default method declared in an interface.
        Parameters:
        clazz - the index of CONSTANT_Class_info structure.
        name - the method name
        desc - the descriptor of the method signature.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[]), Descriptor.ofConstructor(CtClass[])
      • addInvokespecial

        public void addInvokespecial​(boolean isInterface,
                                     int clazz,
                                     java.lang.String name,
                                     java.lang.String desc)
        Appends INVOKESPECIAL.
        Parameters:
        isInterface - true if the invoked method is a default method declared in an interface.
        clazz - the index of CONSTANT_Class_info structure.
        name - the method name
        desc - the descriptor of the method signature.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[]), Descriptor.ofConstructor(CtClass[])
      • addInvokestatic

        public void addInvokestatic​(CtClass clazz,
                                    java.lang.String name,
                                    CtClass returnType,
                                    CtClass[] paramTypes)
        Appends INVOKESTATIC.
        Parameters:
        clazz - the target class.
        name - the method name
        returnType - the return type.
        paramTypes - the parameter types.
      • addInvokestatic

        public void addInvokestatic​(CtClass clazz,
                                    java.lang.String name,
                                    java.lang.String desc)
        Appends INVOKESTATIC.
        Parameters:
        clazz - the target class.
        name - the method name
        desc - the descriptor of the method signature.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[])
      • addInvokestatic

        public void addInvokestatic​(java.lang.String classname,
                                    java.lang.String name,
                                    java.lang.String desc)
        Appends INVOKESTATIC.
        Parameters:
        classname - the fully-qualified class name. It must not be an interface-type name.
        name - the method name
        desc - the descriptor of the method signature.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[])
      • addInvokestatic

        public void addInvokestatic​(int clazz,
                                    java.lang.String name,
                                    java.lang.String desc)
        Appends INVOKESTATIC.
        Parameters:
        clazz - the index of CONSTANT_Class_info structure. It must not be an interface type.
        name - the method name
        desc - the descriptor of the method signature.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[])
      • addInvokevirtual

        public void addInvokevirtual​(CtClass clazz,
                                     java.lang.String name,
                                     CtClass returnType,
                                     CtClass[] paramTypes)
        Appends INVOKEVIRTUAL.

        The specified method must not be an inherited method. It must be directly declared in the class specified in clazz.

        Parameters:
        clazz - the target class.
        name - the method name
        returnType - the return type.
        paramTypes - the parameter types.
      • addInvokevirtual

        public void addInvokevirtual​(CtClass clazz,
                                     java.lang.String name,
                                     java.lang.String desc)
        Appends INVOKEVIRTUAL.

        The specified method must not be an inherited method. It must be directly declared in the class specified in clazz.

        Parameters:
        clazz - the target class.
        name - the method name
        desc - the descriptor of the method signature.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[])
      • addInvokevirtual

        public void addInvokevirtual​(java.lang.String classname,
                                     java.lang.String name,
                                     java.lang.String desc)
        Appends INVOKEVIRTUAL.

        The specified method must not be an inherited method. It must be directly declared in the class specified in classname.

        Parameters:
        classname - the fully-qualified class name.
        name - the method name
        desc - the descriptor of the method signature.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[])
      • addInvokevirtual

        public void addInvokevirtual​(int clazz,
                                     java.lang.String name,
                                     java.lang.String desc)
        Appends INVOKEVIRTUAL.

        The specified method must not be an inherited method. It must be directly declared in the class specified by clazz.

        Parameters:
        clazz - the index of CONSTANT_Class_info structure.
        name - the method name
        desc - the descriptor of the method signature.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[])
      • addInvokeinterface

        public void addInvokeinterface​(CtClass clazz,
                                       java.lang.String name,
                                       CtClass returnType,
                                       CtClass[] paramTypes,
                                       int count)
        Appends INVOKEINTERFACE.
        Parameters:
        clazz - the target class.
        name - the method name
        returnType - the return type.
        paramTypes - the parameter types.
        count - the count operand of the instruction.
      • addInvokeinterface

        public void addInvokeinterface​(CtClass clazz,
                                       java.lang.String name,
                                       java.lang.String desc,
                                       int count)
        Appends INVOKEINTERFACE.
        Parameters:
        clazz - the target class.
        name - the method name
        desc - the descriptor of the method signature.
        count - the count operand of the instruction.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[])
      • addInvokeinterface

        public void addInvokeinterface​(java.lang.String classname,
                                       java.lang.String name,
                                       java.lang.String desc,
                                       int count)
        Appends INVOKEINTERFACE.
        Parameters:
        classname - the fully-qualified class name.
        name - the method name
        desc - the descriptor of the method signature.
        count - the count operand of the instruction.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[])
      • addInvokeinterface

        public void addInvokeinterface​(int clazz,
                                       java.lang.String name,
                                       java.lang.String desc,
                                       int count)
        Appends INVOKEINTERFACE.
        Parameters:
        clazz - the index of CONSTANT_Class_info structure.
        name - the method name
        desc - the descriptor of the method signature.
        count - the count operand of the instruction.
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[])
      • addInvokedynamic

        public void addInvokedynamic​(int bootstrap,
                                     java.lang.String name,
                                     java.lang.String desc)
        Appends INVOKEDYNAMIC.
        Parameters:
        bootstrap - an index into the bootstrap_methods array of the bootstrap method table.
        name - the method name.
        desc - the method descriptor.
        Since:
        3.17
        See Also:
        Descriptor.ofMethod(CtClass,CtClass[])
      • addLdc

        public void addLdc​(java.lang.String s)
        Appends LDC or LDC_W. The pushed item is a String object.
        Parameters:
        s - the character string pushed by LDC or LDC_W.
      • addLdc

        public void addLdc​(int i)
        Appends LDC or LDC_W.
        Parameters:
        i - index into the constant pool.
      • addLdc2w

        public void addLdc2w​(long l)
        Appends LDC2_W. The pushed item is a long value.
      • addLdc2w

        public void addLdc2w​(double d)
        Appends LDC2_W. The pushed item is a double value.
      • addNew

        public void addNew​(CtClass clazz)
        Appends NEW.
        Parameters:
        clazz - the class of the created instance.
      • addNew

        public void addNew​(java.lang.String classname)
        Appends NEW.
        Parameters:
        classname - the fully-qualified class name.
      • addAnewarray

        public void addAnewarray​(java.lang.String classname)
        Appends ANEWARRAY.
        Parameters:
        classname - the qualified class name of the element type.
      • addAnewarray

        public void addAnewarray​(CtClass clazz,
                                 int length)
        Appends ICONST and ANEWARRAY.
        Parameters:
        clazz - the elememnt type.
        length - the array length.
      • addNewarray

        public void addNewarray​(int atype,
                                int length)
        Appends NEWARRAY for primitive types.
        Parameters:
        atype - T_BOOLEAN, T_CHAR, ...
        See Also:
        Opcode
      • addMultiNewarray

        public int addMultiNewarray​(CtClass clazz,
                                    int[] dimensions)
        Appends MULTINEWARRAY.
        Parameters:
        clazz - the array type.
        dimensions - the sizes of all dimensions.
        Returns:
        the length of dimensions.
      • addMultiNewarray

        public int addMultiNewarray​(CtClass clazz,
                                    int dim)
        Appends MULTINEWARRAY. The size of every dimension must have been already pushed on the stack.
        Parameters:
        clazz - the array type.
        dim - the number of the dimensions.
        Returns:
        the value of dim.
      • addMultiNewarray

        public int addMultiNewarray​(java.lang.String desc,
                                    int dim)
        Appends MULTINEWARRAY.
        Parameters:
        desc - the type descriptor of the created array.
        dim - dimensions.
        Returns:
        the value of dim.
      • addPutfield

        public void addPutfield​(CtClass c,
                                java.lang.String name,
                                java.lang.String desc)
        Appends PUTFIELD.
        Parameters:
        c - the target class.
        name - the field name.
        desc - the descriptor of the field type.
      • addPutfield

        public void addPutfield​(java.lang.String classname,
                                java.lang.String name,
                                java.lang.String desc)
        Appends PUTFIELD.
        Parameters:
        classname - the fully-qualified name of the target class.
        name - the field name.
        desc - the descriptor of the field type.
      • addPutstatic

        public void addPutstatic​(CtClass c,
                                 java.lang.String name,
                                 java.lang.String desc)
        Appends PUTSTATIC.
        Parameters:
        c - the target class.
        name - the field name.
        desc - the descriptor of the field type.
      • addPutstatic

        public void addPutstatic​(java.lang.String classname,
                                 java.lang.String fieldName,
                                 java.lang.String desc)
        Appends PUTSTATIC.
        Parameters:
        classname - the fully-qualified name of the target class.
        fieldName - the field name.
        desc - the descriptor of the field type.
      • addReturn

        public void addReturn​(CtClass type)
        Appends ARETURN, IRETURN, .., or RETURN.
        Parameters:
        type - the return type.
      • addRet

        public void addRet​(int var)
        Appends RET.
        Parameters:
        var - local variable
      • addPrintln

        public void addPrintln​(java.lang.String message)
        Appends instructions for executing java.lang.System.println(message).
        Parameters:
        message - printed message.
      • getSize

        public final int getSize()
      • copy

        public final byte[] copy()
      • add

        public void add​(int b1,
                        int b2)
      • add

        public void add​(int b1,
                        int b2,
                        int b3,
                        int b4)