CLConstantPool.java |
1 // Copyright 2012- Bill Campbell, Swami Iyer and Bahar Akbal-Delibas 2 3 package jminusminus; 4 5 import java.io.IOException; 6 import java.util.ArrayList; 7 8 /** 9 * Representation of a class' constant pool. 10 */ 11 class CLConstantPool { 12 // Index of the next item into the constant pool. 13 private int cpIndex; 14 15 // List of constant pool items. 16 private ArrayList<CLCPInfo> cpItems; 17 18 /** 19 * Constructs an empty constant pool. 20 */ 21 public CLConstantPool() { 22 cpIndex = 1; 23 cpItems = new ArrayList<CLCPInfo>(); 24 } 25 26 /** 27 * Returns the size of the constant pool. 28 * 29 * @return the size of the constant pool. 30 */ 31 public int size() { 32 return cpItems.size(); 33 } 34 35 /** 36 * Returns the index of the specified item in the constant pool or -1. 37 * 38 * @param cpInfo item to find. 39 * @return the index of the specified item in the constant pool or -1. 40 */ 41 public int find(CLCPInfo cpInfo) { 42 int index = cpItems.indexOf(cpInfo); 43 return (index != -1) ? cpItems.get(index).cpIndex : index; 44 } 45 46 /** 47 * Returns the constant pool item at the specified index or null. 48 * 49 * @param i constant pool index. 50 * @return the constant pool item at the specified index or null. 51 */ 52 public CLCPInfo cpItem(int i) { 53 if (((i - 1) < 0) || ((i - 1) >= cpItems.size())) { 54 return null; 55 } 56 return cpItems.get(i - 1); 57 } 58 59 /** 60 * Adds the specified (non-null) item to the constant pool and returns its index. 61 * 62 * @param cpInfo the item to add. 63 * @return constant pool index of the item. 64 */ 65 public int addCPItem(CLCPInfo cpInfo) { 66 cpInfo.cpIndex = cpIndex++; 67 cpItems.add(cpInfo); 68 69 // long and double, with their lower and higher words, are treated by JVM as two items in 70 // the constant pool. We have a single representation for each, so we add a null as 71 // a placeholder in the second slot. 72 if ((cpInfo instanceof CLConstantLongInfo) || (cpInfo instanceof CLConstantDoubleInfo)) { 73 cpIndex++; 74 cpItems.add(null); 75 } 76 return cpInfo.cpIndex; 77 } 78 79 /** 80 * Writes the contents of the constant pool to the specified output stream. 81 * 82 * @param out output stream. 83 * @throws IOException if an error occurs while writing. 84 */ 85 public void write(CLOutputStream out) throws IOException { 86 for (CLCPInfo cpInfo : cpItems) { 87 if (cpInfo != null) { 88 cpInfo.write(out); 89 } 90 } 91 } 92 93 /** 94 * Returns the constant pool index of a singleton instance of CLConstantClassInfo. 95 * 96 * @param className class or interface name in internal form. 97 * @return constant pool index. 98 */ 99 public int constantClassInfo(String className) { 100 CLCPInfo c = new CLConstantClassInfo(constantUtf8Info(className)); 101 return findOrAdd(c); 102 } 103 104 /** 105 * Returns the constant pool index of a singleton instance of CLConstantFieldRefInfo. 106 * 107 * @param className class or interface name in internal form. 108 * @param name name of the field. 109 * @param type descriptor of the field. 110 * @return constant pool index. 111 */ 112 public int constantFieldRefInfo(String className, String name, String type) { 113 CLCPInfo c = new CLConstantFieldRefInfo(constantClassInfo(className), 114 constantNameAndTypeInfo(name, type)); 115 return findOrAdd(c); 116 } 117 118 /** 119 * Returns the constant pool index of a singleton instance of CLConstantMethodRefInfo. 120 * 121 * @param className class or interface name in internal form. 122 * @param name name of the method. 123 * @param type descriptor of the method. 124 * @return constant pool index. 125 */ 126 public int constantMethodRefInfo(String className, String name, String type) { 127 CLCPInfo c = new CLConstantMethodRefInfo(constantClassInfo(className), 128 constantNameAndTypeInfo(name, type)); 129 return findOrAdd(c); 130 } 131 132 /** 133 * Returns the constant pool index of a singleton instance of CLConstantInterfaceMethodRefInfo. 134 * 135 * @param className class or interface name in internal form. 136 * @param name name of the method. 137 * @param type descriptor of the method. 138 * @return constant pool index. 139 */ 140 public int constantInterfaceMethodRefInfo(String className, String name, String type) { 141 CLCPInfo c = new CLConstantInterfaceMethodRefInfo( 142 constantClassInfo(className), constantNameAndTypeInfo(name, type)); 143 return findOrAdd(c); 144 } 145 146 /** 147 * Returns the constant pool index of a singleton instance of CLConstantStringInfo. 148 * 149 * @param s the constant string value. 150 * @return constant pool index. 151 */ 152 public int constantStringInfo(String s) { 153 CLCPInfo c = new CLConstantStringInfo(constantUtf8Info(s)); 154 return findOrAdd(c); 155 } 156 157 /** 158 * Returns the constant pool index of a singleton instance of CLConstantIntegerInfo. 159 * 160 * @param i the constant int value. 161 * @return constant pool index. 162 */ 163 public int constantIntegerInfo(int i) { 164 CLCPInfo c = new CLConstantIntegerInfo(i); 165 return findOrAdd(c); 166 } 167 168 /** 169 * Returns the constant pool index of a singleton instance of CLConstantFloatInfo. 170 * 171 * @param f the constant floating-point value. 172 * @return constant pool index. 173 */ 174 public int constantFloatInfo(float f) { 175 CLCPInfo c = new CLConstantFloatInfo(f); 176 return findOrAdd(c); 177 } 178 179 /** 180 * Returns the constant pool index of a singleton instance of CLConstantLongInfo. 181 * 182 * @param l the constant long value. 183 * @return constant pool index. 184 */ 185 public int constantLongInfo(long l) { 186 CLCPInfo c = new CLConstantLongInfo(l); 187 return findOrAdd(c); 188 } 189 190 /** 191 * Returns the constant pool index of a singleton instance of CLConstantDoubleInfo. 192 * 193 * @param d the constant double value. 194 * @return constant pool index. 195 */ 196 public int constantDoubleInfo(double d) { 197 CLCPInfo c = new CLConstantDoubleInfo(d); 198 return findOrAdd(c); 199 } 200 201 /** 202 * Returns the constant pool index of a singleton instance of CLConstantNameAndTypeInfo. 203 * 204 * @param name field or method name. 205 * @param type field or method type descriptor. 206 * @return constant pool index. 207 */ 208 public int constantNameAndTypeInfo(String name, String type) { 209 CLCPInfo c = new CLConstantNameAndTypeInfo(constantUtf8Info(name), constantUtf8Info(type)); 210 return findOrAdd(c); 211 } 212 213 /** 214 * Returns the constant pool index of a singleton instance of CLConstantUtf8Info. 215 * 216 * @param s the constant string value. 217 * @return constant pool index. 218 */ 219 public int constantUtf8Info(String s) { 220 CLCPInfo c = new CLConstantUtf8Info(s.getBytes()); 221 return findOrAdd(c); 222 } 223 224 // Returns the index of the specified item in the constant pool. If the item does not exist, 225 // adds the item to the pool and return its (new) index. 226 private int findOrAdd(CLCPInfo cpInfo) { 227 int index = find(cpInfo); 228 if (index == -1) { 229 index = addCPItem(cpInfo); 230 } 231 return index; 232 } 233 } 234