Code Search for Developers
 
 
  

ConstantPool.java from DrJava at Krugle


Show ConstantPool.java syntax highlighted

/*BEGIN_COPYRIGHT_BLOCK
 *
 * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software is Open Source Initiative approved Open Source Software.
 * Open Source Initative Approved is a trademark of the Open Source Initiative.
 * 
 * This file is part of DrJava.  Download the current version of this project
 * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 * 
 * END_COPYRIGHT_BLOCK*/



/*
 * DynamicJava - Copyright (C) 1999-2001
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to permit
 * persons to whom the Software is furnished to do so, subject to the
 * following conditions:
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL DYADE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name of Dyade shall not be
 * used in advertising or otherwise to promote the sale, use or other
 * dealings in this Software without prior written authorization from
 * Dyade.
 *
 */

package koala.dynamicjava.classfile;

import java.io.*;
import java.util.*;

/**
 * This class represents JVM bytecode constant pools
 *
 * @author Stephane Hillion
 * @version 1.0 - 1999/05/05
 */

public class ConstantPool {
  // Constant pool info tags
  private final static byte CONSTANT_UTF8                = 1;
  private final static byte CONSTANT_INTEGER             = 3;
  private final static byte CONSTANT_FLOAT               = 4;
  private final static byte CONSTANT_LONG                = 5;
  private final static byte CONSTANT_DOUBLE              = 6;
  private final static byte CONSTANT_CLASS               = 7;
  private final static byte CONSTANT_STRING              = 8;
  private final static byte CONSTANT_FIELDREF            = 9;
  private final static byte CONSTANT_METHODREF           = 10;
  private final static byte CONSTANT_INTERFACEMETHODREF  = 11;
  private final static byte CONSTANT_NAMEANDTYPE         = 12;

  /**
   * The constants
   */
  private Map<Object,Info> constants;

  /**
   * The constant count
   */
  private short count;

  /**
   * The constants sorted in a list
   */
  List<Info> constantList;

  /**
   * Creates a new constant pool
   */
  public ConstantPool() {
    constants    = new HashMap<Object,Info>();
    count        = 1;
    constantList = new LinkedList<Info>();
  }

  /**
   * Returns the constant pool count according to the JVM Spec.
   */
  public short getCount() {
    return count;
  }

  /**
   * Adds a constant to the pool. If the constant is already present
   * in the pool, do nothing.
   * @param  cst the constant to add
   * @return the index of the constant in the pool
   */
  public short put(Integer cst) {
    Info info = constants.get(cst);
    if (info == null) {
      info = new IntegerInfo(cst);
    }
    return info.index;
  }

  /**
   * Adds a constant to the pool. If the constant is already present
   * in the pool, do nothing.
   * @param  cst the constant to add
   * @return the index of the constant in the pool
   */
  public short put(Long cst) {
    Info info = constants.get(cst);
    if (info == null) {
      info = new LongInfo(cst);
    }
    return info.index;
  }

  /**
   * Adds a constant to the pool. If the constant is already present
   * in the pool, do nothing.
   * @param  cst the constant to add
   * @return the index of the constant in the pool
   */
  public short put(Float cst) {
    Info info = constants.get(cst);
    if (info == null) {
      info = new FloatInfo(cst);
    }
    return info.index;
  }

  /**
   * Adds a constant to the pool. If the constant is already present
   * in the pool, do nothing.
   * @param  cst the constant to add
   * @return the index of the constant in the pool
   */
  public short put(Double cst) {
    Info info = constants.get(cst);
    if (info == null) {
      info = new DoubleInfo(cst);
    }
    return info.index;
  }

  /**
   * Adds a constant to the pool. If the constant is already present
   * in the pool, do nothing.
   * @param  cst the constant to add
   * @return the index of the constant in the pool
   */
  public short put(ConstantString cst) {
    Info info = constants.get(cst);
    if (info == null) {
      info = new StringInfo(cst);
    }
    return info.index;
  }

  /**
   * Adds a constant to the pool. If the constant is already present
   * in the pool, do nothing.
   * @param  cst the constant to add
   * @return the index of the constant in the pool
   */
  public short put(ClassIdentifier cst) {
    Info info = constants.get(cst);
    if (info == null) {
      info = new ClassInfo(cst);
    }
    return info.index;
  }

  /**
   * Adds a constant to the pool. If the constant is already present
   * in the pool, do nothing.
   * @param  cst the constant to add
   * @return the index of the constant in the pool
   */
  public short put(FieldIdentifier cst) {
    Info info = constants.get(cst);
    if (info == null) {
      info = new FieldInfo(cst);
    }
    return info.index;
  }

  /**
   * Adds a constant to the pool. If the constant is already present
   * in the pool, do nothing.
   * @param  cst the constant to add
   * @return the index of the constant in the pool
   */
  public short put(MethodIdentifier cst) {
    Info info = constants.get(cst);
    if (info == null) {
      info = new MethodInfo(cst);
    }
    return info.index;
  }

  /**
   * Adds a constant to the pool. If the constant is already present
   * in the pool, do nothing.
   * @param  cst the constant to add
   * @return the index of the constant in the pool
   */
  public short put(InterfaceMethodIdentifier cst) {
    Info info = constants.get(cst);
    if (info == null) {
      info = new InterfaceMethodInfo(cst);
    }
    return info.index;
  }

  /**
   * Writes the content of this pool to the given output stream
   */
  public void write(OutputStream out) throws IOException {
    write(new DataOutputStream(out));
  }

  /**
   * Writes the content of this pool to the given output stream
   */
  public void write(DataOutputStream out) throws IOException {
    out.writeShort(count);
    Iterator it = constantList.iterator();
    while(it.hasNext()) {
      ((Info)it.next()).write(out);
    }
  }

  /**
   * Adds a constant to the pool. If the constant is already present
   * in the pool, do nothing.
   * @param  name the name
   * @param  type the type
   * @param  type the type of the parameters
   * @return the index of the constant in the pool
   */
  short putNameAndType(String name, String type, String[] params) {
    NameAndTypeKey ntk = new NameAndTypeKey(name, type, params);
    Info info = constants.get(ntk);
    if (info == null) {
      info = new NameAndTypeInfo(ntk);
    }
    return info.index;
  }

  /**
   * Adds a constant to the pool. If the constant is already present
   * in the pool, do nothing.
   * @param  cst the constant to add
   * @return the index of the constant in the pool
   */
  short putUTF8(String cst) {
    Info info = constants.get(cst);
    if (info == null) {
      info = new UTF8Info(cst);
    }
    return info.index;
  }

  /**
   * Returns the entry at the given position in the pool
   */
  Info get(short i) {
    return constantList.get(i);
  }

  /**
   * This class is used to store info in the pool
   */
  abstract class Info {
    /**
     * The index of the constant in the pool
     */
    short index;

    /**
     * Initializes the object
     */
    Info(Object cst) {
      index = count;
      count += getIndexIncrement();
      constants.put(cst, this);
      constantList.add(this);
    }

    /**
     * Returns the index increment for this type of info
     */
    short getIndexIncrement() {
      return 1;
    }

    /**
     * Writes the constant information to the specified stream
     */
    abstract void write(DataOutputStream out) throws IOException;
  }

  /**
   * This class is used to store integer constants in the pool
   */
  class IntegerInfo extends Info {
    /**
     * The value of the constant
     */
    Integer value;

    /**
     * Creates a new integer constant information object
     */
    IntegerInfo(Integer v) {
      super(v);
      value = v;
    }

    /**
     * Writes the constant information to the specified stream
     */
    void write(DataOutputStream out) throws IOException {
      out.writeByte(CONSTANT_INTEGER);
      out.writeInt(value.intValue());
    }
  }

  /**
   * This class is used to store long constants in the pool
   */
  class LongInfo extends Info {
    /**
     * The value of the constant
     */
    Long value;

    /**
     * Creates a new long constant information object
     */
    LongInfo(Long v) {
      super(v);
      value = v;
    }

    /**
     * Returns the index increment for this type of info
     */
    short getIndexIncrement() {
      return 2;
    }

    /**
     * Writes the constant information to the specified stream
     */
    void write(DataOutputStream out) throws IOException {
      out.writeByte(CONSTANT_LONG);
      out.writeLong(value.longValue());
    }
  }

  /**
   * This class is used to store float constants in the pool
   */
  class FloatInfo extends Info {
    /**
     * The value of the constant
     */
    Float value;

    /**
     * Creates a new float constant information object
     */
    FloatInfo(Float v) {
      super(v);
      value = v;
    }

    /**
     * Writes the constant information to the specified stream
     */
    void write(DataOutputStream out) throws IOException {
      out.writeByte(CONSTANT_FLOAT);
      out.writeFloat(value.floatValue());
    }
  }

  /**
   * This class is used to store double constants in the pool
   */
  class DoubleInfo extends Info {
    /**
     * The value of the constant
     */
    Double value;

    /**
     * Creates a new double constant information object
     */
    DoubleInfo(Double v) {
      super(v);
      value = v;
    }

    /**
     * Returns the index increment for this type of info
     */
    short getIndexIncrement() {
      return 2;
    }

    /**
     * Writes the constant information to the specified stream
     */
    void write(DataOutputStream out) throws IOException {
      out.writeByte(CONSTANT_DOUBLE);
      out.writeDouble(value.doubleValue());
    }
  }

  /**
   * This class is used to store string constants in the pool
   */
  class StringInfo extends Info {
    /**
     * The UTF8 index
     */
    int UTF8Index;

    /**
     * Creates a new string constant information object
     */
    StringInfo(ConstantString v) {
      super(v);
      UTF8Index = putUTF8(v.getValue());
    }

    /**
     * Writes the constant information to the specified stream
     */
    void write(DataOutputStream out) throws IOException {
      out.writeByte(CONSTANT_STRING);
      out.writeShort(UTF8Index);
    }
  }

  /**
   * This class is used to store class constants in the pool
   */
  class ClassInfo extends Info {
    /**
     * The UTF8 index
     */
    int UTF8Index;

    /**
     * Creates a new class constant information object
     */
    ClassInfo(ClassIdentifier v) {
      super(v);
      UTF8Index = putUTF8(v.getValue());
    }

    /**
     * Writes the constant information to the specified stream
     */
    void write(DataOutputStream out) throws IOException {
      out.writeByte(CONSTANT_CLASS);
      out.writeShort(UTF8Index);
    }
  }

  /**
   * This class is used to store field constants in the pool
   */
  class FieldInfo extends Info {
    /**
     * The declaring class index
     */
    int classIndex;

    /**
     * The name and type info index
     */
    int nameAndTypeIndex;

    /**
     * Creates a new field constant information object
     */
    FieldInfo(FieldIdentifier v) {
      super(v);
      classIndex       = put(new ClassIdentifier(v.getDeclaringClass()));
      nameAndTypeIndex = putNameAndType(v.getName(), v.getType(), null);
    }

    /**
     * Writes the constant information to the specified stream
     */
    void write(DataOutputStream out) throws IOException {
      out.writeByte(CONSTANT_FIELDREF);
      out.writeShort(classIndex);
      out.writeShort(nameAndTypeIndex);
    }
  }

  /**
   * This class is used to store method constants in the pool
   */
  class MethodInfo extends Info {
    /**
     * The method declaring class
     */
    int classIndex;

    /**
     * The name and type info index
     */
    int nameAndTypeIndex;

    /**
     * Creates a new method constant information object
     */
    MethodInfo(MethodIdentifier v) {
      super(v);
      classIndex       = put(new ClassIdentifier(v.getDeclaringClass()));
      nameAndTypeIndex = putNameAndType(v.getName(), v.getType(),
                                        v.getParameters());
    }

    /**
     * Writes the constant information to the specified stream
     */
    void write(DataOutputStream out) throws IOException {
      out.writeByte(CONSTANT_METHODREF);
      out.writeShort(classIndex);
      out.writeShort(nameAndTypeIndex);
    }
  }

  /**
   * This class is used to store interface method constants in the pool
   */
  class InterfaceMethodInfo extends Info {
    /**
     * The method declaring class
     */
    int classIndex;

    /**
     * The name and type info index
     */
    int nameAndTypeIndex;

    /**
     * Creates a new method constant information object
     */
    InterfaceMethodInfo(InterfaceMethodIdentifier v) {
      super(v);
      classIndex       = put(new ClassIdentifier(v.getDeclaringClass()));
      nameAndTypeIndex = putNameAndType(v.getName(), v.getType(),
                                        v.getParameters());
    }

    /**
     * Writes the constant information to the specified stream
     */
    void write(DataOutputStream out) throws IOException {
      out.writeByte(CONSTANT_INTERFACEMETHODREF);
      out.writeShort(classIndex);
      out.writeShort(nameAndTypeIndex);
    }
  }

  /**
   * This class is used to store name and type constants in the pool
   */
  class NameAndTypeInfo extends Info {
    /**
     * The name
     */
    int nameIndex;

    /**
     * The type of the field
     */
    int typeIndex;

    /**
     * Creates a new class constant information object
     */
    NameAndTypeInfo(NameAndTypeKey v) {
      super(v);
      nameIndex = putUTF8(v.name);
      typeIndex = putUTF8(v.type);
    }

    /**
     * Writes the constant information to the specified stream
     */
    void write(DataOutputStream out) throws IOException {
      out.writeByte(CONSTANT_NAMEANDTYPE);
      out.writeShort(nameIndex);
      out.writeShort(typeIndex);
    }
  }

  /**
   * This class is used to store UTF8 constants in the pool
   */
  class UTF8Info extends Info {
    /**
     * The value of the constant
     */
    String value;

    /**
     * Creates a new string constant information object
     */
    UTF8Info(String v) {
      super(v);
      value = v;
    }

    /**
     * Writes the constant information to the specified stream
     */
    void write(DataOutputStream out) throws IOException {
      out.writeByte(CONSTANT_UTF8);
      out.writeUTF(value);
    }
  }

  /**
   * This class is used as a key to store a name and type info in the map
   */
  static class NameAndTypeKey {
    String   name;
    String   type;

    NameAndTypeKey(String n, String t, String[] p) {
      name = n;
      type = JVMUtilities.createMethodDescriptor(t, p);
    }

    public boolean equals(Object other) {
      if (other == null || !(other instanceof NameAndTypeKey)) {
        return false;
      }
      NameAndTypeKey fk = (NameAndTypeKey)other;
      return name.equals(fk.name) && type.equals(fk.type);
    }

    public int hashCode() {
      return name.hashCode() + type.hashCode();
    }
  }
}




See more files for this project here

DrJava

DrJava is a lightweight programming environment for Java designed to foster test-driven software development. It includes an intelligent program editor, an interactions pane for evaluating program text, a source level debugger, and a unit testing tool.

Project homepage: http://sourceforge.net/projects/drjava
Programming language(s): Java
License: other

  AbstractMethodIdentifier.java
  AbstractMethodIdentifierTest.java
  AttributeInfo.java
  AttributeOwnerComponent.java
  BytecodeComponent.java
  ClassFile.java
  ClassIdentifier.java
  ClassIdentifierTest.java
  CodeAttribute.java
  ConstantPool.java
  ConstantString.java
  ConstantValueAttribute.java
  ExceptionsAttribute.java
  FieldIdentifier.java
  FieldInfo.java
  InnerClassesAttribute.java
  InnerClassesEntry.java
  InterfaceMethodIdentifier.java
  JVMUtilities.java
  MemberIdentifier.java
  MemberIdentifierTest.java
  MethodIdentifier.java
  MethodIdentifierTest.java
  MethodInfo.java
  SimpleAttribute.java
  package.html