public void writeDetails(Instruction instr) { String indent = space(40); // could get from Options? Set<Integer> lines = lineMap.get(instr.getPC()); if (lines != null) { for (int line: lines) { print(indent); print(String.format(" %4d ", line)); if (line < sourceLines.length) print(sourceLines[line]); println(); int nextLine = nextLine(line); for (int i = line + 1; i < nextLine; i++) { print(indent); print(String.format("(%4d)", i)); if (i < sourceLines.length) print(sourceLines[i]); println(); } } } }
static void checkMethod(String cname, String mname, ConstantPool cp, Code_attribute code) throws ConstantPool.InvalidIndex { for (Instruction i : code.getInstructions()) { String iname = i.getMnemonic(); if ("invokespecial".equals(iname) || "invokestatic".equals(iname)) { int idx = i.getByte(2); System.out.println("Verifying " + cname + ":" + mname + " instruction:" + iname + " index @" + idx); CPInfo cpinfo = cp.get(idx); if (cpinfo instanceof ConstantPool.CONSTANT_Methodref_info) { throw new RuntimeException("unexpected CP type expected " + "InterfaceMethodRef, got MethodRef, " + cname + ", " + mname); } } } }
void checkClassFile(final Path path) throws Exception { ClassFile classFile = ClassFile.read( new BufferedInputStream(Files.newInputStream(path))); constantPool = classFile.constant_pool; utf8Index = constantPool.getUTF8Index("STR_TO_LOOK_FOR"); for (Method method: classFile.methods) { if (method.getName(constantPool).equals("methodToLookFor")) { Code_attribute codeAtt = (Code_attribute)method.attributes.get(Attribute.Code); for (Instruction inst: codeAtt.getInstructions()) { inst.accept(codeVisitor, null); } } } Assert.check(numberOfRefToStr == 1, "There should only be one reference to a CONSTANT_String_info structure in the generated code"); }
void verifyDefaultBody(String classFile) { String workDir = System.getProperty("test.classes"); File file = new File(workDir, classFile); try { final ClassFile cf = ClassFile.read(file); for (Method m : cf.methods) { Code_attribute codeAttr = (Code_attribute)m.attributes.get(Attribute.Code); for (Instruction instr : codeAttr.getInstructions()) { if (instr.getOpcode() == Opcode.INVOKESPECIAL) { int pc_index = instr.getShort(1); CPRefInfo ref = (CPRefInfo)cf.constant_pool.get(pc_index); String className = ref.getClassName(); if (className.equals("BaseInterface")) throw new IllegalStateException("Must not directly refer to TestedInterface"); } } } } catch (Exception e) { e.printStackTrace(); throw new Error("error reading " + file +": " + e); } }
@Override void writeDetails(Instruction instr) { String indent = space(2); // get from Options? int pc = instr.getPC(); List<Note> notes = pcMap.get(pc); if (notes != null) { for (Note n: notes) { print(indent); print("@"); annotationWriter.write(n.anno, false, true); print(", "); println(StringUtils.toLowerCase(n.kind.toString())); } } }
public void writeTrys(Instruction instr, NoteKind kind) { String indent = space(2); // get from Options? int pc = instr.getPC(); List<Exception_data> entries = pcMap.get(pc); if (entries != null) { for (ListIterator<Exception_data> iter = entries.listIterator(kind == NoteKind.END ? entries.size() : 0); kind == NoteKind.END ? iter.hasPrevious() : iter.hasNext() ; ) { Exception_data entry = kind == NoteKind.END ? iter.previous() : iter.next(); if (kind.match(entry, pc)) { print(indent); print(kind.text); print("["); print(indexMap.get(entry)); print("] "); if (entry.catch_type == 0) print("finally"); else { print("#" + entry.catch_type); print(" // "); constantWriter.write(entry.catch_type); } println(); } } } }
public void writeInstr(Instruction instr) { print(String.format("%4d: %-13s ", instr.getPC(), instr.getMnemonic())); // compute the number of indentations for the body of multi-line instructions // This is 6 (the width of "%4d: "), divided by the width of each indentation level, // and rounded up to the next integer. int indentWidth = options.indentWidth; int indent = (6 + indentWidth - 1) / indentWidth; instr.accept(instructionPrinter, indent); println(); }
public Void visitConstantPoolRef(Instruction instr, int index, Integer indent) { print("#" + index); tab(); print("// "); printConstant(index); return null; }
public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Integer indent) { print("#" + index + ", " + value); tab(); print("// "); printConstant(index); return null; }
public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, Integer indent) { int pc = instr.getPC(); print("{ // " + npairs); indent(indent); for (int i = 0; i < npairs; i++) { print(String.format("%n%12d: %d", matches[i], (pc + offsets[i]))); } print("\n default: " + (pc + default_) + "\n}"); indent(-indent); return null; }
public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, Integer indent) { int pc = instr.getPC(); print("{ // " + low + " to " + high); indent(indent); for (int i = 0; i < offsets.length; i++) { print(String.format("%n%12d: %d", (low + i), (pc + offsets[i]))); } print("\n default: " + (pc + default_) + "\n}"); indent(-indent); return null; }
private Element instructions(Element code, Code_attribute c) { Element ielement = new Element("Instructions"); for (Instruction ins : c.getInstructions()) { ielement.add(iv.visit(ins)); } ielement.trimToSize(); return ielement; }
@Override public Element visitNoOperands(Instruction i, Void p) { Opcode o = i.getOpcode(); Element e = new Element(i.getMnemonic()); if (o.opcode > 0xab && o.opcode <= 0xb1) { e.setAttr("pc", "" + i.getPC()); } return e; }
@Override public Element visitArrayType(Instruction i, TypeKind tk, Void p) { Element ie = new Element(i.getMnemonic()); ie.setAttr("num", "" + tk.value); ie.setAttr("val", tk.name); return ie; }
@Override public Element visitConstantPoolRefAndValue(Instruction i, int i1, int i2, Void p) { // workaround for a potential bug in classfile Element ie = new Element(i.getMnemonic()); if (i.getOpcode().equals(Opcode.IINC_W)) { ie.setAttr("loc", "" + i1); ie.setAttr("num", "" + i2); } else { ie.setAttr("ref", x.getCpString(i1)); ie.setAttr("val", "" + i2); } return ie; }
@Override public Element visitLocalAndValue(Instruction i, int i1, int i2, Void p) { Element ie = new Element(i.getMnemonic()); ie.setAttr("loc", "" + i1); ie.setAttr("num", "" + i2); return ie; }
@Override public Element visitLookupSwitch(Instruction i, int i1, int i2, int[] ints, int[] ints1, Void p) { Element ie = new Element(i.getMnemonic()); int pc = i.getPC(); ie.setAttr("lab", "" + (pc + i1)); for (int k = 0 ; k < i2 ; k++) { Element c = new Element("Case"); c.setAttr("num", "" + (ints[k])); c.setAttr("lab", "" + (pc + ints1[k])); c.trimToSize(); ie.add(c); } return ie; }
@Override public Element visitTableSwitch(Instruction i, int i1, int i2, int i3, int[] ints, Void p) { Element ie = new Element(i.getMnemonic()); int pc = i.getPC(); ie.setAttr("lab", "" + (pc + i1)); for (int k : ints) { Element c = new Element("Case"); c.setAttr("num", "" + (k + i2)); c.setAttr("lab", "" + (pc + k)); c.trimToSize(); ie.add(c); } return ie; }
@Override public Element visitUnknown(Instruction i, Void p) { Element e = new Element(i.getMnemonic()); e.setAttr("pc", "" + i.getPC()); e.setAttr("opcode", "" + i.getOpcode().opcode); return e; }
void verifyBytecode(VarargsMethod selected) { bytecodeCheckCount++; File compiledTest = new File("Test.class"); try { ClassFile cf = ClassFile.read(compiledTest); Method testMethod = null; for (Method m : cf.methods) { if (m.getName(cf.constant_pool).equals("test")) { testMethod = m; break; } } if (testMethod == null) { throw new Error("Test method not found"); } Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code); if (testMethod == null) { throw new Error("Code attribute for test() method not found"); } for (Instruction i : ea.getInstructions()) { if (i.getMnemonic().equals("invokevirtual")) { int cp_entry = i.getUnsignedShort(1); CONSTANT_Methodref_info methRef = (CONSTANT_Methodref_info)cf.constant_pool.get(cp_entry); String type = methRef.getNameAndTypeInfo().getType(); if (!type.contains(selected.varargsElement.bytecodeString)) { throw new Error("Unexpected type method call: " + type); } break; } } } catch (Exception e) { e.printStackTrace(); throw new Error("error reading " + compiledTest +": " + e); } }