示例#1
0
文件: M6Method.java 项目: nadezhin/M6
  /**
   * 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);
    }
  }
示例#4
0
  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);
    }
  }