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.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/*from ww w  .j av a2s.com*/
 *
 */
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:com.sun.tdk.jcov.instrument.BranchCodeMethodAdapter.java

License:Open Source License

private void debugDump() {
    /* Opcode Names */

    MethodNode methodNode = (MethodNode) mv;
    InsnList instructions = methodNode.instructions;
    ListIterator iit = instructions.iterator();

    System.out.println(methodNode.name + "  ----");
    while (iit.hasNext()) {
        AbstractInsnNode instr = (AbstractInsnNode) iit.next();
        int opcode = instr.getOpcode();
        if (opcode >= 0) {
            System.out.print("        ");
            System.out.print(Constants.opcNames[opcode]);
            System.out.print("  ");
        }/*from w w w.  j a  v a2  s.c  om*/
        switch (instr.getType()) {
        case LINE:
            System.out.print(((LineNumberNode) instr).line);
            System.out.print("#");
            break;
        case LABEL:
            System.out.print(labelString(((LabelNode) instr)));
            System.out.print(":");
            break;
        case FRAME:
            System.out.print("frame-");
            break;
        case JUMP_INSN:
            System.out.print(labelString(((JumpInsnNode) instr).label));
            break;
        case LOOKUPSWITCH: {
            LookupSwitchInsnNode node = (LookupSwitchInsnNode) instr;
            System.out.println();
            System.out.print("            default: ");
            System.out.print(labelString(node.dflt));
            int len = node.labels.size();
            for (int i = 0; i < len; ++i) {
                LabelNode lnode = (LabelNode) (node.labels.get(i));
                Integer key = (Integer) (node.keys.get(i));
                System.out.println();
                System.out.print("            ");
                System.out.print(key);
                System.out.print(": ");
                System.out.print(labelString(lnode));
            }
            break;
        }
        case TABLESWITCH_INSN: {
            TableSwitchInsnNode node = (TableSwitchInsnNode) instr;
            System.out.println();
            System.out.print("            default: ");
            System.out.print(labelString(node.dflt));
            int len = node.labels.size();
            int key = node.min;
            for (int i = 0; i < len; ++i) {
                LabelNode lnode = (LabelNode) (node.labels.get(i));
                System.out.println();
                System.out.print("            ");
                System.out.print(key++);
                System.out.print(": ");
                System.out.print(labelString(lnode));
            }
            break;
        }
        default:
            break;
        }
        if (insnToBB.get(instr) != null) {
            System.out.println(
                    "  block [" + insnToBB.get(instr).startBCI() + ", " + insnToBB.get(instr).endBCI() + "]");
        } else {
            System.out.println();
        }
    }
}

From source file:com.thomas15v.packetlib.codegenerator.asm.ASMHelper.java

License:MIT License

public static Map<LabelNode, LabelNode> cloneLabels(InsnList source) {
    Map<LabelNode, LabelNode> labels = new HashMap<LabelNode, LabelNode>();

    for (Iterator<AbstractInsnNode> iter = source.iterator(); iter.hasNext();) {
        AbstractInsnNode insn = iter.next();
        if (insn instanceof LabelNode) {
            labels.put((LabelNode) insn, new LabelNode(((LabelNode) insn).getLabel()));
        }/*from www  .  j a  va 2s .c o m*/
    }

    return labels;
}

From source file:com.triage.bytecodemaster.GroovyShardTransformer.java

protected byte[] transformClass(String tapScript, String className, ClassLoader cl, byte[] classFileBuffer)
        throws Exception {
    Timer timer = new Timer();
    timer.start();//from  w  w w .  ja va 2 s  . co  m
    //so that we can reference classes available in the caller when we compile the script

    //MAKES A KEY ASSUMPTION: that all classloaders we will have a path back to the system
    //classloader, and thus will have our groovy stuff in them!
    //if this isnt the case, we may want to have a dual-parent classloader where
    //we can search both the target classloader and the system
    CachingGroovyClassLoader groovyClassLoader = new CachingGroovyClassLoader(cl);

    //load the script in ASM
    ClassNode shimClassNode = new ClassNode();
    String scriptName = className + "-Tap.groovy";

    timer.mark("startParse");
    Class groovyClass = groovyClassLoader.parseClass(tapScript, scriptName);
    timer.mark("endParse");

    String generatedClassName = groovyClass.getName() + ".class";
    byte[] classBytes = groovyClassLoader.getClassBytes(generatedClassName);
    timer.mark("getClassBytes");
    ClassReader shimClassReader = new ClassReader(classBytes);
    shimClassReader.accept(shimClassNode, 0);
    timer.mark("readShimClass");

    ClassNode targetClassNode = new ClassNode();
    ClassReader targetClassReader = new ClassReader(classFileBuffer);
    targetClassReader.accept(targetClassNode, 0);
    timer.mark("readTargetClass");
    //copy instructions        
    //TODO: this is just a POC-- of course all this hardcoded stuff needs
    //to be replaced with real code
    MethodNode targetMethod = null;
    MethodNode sourceMethod = null;
    InsnList instructionsToInject = null;

    if (className.contains("TestFriend")) {
        targetMethod = findMethod(targetClassNode, "whatDoIThinkAbout");
        sourceMethod = findMethod(shimClassNode, "beforeWhatDoIThinkAbout");
        instructionsToInject = sourceMethod.instructions;
    } else if (className.contains("Calculator")) {
        targetMethod = findMethod(targetClassNode, "add");
        sourceMethod = findMethod(shimClassNode, "beforeAdd");

        //HACK: in the calculator script, we do not want a premature
        //return, so lets remove RETURNs from the source.
        //that DOESNT work in gneeral because sometimes we do want a return
        //but this will just see if removing the returns works
        instructionsToInject = sourceMethod.instructions;
        ListIterator li = instructionsToInject.iterator();
        while (li.hasNext()) {
            AbstractInsnNode node = (AbstractInsnNode) li.next();

            if (isReturnOpCode(node.getOpcode())) {
                li.remove();
            }
        }
    }
    timer.mark("gotInstructionsToInject");
    System.out.println("Transforming Target Method:");
    printMethodNode(targetMethod);
    System.out.println("Transforming Source Method:");
    printMethodNode(sourceMethod);

    //insert source instructions in target
    targetMethod.instructions.insert(sourceMethod.instructions);
    timer.mark("injectedInstructions");

    //write a class 

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    targetClassNode.accept(cw);
    timer.mark("finishedWrite");
    System.out.println("Successfully transformed class" + className);
    timer.stop();
    System.out.println("Timings:" + timer);
    return cw.toByteArray();

}

From source file:de.codesourcery.asm.controlflow.AbstractBlock.java

License:Apache License

@Override
public int getByteCodeInstructionCount(MethodNode method) {

    final InsnList instructions = method.instructions;
    @SuppressWarnings("unchecked")
    final ListIterator<AbstractInsnNode> iterator = instructions.iterator();

    int count = 0;
    for (int index = 0; iterator.hasNext(); index++) {
        final AbstractInsnNode node = iterator.next();
        if (containsInstructionNum(index)) {
            final int opCode = node.getOpcode();
            if (opCode >= 0 && opCode < Printer.OPCODES.length) {
                count++;/*from   ww w. j  a v a  2  s. c  o  m*/
            }
        }
    }
    return count;
}

From source file:de.tuberlin.uebb.jbop.optimizer.arithmetic.ArithmeticExpressionInterpreter.java

License:Open Source License

private boolean runIntern(final InsnList original) {
    boolean intern = false;
    final Iterator<AbstractInsnNode> iterator = original.iterator();
    while (iterator.hasNext()) {
        final AbstractInsnNode currentNode = iterator.next();
        Number one, two;//from   w ww . j  ava  2 s. c  om
        AbstractInsnNode numberNode;
        AbstractInsnNode castNode1 = null;
        AbstractInsnNode castNode2 = null;
        try {
            one = NodeHelper.getNumberValue(currentNode);
            numberNode = NodeHelper.getNext(currentNode);
            if (NodeHelper.isCast(numberNode)) {
                castNode1 = numberNode;
                numberNode = NodeHelper.getNext(castNode1);
            }
            two = NodeHelper.getNumberValue(numberNode);
        } catch (final NotANumberException nane) {
            continue;
        }
        AbstractInsnNode op = NodeHelper.getNext(numberNode);
        if (NodeHelper.isCast(op)) {
            castNode2 = op;
            op = NodeHelper.getNext(castNode2);
        }
        if (isArithmeticOp(op)) {
            final AbstractInsnNode replacement = getReplacement(one, two, op);
            original.insert(op, replacement);
            clean(original, iterator, currentNode, numberNode, castNode1, castNode2, op);
            optimized = true;
            intern = true;
        }
    }
    return intern;
}

From source file:de.tuberlin.uebb.jbop.optimizer.array.AbstractLocalArrayOptimizer.java

License:Open Source License

@Override
public InsnList optimize(final InsnList original, final MethodNode methodNode) throws JBOPClassException {
    optimized = false;//from w  ww . j av  a 2 s .c  om
    final Iterator<AbstractInsnNode> iterator = original.iterator();
    final Map<Integer, Object> knownArrays = new TreeMap<>();
    while (iterator.hasNext()) {
        final AbstractInsnNode currentNode = iterator.next();
        final int registerValues = registerValues(currentNode, knownArrays);
        if (registerValues > 0) {
            if (registerValues > 1) {
                iterator.next();
            }
            continue;
        }
        optimized |= handleValues(original, knownArrays, currentNode);
    }
    return original;
}

From source file:de.tuberlin.uebb.jbop.optimizer.array.FieldArrayLengthInliner.java

License:Open Source License

@Override
public InsnList optimize(final InsnList original, final MethodNode method) throws JBOPClassException {
    optimized = false;//from   ww w  .ja v a  2s.co m
    final ListIterator<AbstractInsnNode> iterator = original.iterator();
    final ArrayHelper arrayHelper = new ArrayHelper();
    while (iterator.hasNext()) {
        final AbstractInsnNode aload = iterator.next();
        if (!arrayHelper.isArrayInstruction(classNode, aload, null)) {
            continue;
        }
        if (!arrayHelper.isArrayLength()) {
            continue;
        }
        final GetFieldChainInliner fieldChainInliner = new GetFieldChainInliner();
        fieldChainInliner.setIterator(iterator);
        fieldChainInliner.setInputObject(instance);
        fieldChainInliner.optimize(original, null);
        if (fieldChainInliner.isOptimized()) {
            optimized = true;
            original.remove(aload);
        }
    }
    return original;
}

From source file:de.tuberlin.uebb.jbop.optimizer.array.FieldArrayValueInliner.java

License:Open Source License

@Override
public InsnList optimize(final InsnList original, final MethodNode method) throws JBOPClassException {
    optimized = false;/*from w  w  w.ja  v  a  2  s .  c  om*/
    final ListIterator<AbstractInsnNode> iterator = original.iterator();
    final ArrayHelper arrayHelper = new ArrayHelper();
    while (iterator.hasNext()) {
        final AbstractInsnNode aload = iterator.next();
        if (!arrayHelper.isArrayInstruction(classNode, aload, ImmutableArray.class)) {
            continue;
        }
        if (arrayHelper.isIndexEmpty()) {
            continue;
        }
        handleValue(original, aload, arrayHelper, iterator);
    }
    return original;
}

From source file:de.tuberlin.uebb.jbop.optimizer.controlflow.ConstantIfInliner.java

License:Open Source License

@Override
public InsnList optimize(final InsnList original, final MethodNode methodNode) throws JBOPClassException {
    optimized = false;//from ww  w. ja  va 2  s.c om

    final Iterator<AbstractInsnNode> iterator = original.iterator();

    while (iterator.hasNext()) {
        final AbstractInsnNode currentNode = iterator.next();
        if (NodeHelper.isIf(currentNode)) {
            final AbstractInsnNode node1 = NodeHelper.getPrevious(currentNode);
            if (NodeHelper.isTwoValueIf(currentNode)) {
                final AbstractInsnNode node2 = NodeHelper.getPrevious(node1);
                handle(currentNode, node1, node2, original, iterator);
            } else {

                handle(currentNode, node1, null, original, iterator);
            }
        }
    }
    return original;
}