Example usage for org.objectweb.asm.tree InsnList iterator

List of usage examples for org.objectweb.asm.tree InsnList iterator

Introduction

In this page you can find the example usage for org.objectweb.asm.tree InsnList iterator.

Prototype

@Override
public ListIterator<AbstractInsnNode> iterator() 

Source Link

Document

Returns an iterator over the instructions in this list.

Usage

From source file:com.android.tools.lint.checks.ClickableViewAccessibilityDetector.java

License:Apache License

@SuppressWarnings("unchecked") // ASM API
@Nullable/*  www. j av a 2 s  .co m*/
private static AbstractInsnNode findMethodCallInstruction(@NonNull InsnList instructions, @NonNull String owner,
        @NonNull String name, @NonNull String desc) {
    ListIterator<AbstractInsnNode> iterator = instructions.iterator();

    while (iterator.hasNext()) {
        AbstractInsnNode insnNode = iterator.next();
        if (insnNode.getType() == AbstractInsnNode.METHOD_INSN) {
            MethodInsnNode methodInsnNode = (MethodInsnNode) insnNode;
            if ((methodInsnNode.owner.equals(owner)) && (methodInsnNode.name.equals(name))
                    && (methodInsnNode.desc.equals(desc))) {
                return methodInsnNode;
            }
        }
    }

    return null;
}

From source file:com.geeksaga.flow.analysis.Analysis.java

License:Apache License

private static void print(MethodNode method) {
    InsnList instructions = method.instructions;

    ListIterator<AbstractInsnNode> iterator = instructions.iterator();

    while (iterator.hasNext()) {
        AbstractInsnNode n = iterator.next();

        if (n instanceof MethodInsnNode) {
            logger.debug("\t\t{}", insnToString(n));
        }//from ww  w  .j  a  va 2s . c o m

        if (n instanceof FieldInsnNode) {
            logger.debug("\t\t\t{}", insnToString(n));
        }
    }
}

From source file:com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtilTest.java

License:Open Source License

@Test
public void testRewriteGetProxyMethodSignaturesMethodNode() {
    class TestClass {

        @SuppressWarnings("unused")
        public final String[] PROXY_METHOD_SIGNATURES = _getProxyMethodSignatures();

        private String[] _getProxyMethodSignatures() {
            return new String[0];
        }//from ww w  .  j ava  2 s .c o m
    }

    ClassNode classNode = _loadClass(TestClass.class);

    String[] proxyMethodSignatures = { "testSignature1", "testSignature2", "testSignature3" };

    IntrabandProxyUtil.rewriteGetProxyMethodSignaturesMethodNode(classNode, proxyMethodSignatures);

    MethodNode methodNode = ASMUtil.findMethodNode(classNode.methods, "_getProxyMethodSignatures",
            Type.getType(String[].class));

    InsnList insnList = methodNode.instructions;

    Iterator<AbstractInsnNode> iterator = insnList.iterator();

    _assertInsnNode(iterator.next(), Opcodes.ICONST_3);

    _assertTypeInsnNode(iterator.next(), Opcodes.ANEWARRAY, String.class);

    for (int i = 0; i < proxyMethodSignatures.length; i++) {
        _assertInsnNode(iterator.next(), Opcodes.DUP);
        _assertInsnNode(iterator.next(), Opcodes.ICONST_0 + i);
        _assertLdcInsnNode(iterator.next(), Opcodes.LDC, proxyMethodSignatures[i]);
        _assertInsnNode(iterator.next(), Opcodes.AASTORE);
    }

    _assertInsnNode(iterator.next(), Opcodes.ARETURN);

    Assert.assertFalse(iterator.hasNext());
}

From source file:com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtilTest.java

License:Open Source License

private void _doTestCreateProxyMethodNode(Method method, int index, String skeletonId,
        String stubInternalName) {

    MethodNode proxyMethodNode = IntrabandProxyUtil.createProxyMethodNode(method, index, skeletonId,
            Type.getType(stubInternalName));

    _assertMethodNodeSignature(proxyMethodNode, method.getModifiers() & ~Modifier.ABSTRACT, method.getName(),
            Type.getMethodDescriptor(method), method.getExceptionTypes());

    InsnList insnList = proxyMethodNode.instructions;

    Iterator<AbstractInsnNode> iterator = insnList.iterator();

    // NEW com/liferay/portal/kernel/io/Serializer

    _assertTypeInsnNode(iterator.next(), Opcodes.NEW, Serializer.class);

    // DUP/* ww  w. ja  v  a2s  .c  o m*/

    _assertInsnNode(iterator.next(), Opcodes.DUP);

    // INVOKESPECIAL com/liferay/portal/kernel/io/Serializer <init> ()V

    _assertMethodInsnNode(iterator.next(), Opcodes.INVOKESPECIAL, Type.getInternalName(Serializer.class),
            "<init>", Type.VOID_TYPE);

    // ASTORE argumentsSize

    Type methodType = Type.getType(method);

    int argumentsAndReturnSizes = methodType.getArgumentsAndReturnSizes();

    int argumentsSize = argumentsAndReturnSizes >> 2;

    _assertVarInsnNode(iterator.next(), Opcodes.ASTORE, argumentsSize);

    // ALOAD argumentsSize

    _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize);

    // LDC skeletonId

    _assertLdcInsnNode(iterator.next(), Opcodes.LDC, skeletonId);

    // INVOKEVIRTUAL com/liferay/portal/kernel/io/Serializer writeString
    // (Ljava/lang/String;)V

    _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Serializer.class),
            "writeString", Type.VOID_TYPE, Type.getType(String.class));

    // ALOAD argumentsSize

    _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize);

    // ALOAD 0

    _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, 0);

    // GETFIELD stubInternalName _id Ljava/lang/String;

    _assertFieldInsnNode(iterator.next(), Opcodes.GETFIELD, stubInternalName, "_id", String.class);

    // INVOKEVIRTUAL com/liferay/portal/kernel/io/Serializer writeString
    // (Ljava/lang/String;)V

    _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Serializer.class),
            "writeString", Type.VOID_TYPE, Type.getType(String.class));

    // ALOAD argumentsSize

    _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize);

    if (index <= 5) {

        // ICONST_index

        _assertInsnNode(iterator.next(), Opcodes.ICONST_0 + index);
    } else {

        // BIPUSH index

        _assertIntInsnNode(iterator.next(), Opcodes.BIPUSH, index);
    }

    // INVOKEVIRTUAL com/liferay/portal/kernel/io/Serializer writeInt (I)V

    _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Serializer.class),
            "writeInt", Type.VOID_TYPE, Type.INT_TYPE);

    Class<?>[] parameterTypes = method.getParameterTypes();

    int offset = 1;

    for (int i = 0; i < parameterTypes.length; i++) {
        Class<?> parameterClass = parameterTypes[i];

        // ALOAD argumentsSize

        _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize);

        // xLOAD i

        Type parameterType = Type.getType(parameterClass);

        _assertVarInsnNode(iterator.next(), parameterType.getOpcode(Opcodes.ILOAD), offset);

        offset += parameterType.getSize();

        if (parameterClass.isPrimitive() || (parameterClass == String.class)) {

            String name = TextFormatter.format(parameterClass.getSimpleName(), TextFormatter.G);

            _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL,
                    Type.getInternalName(Serializer.class), "write".concat(name), Type.VOID_TYPE,
                    parameterType);
        } else {
            _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL,
                    Type.getInternalName(Serializer.class), "writeObject", Type.VOID_TYPE,
                    Type.getType(Serializable.class));
        }
    }

    // ALOAD 0

    _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, 0);

    // ALOAD argumentsSize

    _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize);

    Class<?> returnClass = method.getReturnType();

    Type returnType = Type.getType(returnClass);

    if (returnClass == void.class) {

        // INVOKESPECIAL stubInternalName _send
        // (Lcom/liferay/portal/kernel/io/Serializer;)V

        _assertMethodInsnNode(iterator.next(), Opcodes.INVOKESPECIAL, stubInternalName, "_send", Type.VOID_TYPE,
                Type.getType(Serializer.class));

        _assertInsnNode(iterator.next(), Opcodes.RETURN);
    } else {

        // INVOKESPECIAL stubInternalName _syncSend
        // (Lcom/liferay/portal/kernel/io/Serializer;)Ljava/io/Serializable;

        _assertMethodInsnNode(iterator.next(), Opcodes.INVOKESPECIAL, stubInternalName, "_syncSend",
                Type.getType(Serializable.class), Type.getType(Serializer.class));

        if (returnClass.isPrimitive()) {

            // ASTORE argumentsSize + 1

            _assertVarInsnNode(iterator.next(), Opcodes.ASTORE, argumentsSize + 1);

            // ALOAD argumentsSize + 1

            _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize + 1);

            // IFNULL nullCheckLabel

            LabelNode nullCheckLabelNode = _assertJumpInsnNode(iterator.next(), Opcodes.IFNULL);

            // ALOAD argumentsSize + 1

            _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize + 1);

            // CHECKCAST returnType

            _assertTypeInsnNode(iterator.next(), Opcodes.CHECKCAST, _autoboxingMap.get(returnClass));

            if (returnClass == boolean.class) {

                // INVOKEVIRTUAL java/lang/Boolean booleanValue ()Z

                _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL,
                        Type.getInternalName(Boolean.class), "booleanValue", Type.BOOLEAN_TYPE);
            } else if (returnClass == byte.class) {

                // INVOKEVIRTUAL java/lang/Number intValue ()I

                _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL,
                        Type.getInternalName(Number.class), "intValue", Type.INT_TYPE);
            } else if (returnClass == char.class) {

                // INVOKEVIRTUAL java/lang/Character charValue ()C

                _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL,
                        Type.getInternalName(Character.class), "charValue", Type.CHAR_TYPE);
            } else if (returnClass == double.class) {

                // INVOKEVIRTUAL java/lang/Number doubleValue ()D

                _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL,
                        Type.getInternalName(Number.class), "doubleValue", Type.DOUBLE_TYPE);
            } else if (returnClass == float.class) {

                // INVOKEVIRTUAL java/lang/Number floatValue ()F

                _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL,
                        Type.getInternalName(Number.class), "floatValue", Type.FLOAT_TYPE);
            } else if (returnClass == int.class) {

                // INVOKEVIRTUAL java/lang/Number intValue ()I

                _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL,
                        Type.getInternalName(Number.class), "intValue", Type.INT_TYPE);
            } else if (returnClass == long.class) {

                // INVOKEVIRTUAL java/lang/Number longValue ()J

                _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL,
                        Type.getInternalName(Number.class), "longValue", Type.LONG_TYPE);
            } else if (returnClass == short.class) {

                // INVOKEVIRTUAL java/lang/Number intValue ()I

                _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL,
                        Type.getInternalName(Number.class), "intValue", Type.INT_TYPE);
            }

            // xRETURN

            _assertInsnNode(iterator.next(), returnType.getOpcode(Opcodes.IRETURN));

            // nullCheckLabel

            Assert.assertSame(nullCheckLabelNode, iterator.next());

            // xRETURN null/0

            if (!returnClass.isPrimitive()) {
                _assertInsnNode(iterator.next(), Opcodes.ACONST_NULL);
                _assertInsnNode(iterator.next(), Opcodes.ARETURN);
            } else if (returnClass == void.class) {
                _assertInsnNode(iterator.next(), Opcodes.RETURN);
            } else if (returnClass == float.class) {
                _assertInsnNode(iterator.next(), Opcodes.FCONST_0);
                _assertInsnNode(iterator.next(), Opcodes.FRETURN);
            } else if (returnClass == double.class) {
                _assertInsnNode(iterator.next(), Opcodes.DCONST_0);
                _assertInsnNode(iterator.next(), Opcodes.DRETURN);
            } else if (returnClass == long.class) {
                _assertInsnNode(iterator.next(), Opcodes.LCONST_0);
                _assertInsnNode(iterator.next(), Opcodes.LRETURN);
            } else {
                _assertInsnNode(iterator.next(), Opcodes.ICONST_0);
                _assertInsnNode(iterator.next(), Opcodes.IRETURN);
            }
        } else {
            if (returnClass != Object.class) {

                // CHECKCAST

                _assertTypeInsnNode(iterator.next(), Opcodes.CHECKCAST, returnClass);
            }

            // ARETURN

            _assertInsnNode(iterator.next(), Opcodes.ARETURN);
        }
    }

    Assert.assertFalse(iterator.hasNext());
}

From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java

License:Open Source License

/**
 * Clones an instruction list. All labels are remapped unless otherwise specified in {@code globalLabels}.
 * @param insnList instruction list to clone
 * @param globalLabels set of labels that should not be remapped
 * @throws NullPointerException if any argument is {@code null}
 * @return instruction list with cloned instructions
 *///from   ww  w  .j  a va 2 s . co  m
public static InsnList cloneInsnList(InsnList insnList, Set<LabelNode> globalLabels) {
    Validate.notNull(insnList);

    // remap all labelnodes
    Map<LabelNode, LabelNode> labelNodeMapping = new HashMap<>();
    ListIterator<AbstractInsnNode> it = insnList.iterator();
    while (it.hasNext()) {
        AbstractInsnNode abstractInsnNode = it.next();
        if (abstractInsnNode instanceof LabelNode) {
            LabelNode existingLabelNode = (LabelNode) abstractInsnNode;
            labelNodeMapping.put(existingLabelNode, new LabelNode());
        }
    }

    // override remapping such that global labels stay the same
    for (LabelNode globalLabel : globalLabels) {
        labelNodeMapping.put(globalLabel, globalLabel);
    }

    // clone
    InsnList ret = new InsnList();
    it = insnList.iterator();
    while (it.hasNext()) {
        AbstractInsnNode abstractInsnNode = it.next();
        ret.add(abstractInsnNode.clone(labelNodeMapping));
    }

    return ret;
}

From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtils.java

License:Open Source License

/**
 * Find invocations of a certain method.
 * @param insnList instruction list to search through
 * @param expectedMethod type of method being invoked
 * @return list of invocations (may be nodes of type {@link MethodInsnNode} or {@link InvokeDynamicInsnNode})
 * @throws NullPointerException if any argument is {@code null}
 * @throws NullPointerException if {@code expectedMethodType} isn't of sort {@link Type#METHOD}
 *///from   w w  w.j a v  a  2 s.  com
public static List<AbstractInsnNode> findInvocationsOf(InsnList insnList, Method expectedMethod) {
    Validate.notNull(insnList);
    Validate.notNull(expectedMethod);

    List<AbstractInsnNode> ret = new ArrayList<>();

    Type expectedMethodDesc = Type.getType(expectedMethod);
    Type expectedMethodOwner = Type.getType(expectedMethod.getDeclaringClass());
    String expectedMethodName = expectedMethod.getName();

    Iterator<AbstractInsnNode> it = insnList.iterator();
    while (it.hasNext()) {
        AbstractInsnNode instructionNode = it.next();

        Type methodDesc;
        Type methodOwner;
        String methodName;
        if (instructionNode instanceof MethodInsnNode) {
            MethodInsnNode methodInsnNode = (MethodInsnNode) instructionNode;
            methodDesc = Type.getType(methodInsnNode.desc);
            methodOwner = Type.getObjectType(methodInsnNode.owner);
            methodName = expectedMethod.getName();
        } else {
            continue;
        }

        if (methodDesc.equals(expectedMethodDesc) && methodOwner.equals(expectedMethodOwner)
                && methodName.equals(expectedMethodName)) {
            ret.add(instructionNode);
        }
    }

    return ret;
}

From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtils.java

License:Open Source License

/**
 * Find invocations of any method where the parameter list contains a type.
 * @param insnList instruction list to search through
 * @param expectedParamType parameter type
 * @return list of invocations (may be nodes of type {@link MethodInsnNode} or {@link InvokeDynamicInsnNode})
 * @throws NullPointerException if any argument is {@code null}
 * @throws IllegalArgumentException if {@code expectedParamType} is either of sort {@link Type#METHOD} or {@link Type#VOID}
 *///w  w w.  j a  v  a2s  .  c o  m
public static List<AbstractInsnNode> findInvocationsWithParameter(InsnList insnList, Type expectedParamType) {
    Validate.notNull(insnList);
    Validate.notNull(expectedParamType);
    Validate.isTrue(expectedParamType.getSort() != Type.METHOD && expectedParamType.getSort() != Type.VOID);

    List<AbstractInsnNode> ret = new ArrayList<>();

    Iterator<AbstractInsnNode> it = insnList.iterator();
    while (it.hasNext()) {
        AbstractInsnNode instructionNode = it.next();
        Type[] methodParamTypes;
        if (instructionNode instanceof MethodInsnNode) {
            MethodInsnNode methodInsnNode = (MethodInsnNode) instructionNode;
            Type methodType = Type.getType(methodInsnNode.desc);
            methodParamTypes = methodType.getArgumentTypes();
        } else if (instructionNode instanceof InvokeDynamicInsnNode) {
            InvokeDynamicInsnNode invokeDynamicInsnNode = (InvokeDynamicInsnNode) instructionNode;
            Type methodType = Type.getType(invokeDynamicInsnNode.desc);
            methodParamTypes = methodType.getArgumentTypes();
        } else {
            continue;
        }

        if (Arrays.asList(methodParamTypes).contains(expectedParamType)) {
            ret.add(instructionNode);
        }
    }

    return ret;
}

From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtils.java

License:Open Source License

/**
 * Find instructions in a certain class that are of a certain set of opcodes.
 * @param insnList instruction list to search through
 * @param opcodes opcodes to search for/*from   w  w  w .  j  a  va  2  s  . co  m*/
 * @return list of instructions that contain the opcodes being searched for
 * @throws NullPointerException if any argument is {@code null}
 * @throws IllegalArgumentException if {@code opcodes} is empty
 */
public static List<AbstractInsnNode> searchForOpcodes(InsnList insnList, int... opcodes) {
    Validate.notNull(insnList);
    Validate.notNull(opcodes);
    Validate.isTrue(opcodes.length > 0);

    List<AbstractInsnNode> ret = new LinkedList<>();

    Set<Integer> opcodeSet = new HashSet<>();
    Arrays.stream(opcodes).forEach((x) -> opcodeSet.add(x));

    Iterator<AbstractInsnNode> it = insnList.iterator();
    while (it.hasNext()) {
        AbstractInsnNode insnNode = it.next();
        if (opcodeSet.contains(insnNode.getOpcode())) {
            ret.add(insnNode);
        }
    }

    return ret;
}

From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtils.java

License:Open Source License

/**
 * Find trycatch blocks within a method that an instruction is apart of. Only includes the try portion, not the catch (handler) portion.
 * @param insnList instruction list for method
 * @param tryCatchBlockNodes trycatch blocks in method
 * @param insnNode instruction within method being searched against
 * @throws NullPointerException if any argument is {@code null} or contains {@code null}
 * @throws IllegalArgumentException if arguments aren't all from the same method
 * @return items from {@code tryCatchBlockNodes} that {@code insnNode} is a part of
 *///  ww  w.j a v  a2 s .c o m
public static List<TryCatchBlockNode> findTryCatchBlockNodesEncompassingInstruction(InsnList insnList,
        List<TryCatchBlockNode> tryCatchBlockNodes, AbstractInsnNode insnNode) {
    Validate.notNull(insnList);
    Validate.notNull(tryCatchBlockNodes);
    Validate.notNull(insnNode);
    Validate.noNullElements(tryCatchBlockNodes);

    Map<LabelNode, Integer> labelPositions = new HashMap<>();
    int insnNodeIdx = -1;

    // Get index of labels and insnNode within method
    ListIterator<AbstractInsnNode> insnIt = insnList.iterator();
    int insnCounter = 0;
    while (insnIt.hasNext()) {
        AbstractInsnNode node = insnIt.next();

        // If our instruction, save index
        if (node == insnNode) {
            if (insnNodeIdx == -1) {
                insnNodeIdx = insnCounter;
            } else {
                throw new IllegalArgumentException(); // insnNode encountered multiple times in methodNode. Should not happen.
            }
        }

        // If label node, save position
        if (node instanceof LabelNode) {
            labelPositions.put((LabelNode) node, insnCounter);
        }

        // Increment counter
        insnCounter++;
    }

    Validate.isTrue(insnNodeIdx != -1); //throw exception if node not in method list

    // Find out which trycatch blocks insnNode is within
    List<TryCatchBlockNode> ret = new ArrayList<>();
    for (TryCatchBlockNode tryCatchBlockNode : tryCatchBlockNodes) {
        Integer startIdx = labelPositions.get(tryCatchBlockNode.start);
        Integer endIdx = labelPositions.get(tryCatchBlockNode.end);

        Validate.isTrue(startIdx != null);
        Validate.isTrue(endIdx != null);

        if (insnNodeIdx >= startIdx && insnNodeIdx < endIdx) {
            ret.add(tryCatchBlockNode);
        }
    }

    return ret;
}

From source file:com.sun.tdk.jcov.instrument.BlockCodeMethodAdapter.java

License:Open Source License

private SimpleBasicBlock[] completeComputationOfCodeLabelNodes() {
    MethodNode methodNode = (MethodNode) mv;
    InsnList instructions = methodNode.instructions;
    int[] allToReal = new int[instructions.size()];
    int allIdx = 0;
    int insnIdx = 0;
    ListIterator iit = instructions.iterator();

    // Create the method entry block and basic block
    AbstractInsnNode insnFirst = peek(iit);
    SimpleBasicBlock bbFirst = getBB(insnFirst, 0);
    // DataBlock blockFirst = new DataBlockMethEnter();
    // bbFirst.add(blockFirst);

    while (iit.hasNext()) {
        AbstractInsnNode insn = (AbstractInsnNode) iit.next();
        allToReal[allIdx++] = insnIdx;//w  w  w . jav a2s  . com
        int bci = bcis[insnIdx];
        int opcode = insn.getOpcode();
        if (opcode < 0) {
            // a pseudo-instruction
            if (insn.getType() == AbstractInsnNode.LINE) {
                LineNumberNode lineNode = (LineNumberNode) insn;
                method().addLineEntry(bci, lineNode.line);
            }
        } else {
            // a real instruction
            ++insnIdx; // advance the real instruction index

            //System.out.println( "#" + (insnIdx - 1) +
            //        " bci: " + bci + "  " +
            //        instr.toString().replace("org.objectweb.asm.tree.", "").replace("@", " @ ") +
            //        " [" + (opcode>=0? Constants.opcNames[opcode] : " pseudo") +"]");
            switch (opcode) {
            case IFEQ:
            case IFNE:
            case IFLT:
            case IFGE:
            case IFGT:
            case IFLE:
            case IF_ICMPEQ:
            case IF_ICMPNE:
            case IF_ICMPLT:
            case IF_ICMPGE:
            case IF_ICMPGT:
            case IF_ICMPLE:
            case IF_ACMPEQ:
            case IF_ACMPNE:
            case IFNULL:
            case IFNONNULL:
            case JSR: {
                JumpInsnNode jumpInsn = (JumpInsnNode) insn;
                LabelNode insnTrue = jumpInsn.label;
                int bciFalse = bcis[insnIdx]; // fall-through

                DataBranchCond branch = new DataBranchCond(method.rootId, bci, bciFalse - 1);
                /* DataBlockTarget blockTrue = new DataBlockTargetCond(true);
                 DataBlockTarget blockFalse = new DataBlockTargetCond(false);
                 branch.addTarget(blockTrue);
                 branch.addTarget(blockFalse);
                 */
                AbstractInsnNode insnFalse = peek(iit);
                assert (insnFalse != null); // must be fall-through code
                SimpleBasicBlock bbTrue = getBB(insnTrue);
                SimpleBasicBlock bbFalse = getBB(insnFalse, bciFalse);

                exits.add(branch);

                // assign a new label for branch counting
                // LabelNode nlab = new LabelNode();
                // jumpInsn.label = nlab;  // branch to new label
                //  bbTrue.add(blockTrue, nlab);

                //bbFalse.add(blockFalse);
                break;
            }

            case TABLESWITCH: {
                TableSwitchInsnNode switchInsn = (TableSwitchInsnNode) insn;

                // Create a block and basic-block the "default:" case
                LabelNode insnDflt = switchInsn.dflt;
                SimpleBasicBlock bbDefault = getBB(insnDflt);
                DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId());

                // assign a new default label for branch counting
                //LabelNode nlab = new LabelNode();
                //switchInsn.dflt = nlab;  // branch to new label
                //bbDefault.add(blockDefault, nlab);

                // Create the branch information
                int bciEnd = bcis[insnIdx] - 1; // end of the switch
                DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault);
                // branch.addTarget(blockDefault);
                exits.add(branch);

                // Process the other cases
                ListIterator lit = switchInsn.labels.listIterator();
                int key = switchInsn.min;
                while (lit.hasNext()) {
                    // Create a block and basic-block the case
                    LabelNode labCase = (LabelNode) lit.next();
                    SimpleBasicBlock bbCase = getBB(labCase);
                    //DataBlockTargetCase blockCase = new DataBlockTargetCase(key++);
                    //branch.addTarget(blockCase);

                    // assign a new label to the case for branch counting
                    //nlab = new LabelNode();
                    //  lit.set(nlab);
                    // bbCase.add(blockCase, nlab);
                }
                break;
            }

            case LOOKUPSWITCH: {
                LookupSwitchInsnNode switchInsn = (LookupSwitchInsnNode) insn;

                // Create a block and basic-block the "default:" case
                LabelNode insnDflt = switchInsn.dflt;
                SimpleBasicBlock bbDefault = getBB(insnDflt);
                DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId());

                // assign a new default label for branch counting
                // LabelNode nlab = new LabelNode();
                // switchInsn.dflt = nlab;  // branch to new label
                // bbDefault.add(blockDefault, nlab);

                // Create the branch information
                int bciEnd = bcis[insnIdx] - 1; // end of the switch
                DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault);
                // branch.addTarget(blockDefault);
                exits.add(branch);

                // Process the other cases
                ListIterator kit = switchInsn.keys.listIterator();
                ListIterator lit = switchInsn.labels.listIterator();
                while (lit.hasNext()) {
                    // Create a block and basic-block the case
                    LabelNode labCase = (LabelNode) lit.next();
                    SimpleBasicBlock bbCase = getBB(labCase);
                    Integer key = (Integer) kit.next();
                    //                            DataBlockTargetCase blockCase = new DataBlockTargetCase(key.intValue());
                    // branch.addTarget(blockCase);

                    // assign a new label to the case for branch counting
                    //nlab = new LabelNode();
                    //lit.set(nlab);
                    //bbCase.add(blockCase, nlab);
                }
                break;
            }

            case GOTO: {
                JumpInsnNode jumpInsn = (JumpInsnNode) insn;

                // Create origin info, a branch
                int bciEnd = bcis[insnIdx] - 1;
                DataBranchGoto branch = new DataBranchGoto(method.rootId, bci, bciEnd);
                exits.add(branch);

                // Create destination info, a block target
                LabelNode insnTarget = jumpInsn.label;
                SimpleBasicBlock bbTarget = getBB(insnTarget);
                //DataBlockTarget blockTarget = new DataBlockTargetGoto();
                //branch.addTarget(blockTarget);

                // assign a new label for branch counting
                //LabelNode nlab = new LabelNode();
                //jumpInsn.label = nlab;  // branch to new label
                //bbTarget.add(blockTarget, nlab);
                break;
            }
            case ATHROW:
            case RET:
            case IRETURN:
            case LRETURN:
            case FRETURN:
            case DRETURN:
            case ARETURN:
            case RETURN: {
                int bciNext = bcis[insnIdx];
                DataExit exit = new DataExitSimple(method.rootId, bci, bciNext - 1, insn.getOpcode());
                exits.add(exit);

                AbstractInsnNode insnNext = peek(iit);
                if (insnNext != null) {
                    // If there is code after this, it has to be the start of a
                    // new basic block
                    getBB(insnNext, bciNext);
                }
                break;
            }
            default:
                break;
            }
            // try add src block
        }
    }

    // Now go through the try-catch blocks
    LabelNode previousHandler = null;
    for (Iterator tbit = methodNode.tryCatchBlocks.iterator(); tbit.hasNext();) {
        TryCatchBlockNode tcbn = (TryCatchBlockNode) tbit.next();
        LabelNode insnHandler = tcbn.handler;
        if (insnHandler != previousHandler) {
            previousHandler = insnHandler;

            // Create destination info, a block target
            SimpleBasicBlock bbCatch = getBB(insnHandler);

        }
    }

    if (method().getCharacterRangeTable() != null) {
        boolean newBlock = true;
        int skip = 0;
        iit = instructions.iterator();
        while (iit.hasNext()) {
            AbstractInsnNode insn = (AbstractInsnNode) iit.next();
            int index = instructions.indexOf(insn);
            int bci = bcis[allToReal[index]];
            if (bci == skip) {
                continue;
            }

            if (insnToBB.get(insn) != null) {
                skip = bcis[allToReal[instructions.indexOf(insn)]];
            }

            if (insn.getOpcode() < 0) {
                continue;
            }

            for (CharacterRangeTableAttribute.CRTEntry entry : method().getCharacterRangeTable().getEntries()) {
                if (entry.startBCI() == bci) {

                    if ((entry.flags & CRTEntry.CRT_STATEMENT) != 0 /*& newBlock*/) {
                        newBlock = false;
                        if (insnToBB.get(insn) == null) {
                            //System.out.println("Should add block at: " + bci + " in " + method().name +
                            //       " for " + Constants.opcNames[insn.getOpcode()]);
                            getBB(insn);
                            break;
                        }
                    }
                } else {
                    if (entry.endBCI() == index && (entry.flags & CRTEntry.CRT_FLOW_TARGET) != 0) {
                        newBlock = true;
                    }
                }

            }
        }

    }

    // Compute the startBCI for any basic blocks that don't have it'
    SimpleBasicBlock[] basicBlocks = new SimpleBasicBlock[insnToBB.size()];
    int i = 0;
    for (Map.Entry<AbstractInsnNode, SimpleBasicBlock> entry : insnToBB.entrySet()) {
        SimpleBasicBlock bb = entry.getValue();
        if (bb.startBCI() < 0) {
            AbstractInsnNode insn = entry.getKey();
            int index = instructions.indexOf(insn);
            int bci = bcis[allToReal[index]];
            bb.setStartBCI(bci);
        }
        basicBlocks[i++] = bb;
    }
    Arrays.sort(basicBlocks);

    return basicBlocks;
}