Beispiel #1
0
  /**
   * Does a human-friendly dump of this instance.
   *
   * @param out {@code non-null;} where to dump
   * @param prefix {@code non-null;} prefix to attach to each line of output
   * @param verbose whether to be verbose; verbose output includes lines for zero-size instructions
   *     and explicit constant pool indices
   */
  public void debugPrint(Writer out, String prefix, boolean verbose) {
    IndentingWriter iw = new IndentingWriter(out, 0, prefix);
    int sz = size();

    try {
      for (int i = 0; i < sz; i++) {
        DalvInsn insn = (DalvInsn) get0(i);
        String s;

        if ((insn.codeSize() != 0) || verbose) {
          s = insn.listingString("", 0, verbose);
        } else {
          s = null;
        }

        if (s != null) {
          iw.write(s);
        }
      }

      iw.flush();
    } catch (IOException ex) {
      throw new RuntimeException(ex);
    }
  }
Beispiel #2
0
  /**
   * Gets the size of the outgoing arguments area required by this method. This is equal to the
   * largest argument word count of any method referred to by this instance.
   *
   * @return {@code >= 0;} the required outgoing arguments size
   */
  public int getOutsSize() {
    int sz = size();
    int result = 0;

    for (int i = 0; i < sz; i++) {
      DalvInsn insn = (DalvInsn) get0(i);

      if (!(insn instanceof CstInsn)) {
        continue;
      }

      Constant cst = ((CstInsn) insn).getConstant();

      if (!(cst instanceof CstBaseMethodRef)) {
        continue;
      }

      boolean isStatic = (insn.getOpcode().getFamily() == DalvOps.INVOKE_STATIC);
      int count = ((CstBaseMethodRef) cst).getParameterWordCount(isStatic);

      if (count > result) {
        result = count;
      }
    }

    return result;
  }
Beispiel #3
0
  /**
   * Extracts and returns the source position information out of an instruction list.
   *
   * @param insns {@code non-null;} instructions to convert
   * @param howMuch how much information should be included; one of the static constants defined by
   *     this class
   * @return {@code non-null;} the positions list
   */
  public static PositionList make(DalvInsnList insns, int howMuch) {
    switch (howMuch) {
      case NONE:
        {
          return EMPTY;
        }
      case LINES:
      case IMPORTANT:
        {
          // Valid.
          break;
        }
      default:
        {
          throw new IllegalArgumentException("bogus howMuch");
        }
    }

    SourcePosition noInfo = SourcePosition.NO_INFO;
    SourcePosition cur = noInfo;
    int sz = insns.size();
    PositionList.Entry[] arr = new PositionList.Entry[sz];
    boolean lastWasTarget = false;
    int at = 0;

    for (int i = 0; i < sz; i++) {
      DalvInsn insn = insns.get(i);

      if (insn instanceof CodeAddress) {
        lastWasTarget = true;
        ;
        continue;
      }

      SourcePosition pos = insn.getPosition();

      if (pos.equals(noInfo) || pos.sameLine(cur)) {
        continue;
      }

      if ((howMuch == IMPORTANT) && !lastWasTarget) {
        continue;
      }

      cur = pos;
      arr[at] = new PositionList.Entry(insn.getAddress(), pos);
      at++;

      lastWasTarget = false;
    }

    PositionList result = new PositionList(at);
    for (int i = 0; i < at; i++) {
      result.set(i, arr[i]);
    }

    result.setImmutable();
    return result;
  }
Beispiel #4
0
  /**
   * Gets the size of this instance, in 16-bit code units. This will only return a meaningful result
   * if the instructions in this instance all have valid addresses.
   *
   * @return {@code >= 0;} the size
   */
  public int codeSize() {
    int sz = size();

    if (sz == 0) {
      return 0;
    }

    DalvInsn last = get(sz - 1);
    return last.getNextAddress();
  }
Beispiel #5
0
  /**
   * Writes all the instructions in this instance to the given output destination.
   *
   * @param out {@code non-null;} where to write to
   */
  public void writeTo(AnnotatedOutput out) {
    int startCursor = out.getCursor();
    int sz = size();

    if (out.annotates()) {
      boolean verbose = out.isVerbose();

      for (int i = 0; i < sz; i++) {
        DalvInsn insn = (DalvInsn) get0(i);
        int codeBytes = insn.codeSize() * 2;
        String s;

        if ((codeBytes != 0) || verbose) {
          s = insn.listingString("  ", out.getAnnotationWidth(), true);
        } else {
          s = null;
        }

        if (s != null) {
          out.annotate(codeBytes, s);
        } else if (codeBytes != 0) {
          out.annotate(codeBytes, "");
        }
      }
    }

    for (int i = 0; i < sz; i++) {
      DalvInsn insn = (DalvInsn) get0(i);
      try {
        insn.writeTo(out);
      } catch (RuntimeException ex) {
        throw ExceptionWithContext.withContext(ex, "...while writing " + insn);
      }
    }

    // Sanity check of the amount written.
    int written = (out.getCursor() - startCursor) / 2;
    if (written != codeSize()) {
      throw new RuntimeException(
          "write length mismatch; expected " + codeSize() + " but actually wrote " + written);
    }
  }