/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache BCEL" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache BCEL", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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 consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.aspectj.apache.bcel.classfile;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.generic.ArrayType;
import org.aspectj.apache.bcel.generic.ObjectType;

This class represents the constant pool, i.e., a table of constants, of a parsed classfile. It may contain null references, due to the JVM specification that skips an entry after an 8-byte constant (double, long) entry.
/** * This class represents the constant pool, i.e., a table of constants, of a parsed classfile. It may contain null references, due * to the JVM specification that skips an entry after an 8-byte constant (double, long) entry. */
public class ConstantPool implements Node { private Constant[] pool; private int poolSize; // number of entries in the pool (could be < pool.length as the array is resized in 'chunks') private Map<String, Integer> utf8Cache = new HashMap<String, Integer>(); private Map<String, Integer> methodCache = new HashMap<String, Integer>(); private Map<String, Integer> fieldCache = new HashMap<String, Integer>(); public int getSize() { return poolSize; } public ConstantPool() { pool = new Constant[10]; poolSize = 0; } public ConstantPool(Constant[] constants) { pool = constants; poolSize = (constants == null ? 0 : constants.length); } ConstantPool(DataInputStream file) throws IOException { byte tag; poolSize = file.readUnsignedShort(); pool = new Constant[poolSize]; // pool[0] is unused by the compiler and may be used freely by the implementation for (int i = 1; i < poolSize; i++) { pool[i] = Constant.readConstant(file); tag = pool[i].getTag(); if ((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) { i++; } } } public Constant getConstant(int index, byte tag) { Constant c = getConstant(index); // if (c == null) throw new ClassFormatException("Constant pool at index " + index + " is null."); if (c.tag == tag) return c; throw new ClassFormatException("Expected class '" + Constants.CONSTANT_NAMES[tag] + "' at index " + index + " and found " + c); } public Constant getConstant(int index) { try { return pool[index]; } catch (ArrayIndexOutOfBoundsException aioobe) { throw new ClassFormatException("Index " + index + " into constant pool (size:" + poolSize + ") is invalid"); } }
Returns:deep copy of this constant pool
/** * @return deep copy of this constant pool */
public ConstantPool copy() { Constant[] newConstants = new Constant[poolSize]; // use the correct size for (int i = 1; i < poolSize; i++) { if (pool[i] != null) { newConstants[i] = pool[i].copy(); } } return new ConstantPool(newConstants); }
Get string from constant pool and bypass the indirection of `ConstantClass' and `ConstantString' objects. I.e. these classes have an index field that points to another entry of the constant pool of type `ConstantUtf8' which contains the real data.
Params:
  • index – Index in constant pool
  • tag – Tag of expected constant, either ConstantClass or ConstantString
Throws:
See Also:
Returns:Contents of string reference
/** * Get string from constant pool and bypass the indirection of `ConstantClass' and `ConstantString' objects. I.e. these classes * have an index field that points to another entry of the constant pool of type `ConstantUtf8' which contains the real data. * * @param index Index in constant pool * @param tag Tag of expected constant, either ConstantClass or ConstantString * @return Contents of string reference * @see ConstantClass * @see ConstantString * @throws ClassFormatException */
public String getConstantString(int index, byte tag) throws ClassFormatException { Constant c = getConstant(index, tag); int i; /* * This switch() is not that elegant, since the two classes have the same contents, they just differ in the name of the * index field variable. But we want to stick to the JVM naming conventions closely though we could have solved these more * elegantly by using the same variable name or by subclassing. */ // OPTIMIZE remove the difference - use the an interface and same index methods for string ref id switch (tag) { case Constants.CONSTANT_Class: i = ((ConstantClass) c).getNameIndex(); break; case Constants.CONSTANT_String: i = ((ConstantString) c).getStringIndex(); break; default: throw new RuntimeException("getConstantString called with illegal tag " + tag); } // Finally get the string from the constant pool c = getConstant(i, Constants.CONSTANT_Utf8); return ((ConstantUtf8) c).getValue(); }
Resolve constant to a string representation.
/** * Resolve constant to a string representation. */
public String constantToString(Constant c) { String str; int i; switch (c.tag) { case Constants.CONSTANT_Class: i = ((ConstantClass) c).getNameIndex(); c = getConstant(i, Constants.CONSTANT_Utf8); str = Utility.compactClassName(((ConstantUtf8) c).getValue(), false); break; case Constants.CONSTANT_String: i = ((ConstantString) c).getStringIndex(); c = getConstant(i, Constants.CONSTANT_Utf8); str = "\"" + escape(((ConstantUtf8) c).getValue()) + "\""; break; case Constants.CONSTANT_Utf8: case Constants.CONSTANT_Double: case Constants.CONSTANT_Float: case Constants.CONSTANT_Long: case Constants.CONSTANT_Integer: str = ((SimpleConstant) c).getStringValue(); break; case Constants.CONSTANT_NameAndType: str = (constantToString(((ConstantNameAndType) c).getNameIndex(), Constants.CONSTANT_Utf8) + " " + constantToString( ((ConstantNameAndType) c).getSignatureIndex(), Constants.CONSTANT_Utf8)); break; case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref: case Constants.CONSTANT_Fieldref: str = (constantToString(((ConstantCP) c).getClassIndex(), Constants.CONSTANT_Class) + "." + constantToString( ((ConstantCP) c).getNameAndTypeIndex(), Constants.CONSTANT_NameAndType)); break; case Constants.CONSTANT_InvokeDynamic: ConstantInvokeDynamic cID = ((ConstantInvokeDynamic)c); return "#"+cID.getBootstrapMethodAttrIndex()+"."+constantToString(cID.getNameAndTypeIndex(), Constants.CONSTANT_NameAndType); case Constants.CONSTANT_MethodHandle: ConstantMethodHandle cMH = ((ConstantMethodHandle)c); return cMH.getReferenceKind()+":"+constantToString(cMH.getReferenceIndex(),Constants.CONSTANT_Methodref); case Constants.CONSTANT_MethodType: ConstantMethodType cMT = (ConstantMethodType)c; return constantToString(cMT.getDescriptorIndex(),Constants.CONSTANT_Utf8); case Constants.CONSTANT_Module: ConstantModule cM = (ConstantModule)c; return "Module:"+constantToString(cM.getNameIndex(),Constants.CONSTANT_Utf8); case Constants.CONSTANT_Package: ConstantPackage cP = (ConstantPackage)c; return "Package:"+constantToString(cP.getNameIndex(),Constants.CONSTANT_Utf8); default: // Never reached throw new RuntimeException("Unknown constant type " + c.tag); } return str; } private static final String escape(String str) { int len = str.length(); StringBuffer buf = new StringBuffer(len + 5); char[] ch = str.toCharArray(); for (int i = 0; i < len; i++) { switch (ch[i]) { case '\n': buf.append("\\n"); break; case '\r': buf.append("\\r"); break; case '\t': buf.append("\\t"); break; case '\b': buf.append("\\b"); break; case '"': buf.append("\\\""); break; default: buf.append(ch[i]); } } return buf.toString(); } public String constantToString(int index, byte tag) { Constant c = getConstant(index, tag); return constantToString(c); } public String constantToString(int index) { return constantToString(getConstant(index)); } @Override public void accept(ClassVisitor v) { v.visitConstantPool(this); } public Constant[] getConstantPool() { return pool; } // TEMPORARY, DONT LIKE PASSING THIS DATA OUT! public void dump(DataOutputStream file) throws IOException { file.writeShort(poolSize); for (int i = 1; i < poolSize; i++) if (pool[i] != null) pool[i].dump(file); } public ConstantUtf8 getConstantUtf8(int index) { Constant c = getConstant(index); assert c != null; assert c.tag == Constants.CONSTANT_Utf8; return (ConstantUtf8) c; } public ConstantModule getConstantModule(int index) { Constant c = getConstant(index); assert c != null; assert c.tag == Constants.CONSTANT_Module; return (ConstantModule)c; } public ConstantPackage getConstantPackage(int index) { Constant c = getConstant(index); assert c != null; assert c.tag == Constants.CONSTANT_Package; return (ConstantPackage)c; } public String getConstantString_CONSTANTClass(int index) { ConstantClass c = (ConstantClass) getConstant(index, Constants.CONSTANT_Class); index = c.getNameIndex(); return ((ConstantUtf8) getConstant(index, Constants.CONSTANT_Utf8)).getValue(); } public int getLength() { return poolSize; } @Override public String toString() { StringBuffer buf = new StringBuffer(); for (int i = 1; i < poolSize; i++) buf.append(i + ")" + pool[i] + "\n"); return buf.toString(); } public int lookupInteger(int n) { for (int i = 1; i < poolSize; i++) { if (pool[i] instanceof ConstantInteger) { ConstantInteger c = (ConstantInteger) pool[i]; if (c.getValue() == n) return i; } } return -1; } public int lookupUtf8(String string) { Integer pos = utf8Cache.get(string); if (pos != null) { return pos; } for (int i = 1; i < poolSize; i++) { Constant c = pool[i]; if (c != null && c.tag == Constants.CONSTANT_Utf8) { if (((ConstantUtf8) c).getValue().equals(string)) { utf8Cache.put(string, i); return i; } } } return -1; } public int lookupClass(String classname) { for (int i = 1; i < poolSize; i++) { Constant c = pool[i]; if (c != null && c.tag == Constants.CONSTANT_Class) { int cIndex = ((ConstantClass) c).getNameIndex(); String cName = ((ConstantUtf8) pool[cIndex]).getValue(); if (cName.equals(classname)) return i; } } return -1; } public int addUtf8(String n) { int ret = lookupUtf8(n); if (ret != -1) return ret; adjustSize(); ret = poolSize; pool[poolSize++] = new ConstantUtf8(n); return ret; } public int addInteger(int n) { int ret = lookupInteger(n); if (ret != -1) return ret; adjustSize(); ret = poolSize; pool[poolSize++] = new ConstantInteger(n); return ret; } public int addArrayClass(ArrayType type) { return addClass(type.getSignature()); } public int addClass(ObjectType type) { return addClass(type.getClassName()); } public int addClass(String classname) { String toAdd = classname.replace('.', '/'); int ret = lookupClass(toAdd); if (ret != -1) return ret; adjustSize(); ConstantClass c = new ConstantClass(addUtf8(toAdd)); ret = poolSize; pool[poolSize++] = c; return ret; } private void adjustSize() { if (poolSize + 3 >= pool.length) { Constant[] cs = pool; pool = new Constant[cs.length + 8]; System.arraycopy(cs, 0, pool, 0, cs.length); } if (poolSize == 0) poolSize = 1; // someone about to do something in here! } public int addFieldref(String class_name, String field_name, String signature) { int ret = lookupFieldref(class_name, field_name, signature); int class_index, name_and_type_index; if (ret != -1) return ret; adjustSize(); class_index = addClass(class_name); name_and_type_index = addNameAndType(field_name, signature); ret = poolSize; pool[poolSize++] = new ConstantFieldref(class_index, name_and_type_index); return ret; } public int lookupFieldref(String searchClassname, String searchFieldname, String searchSignature) { searchClassname = searchClassname.replace('.', '/'); String k = new StringBuffer().append(searchClassname).append(searchFieldname).append(searchSignature).toString(); Integer pos = fieldCache.get(k); if (pos != null) return pos.intValue(); for (int i = 1; i < poolSize; i++) { Constant c = pool[i]; if (c != null && c.tag == Constants.CONSTANT_Fieldref) { ConstantFieldref cfr = (ConstantFieldref) c; ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()]; // check the class int cIndex = cfr.getClassIndex(); ConstantClass cc = (ConstantClass) pool[cIndex]; String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue(); if (!cName.equals(searchClassname)) continue; // check the name and type String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); if (!name.equals(searchFieldname)) continue; // not this one String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); if (!typeSignature.equals(searchSignature)) continue; fieldCache.put(k, new Integer(i)); return i; } } return -1; } public int addNameAndType(String name, String signature) { int ret = lookupNameAndType(name, signature); if (ret != -1) return ret; adjustSize(); int name_index = addUtf8(name); int signature_index = addUtf8(signature); ret = poolSize; pool[poolSize++] = new ConstantNameAndType(name_index, signature_index); return ret; } public int lookupNameAndType(String searchName, String searchTypeSignature) { for (int i = 1; i < poolSize; i++) { Constant c = pool[i]; if (c != null && c.tag == Constants.CONSTANT_NameAndType) { ConstantNameAndType cnat = (ConstantNameAndType) c; String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); if (!name.equals(searchName)) continue; // not this one String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); if (!typeSignature.equals(searchTypeSignature)) continue; return i; } } return -1; } public int addFloat(float f) { int ret = lookupFloat(f); if (ret != -1) return ret; adjustSize(); ret = poolSize; pool[poolSize++] = new ConstantFloat(f); return ret; } public int lookupFloat(float f) { int bits = Float.floatToIntBits(f); for (int i = 1; i < poolSize; i++) { Constant c = pool[i]; if (c != null && c.tag == Constants.CONSTANT_Float) { ConstantFloat cf = (ConstantFloat) c; if (Float.floatToIntBits(cf.getValue()) == bits) return i; } } return -1; } public int addDouble(double d) { int ret = lookupDouble(d); if (ret != -1) return ret; adjustSize(); ret = poolSize; pool[poolSize] = new ConstantDouble(d); poolSize += 2; return ret; } public int lookupDouble(double d) { long bits = Double.doubleToLongBits(d); for (int i = 1; i < poolSize; i++) { Constant c = pool[i]; if (c != null && c.tag == Constants.CONSTANT_Double) { ConstantDouble cf = (ConstantDouble) c; if (Double.doubleToLongBits(cf.getValue()) == bits) return i; } } return -1; } public int addLong(long l) { int ret = lookupLong(l); if (ret != -1) return ret; adjustSize(); ret = poolSize; pool[poolSize] = new ConstantLong(l); poolSize += 2; return ret; } public int lookupString(String s) { for (int i = 1; i < poolSize; i++) { Constant c = pool[i]; if (c != null && c.tag == Constants.CONSTANT_String) { ConstantString cs = (ConstantString) c; ConstantUtf8 cu8 = (ConstantUtf8) pool[cs.getStringIndex()]; if (cu8.getValue().equals(s)) return i; } } return -1; } public int addString(String str) { int ret = lookupString(str); if (ret != -1) return ret; int utf8 = addUtf8(str); adjustSize(); ConstantString s = new ConstantString(utf8); ret = poolSize; pool[poolSize++] = s; return ret; } public int lookupLong(long l) { for (int i = 1; i < poolSize; i++) { Constant c = pool[i]; if (c != null && c.tag == Constants.CONSTANT_Long) { ConstantLong cf = (ConstantLong) c; if (cf.getValue() == l) return i; } } return -1; } public int addConstant(Constant c, ConstantPool cp) { Constant[] constants = cp.getConstantPool(); switch (c.getTag()) { case Constants.CONSTANT_String: { ConstantString s = (ConstantString) c; ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; return addString(u8.getValue()); } case Constants.CONSTANT_Class: { ConstantClass s = (ConstantClass) c; ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; return addClass(u8.getValue()); } case Constants.CONSTANT_NameAndType: { ConstantNameAndType n = (ConstantNameAndType) c; ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; return addNameAndType(u8.getValue(), u8_2.getValue()); } case Constants.CONSTANT_InvokeDynamic: { ConstantInvokeDynamic cid = (ConstantInvokeDynamic)c; int index1 = cid.getBootstrapMethodAttrIndex(); ConstantNameAndType cnat = (ConstantNameAndType)constants[cid.getNameAndTypeIndex()]; ConstantUtf8 name = (ConstantUtf8) constants[cnat.getNameIndex()]; ConstantUtf8 signature = (ConstantUtf8) constants[cnat.getSignatureIndex()]; int index2 = addNameAndType(name.getValue(), signature.getValue()); return addInvokeDynamic(index1,index2); } case Constants.CONSTANT_MethodHandle: ConstantMethodHandle cmh = (ConstantMethodHandle)c; return addMethodHandle(cmh.getReferenceKind(),addConstant(constants[cmh.getReferenceIndex()],cp)); case Constants.CONSTANT_Utf8: return addUtf8(((ConstantUtf8) c).getValue()); case Constants.CONSTANT_Double: return addDouble(((ConstantDouble) c).getValue()); case Constants.CONSTANT_Float: return addFloat(((ConstantFloat) c).getValue()); case Constants.CONSTANT_Long: return addLong(((ConstantLong) c).getValue()); case Constants.CONSTANT_Integer: return addInteger(((ConstantInteger) c).getValue()); case Constants.CONSTANT_MethodType: ConstantMethodType cmt = (ConstantMethodType)c; return addMethodType(addConstant(constants[cmt.getDescriptorIndex()],cp)); 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.getValue().replace('/', '.'); u8 = (ConstantUtf8) constants[n.getNameIndex()]; String name = u8.getValue(); u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; String signature = u8.getValue(); switch (c.getTag()) { case Constants.CONSTANT_InterfaceMethodref: return addInterfaceMethodref(class_name, name, signature); case Constants.CONSTANT_Methodref: return addMethodref(class_name, name, signature); // OPTIMIZE indicate it should be cached! 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 int addMethodHandle(byte referenceKind, int referenceIndex) { adjustSize(); int ret = poolSize; pool[poolSize++] = new ConstantMethodHandle(referenceKind, referenceIndex); return ret; } public int addMethodType(int descriptorIndex) { adjustSize(); int ret = poolSize; pool[poolSize++] = new ConstantMethodType(descriptorIndex); return ret; } // OPTIMIZE should put it in the cache now 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 = poolSize; pool[poolSize++] = new ConstantMethodref(class_index, name_and_type_index); return ret; } public int addInvokeDynamic(int bootstrapMethodIndex, int constantNameAndTypeIndex) { adjustSize(); int ret = poolSize; pool[poolSize++] = new ConstantInvokeDynamic(bootstrapMethodIndex, constantNameAndTypeIndex); return ret; } public int addInterfaceMethodref(String class_name, String method_name, String signature) { int ret = lookupInterfaceMethodref(class_name, method_name, signature); int class_index, name_and_type_index; if (ret != -1) return ret; adjustSize(); class_index = addClass(class_name); name_and_type_index = addNameAndType(method_name, signature); ret = poolSize; pool[poolSize++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); return ret; } public int lookupInterfaceMethodref(String searchClassname, String searchMethodName, String searchSignature) { searchClassname = searchClassname.replace('.', '/'); for (int i = 1; i < poolSize; i++) { Constant c = pool[i]; if (c != null && c.tag == Constants.CONSTANT_InterfaceMethodref) { ConstantInterfaceMethodref cfr = (ConstantInterfaceMethodref) c; ConstantClass cc = (ConstantClass) pool[cfr.getClassIndex()]; String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue(); if (!cName.equals(searchClassname)) continue; // check the name and type ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()]; String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); if (!name.equals(searchMethodName)) continue; // not this one String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); if (!typeSignature.equals(searchSignature)) continue; return i; } } return -1; } public int lookupMethodref(String searchClassname, String searchMethodName, String searchSignature) { String key = new StringBuffer().append(searchClassname).append(searchMethodName).append(searchSignature).toString(); Integer cached = methodCache.get(key); if (cached != null) return cached.intValue(); searchClassname = searchClassname.replace('.', '/'); for (int i = 1; i < poolSize; i++) { Constant c = pool[i]; if (c != null && c.tag == Constants.CONSTANT_Methodref) { ConstantMethodref cfr = (ConstantMethodref) c; ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()]; // check the class int cIndex = cfr.getClassIndex(); ConstantClass cc = (ConstantClass) pool[cIndex]; String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getValue(); if (!cName.equals(searchClassname)) continue; // check the name and type String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getValue(); if (!name.equals(searchMethodName)) continue; // not this one String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getValue(); if (!typeSignature.equals(searchSignature)) continue; methodCache.put(key, new Integer(i)); return i; } } return -1; } public ConstantPool getFinalConstantPool() { Constant[] cs = new Constant[poolSize]; // create it the exact size we need System.arraycopy(pool, 0, cs, 0, poolSize); return new ConstantPool(cs); } public String getModuleName(int moduleIndex) { return getConstantModule(moduleIndex).getModuleName(this); } public String getPackageName(int packageIndex) { return getConstantPackage(packageIndex).getPackageName(this); } }