コード例 #1
0
  /**
   * Bytecode generation for a method
   *
   * @param classScope
   * @param classFile
   */
  public void generateCode(ClassScope classScope, ClassFile classFile) {

    classFile.codeStream.wideMode = false; // reset wideMode to false
    if (this.ignoreFurtherInvestigation) {
      // method is known to have errors, dump a problem method
      if (this.binding == null) return; // handle methods with invalid signature or duplicates
      int problemsLength;
      CategorizedProblem[] problems =
          this.scope.referenceCompilationUnit().compilationResult.getProblems();
      CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
      System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
      classFile.addProblemMethod(this, this.binding, problemsCopy);
      return;
    }
    int problemResetPC = 0;
    CompilationResult unitResult = null;
    int problemCount = 0;
    if (classScope != null) {
      TypeDeclaration referenceContext = classScope.referenceContext;
      if (referenceContext != null) {
        unitResult = referenceContext.compilationResult();
        problemCount = unitResult.problemCount;
      }
    }
    boolean restart = false;
    boolean abort = false;
    // regular code generation
    do {
      try {
        problemResetPC = classFile.contentsOffset;
        this.generateCode(classFile);
        restart = false;
      } catch (AbortMethod e) {
        // a fatal error was detected during code generation, need to restart code gen if possible
        if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
          // a branch target required a goto_w, restart code gen in wide mode.
          classFile.contentsOffset = problemResetPC;
          classFile.methodCount--;
          classFile.codeStream.resetInWideMode(); // request wide mode
          // reset the problem count to prevent reporting the same warning twice
          if (unitResult != null) {
            unitResult.problemCount = problemCount;
          }
          restart = true;
        } else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) {
          classFile.contentsOffset = problemResetPC;
          classFile.methodCount--;
          classFile.codeStream.resetForCodeGenUnusedLocals();
          // reset the problem count to prevent reporting the same warning twice
          if (unitResult != null) {
            unitResult.problemCount = problemCount;
          }
          restart = true;
        } else {
          restart = false;
          abort = true;
        }
      }
    } while (restart);
    // produce a problem method accounting for this fatal error
    if (abort) {
      int problemsLength;
      CategorizedProblem[] problems =
          this.scope.referenceCompilationUnit().compilationResult.getAllProblems();
      CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
      System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
      classFile.addProblemMethod(this, this.binding, problemsCopy, problemResetPC);
    }
  }