Class Label

java.lang.Object
org.objectweb.asm.Label

public class Label extends Object
A position in the bytecode of a method. Labels are used for jump, goto, and switch instructions, and for try catch blocks. A label designates the instruction that is just after. Note however that there can be other elements between a label and the instruction it designates (such as other labels, stack map frames, line numbers, etc.).
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    (package private) int
    The offset of this label in the bytecode of its method, in bytes.
    (package private) static final Label
    A sentinel element used to indicate the end of a list of labels.
    (package private) static final int
    A flag indicating that a label is only used for debug attributes.
    (package private) static final int
    A flag indicating that a label is the target of a jump instruction, or the start of an exception handler.
    (package private) static final int
    A flag indicating that this label has at least one associated line number.
    (package private) static final int
    A flag indicating that a label corresponds to a reachable basic block.
    (package private) static final int
    A flag indicating that the bytecode offset of a label is known.
    (package private) static final int
    A flag indicating that the basic block corresponding to a label ends with a subroutine call.
    (package private) static final int
    A flag indicating that the basic block corresponding to a label is the end of a subroutine.
    (package private) static final int
    A flag indicating that the basic block corresponding to a label is the start of a subroutine.
    (package private) short
    The type and status of this label or its corresponding basic block.
    (package private) Frame
    The input and output stack map frames of the basic block corresponding to this label.
    A user managed state associated with this label.
    (package private) short
    The number of elements in the input stack of the basic block corresponding to this label.
    private short
    The offset of the last 2 bytes forward reference to this label in the method's bytecode, or 0 if there is none.
    private short
    The offset of the last 2 bytes forward reference to this label in the stack map table, or 0 if there is none.
    private short
    The offset of the last 4 bytes forward reference to this label in the method's bytecode, or 0 if there is none.
    (package private) static final int
    The number of elements to add to the otherLineNumbers array when it needs to be resized to store a new source line number.
    private short
    The source line number corresponding to this label, if FLAG_LINE_NUMBER is set.
    (package private) Label
    The successor of this label, in the order they are visited in MethodVisitor.visitLabel(org.objectweb.asm.Label).
    (package private) Label
    The next element in the list of labels to which this label belongs, or null if it does not belong to any list.
    private int[]
    The source line numbers corresponding to this label, in addition to lineNumber, or null.
    (package private) Edge
    The outgoing edges of the basic block corresponding to this label, in the control flow graph of its method.
    (package private) short
    The maximum height reached by the output stack, relatively to the top of the input stack, in the basic block corresponding to this label.
    (package private) short
    The number of elements in the output stack, at the end of the basic block corresponding to this label.
    (package private) short
    The id of the subroutine to which this basic block belongs, or 0.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Constructs a new label.
  • Method Summary

    Modifier and Type
    Method
    Description
    (package private) final void
    accept(MethodVisitor methodVisitor, boolean visitLineNumbers)
    Makes the given visitor visit this label and its source line numbers, if applicable.
    (package private) final void
    addLineNumber(int lineNumber)
    Adds a source line number corresponding to this label.
    (package private) final void
    addSubroutineRetSuccessors(Label subroutineCaller, Handler firstHandler, ComputeLimits limits)
    Finds the basic blocks that end a subroutine starting with the basic block corresponding to this label and, for each one of them, adds an outgoing edge to the basic block following the given subroutine call.
    (package private) final Label
    Returns the "canonical" Label instance corresponding to this label's bytecode offset, if known, otherwise the label itself.
    int
    Returns the bytecode offset corresponding to this label.
    (package private) final void
    markSubroutine(short subroutineId, Handler firstHandler, ComputeLimits limits)
    Finds the basic blocks that belong to the subroutine starting with the basic block corresponding to this label, and marks these blocks as belonging to this subroutine.
    private Label
    pushSuccessors(Label listOfLabelsToProcess, Handler firstHandler, ComputeLimits limits)
    Adds the successors of this label in the method's control flow graph (except those corresponding to a jsr target, and those already in a list of labels) to the given list of blocks to process, and returns the new list.
    (package private) final void
    put(ByteVector stackMapTableEntries)
    Puts a reference to this label in the stack map table of a method.
    (package private) final void
    put(ByteVector code, int sourceInsnBytecodeOffset, boolean wideReference)
    Puts a reference to this label in the bytecode of a method.
    (package private) final boolean
    resolve(byte[] code, ByteVector stackMapTableEntries, int bytecodeOffset)
    Sets the bytecode offset of this label to the given value and resolves the forward references to this label, if any.
    Returns a string representation of this label.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

    • FLAG_DEBUG_ONLY

      static final int FLAG_DEBUG_ONLY
      A flag indicating that a label is only used for debug attributes. Such a label is not the start of a basic block, the target of a jump instruction, or an exception handler. It can be safely ignored in control flow graph analysis algorithms (for optimization purposes).
      See Also:
    • FLAG_JUMP_TARGET

      static final int FLAG_JUMP_TARGET
      A flag indicating that a label is the target of a jump instruction, or the start of an exception handler.
      See Also:
    • FLAG_RESOLVED

      static final int FLAG_RESOLVED
      A flag indicating that the bytecode offset of a label is known.
      See Also:
    • FLAG_REACHABLE

      static final int FLAG_REACHABLE
      A flag indicating that a label corresponds to a reachable basic block.
      See Also:
    • FLAG_SUBROUTINE_CALLER

      static final int FLAG_SUBROUTINE_CALLER
      A flag indicating that the basic block corresponding to a label ends with a subroutine call. By construction in MethodWriter.visitJumpInsn(int, org.objectweb.asm.Label), labels with this flag set have at least two outgoing edges:
      • the first one corresponds to the instruction that follows the jsr instruction in the bytecode, i.e. where execution continues when it returns from the jsr call. This is a virtual control flow edge, since execution never goes directly from the jsr to the next instruction. Instead, it goes to the subroutine and eventually returns to the instruction following the jsr. This virtual edge is used to compute the real outgoing edges of the basic blocks ending with a ret instruction, in addSubroutineRetSuccessors(org.objectweb.asm.Label, org.objectweb.asm.Handler, org.objectweb.asm.ComputeLimits).
      • the second one corresponds to the target of the jsr instruction,
      See Also:
    • FLAG_SUBROUTINE_START

      static final int FLAG_SUBROUTINE_START
      A flag indicating that the basic block corresponding to a label is the start of a subroutine.
      See Also:
    • FLAG_SUBROUTINE_END

      static final int FLAG_SUBROUTINE_END
      A flag indicating that the basic block corresponding to a label is the end of a subroutine.
      See Also:
    • FLAG_LINE_NUMBER

      static final int FLAG_LINE_NUMBER
      A flag indicating that this label has at least one associated line number.
      See Also:
    • LINE_NUMBERS_CAPACITY_INCREMENT

      static final int LINE_NUMBERS_CAPACITY_INCREMENT
      The number of elements to add to the otherLineNumbers array when it needs to be resized to store a new source line number.
      See Also:
    • EMPTY_LIST

      static final Label EMPTY_LIST
      A sentinel element used to indicate the end of a list of labels.
      See Also:
    • info

      public Object info
      A user managed state associated with this label. Warning: this field is used by the ASM tree package. In order to use it with the ASM tree package you must override the getLabelNode method in MethodNode.
    • flags

      short flags
      The type and status of this label or its corresponding basic block. Must be zero or more of FLAG_DEBUG_ONLY, FLAG_JUMP_TARGET, FLAG_RESOLVED, FLAG_REACHABLE, FLAG_SUBROUTINE_CALLER, FLAG_SUBROUTINE_START, FLAG_SUBROUTINE_END.
    • lineNumber

      private short lineNumber
      The source line number corresponding to this label, if FLAG_LINE_NUMBER is set. If there are several source line numbers corresponding to this label, the first one is stored in this field, and the remaining ones are stored in otherLineNumbers.
    • otherLineNumbers

      private int[] otherLineNumbers
      The source line numbers corresponding to this label, in addition to lineNumber, or null. The first element of this array is the number n of source line numbers it contains, which are stored between indices 1 and n (inclusive).
    • bytecodeOffset

      int bytecodeOffset
      The offset of this label in the bytecode of its method, in bytes. This value is set if and only if the FLAG_RESOLVED flag is set.
    • lastForwardReference

      private short lastForwardReference
      The offset of the last 2 bytes forward reference to this label in the method's bytecode, or 0 if there is none. The unsigned short at this offset contain the offset of the previous 2 bytes forward reference, or 0 if there is none. And so on. The instructions containing these forward references must be 3 bytes instructions (1 opcode byte, 2 bytes argument).

      This field must be interpreted as an unsigned int (Short.toUnsignedInt(short)).

    • lastWideForwardReference

      private short lastWideForwardReference
      The offset of the last 4 bytes forward reference to this label in the method's bytecode, or 0 if there is none. The 4 bytes at this offset contain two unsigned short values:
      • the offset of the previous 4 bytes forward reference, or 0 if there is none,
      • the offset of the first byte of the instruction containing this forward reference.

      And so on.

      This field must be interpreted as an unsigned int (Short.toUnsignedInt(short)).

    • lastStackMapForwardReference

      private short lastStackMapForwardReference
      The offset of the last 2 bytes forward reference to this label in the stack map table, or 0 if there is none. The unsigned short at this offset contain the offset of the previous 2 bytes forward reference, or 0 if there is none. And so on.

      This field must be interpreted as an unsigned int (Short.toUnsignedInt(short)).

    • inputStackSize

      short inputStackSize
      The number of elements in the input stack of the basic block corresponding to this label. This field is computed in MethodWriter.computeMaxStackAndLocal().
    • outputStackSize

      short outputStackSize
      The number of elements in the output stack, at the end of the basic block corresponding to this label. This field is only computed for basic blocks that end with a RET instruction.
    • outputStackMax

      short outputStackMax
      The maximum height reached by the output stack, relatively to the top of the input stack, in the basic block corresponding to this label. This maximum is always positive or null.
    • subroutineId

      short subroutineId
      The id of the subroutine to which this basic block belongs, or 0. If the basic block belongs to several subroutines, this is the id of the "oldest" subroutine that contains it (with the convention that a subroutine calling another one is "older" than the callee). This field is computed in MethodWriter.computeMaxStackAndLocal(), if the method contains JSR instructions.
    • frame

      Frame frame
      The input and output stack map frames of the basic block corresponding to this label. This field is only used when the MethodWriter.COMPUTE_ALL_FRAMES or MethodWriter.COMPUTE_INSERTED_FRAMES option is used.
    • nextBasicBlock

      Label nextBasicBlock
      The successor of this label, in the order they are visited in MethodVisitor.visitLabel(org.objectweb.asm.Label). This linked list does not include labels used for debug info only. If the MethodWriter.COMPUTE_ALL_FRAMES or MethodWriter.COMPUTE_INSERTED_FRAMES option is used then it does not contain either successive labels that denote the same bytecode offset (in this case only the first label appears in this list).
    • outgoingEdges

      Edge outgoingEdges
      The outgoing edges of the basic block corresponding to this label, in the control flow graph of its method. These edges are stored in a linked list of Edge objects, linked to each other by their Edge.nextEdge field.
    • nextListElement

      Label nextListElement
      The next element in the list of labels to which this label belongs, or null if it does not belong to any list. All lists of labels must end with the EMPTY_LIST sentinel, in order to ensure that this field is null if and only if this label does not belong to a list of labels. Note that there can be several lists of labels at the same time, but that a label can belong to at most one list at a time (unless some lists share a common tail, but this is not used in practice).

      List of labels are used in MethodWriter.computeAllFrames() and MethodWriter.computeMaxStackAndLocal() to compute stack map frames and the maximum stack size, respectively, as well as in markSubroutine(short, org.objectweb.asm.Handler, org.objectweb.asm.ComputeLimits) and addSubroutineRetSuccessors(org.objectweb.asm.Label, org.objectweb.asm.Handler, org.objectweb.asm.ComputeLimits) to compute the basic blocks belonging to subroutines and their outgoing edges. Outside of these methods, this field should be null (this property is a precondition and a postcondition of these methods).

  • Constructor Details

    • Label

      public Label()
      Constructs a new label.
  • Method Details

    • getOffset

      public int getOffset()
      Returns the bytecode offset corresponding to this label. This offset is computed from the start of the method's bytecode. This method is intended for Attribute sub classes, and is normally not needed by class generators or adapters.
      Returns:
      the bytecode offset corresponding to this label.
      Throws:
      IllegalStateException - if this label is not resolved yet.
    • getCanonicalInstance

      final Label getCanonicalInstance()
      Returns the "canonical" Label instance corresponding to this label's bytecode offset, if known, otherwise the label itself. The canonical instance is the first label (in the order of their visit by MethodVisitor.visitLabel(org.objectweb.asm.Label)) corresponding to this bytecode offset. It cannot be known for labels which have not been visited yet.

      This method should only be used when the MethodWriter.COMPUTE_ALL_FRAMES option is used.

      Returns:
      the label itself if frame is null, otherwise the Label's frame owner. This corresponds to the "canonical" label instance described above thanks to the way the label frame is set in MethodWriter.visitLabel(org.objectweb.asm.Label).
    • addLineNumber

      final void addLineNumber(int lineNumber)
      Adds a source line number corresponding to this label.
      Parameters:
      lineNumber - a source line number (which should be strictly positive).
    • accept

      final void accept(MethodVisitor methodVisitor, boolean visitLineNumbers)
      Makes the given visitor visit this label and its source line numbers, if applicable.
      Parameters:
      methodVisitor - a method visitor.
      visitLineNumbers - whether to visit of the label's source line numbers, if any.
    • put

      final void put(ByteVector code, int sourceInsnBytecodeOffset, boolean wideReference)
      Puts a reference to this label in the bytecode of a method. If the bytecode offset of the label is known, the relative bytecode offset between the label and the instruction referencing it is computed and written directly. Otherwise, a null relative offset is written and a new forward reference is declared for this label.
      Parameters:
      code - the bytecode of the method. This is where the reference is appended.
      sourceInsnBytecodeOffset - the bytecode offset of the instruction that contains the reference to be appended. If wideReference is false, this must be code.length - 1.
      wideReference - whether the reference must be stored in 4 bytes (instead of 2 bytes).
    • put

      final void put(ByteVector stackMapTableEntries)
      Puts a reference to this label in the stack map table of a method. If the bytecode offset of the label is known, it is written directly. Otherwise, a null relative offset is written and a new forward reference is declared for this label.
      Parameters:
      stackMapTableEntries - the stack map table where the label offset must be added.
    • resolve

      final boolean resolve(byte[] code, ByteVector stackMapTableEntries, int bytecodeOffset)
      Sets the bytecode offset of this label to the given value and resolves the forward references to this label, if any. This method must be called when this label is added to the bytecode of the method, i.e. when its bytecode offset becomes known. This method fills in the blanks that where left in the bytecode (and optionally in the stack map table) by each forward reference previously added to this label.
      Parameters:
      code - the bytecode of the method.
      stackMapTableEntries - the 'entries' array of the StackMapTable code attribute of the method. Maybe null.
      bytecodeOffset - the bytecode offset of this label.
      Returns:
      true if a blank that was left for this label was too small to store the offset. In such a case the corresponding jump instruction is replaced with an equivalent ASM specific instruction using an unsigned two bytes offset. These ASM specific instructions are later replaced with standard bytecode instructions with wider offsets (4 bytes instead of 2), in ClassReader.
    • markSubroutine

      final void markSubroutine(short subroutineId, Handler firstHandler, ComputeLimits limits)
      Finds the basic blocks that belong to the subroutine starting with the basic block corresponding to this label, and marks these blocks as belonging to this subroutine. This method follows the control flow graph to find all the blocks that are reachable from the current basic block WITHOUT following any jsr target.

      Note: a precondition and postcondition of this method is that all labels must have a null nextListElement.

      Parameters:
      subroutineId - the id of the subroutine starting with the basic block corresponding to this label.
      firstHandler - the first element in the exception handler list. May be null.
      limits - the maximum time and space limits for this method.
    • addSubroutineRetSuccessors

      final void addSubroutineRetSuccessors(Label subroutineCaller, Handler firstHandler, ComputeLimits limits)
      Finds the basic blocks that end a subroutine starting with the basic block corresponding to this label and, for each one of them, adds an outgoing edge to the basic block following the given subroutine call. In other words, completes the control flow graph by adding the edges corresponding to the return from this subroutine, when called from the given caller basic block. Throws a RuntimeException if multiple ret instructions are found for this subroutine (See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.9.2: "The instruction following each jsr or jsr_w instruction may be returned to only by a single ret instruction.").

      Note: a precondition and postcondition of this method is that all labels must have a null nextListElement.

      Parameters:
      subroutineCaller - a basic block that ends with a jsr to the basic block corresponding to this label. This label is supposed to correspond to the start of a subroutine.
      firstHandler - the first element in the exception handler list. May be null.
      limits - the maximum time and space limits for this method.
    • pushSuccessors

      private Label pushSuccessors(Label listOfLabelsToProcess, Handler firstHandler, ComputeLimits limits)
      Adds the successors of this label in the method's control flow graph (except those corresponding to a jsr target, and those already in a list of labels) to the given list of blocks to process, and returns the new list.
      Parameters:
      listOfLabelsToProcess - a list of basic blocks to process, linked together with their nextListElement field.
      firstHandler - the first element in the exception handler list. May be null.
      limits - the maximum time and space limits for this method.
      Returns:
      the new list of blocks to process.
    • toString

      public String toString()
      Returns a string representation of this label.
      Overrides:
      toString in class Object
      Returns:
      a string representation of this label.