< prev index next >
src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java
Print this page
*** 1,8 ****
/*
! * reserved comment block
! * DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
--- 1,7 ----
/*
! * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
*** 16,643 ****
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.sun.org.apache.bcel.internal.generic;
-
- import com.sun.org.apache.bcel.internal.Constants;
- import com.sun.org.apache.bcel.internal.classfile.*;
import java.util.HashMap;
/**
! * 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.
*
! * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @see Constant
*/
! public class ConstantPoolGen implements java.io.Serializable {
! protected int size = 1024; // Inital size, sufficient in most cases
! protected Constant[] constants = new Constant[size];
! protected int index = 1; // First entry (0) used by JVM
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 static class Index implements java.io.Serializable {
! int index;
! Index(int i) { index = i; }
}
/**
* Initialize with given array of constants.
*
! * @param c array of given constants, new ones will be appended
*/
! public ConstantPoolGen(Constant[] cs) {
! 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));
}
}
}
/**
* Initialize with given constant pool.
*/
! public ConstantPoolGen(ConstantPool cp) {
this(cp.getConstantPool());
}
/**
* Create empty constant pool.
*/
! public ConstantPoolGen() {}
! /** Resize internal array of constants.
*/
protected void adjustSize() {
! if(index + 3 >= size) {
! Constant[] cs = constants;
!
size *= 2;
constants = new Constant[size];
System.arraycopy(cs, 0, constants, 0, index);
}
}
! private HashMap string_table = new HashMap();
/**
* Look for ConstantString in ConstantPool containing String `str'.
*
* @param str String to search for
* @return index on success, -1 otherwise
*/
! public int lookupString(String str) {
! Index index = (Index)string_table.get(str);
! return (index != null)? index.index : -1;
}
/**
! * Add a new String constant to the ConstantPool, if it is not already in there.
*
* @param str String to add
* @return index of entry
*/
! public int addString(String str) {
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;
}
! private HashMap class_table = new HashMap();
/**
* Look for ConstantClass in ConstantPool named `str'.
*
* @param str String to search for
* @return index on success, -1 otherwise
*/
! public int lookupClass(String str) {
! Index index = (Index)class_table.get(str.replace('.', '/'));
! return (index != null)? index.index : -1;
}
! private int addClass_(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;
}
/**
! * Add a new Class reference to the ConstantPool, if it is not already in there.
*
* @param str Class to add
* @return index of entry
*/
! public int addClass(String str) {
return addClass_(str.replace('.', '/'));
}
/**
* Add a new Class reference to the ConstantPool for a given type.
*
! * @param str Class to add
* @return index of entry
*/
! public int addClass(ObjectType type) {
return addClass(type.getClassName());
}
/**
! * 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
*/
! public int addArrayClass(ArrayType type) {
return addClass_(type.getSignature());
}
/**
* Look for ConstantInteger in ConstantPool.
*
* @param n integer number to look for
* @return index on success, -1 otherwise
*/
! public int lookupInteger(int n) {
! 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;
}
/**
! * 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
*/
! public int addInteger(int n) {
int ret;
!
! if((ret = lookupInteger(n)) != -1)
return ret; // Already in CP
!
adjustSize();
-
ret = index;
constants[index++] = new ConstantInteger(n);
-
return ret;
}
/**
* Look for ConstantFloat in ConstantPool.
*
* @param n Float number to look for
* @return index on success, -1 otherwise
*/
! public int lookupFloat(float n) {
! 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;
}
/**
! * 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
*/
! public int addFloat(float n) {
int ret;
!
! if((ret = lookupFloat(n)) != -1)
return ret; // Already in CP
!
adjustSize();
-
ret = index;
constants[index++] = new ConstantFloat(n);
-
return ret;
}
! private HashMap utf8_table = new HashMap();
/**
* Look for ConstantUtf8 in ConstantPool.
*
* @param n Utf8 string to look for
* @return index on success, -1 otherwise
*/
! public int lookupUtf8(String n) {
! Index index = (Index)utf8_table.get(n);
!
! return (index != null)? index.index : -1;
}
/**
! * 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
*/
! public int addUtf8(String n) {
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;
}
/**
* Look for ConstantLong in ConstantPool.
*
* @param n Long number to look for
* @return index on success, -1 otherwise
*/
! public int lookupLong(long n) {
! 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;
}
/**
! * 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
*/
! public int addLong(long n) {
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;
}
/**
* Look for ConstantDouble in ConstantPool.
*
* @param n Double number to look for
* @return index on success, -1 otherwise
*/
! public int lookupDouble(double n) {
! 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;
}
/**
! * 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
*/
! public int addDouble(double n) {
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;
}
! private HashMap n_a_t_table = new HashMap();
/**
* Look for ConstantNameAndType in ConstantPool.
*
* @param name of variable/method
* @param signature of variable/method
* @return index on success, -1 otherwise
*/
! public int lookupNameAndType(String name, String signature) {
! Index index = (Index)n_a_t_table.get(name + NAT_DELIM + signature);
! return (index != null)? index.index : -1;
}
/**
* 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
*/
! public int addNameAndType(String name, String signature) {
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;
}
! private HashMap cp_table = new HashMap();
/**
* 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
*/
! public int lookupMethodref(String class_name, String method_name, String signature) {
! Index index = (Index)cp_table.get(class_name + METHODREF_DELIM + method_name +
! METHODREF_DELIM + signature);
! return (index != null)? index.index : -1;
}
! public int lookupMethodref(MethodGen method) {
! return lookupMethodref(method.getClassName(), method.getName(),
! method.getSignature());
}
/**
! * 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
*/
! public int addMethodref(String class_name, String method_name, String signature) {
! 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 int addMethodref(MethodGen method) {
! return addMethodref(method.getClassName(), method.getName(),
! method.getSignature());
}
/**
* 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
*/
! public int lookupInterfaceMethodref(String class_name, String method_name, String signature) {
! Index index = (Index)cp_table.get(class_name + IMETHODREF_DELIM + method_name +
! IMETHODREF_DELIM + signature);
! return (index != null)? index.index : -1;
}
! public int lookupInterfaceMethodref(MethodGen method) {
! return lookupInterfaceMethodref(method.getClassName(), method.getName(),
! method.getSignature());
}
/**
! * 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
*/
! public int addInterfaceMethodref(String class_name, String method_name, String signature) {
! 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 int addInterfaceMethodref(MethodGen method) {
! return addInterfaceMethodref(method.getClassName(), method.getName(),
! method.getSignature());
}
/**
* 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
*/
! public int lookupFieldref(String class_name, String field_name, String signature) {
! Index index = (Index)cp_table.get(class_name + FIELDREF_DELIM + field_name +
! FIELDREF_DELIM + signature);
! return (index != null)? index.index : -1;
}
/**
! * 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
*/
! public int addFieldref(String class_name, String field_name, String signature) {
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;
}
/**
* @param i index in constant pool
* @return constant pool entry at index i
*/
! public Constant getConstant(int i) { return constants[i]; }
/**
* Use with care!
*
* @param i index in constant pool
* @param c new constant pool entry at index i
*/
! public void setConstant(int i, Constant c) { constants[i] = c; }
/**
* @return intermediate constant pool
*/
public ConstantPool getConstantPool() {
--- 15,698 ----
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.bcel.internal.generic;
import java.util.HashMap;
+ import java.util.Map;
+
+ import com.sun.org.apache.bcel.internal.Const;
+ import com.sun.org.apache.bcel.internal.classfile.Constant;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantCP;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantClass;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantDouble;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantFieldref;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantFloat;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantInteger;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantInterfaceMethodref;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantInvokeDynamic;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantLong;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantMethodref;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantString;
+ import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8;
/**
! * 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 1749603 2016-06-21 20:50:19Z ggregory $
* @see Constant
*/
! public class ConstantPoolGen {
!
! private static final int DEFAULT_BUFFER_SIZE = 256;
! private int size;
! private Constant[] constants;
! private int index = 1; // First entry (0) used by JVM
private static final String METHODREF_DELIM = ":";
private static final String IMETHODREF_DELIM = "#";
private static final String FIELDREF_DELIM = "&";
! private static final String NAT_DELIM = "%"; // Name and Type
!
! private static class Index {
! final int index;
!
! Index(final int i) {
! index = i;
! }
}
/**
* Initialize with given array of constants.
*
! * @param cs array of given constants, new ones will be appended
*/
! public ConstantPoolGen(final Constant[] cs) {
! final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE);
!
! size = Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64);
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++) {
! final Constant c = constants[i];
! if (c instanceof ConstantString) {
! final ConstantString s = (ConstantString) c;
! final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()];
! final String key = u8.getBytes();
! if (!string_table.containsKey(key)) {
! string_table.put(key, new Index(i));
! }
! } else if (c instanceof ConstantClass) {
! final ConstantClass s = (ConstantClass) c;
! final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()];
! final String key = u8.getBytes();
! if (!class_table.containsKey(key)) {
! class_table.put(key, new Index(i));
! }
! } else if (c instanceof ConstantNameAndType) {
! final ConstantNameAndType n = (ConstantNameAndType) c;
! final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()];
! final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()];
!
! sb.append(u8.getBytes());
! sb.append(NAT_DELIM);
! sb.append(u8_2.getBytes());
! final String key = sb.toString();
! sb.delete(0, sb.length());
!
! if (!n_a_t_table.containsKey(key)) {
! n_a_t_table.put(key, new Index(i));
! }
! } else if (c instanceof ConstantUtf8) {
! final ConstantUtf8 u = (ConstantUtf8) c;
! final String key = u.getBytes();
! if (!utf8_table.containsKey(key)) {
! utf8_table.put(key, new Index(i));
! }
! } else if (c instanceof ConstantCP) {
! final ConstantCP m = (ConstantCP) c;
! String class_name;
! ConstantUtf8 u8;
!
! if (c instanceof ConstantInvokeDynamic) {
! class_name = Integer.toString(((ConstantInvokeDynamic) m).getBootstrapMethodAttrIndex());
! // since name can't begin with digit, can use
! // METHODREF_DELIM with out fear of duplicates.
! } else {
! final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
! u8 = (ConstantUtf8) constants[clazz.getNameIndex()];
! class_name = u8.getBytes().replace('/', '.');
! }
!
! final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()];
! u8 = (ConstantUtf8) constants[n.getNameIndex()];
! final String method_name = u8.getBytes();
! u8 = (ConstantUtf8) constants[n.getSignatureIndex()];
! final String signature = u8.getBytes();
String delim = METHODREF_DELIM;
! if (c instanceof ConstantInterfaceMethodref) {
delim = IMETHODREF_DELIM;
! } else if (c instanceof ConstantFieldref) {
delim = FIELDREF_DELIM;
+ }
! sb.append(class_name);
! sb.append(delim);
! sb.append(method_name);
! sb.append(delim);
! sb.append(signature);
! final String key = sb.toString();
! sb.delete(0, sb.length());
!
! if (!cp_table.containsKey(key)) {
! cp_table.put(key, new Index(i));
! }
! } else if (c == null) { // entries may be null
! // nothing to do
! } else if (c instanceof ConstantInteger) {
! // nothing to do
! } else if (c instanceof ConstantLong) {
! // nothing to do
! } else if (c instanceof ConstantFloat) {
! // nothing to do
! } else if (c instanceof ConstantDouble) {
! // nothing to do
! } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodType) {
! // TODO should this be handled somehow?
! } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodHandle) {
! // TODO should this be handled somehow?
! } else {
! assert false : "Unexpected constant type: " + c.getClass().getName();
}
}
}
/**
* Initialize with given constant pool.
*/
! public ConstantPoolGen(final ConstantPool cp) {
this(cp.getConstantPool());
}
/**
* Create empty constant pool.
*/
! public ConstantPoolGen() {
! size = DEFAULT_BUFFER_SIZE;
! constants = new Constant[size];
! }
! /**
! * Resize internal array of constants.
*/
protected void adjustSize() {
! if (index + 3 >= size) {
! final Constant[] cs = constants;
size *= 2;
constants = new Constant[size];
System.arraycopy(cs, 0, constants, 0, index);
}
}
! private final Map<String, Index> string_table = new HashMap<>();
/**
* Look for ConstantString in ConstantPool containing String `str'.
*
* @param str String to search for
* @return index on success, -1 otherwise
*/
! public int lookupString(final String str) {
! final Index index = string_table.get(str);
! return (index != null) ? index.index : -1;
}
/**
! * Add a new String constant to the ConstantPool, if it is not already in
! * there.
*
* @param str String to add
* @return index of entry
*/
! public int addString(final String str) {
int ret;
! if ((ret = lookupString(str)) != -1) {
return ret; // Already in CP
! }
! final int utf8 = addUtf8(str);
adjustSize();
! final ConstantString s = new ConstantString(utf8);
ret = index;
constants[index++] = s;
! if (!string_table.containsKey(str)) {
string_table.put(str, new Index(ret));
! }
return ret;
}
! private final Map<String, Index> class_table = new HashMap<>();
/**
* Look for ConstantClass in ConstantPool named `str'.
*
* @param str String to search for
* @return index on success, -1 otherwise
*/
! public int lookupClass(final String str) {
! final Index index = class_table.get(str.replace('.', '/'));
! return (index != null) ? index.index : -1;
}
! private int addClass_(final String clazz) {
int ret;
! if ((ret = lookupClass(clazz)) != -1) {
return ret; // Already in CP
! }
adjustSize();
! final ConstantClass c = new ConstantClass(addUtf8(clazz));
ret = index;
constants[index++] = c;
! if (!class_table.containsKey(clazz)) {
class_table.put(clazz, new Index(ret));
! }
return ret;
}
/**
! * Add a new Class reference to the ConstantPool, if it is not already in
! * there.
*
* @param str Class to add
* @return index of entry
*/
! public int addClass(final String str) {
return addClass_(str.replace('.', '/'));
}
/**
* Add a new Class reference to the ConstantPool for a given type.
*
! * @param type Class to add
* @return index of entry
*/
! public int addClass(final ObjectType type) {
return addClass(type.getClassName());
}
/**
! * 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
*/
! public int addArrayClass(final ArrayType type) {
return addClass_(type.getSignature());
}
/**
* Look for ConstantInteger in ConstantPool.
*
* @param n integer number to look for
* @return index on success, -1 otherwise
*/
! public int lookupInteger(final int n) {
! for (int i = 1; i < index; i++) {
! if (constants[i] instanceof ConstantInteger) {
! final ConstantInteger c = (ConstantInteger) constants[i];
! if (c.getBytes() == n) {
return i;
}
}
! }
return -1;
}
/**
! * 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
*/
! public int addInteger(final int n) {
int ret;
! if ((ret = lookupInteger(n)) != -1) {
return ret; // Already in CP
! }
adjustSize();
ret = index;
constants[index++] = new ConstantInteger(n);
return ret;
}
/**
* Look for ConstantFloat in ConstantPool.
*
* @param n Float number to look for
* @return index on success, -1 otherwise
*/
! public int lookupFloat(final float n) {
! final int bits = Float.floatToIntBits(n);
! for (int i = 1; i < index; i++) {
! if (constants[i] instanceof ConstantFloat) {
! final ConstantFloat c = (ConstantFloat) constants[i];
! if (Float.floatToIntBits(c.getBytes()) == bits) {
return i;
}
}
! }
return -1;
}
/**
! * 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
*/
! public int addFloat(final float n) {
int ret;
! if ((ret = lookupFloat(n)) != -1) {
return ret; // Already in CP
! }
adjustSize();
ret = index;
constants[index++] = new ConstantFloat(n);
return ret;
}
! private final Map<String, Index> utf8_table = new HashMap<>();
/**
* Look for ConstantUtf8 in ConstantPool.
*
* @param n Utf8 string to look for
* @return index on success, -1 otherwise
*/
! public int lookupUtf8(final String n) {
! final Index index = utf8_table.get(n);
! return (index != null) ? index.index : -1;
}
/**
! * 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
*/
! public int addUtf8(final String n) {
int ret;
! if ((ret = lookupUtf8(n)) != -1) {
return ret; // Already in CP
! }
adjustSize();
ret = index;
constants[index++] = new ConstantUtf8(n);
! if (!utf8_table.containsKey(n)) {
utf8_table.put(n, new Index(ret));
! }
return ret;
}
/**
* Look for ConstantLong in ConstantPool.
*
* @param n Long number to look for
* @return index on success, -1 otherwise
*/
! public int lookupLong(final long n) {
! for (int i = 1; i < index; i++) {
! if (constants[i] instanceof ConstantLong) {
! final ConstantLong c = (ConstantLong) constants[i];
! if (c.getBytes() == n) {
return i;
}
}
! }
return -1;
}
/**
! * 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
*/
! public int addLong(final long n) {
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;
}
/**
* Look for ConstantDouble in ConstantPool.
*
* @param n Double number to look for
* @return index on success, -1 otherwise
*/
! public int lookupDouble(final double n) {
! final long bits = Double.doubleToLongBits(n);
! for (int i = 1; i < index; i++) {
! if (constants[i] instanceof ConstantDouble) {
! final ConstantDouble c = (ConstantDouble) constants[i];
! if (Double.doubleToLongBits(c.getBytes()) == bits) {
return i;
}
}
! }
return -1;
}
/**
! * 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
*/
! public int addDouble(final double n) {
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;
}
! private final Map<String, Index> n_a_t_table = new HashMap<>();
/**
* Look for ConstantNameAndType in ConstantPool.
*
* @param name of variable/method
* @param signature of variable/method
* @return index on success, -1 otherwise
*/
! public int lookupNameAndType(final String name, final String signature) {
! final Index _index = n_a_t_table.get(name + NAT_DELIM + signature);
! return (_index != null) ? _index.index : -1;
}
/**
* Add a new NameAndType constant to the ConstantPool if it is not already
* in there.
*
! * @param name Name string to add
! * @param signature signature string to add
* @return index of entry
*/
! public int addNameAndType(final String name, final String signature) {
int ret;
! int name_index;
! int 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);
! final String key = name + NAT_DELIM + signature;
! if (!n_a_t_table.containsKey(key)) {
! n_a_t_table.put(key, new Index(ret));
! }
return ret;
}
! private final Map<String, Index> cp_table = new HashMap<>();
/**
* 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
*/
! public int lookupMethodref(final String class_name, final String method_name, final String signature) {
! final Index index = cp_table.get(class_name + METHODREF_DELIM + method_name
! + METHODREF_DELIM + signature);
! return (index != null) ? index.index : -1;
}
! public int lookupMethodref(final MethodGen method) {
! return lookupMethodref(method.getClassName(), method.getName(), method.getSignature());
}
/**
! * Add a new Methodref constant to the ConstantPool, if it is not already in
! * there.
*
! * @param class_name class name string to add
! * @param method_name method name string to add
! * @param signature method signature string to add
* @return index of entry
*/
! public int addMethodref(final String class_name, final String method_name, final String signature) {
! int ret;
! int class_index;
! int 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);
! final String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature;
! if (!cp_table.containsKey(key)) {
! cp_table.put(key, new Index(ret));
! }
return ret;
}
! public int addMethodref(final MethodGen method) {
! return addMethodref(method.getClassName(), method.getName(), method.getSignature());
}
/**
* 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
*/
! public int lookupInterfaceMethodref(final String class_name, final String method_name, final String signature) {
! final Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name
! + IMETHODREF_DELIM + signature);
! return (index != null) ? index.index : -1;
}
! public int lookupInterfaceMethodref(final MethodGen method) {
! return lookupInterfaceMethodref(method.getClassName(), method.getName(), method
! .getSignature());
}
/**
! * Add a new InterfaceMethodref constant to the ConstantPool, if it is not
! * already in there.
*
! * @param class_name class name string to add
! * @param method_name method name string to add
! * @param signature signature string to add
* @return index of entry
*/
! public int addInterfaceMethodref(final String class_name, final String method_name, final String signature) {
! int ret;
! int class_index;
! int 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);
! final String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature;
! if (!cp_table.containsKey(key)) {
! cp_table.put(key, new Index(ret));
! }
return ret;
}
! public int addInterfaceMethodref(final MethodGen method) {
! return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature());
}
/**
* 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
*/
! public int lookupFieldref(final String class_name, final String field_name, final String signature) {
! final Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name
! + FIELDREF_DELIM + signature);
! return (index != null) ? index.index : -1;
}
/**
! * Add a new Fieldref constant to the ConstantPool, if it is not already in
! * there.
*
! * @param class_name class name string to add
! * @param field_name field name string to add
! * @param signature signature string to add
* @return index of entry
*/
! public int addFieldref(final String class_name, final String field_name, final String signature) {
int ret;
! int class_index;
! int 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);
! final String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature;
! if (!cp_table.containsKey(key)) {
! cp_table.put(key, new Index(ret));
! }
return ret;
}
/**
* @param i index in constant pool
* @return constant pool entry at index i
*/
! public Constant getConstant(final int i) {
! return constants[i];
! }
/**
* Use with care!
*
* @param i index in constant pool
* @param c new constant pool entry at index i
*/
! public void setConstant(final int i, final Constant c) {
! constants[i] = c;
! }
/**
* @return intermediate constant pool
*/
public ConstantPool getConstantPool() {
*** 653,753 ****
/**
* @return constant pool with proper length
*/
public ConstantPool getFinalConstantPool() {
! Constant[] cs = new Constant[index];
!
System.arraycopy(constants, 0, cs, 0, index);
-
return new ConstantPool(cs);
}
/**
* @return String representation.
*/
public String toString() {
! StringBuffer buf = new StringBuffer();
!
! for(int i=1; i < index; i++)
! buf.append(i + ")" + constants[i] + "\n");
!
return buf.toString();
}
! /** Import constant from another ConstantPool and return new index.
*/
! public int addConstant(Constant c, ConstantPoolGen cp) {
! 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);
}
}
}
--- 708,789 ----
/**
* @return constant pool with proper length
*/
public ConstantPool getFinalConstantPool() {
! final Constant[] cs = new Constant[index];
System.arraycopy(constants, 0, cs, 0, index);
return new ConstantPool(cs);
}
/**
* @return String representation.
*/
+ @Override
public String toString() {
! final StringBuilder buf = new StringBuilder();
! for (int i = 1; i < index; i++) {
! buf.append(i).append(")").append(constants[i]).append("\n");
! }
return buf.toString();
}
! /**
! * Import constant from another ConstantPool and return new index.
*/
! public int addConstant(final Constant c, final ConstantPoolGen cp) {
! final Constant[] constants = cp.getConstantPool().getConstantPool();
! switch (c.getTag()) {
! case Const.CONSTANT_String: {
! final ConstantString s = (ConstantString) c;
! final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()];
return addString(u8.getBytes());
}
! case Const.CONSTANT_Class: {
! final ConstantClass s = (ConstantClass) c;
! final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()];
return addClass(u8.getBytes());
}
! case Const.CONSTANT_NameAndType: {
! final ConstantNameAndType n = (ConstantNameAndType) c;
! final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()];
! final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()];
return addNameAndType(u8.getBytes(), u8_2.getBytes());
}
! case Const.CONSTANT_Utf8:
! return addUtf8(((ConstantUtf8) c).getBytes());
! case Const.CONSTANT_Double:
! return addDouble(((ConstantDouble) c).getBytes());
! case Const.CONSTANT_Float:
! return addFloat(((ConstantFloat) c).getBytes());
! case Const.CONSTANT_Long:
! return addLong(((ConstantLong) c).getBytes());
! case Const.CONSTANT_Integer:
! return addInteger(((ConstantInteger) c).getBytes());
! case Const.CONSTANT_InterfaceMethodref:
! case Const.CONSTANT_Methodref:
! case Const.CONSTANT_Fieldref: {
! final ConstantCP m = (ConstantCP) c;
! final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
! final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()];
! ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()];
! final String class_name = u8.getBytes().replace('/', '.');
! u8 = (ConstantUtf8) constants[n.getNameIndex()];
! final String name = u8.getBytes();
! u8 = (ConstantUtf8) constants[n.getSignatureIndex()];
! final String signature = u8.getBytes();
! switch (c.getTag()) {
! case Const.CONSTANT_InterfaceMethodref:
return addInterfaceMethodref(class_name, name, signature);
! case Const.CONSTANT_Methodref:
return addMethodref(class_name, name, signature);
! case Const.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);
}
}
}
< prev index next >