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

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

Introduction

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

Prototype

public int indexOf(final AbstractInsnNode insnNode) 

Source Link

Document

Returns the index of the given instruction in this list.

Usage

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

License:Apache License

@Nullable
private String findFirstArgType(ClassContext context, ClassNode classNode, MethodNode method,
        MethodInsnNode call) {//  ww  w.  java2  s  .co  m
    // Find object being passed in as the first argument
    Analyzer analyzer = new Analyzer(new SourceInterpreter() {
        @Override
        public SourceValue newOperation(AbstractInsnNode insn) {
            if (insn.getOpcode() == Opcodes.NEW) {
                String desc = ((TypeInsnNode) insn).desc;
                return new TypeValue(1, desc);
            }
            return super.newOperation(insn);
        }

        @Override
        public SourceValue newValue(Type type) {
            if (type != null && type.getSort() == Type.VOID) {
                return null;
            } else if (type != null) {
                return new TypeValue(1, type.getInternalName());
            }
            return super.newValue(type);
        }

        @Override
        public SourceValue copyOperation(AbstractInsnNode insn, SourceValue value) {
            return value;
        }
    });
    try {
        Frame[] frames = analyzer.analyze(classNode.name, method);
        InsnList instructions = method.instructions;
        Frame frame = frames[instructions.indexOf(call)];
        if (frame.getStackSize() <= 1) {
            return null;
        }
        SourceValue stackValue = (SourceValue) frame.getStack(1);
        if (stackValue instanceof TypeValue) {
            return ((TypeValue) stackValue).getFqcn();
        }
    } catch (AnalyzerException e) {
        context.log(e, null);
    }

    return null;
}

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

License:Apache License

@Override
public void checkCall(@NonNull ClassContext context, @NonNull ClassNode classNode, @NonNull MethodNode method,
        @NonNull MethodInsnNode call) {/* w  w w. j  a v a2 s.  c o  m*/
    String owner = call.owner;
    String desc = call.desc;
    String name = call.name;
    if (owner.equals(DATE_FORMAT_OWNER)) {
        if (!name.equals(CONSTRUCTOR_NAME)) {
            return;
        }
        if (desc.equals("(Ljava/lang/String;Ljava/text/DateFormatSymbols;)V") //$NON-NLS-1$
                || desc.equals("()V") //$NON-NLS-1$
                || desc.equals("(Ljava/lang/String;)V")) { //$NON-NLS-1$
            Location location = context.getLocation(call);
            String message = "To get local formatting use getDateInstance(), getDateTimeInstance(), "
                    + "or getTimeInstance(), or use new SimpleDateFormat(String template, "
                    + "Locale locale) with for example Locale.US for ASCII dates.";
            context.report(DATE_FORMAT, method, call, location, message, null);
        }
        return;
    } else if (!owner.equals(STRING_OWNER)) {
        return;
    }

    if (name.equals(FORMAT_METHOD)) {
        // Only check the non-locale version of String.format
        if (!desc.equals("(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;")) { //$NON-NLS-1$
            return;
        }
        // Find the formatting string
        Analyzer analyzer = new Analyzer(new SourceInterpreter() {
            @Override
            public SourceValue newOperation(AbstractInsnNode insn) {
                if (insn.getOpcode() == Opcodes.LDC) {
                    Object cst = ((LdcInsnNode) insn).cst;
                    if (cst instanceof String) {
                        return new StringValue(1, (String) cst);
                    }
                }
                return super.newOperation(insn);
            }
        });
        try {
            Frame[] frames = analyzer.analyze(classNode.name, method);
            InsnList instructions = method.instructions;
            Frame frame = frames[instructions.indexOf(call)];
            if (frame.getStackSize() == 0) {
                return;
            }
            SourceValue stackValue = (SourceValue) frame.getStack(0);
            if (stackValue instanceof StringValue) {
                String format = ((StringValue) stackValue).getString();
                if (format != null && StringFormatDetector.isLocaleSpecific(format)) {
                    Location location = context.getLocation(call);
                    String message = "Implicitly using the default locale is a common source of bugs: "
                            + "Use String.format(Locale, ...) instead";
                    context.report(STRING_LOCALE, method, call, location, message, null);
                }
            }
        } catch (AnalyzerException e) {
            context.log(e, null);
        }
    } else {
        if (desc.equals("()Ljava/lang/String;")) { //$NON-NLS-1$
            Location location = context.getLocation(call);
            String message = String.format("Implicitly using the default locale is a common source of bugs: "
                    + "Use %1$s(Locale) instead", name);
            context.report(STRING_LOCALE, method, call, location, message, null);
        }
    }
}

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

License:Apache License

@Override
public void checkCall(@NonNull ClassContext context, @NonNull ClassNode classNode, @NonNull MethodNode method,
        @NonNull MethodInsnNode call) {/*w  w w  .  ja  v a2s  .  c o  m*/
    String owner = call.owner;
    String desc = call.desc;
    if (owner.equals(OWNER_SECURE_RANDOM)) {
        if (desc.startsWith(LONG_ARG)) {
            checkValidSetSeed(context, call);
        } else if (desc.startsWith("([B)")) { //$NON-NLS-1$
            // setSeed(byte[]) ...
            // We could do some flow analysis here to see whether the byte array getting
            // passed in appears to be fixed.
            // However, people calling this constructor rather than the simpler one
            // with a fixed integer are probably less likely to make that mistake... right?
        }
    } else if (owner.equals(OWNER_RANDOM) && desc.startsWith(LONG_ARG)) {
        // Called setSeed(long) on an instanceof a Random object. Flag this if the instance
        // is likely a SecureRandom.

        // Track allocations such that we know whether the type of the call
        // is on a SecureRandom rather than a Random
        Analyzer analyzer = new Analyzer(new BasicInterpreter() {
            @Override
            public BasicValue newValue(Type type) {
                if (type != null && type.getDescriptor().equals(VM_SECURE_RANDOM)) {
                    return new BasicValue(type);
                }
                return super.newValue(type);
            }
        });
        try {
            Frame[] frames = analyzer.analyze(classNode.name, method);
            InsnList instructions = method.instructions;
            Frame frame = frames[instructions.indexOf(call)];
            int stackSlot = frame.getStackSize();
            for (Type type : Type.getArgumentTypes(desc)) {
                stackSlot -= type.getSize();
            }
            BasicValue stackValue = (BasicValue) frame.getStack(stackSlot);
            Type type = stackValue.getType();
            if (type != null && type.getDescriptor().equals(VM_SECURE_RANDOM)) {
                checkValidSetSeed(context, call);
            }
        } catch (AnalyzerException e) {
            context.log(e, null);
        }
    } else if (owner.equals(OWNER_RANDOM) && desc.startsWith(LONG_ARG)) {
        // Called setSeed(long) on an instanceof a Random object. Flag this if the instance
        // is likely a SecureRandom.
        // TODO
    }
}

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

License:Apache License

@Override
public void checkCall(@NonNull ClassContext context, @NonNull ClassNode classNode, @NonNull MethodNode method,
        @NonNull MethodInsnNode call) {//from   www  . j a  v a2  s. c o m
    // The leak behavior is fixed in ICS:
    // http://code.google.com/p/android/issues/detail?id=18273
    if (context.getMainProject().getMinSdk() >= 14) {
        return;
    }

    String owner = call.owner;
    String desc = call.desc;
    if (owner.equals("android/view/View") //$NON-NLS-1$
            && desc.equals("(ILjava/lang/Object;)V")) { //$NON-NLS-1$
        Analyzer analyzer = new Analyzer(new BasicInterpreter() {
            @Override
            public BasicValue newValue(Type type) {
                if (type == null) {
                    return BasicValue.UNINITIALIZED_VALUE;
                } else if (type.getSort() == Type.VOID) {
                    return null;
                } else {
                    return new BasicValue(type);
                }
            }
        });
        try {
            Frame[] frames = analyzer.analyze(classNode.name, method);
            InsnList instructions = method.instructions;
            Frame frame = frames[instructions.indexOf(call)];
            if (frame.getStackSize() < 3) {
                return;
            }
            BasicValue stackValue = (BasicValue) frame.getStack(2);
            Type type = stackValue.getType();
            if (type == null) {
                return;
            }

            String internalName = type.getInternalName();
            String className = type.getClassName();
            LintDriver driver = context.getDriver();

            SdkInfo sdkInfo = context.getClient().getSdkInfo(context.getMainProject());
            String objectType = null;
            while (className != null) {
                if (className.equals("android.view.View")) { //$NON-NLS-1$
                    objectType = "views";
                    break;
                } else if (className.endsWith("ViewHolder")) { //$NON-NLS-1$
                    objectType = "view holders";
                    break;
                } else if (className.endsWith("Cursor") //$NON-NLS-1$
                        && className.startsWith("android.")) { //$NON-NLS-1$
                    objectType = "cursors";
                    break;
                }

                // TBD: Bitmaps, drawables? That's tricky, because as explained in
                // http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html
                // apparently these are used along with nulling out the callbacks,
                // and that's harder to detect here

                String parent = sdkInfo.getParentViewClass(className);
                if (parent == null) {
                    if (internalName == null) {
                        internalName = className.replace('.', '/');
                    }
                    assert internalName != null;
                    parent = driver.getSuperClass(internalName);
                }
                className = parent;
                internalName = null;
            }

            if (objectType != null) {
                Location location = context.getLocation(call);
                String message = String.format("Avoid setting %1$s as values for setTag: "
                        + "Can lead to memory leaks in versions older than Android 4.0", objectType);
                context.report(ISSUE, method, call, location, message, null);
            }
        } catch (AnalyzerException e) {
            context.log(e, null);
        }
    }
}

From source file:com.lodgon.parboiled.transform.InstructionGroupCreator.java

License:Open Source License

private void sort(InstructionGroup group) {
    final InsnList instructions = method.instructions;
    Collections.sort(group.getNodes(), new Comparator<InstructionGraphNode>() {
        public int compare(InstructionGraphNode a, InstructionGraphNode b) {
            return Integer.valueOf(instructions.indexOf(a.getInstruction()))
                    .compareTo(instructions.indexOf(b.getInstruction()));
        }// www .  j a v a2  s . co  m
    });
}

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

License:Open Source License

/**
 * Find line number associated with an instruction.
 * @param insnList instruction list for 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 line number node associated with the instruction, or {@code null} if no line number exists
 */// w w w.ja v  a  2s .  c om
public static LineNumberNode findLineNumberForInstruction(InsnList insnList, AbstractInsnNode insnNode) {
    Validate.notNull(insnList);
    Validate.notNull(insnNode);

    int idx = insnList.indexOf(insnNode);
    Validate.isTrue(idx != -1);

    // Get index of labels and insnNode within method
    ListIterator<AbstractInsnNode> insnIt = insnList.iterator(idx);
    while (insnIt.hasPrevious()) {
        AbstractInsnNode node = insnIt.previous();

        if (node instanceof LineNumberNode) {
            return (LineNumberNode) node;
        }
    }

    return null;
}

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  ww  .  j ava 2 s. c om
        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;
}

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

License:Open Source License

/**
 * Do fix ups so that: There are unique CodeLabelNodes at the beginning of
 * each basic block; All branch-mode blocks hang off CodeLabelNodes Misc
 * info, like case values, are attached Fall throughs from one block to
 * another are computed//  w w  w .  java  2  s. c  o  m
 *
 */
private BasicBlock[] 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);
    BasicBlock bbFirst = getBB(insnFirst, 0);
    DataBlock blockFirst = new DataBlockMethEnter(bbFirst.rootId());
    bbFirst.add(blockFirst);

    while (iit.hasNext()) {
        AbstractInsnNode insn = (AbstractInsnNode) iit.next();
        allToReal[allIdx++] = insnIdx;
        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(branch.rootId(), true);
                DataBlockTarget blockFalse = new DataBlockTargetCond(branch.rootId(), false);
                branch.addTarget(blockTrue);
                branch.addTarget(blockFalse);

                AbstractInsnNode insnFalse = peek(iit);
                assert (insnFalse != null); // must be fall-through code
                BasicBlock bbTrue = getBB(insnTrue);
                BasicBlock 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;
                BasicBlock 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();
                    BasicBlock bbCase = getBB(labCase);
                    DataBlockTargetCase blockCase = new DataBlockTargetCase(bbCase.rootId(), 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;
                BasicBlock 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();
                    BasicBlock bbCase = getBB(labCase);
                    Integer key = (Integer) kit.next();
                    DataBlockTargetCase blockCase = new DataBlockTargetCase(branch.rootId(), 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;
                BasicBlock bbTarget = getBB(insnTarget);
                DataBlockTarget blockTarget = new DataBlockTargetGoto(bbTarget.rootId());
                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
            BasicBlock bbCatch = getBB(insnHandler);
            DataBlockCatch blockCatch = new DataBlockCatch(bbCatch.rootId());

            // assign a new label for catch counting
            LabelNode nlab = new LabelNode();
            tcbn.handler = nlab; // change handler
            bbCatch.add(blockCatch, nlab);
        }
    }
    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'
    BasicBlock[] basicBlocks = new BasicBlock[insnToBB.size()];
    int i = 0;
    for (Map.Entry<AbstractInsnNode, BasicBlock> entry : insnToBB.entrySet()) {
        BasicBlock 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;
}

From source file:edu.mit.streamjit.util.bytecode.MethodResolver.java

License:Open Source License

private void findBlockBoundaries() {
    InsnList insns = methodNode.instructions;
    //We find the indices of any block-ending instruction and of any jump
    //target, sort, remove duplicates, then use pairs to define blocks. Note
    //these are end-exclusive indices, thus one after the block-enders, but
    //right on the jump targets (they're one-past-the-end of the preceding
    //block).//from w  w  w .  jav  a2s. com
    List<Integer> indices = new ArrayList<>();
    indices.add(0);
    for (int i = 0; i < insns.size(); ++i) {
        AbstractInsnNode insn = insns.get(i);
        int opcode = insn.getOpcode();
        //Terminator opcodes end blocks.
        if (insn instanceof JumpInsnNode || insn instanceof LookupSwitchInsnNode
                || insn instanceof TableSwitchInsnNode || opcode == Opcodes.ATHROW || opcode == Opcodes.IRETURN
                || opcode == Opcodes.LRETURN || opcode == Opcodes.FRETURN || opcode == Opcodes.DRETURN
                || opcode == Opcodes.ARETURN || opcode == Opcodes.RETURN) {
            indices.add(i + 1);
        }
        //Jump targets of this instruction end blocks.
        if (insn instanceof JumpInsnNode)
            indices.add(insns.indexOf(((JumpInsnNode) insn).label));
        else if (insn instanceof LookupSwitchInsnNode) {
            indices.add(insns.indexOf(((LookupSwitchInsnNode) insn).dflt));
            for (Object label : ((LookupSwitchInsnNode) insn).labels)
                indices.add(insns.indexOf((LabelNode) label));
        } else if (insn instanceof TableSwitchInsnNode) {
            indices.add(insns.indexOf(((TableSwitchInsnNode) insn).dflt));
            for (Object label : ((TableSwitchInsnNode) insn).labels)
                indices.add(insns.indexOf((LabelNode) label));
        }

        //While we're scanning the instructions, make the UninitializedValue
        //values for 'new' opcodes.
        if (opcode == Opcodes.NEW) {
            Klass k = getKlassByInternalName(((TypeInsnNode) insn).desc);
            ReferenceType t = typeFactory.getReferenceType(k);
            newValues.put(insn, new UninitializedValue(t, "new" + (counter++)));
        }
    }

    //Remove duplicates and sort via TreeSet.
    indices = new ArrayList<>(new TreeSet<>(indices));
    for (int i = 1; i < indices.size(); ++i)
        blocks.add(new BBInfo(indices.get(i - 1), indices.get(i), i - 1));
}

From source file:net.epoxide.surge.asm.ASMUtils.java

License:Creative Commons License

/**
 * Removes a specific set of instructions (the needle) from a much larger set of
 * instructions (the hay stack). Be cautious when using this method, as it is almost never
 * a good idea to remove instructions./*from  w  w w  .  j  ava  2s.  co m*/
 *
 * @param haystack: A large list of instructions which is being searched through.
 * @param needle: A specific list of instructions which are to be removed from the larger
 *        instruction list.
 */
public static void removeNeedleFromHaystack(InsnList haystack, InsnList needle) {

    final int firstInd = haystack.indexOf(findFirstNodeFromNeedle(haystack, needle));
    final int lastInd = haystack.indexOf(findLastNodeFromNeedle(haystack, needle));
    final List<AbstractInsnNode> realNeedle = new ArrayList<AbstractInsnNode>();

    for (int i = firstInd; i <= lastInd; i++)
        realNeedle.add(haystack.get(i));

    for (final AbstractInsnNode node : realNeedle)
        haystack.remove(node);
}