1 4 package gnu.bytecode; 5 6 9 10 public class ConstantPool 11 { 12 static public final byte CLASS = 7; 13 static public final byte FIELDREF = 9; 14 static public final byte METHODREF = 10; 15 static public final byte INTERFACE_METHODREF = 11; 16 static public final byte STRING = 8; 17 static public final byte INTEGER = 3; 18 static public final byte FLOAT = 4; 19 static public final byte LONG = 5; 20 static public final byte DOUBLE = 6; 21 static public final byte NAME_AND_TYPE = 12; 22 static public final byte UTF8 = 1; 23 24 26 CpoolEntry[] pool; 27 28 30 int count; 31 32 public final int getCount() 33 { 34 return count; 35 } 36 37 41 public final CpoolEntry getPoolEntry(int index) 42 { 43 return pool[index]; 44 } 45 46 boolean locked; 47 48 CpoolEntry[] hashTab; 49 50 void rehash () 51 { 52 if (hashTab == null && count > 0) 53 { 54 for (int i = pool.length; --i >= 0; ) 56 { 57 CpoolEntry entry = pool[i]; 58 if (entry != null) 60 entry.hashCode(); 61 } 62 } 63 64 hashTab = new CpoolEntry[count < 5 ? 101 : 2 * count]; 65 if (pool != null) 66 { 67 for (int i = pool.length; --i >= 0; ) 68 { 69 CpoolEntry entry = pool[i]; 70 if (entry != null) 71 entry.add_hashed (this); 72 } 73 } 74 } 75 76 public CpoolUtf8 addUtf8 (String s) 77 { 78 s = s.intern(); 79 int h = s.hashCode(); 80 81 if (hashTab == null) 83 rehash(); 84 85 int index = (h & 0x7FFFFFFF) % hashTab.length; 86 for (CpoolEntry entry = hashTab[index]; entry != null; entry = entry.next) 87 { 88 if (h == entry.hash && entry instanceof CpoolUtf8) 89 { 90 CpoolUtf8 utf = (CpoolUtf8) entry; 91 if (utf.string == s) 92 return utf; 93 } 94 } 95 if (locked) 96 throw new Error ("adding new Utf8 entry to locked contant pool: "+s); 97 return new CpoolUtf8(this, h, s); 98 } 99 100 public CpoolClass addClass (ObjectType otype) 101 { 102 return addClass(addUtf8(otype.getInternalName())); 103 } 104 105 public CpoolClass addClass (String name) 106 { 107 return addClass(addUtf8(name.replace('.', '/'))); 108 } 109 110 public CpoolClass addClass (CpoolUtf8 name) 111 { 112 int h = CpoolClass.hashCode(name); 113 114 if (hashTab == null) 116 rehash(); 117 int index = (h & 0x7FFFFFFF) % hashTab.length; 118 for (CpoolEntry entry = hashTab[index]; entry != null; entry = entry.next) 119 { 120 if (h == entry.hash && entry instanceof CpoolClass) 121 { 122 CpoolClass ent = (CpoolClass) entry; 123 if (ent.name == name) 124 return ent; 125 } 126 } 127 return new CpoolClass (this, h, name); 128 } 129 130 CpoolValue1 addValue1 (int tag, int val) 131 { 132 int h = CpoolValue1.hashCode(val); 133 134 if (hashTab == null) 136 rehash(); 137 int index = (h & 0x7FFFFFFF) % hashTab.length; 138 for (CpoolEntry entry = hashTab[index]; entry != null; entry = entry.next) 139 { 140 if (h == entry.hash && entry instanceof CpoolValue1) 141 { 142 CpoolValue1 ent = (CpoolValue1) entry; 143 if (ent.tag == tag && ent.value == val) 144 return ent; 145 } 146 } 147 return new CpoolValue1 (this, tag, h, val); 148 } 149 150 CpoolValue2 addValue2 (int tag, long val) 151 { 152 int h = CpoolValue2.hashCode(val); 153 154 if (hashTab == null) 156 rehash(); 157 int index = (h & 0x7FFFFFFF) % hashTab.length; 158 for (CpoolEntry entry = hashTab[index]; entry != null; entry = entry.next) 159 { 160 if (h == entry.hash && entry instanceof CpoolValue2) 161 { 162 CpoolValue2 ent = (CpoolValue2) entry; 163 if (ent.tag == tag && ent.value == val) 164 return ent; 165 } 166 } 167 return new CpoolValue2 (this, tag, h, val); 168 } 169 170 public CpoolValue1 addInt (int val) 171 { 172 return addValue1(INTEGER, val); 173 } 174 175 public CpoolValue2 addLong (long val) 176 { 177 return addValue2(LONG, val); 178 } 179 180 public CpoolValue1 addFloat (float val) 181 { 182 return addValue1(FLOAT, Float.floatToIntBits(val)); 183 } 184 185 public CpoolValue2 addDouble (double val) 186 { 187 return addValue2(DOUBLE, Double.doubleToLongBits(val)); 188 } 189 190 public final CpoolString addString (String string) 191 { 192 return addString(addUtf8(string)); 193 } 194 195 public CpoolString addString (CpoolUtf8 str) 196 { 197 int h = CpoolString.hashCode (str); 198 199 if (hashTab == null) 201 rehash(); 202 int index = (h & 0x7FFFFFFF) % hashTab.length; 203 for (CpoolEntry entry = hashTab[index]; entry != null; entry = entry.next) 204 { 205 if (h == entry.hash && entry instanceof CpoolString) 206 { 207 CpoolString ent = (CpoolString) entry; 208 if (ent.str == str) 209 return ent; 210 } 211 } 212 return new CpoolString (this, h, str); 213 } 214 215 public CpoolNameAndType addNameAndType (Method method) 216 { 217 CpoolUtf8 name = addUtf8(method.getName()); 218 CpoolUtf8 type = addUtf8(method.getSignature ()); 219 return addNameAndType(name, type); 220 } 221 222 public CpoolNameAndType addNameAndType (Field field) 223 { 224 CpoolUtf8 name = addUtf8(field.getName()); 225 CpoolUtf8 type = addUtf8(field.getSignature ()); 226 return addNameAndType(name, type); 227 } 228 229 public CpoolNameAndType 230 addNameAndType (CpoolUtf8 name, CpoolUtf8 type) 231 { 232 int h = CpoolNameAndType.hashCode (name, type); 233 234 if (hashTab == null) 236 rehash(); 237 int index = (h & 0x7FFFFFFF) % hashTab.length; 238 for (CpoolEntry entry = hashTab[index]; entry != null; entry = entry.next) 239 { 240 if (h == entry.hash 241 && entry instanceof CpoolNameAndType 242 && ((CpoolNameAndType)entry).name == name 243 && ((CpoolNameAndType)entry).type == type) 244 return (CpoolNameAndType)entry; 245 } 246 return new CpoolNameAndType(this, h, name, type); 247 } 248 249 public CpoolRef 250 addRef (int tag, CpoolClass clas, CpoolNameAndType nameAndType) 251 { 252 int h = CpoolRef.hashCode (clas, nameAndType); 253 254 if (hashTab == null) 256 rehash(); 257 int index = (h & 0x7FFFFFFF) % hashTab.length; 258 for (CpoolEntry entry = hashTab[index]; entry != null; entry = entry.next) 259 { 260 if (h == entry.hash && entry instanceof CpoolRef) 261 { 262 CpoolRef ref = (CpoolRef) entry; 263 if (ref.tag == tag 264 && ref.clas == clas 265 && ref.nameAndType== nameAndType) 266 return ref; 267 } 268 } 269 return new CpoolRef (this, h, tag, clas, nameAndType); 270 } 271 272 public CpoolRef addMethodRef (Method method) 273 { 274 CpoolClass clas = addClass(method.classfile.this_name); 275 int tag; 276 if ((method.getDeclaringClass().getModifiers() & Access.INTERFACE) == 0) 277 tag = 10; else 279 tag = 11; CpoolNameAndType nameType = addNameAndType(method); 281 return addRef(tag, clas, nameType); 282 } 283 284 public CpoolRef addFieldRef (Field field) 285 { 286 CpoolClass clas = addClass(field.owner.this_name); 287 int tag = 9; CpoolNameAndType nameType = addNameAndType(field); 289 return addRef(tag, clas, nameType); 290 } 291 292 void write (java.io.DataOutputStream dstr) throws java.io.IOException 293 { 294 dstr.writeShort(count+1); 295 for (int i = 1; i <= count; i++) 296 { 297 CpoolEntry entry = pool[i]; 298 if (entry != null) 299 entry.write (dstr); 300 } 301 locked = true; 302 } 303 304 308 CpoolEntry getForced(int index, int tag) 309 { 310 index = index & 0xffff; 311 CpoolEntry entry = pool[index]; 312 if (entry == null) 313 { 314 if (locked) 315 throw new Error ("adding new entry to locked contant pool"); 316 switch (tag) 317 { 318 case UTF8: entry = new CpoolUtf8(); break; 319 case INTEGER: 320 case FLOAT: entry = new CpoolValue1(tag); break; 321 case LONG: 322 case DOUBLE: entry = new CpoolValue2(tag); break; 323 case CLASS: entry = new CpoolClass(); break; 324 case STRING: entry = new CpoolString(); break; 325 case FIELDREF: 326 case METHODREF: 327 case INTERFACE_METHODREF: entry = new CpoolRef(tag); break; 328 case NAME_AND_TYPE: entry = new CpoolNameAndType(); 329 } 330 pool[index] = entry; 331 entry.index = index; 332 } 333 else if (entry.getTag() != tag) 334 throw new ClassFormatError ("conflicting constant pool tags at "+index); 335 return entry; 336 } 337 338 public ConstantPool () { } 339 340 public ConstantPool (java.io.DataInputStream dstr) 341 throws java.io.IOException 342 { 343 count = dstr.readUnsignedShort() - 1; 344 pool = new CpoolEntry[count+1]; 345 for (int i = 1; i <= count; i++) 346 { 347 byte tag = dstr.readByte(); 348 CpoolEntry entry = getForced(i, tag); 349 switch (tag) 350 { 351 case UTF8: 352 ((CpoolUtf8) entry).string = dstr.readUTF(); 353 break; 354 case INTEGER: 355 case FLOAT: 356 ((CpoolValue1) entry).value = dstr.readInt(); 357 break; 358 case LONG: 359 case DOUBLE: 360 ((CpoolValue2) entry).value = dstr.readLong(); 361 i++; 362 break; 363 case CLASS: 364 ((CpoolClass) entry).name = 365 (CpoolUtf8) getForced(dstr.readUnsignedShort(), UTF8); 366 break; 367 case STRING: 368 ((CpoolString) entry).str = 369 (CpoolUtf8) getForced(dstr.readUnsignedShort(), UTF8); 370 break; 371 case FIELDREF: 372 case METHODREF: 373 case INTERFACE_METHODREF: 374 CpoolRef ref = (CpoolRef) entry; 375 ref.clas = (CpoolClass) getForced(dstr.readUnsignedShort(), CLASS); 376 ref.nameAndType = (CpoolNameAndType) 377 getForced(dstr.readUnsignedShort(), NAME_AND_TYPE); 378 break; 379 case NAME_AND_TYPE: 380 CpoolNameAndType ntyp = (CpoolNameAndType) entry; 381 ntyp.name = (CpoolUtf8) getForced(dstr.readUnsignedShort(), UTF8); 382 ntyp.type = (CpoolUtf8) getForced(dstr.readUnsignedShort(), UTF8); 383 break; 384 } 385 } 386 } 387 } 388 | Popular Tags |