1 package com.sun.org.apache.bcel.internal.generic; 2 3 56 57 import com.sun.org.apache.bcel.internal.Constants; 58 import com.sun.org.apache.bcel.internal.classfile.*; 59 import java.util.HashMap ; 60 61 75 public class ConstantPoolGen { 76 protected int size = 1024; protected Constant[] constants = new Constant[size]; 78 protected int index = 1; 80 private static final String METHODREF_DELIM = ":"; 81 private static final String IMETHODREF_DELIM = "#"; 82 private static final String FIELDREF_DELIM = "&"; 83 private static final String NAT_DELIM = "%"; 84 85 private static class Index { 86 int index; 87 Index(int i) { index = i; } 88 } 89 90 95 public ConstantPoolGen(Constant[] cs) { 96 if(cs.length > size) { 97 size = cs.length; 98 constants = new Constant[size]; 99 } 100 101 System.arraycopy(cs, 0, constants, 0, cs.length); 102 103 if(cs.length > 0) 104 index = cs.length; 105 106 for(int i=1; i < index; i++) { 107 Constant c = constants[i]; 108 109 if(c instanceof ConstantString) { 110 ConstantString s = (ConstantString)c; 111 ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()]; 112 113 string_table.put(u8.getBytes(), new Index(i)); 114 } else if(c instanceof ConstantClass) { 115 ConstantClass s = (ConstantClass)c; 116 ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()]; 117 118 class_table.put(u8.getBytes(), new Index(i)); 119 } else if(c instanceof ConstantNameAndType) { 120 ConstantNameAndType n = (ConstantNameAndType)c; 121 ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()]; 122 ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()]; 123 124 n_a_t_table.put(u8.getBytes() + NAT_DELIM + u8_2.getBytes(), new Index(i)); 125 } else if(c instanceof ConstantUtf8) { 126 ConstantUtf8 u = (ConstantUtf8)c; 127 128 utf8_table.put(u.getBytes(), new Index(i)); 129 } else if(c instanceof ConstantCP) { 130 ConstantCP m = (ConstantCP)c; 131 ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()]; 132 ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()]; 133 134 ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()]; 135 String class_name = u8.getBytes().replace('/', '.'); 136 137 u8 = (ConstantUtf8)constants[n.getNameIndex()]; 138 String method_name = u8.getBytes(); 139 140 u8 = (ConstantUtf8)constants[n.getSignatureIndex()]; 141 String signature = u8.getBytes(); 142 143 String delim = METHODREF_DELIM; 144 145 if(c instanceof ConstantInterfaceMethodref) 146 delim = IMETHODREF_DELIM; 147 else if(c instanceof ConstantFieldref) 148 delim = FIELDREF_DELIM; 149 150 cp_table.put(class_name + delim + method_name + delim + signature, new Index(i)); 151 } 152 } 153 } 154 155 158 public ConstantPoolGen(ConstantPool cp) { 159 this(cp.getConstantPool()); 160 } 161 162 165 public ConstantPoolGen() {} 166 167 169 protected void adjustSize() { 170 if(index + 3 >= size) { 171 Constant[] cs = constants; 172 173 size *= 2; 174 constants = new Constant[size]; 175 System.arraycopy(cs, 0, constants, 0, index); 176 } 177 } 178 179 private HashMap string_table = new HashMap (); 180 181 187 public int lookupString(String str) { 188 Index index = (Index)string_table.get(str); 189 return (index != null)? index.index : -1; 190 } 191 192 198 public int addString(String str) { 199 int ret; 200 201 if((ret = lookupString(str)) != -1) 202 return ret; 204 adjustSize(); 205 206 ConstantUtf8 u8 = new ConstantUtf8(str); 207 ConstantString s = new ConstantString(index); 208 209 constants[index++] = u8; 210 ret = index; 211 constants[index++] = s; 212 213 string_table.put(str, new Index(ret)); 214 215 return ret; 216 } 217 218 private HashMap class_table = new HashMap (); 219 220 226 public int lookupClass(String str) { 227 Index index = (Index)class_table.get(str.replace('.', '/')); 228 return (index != null)? index.index : -1; 229 } 230 231 private int addClass_(String clazz) { 232 int ret; 233 234 if((ret = lookupClass(clazz)) != -1) 235 return ret; 237 adjustSize(); 238 239 ConstantClass c = new ConstantClass(addUtf8(clazz)); 240 241 ret = index; 242 constants[index++] = c; 243 244 class_table.put(clazz, new Index(ret)); 245 246 return ret; 247 } 248 249 255 public int addClass(String str) { 256 return addClass_(str.replace('.', '/')); 257 } 258 259 265 public int addClass(ObjectType type) { 266 return addClass(type.getClassName()); 267 } 268 269 276 public int addArrayClass(ArrayType type) { 277 return addClass_(type.getSignature()); 278 } 279 280 286 public int lookupInteger(int n) { 287 for(int i=1; i < index; i++) { 288 if(constants[i] instanceof ConstantInteger) { 289 ConstantInteger c = (ConstantInteger)constants[i]; 290 291 if(c.getBytes() == n) 292 return i; 293 } 294 } 295 296 return -1; 297 } 298 299 305 public int addInteger(int n) { 306 int ret; 307 308 if((ret = lookupInteger(n)) != -1) 309 return ret; 311 adjustSize(); 312 313 ret = index; 314 constants[index++] = new ConstantInteger(n); 315 316 return ret; 317 } 318 319 325 public int lookupFloat(float n) { 326 for(int i=1; i < index; i++) { 327 if(constants[i] instanceof ConstantFloat) { 328 ConstantFloat c = (ConstantFloat)constants[i]; 329 330 if(c.getBytes() == n) 331 return i; 332 } 333 } 334 335 return -1; 336 } 337 338 344 public int addFloat(float n) { 345 int ret; 346 347 if((ret = lookupFloat(n)) != -1) 348 return ret; 350 adjustSize(); 351 352 ret = index; 353 constants[index++] = new ConstantFloat(n); 354 355 return ret; 356 } 357 358 private HashMap utf8_table = new HashMap (); 359 360 366 public int lookupUtf8(String n) { 367 Index index = (Index)utf8_table.get(n); 368 369 return (index != null)? index.index : -1; 370 } 371 372 378 public int addUtf8(String n) { 379 int ret; 380 381 if((ret = lookupUtf8(n)) != -1) 382 return ret; 384 adjustSize(); 385 386 ret = index; 387 constants[index++] = new ConstantUtf8(n); 388 389 utf8_table.put(n, new Index(ret)); 390 391 return ret; 392 } 393 394 400 public int lookupLong(long n) { 401 for(int i=1; i < index; i++) { 402 if(constants[i] instanceof ConstantLong) { 403 ConstantLong c = (ConstantLong)constants[i]; 404 405 if(c.getBytes() == n) 406 return i; 407 } 408 } 409 410 return -1; 411 } 412 413 419 public int addLong(long n) { 420 int ret; 421 422 if((ret = lookupLong(n)) != -1) 423 return ret; 425 adjustSize(); 426 427 ret = index; 428 constants[index] = new ConstantLong(n); 429 index += 2; 431 return ret; 432 } 433 434 440 public int lookupDouble(double n) { 441 for(int i=1; i < index; i++) { 442 if(constants[i] instanceof ConstantDouble) { 443 ConstantDouble c = (ConstantDouble)constants[i]; 444 445 if(c.getBytes() == n) 446 return i; 447 } 448 } 449 450 return -1; 451 } 452 453 459 public int addDouble(double n) { 460 int ret; 461 462 if((ret = lookupDouble(n)) != -1) 463 return ret; 465 adjustSize(); 466 467 ret = index; 468 constants[index] = new ConstantDouble(n); 469 index += 2; 471 return ret; 472 } 473 474 private HashMap n_a_t_table = new HashMap (); 475 476 483 public int lookupNameAndType(String name, String signature) { 484 Index index = (Index)n_a_t_table.get(name + NAT_DELIM + signature); 485 return (index != null)? index.index : -1; 486 } 487 488 495 public int addNameAndType(String name, String signature) { 496 int ret; 497 int name_index, signature_index; 498 499 if((ret = lookupNameAndType(name, signature)) != -1) 500 return ret; 502 adjustSize(); 503 504 name_index = addUtf8(name); 505 signature_index = addUtf8(signature); 506 ret = index; 507 constants[index++] = new ConstantNameAndType(name_index, signature_index); 508 509 n_a_t_table.put(name + NAT_DELIM + signature, new Index(ret)); 510 return ret; 511 } 512 513 private HashMap cp_table = new HashMap (); 514 515 523 public int lookupMethodref(String class_name, String method_name, String signature) { 524 Index index = (Index)cp_table.get(class_name + METHODREF_DELIM + method_name + 525 METHODREF_DELIM + signature); 526 return (index != null)? index.index : -1; 527 } 528 529 public int lookupMethodref(MethodGen method) { 530 return lookupMethodref(method.getClassName(), method.getName(), 531 method.getSignature()); 532 } 533 534 541 public int addMethodref(String class_name, String method_name, String signature) { 542 int ret, class_index, name_and_type_index; 543 544 if((ret = lookupMethodref(class_name, method_name, signature)) != -1) 545 return ret; 547 adjustSize(); 548 549 name_and_type_index = addNameAndType(method_name, signature); 550 class_index = addClass(class_name); 551 ret = index; 552 constants[index++] = new ConstantMethodref(class_index, name_and_type_index); 553 554 cp_table.put(class_name + METHODREF_DELIM + method_name + 555 METHODREF_DELIM + signature, new Index(ret)); 556 557 return ret; 558 } 559 560 public int addMethodref(MethodGen method) { 561 return addMethodref(method.getClassName(), method.getName(), 562 method.getSignature()); 563 } 564 565 573 public int lookupInterfaceMethodref(String class_name, String method_name, String signature) { 574 Index index = (Index)cp_table.get(class_name + IMETHODREF_DELIM + method_name + 575 IMETHODREF_DELIM + signature); 576 return (index != null)? index.index : -1; 577 } 578 579 public int lookupInterfaceMethodref(MethodGen method) { 580 return lookupInterfaceMethodref(method.getClassName(), method.getName(), 581 method.getSignature()); 582 } 583 584 591 public int addInterfaceMethodref(String class_name, String method_name, String signature) { 592 int ret, class_index, name_and_type_index; 593 594 if((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) 595 return ret; 597 adjustSize(); 598 599 class_index = addClass(class_name); 600 name_and_type_index = addNameAndType(method_name, signature); 601 ret = index; 602 constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); 603 604 cp_table.put(class_name + IMETHODREF_DELIM + method_name + 605 IMETHODREF_DELIM + signature, new Index(ret)); 606 607 return ret; 608 } 609 610 public int addInterfaceMethodref(MethodGen method) { 611 return addInterfaceMethodref(method.getClassName(), method.getName(), 612 method.getSignature()); 613 } 614 615 623 public int lookupFieldref(String class_name, String field_name, String signature) { 624 Index index = (Index)cp_table.get(class_name + FIELDREF_DELIM + field_name + 625 FIELDREF_DELIM + signature); 626 return (index != null)? index.index : -1; 627 } 628 629 636 public int addFieldref(String class_name, String field_name, String signature) { 637 int ret; 638 int class_index, name_and_type_index; 639 640 if((ret = lookupFieldref(class_name, field_name, signature)) != -1) 641 return ret; 643 adjustSize(); 644 645 class_index = addClass(class_name); 646 name_and_type_index = addNameAndType(field_name, signature); 647 ret = index; 648 constants[index++] = new ConstantFieldref(class_index, name_and_type_index); 649 650 cp_table.put(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature, new Index(ret)); 651 652 return ret; 653 } 654 655 659 public Constant getConstant(int i) { return constants[i]; } 660 661 667 public void setConstant(int i, Constant c) { constants[i] = c; } 668 669 672 public ConstantPool getConstantPool() { 673 return new ConstantPool(constants); 674 } 675 676 679 public int getSize() { 680 return index; 681 } 682 683 686 public ConstantPool getFinalConstantPool() { 687 Constant[] cs = new Constant[index]; 688 689 System.arraycopy(constants, 0, cs, 0, index); 690 691 return new ConstantPool(cs); 692 } 693 694 697 public String toString() { 698 StringBuffer buf = new StringBuffer (); 699 700 for(int i=1; i < index; i++) 701 buf.append(i + ")" + constants[i] + "\n"); 702 703 return buf.toString(); 704 } 705 706 708 public int addConstant(Constant c, ConstantPoolGen cp) { 709 Constant[] constants = cp.getConstantPool().getConstantPool(); 710 711 switch(c.getTag()) { 712 case Constants.CONSTANT_String: { 713 ConstantString s = (ConstantString)c; 714 ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()]; 715 716 return addString(u8.getBytes()); 717 } 718 719 case Constants.CONSTANT_Class: { 720 ConstantClass s = (ConstantClass)c; 721 ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()]; 722 723 return addClass(u8.getBytes()); 724 } 725 726 case Constants.CONSTANT_NameAndType: { 727 ConstantNameAndType n = (ConstantNameAndType)c; 728 ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()]; 729 ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()]; 730 731 return addNameAndType(u8.getBytes(), u8_2.getBytes()); 732 } 733 734 case Constants.CONSTANT_Utf8: 735 return addUtf8(((ConstantUtf8)c).getBytes()); 736 737 case Constants.CONSTANT_Double: 738 return addDouble(((ConstantDouble)c).getBytes()); 739 740 case Constants.CONSTANT_Float: 741 return addFloat(((ConstantFloat)c).getBytes()); 742 743 case Constants.CONSTANT_Long: 744 return addLong(((ConstantLong)c).getBytes()); 745 746 case Constants.CONSTANT_Integer: 747 return addInteger(((ConstantInteger)c).getBytes()); 748 749 case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref: 750 case Constants.CONSTANT_Fieldref: { 751 ConstantCP m = (ConstantCP)c; 752 ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()]; 753 ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()]; 754 ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()]; 755 String class_name = u8.getBytes().replace('/', '.'); 756 757 u8 = (ConstantUtf8)constants[n.getNameIndex()]; 758 String name = u8.getBytes(); 759 760 u8 = (ConstantUtf8)constants[n.getSignatureIndex()]; 761 String signature = u8.getBytes(); 762 763 switch(c.getTag()) { 764 case Constants.CONSTANT_InterfaceMethodref: 765 return addInterfaceMethodref(class_name, name, signature); 766 767 case Constants.CONSTANT_Methodref: 768 return addMethodref(class_name, name, signature); 769 770 case Constants.CONSTANT_Fieldref: 771 return addFieldref(class_name, name, signature); 772 773 default: throw new RuntimeException ("Unknown constant type " + c); 775 } 776 } 777 778 default: throw new RuntimeException ("Unknown constant type " + c); 780 } 781 } 782 } 783 | Popular Tags |