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

📄 classreader.java

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
              }
              break;
            case ClassWriter.TYPE_INSN:
              cv.visitTypeInsn(opcode, readClass(v + 1, c));
              v += 3;
              break;
            case ClassWriter.IINC_INSN:
              cv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]);
              v += 3;
              break;
            // case MANA_INSN:
            default:
              cv.visitMultiANewArrayInsn(readClass(v + 1, c), b[v + 3] & 0xFF);
              v += 4;
              break;
          }
        }
        l = labels[codeEnd - codeStart];
        if (l != null) {
          cv.visitLabel(l);
        }
        // visits the try catch entries
        j = readUnsignedShort(v); v += 2;
        for ( ; j > 0; --j) {
          Label start = labels[readUnsignedShort(v)];
          Label end = labels[readUnsignedShort(v + 2)];
          Label handler = labels[readUnsignedShort(v + 4)];
          int type = readUnsignedShort(v + 6);
          if (type == 0) {
            cv.visitTryCatchBlock(start, end, handler, null);
          } else {
            cv.visitTryCatchBlock(start, end, handler, readUTF8(items[type], c));
          }
          v += 8;
        }
        // visits the local variable table
        j = readUnsignedShort(v); v += 2;
        if (!skipDebug) {
          for ( ; j > 0; --j) {
            String attrName = readUTF8(v, c);
            if (attrName.equals("LocalVariableTable")) {
              k = readUnsignedShort(v + 6);
              w = v + 8;
              for ( ; k > 0; --k) {
                label = readUnsignedShort(w);
                Label start = labels[label];
                label += readUnsignedShort(w + 2);
                Label end = labels[label];
                cv.visitLocalVariable(
                  readUTF8(w + 4, c),
                  readUTF8(w + 6, c),
                  start,
                  end,
                  readUnsignedShort(w + 8));
                w += 10;
              }
            }
            v += 6 + readInt(v + 2);
          }
        }
        // visits the other attributes
        while (cattrs != null) {
          attr = cattrs.next;
          cattrs.next = null;
          cv.visitAttribute(cattrs);
          cattrs = attr;
        }
        // visits the max stack and max locals values
        cv.visitMaxs(maxStack, maxLocals);
      }
    }
    // visits the class attributes
    Attribute last = null;
    attr = clattrs;
    while (attr != null) {
      Attribute next = attr.next;
      attr.next = last;
      last = attr;
      attr = next;
    }    
    while (last != null) {
      attr = last.next;
      last.next = null;
      classVisitor.visitAttribute(last);
      last = attr;
    }
    // visits the end of the class
    classVisitor.visitEnd();
  }

  // --------------------------------------------------------------------------
  // Utility methods: low level parsing
  // --------------------------------------------------------------------------

  /**
   * Returns the start index of the constant pool item in {@link #b b}, plus 
   * one. <i>This method is intended for {@link Attribute} sub classes, and is 
   * normally not needed by class generators or adapters.</i>
   * 
   * @param item the index a constant pool item.
   * @return the start index of the constant pool item in {@link #b b}, plus 
   *      one.
   */
  
  public int getItem (final int item) {
    return items[item];
  }
  
  /**
   * Reads a byte value in {@link #b b}. <i>This method is intended
   * for {@link Attribute} sub classes, and is normally not needed by class
   * generators or adapters.</i>
   *
   * @param index the start index of the value to be read in {@link #b b}.
   * @return the read value.
   */

  public int readByte (final int index) {
    return b[index] & 0xFF;
  }

  /**
   * Reads an unsigned short value in {@link #b b}. <i>This method is intended
   * for {@link Attribute} sub classes, and is normally not needed by class
   * generators or adapters.</i>
   *
   * @param index the start index of the value to be read in {@link #b b}.
   * @return the read value.
   */

  public int readUnsignedShort (final int index) {
    byte[] b = this.b;
    return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
  }

  /**
   * Reads a signed short value in {@link #b b}. <i>This method is intended
   * for {@link Attribute} sub classes, and is normally not needed by class
   * generators or adapters.</i>
   *
   * @param index the start index of the value to be read in {@link #b b}.
   * @return the read value.
   */

  public short readShort (final int index) {
    byte[] b = this.b;
    return (short)(((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
  }

  /**
   * Reads a signed int value in {@link #b b}. <i>This method is intended
   * for {@link Attribute} sub classes, and is normally not needed by class
   * generators or adapters.</i>
   *
   * @param index the start index of the value to be read in {@link #b b}.
   * @return the read value.
   */

  public int readInt (final int index) {
    byte[] b = this.b;
    return ((b[index] & 0xFF) << 24) |
           ((b[index + 1] & 0xFF) << 16) |
           ((b[index + 2] & 0xFF) << 8) |
           (b[index + 3] & 0xFF);
  }

  /**
   * Reads a signed long value in {@link #b b}. <i>This method is intended
   * for {@link Attribute} sub classes, and is normally not needed by class
   * generators or adapters.</i>
   *
   * @param index the start index of the value to be read in {@link #b b}.
   * @return the read value.
   */

  public long readLong (final int index) {
    long l1 = readInt(index);
    long l0 = readInt(index + 4) & 0xFFFFFFFFL;
    return (l1 << 32) | l0;
  }

  /**
   * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method is
   * intended for {@link Attribute} sub classes, and is normally not needed by
   * class generators or adapters.</i>
   *
   * @param index the start index of an unsigned short value in {@link #b b},
   *      whose value is the index of an UTF8 constant pool item.
   * @param buf buffer to be used to read the item. This buffer must be
   *      sufficiently large. It is not automatically resized.
   * @return the String corresponding to the specified UTF8 item.
   */

  public String readUTF8 (int index, final char[] buf) {
    // consults cache
    int item = readUnsignedShort(index);
    String s = strings[item];
    if (s != null) {
      return s;
    }
    // computes the start index of the CONSTANT_Utf8 item in b
    index = items[item];
    // reads the length of the string (in bytes, not characters)
    int utfLen = readUnsignedShort(index);
    index += 2;
    // parses the string bytes
    int endIndex = index + utfLen;
    byte[] b = this.b;
    int strLen = 0;
    int c, d, e;
    while (index < endIndex) {
      c = b[index++] & 0xFF;
      switch (c >> 4) {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
          // 0xxxxxxx
          buf[strLen++] = (char)c;
          break;
        case 12:
        case 13:
          // 110x xxxx   10xx xxxx
          d = b[index++];
          buf[strLen++] = (char)(((c & 0x1F) << 6) | (d & 0x3F));
          break;
        default:
          // 1110 xxxx  10xx xxxx  10xx xxxx
          d = b[index++];
          e = b[index++];
          buf[strLen++] =
            (char)(((c & 0x0F) << 12) | ((d & 0x3F) << 6) | (e & 0x3F));
          break;
      }
    }
    s = new String(buf, 0, strLen);
    strings[item] = s;
    return s;
  }

  /**
   * Reads a class constant pool item in {@link #b b}. <i>This method is
   * intended for {@link Attribute} sub classes, and is normally not needed by
   * class generators or adapters.</i>
   *
   * @param index the start index of an unsigned short value in {@link #b b},
   *      whose value is the index of a class constant pool item.
   * @param buf buffer to be used to read the item. This buffer must be
   *      sufficiently large. It is not automatically resized.
   * @return the String corresponding to the specified class item.
   */

  public String readClass (final int index, final char[] buf) {
    // computes the start index of the CONSTANT_Class item in b
    // and reads the CONSTANT_Utf8 item designated by
    // the first two bytes of this CONSTANT_Class item
    return readUTF8(items[readUnsignedShort(index)], buf);
  }

  /**
   * Reads a numeric or string constant pool item in {@link #b b}. <i>This
   * method is intended for {@link Attribute} sub classes, and is normally not
   * needed by class generators or adapters.</i>
   *
   * @param item the index of a constant pool item.
   * @param buf buffer to be used to read the item. This buffer must be
   *      sufficiently large. It is not automatically resized.
   * @return the {@link java.lang.Integer Integer}, {@link java.lang.Float
   *      Float}, {@link java.lang.Long Long}, {@link java.lang.Double Double},
   *      {@link String String} or {@link Type Type} corresponding to the given 
   *      constant pool item.
   */

  public Object readConst (final int item, final char[] buf) {
    int index = items[item];
    switch (b[index - 1]) {
      case ClassWriter.INT:
        return new Integer(readInt(index));
      case ClassWriter.FLOAT:
        return new Float(Float.intBitsToFloat(readInt(index)));
      case ClassWriter.LONG:
        return new Long(readLong(index));
      case ClassWriter.DOUBLE:
        return new Double(Double.longBitsToDouble(readLong(index)));
      case ClassWriter.CLASS:
        String s = readUTF8(index, buf);
        return Type.getType(s.charAt(0) == '[' ? s : "L" + s + ";");
      //case ClassWriter.STR:
      default:
        return readUTF8(index, buf);
    }
  }

  /**
   * Reads an attribute in {@link #b b}.
   *
   * @param attrs prototypes of the attributes that must be parsed during the
   *      visit of the class. Any attribute whose type is not equal to the type
   *      of one the prototypes is ignored (i.e. an empty {@link Attribute}
   *      instance is returned).
   * @param type the type of the attribute.
   * @param off index of the first byte of the attribute's content in {@link #b
   *      b}. The 6 attribute header bytes, containing the type and the length
   *      of the attribute, are not taken into account here (they have already
   *      been read).
   * @param len the length of the attribute's content.
   * @param buf buffer to be used to call {@link #readUTF8 readUTF8}, {@link
   *      #readClass(int,char[]) readClass} or {@link #readConst readConst}.
   * @param codeOff index of the first byte of code's attribute content in
   *      {@link #b b}, or -1 if the attribute to be read is not a code
   *      attribute. The 6 attribute header bytes, containing the type and the
   *      length of the attribute, are not taken into account here.
   * @param labels the labels of the method's code, or <tt>null</tt> if the
   *      attribute to be read is not a code attribute.
   * @return the attribute that has been read, or <tt>null</tt> to skip this
   *      attribute.
   */

  protected Attribute readAttribute (
    final Attribute[] attrs,
    final String type,
    final int off,
    final int len,
    final char[] buf,
    final int codeOff,
    final Label[] labels)
  {
    for (int i = 0; i < attrs.length; ++i) {
      if (attrs[i].type.equals(type)) {
        return attrs[i].read(this, off, len, buf, codeOff, labels);
      }
    }
    return new Attribute(type);
  }
}

⌨️ 快捷键说明

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