List of usage examples for org.objectweb.asm.tree InsnList indexOf
public int indexOf(final AbstractInsnNode insnNode)
From source file:com.android.tools.lint.checks.JavaScriptInterfaceDetector.java
License:Apache License
@Nullable private String findFirstArgType(ClassContext context, ClassNode classNode, MethodNode method, MethodInsnNode call) {// ww w. java2 s .co m // Find object being passed in as the first argument Analyzer analyzer = new Analyzer(new SourceInterpreter() { @Override public SourceValue newOperation(AbstractInsnNode insn) { if (insn.getOpcode() == Opcodes.NEW) { String desc = ((TypeInsnNode) insn).desc; return new TypeValue(1, desc); } return super.newOperation(insn); } @Override public SourceValue newValue(Type type) { if (type != null && type.getSort() == Type.VOID) { return null; } else if (type != null) { return new TypeValue(1, type.getInternalName()); } return super.newValue(type); } @Override public SourceValue copyOperation(AbstractInsnNode insn, SourceValue value) { return value; } }); try { Frame[] frames = analyzer.analyze(classNode.name, method); InsnList instructions = method.instructions; Frame frame = frames[instructions.indexOf(call)]; if (frame.getStackSize() <= 1) { return null; } SourceValue stackValue = (SourceValue) frame.getStack(1); if (stackValue instanceof TypeValue) { return ((TypeValue) stackValue).getFqcn(); } } catch (AnalyzerException e) { context.log(e, null); } return null; }
From source file:com.android.tools.lint.checks.LocaleDetector.java
License:Apache License
@Override public void checkCall(@NonNull ClassContext context, @NonNull ClassNode classNode, @NonNull MethodNode method, @NonNull MethodInsnNode call) {/* w w w. j a v a2 s. c o m*/ String owner = call.owner; String desc = call.desc; String name = call.name; if (owner.equals(DATE_FORMAT_OWNER)) { if (!name.equals(CONSTRUCTOR_NAME)) { return; } if (desc.equals("(Ljava/lang/String;Ljava/text/DateFormatSymbols;)V") //$NON-NLS-1$ || desc.equals("()V") //$NON-NLS-1$ || desc.equals("(Ljava/lang/String;)V")) { //$NON-NLS-1$ Location location = context.getLocation(call); String message = "To get local formatting use getDateInstance(), getDateTimeInstance(), " + "or getTimeInstance(), or use new SimpleDateFormat(String template, " + "Locale locale) with for example Locale.US for ASCII dates."; context.report(DATE_FORMAT, method, call, location, message, null); } return; } else if (!owner.equals(STRING_OWNER)) { return; } if (name.equals(FORMAT_METHOD)) { // Only check the non-locale version of String.format if (!desc.equals("(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;")) { //$NON-NLS-1$ return; } // Find the formatting string Analyzer analyzer = new Analyzer(new SourceInterpreter() { @Override public SourceValue newOperation(AbstractInsnNode insn) { if (insn.getOpcode() == Opcodes.LDC) { Object cst = ((LdcInsnNode) insn).cst; if (cst instanceof String) { return new StringValue(1, (String) cst); } } return super.newOperation(insn); } }); try { Frame[] frames = analyzer.analyze(classNode.name, method); InsnList instructions = method.instructions; Frame frame = frames[instructions.indexOf(call)]; if (frame.getStackSize() == 0) { return; } SourceValue stackValue = (SourceValue) frame.getStack(0); if (stackValue instanceof StringValue) { String format = ((StringValue) stackValue).getString(); if (format != null && StringFormatDetector.isLocaleSpecific(format)) { Location location = context.getLocation(call); String message = "Implicitly using the default locale is a common source of bugs: " + "Use String.format(Locale, ...) instead"; context.report(STRING_LOCALE, method, call, location, message, null); } } } catch (AnalyzerException e) { context.log(e, null); } } else { if (desc.equals("()Ljava/lang/String;")) { //$NON-NLS-1$ Location location = context.getLocation(call); String message = String.format("Implicitly using the default locale is a common source of bugs: " + "Use %1$s(Locale) instead", name); context.report(STRING_LOCALE, method, call, location, message, null); } } }
From source file:com.android.tools.lint.checks.SecureRandomDetector.java
License:Apache License
@Override public void checkCall(@NonNull ClassContext context, @NonNull ClassNode classNode, @NonNull MethodNode method, @NonNull MethodInsnNode call) {/*w w w . ja v a2s . c o m*/ String owner = call.owner; String desc = call.desc; if (owner.equals(OWNER_SECURE_RANDOM)) { if (desc.startsWith(LONG_ARG)) { checkValidSetSeed(context, call); } else if (desc.startsWith("([B)")) { //$NON-NLS-1$ // setSeed(byte[]) ... // We could do some flow analysis here to see whether the byte array getting // passed in appears to be fixed. // However, people calling this constructor rather than the simpler one // with a fixed integer are probably less likely to make that mistake... right? } } else if (owner.equals(OWNER_RANDOM) && desc.startsWith(LONG_ARG)) { // Called setSeed(long) on an instanceof a Random object. Flag this if the instance // is likely a SecureRandom. // Track allocations such that we know whether the type of the call // is on a SecureRandom rather than a Random Analyzer analyzer = new Analyzer(new BasicInterpreter() { @Override public BasicValue newValue(Type type) { if (type != null && type.getDescriptor().equals(VM_SECURE_RANDOM)) { return new BasicValue(type); } return super.newValue(type); } }); try { Frame[] frames = analyzer.analyze(classNode.name, method); InsnList instructions = method.instructions; Frame frame = frames[instructions.indexOf(call)]; int stackSlot = frame.getStackSize(); for (Type type : Type.getArgumentTypes(desc)) { stackSlot -= type.getSize(); } BasicValue stackValue = (BasicValue) frame.getStack(stackSlot); Type type = stackValue.getType(); if (type != null && type.getDescriptor().equals(VM_SECURE_RANDOM)) { checkValidSetSeed(context, call); } } catch (AnalyzerException e) { context.log(e, null); } } else if (owner.equals(OWNER_RANDOM) && desc.startsWith(LONG_ARG)) { // Called setSeed(long) on an instanceof a Random object. Flag this if the instance // is likely a SecureRandom. // TODO } }
From source file:com.android.tools.lint.checks.ViewTagDetector.java
License:Apache License
@Override public void checkCall(@NonNull ClassContext context, @NonNull ClassNode classNode, @NonNull MethodNode method, @NonNull MethodInsnNode call) {//from www . j a v a2 s. c o m // The leak behavior is fixed in ICS: // http://code.google.com/p/android/issues/detail?id=18273 if (context.getMainProject().getMinSdk() >= 14) { return; } String owner = call.owner; String desc = call.desc; if (owner.equals("android/view/View") //$NON-NLS-1$ && desc.equals("(ILjava/lang/Object;)V")) { //$NON-NLS-1$ Analyzer analyzer = new Analyzer(new BasicInterpreter() { @Override public BasicValue newValue(Type type) { if (type == null) { return BasicValue.UNINITIALIZED_VALUE; } else if (type.getSort() == Type.VOID) { return null; } else { return new BasicValue(type); } } }); try { Frame[] frames = analyzer.analyze(classNode.name, method); InsnList instructions = method.instructions; Frame frame = frames[instructions.indexOf(call)]; if (frame.getStackSize() < 3) { return; } BasicValue stackValue = (BasicValue) frame.getStack(2); Type type = stackValue.getType(); if (type == null) { return; } String internalName = type.getInternalName(); String className = type.getClassName(); LintDriver driver = context.getDriver(); SdkInfo sdkInfo = context.getClient().getSdkInfo(context.getMainProject()); String objectType = null; while (className != null) { if (className.equals("android.view.View")) { //$NON-NLS-1$ objectType = "views"; break; } else if (className.endsWith("ViewHolder")) { //$NON-NLS-1$ objectType = "view holders"; break; } else if (className.endsWith("Cursor") //$NON-NLS-1$ && className.startsWith("android.")) { //$NON-NLS-1$ objectType = "cursors"; break; } // TBD: Bitmaps, drawables? That's tricky, because as explained in // http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html // apparently these are used along with nulling out the callbacks, // and that's harder to detect here String parent = sdkInfo.getParentViewClass(className); if (parent == null) { if (internalName == null) { internalName = className.replace('.', '/'); } assert internalName != null; parent = driver.getSuperClass(internalName); } className = parent; internalName = null; } if (objectType != null) { Location location = context.getLocation(call); String message = String.format("Avoid setting %1$s as values for setTag: " + "Can lead to memory leaks in versions older than Android 4.0", objectType); context.report(ISSUE, method, call, location, message, null); } } catch (AnalyzerException e) { context.log(e, null); } } }
From source file:com.lodgon.parboiled.transform.InstructionGroupCreator.java
License:Open Source License
private void sort(InstructionGroup group) { final InsnList instructions = method.instructions; Collections.sort(group.getNodes(), new Comparator<InstructionGraphNode>() { public int compare(InstructionGraphNode a, InstructionGraphNode b) { return Integer.valueOf(instructions.indexOf(a.getInstruction())) .compareTo(instructions.indexOf(b.getInstruction())); }// www . j a v a2 s . co m }); }
From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtils.java
License:Open Source License
/** * Find line number associated with an instruction. * @param insnList instruction list for method * @param insnNode instruction within method being searched against * @throws NullPointerException if any argument is {@code null} or contains {@code null} * @throws IllegalArgumentException if arguments aren't all from the same method * @return line number node associated with the instruction, or {@code null} if no line number exists */// w w w.ja v a 2s . c om public static LineNumberNode findLineNumberForInstruction(InsnList insnList, AbstractInsnNode insnNode) { Validate.notNull(insnList); Validate.notNull(insnNode); int idx = insnList.indexOf(insnNode); Validate.isTrue(idx != -1); // Get index of labels and insnNode within method ListIterator<AbstractInsnNode> insnIt = insnList.iterator(idx); while (insnIt.hasPrevious()) { AbstractInsnNode node = insnIt.previous(); if (node instanceof LineNumberNode) { return (LineNumberNode) node; } } return null; }
From source file:com.sun.tdk.jcov.instrument.BlockCodeMethodAdapter.java
License:Open Source License
private SimpleBasicBlock[] completeComputationOfCodeLabelNodes() { MethodNode methodNode = (MethodNode) mv; InsnList instructions = methodNode.instructions; int[] allToReal = new int[instructions.size()]; int allIdx = 0; int insnIdx = 0; ListIterator iit = instructions.iterator(); // Create the method entry block and basic block AbstractInsnNode insnFirst = peek(iit); SimpleBasicBlock bbFirst = getBB(insnFirst, 0); // DataBlock blockFirst = new DataBlockMethEnter(); // bbFirst.add(blockFirst); while (iit.hasNext()) { AbstractInsnNode insn = (AbstractInsnNode) iit.next(); allToReal[allIdx++] = insnIdx;//w ww . j ava 2 s. c om int bci = bcis[insnIdx]; int opcode = insn.getOpcode(); if (opcode < 0) { // a pseudo-instruction if (insn.getType() == AbstractInsnNode.LINE) { LineNumberNode lineNode = (LineNumberNode) insn; method().addLineEntry(bci, lineNode.line); } } else { // a real instruction ++insnIdx; // advance the real instruction index //System.out.println( "#" + (insnIdx - 1) + // " bci: " + bci + " " + // instr.toString().replace("org.objectweb.asm.tree.", "").replace("@", " @ ") + // " [" + (opcode>=0? Constants.opcNames[opcode] : " pseudo") +"]"); switch (opcode) { case IFEQ: case IFNE: case IFLT: case IFGE: case IFGT: case IFLE: case IF_ICMPEQ: case IF_ICMPNE: case IF_ICMPLT: case IF_ICMPGE: case IF_ICMPGT: case IF_ICMPLE: case IF_ACMPEQ: case IF_ACMPNE: case IFNULL: case IFNONNULL: case JSR: { JumpInsnNode jumpInsn = (JumpInsnNode) insn; LabelNode insnTrue = jumpInsn.label; int bciFalse = bcis[insnIdx]; // fall-through DataBranchCond branch = new DataBranchCond(method.rootId, bci, bciFalse - 1); /* DataBlockTarget blockTrue = new DataBlockTargetCond(true); DataBlockTarget blockFalse = new DataBlockTargetCond(false); branch.addTarget(blockTrue); branch.addTarget(blockFalse); */ AbstractInsnNode insnFalse = peek(iit); assert (insnFalse != null); // must be fall-through code SimpleBasicBlock bbTrue = getBB(insnTrue); SimpleBasicBlock bbFalse = getBB(insnFalse, bciFalse); exits.add(branch); // assign a new label for branch counting // LabelNode nlab = new LabelNode(); // jumpInsn.label = nlab; // branch to new label // bbTrue.add(blockTrue, nlab); //bbFalse.add(blockFalse); break; } case TABLESWITCH: { TableSwitchInsnNode switchInsn = (TableSwitchInsnNode) insn; // Create a block and basic-block the "default:" case LabelNode insnDflt = switchInsn.dflt; SimpleBasicBlock bbDefault = getBB(insnDflt); DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId()); // assign a new default label for branch counting //LabelNode nlab = new LabelNode(); //switchInsn.dflt = nlab; // branch to new label //bbDefault.add(blockDefault, nlab); // Create the branch information int bciEnd = bcis[insnIdx] - 1; // end of the switch DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault); // branch.addTarget(blockDefault); exits.add(branch); // Process the other cases ListIterator lit = switchInsn.labels.listIterator(); int key = switchInsn.min; while (lit.hasNext()) { // Create a block and basic-block the case LabelNode labCase = (LabelNode) lit.next(); SimpleBasicBlock bbCase = getBB(labCase); //DataBlockTargetCase blockCase = new DataBlockTargetCase(key++); //branch.addTarget(blockCase); // assign a new label to the case for branch counting //nlab = new LabelNode(); // lit.set(nlab); // bbCase.add(blockCase, nlab); } break; } case LOOKUPSWITCH: { LookupSwitchInsnNode switchInsn = (LookupSwitchInsnNode) insn; // Create a block and basic-block the "default:" case LabelNode insnDflt = switchInsn.dflt; SimpleBasicBlock bbDefault = getBB(insnDflt); DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId()); // assign a new default label for branch counting // LabelNode nlab = new LabelNode(); // switchInsn.dflt = nlab; // branch to new label // bbDefault.add(blockDefault, nlab); // Create the branch information int bciEnd = bcis[insnIdx] - 1; // end of the switch DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault); // branch.addTarget(blockDefault); exits.add(branch); // Process the other cases ListIterator kit = switchInsn.keys.listIterator(); ListIterator lit = switchInsn.labels.listIterator(); while (lit.hasNext()) { // Create a block and basic-block the case LabelNode labCase = (LabelNode) lit.next(); SimpleBasicBlock bbCase = getBB(labCase); Integer key = (Integer) kit.next(); // DataBlockTargetCase blockCase = new DataBlockTargetCase(key.intValue()); // branch.addTarget(blockCase); // assign a new label to the case for branch counting //nlab = new LabelNode(); //lit.set(nlab); //bbCase.add(blockCase, nlab); } break; } case GOTO: { JumpInsnNode jumpInsn = (JumpInsnNode) insn; // Create origin info, a branch int bciEnd = bcis[insnIdx] - 1; DataBranchGoto branch = new DataBranchGoto(method.rootId, bci, bciEnd); exits.add(branch); // Create destination info, a block target LabelNode insnTarget = jumpInsn.label; SimpleBasicBlock bbTarget = getBB(insnTarget); //DataBlockTarget blockTarget = new DataBlockTargetGoto(); //branch.addTarget(blockTarget); // assign a new label for branch counting //LabelNode nlab = new LabelNode(); //jumpInsn.label = nlab; // branch to new label //bbTarget.add(blockTarget, nlab); break; } case ATHROW: case RET: case IRETURN: case LRETURN: case FRETURN: case DRETURN: case ARETURN: case RETURN: { int bciNext = bcis[insnIdx]; DataExit exit = new DataExitSimple(method.rootId, bci, bciNext - 1, insn.getOpcode()); exits.add(exit); AbstractInsnNode insnNext = peek(iit); if (insnNext != null) { // If there is code after this, it has to be the start of a // new basic block getBB(insnNext, bciNext); } break; } default: break; } // try add src block } } // Now go through the try-catch blocks LabelNode previousHandler = null; for (Iterator tbit = methodNode.tryCatchBlocks.iterator(); tbit.hasNext();) { TryCatchBlockNode tcbn = (TryCatchBlockNode) tbit.next(); LabelNode insnHandler = tcbn.handler; if (insnHandler != previousHandler) { previousHandler = insnHandler; // Create destination info, a block target SimpleBasicBlock bbCatch = getBB(insnHandler); } } if (method().getCharacterRangeTable() != null) { boolean newBlock = true; int skip = 0; iit = instructions.iterator(); while (iit.hasNext()) { AbstractInsnNode insn = (AbstractInsnNode) iit.next(); int index = instructions.indexOf(insn); int bci = bcis[allToReal[index]]; if (bci == skip) { continue; } if (insnToBB.get(insn) != null) { skip = bcis[allToReal[instructions.indexOf(insn)]]; } if (insn.getOpcode() < 0) { continue; } for (CharacterRangeTableAttribute.CRTEntry entry : method().getCharacterRangeTable().getEntries()) { if (entry.startBCI() == bci) { if ((entry.flags & CRTEntry.CRT_STATEMENT) != 0 /*& newBlock*/) { newBlock = false; if (insnToBB.get(insn) == null) { //System.out.println("Should add block at: " + bci + " in " + method().name + // " for " + Constants.opcNames[insn.getOpcode()]); getBB(insn); break; } } } else { if (entry.endBCI() == index && (entry.flags & CRTEntry.CRT_FLOW_TARGET) != 0) { newBlock = true; } } } } } // Compute the startBCI for any basic blocks that don't have it' SimpleBasicBlock[] basicBlocks = new SimpleBasicBlock[insnToBB.size()]; int i = 0; for (Map.Entry<AbstractInsnNode, SimpleBasicBlock> entry : insnToBB.entrySet()) { SimpleBasicBlock bb = entry.getValue(); if (bb.startBCI() < 0) { AbstractInsnNode insn = entry.getKey(); int index = instructions.indexOf(insn); int bci = bcis[allToReal[index]]; bb.setStartBCI(bci); } basicBlocks[i++] = bb; } Arrays.sort(basicBlocks); return basicBlocks; }
From source file:com.sun.tdk.jcov.instrument.BranchCodeMethodAdapter.java
License:Open Source License
/** * Do fix ups so that: There are unique CodeLabelNodes at the beginning of * each basic block; All branch-mode blocks hang off CodeLabelNodes Misc * info, like case values, are attached Fall throughs from one block to * another are computed// w w w . java 2 s. c o m * */ private BasicBlock[] completeComputationOfCodeLabelNodes() { MethodNode methodNode = (MethodNode) mv; InsnList instructions = methodNode.instructions; int[] allToReal = new int[instructions.size()]; int allIdx = 0; int insnIdx = 0; ListIterator iit = instructions.iterator(); // Create the method entry block and basic block AbstractInsnNode insnFirst = peek(iit); BasicBlock bbFirst = getBB(insnFirst, 0); DataBlock blockFirst = new DataBlockMethEnter(bbFirst.rootId()); bbFirst.add(blockFirst); while (iit.hasNext()) { AbstractInsnNode insn = (AbstractInsnNode) iit.next(); allToReal[allIdx++] = insnIdx; int bci = bcis[insnIdx]; int opcode = insn.getOpcode(); if (opcode < 0) { // a pseudo-instruction if (insn.getType() == AbstractInsnNode.LINE) { LineNumberNode lineNode = (LineNumberNode) insn; method().addLineEntry(bci, lineNode.line); } } else { // a real instruction ++insnIdx; // advance the real instruction index //System.out.println( "#" + (insnIdx - 1) + // " bci: " + bci + " " + // instr.toString().replace("org.objectweb.asm.tree.", "").replace("@", " @ ") + // " [" + (opcode>=0? Constants.opcNames[opcode] : " pseudo") +"]"); switch (opcode) { case IFEQ: case IFNE: case IFLT: case IFGE: case IFGT: case IFLE: case IF_ICMPEQ: case IF_ICMPNE: case IF_ICMPLT: case IF_ICMPGE: case IF_ICMPGT: case IF_ICMPLE: case IF_ACMPEQ: case IF_ACMPNE: case IFNULL: case IFNONNULL: //case JSR: { JumpInsnNode jumpInsn = (JumpInsnNode) insn; LabelNode insnTrue = jumpInsn.label; int bciFalse = bcis[insnIdx]; // fall-through DataBranchCond branch = new DataBranchCond(method.rootId, bci, bciFalse - 1); DataBlockTarget blockTrue = new DataBlockTargetCond(branch.rootId(), true); DataBlockTarget blockFalse = new DataBlockTargetCond(branch.rootId(), false); branch.addTarget(blockTrue); branch.addTarget(blockFalse); AbstractInsnNode insnFalse = peek(iit); assert (insnFalse != null); // must be fall-through code BasicBlock bbTrue = getBB(insnTrue); BasicBlock bbFalse = getBB(insnFalse, bciFalse); exits.add(branch); // assign a new label for branch counting LabelNode nlab = new LabelNode(); jumpInsn.label = nlab; // branch to new label bbTrue.add(blockTrue, nlab); bbFalse.add(blockFalse); break; } case TABLESWITCH: { TableSwitchInsnNode switchInsn = (TableSwitchInsnNode) insn; // Create a block and basic-block the "default:" case LabelNode insnDflt = switchInsn.dflt; BasicBlock bbDefault = getBB(insnDflt); DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId()); // assign a new default label for branch counting LabelNode nlab = new LabelNode(); switchInsn.dflt = nlab; // branch to new label bbDefault.add(blockDefault, nlab); // Create the branch information int bciEnd = bcis[insnIdx] - 1; // end of the switch DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault); branch.addTarget(blockDefault); exits.add(branch); // Process the other cases ListIterator lit = switchInsn.labels.listIterator(); int key = switchInsn.min; while (lit.hasNext()) { // Create a block and basic-block the case LabelNode labCase = (LabelNode) lit.next(); BasicBlock bbCase = getBB(labCase); DataBlockTargetCase blockCase = new DataBlockTargetCase(bbCase.rootId(), key++); branch.addTarget(blockCase); // assign a new label to the case for branch counting nlab = new LabelNode(); lit.set(nlab); bbCase.add(blockCase, nlab); } break; } case LOOKUPSWITCH: { LookupSwitchInsnNode switchInsn = (LookupSwitchInsnNode) insn; // Create a block and basic-block the "default:" case LabelNode insnDflt = switchInsn.dflt; BasicBlock bbDefault = getBB(insnDflt); DataBlockTargetDefault blockDefault = new DataBlockTargetDefault(bbDefault.rootId()); // assign a new default label for branch counting LabelNode nlab = new LabelNode(); switchInsn.dflt = nlab; // branch to new label bbDefault.add(blockDefault, nlab); // Create the branch information int bciEnd = bcis[insnIdx] - 1; // end of the switch DataBranchSwitch branch = new DataBranchSwitch(method.rootId, bci, bciEnd, blockDefault); branch.addTarget(blockDefault); exits.add(branch); // Process the other cases ListIterator kit = switchInsn.keys.listIterator(); ListIterator lit = switchInsn.labels.listIterator(); while (lit.hasNext()) { // Create a block and basic-block the case LabelNode labCase = (LabelNode) lit.next(); BasicBlock bbCase = getBB(labCase); Integer key = (Integer) kit.next(); DataBlockTargetCase blockCase = new DataBlockTargetCase(branch.rootId(), key.intValue()); branch.addTarget(blockCase); // assign a new label to the case for branch counting nlab = new LabelNode(); lit.set(nlab); bbCase.add(blockCase, nlab); } break; } case GOTO: { JumpInsnNode jumpInsn = (JumpInsnNode) insn; // Create origin info, a branch int bciEnd = bcis[insnIdx] - 1; DataBranchGoto branch = new DataBranchGoto(method.rootId, bci, bciEnd); exits.add(branch); // Create destination info, a block target LabelNode insnTarget = jumpInsn.label; BasicBlock bbTarget = getBB(insnTarget); DataBlockTarget blockTarget = new DataBlockTargetGoto(bbTarget.rootId()); branch.addTarget(blockTarget); // assign a new label for branch counting LabelNode nlab = new LabelNode(); jumpInsn.label = nlab; // branch to new label bbTarget.add(blockTarget, nlab); break; } case ATHROW: case RET: case IRETURN: case LRETURN: case FRETURN: case DRETURN: case ARETURN: case RETURN: { int bciNext = bcis[insnIdx]; DataExit exit = new DataExitSimple(method.rootId, bci, bciNext - 1, insn.getOpcode()); exits.add(exit); AbstractInsnNode insnNext = peek(iit); if (insnNext != null) { // If there is code after this, it has to be the start of a // new basic block getBB(insnNext, bciNext); } break; } default: break; } // try add src block } } // Now go through the try-catch blocks LabelNode previousHandler = null; for (Iterator tbit = methodNode.tryCatchBlocks.iterator(); tbit.hasNext();) { TryCatchBlockNode tcbn = (TryCatchBlockNode) tbit.next(); LabelNode insnHandler = tcbn.handler; if (insnHandler != previousHandler) { previousHandler = insnHandler; // Create destination info, a block target BasicBlock bbCatch = getBB(insnHandler); DataBlockCatch blockCatch = new DataBlockCatch(bbCatch.rootId()); // assign a new label for catch counting LabelNode nlab = new LabelNode(); tcbn.handler = nlab; // change handler bbCatch.add(blockCatch, nlab); } } if (method().getCharacterRangeTable() != null) { boolean newBlock = true; int skip = 0; iit = instructions.iterator(); while (iit.hasNext()) { AbstractInsnNode insn = (AbstractInsnNode) iit.next(); int index = instructions.indexOf(insn); int bci = bcis[allToReal[index]]; if (bci == skip) { continue; } if (insnToBB.get(insn) != null) { skip = bcis[allToReal[instructions.indexOf(insn)]]; } if (insn.getOpcode() < 0) { continue; } for (CharacterRangeTableAttribute.CRTEntry entry : method().getCharacterRangeTable().getEntries()) { if (entry.startBCI() == bci) { if ((entry.flags & CRTEntry.CRT_STATEMENT) != 0 /*& newBlock*/) { newBlock = false; if (insnToBB.get(insn) == null) { //System.out.println("Should add block at: " + bci + " in " + method().name + // " for " + Constants.opcNames[insn.getOpcode()]); getBB(insn); break; } } } else { if (entry.endBCI() == index && (entry.flags & CRTEntry.CRT_FLOW_TARGET) != 0) { newBlock = true; } } } } } // Compute the startBCI for any basic blocks that don't have it' BasicBlock[] basicBlocks = new BasicBlock[insnToBB.size()]; int i = 0; for (Map.Entry<AbstractInsnNode, BasicBlock> entry : insnToBB.entrySet()) { BasicBlock bb = entry.getValue(); if (bb.startBCI() < 0) { AbstractInsnNode insn = entry.getKey(); int index = instructions.indexOf(insn); int bci = bcis[allToReal[index]]; bb.setStartBCI(bci); } basicBlocks[i++] = bb; } Arrays.sort(basicBlocks); return basicBlocks; }
From source file:edu.mit.streamjit.util.bytecode.MethodResolver.java
License:Open Source License
private void findBlockBoundaries() { InsnList insns = methodNode.instructions; //We find the indices of any block-ending instruction and of any jump //target, sort, remove duplicates, then use pairs to define blocks. Note //these are end-exclusive indices, thus one after the block-enders, but //right on the jump targets (they're one-past-the-end of the preceding //block).//from w w w . jav a2s. com List<Integer> indices = new ArrayList<>(); indices.add(0); for (int i = 0; i < insns.size(); ++i) { AbstractInsnNode insn = insns.get(i); int opcode = insn.getOpcode(); //Terminator opcodes end blocks. if (insn instanceof JumpInsnNode || insn instanceof LookupSwitchInsnNode || insn instanceof TableSwitchInsnNode || opcode == Opcodes.ATHROW || opcode == Opcodes.IRETURN || opcode == Opcodes.LRETURN || opcode == Opcodes.FRETURN || opcode == Opcodes.DRETURN || opcode == Opcodes.ARETURN || opcode == Opcodes.RETURN) { indices.add(i + 1); } //Jump targets of this instruction end blocks. if (insn instanceof JumpInsnNode) indices.add(insns.indexOf(((JumpInsnNode) insn).label)); else if (insn instanceof LookupSwitchInsnNode) { indices.add(insns.indexOf(((LookupSwitchInsnNode) insn).dflt)); for (Object label : ((LookupSwitchInsnNode) insn).labels) indices.add(insns.indexOf((LabelNode) label)); } else if (insn instanceof TableSwitchInsnNode) { indices.add(insns.indexOf(((TableSwitchInsnNode) insn).dflt)); for (Object label : ((TableSwitchInsnNode) insn).labels) indices.add(insns.indexOf((LabelNode) label)); } //While we're scanning the instructions, make the UninitializedValue //values for 'new' opcodes. if (opcode == Opcodes.NEW) { Klass k = getKlassByInternalName(((TypeInsnNode) insn).desc); ReferenceType t = typeFactory.getReferenceType(k); newValues.put(insn, new UninitializedValue(t, "new" + (counter++))); } } //Remove duplicates and sort via TreeSet. indices = new ArrayList<>(new TreeSet<>(indices)); for (int i = 1; i < indices.size(); ++i) blocks.add(new BBInfo(indices.get(i - 1), indices.get(i), i - 1)); }
From source file:net.epoxide.surge.asm.ASMUtils.java
License:Creative Commons License
/** * Removes a specific set of instructions (the needle) from a much larger set of * instructions (the hay stack). Be cautious when using this method, as it is almost never * a good idea to remove instructions./*from w w w . j ava 2s. co m*/ * * @param haystack: A large list of instructions which is being searched through. * @param needle: A specific list of instructions which are to be removed from the larger * instruction list. */ public static void removeNeedleFromHaystack(InsnList haystack, InsnList needle) { final int firstInd = haystack.indexOf(findFirstNodeFromNeedle(haystack, needle)); final int lastInd = haystack.indexOf(findLastNodeFromNeedle(haystack, needle)); final List<AbstractInsnNode> realNeedle = new ArrayList<AbstractInsnNode>(); for (int i = firstInd; i <= lastInd; i++) realNeedle.add(haystack.get(i)); for (final AbstractInsnNode node : realNeedle) haystack.remove(node); }