Label.java revision 674060f01e9090cd21b3c5656cc3204912ad17a6
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/***
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ASM: a very small and fast Java bytecode manipulation framework
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2000-2007 INRIA, France Telecom
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All rights reserved.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) * modification, are permitted provided that the following conditions
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are met:
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    documentation and/or other materials provided with the distribution.
14a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) * 3. Neither the name of the copyright holders nor the names of its
15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *    contributors may be used to endorse or promote products derived from
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *    this software without specific prior written permission.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
18bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * THE POSSIBILITY OF SUCH DAMAGE.
29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch */
30a3f7b4e666c476898878fa745f637129375cd889Ben Murdochpackage org.mockito.asm;
31a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/**
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * A label represents a position in the bytecode of a method. Labels are used
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for jump, goto, and switch instructions, and for try catch blocks.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @author Eric Bruneton
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochpublic class Label {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Indicates if this label is only used for debug attributes. Such a label
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * is not the start of a basic block, the target of a jump instruction, or
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * an exception handler. It can be safely ignored in control flow graph
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * analysis algorithms (for optimization purposes).
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch     */
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static final int DEBUG = 1;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Indicates if the position of this label is known.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static final int RESOLVED = 2;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Indicates if this label has been updated, after instruction resizing.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static final int RESIZED = 4;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Indicates if this basic block has been pushed in the basic block stack.
60a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch     * See {@link MethodWriter#visitMaxs visitMaxs}.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    static final int PUSHED = 8;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Indicates if this label is the target of a jump instruction, or the start
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * of an exception handler.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static final int TARGET = 16;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Indicates if a stack map frame must be stored for this label.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static final int STORE = 32;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Indicates if this label corresponds to a reachable basic block.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    static final int REACHABLE = 64;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Indicates if this basic block ends with a JSR instruction.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    static final int JSR = 128;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Indicates if this basic block ends with a RET instruction.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    static final int RET = 256;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Indicates if this basic block is the start of a subroutine.
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    static final int SUBROUTINE = 512;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Indicates if this subroutine basic block has been visited.
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    static final int VISITED = 1024;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Field used to associate user information to a label. Warning: this field
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * is used by the ASM tree package. In order to use it with the ASM tree
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * package you must override the {@link
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * org.mockito.asm.tree.MethodNode#getLabelNode} method.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public Object info;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Flags that indicate the status of this label.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @see #DEBUG
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @see #RESOLVED
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @see #RESIZED
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @see #PUSHED
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @see #TARGET
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @see #STORE
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @see #REACHABLE
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @see #JSR
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @see #RET
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int status;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The line number corresponding to this label, if known.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int line;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The position of this label in the code, if known.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int position;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Number of forward references to this label, times two.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private int referenceCount;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Informations about forward references. Each forward reference is
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * described by two consecutive integers in this array: the first one is the
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * position of the first byte of the bytecode instruction that contains the
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * forward reference, while the second is the position of the first byte of
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the forward reference itself. In fact the sign of the first integer
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * indicates if this reference uses 2 or 4 bytes, and its absolute value
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * gives the position of the bytecode instruction. This array is also used
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * as a bitset to store the subroutines to which a basic block belongs. This
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * information is needed in {@linked  MethodWriter#visitMaxs}, after all
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * forward references have been resolved. Hence the same array can be used
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * for both purposes without problems.
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private int[] srcAndRefPositions;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // ------------------------------------------------------------------------
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /*
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Fields for the control flow and data flow graph analysis algorithms (used
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * to compute the maximum stack size or the stack map frames). A control
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * flow graph contains one node per "basic block", and one edge per "jump"
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * from one basic block to another. Each node (i.e., each basic block) is
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * represented by the Label object that corresponds to the first instruction
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * of this basic block. Each node also stores the list of its successors in
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * the graph, as a linked list of Edge objects.
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * The control flow analysis algorithms used to compute the maximum stack
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * size or the stack map frames are similar and use two steps. The first
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * step, during the visit of each instruction, builds information about the
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * state of the local variables and the operand stack at the end of each
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * basic block, called the "output frame", <i>relatively</i> to the frame
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * state at the beginning of the basic block, which is called the "input
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * frame", and which is <i>unknown</i> during this step. The second step,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * in {@link MethodWriter#visitMaxs}, is a fix point algorithm that
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * computes information about the input frame of each basic block, from the
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * input state of the first basic block (known from the method signature),
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * and by the using the previously computed relative output frames.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The algorithm used to compute the maximum stack size only computes the
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * relative output and absolute input stack heights, while the algorithm
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * used to compute stack map frames computes relative output frames and
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * absolute input frames.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)     * Start of the output stack relatively to the input stack. The exact
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * semantics of this field depends on the algorithm that is used.
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     *
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * When only the maximum stack size is computed, this field is the number of
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * elements in the input stack.
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * When the stack map frames are completely computed, this field is the
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * offset of the first output stack element relatively to the top of the
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * input stack. This offset is always negative or null. A null offset means
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * that the output stack must be appended to the input stack. A -n offset
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * means that the first n output stack elements must replace the top n input
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * stack elements, and that the other elements must be appended to the input
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * stack.
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int inputStackTop;
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)     * Maximum height reached by the output stack, relatively to the top of the
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * input stack. This maximum is always positive or null.
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int outputStackMax;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Information about the input and output stack map frames of this basic
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * block. This field is only used when {@link ClassWriter#COMPUTE_FRAMES}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * option is used.
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Frame frame;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The successor of this label, in the order they are visited. This linked
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * list does not include labels used for debug info only. If
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * does not contain successive labels that denote the same bytecode position
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * (in this case only the first label appears in this list).
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Label successor;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The successors of this node in the control flow graph. These successors
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * are stored in a linked list of {@link Edge Edge} objects, linked to each
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * other by their {@link Edge#next} field.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Edge successors;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The next basic block in the basic block stack. This stack is used in the
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * main loop of the fix point algorithm used in the second step of the
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * control flow analysis algorithms.
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @see MethodWriter#visitMaxs
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Label next;
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // ------------------------------------------------------------------------
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Constructor
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ------------------------------------------------------------------------
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Constructs a new label.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public Label() {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ------------------------------------------------------------------------
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Methods to compute offsets and to manage forward references
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ------------------------------------------------------------------------
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Returns the offset corresponding to this label. This offset is computed
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * from the start of the method's bytecode. <i>This method is intended for
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * {@link Attribute} sub classes, and is normally not needed by class
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * generators or adapters.</i>
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch     * @return the offset corresponding to this label.
2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch     * @throws IllegalStateException if this label is not resolved yet.
2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch     */
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public int getOffset() {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((status & RESOLVED) == 0) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            throw new IllegalStateException("Label offset position has not been resolved yet");
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return position;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Puts a reference to this label in the bytecode of a method. If the
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * position of the label is known, the offset is computed and written
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * directly. Otherwise, a null offset is written and a new forward reference
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * is declared for this label.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param owner the code writer that calls this method.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param out the bytecode of the method.
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param source the position of first byte of the bytecode instruction that
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *        contains this label.
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param wideOffset <tt>true</tt> if the reference must be stored in 4
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *        bytes, or <tt>false</tt> if it must be stored with 2 bytes.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @throws IllegalArgumentException if this label has not been created by
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)     *         the given code writer.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    void put(
2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        final MethodWriter owner,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final ByteVector out,
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        final int source,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final boolean wideOffset)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((status & RESOLVED) == 0) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (wideOffset) {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                addReference(-1 - source, out.length);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                out.putInt(-1);
292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            } else {
293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                addReference(source, out.length);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                out.putShort(-1);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (wideOffset) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                out.putInt(position - source);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                out.putShort(position - source);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Adds a forward reference to this label. This method must be called only
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * for a true forward reference, i.e. only if this label is not resolved
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * yet. For backward references, the offset of the reference can be, and
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * must be, computed and stored directly.
310ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch     *
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @param sourcePosition the position of the referencing instruction. This
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *        position will be used to compute the offset of this forward
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *        reference.
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @param referencePosition the position where the offset for this forward
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *        reference must be stored.
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private void addReference(
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final int sourcePosition,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final int referencePosition)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (srcAndRefPositions == null) {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            srcAndRefPositions = new int[6];
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (referenceCount >= srcAndRefPositions.length) {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int[] a = new int[srcAndRefPositions.length + 6];
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            System.arraycopy(srcAndRefPositions,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    0,
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    a,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    0,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    srcAndRefPositions.length);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            srcAndRefPositions = a;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        srcAndRefPositions[referenceCount++] = sourcePosition;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        srcAndRefPositions[referenceCount++] = referencePosition;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Resolves all forward references to this label. This method must be called
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * when this label is added to the bytecode of the method, i.e. when its
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * position becomes known. This method fills in the blanks that where left
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * in the bytecode by each forward reference previously added to this label.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param owner the code writer that calls this method.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param position the position of this label in the bytecode.
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param data the bytecode of the method.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return <tt>true</tt> if a blank that was left for this label was to
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *         small to store the offset. In such a case the corresponding jump
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *         instruction is replaced with a pseudo instruction (using unused
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *         opcodes) using an unsigned two bytes offset. These pseudo
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *         instructions will need to be replaced with true instructions with
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *         wider offsets (4 bytes instead of 2). This is done in
3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)     *         {@link MethodWriter#resizeInstructions}.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @throws IllegalArgumentException if this label has already been resolved,
3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)     *         or if it has not been created by the given code writer.
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)     */
3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    boolean resolve(
3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        final MethodWriter owner,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final int position,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final byte[] data)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        boolean needUpdate = false;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.status |= RESOLVED;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.position = position;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int i = 0;
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        while (i < referenceCount) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int source = srcAndRefPositions[i++];
3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            int reference = srcAndRefPositions[i++];
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            int offset;
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            if (source >= 0) {
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                offset = position - source;
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) {
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                    /*
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     * changes the opcode of the jump instruction, in order to
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     * be able to find it later (see resizeInstructions in
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     * MethodWriter). These temporary opcodes are similar to
376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     * jump instruction opcodes, except that the 2 bytes offset
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     * is unsigned (and can therefore represent values from 0 to
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     * 65535, which is sufficient since the size of a method is
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     * limited to 65535 bytes).
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     */
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int opcode = data[reference - 1] & 0xFF;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (opcode <= Opcodes.JSR) {
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                        // changes IFEQ ... JSR to opcodes 202 to 217
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        data[reference - 1] = (byte) (opcode + 49);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    } else {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        // changes IFNULL and IFNONNULL to opcodes 218 and 219
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        data[reference - 1] = (byte) (opcode + 20);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    needUpdate = true;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                data[reference++] = (byte) (offset >>> 8);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                data[reference] = (byte) offset;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                offset = position + source + 1;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                data[reference++] = (byte) (offset >>> 24);
396ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                data[reference++] = (byte) (offset >>> 16);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                data[reference++] = (byte) (offset >>> 8);
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                data[reference] = (byte) offset;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return needUpdate;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Returns the first label of the series to which this label belongs. For an
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * isolated label or for the first label in a series of successive labels,
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * this method returns the label itself. For other labels it returns the
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * first label of the series.
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return the first label of the series to which this label belongs.
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Label getFirst() {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return !ClassReader.FRAMES || frame == null ? this : frame.owner;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ------------------------------------------------------------------------
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Methods related to subroutines
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ------------------------------------------------------------------------
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Returns true is this basic block belongs to the given subroutine.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @param id a subroutine id.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return true is this basic block belongs to the given subroutine.
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    boolean inSubroutine(final long id) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((status & Label.VISITED) != 0) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return (srcAndRefPositions[(int) (id >>> 32)] & (int) id) != 0;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        return false;
431ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    }
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Returns true if this basic block and the given one belong to a common
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * subroutine.
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param block another basic block.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return true if this basic block and the given one belong to a common
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *         subroutine.
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    boolean inSameSubroutine(final Label block) {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < srcAndRefPositions.length; ++i) {
4437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            if ((srcAndRefPositions[i] & block.srcAndRefPositions[i]) != 0) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return true;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Marks this basic block as belonging to the given subroutine.
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @param id a subroutine id.
454ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch     * @param nbSubroutines the total number of subroutines in the method.
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void addToSubroutine(final long id, final int nbSubroutines) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((status & VISITED) == 0) {
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            status |= VISITED;
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            srcAndRefPositions = new int[(nbSubroutines - 1) / 32 + 1];
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        srcAndRefPositions[(int) (id >>> 32)] |= (int) id;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Finds the basic blocks that belong to a given subroutine, and marks these
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * blocks as belonging to this subroutine. This recursive method follows the
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * control flow graph to find all the blocks that are reachable from the
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * current block WITHOUT following any JSR target.
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param JSR a JSR block that jumps to this subroutine. If this JSR is not
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *        null it is added to the successor of the RET blocks found in the
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *        subroutine.
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param id the id of this subroutine.
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param nbSubroutines the total number of subroutines in the method.
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void visitSubroutine(final Label JSR, final long id, final int nbSubroutines)
47790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    {
47890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (JSR != null) {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if ((status & VISITED) != 0) {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            status |= VISITED;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // adds JSR to the successors of this block, if it is a RET block
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if ((status & RET) != 0) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (!inSameSubroutine(JSR)) {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Edge e = new Edge();
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    e.info = inputStackTop;
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    e.successor = JSR.successors.successor;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    e.next = successors;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    successors = e;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // if this block already belongs to subroutine 'id', returns
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (inSubroutine(id)) {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            // marks this block as belonging to subroutine 'id'
499ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            addToSubroutine(id, nbSubroutines);
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // calls this method recursively on each successor, except JSR targets
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Edge e = successors;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        while (e != null) {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // if this block is a JSR block, then 'successors.next' leads
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // to the JSR target (see {@link #visitJumpInsn}) and must therefore
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // not be followed
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if ((status & Label.JSR) == 0 || e != successors.next) {
5087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                e.successor.visitSubroutine(JSR, id, nbSubroutines);
5097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            }
5107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            e = e.next;
5117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
5127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
5137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // ------------------------------------------------------------------------
5157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Overriden Object methods
516ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // ------------------------------------------------------------------------
5177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    /**
5197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch     * Returns a string representation of this label.
5207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch     *
5217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch     * @return a string representation of this label.
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public String toString() {
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return "L" + System.identityHashCode(this);
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)