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

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

Introduction

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

Prototype

int size

To view the source code for org.objectweb.asm.tree InsnList size.

Click Source Link

Document

The number of instructions in this list.

Usage

From source file:com.android.tools.lint.client.api.LintDriver.java

License:Apache License

@Nullable
private static MethodInsnNode findConstructorInvocation(@NonNull MethodNode method, @NonNull String className) {
    InsnList nodes = ((MethodNode) method).instructions;
    for (int i = 0, n = nodes.size(); i < n; i++) {
        AbstractInsnNode instruction = nodes.get(i);
        if (instruction.getOpcode() == Opcodes.INVOKESPECIAL) {
            MethodInsnNode call = (MethodInsnNode) instruction;
            if (className.equals(call.owner)) {
                return call;
            }/*from   w w w .  ja  va 2  s  .  c o m*/
        }
    }

    return null;
}

From source file:com.github.antag99.retinazer.weaver.SystemProcessor.java

License:Open Source License

private void processMethod(MethodNode methodNode) {
    InsnList insns = methodNode.instructions;

    // Filter out debugging nodes/labels
    int count = 0;
    int maxCount = insns.size();
    AbstractInsnNode[] nodes = new AbstractInsnNode[maxCount];
    for (AbstractInsnNode node = insns.getFirst(); node != null; node = node.getNext())
        if (node.getOpcode() > 0)
            nodes[count++] = node;//  w ww.j  av  a 2s.  c  o  m

    // Find mapper get() calls and create an own flyweight instance for each
    for (int i = 0; i <= count - 4; i++) {
        if (!(nodes[i + 0] instanceof VarInsnNode))
            continue;
        if (!(nodes[i + 1] instanceof FieldInsnNode))
            continue;
        if (!(nodes[i + 2] instanceof VarInsnNode))
            continue;
        if (!(nodes[i + 3] instanceof MethodInsnNode))
            continue;

        VarInsnNode loadThis = (VarInsnNode) nodes[i + 0];
        FieldInsnNode getField = (FieldInsnNode) nodes[i + 1];
        VarInsnNode loadEntity = (VarInsnNode) nodes[i + 2];
        MethodInsnNode getMethod = (MethodInsnNode) nodes[i + 3];

        if (loadThis.var != 0 || loadThis.getOpcode() != ALOAD)
            continue;

        if (!getField.owner.equals(metadata.internalName)
                || !getField.desc.equals("L" + WeaverConstants.MAPPER_NAME + ";")
                || !metadata.mappersByName.containsKey(getField.name))
            continue;
        if (loadEntity.getOpcode() != ILOAD)
            continue;
        if (!getMethod.owner.equals(WeaverConstants.MAPPER_NAME)
                || !getMethod.desc.equals("(I)L" + WeaverConstants.COMPONENT_NAME + ";")
                || !getMethod.name.equals("get"))
            continue;

        SystemMapper mapper = metadata.mappersByName.get(getField.name);

        // Add field to hold the flyweight
        String fieldName = "flyweight$" + flyweightFields.size();
        String fieldDesc = mapper.componentType.getDescriptor();
        FieldNode fieldNode = new FieldNode(ACC_PRIVATE, fieldName, fieldDesc, null, null);
        fieldNode.visitAnnotation("Lcom/github/antag99/retinazer/SkipWire;", true);
        FlyweightField flyweightField = new FlyweightField();
        flyweightField.fieldNode = fieldNode;
        flyweightField.mapper = mapper;
        flyweightFields.add(flyweightField);

        // Rewrite access to use the flyweight
        getField.owner = metadata.internalName;
        getField.name = fieldName;
        getField.desc = fieldDesc;
        insns.insert(getField, new InsnNode(DUP));
        insns.insert(loadEntity, new FieldInsnNode(PUTFIELD, mapper.componentType.getInternalName(),
                WeaverConstants.INDEX_FIELD_NAME, WeaverConstants.INDEX_FIELD_DESC));
        insns.remove(getMethod);
    }
}

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

License:Open Source License

private void _doTestToClass(boolean proxyClassesDumpEnabled, boolean logEnabled) throws FileNotFoundException {

    class TestClass {
    }/*www  .ja  va2 s. c  o  m*/

    ClassNode classNode = _loadClass(TestClass.class);

    MethodNode methodNode = new MethodNode(Opcodes.ACC_PUBLIC, "<clinit>", "()V", null, null);

    methodNode.visitCode();
    methodNode.visitInsn(Opcodes.RETURN);
    methodNode.visitEnd();

    List<MethodNode> methodNodes = classNode.methods;

    methodNodes.add(methodNode);

    ClassLoader classLoader = new URLClassLoader(new URL[0], null);

    Level level = Level.WARNING;

    if (logEnabled) {
        level = Level.INFO;
    }

    try (CaptureHandler captureHandler = JDKLoggerTestUtil
            .configureJDKLogger(IntrabandProxyUtil.class.getName(), level)) {

        List<LogRecord> logRecords = captureHandler.getLogRecords();

        IntrabandProxyUtil.toClass(classNode, classLoader);

        if (proxyClassesDumpEnabled) {
            StringBundler sb = new StringBundler(6);

            sb.append(SystemProperties.get(SystemProperties.TMP_DIR));
            sb.append(StringPool.SLASH);
            sb.append(PropsValues.INTRABAND_PROXY_DUMP_CLASSES_DIR);
            sb.append(StringPool.SLASH);
            sb.append(classNode.name);
            sb.append(".class");

            String filePath = sb.toString();

            File classFile = new File(filePath);

            Assert.assertTrue(classFile.exists());

            ClassNode reloadedClassNode = _loadClass(new FileInputStream(classFile));

            MethodNode clinitMethodNode = ASMUtil.findMethodNode(reloadedClassNode.methods, "<clinit>",
                    Type.VOID_TYPE);

            InsnList insnList = clinitMethodNode.instructions;

            Assert.assertEquals(1, insnList.size());

            _assertInsnNode(insnList.getFirst(), Opcodes.RETURN);

            if (logEnabled) {
                Assert.assertEquals(1, logRecords.size());

                LogRecord logRecord = logRecords.get(0);

                Assert.assertEquals(logRecord.getMessage(), "Dumpped class ".concat(filePath));
            }
        }

        if (!proxyClassesDumpEnabled || !logEnabled) {
            Assert.assertTrue(logRecords.isEmpty());
        }
    }

    try {
        IntrabandProxyUtil.toClass(classNode, classLoader);

        Assert.fail();
    } catch (RuntimeException re) {
        Throwable throwable = re.getCause();

        Assert.assertSame(InvocationTargetException.class, throwable.getClass());

        throwable = throwable.getCause();

        Assert.assertSame(LinkageError.class, throwable.getClass());

        String message = throwable.getMessage();

        Assert.assertTrue(message.contains(
                "duplicate class definition for name: \"" + Type.getInternalName(TestClass.class) + "\""));
    }
}

From source file:com.lion328.xenonlauncher.patcher.StringReplaceFilePatcher.java

License:Open Source License

@Override
public byte[] patchFile(String name, byte[] original) {
    if (!name.endsWith(".class")) {
        return original;
    }//from  w ww  .  j a  v a  2  s .c o  m

    ClassReader reader = new ClassReader(original);
    ClassNode node = new ClassNode();
    reader.accept(node, 0);

    List fields = node.fields;
    FieldNode field;
    for (Object obj : fields) {
        if (!(obj instanceof FieldNode)) {
            continue;
        }

        field = (FieldNode) obj;

        if (field.value instanceof String) {
            field.value = ((String) field.value).replace(find, replace);
        }
    }

    List methods = node.methods;
    MethodNode method;
    for (Object obj : methods) {
        if (!(obj instanceof MethodNode)) {
            continue;
        }

        method = (MethodNode) obj;

        InsnList insns = method.instructions;

        for (int i = 0; i < insns.size(); i++) {
            AbstractInsnNode insn = insns.get(i);

            if (!(insn instanceof LdcInsnNode)) {
                continue;
            }

            LdcInsnNode ldc = (LdcInsnNode) insn;

            if (!(ldc.cst instanceof String)) {
                continue;
            }

            ldc.cst = ((String) ldc.cst).replace(find, replace);
        }
    }

    ClassWriter writer = new ClassWriter(0);
    node.accept(writer);

    return writer.toByteArray();
}

From source file:com.offbynull.coroutines.instrumenter.generators.GenericGenerators.java

License:Open Source License

/**
 * Combines multiple instructions in to a single instruction list. You can include normal instructions ({@link AbstractInsnNode}),
 * instruction lists ({@link InsnList}), or instruction generators ({@link InstructionGenerator}).
 * @param insns instructions//  w w  w .  j a  v  a 2  s . co m
 * @throws NullPointerException if any argument is {@code null} or contains {@code null} 
 * @return merged instructions
 */
public static InsnList merge(Object... insns) {
    Validate.notNull(insns);
    Validate.noNullElements(insns);

    InsnList ret = new InsnList();
    for (Object insn : insns) {
        if (insn instanceof AbstractInsnNode) {
            // add single instruction
            AbstractInsnNode insnNode = (AbstractInsnNode) insn;
            ret.add(insnNode);
        } else if (insn instanceof InsnList) {
            // add instruction list
            InsnList insnList = (InsnList) insn;
            for (int i = 0; i < insnList.size(); i++) {
                Validate.notNull(insnList.get(i));
            }
            ret.add((InsnList) insn);
        } else if (insn instanceof InstructionGenerator) {
            // generate conditional merger instruction list and add
            InsnList insnList = ((InstructionGenerator) insn).generate();
            for (int i = 0; i < insnList.size(); i++) {
                Validate.notNull(insnList.get(i));
            }
            ret.add(insnList);
        } else {
            // unrecognized
            throw new IllegalArgumentException();
        }
    }

    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;/*from   w w  w  . j a  v a  2 s. c  o m*/
        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.  ja  v  a  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:com.triage.bytecodemaster.TestObjectReferenceSwitches.java

public void testReplacingThisWithOtherVariable() throws Exception {

    final String FIELDPROXYWORKED = "FIELDPROXYWORKED";

    //set up the proxy object. this is the object that will receive
    //the proxied calls
    TestSubClass tcc = new TestSubClass();
    tcc.setBaseString(FIELDPROXYWORKED);

    TestBaseClassHolder.setTestBase(tcc);

    //get the dynamic source that has the donor body in it
    ClassNode donorSource = loadGroovyTestClassAsBytecode(GROOVY_CLASS_FIELDREF);
    MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout");

    System.out.println("Donor");
    printMethodNode(donorMethod);//from w w w.ja  v a2 s .co  m

    //alright here's the strategy:  (1) inject a new local variable that points 
    //   to our remote instance,
    //  (2) inject code that sets this local to the value of a method call,
    //  (3) change references to 'this' ( ALOAD0 or ALOAD 0 ) to ALOAD1

    InsnList instructionsToInject = donorMethod.instructions;

    //make a new local variable
    LabelNode begin = new LabelNode();
    LabelNode end = new LabelNode();
    instructionsToInject.insertBefore(instructionsToInject.getFirst(), begin);
    instructionsToInject.add(end);

    Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass");
    int variableIndex = donorMethod.maxLocals;
    donorMethod.maxLocals += type.getSize();
    donorMethod.visitLocalVariable("proxy", type.getDescriptor(), null, begin.getLabel(), end.getLabel(),
            variableIndex);

    //set the value of the local variable with a new instruction at the top
    //fetch a reference to our proxy object
    MethodInsnNode getTestBase = new MethodInsnNode(Opcodes.INVOKESTATIC,
            "com/triage/bytecodemaster/fortesting/TestBaseClassHolder", "getTestBase",
            "()Lcom/triage/bytecodemaster/fortesting/TestBaseClass;");

    //insert after begin label
    instructionsToInject.insert(begin, getTestBase);

    //store reference
    VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex);

    //insert store after fetch
    instructionsToInject.insert(getTestBase, setRef);

    //replace all references to 'this'  with the new variable

    for (int currentIndex = 0; currentIndex < instructionsToInject.size(); currentIndex++) {
        AbstractInsnNode node = instructionsToInject.get(currentIndex);
        if (node.getOpcode() == Opcodes.ALOAD) {
            VarInsnNode vin = (VarInsnNode) node;

            //'this' is var index 0. ours is var index varindex
            if (vin.var == 0) {
                vin.var = variableIndex;
            }
        }
    }

    System.out.println(">>>>>>>>>Finished Modifying<<<<<<<<");
    printMethodNode(donorMethod);
    String NEWCLASSNAME = "ScriptTestClass";

    //write a class 
    Class c = createClassFromClassNode(donorSource, NEWCLASSNAME);

    Object o = c.newInstance();
    Method m = o.getClass().getDeclaredMethod("before_whatDoIThinkAbout", String.class);

    //should return HAHAHA not baseStringValue 
    String result = (String) m.invoke(o, new Object[] { "AAAA" });
    System.out.println("TestDonorClass.whatDoIThinkAbout Result: " + result);
    assertTrue(result.equals(FIELDPROXYWORKED + "AAAA"));
}

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

@Test
public void testInjectingIntoMethodWithLotsOfParameters() throws Exception {
    final String FIELDPROXYWORKED = "FIELDPROXYWORKED";

    //set up the proxy object. this is the object that will receive
    //the proxied calls
    TestSubClass tcc = new TestSubClass();
    tcc.setBaseString(FIELDPROXYWORKED);

    TestBaseClassHolder.setTestBase(tcc);

    //get the dynamic source that has the donor body in it
    ClassNode donorSource = loadGroovyTestClassAsBytecode(GROOVY_CLASS_FIELDREF2);
    MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout");

    System.out.println("Donor Method Before Modifications:");
    printMethodNode(donorMethod);/*  w  w  w  . j  a v  a2s. c  o m*/

    String TARGETCLASSNAME = "com.triage.bytecodemaster.fortesting.Concatenator";
    ClassNode targetSource = loadLocalClass(TARGETCLASSNAME);

    ClassNode exampleSource = loadLocalClass("com.triage.bytecodemaster.fortesting.JustLikeGroovyClass");
    MethodNode exampleMethod = findMethod(exampleSource, "before_whatDoIThinkAbout");

    System.out.println("Example Method-- Should be just like the Donor Source");
    printMethodNode(exampleMethod);
    MethodNode targetMethod = findMethod(targetSource, "concat");
    System.out.println("Target Method <Before Mods>");
    printMethodNode(targetMethod);

    //alright here's the strategy:  (1) inject a new local variable that points 
    //   to our remote instance,
    //  (2) inject code that sets this local to the value of a method call,
    //  (3) change references to 'this' ( ALOAD0 or ALOAD 0 ) to ALOAD1

    InsnList instructionsToInject = donorMethod.instructions;
    InsnList targetInstructions = targetMethod.instructions;

    //make a new local variable in the donor method.
    //this variable needs to have a slot high enough that it doesnt
    //conflict with either the target or the source method
    //it will hold references to the objects we replace with 'this'
    LabelNode begin = new LabelNode();
    LabelNode end = new LabelNode();
    targetInstructions.insertBefore(targetInstructions.getFirst(), begin);
    targetInstructions.add(end);

    Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass");
    int variableIndex = targetMethod.maxLocals;
    targetMethod.maxLocals += type.getSize();
    targetMethod.visitLocalVariable("proxy", type.getDescriptor(), null, begin.getLabel(), end.getLabel(),
            variableIndex);

    //set the value of the local variable with a new instruction at the top
    //fetch a reference to our proxy object
    MethodInsnNode getTestBase = new MethodInsnNode(Opcodes.INVOKESTATIC,
            "com/triage/bytecodemaster/fortesting/TestBaseClassHolder", "getTestBase",
            "()Lcom/triage/bytecodemaster/fortesting/TestBaseClass;");

    //insert after begin label
    targetInstructions.insert(begin, getTestBase);

    //store reference
    VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex);

    //insert store after fetch
    targetInstructions.insert(getTestBase, setRef);

    //replace all references to 'this' in the DONOR method with the new variable
    //in the TARGET code

    for (int currentIndex = 0; currentIndex < instructionsToInject.size(); currentIndex++) {
        AbstractInsnNode node = instructionsToInject.get(currentIndex);
        if (node.getOpcode() == Opcodes.ALOAD) {
            VarInsnNode vin = (VarInsnNode) node;

            //'this' is var index 0. ours is var index varindex
            if (vin.var == 0) {
                vin.var = variableIndex;
            }
        }

        //remove return methods. this will prevent a return. it should cause the donor 
        //method to have parameters that overlap with the target, which has more parameters
        if (node.getOpcode() == Opcodes.RETURN || node.getOpcode() == Opcodes.ARETURN) {
            instructionsToInject.remove(node);
        }
    }

    System.out.println(">>>>>>>>>Finished Modifying Donor Method <<<<<<<<");
    printMethodNode(donorMethod);
    String NEWCLASSNAME = "ScriptTestClass";

    //stash instructions at the beginning of the original method, 
    //but after populating the new variable
    targetInstructions.insert(setRef, instructionsToInject);

    System.out.println("Modified Target:");
    printMethodNode(targetMethod);

    //write a class 
    Class c = createClassFromClassNode(targetSource, TARGETCLASSNAME);

    Object o = c.newInstance();
    Method m = o.getClass().getDeclaredMethod("concat", String.class, String.class, String.class, String.class);

    //should return HAHAHA not baseStringValue 
    String result = (String) m.invoke(o, new Object[] { "A", "B", "C", "D" });
    System.out.println("Concatenator.concat Result: " + result);
    assertTrue(result.equals("ABCD"));

}

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

public void testMergedInReplacingThisWithOtherVariable() throws Exception {

    final String FIELDPROXYWORKED = "FIELDPROXYWORKED";

    //set up the proxy object. this is the object that will receive
    //the proxied calls
    TestSubClass tcc = new TestSubClass();
    tcc.setBaseString(FIELDPROXYWORKED);

    TestBaseClassHolder.setTestBase(tcc);

    //get the dynamic source that has the donor body in it
    ClassNode donorSource = loadGroovyTestClassAsBytecode(GROOVY_CLASS_FIELDREF);
    MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout");

    //load the target class
    String TARGETCLASSNAME = "com.triage.bytecodemaster.fortesting.TestFriend";
    ClassNode targetSource = loadLocalClass(TARGETCLASSNAME);
    MethodNode targetMethod = findMethod(targetSource, "whatDoIThinkAbout");

    System.out.println("Target");
    printMethodNode(targetMethod);//  w ww. j  a  v  a 2  s  .  com

    System.out.println("Donor");
    printMethodNode(donorMethod);

    //alright here's the strategy:  (1) inject a new local variable that points 
    //   to our remote instance,
    //  (2) inject code that sets this local to the value of a method call,
    //  (3) change references to 'this' ( ALOAD0 or ALOAD 0 ) to ALOAD1

    InsnList instructionsToInject = donorMethod.instructions;

    //make a new local variable
    LabelNode begin = new LabelNode();
    LabelNode end = new LabelNode();
    instructionsToInject.insertBefore(instructionsToInject.getFirst(), begin);
    instructionsToInject.add(end);

    Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass");
    int variableIndex = donorMethod.maxLocals;
    donorMethod.maxLocals += type.getSize();
    donorMethod.visitLocalVariable("proxy", type.getDescriptor(), null, begin.getLabel(), end.getLabel(),
            variableIndex);

    //set the value of the local variable with a new instruction at the top
    //fetch a reference to our proxy object
    MethodInsnNode getTestBase = new MethodInsnNode(Opcodes.INVOKESTATIC,
            "com/triage/bytecodemaster/fortesting/TestBaseClassHolder", "getTestBase",
            "()Lcom/triage/bytecodemaster/fortesting/TestBaseClass;");

    //insert after begin label
    instructionsToInject.insert(begin, getTestBase);

    //store reference
    VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex);

    //insert store after fetch
    instructionsToInject.insert(getTestBase, setRef);

    //replace all references to 'this'  with the new variable

    for (int currentIndex = 0; currentIndex < instructionsToInject.size(); currentIndex++) {
        AbstractInsnNode node = instructionsToInject.get(currentIndex);
        if (node.getOpcode() == Opcodes.ALOAD) {
            VarInsnNode vin = (VarInsnNode) node;

            //'this' is var index 0. ours is var index varindex
            if (vin.var == 0) {
                vin.var = variableIndex;
            }
        }
    }

    System.out.println(">>>>>>>>>Finished Modifying<<<<<<<<");
    printMethodNode(donorMethod);

    //insert the donorMethod
    targetMethod.instructions.insert(instructionsToInject);

    System.out.println(">>>>>>>>>Final Method<<<<<<<<");
    printMethodNode(targetMethod);

    //write a class 
    Class c = createClassFromClassNode(targetSource, TARGETCLASSNAME);

    Object o = c.newInstance();
    Method m = o.getClass().getDeclaredMethod("whatDoIThinkAbout", TestPerson.class);
    TestPerson testPerson = new TestPerson();
    testPerson.setName("AAAA");
    //should return HAHAHA not baseStringValue 
    String result = (String) m.invoke(o, new Object[] { testPerson });
    System.out.println("TestFriend.whatDoIThinkAbout Result: " + result);
    assertTrue(result.equals(FIELDPROXYWORKED + "AAAA"));
}