예제 #1
0
  /*
   * insertGapCore0w() can handle a long code sequence more than 32K.
   * It guarantees that the length of the inserted gap (NOPs) is equal to
   * gapLength.  No other NOPs except some NOPs following TABLESWITCH or
   * LOOKUPSWITCH will not be inserted.
   *
   * Note: currentPos might be moved.
   *
   * @param where       It must indicate the first byte of an opcode.
   * @param newWhere    It contains the updated index of the position where a gap
   *                    is inserted and the length of the gap.
   *                    It must not be null.
   */
  private byte[] insertGapCore0w(
      byte[] code,
      int where,
      int gapLength,
      boolean exclusive,
      ExceptionTable etable,
      CodeAttribute ca,
      Gap newWhere)
      throws BadBytecode {
    if (gapLength <= 0) return code;

    ArrayList jumps = makeJumpList(code, code.length);
    Pointers pointers = new Pointers(currentPos, mark, where, etable, ca);
    byte[] r = insertGap2w(code, where, gapLength, exclusive, jumps, pointers);
    currentPos = pointers.cursor;
    mark = pointers.mark;
    int where2 = pointers.mark0;
    if (where2 == currentPos && !exclusive) currentPos += gapLength;

    if (exclusive) where2 -= gapLength;

    newWhere.position = where2;
    newWhere.length = gapLength;
    return r;
  }
예제 #2
0
  /**
   * Inserts an inclusive or exclusive gap in front of the instruction at the given index <code>pos
   * </code>. Branch offsets and the exception table in the method body are also updated. The
   * inserted gap is filled with NOP. The gap length may be extended to a multiple of 4.
   *
   * <p>Suppose that the instruction at the given index is at the beginning of a block statement. If
   * the gap is inclusive, then it is included within that block. If the gap is exclusive, then it
   * is excluded from that block.
   *
   * <p>The index at which the gap is actually inserted might be different from pos since some other
   * bytes might be inserted at other positions (e.g. to change <code>GOTO</code> to <code>GOTO_W
   * </code>). The index is available from the <code>Gap</code> object returned by this method.
   *
   * <p>Suppose that the gap is inserted at the position of the next instruction that would be
   * returned by <code>next()</code> (not the last instruction returned by the last call to <code>
   * next()</code>). The next instruction returned by <code>next()</code> after the gap is inserted
   * is still the same instruction. It is not <code>NOP</code> at the first byte of the inserted
   * gap.
   *
   * @param pos the index at which a gap is inserted.
   * @param length gap length.
   * @param exclusive true if exclusive, otherwise false.
   * @return the position and the length of the inserted gap.
   * @since 3.11
   */
  public Gap insertGapAt(int pos, int length, boolean exclusive) throws BadBytecode {
    /** cursorPos indicates the next bytecode whichever exclusive is true or false. */
    Gap gap = new Gap();
    if (length <= 0) {
      gap.position = pos;
      gap.length = 0;
      return gap;
    }

    byte[] c;
    int length2;
    if (bytecode.length + length > Short.MAX_VALUE) {
      // currentPos might change after calling insertGapCore0w().
      c =
          insertGapCore0w(
              bytecode, pos, length, exclusive, get().getExceptionTable(), codeAttr, gap);
      pos = gap.position;
      length2 = length; // == gap.length
    } else {
      int cur = currentPos;
      c = insertGapCore0(bytecode, pos, length, exclusive, get().getExceptionTable(), codeAttr);
      // insertGapCore0() never changes pos.
      length2 = c.length - bytecode.length;
      gap.position = pos;
      gap.length = length2;
      if (cur >= pos) currentPos = cur + length2;

      if (mark > pos || (mark == pos && exclusive)) mark += length2;
    }

    codeAttr.setCode(c);
    bytecode = c;
    endPos = getCodeLength();
    updateCursors(pos, length2);
    return gap;
  }