protected void checkCov(String methodName) { MethodFlow flow = getFlow(methodName); if (flow == null) return; ArrayList<BasicBlock> bbs = flow.getBasicBlocks(); // Verify that all instructions are covered and that the only ones that // aren't are labelnodes. Also verify that there are no overlaps. int size = flow.instructions.size(); boolean coverage[] = new boolean[size]; for (int i = 0; i < size; i++) { coverage[i] = false; } for (BasicBlock bb : bbs) { /* * if (bb.startFrame == null) { fail("BB doesn't have a starting * frame"); return; } */ int end = bb.endPos; for (int i = bb.startPos; i <= end; i++) { if (coverage[i]) { fail("BasicBlock overlap"); return; } coverage[i] = true; } } for (int i = 0; i < size; i++) { if (!coverage[i]) { fail("Instruction " + i + " not covered"); return; } } }
private static void reportFlow(MethodFlow method, String className) { resetIndentation(); pn("Method : " + className + '.' + method.name); pn("MaxStack: " + method.maxStack); pn("MaxLocals: " + method.maxLocals); ArrayList<BasicBlock> bbs = method.getBasicBlocks(); Collections.sort(bbs); indent(2); for (BasicBlock bb : bbs) { AbstractInsnNode ainode = bb.getInstruction(bb.startPos); if (ainode instanceof MethodInsnNode) { MethodInsnNode m = (MethodInsnNode) ainode; int n = getNumArgs(m); // This many will get consumed from stack pn("Call(" + n + "): " + m.owner + "." + m.name + m.desc); indent(2); pn("Inframe: "); indent(2); Frame f = bb.startFrame; pn(f.toString()); dedent(2); pn("Live locals:"); indent(2); Usage u = bb.getVarUsage(); pn(u.toString()); dedent(2); pn("Actual usage: " + uniqueItems(bb, f, u, n)); dedent(2); } } dedent(2); }
/** Returns the first basic block in the flow that has a method invocation of <methodName> */ protected BasicBlock getBBForMethod(MethodFlow flow, String methodName) { for (BasicBlock bb : flow.getBasicBlocks()) { AbstractInsnNode ainode = bb.getInstruction(bb.startPos); if (ainode instanceof MethodInsnNode && ((MethodInsnNode) ainode).name.equals(methodName)) { return bb; } } fail("No method invocation found for " + methodName); return null; }