@Override public String visitConstantPoolRef(Instruction instr, int index, Void p) { StringBuilder sb = new StringBuilder(); sb.append(instr.getMnemonic()); cpRef(sb, instr.getOpcode(), cls.constantPool[index]); return sb.toString(); }
@Override public String visitBranch(Instruction instr, int offset, Void p) { StringBuilder sb = new StringBuilder(); return sb.append(instr.getMnemonic()) .append(' ') .append(label(instr.getPC(), offset)) .toString(); }
@Override public String visitLocalAndValue(Instruction instr, int index, int value, Void p) { StringBuilder sb = new StringBuilder(); return sb.append(instr.getMnemonic()) .append(' ') .append(index) .append(' ') .append(value) .toString(); }
void verifyBytecode(VarargsMethod selected, JavaSource source, int id) { bytecodeCheckCount.incrementAndGet(); File compiledTest = new File(String.format("Test%d.class", id)); 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(); String sig = selected.parameterTypes.bytecodeSigStr; if (!type.contains(sig)) { throw new Error( "Unexpected type method call: " + type + "" + "\nfound: " + sig + "\n" + source.getCharContent(true)); } break; } } } catch (Exception e) { e.printStackTrace(); throw new Error("error reading " + compiledTest + ": " + e); } }
@Override public String visitTableSwitch( Instruction instr, int default_, int low, int high, int[] offsets, Void p) { StringBuilder sb = new StringBuilder(); sb.append(instr.getMnemonic()) // the opcode .append(" (tableswitchinfo ") .append(label(instr.getPC(), default_)) // the default target .append(" (") .append(low) .append(" . ") .append(high) .append(") ("); for (int i = 0; i < high - low + 1; i++) { sb.append(label(instr.getPC(), offsets[i])).append(' '); } sb.setCharAt(sb.length() - 1, ')'); return sb.append(")").toString(); }
@Override public String visitLookupSwitch( Instruction instr, int default_, int npairs, int[] matches, int[] offsets, Void p) { StringBuilder sb = new StringBuilder(); sb.append(instr.getMnemonic()) // the opcode .append(" (lookupswitchinfo ") .append(label(instr.getPC(), default_)) // the default target .append(' ') .append(npairs) // the pair count .append(" ("); for (int i = 0; i < npairs; i++) { sb.append('(') .append(matches[i]) .append(" . ") .append(label(instr.getPC(), offsets[i])) .append(") "); } sb.setCharAt(sb.length() - 1, ')'); return sb.append(")").toString(); }
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); } }
@Override public String visitArrayType(Instruction instr, Instruction.TypeKind tk, Void p) { StringBuilder sb = new StringBuilder(); return sb.append(instr.getMnemonic()).append(' ').append(typeKind(tk)).toString(); }
@Override public String visitNoOperands(Instruction instr, Void p) { StringBuilder sb = new StringBuilder(); return sb.append(instr.getMnemonic()).toString(); }