FileDocCategorySizeDatePackage
ConstantPoolGen.javaAPI DocJava SE 6 API22581Tue Jun 10 00:22:18 BST 2008com.sun.org.apache.bcel.internal.generic

ConstantPoolGen

public class ConstantPoolGen extends Object implements Serializable
This class is used to build up a constant pool. The user adds constants via `addXXX' methods, `addString', `addClass', etc.. These methods return an index into the constant pool. Finally, `getFinalConstantPool()' returns the constant pool built up. Intermediate versions of the constant pool can be obtained with `getConstantPool()'. A constant pool has capacity for Constants.MAX_SHORT entries. Note that the first (0) is used by the JVM and that Double and Long constants need two slots.
version
$Id: ConstantPoolGen.java,v 1.1.2.1 2005/07/31 23:45:00 jeffsuttor Exp $
author
M. Dahm
see
Constant

Fields Summary
protected int
size
protected Constant[]
constants
protected int
index
private static final String
METHODREF_DELIM
private static final String
IMETHODREF_DELIM
private static final String
FIELDREF_DELIM
private static final String
NAT_DELIM
private HashMap
string_table
private HashMap
class_table
private HashMap
utf8_table
private HashMap
n_a_t_table
private HashMap
cp_table
Constructors Summary
public ConstantPoolGen(Constant[] cs)
Initialize with given array of constants.

param
c array of given constants, new ones will be appended

    if(cs.length > size) {
      size      = cs.length;
      constants = new Constant[size];
    }

    System.arraycopy(cs, 0, constants, 0, cs.length);

    if(cs.length > 0)
      index = cs.length;

    for(int i=1; i < index; i++) {
      Constant c = constants[i];

      if(c instanceof ConstantString) {
	ConstantString s  = (ConstantString)c;
	ConstantUtf8   u8 = (ConstantUtf8)constants[s.getStringIndex()];

	string_table.put(u8.getBytes(), new Index(i));
      } else if(c instanceof ConstantClass) {
	ConstantClass s  = (ConstantClass)c;
	ConstantUtf8  u8 = (ConstantUtf8)constants[s.getNameIndex()];

	class_table.put(u8.getBytes(), new Index(i));
      } else if(c instanceof ConstantNameAndType) {
	ConstantNameAndType n    = (ConstantNameAndType)c;
	ConstantUtf8        u8   = (ConstantUtf8)constants[n.getNameIndex()];
	ConstantUtf8        u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];

	n_a_t_table.put(u8.getBytes() + NAT_DELIM + u8_2.getBytes(), new Index(i));
       } else if(c instanceof ConstantUtf8) {
         ConstantUtf8 u = (ConstantUtf8)c;
         
         utf8_table.put(u.getBytes(), new Index(i));
      } else if(c instanceof ConstantCP) {
	ConstantCP          m     = (ConstantCP)c;
	ConstantClass       clazz = (ConstantClass)constants[m.getClassIndex()];
	ConstantNameAndType n     = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
	
        ConstantUtf8 u8         = (ConstantUtf8)constants[clazz.getNameIndex()];
        String       class_name = u8.getBytes().replace('/", '.");

	u8 = (ConstantUtf8)constants[n.getNameIndex()];
	String method_name = u8.getBytes();

	u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
	String signature = u8.getBytes();

	String delim = METHODREF_DELIM;

	if(c instanceof ConstantInterfaceMethodref)
	  delim = IMETHODREF_DELIM;
	else if(c instanceof ConstantFieldref)
	  delim = FIELDREF_DELIM;

	cp_table.put(class_name + delim + method_name + delim + signature, new Index(i));
      }
    }
  
public ConstantPoolGen(ConstantPool cp)
Initialize with given constant pool.

    this(cp.getConstantPool());
  
public ConstantPoolGen()
Create empty constant pool.

Methods Summary
public intaddArrayClass(com.sun.org.apache.bcel.internal.generic.ArrayType type)
Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY instruction, e.g. to the ConstantPool.

param
type type of array class
return
index of entry

    return addClass_(type.getSignature());
  
public intaddClass(com.sun.org.apache.bcel.internal.generic.ObjectType type)
Add a new Class reference to the ConstantPool for a given type.

param
str Class to add
return
index of entry

    return addClass(type.getClassName());
  
public intaddClass(java.lang.String str)
Add a new Class reference to the ConstantPool, if it is not already in there.

param
str Class to add
return
index of entry

    return addClass_(str.replace('.", '/"));
  
private intaddClass_(java.lang.String clazz)

    int    ret;

    if((ret = lookupClass(clazz)) != -1)
      return ret; // Already in CP

    adjustSize();

    ConstantClass c = new ConstantClass(addUtf8(clazz));

    ret = index;
    constants[index++] = c;

    class_table.put(clazz, new Index(ret));

    return ret;
  
public intaddConstant(com.sun.org.apache.bcel.internal.classfile.Constant c, com.sun.org.apache.bcel.internal.generic.ConstantPoolGen cp)
Import constant from another ConstantPool and return new index.

    Constant[] constants = cp.getConstantPool().getConstantPool();

    switch(c.getTag()) {
    case Constants.CONSTANT_String: {
      ConstantString s  = (ConstantString)c;
      ConstantUtf8   u8 = (ConstantUtf8)constants[s.getStringIndex()];

      return addString(u8.getBytes());
    }

    case Constants.CONSTANT_Class: {
      ConstantClass s  = (ConstantClass)c;
      ConstantUtf8  u8 = (ConstantUtf8)constants[s.getNameIndex()];

      return addClass(u8.getBytes());
    }

    case Constants.CONSTANT_NameAndType: {
      ConstantNameAndType n    = (ConstantNameAndType)c;
      ConstantUtf8        u8   = (ConstantUtf8)constants[n.getNameIndex()];
      ConstantUtf8        u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];

      return addNameAndType(u8.getBytes(), u8_2.getBytes());
    }

    case Constants.CONSTANT_Utf8:
      return addUtf8(((ConstantUtf8)c).getBytes());

    case Constants.CONSTANT_Double:
      return addDouble(((ConstantDouble)c).getBytes());

    case Constants.CONSTANT_Float:
      return addFloat(((ConstantFloat)c).getBytes());

    case Constants.CONSTANT_Long:
      return addLong(((ConstantLong)c).getBytes());

    case Constants.CONSTANT_Integer:
      return addInteger(((ConstantInteger)c).getBytes());

    case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref:
    case Constants.CONSTANT_Fieldref: {
      ConstantCP          m     = (ConstantCP)c;
      ConstantClass       clazz = (ConstantClass)constants[m.getClassIndex()];
      ConstantNameAndType n     = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
      ConstantUtf8 u8           = (ConstantUtf8)constants[clazz.getNameIndex()];
      String       class_name   = u8.getBytes().replace('/", '.");

      u8 = (ConstantUtf8)constants[n.getNameIndex()];
      String name = u8.getBytes();

      u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
      String signature = u8.getBytes();

      switch(c.getTag()) {
      case Constants.CONSTANT_InterfaceMethodref:
	return addInterfaceMethodref(class_name, name, signature);

      case Constants.CONSTANT_Methodref:
	return addMethodref(class_name, name, signature);

      case Constants.CONSTANT_Fieldref:
	return addFieldref(class_name, name, signature);

      default: // Never reached
	throw new RuntimeException("Unknown constant type " + c);
      }
    }

    default: // Never reached
      throw new RuntimeException("Unknown constant type " + c);
    }
  
public intaddDouble(double n)
Add a new double constant to the ConstantPool, if it is not already in there.

param
n Double number to add
return
index of entry

    int  ret;

    if((ret = lookupDouble(n)) != -1)
      return ret; // Already in CP

    adjustSize();

    ret = index;
    constants[index] = new ConstantDouble(n);
    index += 2;   // Wastes one entry according to spec

    return ret;
  
public intaddFieldref(java.lang.String class_name, java.lang.String field_name, java.lang.String signature)
Add a new Fieldref constant to the ConstantPool, if it is not already in there.

param
n Fieldref string to add
return
index of entry

    int  ret;
    int  class_index, name_and_type_index;

    if((ret = lookupFieldref(class_name, field_name, signature)) != -1)
      return ret; // Already in CP

    adjustSize();

    class_index         = addClass(class_name);
    name_and_type_index = addNameAndType(field_name, signature);
    ret = index;
    constants[index++] = new ConstantFieldref(class_index, name_and_type_index);

    cp_table.put(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature, new Index(ret));

    return ret;
  
public intaddFloat(float n)
Add a new Float constant to the ConstantPool, if it is not already in there.

param
n Float number to add
return
index of entry

    int  ret;

    if((ret = lookupFloat(n)) != -1)
      return ret; // Already in CP

    adjustSize();

    ret = index;
    constants[index++] = new ConstantFloat(n);

    return ret;
  
public intaddInteger(int n)
Add a new Integer constant to the ConstantPool, if it is not already in there.

param
n integer number to add
return
index of entry

    int  ret;

    if((ret = lookupInteger(n)) != -1)
      return ret; // Already in CP

    adjustSize();

    ret = index;
    constants[index++] = new ConstantInteger(n);

    return ret;
  
public intaddInterfaceMethodref(java.lang.String class_name, java.lang.String method_name, java.lang.String signature)
Add a new InterfaceMethodref constant to the ConstantPool, if it is not already in there.

param
n InterfaceMethodref string to add
return
index of entry

    int ret, class_index, name_and_type_index;

    if((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1)
      return ret; // Already in CP

    adjustSize();

    class_index         = addClass(class_name);
    name_and_type_index = addNameAndType(method_name, signature);
    ret = index;
    constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index);

    cp_table.put(class_name + IMETHODREF_DELIM + method_name +
		 IMETHODREF_DELIM + signature, new Index(ret));

    return ret;
  
public intaddInterfaceMethodref(com.sun.org.apache.bcel.internal.generic.MethodGen method)

    return addInterfaceMethodref(method.getClassName(), method.getName(),
				 method.getSignature());
  
public intaddLong(long n)
Add a new long constant to the ConstantPool, if it is not already in there.

param
n Long number to add
return
index of entry

    int  ret;

    if((ret = lookupLong(n)) != -1)
      return ret; // Already in CP

    adjustSize();

    ret = index;
    constants[index] = new ConstantLong(n);
    index += 2;   // Wastes one entry according to spec

    return ret;
  
public intaddMethodref(java.lang.String class_name, java.lang.String method_name, java.lang.String signature)
Add a new Methodref constant to the ConstantPool, if it is not already in there.

param
n Methodref string to add
return
index of entry

    int  ret, class_index, name_and_type_index;

    if((ret = lookupMethodref(class_name, method_name, signature)) != -1)
      return ret; // Already in CP

    adjustSize();

    name_and_type_index = addNameAndType(method_name, signature);
    class_index         = addClass(class_name);
    ret = index;
    constants[index++] = new ConstantMethodref(class_index, name_and_type_index);

    cp_table.put(class_name + METHODREF_DELIM + method_name +
		 METHODREF_DELIM + signature, new Index(ret));

    return ret;
  
public intaddMethodref(com.sun.org.apache.bcel.internal.generic.MethodGen method)

    return addMethodref(method.getClassName(), method.getName(),
			method.getSignature());
  
public intaddNameAndType(java.lang.String name, java.lang.String signature)
Add a new NameAndType constant to the ConstantPool if it is not already in there.

param
n NameAndType string to add
return
index of entry

    int  ret;
    int  name_index, signature_index;

    if((ret = lookupNameAndType(name, signature)) != -1)
      return ret; // Already in CP

    adjustSize();

    name_index      = addUtf8(name);
    signature_index = addUtf8(signature);
    ret = index;
    constants[index++] = new ConstantNameAndType(name_index, signature_index);

    n_a_t_table.put(name + NAT_DELIM + signature, new Index(ret));
    return ret;
  
public intaddString(java.lang.String str)
Add a new String constant to the ConstantPool, if it is not already in there.

param
str String to add
return
index of entry

    int ret;
    
    if((ret = lookupString(str)) != -1)
      return ret; // Already in CP

    int utf8 = addUtf8(str);

    adjustSize();

    ConstantString s  = new ConstantString(utf8);
       
    ret = index;
    constants[index++] = s;

    string_table.put(str, new Index(ret));

    return ret;
  
public intaddUtf8(java.lang.String n)
Add a new Utf8 constant to the ConstantPool, if it is not already in there.

param
n Utf8 string to add
return
index of entry

    int  ret;

    if((ret = lookupUtf8(n)) != -1)
      return ret; // Already in CP

    adjustSize();

    ret = index;
    constants[index++] = new ConstantUtf8(n);

    utf8_table.put(n, new Index(ret));

    return ret;
  
protected voidadjustSize()
Resize internal array of constants.

    if(index + 3 >= size) {
      Constant[] cs = constants;

      size      *= 2;
      constants  = new Constant[size];
      System.arraycopy(cs, 0, constants, 0, index);
    }
  
public com.sun.org.apache.bcel.internal.classfile.ConstantgetConstant(int i)

param
i index in constant pool
return
constant pool entry at index i

 return constants[i]; 
public com.sun.org.apache.bcel.internal.classfile.ConstantPoolgetConstantPool()

return
intermediate constant pool

    return new ConstantPool(constants);
  
public com.sun.org.apache.bcel.internal.classfile.ConstantPoolgetFinalConstantPool()

return
constant pool with proper length

 
    Constant[] cs = new Constant[index];
    
    System.arraycopy(constants, 0, cs, 0, index);

    return new ConstantPool(cs); 
  
public intgetSize()

return
current size of constant pool

    return index;
  
public intlookupClass(java.lang.String str)
Look for ConstantClass in ConstantPool named `str'.

param
str String to search for
return
index on success, -1 otherwise


                        
      
    Index index = (Index)class_table.get(str.replace('.", '/"));
    return (index != null)? index.index : -1;
  
public intlookupDouble(double n)
Look for ConstantDouble in ConstantPool.

param
n Double number to look for
return
index on success, -1 otherwise

    long bits = Double.doubleToLongBits(n);

    for(int i=1; i < index; i++) {
      if(constants[i] instanceof ConstantDouble) {
	ConstantDouble c = (ConstantDouble)constants[i];
	
	if(Double.doubleToLongBits(c.getBytes()) == bits)
	  return i;
      }
    }

    return -1;
  
public intlookupFieldref(java.lang.String class_name, java.lang.String field_name, java.lang.String signature)
Look for ConstantFieldref in ConstantPool.

param
class_name Where to find method
param
field_name Guess what
param
signature return and argument types
return
index on success, -1 otherwise

    Index index = (Index)cp_table.get(class_name + FIELDREF_DELIM + field_name +
				      FIELDREF_DELIM + signature);
    return (index != null)? index.index : -1;
  
public intlookupFloat(float n)
Look for ConstantFloat in ConstantPool.

param
n Float number to look for
return
index on success, -1 otherwise

    int bits = Float.floatToIntBits(n);

    for(int i=1; i < index; i++) {
      if(constants[i] instanceof ConstantFloat) {
	ConstantFloat c = (ConstantFloat)constants[i];

	if(Float.floatToIntBits(c.getBytes()) == bits)
	  return i;
      }
    }

    return -1;
  
public intlookupInteger(int n)
Look for ConstantInteger in ConstantPool.

param
n integer number to look for
return
index on success, -1 otherwise

    for(int i=1; i < index; i++) {
      if(constants[i] instanceof ConstantInteger) {
	ConstantInteger c = (ConstantInteger)constants[i];

	if(c.getBytes() == n)
	  return i;
      }
    }

    return -1;
  
public intlookupInterfaceMethodref(java.lang.String class_name, java.lang.String method_name, java.lang.String signature)
Look for ConstantInterfaceMethodref in ConstantPool.

param
class_name Where to find method
param
method_name Guess what
param
signature return and argument types
return
index on success, -1 otherwise

    Index index = (Index)cp_table.get(class_name + IMETHODREF_DELIM + method_name +
				      IMETHODREF_DELIM + signature);
    return (index != null)? index.index : -1;
  
public intlookupInterfaceMethodref(com.sun.org.apache.bcel.internal.generic.MethodGen method)

    return lookupInterfaceMethodref(method.getClassName(), method.getName(),
				    method.getSignature());
  
public intlookupLong(long n)
Look for ConstantLong in ConstantPool.

param
n Long number to look for
return
index on success, -1 otherwise

    for(int i=1; i < index; i++) {
      if(constants[i] instanceof ConstantLong) {
	ConstantLong c = (ConstantLong)constants[i];

	if(c.getBytes() == n)
	  return i;
      }
    }

    return -1;
  
public intlookupMethodref(java.lang.String class_name, java.lang.String method_name, java.lang.String signature)
Look for ConstantMethodref in ConstantPool.

param
class_name Where to find method
param
method_name Guess what
param
signature return and argument types
return
index on success, -1 otherwise


                                 
          
    Index index = (Index)cp_table.get(class_name + METHODREF_DELIM + method_name +
				      METHODREF_DELIM + signature);
    return (index != null)? index.index : -1;
  
public intlookupMethodref(com.sun.org.apache.bcel.internal.generic.MethodGen method)

    return lookupMethodref(method.getClassName(), method.getName(),
			  method.getSignature());
  
public intlookupNameAndType(java.lang.String name, java.lang.String signature)
Look for ConstantNameAndType in ConstantPool.

param
name of variable/method
param
signature of variable/method
return
index on success, -1 otherwise


                         
        
    Index index = (Index)n_a_t_table.get(name + NAT_DELIM + signature);
    return (index != null)? index.index : -1;
  
public intlookupString(java.lang.String str)
Look for ConstantString in ConstantPool containing String `str'.

param
str String to search for
return
index on success, -1 otherwise


                          
      
    Index index = (Index)string_table.get(str);
    return (index != null)? index.index : -1;
  
public intlookupUtf8(java.lang.String n)
Look for ConstantUtf8 in ConstantPool.

param
n Utf8 string to look for
return
index on success, -1 otherwise


                        
      
    Index index = (Index)utf8_table.get(n);

    return (index != null)? index.index : -1;
  
public voidsetConstant(int i, com.sun.org.apache.bcel.internal.classfile.Constant c)
Use with care!

param
i index in constant pool
param
c new constant pool entry at index i

 constants[i] = c; 
public java.lang.StringtoString()

return
String representation.

    StringBuffer buf = new StringBuffer();

    for(int i=1; i < index; i++)
      buf.append(i + ")" + constants[i] + "\n");

    return buf.toString();