1 17 package org.apache.bcel.generic; 18 19 import java.util.HashMap ; 20 import java.util.Map ; 21 import org.apache.bcel.Constants; 22 import org.apache.bcel.classfile.Constant; 23 import org.apache.bcel.classfile.ConstantCP; 24 import org.apache.bcel.classfile.ConstantClass; 25 import org.apache.bcel.classfile.ConstantDouble; 26 import org.apache.bcel.classfile.ConstantFieldref; 27 import org.apache.bcel.classfile.ConstantFloat; 28 import org.apache.bcel.classfile.ConstantInteger; 29 import org.apache.bcel.classfile.ConstantInterfaceMethodref; 30 import org.apache.bcel.classfile.ConstantLong; 31 import org.apache.bcel.classfile.ConstantMethodref; 32 import org.apache.bcel.classfile.ConstantNameAndType; 33 import org.apache.bcel.classfile.ConstantPool; 34 import org.apache.bcel.classfile.ConstantString; 35 import org.apache.bcel.classfile.ConstantUtf8; 36 37 51 public class ConstantPoolGen implements java.io.Serializable { 52 53 protected int size = 1024; protected Constant[] constants = new Constant[size]; 55 protected int index = 1; private static final String METHODREF_DELIM = ":"; 57 private static final String IMETHODREF_DELIM = "#"; 58 private static final String FIELDREF_DELIM = "&"; 59 private static final String NAT_DELIM = "%"; 60 61 private static class Index implements java.io.Serializable { 62 63 int index; 64 65 66 Index(int i) { 67 index = i; 68 } 69 } 70 71 72 77 public ConstantPoolGen(Constant[] cs) { 78 if (cs.length > size) { 79 size = cs.length; 80 constants = new Constant[size]; 81 } 82 System.arraycopy(cs, 0, constants, 0, cs.length); 83 if (cs.length > 0) { 84 index = cs.length; 85 } 86 for (int i = 1; i < index; i++) { 87 Constant c = constants[i]; 88 if (c instanceof ConstantString) { 89 ConstantString s = (ConstantString) c; 90 ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; 91 String key = u8.getBytes(); 92 if (!string_table.containsKey(key)) { 93 string_table.put(key, new Index(i)); 94 } 95 } else if (c instanceof ConstantClass) { 96 ConstantClass s = (ConstantClass) c; 97 ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; 98 String key = u8.getBytes(); 99 if (!class_table.containsKey(key)) { 100 class_table.put(key, new Index(i)); 101 } 102 } else if (c instanceof ConstantNameAndType) { 103 ConstantNameAndType n = (ConstantNameAndType) c; 104 ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 105 ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; 106 String key = u8.getBytes() + NAT_DELIM + u8_2.getBytes(); 107 if (!n_a_t_table.containsKey(key)) { 108 n_a_t_table.put(key, new Index(i)); 109 } 110 } else if (c instanceof ConstantUtf8) { 111 ConstantUtf8 u = (ConstantUtf8) c; 112 String key = u.getBytes(); 113 if (!utf8_table.containsKey(key)) { 114 utf8_table.put(key, new Index(i)); 115 } 116 } else if (c instanceof ConstantCP) { 117 ConstantCP m = (ConstantCP) c; 118 ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; 119 ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; 120 ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; 121 String class_name = u8.getBytes().replace('/', '.'); 122 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 123 String method_name = u8.getBytes(); 124 u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; 125 String signature = u8.getBytes(); 126 String delim = METHODREF_DELIM; 127 if (c instanceof ConstantInterfaceMethodref) { 128 delim = IMETHODREF_DELIM; 129 } else if (c instanceof ConstantFieldref) { 130 delim = FIELDREF_DELIM; 131 } 132 String key = class_name + delim + method_name + delim + signature; 133 if (!cp_table.containsKey(key)) { 134 cp_table.put(key, new Index(i)); 135 } 136 } 137 } 138 } 139 140 141 144 public ConstantPoolGen(ConstantPool cp) { 145 this(cp.getConstantPool()); 146 } 147 148 149 152 public ConstantPoolGen() { 153 } 154 155 156 158 protected void adjustSize() { 159 if (index + 3 >= size) { 160 Constant[] cs = constants; 161 size *= 2; 162 constants = new Constant[size]; 163 System.arraycopy(cs, 0, constants, 0, index); 164 } 165 } 166 167 private Map string_table = new HashMap (); 168 169 170 176 public int lookupString( String str ) { 177 Index index = (Index) string_table.get(str); 178 return (index != null) ? index.index : -1; 179 } 180 181 182 188 public int addString( String str ) { 189 int ret; 190 if ((ret = lookupString(str)) != -1) { 191 return ret; } 193 int utf8 = addUtf8(str); 194 adjustSize(); 195 ConstantString s = new ConstantString(utf8); 196 ret = index; 197 constants[index++] = s; 198 if (!string_table.containsKey(str)) { 199 string_table.put(str, new Index(ret)); 200 } 201 return ret; 202 } 203 204 private Map class_table = new HashMap (); 205 206 207 213 public int lookupClass( String str ) { 214 Index index = (Index) class_table.get(str.replace('.', '/')); 215 return (index != null) ? index.index : -1; 216 } 217 218 219 private int addClass_( String clazz ) { 220 int ret; 221 if ((ret = lookupClass(clazz)) != -1) { 222 return ret; } 224 adjustSize(); 225 ConstantClass c = new ConstantClass(addUtf8(clazz)); 226 ret = index; 227 constants[index++] = c; 228 if (!class_table.containsKey(clazz)) { 229 class_table.put(clazz, new Index(ret)); 230 } 231 return ret; 232 } 233 234 235 241 public int addClass( String str ) { 242 return addClass_(str.replace('.', '/')); 243 } 244 245 246 252 public int addClass( ObjectType type ) { 253 return addClass(type.getClassName()); 254 } 255 256 257 264 public int addArrayClass( ArrayType type ) { 265 return addClass_(type.getSignature()); 266 } 267 268 269 275 public int lookupInteger( int n ) { 276 for (int i = 1; i < index; i++) { 277 if (constants[i] instanceof ConstantInteger) { 278 ConstantInteger c = (ConstantInteger) constants[i]; 279 if (c.getBytes() == n) { 280 return i; 281 } 282 } 283 } 284 return -1; 285 } 286 287 288 294 public int addInteger( int n ) { 295 int ret; 296 if ((ret = lookupInteger(n)) != -1) { 297 return ret; } 299 adjustSize(); 300 ret = index; 301 constants[index++] = new ConstantInteger(n); 302 return ret; 303 } 304 305 306 312 public int lookupFloat( float n ) { 313 int bits = Float.floatToIntBits(n); 314 for (int i = 1; i < index; i++) { 315 if (constants[i] instanceof ConstantFloat) { 316 ConstantFloat c = (ConstantFloat) constants[i]; 317 if (Float.floatToIntBits(c.getBytes()) == bits) { 318 return i; 319 } 320 } 321 } 322 return -1; 323 } 324 325 326 332 public int addFloat( float n ) { 333 int ret; 334 if ((ret = lookupFloat(n)) != -1) { 335 return ret; } 337 adjustSize(); 338 ret = index; 339 constants[index++] = new ConstantFloat(n); 340 return ret; 341 } 342 343 private Map utf8_table = new HashMap (); 344 345 346 352 public int lookupUtf8( String n ) { 353 Index index = (Index) utf8_table.get(n); 354 return (index != null) ? index.index : -1; 355 } 356 357 358 364 public int addUtf8( String n ) { 365 int ret; 366 if ((ret = lookupUtf8(n)) != -1) { 367 return ret; } 369 adjustSize(); 370 ret = index; 371 constants[index++] = new ConstantUtf8(n); 372 if (!utf8_table.containsKey(n)) { 373 utf8_table.put(n, new Index(ret)); 374 } 375 return ret; 376 } 377 378 379 385 public int lookupLong( long n ) { 386 for (int i = 1; i < index; i++) { 387 if (constants[i] instanceof ConstantLong) { 388 ConstantLong c = (ConstantLong) constants[i]; 389 if (c.getBytes() == n) { 390 return i; 391 } 392 } 393 } 394 return -1; 395 } 396 397 398 404 public int addLong( long n ) { 405 int ret; 406 if ((ret = lookupLong(n)) != -1) { 407 return ret; } 409 adjustSize(); 410 ret = index; 411 constants[index] = new ConstantLong(n); 412 index += 2; return ret; 414 } 415 416 417 423 public int lookupDouble( double n ) { 424 long bits = Double.doubleToLongBits(n); 425 for (int i = 1; i < index; i++) { 426 if (constants[i] instanceof ConstantDouble) { 427 ConstantDouble c = (ConstantDouble) constants[i]; 428 if (Double.doubleToLongBits(c.getBytes()) == bits) { 429 return i; 430 } 431 } 432 } 433 return -1; 434 } 435 436 437 443 public int addDouble( double n ) { 444 int ret; 445 if ((ret = lookupDouble(n)) != -1) { 446 return ret; } 448 adjustSize(); 449 ret = index; 450 constants[index] = new ConstantDouble(n); 451 index += 2; return ret; 453 } 454 455 private Map n_a_t_table = new HashMap (); 456 457 458 465 public int lookupNameAndType( String name, String signature ) { 466 Index _index = (Index) n_a_t_table.get(name + NAT_DELIM + signature); 467 return (_index != null) ? _index.index : -1; 468 } 469 470 471 479 public int addNameAndType( String name, String signature ) { 480 int ret; 481 int name_index, signature_index; 482 if ((ret = lookupNameAndType(name, signature)) != -1) { 483 return ret; } 485 adjustSize(); 486 name_index = addUtf8(name); 487 signature_index = addUtf8(signature); 488 ret = index; 489 constants[index++] = new ConstantNameAndType(name_index, signature_index); 490 String key = name + NAT_DELIM + signature; 491 if (!n_a_t_table.containsKey(key)) { 492 n_a_t_table.put(key, new Index(ret)); 493 } 494 return ret; 495 } 496 497 private Map cp_table = new HashMap (); 498 499 500 508 public int lookupMethodref( String class_name, String method_name, String signature ) { 509 Index index = (Index) cp_table.get(class_name + METHODREF_DELIM + method_name 510 + METHODREF_DELIM + signature); 511 return (index != null) ? index.index : -1; 512 } 513 514 515 public int lookupMethodref( MethodGen method ) { 516 return lookupMethodref(method.getClassName(), method.getName(), method.getSignature()); 517 } 518 519 520 529 public int addMethodref( String class_name, String method_name, String signature ) { 530 int ret, class_index, name_and_type_index; 531 if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) { 532 return ret; } 534 adjustSize(); 535 name_and_type_index = addNameAndType(method_name, signature); 536 class_index = addClass(class_name); 537 ret = index; 538 constants[index++] = new ConstantMethodref(class_index, name_and_type_index); 539 String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature; 540 if (!cp_table.containsKey(key)) { 541 cp_table.put(key, new Index(ret)); 542 } 543 return ret; 544 } 545 546 547 public int addMethodref( MethodGen method ) { 548 return addMethodref(method.getClassName(), method.getName(), method.getSignature()); 549 } 550 551 552 560 public int lookupInterfaceMethodref( String class_name, String method_name, String signature ) { 561 Index index = (Index) cp_table.get(class_name + IMETHODREF_DELIM + method_name 562 + IMETHODREF_DELIM + signature); 563 return (index != null) ? index.index : -1; 564 } 565 566 567 public int lookupInterfaceMethodref( MethodGen method ) { 568 return lookupInterfaceMethodref(method.getClassName(), method.getName(), method 569 .getSignature()); 570 } 571 572 573 582 public int addInterfaceMethodref( String class_name, String method_name, String signature ) { 583 int ret, class_index, name_and_type_index; 584 if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) { 585 return ret; } 587 adjustSize(); 588 class_index = addClass(class_name); 589 name_and_type_index = addNameAndType(method_name, signature); 590 ret = index; 591 constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); 592 String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature; 593 if (!cp_table.containsKey(key)) { 594 cp_table.put(key, new Index(ret)); 595 } 596 return ret; 597 } 598 599 600 public int addInterfaceMethodref( MethodGen method ) { 601 return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature()); 602 } 603 604 605 613 public int lookupFieldref( String class_name, String field_name, String signature ) { 614 Index index = (Index) cp_table.get(class_name + FIELDREF_DELIM + field_name 615 + FIELDREF_DELIM + signature); 616 return (index != null) ? index.index : -1; 617 } 618 619 620 629 public int addFieldref( String class_name, String field_name, String signature ) { 630 int ret; 631 int class_index, name_and_type_index; 632 if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) { 633 return ret; } 635 adjustSize(); 636 class_index = addClass(class_name); 637 name_and_type_index = addNameAndType(field_name, signature); 638 ret = index; 639 constants[index++] = new ConstantFieldref(class_index, name_and_type_index); 640 String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature; 641 if (!cp_table.containsKey(key)) { 642 cp_table.put(key, new Index(ret)); 643 } 644 return ret; 645 } 646 647 648 652 public Constant getConstant( int i ) { 653 return constants[i]; 654 } 655 656 657 663 public void setConstant( int i, Constant c ) { 664 constants[i] = c; 665 } 666 667 668 671 public ConstantPool getConstantPool() { 672 return new ConstantPool(constants); 673 } 674 675 676 679 public int getSize() { 680 return index; 681 } 682 683 684 687 public ConstantPool getFinalConstantPool() { 688 Constant[] cs = new Constant[index]; 689 System.arraycopy(constants, 0, cs, 0, index); 690 return new ConstantPool(cs); 691 } 692 693 694 697 public String toString() { 698 StringBuffer buf = new StringBuffer (); 699 for (int i = 1; i < index; i++) { 700 buf.append(i).append(")").append(constants[i]).append("\n"); 701 } 702 return buf.toString(); 703 } 704 705 706 708 public int addConstant( Constant c, ConstantPoolGen cp ) { 709 Constant[] constants = cp.getConstantPool().getConstantPool(); 710 switch (c.getTag()) { 711 case Constants.CONSTANT_String: { 712 ConstantString s = (ConstantString) c; 713 ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; 714 return addString(u8.getBytes()); 715 } 716 case Constants.CONSTANT_Class: { 717 ConstantClass s = (ConstantClass) c; 718 ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; 719 return addClass(u8.getBytes()); 720 } 721 case Constants.CONSTANT_NameAndType: { 722 ConstantNameAndType n = (ConstantNameAndType) c; 723 ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 724 ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; 725 return addNameAndType(u8.getBytes(), u8_2.getBytes()); 726 } 727 case Constants.CONSTANT_Utf8: 728 return addUtf8(((ConstantUtf8) c).getBytes()); 729 case Constants.CONSTANT_Double: 730 return addDouble(((ConstantDouble) c).getBytes()); 731 case Constants.CONSTANT_Float: 732 return addFloat(((ConstantFloat) c).getBytes()); 733 case Constants.CONSTANT_Long: 734 return addLong(((ConstantLong) c).getBytes()); 735 case Constants.CONSTANT_Integer: 736 return addInteger(((ConstantInteger) c).getBytes()); 737 case Constants.CONSTANT_InterfaceMethodref: 738 case Constants.CONSTANT_Methodref: 739 case Constants.CONSTANT_Fieldref: { 740 ConstantCP m = (ConstantCP) c; 741 ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; 742 ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; 743 ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; 744 String class_name = u8.getBytes().replace('/', '.'); 745 u8 = (ConstantUtf8) constants[n.getNameIndex()]; 746 String name = u8.getBytes(); 747 u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; 748 String signature = u8.getBytes(); 749 switch (c.getTag()) { 750 case Constants.CONSTANT_InterfaceMethodref: 751 return addInterfaceMethodref(class_name, name, signature); 752 case Constants.CONSTANT_Methodref: 753 return addMethodref(class_name, name, signature); 754 case Constants.CONSTANT_Fieldref: 755 return addFieldref(class_name, name, signature); 756 default: throw new RuntimeException ("Unknown constant type " + c); 758 } 759 } 760 default: throw new RuntimeException ("Unknown constant type " + c); 762 } 763 } 764 } 765 | Popular Tags |