List of usage examples for org.objectweb.asm.tree InsnList iterator
@Override
public ListIterator<AbstractInsnNode> iterator()
From source file:com.android.tools.lint.checks.ClickableViewAccessibilityDetector.java
License:Apache License
@SuppressWarnings("unchecked") // ASM API @Nullable/* www. j av a 2 s .co m*/ private static AbstractInsnNode findMethodCallInstruction(@NonNull InsnList instructions, @NonNull String owner, @NonNull String name, @NonNull String desc) { ListIterator<AbstractInsnNode> iterator = instructions.iterator(); while (iterator.hasNext()) { AbstractInsnNode insnNode = iterator.next(); if (insnNode.getType() == AbstractInsnNode.METHOD_INSN) { MethodInsnNode methodInsnNode = (MethodInsnNode) insnNode; if ((methodInsnNode.owner.equals(owner)) && (methodInsnNode.name.equals(name)) && (methodInsnNode.desc.equals(desc))) { return methodInsnNode; } } } return null; }
From source file:com.geeksaga.flow.analysis.Analysis.java
License:Apache License
private static void print(MethodNode method) { InsnList instructions = method.instructions; ListIterator<AbstractInsnNode> iterator = instructions.iterator(); while (iterator.hasNext()) { AbstractInsnNode n = iterator.next(); if (n instanceof MethodInsnNode) { logger.debug("\t\t{}", insnToString(n)); }//from ww w .j a va 2s . c o m if (n instanceof FieldInsnNode) { logger.debug("\t\t\t{}", insnToString(n)); } } }
From source file:com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtilTest.java
License:Open Source License
@Test public void testRewriteGetProxyMethodSignaturesMethodNode() { class TestClass { @SuppressWarnings("unused") public final String[] PROXY_METHOD_SIGNATURES = _getProxyMethodSignatures(); private String[] _getProxyMethodSignatures() { return new String[0]; }//from ww w . j ava 2 s .c o m } ClassNode classNode = _loadClass(TestClass.class); String[] proxyMethodSignatures = { "testSignature1", "testSignature2", "testSignature3" }; IntrabandProxyUtil.rewriteGetProxyMethodSignaturesMethodNode(classNode, proxyMethodSignatures); MethodNode methodNode = ASMUtil.findMethodNode(classNode.methods, "_getProxyMethodSignatures", Type.getType(String[].class)); InsnList insnList = methodNode.instructions; Iterator<AbstractInsnNode> iterator = insnList.iterator(); _assertInsnNode(iterator.next(), Opcodes.ICONST_3); _assertTypeInsnNode(iterator.next(), Opcodes.ANEWARRAY, String.class); for (int i = 0; i < proxyMethodSignatures.length; i++) { _assertInsnNode(iterator.next(), Opcodes.DUP); _assertInsnNode(iterator.next(), Opcodes.ICONST_0 + i); _assertLdcInsnNode(iterator.next(), Opcodes.LDC, proxyMethodSignatures[i]); _assertInsnNode(iterator.next(), Opcodes.AASTORE); } _assertInsnNode(iterator.next(), Opcodes.ARETURN); Assert.assertFalse(iterator.hasNext()); }
From source file:com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtilTest.java
License:Open Source License
private void _doTestCreateProxyMethodNode(Method method, int index, String skeletonId, String stubInternalName) { MethodNode proxyMethodNode = IntrabandProxyUtil.createProxyMethodNode(method, index, skeletonId, Type.getType(stubInternalName)); _assertMethodNodeSignature(proxyMethodNode, method.getModifiers() & ~Modifier.ABSTRACT, method.getName(), Type.getMethodDescriptor(method), method.getExceptionTypes()); InsnList insnList = proxyMethodNode.instructions; Iterator<AbstractInsnNode> iterator = insnList.iterator(); // NEW com/liferay/portal/kernel/io/Serializer _assertTypeInsnNode(iterator.next(), Opcodes.NEW, Serializer.class); // DUP/* ww w. ja v a2s .c o m*/ _assertInsnNode(iterator.next(), Opcodes.DUP); // INVOKESPECIAL com/liferay/portal/kernel/io/Serializer <init> ()V _assertMethodInsnNode(iterator.next(), Opcodes.INVOKESPECIAL, Type.getInternalName(Serializer.class), "<init>", Type.VOID_TYPE); // ASTORE argumentsSize Type methodType = Type.getType(method); int argumentsAndReturnSizes = methodType.getArgumentsAndReturnSizes(); int argumentsSize = argumentsAndReturnSizes >> 2; _assertVarInsnNode(iterator.next(), Opcodes.ASTORE, argumentsSize); // ALOAD argumentsSize _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize); // LDC skeletonId _assertLdcInsnNode(iterator.next(), Opcodes.LDC, skeletonId); // INVOKEVIRTUAL com/liferay/portal/kernel/io/Serializer writeString // (Ljava/lang/String;)V _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Serializer.class), "writeString", Type.VOID_TYPE, Type.getType(String.class)); // ALOAD argumentsSize _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize); // ALOAD 0 _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, 0); // GETFIELD stubInternalName _id Ljava/lang/String; _assertFieldInsnNode(iterator.next(), Opcodes.GETFIELD, stubInternalName, "_id", String.class); // INVOKEVIRTUAL com/liferay/portal/kernel/io/Serializer writeString // (Ljava/lang/String;)V _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Serializer.class), "writeString", Type.VOID_TYPE, Type.getType(String.class)); // ALOAD argumentsSize _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize); if (index <= 5) { // ICONST_index _assertInsnNode(iterator.next(), Opcodes.ICONST_0 + index); } else { // BIPUSH index _assertIntInsnNode(iterator.next(), Opcodes.BIPUSH, index); } // INVOKEVIRTUAL com/liferay/portal/kernel/io/Serializer writeInt (I)V _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Serializer.class), "writeInt", Type.VOID_TYPE, Type.INT_TYPE); Class<?>[] parameterTypes = method.getParameterTypes(); int offset = 1; for (int i = 0; i < parameterTypes.length; i++) { Class<?> parameterClass = parameterTypes[i]; // ALOAD argumentsSize _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize); // xLOAD i Type parameterType = Type.getType(parameterClass); _assertVarInsnNode(iterator.next(), parameterType.getOpcode(Opcodes.ILOAD), offset); offset += parameterType.getSize(); if (parameterClass.isPrimitive() || (parameterClass == String.class)) { String name = TextFormatter.format(parameterClass.getSimpleName(), TextFormatter.G); _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Serializer.class), "write".concat(name), Type.VOID_TYPE, parameterType); } else { _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Serializer.class), "writeObject", Type.VOID_TYPE, Type.getType(Serializable.class)); } } // ALOAD 0 _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, 0); // ALOAD argumentsSize _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize); Class<?> returnClass = method.getReturnType(); Type returnType = Type.getType(returnClass); if (returnClass == void.class) { // INVOKESPECIAL stubInternalName _send // (Lcom/liferay/portal/kernel/io/Serializer;)V _assertMethodInsnNode(iterator.next(), Opcodes.INVOKESPECIAL, stubInternalName, "_send", Type.VOID_TYPE, Type.getType(Serializer.class)); _assertInsnNode(iterator.next(), Opcodes.RETURN); } else { // INVOKESPECIAL stubInternalName _syncSend // (Lcom/liferay/portal/kernel/io/Serializer;)Ljava/io/Serializable; _assertMethodInsnNode(iterator.next(), Opcodes.INVOKESPECIAL, stubInternalName, "_syncSend", Type.getType(Serializable.class), Type.getType(Serializer.class)); if (returnClass.isPrimitive()) { // ASTORE argumentsSize + 1 _assertVarInsnNode(iterator.next(), Opcodes.ASTORE, argumentsSize + 1); // ALOAD argumentsSize + 1 _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize + 1); // IFNULL nullCheckLabel LabelNode nullCheckLabelNode = _assertJumpInsnNode(iterator.next(), Opcodes.IFNULL); // ALOAD argumentsSize + 1 _assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize + 1); // CHECKCAST returnType _assertTypeInsnNode(iterator.next(), Opcodes.CHECKCAST, _autoboxingMap.get(returnClass)); if (returnClass == boolean.class) { // INVOKEVIRTUAL java/lang/Boolean booleanValue ()Z _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Boolean.class), "booleanValue", Type.BOOLEAN_TYPE); } else if (returnClass == byte.class) { // INVOKEVIRTUAL java/lang/Number intValue ()I _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Number.class), "intValue", Type.INT_TYPE); } else if (returnClass == char.class) { // INVOKEVIRTUAL java/lang/Character charValue ()C _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Character.class), "charValue", Type.CHAR_TYPE); } else if (returnClass == double.class) { // INVOKEVIRTUAL java/lang/Number doubleValue ()D _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Number.class), "doubleValue", Type.DOUBLE_TYPE); } else if (returnClass == float.class) { // INVOKEVIRTUAL java/lang/Number floatValue ()F _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Number.class), "floatValue", Type.FLOAT_TYPE); } else if (returnClass == int.class) { // INVOKEVIRTUAL java/lang/Number intValue ()I _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Number.class), "intValue", Type.INT_TYPE); } else if (returnClass == long.class) { // INVOKEVIRTUAL java/lang/Number longValue ()J _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Number.class), "longValue", Type.LONG_TYPE); } else if (returnClass == short.class) { // INVOKEVIRTUAL java/lang/Number intValue ()I _assertMethodInsnNode(iterator.next(), Opcodes.INVOKEVIRTUAL, Type.getInternalName(Number.class), "intValue", Type.INT_TYPE); } // xRETURN _assertInsnNode(iterator.next(), returnType.getOpcode(Opcodes.IRETURN)); // nullCheckLabel Assert.assertSame(nullCheckLabelNode, iterator.next()); // xRETURN null/0 if (!returnClass.isPrimitive()) { _assertInsnNode(iterator.next(), Opcodes.ACONST_NULL); _assertInsnNode(iterator.next(), Opcodes.ARETURN); } else if (returnClass == void.class) { _assertInsnNode(iterator.next(), Opcodes.RETURN); } else if (returnClass == float.class) { _assertInsnNode(iterator.next(), Opcodes.FCONST_0); _assertInsnNode(iterator.next(), Opcodes.FRETURN); } else if (returnClass == double.class) { _assertInsnNode(iterator.next(), Opcodes.DCONST_0); _assertInsnNode(iterator.next(), Opcodes.DRETURN); } else if (returnClass == long.class) { _assertInsnNode(iterator.next(), Opcodes.LCONST_0); _assertInsnNode(iterator.next(), Opcodes.LRETURN); } else { _assertInsnNode(iterator.next(), Opcodes.ICONST_0); _assertInsnNode(iterator.next(), Opcodes.IRETURN); } } else { if (returnClass != Object.class) { // CHECKCAST _assertTypeInsnNode(iterator.next(), Opcodes.CHECKCAST, returnClass); } // ARETURN _assertInsnNode(iterator.next(), Opcodes.ARETURN); } } Assert.assertFalse(iterator.hasNext()); }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Clones an instruction list. All labels are remapped unless otherwise specified in {@code globalLabels}. * @param insnList instruction list to clone * @param globalLabels set of labels that should not be remapped * @throws NullPointerException if any argument is {@code null} * @return instruction list with cloned instructions *///from ww w .j a va 2 s . co m public static InsnList cloneInsnList(InsnList insnList, Set<LabelNode> globalLabels) { Validate.notNull(insnList); // remap all labelnodes Map<LabelNode, LabelNode> labelNodeMapping = new HashMap<>(); ListIterator<AbstractInsnNode> it = insnList.iterator(); while (it.hasNext()) { AbstractInsnNode abstractInsnNode = it.next(); if (abstractInsnNode instanceof LabelNode) { LabelNode existingLabelNode = (LabelNode) abstractInsnNode; labelNodeMapping.put(existingLabelNode, new LabelNode()); } } // override remapping such that global labels stay the same for (LabelNode globalLabel : globalLabels) { labelNodeMapping.put(globalLabel, globalLabel); } // clone InsnList ret = new InsnList(); it = insnList.iterator(); while (it.hasNext()) { AbstractInsnNode abstractInsnNode = it.next(); ret.add(abstractInsnNode.clone(labelNodeMapping)); } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtils.java
License:Open Source License
/** * Find invocations of a certain method. * @param insnList instruction list to search through * @param expectedMethod type of method being invoked * @return list of invocations (may be nodes of type {@link MethodInsnNode} or {@link InvokeDynamicInsnNode}) * @throws NullPointerException if any argument is {@code null} * @throws NullPointerException if {@code expectedMethodType} isn't of sort {@link Type#METHOD} *///from w w w.j a v a 2 s. com public static List<AbstractInsnNode> findInvocationsOf(InsnList insnList, Method expectedMethod) { Validate.notNull(insnList); Validate.notNull(expectedMethod); List<AbstractInsnNode> ret = new ArrayList<>(); Type expectedMethodDesc = Type.getType(expectedMethod); Type expectedMethodOwner = Type.getType(expectedMethod.getDeclaringClass()); String expectedMethodName = expectedMethod.getName(); Iterator<AbstractInsnNode> it = insnList.iterator(); while (it.hasNext()) { AbstractInsnNode instructionNode = it.next(); Type methodDesc; Type methodOwner; String methodName; if (instructionNode instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) instructionNode; methodDesc = Type.getType(methodInsnNode.desc); methodOwner = Type.getObjectType(methodInsnNode.owner); methodName = expectedMethod.getName(); } else { continue; } if (methodDesc.equals(expectedMethodDesc) && methodOwner.equals(expectedMethodOwner) && methodName.equals(expectedMethodName)) { ret.add(instructionNode); } } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtils.java
License:Open Source License
/** * Find invocations of any method where the parameter list contains a type. * @param insnList instruction list to search through * @param expectedParamType parameter type * @return list of invocations (may be nodes of type {@link MethodInsnNode} or {@link InvokeDynamicInsnNode}) * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if {@code expectedParamType} is either of sort {@link Type#METHOD} or {@link Type#VOID} *///w w w. j a v a2s . c o m public static List<AbstractInsnNode> findInvocationsWithParameter(InsnList insnList, Type expectedParamType) { Validate.notNull(insnList); Validate.notNull(expectedParamType); Validate.isTrue(expectedParamType.getSort() != Type.METHOD && expectedParamType.getSort() != Type.VOID); List<AbstractInsnNode> ret = new ArrayList<>(); Iterator<AbstractInsnNode> it = insnList.iterator(); while (it.hasNext()) { AbstractInsnNode instructionNode = it.next(); Type[] methodParamTypes; if (instructionNode instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) instructionNode; Type methodType = Type.getType(methodInsnNode.desc); methodParamTypes = methodType.getArgumentTypes(); } else if (instructionNode instanceof InvokeDynamicInsnNode) { InvokeDynamicInsnNode invokeDynamicInsnNode = (InvokeDynamicInsnNode) instructionNode; Type methodType = Type.getType(invokeDynamicInsnNode.desc); methodParamTypes = methodType.getArgumentTypes(); } else { continue; } if (Arrays.asList(methodParamTypes).contains(expectedParamType)) { ret.add(instructionNode); } } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtils.java
License:Open Source License
/** * Find instructions in a certain class that are of a certain set of opcodes. * @param insnList instruction list to search through * @param opcodes opcodes to search for/*from w w w . j a va 2 s . co m*/ * @return list of instructions that contain the opcodes being searched for * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if {@code opcodes} is empty */ public static List<AbstractInsnNode> searchForOpcodes(InsnList insnList, int... opcodes) { Validate.notNull(insnList); Validate.notNull(opcodes); Validate.isTrue(opcodes.length > 0); List<AbstractInsnNode> ret = new LinkedList<>(); Set<Integer> opcodeSet = new HashSet<>(); Arrays.stream(opcodes).forEach((x) -> opcodeSet.add(x)); Iterator<AbstractInsnNode> it = insnList.iterator(); while (it.hasNext()) { AbstractInsnNode insnNode = it.next(); if (opcodeSet.contains(insnNode.getOpcode())) { ret.add(insnNode); } } return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtils.java
License:Open Source License
/** * Find trycatch blocks within a method that an instruction is apart of. Only includes the try portion, not the catch (handler) portion. * @param insnList instruction list for method * @param tryCatchBlockNodes trycatch blocks in method * @param insnNode instruction within method being searched against * @throws NullPointerException if any argument is {@code null} or contains {@code null} * @throws IllegalArgumentException if arguments aren't all from the same method * @return items from {@code tryCatchBlockNodes} that {@code insnNode} is a part of */// ww w.j a v a2 s .c o m public static List<TryCatchBlockNode> findTryCatchBlockNodesEncompassingInstruction(InsnList insnList, List<TryCatchBlockNode> tryCatchBlockNodes, AbstractInsnNode insnNode) { Validate.notNull(insnList); Validate.notNull(tryCatchBlockNodes); Validate.notNull(insnNode); Validate.noNullElements(tryCatchBlockNodes); Map<LabelNode, Integer> labelPositions = new HashMap<>(); int insnNodeIdx = -1; // Get index of labels and insnNode within method ListIterator<AbstractInsnNode> insnIt = insnList.iterator(); int insnCounter = 0; while (insnIt.hasNext()) { AbstractInsnNode node = insnIt.next(); // If our instruction, save index if (node == insnNode) { if (insnNodeIdx == -1) { insnNodeIdx = insnCounter; } else { throw new IllegalArgumentException(); // insnNode encountered multiple times in methodNode. Should not happen. } } // If label node, save position if (node instanceof LabelNode) { labelPositions.put((LabelNode) node, insnCounter); } // Increment counter insnCounter++; } Validate.isTrue(insnNodeIdx != -1); //throw exception if node not in method list // Find out which trycatch blocks insnNode is within List<TryCatchBlockNode> ret = new ArrayList<>(); for (TryCatchBlockNode tryCatchBlockNode : tryCatchBlockNodes) { Integer startIdx = labelPositions.get(tryCatchBlockNode.start); Integer endIdx = labelPositions.get(tryCatchBlockNode.end); Validate.isTrue(startIdx != null); Validate.isTrue(endIdx != null); if (insnNodeIdx >= startIdx && insnNodeIdx < endIdx) { ret.add(tryCatchBlockNode); } } return ret; }
From source file:com.sun.tdk.jcov.instrument.BlockCodeMethodAdapter.java
License:Open Source License
private SimpleBasicBlock[] completeComputationOfCodeLabelNodes() { MethodNode methodNode = (MethodNode) mv; InsnList instructions = methodNode.instructions; int[] allToReal = new int[instructions.size()]; int allIdx = 0; int insnIdx = 0; ListIterator iit = instructions.iterator(); // Create the method entry block and basic block AbstractInsnNode insnFirst = peek(iit); SimpleBasicBlock bbFirst = getBB(insnFirst, 0); // DataBlock blockFirst = new DataBlockMethEnter(); // bbFirst.add(blockFirst); while (iit.hasNext()) { AbstractInsnNode insn = (AbstractInsnNode) iit.next(); allToReal[allIdx++] = insnIdx;//w w w . jav a2s . com int bci = bcis[insnIdx]; int opcode = insn.getOpcode(); if (opcode < 0) { // a pseudo-instruction if (insn.getType() == AbstractInsnNode.LINE) { LineNumberNode lineNode = (LineNumberNode) insn; method().addLineEntry(bci, lineNode.line); } } else { // a real instruction ++insnIdx; // advance the real instruction index //System.out.println( "#" + (insnIdx - 1) + // " bci: " + bci + " " + // instr.toString().replace("org.objectweb.asm.tree.", "").replace("@", " @ ") + // " [" + (opcode>=0? Constants.opcNames[opcode] : " pseudo") +"]"); switch (opcode) { case IFEQ: case IFNE: case IFLT: case IFGE: case IFGT: case IFLE: case IF_ICMPEQ: case IF_ICMPNE: case IF_ICMPLT: case IF_ICMPGE: case IF_ICMPGT: case IF_ICMPLE: case IF_ACMPEQ: case IF_ACMPNE: case IFNULL: case IFNONNULL: case JSR: { JumpInsnNode jumpInsn = (JumpInsnNode) insn; LabelNode insnTrue = jumpInsn.label; int bciFalse = bcis[insnIdx]; // fall-through DataBranchCond branch = new DataBranchCond(method.rootId, bci, bciFalse - 1); /* DataBlockTarget blockTrue = new DataBlockTargetCond(true); DataBlockTarget blockFalse = new DataBlockTargetCond(false); branch.addTarget(blockTrue); branch.addTarget(blockFalse); */ AbstractInsnNode insnFalse = peek(iit); assert (insnFalse != null); // must be fall-through code SimpleBasicBlock bbTrue = getBB(insnTrue); SimpleBasicBlock bbFalse = getBB(insnFalse, bciFalse); exits.add(branch); // assign a new label for branch counting // LabelNode nlab = new LabelNode(); // jumpInsn.label = nlab; // branch to new label // bbTrue.add(blockTrue, nlab); //bbFalse.add(blockFalse); break; } case TABLESWITCH: { TableSwitchInsnNode switchInsn = (TableSwitchInsnNode) insn; // Create a block and basic-block the "default:" case LabelNode insnDflt = switchInsn.dflt; SimpleBasicBlock bbDefault = getBB(insnDflt); DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId()); // assign a new default label for branch counting //LabelNode nlab = new LabelNode(); //switchInsn.dflt = nlab; // branch to new label //bbDefault.add(blockDefault, nlab); // Create the branch information int bciEnd = bcis[insnIdx] - 1; // end of the switch DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault); // branch.addTarget(blockDefault); exits.add(branch); // Process the other cases ListIterator lit = switchInsn.labels.listIterator(); int key = switchInsn.min; while (lit.hasNext()) { // Create a block and basic-block the case LabelNode labCase = (LabelNode) lit.next(); SimpleBasicBlock bbCase = getBB(labCase); //DataBlockTargetCase blockCase = new DataBlockTargetCase(key++); //branch.addTarget(blockCase); // assign a new label to the case for branch counting //nlab = new LabelNode(); // lit.set(nlab); // bbCase.add(blockCase, nlab); } break; } case LOOKUPSWITCH: { LookupSwitchInsnNode switchInsn = (LookupSwitchInsnNode) insn; // Create a block and basic-block the "default:" case LabelNode insnDflt = switchInsn.dflt; SimpleBasicBlock bbDefault = getBB(insnDflt); DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId()); // assign a new default label for branch counting // LabelNode nlab = new LabelNode(); // switchInsn.dflt = nlab; // branch to new label // bbDefault.add(blockDefault, nlab); // Create the branch information int bciEnd = bcis[insnIdx] - 1; // end of the switch DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault); // branch.addTarget(blockDefault); exits.add(branch); // Process the other cases ListIterator kit = switchInsn.keys.listIterator(); ListIterator lit = switchInsn.labels.listIterator(); while (lit.hasNext()) { // Create a block and basic-block the case LabelNode labCase = (LabelNode) lit.next(); SimpleBasicBlock bbCase = getBB(labCase); Integer key = (Integer) kit.next(); // DataBlockTargetCase blockCase = new DataBlockTargetCase(key.intValue()); // branch.addTarget(blockCase); // assign a new label to the case for branch counting //nlab = new LabelNode(); //lit.set(nlab); //bbCase.add(blockCase, nlab); } break; } case GOTO: { JumpInsnNode jumpInsn = (JumpInsnNode) insn; // Create origin info, a branch int bciEnd = bcis[insnIdx] - 1; DataBranchGoto branch = new DataBranchGoto(method.rootId, bci, bciEnd); exits.add(branch); // Create destination info, a block target LabelNode insnTarget = jumpInsn.label; SimpleBasicBlock bbTarget = getBB(insnTarget); //DataBlockTarget blockTarget = new DataBlockTargetGoto(); //branch.addTarget(blockTarget); // assign a new label for branch counting //LabelNode nlab = new LabelNode(); //jumpInsn.label = nlab; // branch to new label //bbTarget.add(blockTarget, nlab); break; } case ATHROW: case RET: case IRETURN: case LRETURN: case FRETURN: case DRETURN: case ARETURN: case RETURN: { int bciNext = bcis[insnIdx]; DataExit exit = new DataExitSimple(method.rootId, bci, bciNext - 1, insn.getOpcode()); exits.add(exit); AbstractInsnNode insnNext = peek(iit); if (insnNext != null) { // If there is code after this, it has to be the start of a // new basic block getBB(insnNext, bciNext); } break; } default: break; } // try add src block } } // Now go through the try-catch blocks LabelNode previousHandler = null; for (Iterator tbit = methodNode.tryCatchBlocks.iterator(); tbit.hasNext();) { TryCatchBlockNode tcbn = (TryCatchBlockNode) tbit.next(); LabelNode insnHandler = tcbn.handler; if (insnHandler != previousHandler) { previousHandler = insnHandler; // Create destination info, a block target SimpleBasicBlock bbCatch = getBB(insnHandler); } } if (method().getCharacterRangeTable() != null) { boolean newBlock = true; int skip = 0; iit = instructions.iterator(); while (iit.hasNext()) { AbstractInsnNode insn = (AbstractInsnNode) iit.next(); int index = instructions.indexOf(insn); int bci = bcis[allToReal[index]]; if (bci == skip) { continue; } if (insnToBB.get(insn) != null) { skip = bcis[allToReal[instructions.indexOf(insn)]]; } if (insn.getOpcode() < 0) { continue; } for (CharacterRangeTableAttribute.CRTEntry entry : method().getCharacterRangeTable().getEntries()) { if (entry.startBCI() == bci) { if ((entry.flags & CRTEntry.CRT_STATEMENT) != 0 /*& newBlock*/) { newBlock = false; if (insnToBB.get(insn) == null) { //System.out.println("Should add block at: " + bci + " in " + method().name + // " for " + Constants.opcNames[insn.getOpcode()]); getBB(insn); break; } } } else { if (entry.endBCI() == index && (entry.flags & CRTEntry.CRT_FLOW_TARGET) != 0) { newBlock = true; } } } } } // Compute the startBCI for any basic blocks that don't have it' SimpleBasicBlock[] basicBlocks = new SimpleBasicBlock[insnToBB.size()]; int i = 0; for (Map.Entry<AbstractInsnNode, SimpleBasicBlock> entry : insnToBB.entrySet()) { SimpleBasicBlock bb = entry.getValue(); if (bb.startBCI() < 0) { AbstractInsnNode insn = entry.getKey(); int index = instructions.indexOf(insn); int bci = bcis[allToReal[index]]; bb.setStartBCI(bci); } basicBlocks[i++] = bb; } Arrays.sort(basicBlocks); return basicBlocks; }