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

📄 classwriter.java

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    } else if (cst instanceof Float) {
      float val = ((Float)cst).floatValue();
      return newFloat(val);
    } else if (cst instanceof Long) {
      long val = ((Long)cst).longValue();
      return newLong(val);
    } else if (cst instanceof Double) {
      double val = ((Double)cst).doubleValue();
      return newDouble(val);
    } else if (cst instanceof String) {
      return newString((String)cst);
    } else if (cst instanceof Type) {
      Type t = (Type)cst;
      return newClassItem(
        t.getSort() == Type.OBJECT ? t.getInternalName() : t.getDescriptor());
    } else {
      throw new IllegalArgumentException("value " + cst);
    }
  }

  /**
   * Adds a number or string constant to the constant pool of the class being
   * build. Does nothing if the constant pool already contains a similar item.
   * <i>This method is intended for {@link Attribute} sub classes, and is
   * normally not needed by class generators or adapters.</i>
   *
   * @param cst the value of the constant to be added to the constant pool. This
   *      parameter must be an {@link java.lang.Integer Integer}, a {@link
   *      java.lang.Float Float}, a {@link java.lang.Long Long}, a {@link
          java.lang.Double Double} or a {@link String String}.
   * @return the index of a new or already existing constant item with the given
   *      value.
   */

  public int newConst (final Object cst) {
    return newConstItem(cst).index;
  }

  public int newConstInt (final int i) {
    return newInteger(i).index;
  }

  public int newConstLong (final long l) {
    return newLong(l).index;
  }

  public int newConstFloat (final float f) {
    return newFloat(f).index;
  }

  public int newConstDouble (final double d) {
    return newDouble(d).index;
  }

  /**
   * Adds an UTF8 string to the constant pool of the class being build. Does
   * nothing if the constant pool already contains a similar item. <i>This
   * method is intended for {@link Attribute} sub classes, and is normally not
   * needed by class generators or adapters.</i>
   *
   * @param value the String value.
   * @return the index of a new or already existing UTF8 item.
   */

  public int newUTF8 (final String value) {
    key.set(UTF8, value, null, null);
    Item result = get(key);
    if (result == null) {
      pool.putByte(UTF8).putUTF8(value);
      result = new Item(index++, key);
      put(result);
    }
    return result.index;
  }

  /**
   * Adds a class reference to the constant pool of the class being build. Does
   * nothing if the constant pool already contains a similar item. <i>This
   * method is intended for {@link Attribute} sub classes, and is normally not
   * needed by class generators or adapters.</i>
   *
   * @param value the internal name of the class.
   * @return the index of a new or already existing class reference item.
   */

  public int newClass (final String value) {
    return newClassItem(value).index;
  }

  /**
   * Adds a class reference to the constant pool of the class being build. Does
   * nothing if the constant pool already contains a similar item. <i>This
   * method is intended for {@link Attribute} sub classes, and is normally not
   * needed by class generators or adapters.</i>
   *
   * @param value the internal name of the class.
   * @return a new or already existing class reference item.
   */
  
  private Item newClassItem (final String value) {
    key2.set(CLASS, value, null, null);
    Item result = get(key2);
    if (result == null) {
      pool.put12(CLASS, newUTF8(value));
      result = new Item(index++, key2);
      put(result);
    }
    return result;
  }

  /**
   * Adds a field reference to the constant pool of the class being build. Does
   * nothing if the constant pool already contains a similar item. <i>This
   * method is intended for {@link Attribute} sub classes, and is normally not
   * needed by class generators or adapters.</i>
   *
   * @param owner the internal name of the field's owner class.
   * @param name the field's name.
   * @param desc the field's descriptor.
   * @return the index of a new or already existing field reference item.
   */

  public int newField (
    final String owner,
    final String name,
    final String desc)
  {
    key3.set(FIELD, owner, name, desc);
    Item result = get(key3);
    if (result == null) {
      put122(FIELD, newClass(owner), newNameType(name, desc));
      result = new Item(index++, key3);
      put(result);
    }
    return result.index;
  }

  /**
   * Adds a method reference to the constant pool of the class being build. Does
   * nothing if the constant pool already contains a similar item.
   *
   * @param owner the internal name of the method's owner class.
   * @param name the method's name.
   * @param desc the method's descriptor.
   * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
   * @return a new or already existing method reference item.
   */

  Item newMethodItem (
    final String owner,
    final String name,
    final String desc,
    final boolean itf)
  {
    key3.set(itf ? IMETH : METH, owner, name, desc);
    Item result = get(key3);
    if (result == null) {
      put122(itf ? IMETH : METH, newClass(owner), newNameType(name, desc));
      result = new Item(index++, key3);
      put(result);
    }
    return result;
  }

  /**
   * Adds a method reference to the constant pool of the class being build. Does
   * nothing if the constant pool already contains a similar item. <i>This
   * method is intended for {@link Attribute} sub classes, and is normally not
   * needed by class generators or adapters.</i>
   *
   * @param owner the internal name of the method's owner class.
   * @param name the method's name.
   * @param desc the method's descriptor.
   * @param itf <tt>true</tt> if <tt>owner</tt> is an interface.
   * @return the index of a new or already existing method reference item.
   */

  public int newMethod (
    final String owner,
    final String name,
    final String desc,
    final boolean itf)
  {
    return newMethodItem(owner, name, desc, itf).index;
  }

  /**
   * Adds an integer to the constant pool of the class being build. Does nothing
   * if the constant pool already contains a similar item.
   *
   * @param value the int value.
   * @return a new or already existing int item.
   */

  private Item newInteger (final int value) {
    key.set(value);
    Item result = get(key);
    if (result == null) {
      pool.putByte(INT).putInt(value);
      result = new Item(index++, key);
      put(result);
    }
    return result;
  }

  /**
   * Adds a float to the constant pool of the class being build. Does nothing if
   * the constant pool already contains a similar item.
   *
   * @param value the float value.
   * @return a new or already existing float item.
   */

  private Item newFloat (final float value) {
    key.set(value);
    Item result = get(key);
    if (result == null) {
      pool.putByte(FLOAT).putInt(Float.floatToIntBits(value));
      result = new Item(index++, key);
      put(result);
    }
    return result;
  }

  /**
   * Adds a long to the constant pool of the class being build. Does nothing if
   * the constant pool already contains a similar item.
   *
   * @param value the long value.
   * @return a new or already existing long item.
   */

  private Item newLong (final long value) {
    key.set(value);
    Item result = get(key);
    if (result == null) {
      pool.putByte(LONG).putLong(value);
      result = new Item(index, key);
      put(result);
      index += 2;
    }
    return result;
  }

  /**
   * Adds a double to the constant pool of the class being build. Does nothing
   * if the constant pool already contains a similar item.
   *
   * @param value the double value.
   * @return a new or already existing double item.
   */

  private Item newDouble (final double value) {
    key.set(value);
    Item result = get(key);
    if (result == null) {
      pool.putByte(DOUBLE).putLong(Double.doubleToLongBits(value));
      result = new Item(index, key);
      put(result);
      index += 2;
    }
    return result;
  }

  /**
   * Adds a string to the constant pool of the class being build. Does nothing
   * if the constant pool already contains a similar item.
   *
   * @param value the String value.
   * @return a new or already existing string item.
   */

  private Item newString (final String value) {
    key2.set(STR, value, null, null);
    Item result = get(key2);
    if (result == null) {
      pool.put12(STR, newUTF8(value));
      result = new Item(index++, key2);
      put(result);
    }
    return result;
  }

  /**
   * Adds a name and type to the constant pool of the class being build. Does
   * nothing if the constant pool already contains a similar item. <i>This
   * method is intended for {@link Attribute} sub classes, and is normally not
   * needed by class generators or adapters.</i>
   *
   * @param name a name.
   * @param desc a type descriptor.
   * @return the index of a new or already existing name and type item.
   */

  public int newNameType (final String name, final String desc) {
    key2.set(NAME_TYPE, name, desc, null);
    Item result = get(key2);
    if (result == null) {
      put122(NAME_TYPE, newUTF8(name), newUTF8(desc));
      result = new Item(index++, key2);
      put(result);
    }
    return result.index;
  }

  /**
   * Returns the constant pool's hash table item which is equal to the given
   * item.
   *
   * @param key a constant pool item.
   * @return the constant pool's hash table item which is equal to the given
   *      item, or <tt>null</tt> if there is no such item.
   */

  private Item get (final Item key) {
    int h = key.hashCode;
    Item i = items[h % items.length];
    while (i != null) {
      if (i.hashCode == h && key.isEqualTo(i)) {
        return i;
      }
      i = i.next;
    }
    return null;
  }

  /**
   * Puts the given item in the constant pool's hash table. The hash table
   * <i>must</i> not already contains this item.
   *
   * @param i the item to be added to the constant pool's hash table.
   */

  private void put (final Item i) {
    if (index > threshold) {
      Item[] newItems = new Item[items.length * 2 + 1];
      for (int l = items.length - 1; l >= 0; --l) {
        Item j = items[l];
        while (j != null) {
          int index = j.hashCode % newItems.length;
          Item k = j.next;
          j.next = newItems[index];
          newItems[index] = j;
          j = k;
        }
      }
      items = newItems;
      threshold = (int)(items.length * 0.75);
    }
    int index = i.hashCode % items.length;
    i.next = items[index];
    items[index] = i;
  }

  /**
   * Puts one byte and two shorts into the constant pool.
   *
   * @param b a byte.
   * @param s1 a short.
   * @param s2 another short.
   */

  private void put122 (final int b, final int s1, final int s2) {
    pool.put12(b, s1).putShort(s2);
  }
}

⌨️ 快捷键说明

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