/** * This method processes the MethodInfo given in the constructor. It is necessary to call this * method before querying this method. * * @param constant_pool The constant pool element from the M6Class object representing the outer * class from which this method is taken from. */ public void processMethod() throws ConstantPoolException, DescriptorException { /* The name of the method */ if (debug) { System.out.println("\nProcessing method: " + name + "Parameters: " + params); } /* Process the code attribute */ if (cai != null && !no_method_body) { LinkedHashMap<Integer, Integer> labels = new LinkedHashMap<>(); LabelsVisitor labelsVisitor = new LabelsVisitor(); for (Instruction inst : cai.getInstructions()) { for (int offset : inst.accept(labelsVisitor, null)) { int label = inst.getPC() + offset; if (!labels.containsKey(label)) { labels.put(label, labels.size()); } } } for (Code_attribute.Exception_data e : cai.exception_table) { if (!labels.containsKey(e.start_pc)) { labels.put(e.start_pc, labels.size()); } if (!labels.containsKey(e.end_pc)) { labels.put(e.end_pc, labels.size()); } if (!labels.containsKey(e.handler_pc)) { labels.put(e.handler_pc, labels.size()); } } int offset = 0; int li = 0; // index in linenumber table // get the parsed code part for (Instruction instr : cai.getInstructions()) { if (lnt != null && li < lnt.line_number_table.length && lnt.line_number_table[li].start_pc == instr.getPC()) { m6instructions.add("; " + "line_number #" + lnt.line_number_table[li].line_number); li++; } String resultStr = parseInst(instr, offset, labels); if (resultStr != null) { m6instructions.add(resultStr); offset = offset + instr.length(); } } // resolve any tag to absolute offsets. resolveTagInCode(); // add an end marker to the code. m6instructions.add("(endofcode " + code_length + ")"); } processed = true; }
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 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); } }
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); } }