286N/A/*
286N/A * reserved comment block
286N/A * DO NOT REMOVE OR ALTER!
286N/A */
286N/Apackage com.sun.org.apache.bcel.internal.generic;
286N/A
286N/A/* ====================================================================
286N/A * The Apache Software License, Version 1.1
286N/A *
286N/A * Copyright (c) 2001 The Apache Software Foundation. All rights
286N/A * reserved.
286N/A *
286N/A * Redistribution and use in source and binary forms, with or without
286N/A * modification, are permitted provided that the following conditions
286N/A * are met:
286N/A *
286N/A * 1. Redistributions of source code must retain the above copyright
286N/A * notice, this list of conditions and the following disclaimer.
286N/A *
286N/A * 2. Redistributions in binary form must reproduce the above copyright
286N/A * notice, this list of conditions and the following disclaimer in
286N/A * the documentation and/or other materials provided with the
286N/A * distribution.
286N/A *
286N/A * 3. The end-user documentation included with the redistribution,
286N/A * if any, must include the following acknowledgment:
286N/A * "This product includes software developed by the
286N/A * Apache Software Foundation (http://www.apache.org/)."
286N/A * Alternately, this acknowledgment may appear in the software itself,
286N/A * if and wherever such third-party acknowledgments normally appear.
286N/A *
286N/A * 4. The names "Apache" and "Apache Software Foundation" and
286N/A * "Apache BCEL" must not be used to endorse or promote products
286N/A * derived from this software without prior written permission. For
286N/A * written permission, please contact apache@apache.org.
286N/A *
286N/A * 5. Products derived from this software may not be called "Apache",
286N/A * "Apache BCEL", nor may "Apache" appear in their name, without
286N/A * prior written permission of the Apache Software Foundation.
286N/A *
286N/A * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
286N/A * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
286N/A * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
286N/A * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
286N/A * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
286N/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
286N/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
286N/A * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
286N/A * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
286N/A * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
286N/A * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
286N/A * SUCH DAMAGE.
286N/A * ====================================================================
286N/A *
286N/A * This software consists of voluntary contributions made by many
286N/A * individuals on behalf of the Apache Software Foundation. For more
286N/A * information on the Apache Software Foundation, please see
286N/A * <http://www.apache.org/>.
286N/A */
286N/A
286N/Aimport com.sun.org.apache.bcel.internal.Constants;
286N/Aimport com.sun.org.apache.bcel.internal.classfile.*;
286N/Aimport java.util.HashMap;
286N/A
286N/A/**
286N/A * This class is used to build up a constant pool. The user adds
286N/A * constants via `addXXX' methods, `addString', `addClass',
286N/A * etc.. These methods return an index into the constant
286N/A * pool. Finally, `getFinalConstantPool()' returns the constant pool
286N/A * built up. Intermediate versions of the constant pool can be
286N/A * obtained with `getConstantPool()'. A constant pool has capacity for
286N/A * Constants.MAX_SHORT entries. Note that the first (0) is used by the
286N/A * JVM and that Double and Long constants need two slots.
286N/A *
286N/A * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
286N/A * @see Constant
286N/A */
286N/Apublic class ConstantPoolGen implements java.io.Serializable {
286N/A protected int size = 1024; // Inital size, sufficient in most cases
286N/A protected Constant[] constants = new Constant[size];
286N/A protected int index = 1; // First entry (0) used by JVM
286N/A
286N/A private static final String METHODREF_DELIM = ":";
286N/A private static final String IMETHODREF_DELIM = "#";
286N/A private static final String FIELDREF_DELIM = "&";
286N/A private static final String NAT_DELIM = "%";
286N/A
286N/A private static class Index implements java.io.Serializable {
286N/A int index;
286N/A Index(int i) { index = i; }
286N/A }
286N/A
286N/A /**
286N/A * Initialize with given array of constants.
286N/A *
286N/A * @param c array of given constants, new ones will be appended
286N/A */
286N/A public ConstantPoolGen(Constant[] cs) {
286N/A if(cs.length > size) {
286N/A size = cs.length;
286N/A constants = new Constant[size];
286N/A }
286N/A
286N/A System.arraycopy(cs, 0, constants, 0, cs.length);
286N/A
286N/A if(cs.length > 0)
286N/A index = cs.length;
286N/A
286N/A for(int i=1; i < index; i++) {
286N/A Constant c = constants[i];
286N/A
286N/A if(c instanceof ConstantString) {
286N/A ConstantString s = (ConstantString)c;
286N/A ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()];
286N/A
286N/A string_table.put(u8.getBytes(), new Index(i));
286N/A } else if(c instanceof ConstantClass) {
286N/A ConstantClass s = (ConstantClass)c;
286N/A ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
286N/A
286N/A class_table.put(u8.getBytes(), new Index(i));
286N/A } else if(c instanceof ConstantNameAndType) {
286N/A ConstantNameAndType n = (ConstantNameAndType)c;
286N/A ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()];
286N/A ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];
286N/A
286N/A n_a_t_table.put(u8.getBytes() + NAT_DELIM + u8_2.getBytes(), new Index(i));
286N/A } else if(c instanceof ConstantUtf8) {
286N/A ConstantUtf8 u = (ConstantUtf8)c;
286N/A
286N/A utf8_table.put(u.getBytes(), new Index(i));
286N/A } else if(c instanceof ConstantCP) {
286N/A ConstantCP m = (ConstantCP)c;
286N/A ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()];
286N/A ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
286N/A
286N/A ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()];
286N/A String class_name = u8.getBytes().replace('/', '.');
286N/A
286N/A u8 = (ConstantUtf8)constants[n.getNameIndex()];
286N/A String method_name = u8.getBytes();
286N/A
286N/A u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
286N/A String signature = u8.getBytes();
286N/A
286N/A String delim = METHODREF_DELIM;
286N/A
286N/A if(c instanceof ConstantInterfaceMethodref)
286N/A delim = IMETHODREF_DELIM;
286N/A else if(c instanceof ConstantFieldref)
286N/A delim = FIELDREF_DELIM;
286N/A
286N/A cp_table.put(class_name + delim + method_name + delim + signature, new Index(i));
286N/A }
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * Initialize with given constant pool.
286N/A */
286N/A public ConstantPoolGen(ConstantPool cp) {
286N/A this(cp.getConstantPool());
286N/A }
286N/A
286N/A /**
286N/A * Create empty constant pool.
286N/A */
286N/A public ConstantPoolGen() {}
286N/A
286N/A /** Resize internal array of constants.
286N/A */
286N/A protected void adjustSize() {
286N/A if(index + 3 >= size) {
286N/A Constant[] cs = constants;
286N/A
286N/A size *= 2;
286N/A constants = new Constant[size];
286N/A System.arraycopy(cs, 0, constants, 0, index);
286N/A }
286N/A }
286N/A
286N/A private HashMap string_table = new HashMap();
286N/A
286N/A /**
286N/A * Look for ConstantString in ConstantPool containing String `str'.
286N/A *
286N/A * @param str String to search for
286N/A * @return index on success, -1 otherwise
286N/A */
286N/A public int lookupString(String str) {
286N/A Index index = (Index)string_table.get(str);
286N/A return (index != null)? index.index : -1;
286N/A }
286N/A
286N/A /**
286N/A * Add a new String constant to the ConstantPool, if it is not already in there.
286N/A *
286N/A * @param str String to add
286N/A * @return index of entry
286N/A */
286N/A public int addString(String str) {
286N/A int ret;
286N/A
286N/A if((ret = lookupString(str)) != -1)
286N/A return ret; // Already in CP
286N/A
286N/A int utf8 = addUtf8(str);
286N/A
286N/A adjustSize();
286N/A
286N/A ConstantString s = new ConstantString(utf8);
286N/A
286N/A ret = index;
286N/A constants[index++] = s;
286N/A
286N/A string_table.put(str, new Index(ret));
286N/A
286N/A return ret;
286N/A }
286N/A
286N/A private HashMap class_table = new HashMap();
286N/A
286N/A /**
286N/A * Look for ConstantClass in ConstantPool named `str'.
286N/A *
286N/A * @param str String to search for
286N/A * @return index on success, -1 otherwise
286N/A */
286N/A public int lookupClass(String str) {
286N/A Index index = (Index)class_table.get(str.replace('.', '/'));
286N/A return (index != null)? index.index : -1;
286N/A }
286N/A
286N/A private int addClass_(String clazz) {
286N/A int ret;
286N/A
286N/A if((ret = lookupClass(clazz)) != -1)
286N/A return ret; // Already in CP
286N/A
286N/A adjustSize();
286N/A
286N/A ConstantClass c = new ConstantClass(addUtf8(clazz));
286N/A
286N/A ret = index;
286N/A constants[index++] = c;
286N/A
286N/A class_table.put(clazz, new Index(ret));
286N/A
286N/A return ret;
286N/A }
286N/A
286N/A /**
286N/A * Add a new Class reference to the ConstantPool, if it is not already in there.
286N/A *
286N/A * @param str Class to add
286N/A * @return index of entry
286N/A */
286N/A public int addClass(String str) {
286N/A return addClass_(str.replace('.', '/'));
286N/A }
286N/A
286N/A /**
286N/A * Add a new Class reference to the ConstantPool for a given type.
286N/A *
286N/A * @param str Class to add
286N/A * @return index of entry
286N/A */
286N/A public int addClass(ObjectType type) {
286N/A return addClass(type.getClassName());
286N/A }
286N/A
286N/A /**
286N/A * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY
286N/A * instruction, e.g. to the ConstantPool.
286N/A *
286N/A * @param type type of array class
286N/A * @return index of entry
286N/A */
286N/A public int addArrayClass(ArrayType type) {
286N/A return addClass_(type.getSignature());
286N/A }
286N/A
286N/A /**
286N/A * Look for ConstantInteger in ConstantPool.
286N/A *
286N/A * @param n integer number to look for
286N/A * @return index on success, -1 otherwise
286N/A */
286N/A public int lookupInteger(int n) {
286N/A for(int i=1; i < index; i++) {
286N/A if(constants[i] instanceof ConstantInteger) {
286N/A ConstantInteger c = (ConstantInteger)constants[i];
286N/A
286N/A if(c.getBytes() == n)
286N/A return i;
286N/A }
286N/A }
286N/A
286N/A return -1;
286N/A }
286N/A
286N/A /**
286N/A * Add a new Integer constant to the ConstantPool, if it is not already in there.
286N/A *
286N/A * @param n integer number to add
286N/A * @return index of entry
286N/A */
286N/A public int addInteger(int n) {
286N/A int ret;
286N/A
286N/A if((ret = lookupInteger(n)) != -1)
286N/A return ret; // Already in CP
286N/A
286N/A adjustSize();
286N/A
286N/A ret = index;
286N/A constants[index++] = new ConstantInteger(n);
286N/A
286N/A return ret;
286N/A }
286N/A
286N/A /**
286N/A * Look for ConstantFloat in ConstantPool.
286N/A *
286N/A * @param n Float number to look for
286N/A * @return index on success, -1 otherwise
286N/A */
286N/A public int lookupFloat(float n) {
286N/A int bits = Float.floatToIntBits(n);
286N/A
286N/A for(int i=1; i < index; i++) {
286N/A if(constants[i] instanceof ConstantFloat) {
286N/A ConstantFloat c = (ConstantFloat)constants[i];
286N/A
286N/A if(Float.floatToIntBits(c.getBytes()) == bits)
286N/A return i;
286N/A }
286N/A }
286N/A
286N/A return -1;
286N/A }
286N/A
286N/A /**
286N/A * Add a new Float constant to the ConstantPool, if it is not already in there.
286N/A *
286N/A * @param n Float number to add
286N/A * @return index of entry
286N/A */
286N/A public int addFloat(float n) {
286N/A int ret;
286N/A
286N/A if((ret = lookupFloat(n)) != -1)
286N/A return ret; // Already in CP
286N/A
286N/A adjustSize();
286N/A
286N/A ret = index;
286N/A constants[index++] = new ConstantFloat(n);
286N/A
286N/A return ret;
286N/A }
286N/A
286N/A private HashMap utf8_table = new HashMap();
286N/A
286N/A /**
286N/A * Look for ConstantUtf8 in ConstantPool.
286N/A *
286N/A * @param n Utf8 string to look for
286N/A * @return index on success, -1 otherwise
286N/A */
286N/A public int lookupUtf8(String n) {
286N/A Index index = (Index)utf8_table.get(n);
286N/A
286N/A return (index != null)? index.index : -1;
286N/A }
286N/A
286N/A /**
286N/A * Add a new Utf8 constant to the ConstantPool, if it is not already in there.
286N/A *
286N/A * @param n Utf8 string to add
286N/A * @return index of entry
286N/A */
286N/A public int addUtf8(String n) {
286N/A int ret;
286N/A
286N/A if((ret = lookupUtf8(n)) != -1)
286N/A return ret; // Already in CP
286N/A
286N/A adjustSize();
286N/A
286N/A ret = index;
286N/A constants[index++] = new ConstantUtf8(n);
286N/A
286N/A utf8_table.put(n, new Index(ret));
286N/A
286N/A return ret;
286N/A }
286N/A
286N/A /**
286N/A * Look for ConstantLong in ConstantPool.
286N/A *
286N/A * @param n Long number to look for
286N/A * @return index on success, -1 otherwise
286N/A */
286N/A public int lookupLong(long n) {
286N/A for(int i=1; i < index; i++) {
286N/A if(constants[i] instanceof ConstantLong) {
286N/A ConstantLong c = (ConstantLong)constants[i];
286N/A
286N/A if(c.getBytes() == n)
286N/A return i;
286N/A }
286N/A }
286N/A
286N/A return -1;
286N/A }
286N/A
286N/A /**
286N/A * Add a new long constant to the ConstantPool, if it is not already in there.
286N/A *
286N/A * @param n Long number to add
286N/A * @return index of entry
286N/A */
286N/A public int addLong(long n) {
286N/A int ret;
286N/A
286N/A if((ret = lookupLong(n)) != -1)
286N/A return ret; // Already in CP
286N/A
286N/A adjustSize();
286N/A
286N/A ret = index;
286N/A constants[index] = new ConstantLong(n);
286N/A index += 2; // Wastes one entry according to spec
286N/A
286N/A return ret;
286N/A }
286N/A
286N/A /**
286N/A * Look for ConstantDouble in ConstantPool.
286N/A *
286N/A * @param n Double number to look for
286N/A * @return index on success, -1 otherwise
286N/A */
286N/A public int lookupDouble(double n) {
286N/A long bits = Double.doubleToLongBits(n);
286N/A
286N/A for(int i=1; i < index; i++) {
286N/A if(constants[i] instanceof ConstantDouble) {
286N/A ConstantDouble c = (ConstantDouble)constants[i];
286N/A
286N/A if(Double.doubleToLongBits(c.getBytes()) == bits)
286N/A return i;
286N/A }
286N/A }
286N/A
286N/A return -1;
286N/A }
286N/A
286N/A /**
286N/A * Add a new double constant to the ConstantPool, if it is not already in there.
286N/A *
286N/A * @param n Double number to add
286N/A * @return index of entry
286N/A */
286N/A public int addDouble(double n) {
286N/A int ret;
286N/A
286N/A if((ret = lookupDouble(n)) != -1)
286N/A return ret; // Already in CP
286N/A
286N/A adjustSize();
286N/A
286N/A ret = index;
286N/A constants[index] = new ConstantDouble(n);
286N/A index += 2; // Wastes one entry according to spec
286N/A
286N/A return ret;
286N/A }
286N/A
286N/A private HashMap n_a_t_table = new HashMap();
286N/A
286N/A /**
286N/A * Look for ConstantNameAndType in ConstantPool.
286N/A *
286N/A * @param name of variable/method
286N/A * @param signature of variable/method
286N/A * @return index on success, -1 otherwise
286N/A */
286N/A public int lookupNameAndType(String name, String signature) {
286N/A Index index = (Index)n_a_t_table.get(name + NAT_DELIM + signature);
286N/A return (index != null)? index.index : -1;
286N/A }
286N/A
286N/A /**
286N/A * Add a new NameAndType constant to the ConstantPool if it is not already
286N/A * in there.
286N/A *
286N/A * @param n NameAndType string to add
286N/A * @return index of entry
286N/A */
286N/A public int addNameAndType(String name, String signature) {
286N/A int ret;
286N/A int name_index, signature_index;
286N/A
286N/A if((ret = lookupNameAndType(name, signature)) != -1)
286N/A return ret; // Already in CP
286N/A
286N/A adjustSize();
286N/A
286N/A name_index = addUtf8(name);
286N/A signature_index = addUtf8(signature);
286N/A ret = index;
286N/A constants[index++] = new ConstantNameAndType(name_index, signature_index);
286N/A
286N/A n_a_t_table.put(name + NAT_DELIM + signature, new Index(ret));
286N/A return ret;
286N/A }
286N/A
286N/A private HashMap cp_table = new HashMap();
286N/A
286N/A /**
286N/A * Look for ConstantMethodref in ConstantPool.
286N/A *
286N/A * @param class_name Where to find method
286N/A * @param method_name Guess what
286N/A * @param signature return and argument types
286N/A * @return index on success, -1 otherwise
286N/A */
286N/A public int lookupMethodref(String class_name, String method_name, String signature) {
286N/A Index index = (Index)cp_table.get(class_name + METHODREF_DELIM + method_name +
286N/A METHODREF_DELIM + signature);
286N/A return (index != null)? index.index : -1;
286N/A }
286N/A
286N/A public int lookupMethodref(MethodGen method) {
286N/A return lookupMethodref(method.getClassName(), method.getName(),
286N/A method.getSignature());
286N/A }
286N/A
286N/A /**
286N/A * Add a new Methodref constant to the ConstantPool, if it is not already
286N/A * in there.
286N/A *
286N/A * @param n Methodref string to add
286N/A * @return index of entry
286N/A */
286N/A public int addMethodref(String class_name, String method_name, String signature) {
286N/A int ret, class_index, name_and_type_index;
286N/A
286N/A if((ret = lookupMethodref(class_name, method_name, signature)) != -1)
286N/A return ret; // Already in CP
286N/A
286N/A adjustSize();
286N/A
286N/A name_and_type_index = addNameAndType(method_name, signature);
286N/A class_index = addClass(class_name);
286N/A ret = index;
286N/A constants[index++] = new ConstantMethodref(class_index, name_and_type_index);
286N/A
286N/A cp_table.put(class_name + METHODREF_DELIM + method_name +
286N/A METHODREF_DELIM + signature, new Index(ret));
286N/A
286N/A return ret;
286N/A }
286N/A
286N/A public int addMethodref(MethodGen method) {
286N/A return addMethodref(method.getClassName(), method.getName(),
286N/A method.getSignature());
286N/A }
286N/A
286N/A /**
286N/A * Look for ConstantInterfaceMethodref in ConstantPool.
286N/A *
286N/A * @param class_name Where to find method
286N/A * @param method_name Guess what
286N/A * @param signature return and argument types
286N/A * @return index on success, -1 otherwise
286N/A */
286N/A public int lookupInterfaceMethodref(String class_name, String method_name, String signature) {
286N/A Index index = (Index)cp_table.get(class_name + IMETHODREF_DELIM + method_name +
286N/A IMETHODREF_DELIM + signature);
286N/A return (index != null)? index.index : -1;
286N/A }
286N/A
286N/A public int lookupInterfaceMethodref(MethodGen method) {
286N/A return lookupInterfaceMethodref(method.getClassName(), method.getName(),
286N/A method.getSignature());
286N/A }
286N/A
286N/A /**
286N/A * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already
286N/A * in there.
286N/A *
286N/A * @param n InterfaceMethodref string to add
286N/A * @return index of entry
286N/A */
286N/A public int addInterfaceMethodref(String class_name, String method_name, String signature) {
286N/A int ret, class_index, name_and_type_index;
286N/A
286N/A if((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1)
286N/A return ret; // Already in CP
286N/A
286N/A adjustSize();
286N/A
286N/A class_index = addClass(class_name);
286N/A name_and_type_index = addNameAndType(method_name, signature);
286N/A ret = index;
286N/A constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index);
286N/A
286N/A cp_table.put(class_name + IMETHODREF_DELIM + method_name +
286N/A IMETHODREF_DELIM + signature, new Index(ret));
286N/A
286N/A return ret;
286N/A }
286N/A
286N/A public int addInterfaceMethodref(MethodGen method) {
286N/A return addInterfaceMethodref(method.getClassName(), method.getName(),
286N/A method.getSignature());
286N/A }
286N/A
286N/A /**
286N/A * Look for ConstantFieldref in ConstantPool.
286N/A *
286N/A * @param class_name Where to find method
286N/A * @param field_name Guess what
286N/A * @param signature return and argument types
286N/A * @return index on success, -1 otherwise
286N/A */
286N/A public int lookupFieldref(String class_name, String field_name, String signature) {
286N/A Index index = (Index)cp_table.get(class_name + FIELDREF_DELIM + field_name +
286N/A FIELDREF_DELIM + signature);
286N/A return (index != null)? index.index : -1;
286N/A }
286N/A
286N/A /**
286N/A * Add a new Fieldref constant to the ConstantPool, if it is not already
286N/A * in there.
286N/A *
286N/A * @param n Fieldref string to add
286N/A * @return index of entry
286N/A */
286N/A public int addFieldref(String class_name, String field_name, String signature) {
286N/A int ret;
286N/A int class_index, name_and_type_index;
286N/A
286N/A if((ret = lookupFieldref(class_name, field_name, signature)) != -1)
286N/A return ret; // Already in CP
286N/A
286N/A adjustSize();
286N/A
286N/A class_index = addClass(class_name);
286N/A name_and_type_index = addNameAndType(field_name, signature);
286N/A ret = index;
286N/A constants[index++] = new ConstantFieldref(class_index, name_and_type_index);
286N/A
286N/A cp_table.put(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature, new Index(ret));
286N/A
286N/A return ret;
286N/A }
286N/A
286N/A /**
286N/A * @param i index in constant pool
286N/A * @return constant pool entry at index i
286N/A */
286N/A public Constant getConstant(int i) { return constants[i]; }
286N/A
286N/A /**
286N/A * Use with care!
286N/A *
286N/A * @param i index in constant pool
286N/A * @param c new constant pool entry at index i
286N/A */
286N/A public void setConstant(int i, Constant c) { constants[i] = c; }
286N/A
286N/A /**
286N/A * @return intermediate constant pool
286N/A */
286N/A public ConstantPool getConstantPool() {
286N/A return new ConstantPool(constants);
286N/A }
286N/A
286N/A /**
286N/A * @return current size of constant pool
286N/A */
286N/A public int getSize() {
286N/A return index;
286N/A }
286N/A
286N/A /**
286N/A * @return constant pool with proper length
286N/A */
286N/A public ConstantPool getFinalConstantPool() {
286N/A Constant[] cs = new Constant[index];
286N/A
286N/A System.arraycopy(constants, 0, cs, 0, index);
286N/A
286N/A return new ConstantPool(cs);
286N/A }
286N/A
286N/A /**
286N/A * @return String representation.
286N/A */
286N/A public String toString() {
286N/A StringBuffer buf = new StringBuffer();
286N/A
286N/A for(int i=1; i < index; i++)
286N/A buf.append(i + ")" + constants[i] + "\n");
286N/A
286N/A return buf.toString();
286N/A }
286N/A
286N/A /** Import constant from another ConstantPool and return new index.
286N/A */
286N/A public int addConstant(Constant c, ConstantPoolGen cp) {
286N/A Constant[] constants = cp.getConstantPool().getConstantPool();
286N/A
286N/A switch(c.getTag()) {
286N/A case Constants.CONSTANT_String: {
286N/A ConstantString s = (ConstantString)c;
286N/A ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()];
286N/A
286N/A return addString(u8.getBytes());
286N/A }
286N/A
286N/A case Constants.CONSTANT_Class: {
286N/A ConstantClass s = (ConstantClass)c;
286N/A ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
286N/A
286N/A return addClass(u8.getBytes());
286N/A }
286N/A
286N/A case Constants.CONSTANT_NameAndType: {
286N/A ConstantNameAndType n = (ConstantNameAndType)c;
286N/A ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()];
286N/A ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];
286N/A
286N/A return addNameAndType(u8.getBytes(), u8_2.getBytes());
286N/A }
286N/A
286N/A case Constants.CONSTANT_Utf8:
286N/A return addUtf8(((ConstantUtf8)c).getBytes());
286N/A
286N/A case Constants.CONSTANT_Double:
286N/A return addDouble(((ConstantDouble)c).getBytes());
286N/A
286N/A case Constants.CONSTANT_Float:
286N/A return addFloat(((ConstantFloat)c).getBytes());
286N/A
286N/A case Constants.CONSTANT_Long:
286N/A return addLong(((ConstantLong)c).getBytes());
286N/A
286N/A case Constants.CONSTANT_Integer:
286N/A return addInteger(((ConstantInteger)c).getBytes());
286N/A
286N/A case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref:
286N/A case Constants.CONSTANT_Fieldref: {
286N/A ConstantCP m = (ConstantCP)c;
286N/A ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()];
286N/A ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
286N/A ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()];
286N/A String class_name = u8.getBytes().replace('/', '.');
286N/A
286N/A u8 = (ConstantUtf8)constants[n.getNameIndex()];
286N/A String name = u8.getBytes();
286N/A
286N/A u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
286N/A String signature = u8.getBytes();
286N/A
286N/A switch(c.getTag()) {
286N/A case Constants.CONSTANT_InterfaceMethodref:
286N/A return addInterfaceMethodref(class_name, name, signature);
286N/A
286N/A case Constants.CONSTANT_Methodref:
286N/A return addMethodref(class_name, name, signature);
286N/A
286N/A case Constants.CONSTANT_Fieldref:
286N/A return addFieldref(class_name, name, signature);
286N/A
286N/A default: // Never reached
286N/A throw new RuntimeException("Unknown constant type " + c);
286N/A }
286N/A }
286N/A
286N/A default: // Never reached
286N/A throw new RuntimeException("Unknown constant type " + c);
286N/A }
286N/A }
286N/A}