📄 constantpoolgen.java
字号:
package de.fub.bytecode.generic;import de.fub.bytecode.Constants;import de.fub.bytecode.classfile.*;import java.util.Hashtable;/** * 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.6 2001/05/15 11:20:06 dahm Exp $ * @author <A HREF="http://www.berlin.de/~markus.dahm/">M. Dahm</A> * @see Constant */public class ConstantPoolGen { 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 { 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 Hashtable string_table = new Hashtable(); /** * 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 adjustSize(); ConstantUtf8 u8 = new ConstantUtf8(str); ConstantString s = new ConstantString(index); constants[index++] = u8; ret = index; constants[index++] = s; string_table.put(str, new Index(ret)); return ret; } private Hashtable class_table = new Hashtable(); /** * 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) { for(int i=1; i < index; i++) { if(constants[i] instanceof ConstantFloat) { ConstantFloat c = (ConstantFloat)constants[i]; if(c.getBytes() == n) 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 Hashtable utf8_table = new Hashtable(); /** * 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -