⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codewriter.java

📁 开源的java 编辑器源代码
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
    do {      if (state == 3) {        state = 2;      }      u = 0;      while (u < b.length) {        int opcode = b[u] & 0xFF;  // opcode of current instruction        int insert = 0;            // bytes to be added after this instruction        switch (ClassWriter.TYPE[opcode]) {          case ClassWriter.NOARG_INSN:          case ClassWriter.IMPLVAR_INSN:            u += 1;            break;          case ClassWriter.LABEL_INSN:            if (opcode > 201) {              // converts temporary opcodes 202 to 217 (inclusive), 218 and 219              // to IFEQ ... JSR (inclusive), IFNULL and IFNONNULL              opcode = opcode < 218 ? opcode - 49 : opcode - 20;              label = u + readUnsignedShort(b, u + 1);            } else {              label = u + readShort(b, u + 1);            }            newOffset = getNewOffset(allIndexes, allSizes, u, label);            if (newOffset < Short.MIN_VALUE || newOffset > Short.MAX_VALUE) {              if (!resize[u]) {                if (opcode == Constants.GOTO || opcode == Constants.JSR) {                  // two additional bytes will be required to replace this                  // GOTO or JSR instruction with a GOTO_W or a JSR_W                  insert = 2;                } else {                  // five additional bytes will be required to replace this                  // IFxxx <l> instruction with IFNOTxxx <l'> GOTO_W <l>, where                  // IFNOTxxx is the "opposite" opcode of IFxxx (i.e., IFNE for                  // IFEQ) and where <l'> designates the instruction just after                  // the GOTO_W.                  insert = 5;                }                resize[u] = true;              }            }            u += 3;            break;          case ClassWriter.LABELW_INSN:            u += 5;            break;          case ClassWriter.TABL_INSN:            if (state == 1) {              // true number of bytes to be added (or removed) from this              // instruction = (future number of padding bytes - current number              // of padding byte) - previously over estimated variation =              // = ((3 - newOffset%4) - (3 - u%4)) - u%4              // = (-newOffset%4 + u%4) - u%4              // = -(newOffset & 3)              newOffset = getNewOffset(allIndexes, allSizes, 0, u);              insert = -(newOffset & 3);            } else if (!resize[u]) {              // over estimation of the number of bytes to be added to this              // instruction = 3 - current number of padding bytes = 3 - (3 -              // u%4) = u%4 = u & 3              insert = u & 3;              resize[u] = true;            }            // skips instruction            u = u + 4 - (u & 3);            u += 4*(readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;            break;          case ClassWriter.LOOK_INSN:            if (state == 1) {              // like TABL_INSN              newOffset = getNewOffset(allIndexes, allSizes, 0, u);              insert = -(newOffset & 3);            } else if (!resize[u]) {              // like TABL_INSN              insert = u & 3;              resize[u] = true;            }            // skips instruction            u = u + 4 - (u & 3);            u += 8*readInt(b, u + 4) + 8;            break;          case ClassWriter.WIDE_INSN:            opcode = b[u + 1] & 0xFF;            if (opcode == Constants.IINC) {              u += 6;            } else {              u += 4;            }            break;          case ClassWriter.VAR_INSN:          case ClassWriter.SBYTE_INSN:          case ClassWriter.LDC_INSN:            u += 2;            break;          case ClassWriter.SHORT_INSN:          case ClassWriter.LDCW_INSN:          case ClassWriter.FIELDORMETH_INSN:          case ClassWriter.TYPE_INSN:          case ClassWriter.IINC_INSN:            u += 3;            break;          case ClassWriter.ITFMETH_INSN:            u += 5;            break;          // case ClassWriter.MANA_INSN:          default:            u += 4;            break;        }        if (insert != 0) {          // adds a new (u, insert) entry in the allIndexes and allSizes arrays          int[] newIndexes = new int[allIndexes.length + 1];          int[] newSizes = new int[allSizes.length + 1];          System.arraycopy(allIndexes, 0, newIndexes, 0, allIndexes.length);          System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);          newIndexes[allIndexes.length] = u;          newSizes[allSizes.length] = insert;          allIndexes = newIndexes;          allSizes = newSizes;          if (insert > 0) {            state = 3;          }        }      }      if (state < 3) {        --state;      }    } while (state != 0);    // 2nd step:    // copies the bytecode of the method into a new bytevector, updates the    // offsets, and inserts (or removes) bytes as requested.    ByteVector newCode = new ByteVector(code.length);    u = 0;    while (u < code.length) {      for (i = allIndexes.length - 1; i >= 0; --i) {        if (allIndexes[i] == u) {          if (i < len) {            if (sizes[i] > 0) {              newCode.putByteArray(null, 0, sizes[i]);            } else {              newCode.length += sizes[i];            }            indexes[i] = newCode.length;          }        }      }      int opcode = b[u] & 0xFF;      switch (ClassWriter.TYPE[opcode]) {        case ClassWriter.NOARG_INSN:        case ClassWriter.IMPLVAR_INSN:          newCode.put1(opcode);          u += 1;          break;        case ClassWriter.LABEL_INSN:          if (opcode > 201) {            // changes temporary opcodes 202 to 217 (inclusive), 218 and 219            // to IFEQ ... JSR (inclusive), IFNULL and IFNONNULL            opcode = opcode < 218 ? opcode - 49 : opcode - 20;            label = u + readUnsignedShort(b, u + 1);          } else {            label = u + readShort(b, u + 1);          }          newOffset = getNewOffset(allIndexes, allSizes, u, label);          if (newOffset < Short.MIN_VALUE || newOffset > Short.MAX_VALUE) {            // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx <l> with            // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is the "opposite" opcode            // of IFxxx (i.e., IFNE for IFEQ) and where <l'> designates the            // instruction just after the GOTO_W.            if (opcode == Constants.GOTO) {              newCode.put1(200); // GOTO_W            } else if (opcode == Constants.JSR) {              newCode.put1(201); // JSR_W            } else {              newCode.put1(opcode <= 166 ? ((opcode + 1) ^ 1) - 1 : opcode ^ 1);              newCode.put2(8);   // jump offset              newCode.put1(200); // GOTO_W              newOffset -= 3;    // newOffset now computed from start of GOTO_W            }            newCode.put4(newOffset);          } else {            newCode.put1(opcode);            newCode.put2(newOffset);          }          u += 3;          break;        case ClassWriter.LABELW_INSN:          label = u + readInt(b, u + 1);          newOffset = getNewOffset(allIndexes, allSizes, u, label);          newCode.put1(opcode);          newCode.put4(newOffset);          u += 5;          break;        case ClassWriter.TABL_INSN:          // skips 0 to 3 padding bytes          v = u;          u = u + 4 - (v & 3);          // reads and copies instruction          int source = newCode.length;          newCode.put1(Constants.TABLESWITCH);          while (newCode.length % 4 != 0) {            newCode.put1(0);          }          label = v + readInt(b, u); u += 4;          newOffset = getNewOffset(allIndexes, allSizes, v, label);          newCode.put4(newOffset);          j = readInt(b, u); u += 4;          newCode.put4(j);          j = readInt(b, u) - j + 1; u += 4;          newCode.put4(readInt(b, u - 4));          for ( ; j > 0; --j) {            label = v + readInt(b, u); u += 4;            newOffset = getNewOffset(allIndexes, allSizes, v, label);            newCode.put4(newOffset);          }          break;        case ClassWriter.LOOK_INSN:          // skips 0 to 3 padding bytes          v = u;          u = u + 4 - (v & 3);          // reads and copies instruction          source = newCode.length;          newCode.put1(Constants.LOOKUPSWITCH);          while (newCode.length % 4 != 0) {            newCode.put1(0);          }          label = v + readInt(b, u); u += 4;          newOffset = getNewOffset(allIndexes, allSizes, v, label);          newCode.put4(newOffset);          j = readInt(b, u); u += 4;          newCode.put4(j);          for ( ; j > 0; --j) {            newCode.put4(readInt(b, u)); u += 4;            label = v + readInt(b, u); u += 4;            newOffset = getNewOffset(allIndexes, allSizes, v, label);            newCode.put4(newOffset);          }          break;        case ClassWriter.WIDE_INSN:          opcode = b[u + 1] & 0xFF;          if (opcode == Constants.IINC) {            newCode.putByteArray(b, u, 6);            u += 6;          } else {            newCode.putByteArray(b, u, 4);            u += 4;          }          break;        case ClassWriter.VAR_INSN:        case ClassWriter.SBYTE_INSN:        case ClassWriter.LDC_INSN:          newCode.putByteArray(b, u, 2);          u += 2;          break;        case ClassWriter.SHORT_INSN:        case ClassWriter.LDCW_INSN:        case ClassWriter.FIELDORMETH_INSN:        case ClassWriter.TYPE_INSN:        case ClassWriter.IINC_INSN:          newCode.putByteArray(b, u, 3);          u += 3;          break;        case ClassWriter.ITFMETH_INSN:          newCode.putByteArray(b, u, 5);          u += 5;          break;        // case MANA_INSN:        default:          newCode.putByteArray(b, u, 4);          u += 4;          break;      }    }    // updates the instructions addresses in the    // catch, local var and line number tables    if (catchTable != null) {      b = catchTable.data;      u = 0;      while (u < catchTable.length) {        writeShort(b, u, getNewOffset(          allIndexes, allSizes, 0, readUnsignedShort(b, u)));        writeShort(b, u + 2, getNewOffset(          allIndexes, allSizes, 0, readUnsignedShort(b, u + 2)));        writeShort(b, u + 4, getNewOffset(          allIndexes, allSizes, 0, readUnsignedShort(b, u + 4)));        u += 8;      }    }    if (localVar != null) {      b = localVar.data;      u = 0;      while (u < localVar.length) {        label = readUnsignedShort(b, u);        newOffset = getNewOffset(allIndexes, allSizes, 0, label);        writeShort(b, u, newOffset);        label += readUnsignedShort(b, u + 2);        newOffset = getNewOffset(allIndexes, allSizes, 0, label) - newOffset;        writeShort(b, u, newOffset);        u += 10;      }    }    if (lineNumber != null) {      b = lineNumber.data;      u = 0;      while (u < lineNumber.length) {        writeShort(b, u, getNewOffset(          allIndexes, allSizes, 0, readUnsignedShort(b, u)));        u += 4;      }    }    // replaces old bytecodes with new ones    code = newCode;    // returns the positions of the resized instructions    return indexes;  }  /**   * Reads an unsigned short value in the given byte array.   *   * @param b a byte array.   * @param index the start index of the value to be read.   * @return the read value.   */  static int readUnsignedShort (final byte[] b, final int index) {    return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);  }  /**   * Reads a signed short value in the given byte array.   *   * @param b a byte array.   * @param index the start index of the value to be read.   * @return the read value.   */  static short readShort (final byte[] b, final int index) {    return (short)(((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));  }  /**   * Reads a signed int value in the given byte array.   *   * @param b a byte array.   * @param index the start index of the value to be read.   * @return the read value.   */  static int readInt (final byte[] b, final int index) {    return ((b[index] & 0xFF) << 24) |           ((b[index + 1] & 0xFF) << 16) |           ((b[index + 2] & 0xFF) << 8) |           (b[index + 3] & 0xFF);  }  /**   * Writes a short value in the given byte array.   *   * @param b a byte array.   * @param index where the first byte of the short value must be written.   * @param s the value to be written in the given byte array.   */  static void writeShort (final byte[] b, final int index, final int s) {    b[index] = (byte)(s >>> 8);    b[index + 1] = (byte)s;  }  /**   * Computes the future value of a bytecode offset.   * <p>   * Note: it is possible to have several entries for the same instruction   * in the <tt>indexes</tt> and <tt>sizes</tt>: two entries (index=a,size=b)   * and (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').   *   * @param indexes current positions of the instructions to be resized. Each   *      instruction must be designated by the index of its <i>last</i> byte,   *      plus one (or, in other words, by the index of the <i>first</i> byte of   *      the <i>next</i> instruction).   * @param sizes the number of bytes to be <i>added</i> to the above   *      instructions. More precisely, for each i < <tt>len</tt>,   *      <tt>sizes</tt>[i] bytes will be added at the end of the instruction   *      designated by <tt>indexes</tt>[i] or, if <tt>sizes</tt>[i] is   *      negative, the <i>last</i> |<tt>sizes[i]</tt>| bytes of the instruction   *      will be removed (the instruction size <i>must not</i> become negative   *      or null).   * @param begin index of the first byte of the source instruction.   * @param end index of the first byte of the target instruction.   * @return the future value of the given bytecode offset.   */  static int getNewOffset (    final int[] indexes,    final int[] sizes,    final int begin,    final int end)  {    int offset = end - begin;    for (int i = 0; i < indexes.length; ++i) {      if (begin < indexes[i] && indexes[i] <= end) { // forward jump        offset += sizes[i];      } else if (end < indexes[i] && indexes[i] <= begin) { // backward jump        offset -= sizes[i];      }    }    return offset;  }  /**   * Returns the current size of the bytecode of this method. This size just   * includes the size of the bytecode instructions: it does not include the   * size of the Exceptions, LocalVariableTable, LineNumberTable, Synthetic   * and Deprecated attributes, if present.   *   * @return the current size of the bytecode of this method.   */  protected int getCodeSize () {    return code.length;  }  /**   * Returns the current bytecode of this method. This bytecode only contains   * the instructions: it does not include the Exceptions, LocalVariableTable,   * LineNumberTable, Synthetic and Deprecated attributes, if present.   *   * @return the current bytecode of this method. The bytecode is contained   *      between the index 0 (inclusive) and the index {@link #getCodeSize   *      getCodeSize} (exclusive).   */  protected byte[] getCode () {    return code.data;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -