1 /* 2 * Javassist, a Java-bytecode translator toolkit. 3 * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. 4 * 5 * The contents of this file are subject to the Mozilla Public License Version 6 * 1.1 (the "License"); you may not use this file except in compliance with 7 * the License. Alternatively, the contents of this file may be used under 8 * the terms of the GNU Lesser General Public License Version 2.1 or later, 9 * or the Apache License Version 2.0. 10 * 11 * Software distributed under the License is distributed on an "AS IS" basis, 12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 * for the specific language governing rights and limitations under the 14 * License. 15 */ 16 17 package javassist.bytecode; 18 19 import java.io.ByteArrayOutputStream; 20 import java.io.DataInputStream; 21 import java.io.DataOutputStream; 22 import java.io.IOException; 23 import java.io.PrintWriter; 24 import java.util.HashMap; 25 import java.util.HashSet; 26 import java.util.Map; 27 import java.util.Set; 28 29 import javassist.CtClass; 30 31 /** 32 * Constant pool table. 33 */ 34 public final class ConstPool 35 { 36 LongVector items; 37 int numOfItems; 38 int thisClassInfo; 39 Map<ConstInfo,ConstInfo> itemsCache; 40 41 /** 42 * <code>CONSTANT_Class</code> 43 */ 44 public static final int CONST_Class = ClassInfo.tag; 45 46 /** 47 * <code>CONSTANT_Fieldref</code> 48 */ 49 public static final int CONST_Fieldref = FieldrefInfo.tag; 50 51 /** 52 * <code>CONSTANT_Methodref</code> 53 */ 54 public static final int CONST_Methodref = MethodrefInfo.tag; 55 56 /** 57 * <code>CONSTANT_InterfaceMethodref</code> 58 */ 59 public static final int CONST_InterfaceMethodref 60 = InterfaceMethodrefInfo.tag; 61 62 /** 63 * <code>CONSTANT_String</code> 64 */ 65 public static final int CONST_String = StringInfo.tag; 66 67 /** 68 * <code>CONSTANT_Integer</code> 69 */ 70 public static final int CONST_Integer = IntegerInfo.tag; 71 72 /** 73 * <code>CONSTANT_Float</code> 74 */ 75 public static final int CONST_Float = FloatInfo.tag; 76 77 /** 78 * <code>CONSTANT_Long</code> 79 */ 80 public static final int CONST_Long = LongInfo.tag; 81 82 /** 83 * <code>CONSTANT_Double</code> 84 */ 85 public static final int CONST_Double = DoubleInfo.tag; 86 87 /** 88 * <code>CONSTANT_NameAndType</code> 89 */ 90 public static final int CONST_NameAndType = NameAndTypeInfo.tag; 91 92 /** 93 * <code>CONSTANT_Utf8</code> 94 */ 95 public static final int CONST_Utf8 = Utf8Info.tag; 96 97 /** 98 * <code>CONSTANT_MethodHandle</code> 99 */ 100 public static final int CONST_MethodHandle = MethodHandleInfo.tag; 101 102 /** 103 * <code>CONSTANT_MethodHandle</code> 104 */ 105 public static final int CONST_MethodType = MethodTypeInfo.tag; 106 107 /** 108 * <code>CONSTANT_MethodHandle</code> 109 */ 110 public static final int CONST_InvokeDynamic = InvokeDynamicInfo.tag; 111 112 /** 113 * <code>CONSTANT_Module</code> 114 */ 115 public static final int CONST_Module = ModuleInfo.tag; 116 117 /** 118 * <code>CONSTANT_Package</code> 119 */ 120 public static final int CONST_Package = PackageInfo.tag; 121 122 /** 123 * Represents the class using this constant pool table. 124 */ 125 public static final CtClass THIS = null; 126 127 /** 128 * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. 129 */ 130 public static final int REF_getField = 1; 131 132 /** 133 * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. 134 */ 135 public static final int REF_getStatic = 2; 136 137 /** 138 * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. 139 */ 140 public static final int REF_putField = 3; 141 142 /** 143 * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. 144 */ 145 public static final int REF_putStatic = 4; 146 147 /** 148 * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. 149 */ 150 public static final int REF_invokeVirtual = 5; 151 152 /** 153 * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. 154 */ 155 public static final int REF_invokeStatic = 6; 156 157 /** 158 * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. 159 */ 160 public static final int REF_invokeSpecial = 7; 161 162 /** 163 * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. 164 */ 165 public static final int REF_newInvokeSpecial = 8; 166 167 /** 168 * <code>reference_kind</code> of <code>CONSTANT_MethodHandle_info</code>. 169 */ 170 public static final int REF_invokeInterface = 9; 171 172 /** 173 * Constructs a constant pool table. 174 * 175 * @param thisclass the name of the class using this constant 176 * pool table 177 */ ConstPool(String thisclass)178 public ConstPool(String thisclass) 179 { 180 items = new LongVector(); 181 itemsCache = null; 182 numOfItems = 0; 183 addItem0(null); // index 0 is reserved by the JVM. 184 thisClassInfo = addClassInfo(thisclass); 185 } 186 187 /** 188 * Constructs a constant pool table from the given byte stream. 189 * 190 * @param in byte stream. 191 */ ConstPool(DataInputStream in)192 public ConstPool(DataInputStream in) throws IOException 193 { 194 itemsCache = null; 195 thisClassInfo = 0; 196 /* read() initializes items and numOfItems, and do addItem(null). 197 */ 198 read(in); 199 } 200 prune()201 void prune() 202 { 203 itemsCache = null; 204 } 205 206 /** 207 * Returns the number of entries in this table. 208 */ getSize()209 public int getSize() 210 { 211 return numOfItems; 212 } 213 214 /** 215 * Returns the name of the class using this constant pool table. 216 */ getClassName()217 public String getClassName() 218 { 219 return getClassInfo(thisClassInfo); 220 } 221 222 /** 223 * Returns the index of <code>CONSTANT_Class_info</code> structure 224 * specifying the class using this constant pool table. 225 */ getThisClassInfo()226 public int getThisClassInfo() 227 { 228 return thisClassInfo; 229 } 230 setThisClassInfo(int i)231 void setThisClassInfo(int i) 232 { 233 thisClassInfo = i; 234 } 235 getItem(int n)236 ConstInfo getItem(int n) 237 { 238 return items.elementAt(n); 239 } 240 241 /** 242 * Returns the <code>tag</code> field of the constant pool table 243 * entry at the given index. 244 * 245 * @return either <code>CONST_Class</code>, <code>CONST_Fieldref</code>, 246 * <code>CONST_Methodref</code>, or ... 247 */ getTag(int index)248 public int getTag(int index) 249 { 250 return getItem(index).getTag(); 251 } 252 253 /** 254 * Reads <code>CONSTANT_Class_info</code> structure 255 * at the given index. 256 * 257 * @return a fully-qualified class or interface name specified 258 * by <code>name_index</code>. If the type is an array 259 * type, this method returns an encoded name like 260 * <code>[Ljava.lang.Object;</code> (note that the separators 261 * are not slashes but dots). 262 * @see javassist.ClassPool#getCtClass(String) 263 */ getClassInfo(int index)264 public String getClassInfo(int index) 265 { 266 ClassInfo c = (ClassInfo)getItem(index); 267 if (c == null) 268 return null; 269 return Descriptor.toJavaName(getUtf8Info(c.name)); 270 } 271 272 /** 273 * Reads <code>CONSTANT_Class_info</code> structure 274 * at the given index. 275 * 276 * @return the descriptor of the type specified 277 * by <code>name_index</code>. 278 * @see javassist.ClassPool#getCtClass(String) 279 * @since 3.15 280 */ getClassInfoByDescriptor(int index)281 public String getClassInfoByDescriptor(int index) 282 { 283 ClassInfo c = (ClassInfo)getItem(index); 284 if (c == null) 285 return null; 286 String className = getUtf8Info(c.name); 287 if (className.charAt(0) == '[') 288 return className; 289 return Descriptor.of(className); 290 } 291 292 /** 293 * Reads the <code>name_index</code> field of the 294 * <code>CONSTANT_NameAndType_info</code> structure 295 * at the given index. 296 */ getNameAndTypeName(int index)297 public int getNameAndTypeName(int index) 298 { 299 NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index); 300 return ntinfo.memberName; 301 } 302 303 /** 304 * Reads the <code>descriptor_index</code> field of the 305 * <code>CONSTANT_NameAndType_info</code> structure 306 * at the given index. 307 */ getNameAndTypeDescriptor(int index)308 public int getNameAndTypeDescriptor(int index) 309 { 310 NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index); 311 return ntinfo.typeDescriptor; 312 } 313 314 /** 315 * Reads the <code>class_index</code> field of the 316 * <code>CONSTANT_Fieldref_info</code>, 317 * <code>CONSTANT_Methodref_info</code>, 318 * or <code>CONSTANT_Interfaceref_info</code>, 319 * structure at the given index. 320 * 321 * @since 3.6 322 */ getMemberClass(int index)323 public int getMemberClass(int index) 324 { 325 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 326 return minfo.classIndex; 327 } 328 329 /** 330 * Reads the <code>name_and_type_index</code> field of the 331 * <code>CONSTANT_Fieldref_info</code>, 332 * <code>CONSTANT_Methodref_info</code>, 333 * or <code>CONSTANT_Interfaceref_info</code>, 334 * structure at the given index. 335 * 336 * @since 3.6 337 */ getMemberNameAndType(int index)338 public int getMemberNameAndType(int index) 339 { 340 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 341 return minfo.nameAndTypeIndex; 342 } 343 344 /** 345 * Reads the <code>class_index</code> field of the 346 * <code>CONSTANT_Fieldref_info</code> structure 347 * at the given index. 348 */ getFieldrefClass(int index)349 public int getFieldrefClass(int index) 350 { 351 FieldrefInfo finfo = (FieldrefInfo)getItem(index); 352 return finfo.classIndex; 353 } 354 355 /** 356 * Reads the <code>class_index</code> field of the 357 * <code>CONSTANT_Fieldref_info</code> structure 358 * at the given index. 359 * 360 * @return the name of the class at that <code>class_index</code>. 361 */ getFieldrefClassName(int index)362 public String getFieldrefClassName(int index) 363 { 364 FieldrefInfo f = (FieldrefInfo)getItem(index); 365 if (f == null) 366 return null; 367 return getClassInfo(f.classIndex); 368 } 369 370 /** 371 * Reads the <code>name_and_type_index</code> field of the 372 * <code>CONSTANT_Fieldref_info</code> structure 373 * at the given index. 374 */ getFieldrefNameAndType(int index)375 public int getFieldrefNameAndType(int index) 376 { 377 FieldrefInfo finfo = (FieldrefInfo)getItem(index); 378 return finfo.nameAndTypeIndex; 379 } 380 381 /** 382 * Reads the <code>name_index</code> field of the 383 * <code>CONSTANT_NameAndType_info</code> structure 384 * indirectly specified by the given index. 385 * 386 * @param index an index to a <code>CONSTANT_Fieldref_info</code>. 387 * @return the name of the field. 388 */ getFieldrefName(int index)389 public String getFieldrefName(int index) 390 { 391 FieldrefInfo f = (FieldrefInfo)getItem(index); 392 if (f == null) 393 return null; 394 NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex); 395 if(n == null) 396 return null; 397 return getUtf8Info(n.memberName); 398 } 399 400 /** 401 * Reads the <code>descriptor_index</code> field of the 402 * <code>CONSTANT_NameAndType_info</code> structure 403 * indirectly specified by the given index. 404 * 405 * @param index an index to a <code>CONSTANT_Fieldref_info</code>. 406 * @return the type descriptor of the field. 407 */ getFieldrefType(int index)408 public String getFieldrefType(int index) 409 { 410 FieldrefInfo f = (FieldrefInfo)getItem(index); 411 if (f == null) 412 return null; 413 NameAndTypeInfo n = (NameAndTypeInfo)getItem(f.nameAndTypeIndex); 414 if(n == null) 415 return null; 416 return getUtf8Info(n.typeDescriptor); 417 } 418 419 /** 420 * Reads the <code>class_index</code> field of the 421 * <code>CONSTANT_Methodref_info</code> structure 422 * at the given index. 423 */ getMethodrefClass(int index)424 public int getMethodrefClass(int index) 425 { 426 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 427 return minfo.classIndex; 428 } 429 430 /** 431 * Reads the <code>class_index</code> field of the 432 * <code>CONSTANT_Methodref_info</code> structure 433 * at the given index. 434 * 435 * @return the name of the class at that <code>class_index</code>. 436 */ getMethodrefClassName(int index)437 public String getMethodrefClassName(int index) 438 { 439 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 440 if (minfo == null) 441 return null; 442 return getClassInfo(minfo.classIndex); 443 } 444 445 /** 446 * Reads the <code>name_and_type_index</code> field of the 447 * <code>CONSTANT_Methodref_info</code> structure 448 * at the given index. 449 */ getMethodrefNameAndType(int index)450 public int getMethodrefNameAndType(int index) 451 { 452 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 453 return minfo.nameAndTypeIndex; 454 } 455 456 /** 457 * Reads the <code>name_index</code> field of the 458 * <code>CONSTANT_NameAndType_info</code> structure 459 * indirectly specified by the given index. 460 * 461 * @param index an index to a <code>CONSTANT_Methodref_info</code>. 462 * @return the name of the method. 463 */ getMethodrefName(int index)464 public String getMethodrefName(int index) 465 { 466 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 467 if (minfo == null) 468 return null; 469 NameAndTypeInfo n 470 = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); 471 if(n == null) 472 return null; 473 return getUtf8Info(n.memberName); 474 } 475 476 /** 477 * Reads the <code>descriptor_index</code> field of the 478 * <code>CONSTANT_NameAndType_info</code> structure 479 * indirectly specified by the given index. 480 * 481 * @param index an index to a <code>CONSTANT_Methodref_info</code>. 482 * @return the descriptor of the method. 483 */ getMethodrefType(int index)484 public String getMethodrefType(int index) 485 { 486 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 487 if (minfo == null) 488 return null; 489 NameAndTypeInfo n 490 = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); 491 if(n == null) 492 return null; 493 return getUtf8Info(n.typeDescriptor); 494 } 495 496 /** 497 * Reads the <code>class_index</code> field of the 498 * <code>CONSTANT_InterfaceMethodref_info</code> structure 499 * at the given index. 500 */ getInterfaceMethodrefClass(int index)501 public int getInterfaceMethodrefClass(int index) 502 { 503 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 504 return minfo.classIndex; 505 } 506 507 /** 508 * Reads the <code>class_index</code> field of the 509 * <code>CONSTANT_InterfaceMethodref_info</code> structure 510 * at the given index. 511 * 512 * @return the name of the class at that <code>class_index</code>. 513 */ getInterfaceMethodrefClassName(int index)514 public String getInterfaceMethodrefClassName(int index) 515 { 516 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 517 return getClassInfo(minfo.classIndex); 518 } 519 520 /** 521 * Reads the <code>name_and_type_index</code> field of the 522 * <code>CONSTANT_InterfaceMethodref_info</code> structure 523 * at the given index. 524 */ getInterfaceMethodrefNameAndType(int index)525 public int getInterfaceMethodrefNameAndType(int index) 526 { 527 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 528 return minfo.nameAndTypeIndex; 529 } 530 531 /** 532 * Reads the <code>name_index</code> field of the 533 * <code>CONSTANT_NameAndType_info</code> structure 534 * indirectly specified by the given index. 535 * 536 * @param index an index to 537 * a <code>CONSTANT_InterfaceMethodref_info</code>. 538 * @return the name of the method. 539 */ getInterfaceMethodrefName(int index)540 public String getInterfaceMethodrefName(int index) 541 { 542 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 543 if (minfo == null) 544 return null; 545 NameAndTypeInfo n 546 = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); 547 if(n == null) 548 return null; 549 return getUtf8Info(n.memberName); 550 } 551 552 /** 553 * Reads the <code>descriptor_index</code> field of the 554 * <code>CONSTANT_NameAndType_info</code> structure 555 * indirectly specified by the given index. 556 * 557 * @param index an index to 558 * a <code>CONSTANT_InterfaceMethodref_info</code>. 559 * @return the descriptor of the method. 560 */ getInterfaceMethodrefType(int index)561 public String getInterfaceMethodrefType(int index) 562 { 563 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 564 if (minfo == null) 565 return null; 566 NameAndTypeInfo n 567 = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); 568 if(n == null) 569 return null; 570 return getUtf8Info(n.typeDescriptor); 571 } 572 /** 573 * Reads <code>CONSTANT_Integer_info</code>, <code>_Float_info</code>, 574 * <code>_Long_info</code>, <code>_Double_info</code>, or 575 * <code>_String_info</code> structure. 576 * These are used with the LDC instruction. 577 * 578 * @return a <code>String</code> value or a wrapped primitive-type 579 * value. 580 */ getLdcValue(int index)581 public Object getLdcValue(int index) 582 { 583 ConstInfo constInfo = this.getItem(index); 584 Object value = null; 585 if (constInfo instanceof StringInfo) 586 value = this.getStringInfo(index); 587 else if (constInfo instanceof FloatInfo) 588 value = Float.valueOf(getFloatInfo(index)); 589 else if (constInfo instanceof IntegerInfo) 590 value = Integer.valueOf(getIntegerInfo(index)); 591 else if (constInfo instanceof LongInfo) 592 value = Long.valueOf(getLongInfo(index)); 593 else if (constInfo instanceof DoubleInfo) 594 value = Double.valueOf(getDoubleInfo(index)); 595 596 return value; 597 } 598 599 /** 600 * Reads <code>CONSTANT_Integer_info</code> structure 601 * at the given index. 602 * 603 * @return the value specified by this entry. 604 */ getIntegerInfo(int index)605 public int getIntegerInfo(int index) 606 { 607 IntegerInfo i = (IntegerInfo)getItem(index); 608 return i.value; 609 } 610 611 /** 612 * Reads <code>CONSTANT_Float_info</code> structure 613 * at the given index. 614 * 615 * @return the value specified by this entry. 616 */ getFloatInfo(int index)617 public float getFloatInfo(int index) 618 { 619 FloatInfo i = (FloatInfo)getItem(index); 620 return i.value; 621 } 622 623 /** 624 * Reads <code>CONSTANT_Long_info</code> structure 625 * at the given index. 626 * 627 * @return the value specified by this entry. 628 */ getLongInfo(int index)629 public long getLongInfo(int index) 630 { 631 LongInfo i = (LongInfo)getItem(index); 632 return i.value; 633 } 634 635 /** 636 * Reads <code>CONSTANT_Double_info</code> structure 637 * at the given index. 638 * 639 * @return the value specified by this entry. 640 */ getDoubleInfo(int index)641 public double getDoubleInfo(int index) 642 { 643 DoubleInfo i = (DoubleInfo)getItem(index); 644 return i.value; 645 } 646 647 /** 648 * Reads <code>CONSTANT_String_info</code> structure 649 * at the given index. 650 * 651 * @return the string specified by <code>string_index</code>. 652 */ getStringInfo(int index)653 public String getStringInfo(int index) 654 { 655 StringInfo si = (StringInfo)getItem(index); 656 return getUtf8Info(si.string); 657 } 658 659 /** 660 * Reads <code>CONSTANT_utf8_info</code> structure 661 * at the given index. 662 * 663 * @return the string specified by this entry. 664 */ getUtf8Info(int index)665 public String getUtf8Info(int index) 666 { 667 Utf8Info utf = (Utf8Info)getItem(index); 668 return utf.string; 669 } 670 671 /** 672 * Reads the <code>reference_kind</code> field of the 673 * <code>CONSTANT_MethodHandle_info</code> structure 674 * at the given index. 675 * 676 * @see #REF_getField 677 * @see #REF_getStatic 678 * @see #REF_invokeInterface 679 * @see #REF_invokeSpecial 680 * @see #REF_invokeStatic 681 * @see #REF_invokeVirtual 682 * @see #REF_newInvokeSpecial 683 * @see #REF_putField 684 * @see #REF_putStatic 685 * @since 3.17 686 */ getMethodHandleKind(int index)687 public int getMethodHandleKind(int index) 688 { 689 MethodHandleInfo mhinfo = (MethodHandleInfo)getItem(index); 690 return mhinfo.refKind; 691 } 692 693 /** 694 * Reads the <code>reference_index</code> field of the 695 * <code>CONSTANT_MethodHandle_info</code> structure 696 * at the given index. 697 * 698 * @since 3.17 699 */ getMethodHandleIndex(int index)700 public int getMethodHandleIndex(int index) 701 { 702 MethodHandleInfo mhinfo = (MethodHandleInfo)getItem(index); 703 return mhinfo.refIndex; 704 } 705 706 /** 707 * Reads the <code>descriptor_index</code> field of the 708 * <code>CONSTANT_MethodType_info</code> structure 709 * at the given index. 710 * 711 * @since 3.17 712 */ getMethodTypeInfo(int index)713 public int getMethodTypeInfo(int index) 714 { 715 MethodTypeInfo mtinfo = (MethodTypeInfo)getItem(index); 716 return mtinfo.descriptor; 717 } 718 719 /** 720 * Reads the <code>bootstrap_method_attr_index</code> field of the 721 * <code>CONSTANT_InvokeDynamic_info</code> structure 722 * at the given index. 723 * 724 * @since 3.17 725 */ getInvokeDynamicBootstrap(int index)726 public int getInvokeDynamicBootstrap(int index) 727 { 728 InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index); 729 return iv.bootstrap; 730 } 731 732 /** 733 * Reads the <code>name_and_type_index</code> field of the 734 * <code>CONSTANT_InvokeDynamic_info</code> structure 735 * at the given index. 736 * 737 * @since 3.17 738 */ getInvokeDynamicNameAndType(int index)739 public int getInvokeDynamicNameAndType(int index) 740 { 741 InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index); 742 return iv.nameAndType; 743 } 744 745 /** 746 * Reads the <code>descriptor_index</code> field of the 747 * <code>CONSTANT_NameAndType_info</code> structure 748 * indirectly specified by the given index. 749 * 750 * @param index an index to a <code>CONSTANT_InvokeDynamic_info</code>. 751 * @return the descriptor of the method. 752 * @since 3.17 753 */ getInvokeDynamicType(int index)754 public String getInvokeDynamicType(int index) 755 { 756 InvokeDynamicInfo iv = (InvokeDynamicInfo)getItem(index); 757 if (iv == null) 758 return null; 759 NameAndTypeInfo n = (NameAndTypeInfo)getItem(iv.nameAndType); 760 if(n == null) 761 return null; 762 return getUtf8Info(n.typeDescriptor); 763 } 764 765 /** 766 * Reads the <code>name_index</code> field of the 767 * <code>CONSTANT_Module_info</code> structure at the given index. 768 * 769 * @return the module name at <code>name_index</code>. 770 * @since 3.22 771 */ getModuleInfo(int index)772 public String getModuleInfo(int index) 773 { 774 ModuleInfo mi = (ModuleInfo)getItem(index); 775 return getUtf8Info(mi.name); 776 } 777 778 /** 779 * Reads the <code>name_index</code> field of the 780 * <code>CONSTANT_Package_info</code> structure at the given index. 781 * 782 * @return the package name at <code>name_index</code>. It is a slash- 783 * separated name such as com/oracle/net. 784 * @since 3.22 785 */ getPackageInfo(int index)786 public String getPackageInfo(int index) 787 { 788 PackageInfo mi = (PackageInfo)getItem(index); 789 return getUtf8Info(mi.name); 790 } 791 792 /** 793 * Determines whether <code>CONSTANT_Methodref_info</code> 794 * structure at the given index represents the constructor 795 * of the given class. 796 * 797 * @return the <code>descriptor_index</code> specifying 798 * the type descriptor of the that constructor. 799 * If it is not that constructor, 800 * <code>isConstructor()</code> returns 0. 801 */ isConstructor(String classname, int index)802 public int isConstructor(String classname, int index) 803 { 804 return isMember(classname, MethodInfo.nameInit, index); 805 } 806 807 /** 808 * Determines whether <code>CONSTANT_Methodref_info</code>, 809 * <code>CONSTANT_Fieldref_info</code>, or 810 * <code>CONSTANT_InterfaceMethodref_info</code> structure 811 * at the given index represents the member with the specified 812 * name and declaring class. 813 * 814 * @param classname the class declaring the member 815 * @param membername the member name 816 * @param index the index into the constant pool table 817 * 818 * @return the <code>descriptor_index</code> specifying 819 * the type descriptor of that member. 820 * If it is not that member, 821 * <code>isMember()</code> returns 0. 822 */ isMember(String classname, String membername, int index)823 public int isMember(String classname, String membername, int index) 824 { 825 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 826 if (getClassInfo(minfo.classIndex).equals(classname)) { 827 NameAndTypeInfo ntinfo 828 = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); 829 if (getUtf8Info(ntinfo.memberName).equals(membername)) 830 return ntinfo.typeDescriptor; 831 } 832 833 return 0; // false 834 } 835 836 /** 837 * Determines whether <code>CONSTANT_Methodref_info</code>, 838 * <code>CONSTANT_Fieldref_info</code>, or 839 * <code>CONSTANT_InterfaceMethodref_info</code> structure 840 * at the given index has the name and the descriptor 841 * given as the arguments. 842 * 843 * @param membername the member name 844 * @param desc the descriptor of the member. 845 * @param index the index into the constant pool table 846 * 847 * @return the name of the target class specified by 848 * the <code>..._info</code> structure 849 * at <code>index</code>. 850 * Otherwise, null if that structure does not 851 * match the given member name and descriptor. 852 */ eqMember(String membername, String desc, int index)853 public String eqMember(String membername, String desc, int index) 854 { 855 MemberrefInfo minfo = (MemberrefInfo)getItem(index); 856 NameAndTypeInfo ntinfo 857 = (NameAndTypeInfo)getItem(minfo.nameAndTypeIndex); 858 if (getUtf8Info(ntinfo.memberName).equals(membername) 859 && getUtf8Info(ntinfo.typeDescriptor).equals(desc)) 860 return getClassInfo(minfo.classIndex); 861 return null; // false 862 } 863 addItem0(ConstInfo info)864 private int addItem0(ConstInfo info) 865 { 866 items.addElement(info); 867 return numOfItems++; 868 } 869 addItem(ConstInfo info)870 private int addItem(ConstInfo info) 871 { 872 if (itemsCache == null) 873 itemsCache = makeItemsCache(items); 874 875 ConstInfo found = itemsCache.get(info); 876 if (found != null) 877 return found.index; 878 items.addElement(info); 879 itemsCache.put(info, info); 880 return numOfItems++; 881 } 882 883 /** 884 * Copies the n-th item in this ConstPool object into the destination 885 * ConstPool object. 886 * The class names that the item refers to are renamed according 887 * to the given map. 888 * 889 * @param n the <i>n</i>-th item 890 * @param dest destination constant pool table 891 * @param classnames the map or null. 892 * @return the index of the copied item into the destination ClassPool. 893 */ copy(int n, ConstPool dest, Map<String,String> classnames)894 public int copy(int n, ConstPool dest, Map<String,String> classnames) 895 { 896 if (n == 0) 897 return 0; 898 899 ConstInfo info = getItem(n); 900 return info.copy(this, dest, classnames); 901 } 902 addConstInfoPadding()903 int addConstInfoPadding() { 904 return addItem0(new ConstInfoPadding(numOfItems)); 905 } 906 907 /** 908 * Adds a new <code>CONSTANT_Class_info</code> structure. 909 * 910 * <p>This also adds a <code>CONSTANT_Utf8_info</code> structure 911 * for storing the class name. 912 * 913 * @return the index of the added entry. 914 */ addClassInfo(CtClass c)915 public int addClassInfo(CtClass c) 916 { 917 if (c == THIS) 918 return thisClassInfo; 919 else if (!c.isArray()) 920 return addClassInfo(c.getName()); 921 else { 922 // an array type is recorded in the hashtable with 923 // the key "[L<classname>;" instead of "<classname>". 924 // 925 // note: toJvmName(toJvmName(c)) is equal to toJvmName(c). 926 927 return addClassInfo(Descriptor.toJvmName(c)); 928 } 929 } 930 931 /** 932 * Adds a new <code>CONSTANT_Class_info</code> structure. 933 * 934 * <p>This also adds a <code>CONSTANT_Utf8_info</code> structure 935 * for storing the class name. 936 * 937 * @param qname a fully-qualified class name 938 * (or the JVM-internal representation of that name). 939 * @return the index of the added entry. 940 */ addClassInfo(String qname)941 public int addClassInfo(String qname) 942 { 943 int utf8 = addUtf8Info(Descriptor.toJvmName(qname)); 944 return addItem(new ClassInfo(utf8, numOfItems)); 945 } 946 947 /** 948 * Adds a new <code>CONSTANT_NameAndType_info</code> structure. 949 * 950 * <p>This also adds <code>CONSTANT_Utf8_info</code> structures. 951 * 952 * @param name <code>name_index</code> 953 * @param type <code>descriptor_index</code> 954 * @return the index of the added entry. 955 */ addNameAndTypeInfo(String name, String type)956 public int addNameAndTypeInfo(String name, String type) 957 { 958 return addNameAndTypeInfo(addUtf8Info(name), addUtf8Info(type)); 959 } 960 961 /** 962 * Adds a new <code>CONSTANT_NameAndType_info</code> structure. 963 * 964 * @param name <code>name_index</code> 965 * @param type <code>descriptor_index</code> 966 * @return the index of the added entry. 967 */ addNameAndTypeInfo(int name, int type)968 public int addNameAndTypeInfo(int name, int type) 969 { 970 return addItem(new NameAndTypeInfo(name, type, numOfItems)); 971 } 972 973 /** 974 * Adds a new <code>CONSTANT_Fieldref_info</code> structure. 975 * 976 * <p>This also adds a new <code>CONSTANT_NameAndType_info</code> 977 * structure. 978 * 979 * @param classInfo <code>class_index</code> 980 * @param name <code>name_index</code> 981 * of <code>CONSTANT_NameAndType_info</code>. 982 * @param type <code>descriptor_index</code> 983 * of <code>CONSTANT_NameAndType_info</code>. 984 * @return the index of the added entry. 985 */ addFieldrefInfo(int classInfo, String name, String type)986 public int addFieldrefInfo(int classInfo, String name, String type) 987 { 988 int nt = addNameAndTypeInfo(name, type); 989 return addFieldrefInfo(classInfo, nt); 990 } 991 992 /** 993 * Adds a new <code>CONSTANT_Fieldref_info</code> structure. 994 * 995 * @param classInfo <code>class_index</code> 996 * @param nameAndTypeInfo <code>name_and_type_index</code>. 997 * @return the index of the added entry. 998 */ addFieldrefInfo(int classInfo, int nameAndTypeInfo)999 public int addFieldrefInfo(int classInfo, int nameAndTypeInfo) 1000 { 1001 return addItem(new FieldrefInfo(classInfo, nameAndTypeInfo, 1002 numOfItems)); 1003 } 1004 1005 /** 1006 * Adds a new <code>CONSTANT_Methodref_info</code> structure. 1007 * 1008 * <p>This also adds a new <code>CONSTANT_NameAndType_info</code> 1009 * structure. 1010 * 1011 * @param classInfo <code>class_index</code> 1012 * @param name <code>name_index</code> 1013 * of <code>CONSTANT_NameAndType_info</code>. 1014 * @param type <code>descriptor_index</code> 1015 * of <code>CONSTANT_NameAndType_info</code>. 1016 * @return the index of the added entry. 1017 */ addMethodrefInfo(int classInfo, String name, String type)1018 public int addMethodrefInfo(int classInfo, String name, String type) 1019 { 1020 int nt = addNameAndTypeInfo(name, type); 1021 return addMethodrefInfo(classInfo, nt); 1022 } 1023 1024 /** 1025 * Adds a new <code>CONSTANT_Methodref_info</code> structure. 1026 * 1027 * @param classInfo <code>class_index</code> 1028 * @param nameAndTypeInfo <code>name_and_type_index</code>. 1029 * @return the index of the added entry. 1030 */ addMethodrefInfo(int classInfo, int nameAndTypeInfo)1031 public int addMethodrefInfo(int classInfo, int nameAndTypeInfo) 1032 { 1033 return addItem(new MethodrefInfo(classInfo, 1034 nameAndTypeInfo, numOfItems)); 1035 } 1036 1037 /** 1038 * Adds a new <code>CONSTANT_InterfaceMethodref_info</code> 1039 * structure. 1040 * 1041 * <p>This also adds a new <code>CONSTANT_NameAndType_info</code> 1042 * structure. 1043 * 1044 * @param classInfo <code>class_index</code> 1045 * @param name <code>name_index</code> 1046 * of <code>CONSTANT_NameAndType_info</code>. 1047 * @param type <code>descriptor_index</code> 1048 * of <code>CONSTANT_NameAndType_info</code>. 1049 * @return the index of the added entry. 1050 */ addInterfaceMethodrefInfo(int classInfo, String name, String type)1051 public int addInterfaceMethodrefInfo(int classInfo, 1052 String name, 1053 String type) 1054 { 1055 int nt = addNameAndTypeInfo(name, type); 1056 return addInterfaceMethodrefInfo(classInfo, nt); 1057 } 1058 1059 /** 1060 * Adds a new <code>CONSTANT_InterfaceMethodref_info</code> 1061 * structure. 1062 * 1063 * @param classInfo <code>class_index</code> 1064 * @param nameAndTypeInfo <code>name_and_type_index</code>. 1065 * @return the index of the added entry. 1066 */ addInterfaceMethodrefInfo(int classInfo, int nameAndTypeInfo)1067 public int addInterfaceMethodrefInfo(int classInfo, 1068 int nameAndTypeInfo) 1069 { 1070 return addItem(new InterfaceMethodrefInfo(classInfo, 1071 nameAndTypeInfo, 1072 numOfItems)); 1073 } 1074 1075 /** 1076 * Adds a new <code>CONSTANT_String_info</code> 1077 * structure. 1078 * 1079 * <p>This also adds a new <code>CONSTANT_Utf8_info</code> 1080 * structure. 1081 * 1082 * @return the index of the added entry. 1083 */ addStringInfo(String str)1084 public int addStringInfo(String str) 1085 { 1086 int utf = addUtf8Info(str); 1087 return addItem(new StringInfo(utf, numOfItems)); 1088 } 1089 1090 /** 1091 * Adds a new <code>CONSTANT_Integer_info</code> 1092 * structure. 1093 * 1094 * @return the index of the added entry. 1095 */ addIntegerInfo(int i)1096 public int addIntegerInfo(int i) 1097 { 1098 return addItem(new IntegerInfo(i, numOfItems)); 1099 } 1100 1101 /** 1102 * Adds a new <code>CONSTANT_Float_info</code> 1103 * structure. 1104 * 1105 * @return the index of the added entry. 1106 */ addFloatInfo(float f)1107 public int addFloatInfo(float f) 1108 { 1109 return addItem(new FloatInfo(f, numOfItems)); 1110 } 1111 1112 /** 1113 * Adds a new <code>CONSTANT_Long_info</code> 1114 * structure. 1115 * 1116 * @return the index of the added entry. 1117 */ addLongInfo(long l)1118 public int addLongInfo(long l) 1119 { 1120 int i = addItem(new LongInfo(l, numOfItems)); 1121 if (i == numOfItems - 1) // if not existing 1122 addConstInfoPadding(); 1123 1124 return i; 1125 } 1126 1127 /** 1128 * Adds a new <code>CONSTANT_Double_info</code> 1129 * structure. 1130 * 1131 * @return the index of the added entry. 1132 */ addDoubleInfo(double d)1133 public int addDoubleInfo(double d) 1134 { 1135 int i = addItem(new DoubleInfo(d, numOfItems)); 1136 if (i == numOfItems - 1) // if not existing 1137 addConstInfoPadding(); 1138 1139 return i; 1140 } 1141 1142 /** 1143 * Adds a new <code>CONSTANT_Utf8_info</code> 1144 * structure. 1145 * 1146 * @return the index of the added entry. 1147 */ addUtf8Info(String utf8)1148 public int addUtf8Info(String utf8) 1149 { 1150 return addItem(new Utf8Info(utf8, numOfItems)); 1151 } 1152 1153 /** 1154 * Adds a new <code>CONSTANT_MethodHandle_info</code> 1155 * structure. 1156 * 1157 * @param kind <code>reference_kind</code> 1158 * such as {@link #REF_invokeStatic <code>REF_invokeStatic</code>}. 1159 * @param index <code>reference_index</code>. 1160 * @return the index of the added entry. 1161 * 1162 * @since 3.17 1163 */ addMethodHandleInfo(int kind, int index)1164 public int addMethodHandleInfo(int kind, int index) 1165 { 1166 return addItem(new MethodHandleInfo(kind, index, numOfItems)); 1167 } 1168 1169 /** 1170 * Adds a new <code>CONSTANT_MethodType_info</code> 1171 * structure. 1172 * 1173 * @param desc <code>descriptor_index</code>. 1174 * @return the index of the added entry. 1175 * 1176 * @since 3.17 1177 */ addMethodTypeInfo(int desc)1178 public int addMethodTypeInfo(int desc) 1179 { 1180 return addItem(new MethodTypeInfo(desc, numOfItems)); 1181 } 1182 1183 /** 1184 * Adds a new <code>CONSTANT_InvokeDynamic_info</code> 1185 * structure. 1186 * 1187 * @param bootstrap <code>bootstrap_method_attr_index</code>. 1188 * @param nameAndType <code>name_and_type_index</code>. 1189 * @return the index of the added entry. 1190 * 1191 * @since 3.17 1192 */ addInvokeDynamicInfo(int bootstrap, int nameAndType)1193 public int addInvokeDynamicInfo(int bootstrap, int nameAndType) 1194 { 1195 return addItem(new InvokeDynamicInfo(bootstrap, nameAndType, numOfItems)); 1196 } 1197 1198 /** 1199 * Adds a new <code>CONSTANT_Module_info</code> 1200 * @param nameIndex the index of the Utf8 entry. 1201 * @return the index of the added entry. 1202 * @since 3.22 1203 */ addModuleInfo(int nameIndex)1204 public int addModuleInfo(int nameIndex) 1205 { 1206 return addItem(new ModuleInfo(nameIndex, numOfItems)); 1207 } 1208 1209 /** 1210 * Adds a new <code>CONSTANT_Package_info</code> 1211 * @param nameIndex the index of the Utf8 entry. 1212 * @return the index of the added entry. 1213 * @since 3.22 1214 */ addPackageInfo(int nameIndex)1215 public int addPackageInfo(int nameIndex) 1216 { 1217 return addItem(new PackageInfo(nameIndex, numOfItems)); 1218 } 1219 1220 /** 1221 * Get all the class names. 1222 * 1223 * @return a set of class names (<code>String</code> objects). 1224 */ getClassNames()1225 public Set<String> getClassNames() 1226 { 1227 Set<String> result = new HashSet<String>(); 1228 LongVector v = items; 1229 int size = numOfItems; 1230 for (int i = 1; i < size; ++i) { 1231 String className = v.elementAt(i).getClassName(this); 1232 if (className != null) 1233 result.add(className); 1234 } 1235 return result; 1236 } 1237 1238 /** 1239 * Replaces all occurrences of a class name. 1240 * 1241 * @param oldName the replaced name (JVM-internal representation). 1242 * @param newName the substituted name (JVM-internal representation). 1243 */ renameClass(String oldName, String newName)1244 public void renameClass(String oldName, String newName) 1245 { 1246 LongVector v = items; 1247 int size = numOfItems; 1248 for (int i = 1; i < size; ++i) { 1249 ConstInfo ci = v.elementAt(i); 1250 ci.renameClass(this, oldName, newName, itemsCache); 1251 } 1252 } 1253 1254 /** 1255 * Replaces all occurrences of class names. 1256 * 1257 * @param classnames specifies pairs of replaced and substituted 1258 * name. 1259 */ renameClass(Map<String,String> classnames)1260 public void renameClass(Map<String,String> classnames) 1261 { 1262 LongVector v = items; 1263 int size = numOfItems; 1264 for (int i = 1; i < size; ++i) { 1265 ConstInfo ci = v.elementAt(i); 1266 ci.renameClass(this, classnames, itemsCache); 1267 } 1268 } 1269 read(DataInputStream in)1270 private void read(DataInputStream in) throws IOException 1271 { 1272 int n = in.readUnsignedShort(); 1273 1274 items = new LongVector(n); 1275 numOfItems = 0; 1276 addItem0(null); // index 0 is reserved by the JVM. 1277 1278 while (--n > 0) { // index 0 is reserved by JVM 1279 int tag = readOne(in); 1280 if ((tag == LongInfo.tag) || (tag == DoubleInfo.tag)) { 1281 addConstInfoPadding(); 1282 --n; 1283 } 1284 } 1285 } 1286 makeItemsCache(LongVector items)1287 private static Map<ConstInfo,ConstInfo> makeItemsCache(LongVector items) 1288 { 1289 Map<ConstInfo,ConstInfo> cache = new HashMap<ConstInfo,ConstInfo>(); 1290 int i = 1; 1291 while (true) { 1292 ConstInfo info = items.elementAt(i++); 1293 if (info == null) 1294 break; 1295 cache.put(info, info); 1296 } 1297 1298 return cache; 1299 } 1300 readOne(DataInputStream in)1301 private int readOne(DataInputStream in) throws IOException 1302 { 1303 ConstInfo info; 1304 int tag = in.readUnsignedByte(); 1305 switch (tag) { 1306 case Utf8Info.tag : // 1 1307 info = new Utf8Info(in, numOfItems); 1308 break; 1309 case IntegerInfo.tag : // 3 1310 info = new IntegerInfo(in, numOfItems); 1311 break; 1312 case FloatInfo.tag : // 4 1313 info = new FloatInfo(in, numOfItems); 1314 break; 1315 case LongInfo.tag : // 5 1316 info = new LongInfo(in, numOfItems); 1317 break; 1318 case DoubleInfo.tag : // 6 1319 info = new DoubleInfo(in, numOfItems); 1320 break; 1321 case ClassInfo.tag : // 7 1322 info = new ClassInfo(in, numOfItems); 1323 break; 1324 case StringInfo.tag : // 8 1325 info = new StringInfo(in, numOfItems); 1326 break; 1327 case FieldrefInfo.tag : // 9 1328 info = new FieldrefInfo(in, numOfItems); 1329 break; 1330 case MethodrefInfo.tag : // 10 1331 info = new MethodrefInfo(in, numOfItems); 1332 break; 1333 case InterfaceMethodrefInfo.tag : // 11 1334 info = new InterfaceMethodrefInfo(in, numOfItems); 1335 break; 1336 case NameAndTypeInfo.tag : // 12 1337 info = new NameAndTypeInfo(in, numOfItems); 1338 break; 1339 case MethodHandleInfo.tag : // 15 1340 info = new MethodHandleInfo(in, numOfItems); 1341 break; 1342 case MethodTypeInfo.tag : // 16 1343 info = new MethodTypeInfo(in, numOfItems); 1344 break; 1345 case InvokeDynamicInfo.tag : // 18 1346 info = new InvokeDynamicInfo(in, numOfItems); 1347 break; 1348 case ModuleInfo.tag : // 19 1349 info = new ModuleInfo(in, numOfItems); 1350 break; 1351 case PackageInfo.tag : // 20 1352 info = new PackageInfo(in, numOfItems); 1353 break; 1354 default : 1355 throw new IOException("invalid constant type: " 1356 + tag + " at " + numOfItems); 1357 } 1358 1359 addItem0(info); 1360 return tag; 1361 } 1362 1363 /** 1364 * Writes the contents of the constant pool table. 1365 */ write(DataOutputStream out)1366 public void write(DataOutputStream out) throws IOException 1367 { 1368 out.writeShort(numOfItems); 1369 LongVector v = items; 1370 int size = numOfItems; 1371 for (int i = 1; i < size; ++i) 1372 v.elementAt(i).write(out); 1373 } 1374 1375 /** 1376 * Prints the contents of the constant pool table. 1377 */ print()1378 public void print() 1379 { 1380 print(new PrintWriter(System.out, true)); 1381 } 1382 1383 /** 1384 * Prints the contents of the constant pool table. 1385 */ print(PrintWriter out)1386 public void print(PrintWriter out) 1387 { 1388 int size = numOfItems; 1389 for (int i = 1; i < size; ++i) { 1390 out.print(i); 1391 out.print(" "); 1392 items.elementAt(i).print(out); 1393 } 1394 } 1395 } 1396 1397 abstract class ConstInfo 1398 { 1399 int index; 1400 ConstInfo(int i)1401 public ConstInfo(int i) { index = i; } 1402 getTag()1403 public abstract int getTag(); 1404 getClassName(ConstPool cp)1405 public String getClassName(ConstPool cp) { return null; } renameClass(ConstPool cp, String oldName, String newName, Map<ConstInfo,ConstInfo> cache)1406 public void renameClass(ConstPool cp, String oldName, String newName, 1407 Map<ConstInfo,ConstInfo> cache) {} renameClass(ConstPool cp, Map<String,String> classnames, Map<ConstInfo,ConstInfo> cache)1408 public void renameClass(ConstPool cp, Map<String,String> classnames, 1409 Map<ConstInfo,ConstInfo> cache) {} copy(ConstPool src, ConstPool dest, Map<String, String> classnames)1410 public abstract int copy(ConstPool src, ConstPool dest, 1411 Map<String, String> classnames); 1412 // ** classnames is a mapping between JVM names. 1413 write(DataOutputStream out)1414 public abstract void write(DataOutputStream out) throws IOException; print(PrintWriter out)1415 public abstract void print(PrintWriter out); 1416 1417 @Override toString()1418 public String toString() { 1419 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 1420 PrintWriter out = new PrintWriter(bout); 1421 print(out); 1422 return bout.toString(); 1423 } 1424 } 1425 1426 /* padding following DoubleInfo or LongInfo. 1427 */ 1428 class ConstInfoPadding extends ConstInfo 1429 { ConstInfoPadding(int i)1430 public ConstInfoPadding(int i) { super(i); } 1431 1432 @Override getTag()1433 public int getTag() { return 0; } 1434 1435 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)1436 public int copy(ConstPool src, ConstPool dest, Map<String,String> map) 1437 { 1438 return dest.addConstInfoPadding(); 1439 } 1440 1441 @Override write(DataOutputStream out)1442 public void write(DataOutputStream out) throws IOException {} 1443 1444 @Override print(PrintWriter out)1445 public void print(PrintWriter out) 1446 { 1447 out.println("padding"); 1448 } 1449 } 1450 1451 class ClassInfo extends ConstInfo 1452 { 1453 static final int tag = 7; 1454 int name; 1455 ClassInfo(int className, int index)1456 public ClassInfo(int className, int index) 1457 { 1458 super(index); 1459 name = className; 1460 } 1461 ClassInfo(DataInputStream in, int index)1462 public ClassInfo(DataInputStream in, int index) throws IOException 1463 { 1464 super(index); 1465 name = in.readUnsignedShort(); 1466 } 1467 1468 @Override hashCode()1469 public int hashCode() { return name; } 1470 1471 @Override equals(Object obj)1472 public boolean equals(Object obj) 1473 { 1474 return obj instanceof ClassInfo && ((ClassInfo)obj).name == name; 1475 } 1476 1477 @Override getTag()1478 public int getTag() { return tag; } 1479 1480 @Override getClassName(ConstPool cp)1481 public String getClassName(ConstPool cp) 1482 { 1483 return cp.getUtf8Info(name); 1484 } 1485 1486 @Override renameClass(ConstPool cp, String oldName, String newName, Map<ConstInfo,ConstInfo> cache)1487 public void renameClass(ConstPool cp, String oldName, String newName, 1488 Map<ConstInfo,ConstInfo> cache) 1489 { 1490 String nameStr = cp.getUtf8Info(name); 1491 String newNameStr = null; 1492 if (nameStr.equals(oldName)) 1493 newNameStr = newName; 1494 else if (nameStr.charAt(0) == '[') { 1495 String s = Descriptor.rename(nameStr, oldName, newName); 1496 if (nameStr != s) 1497 newNameStr = s; 1498 } 1499 1500 if (newNameStr != null) 1501 if (cache == null) 1502 name = cp.addUtf8Info(newNameStr); 1503 else { 1504 cache.remove(this); 1505 name = cp.addUtf8Info(newNameStr); 1506 cache.put(this, this); 1507 } 1508 } 1509 1510 @Override renameClass(ConstPool cp, Map<String,String> map, Map<ConstInfo,ConstInfo> cache)1511 public void renameClass(ConstPool cp, Map<String,String> map, 1512 Map<ConstInfo,ConstInfo> cache) 1513 { 1514 String oldName = cp.getUtf8Info(name); 1515 String newName = null; 1516 if (oldName.charAt(0) == '[') { 1517 String s = Descriptor.rename(oldName, map); 1518 if (oldName != s) 1519 newName = s; 1520 } 1521 else { 1522 String s = map.get(oldName); 1523 if (s != null && !s.equals(oldName)) 1524 newName = s; 1525 } 1526 1527 if (newName != null) { 1528 if (cache == null) 1529 name = cp.addUtf8Info(newName); 1530 else { 1531 cache.remove(this); 1532 name = cp.addUtf8Info(newName); 1533 cache.put(this, this); 1534 } 1535 } 1536 } 1537 1538 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)1539 public int copy(ConstPool src, ConstPool dest, Map<String,String> map) 1540 { 1541 String classname = src.getUtf8Info(name); 1542 if (map != null) { 1543 String newname = map.get(classname); 1544 if (newname != null) 1545 classname = newname; 1546 } 1547 1548 return dest.addClassInfo(classname); 1549 } 1550 1551 @Override write(DataOutputStream out)1552 public void write(DataOutputStream out) throws IOException 1553 { 1554 out.writeByte(tag); 1555 out.writeShort(name); 1556 } 1557 1558 @Override print(PrintWriter out)1559 public void print(PrintWriter out) 1560 { 1561 out.print("Class #"); 1562 out.println(name); 1563 } 1564 } 1565 1566 class NameAndTypeInfo extends ConstInfo 1567 { 1568 static final int tag = 12; 1569 int memberName; 1570 int typeDescriptor; 1571 NameAndTypeInfo(int name, int type, int index)1572 public NameAndTypeInfo(int name, int type, int index) 1573 { 1574 super(index); 1575 memberName = name; 1576 typeDescriptor = type; 1577 } 1578 NameAndTypeInfo(DataInputStream in, int index)1579 public NameAndTypeInfo(DataInputStream in, int index) throws IOException 1580 { 1581 super(index); 1582 memberName = in.readUnsignedShort(); 1583 typeDescriptor = in.readUnsignedShort(); 1584 } 1585 1586 @Override hashCode()1587 public int hashCode() { return (memberName << 16) ^ typeDescriptor; } 1588 1589 @Override equals(Object obj)1590 public boolean equals(Object obj) 1591 { 1592 if (obj instanceof NameAndTypeInfo) { 1593 NameAndTypeInfo nti = (NameAndTypeInfo)obj; 1594 return nti.memberName == memberName 1595 && nti.typeDescriptor == typeDescriptor; 1596 } 1597 return false; 1598 } 1599 1600 @Override getTag()1601 public int getTag() { return tag; } 1602 1603 @Override renameClass(ConstPool cp, String oldName, String newName, Map<ConstInfo,ConstInfo> cache)1604 public void renameClass(ConstPool cp, String oldName, String newName, 1605 Map<ConstInfo,ConstInfo> cache) 1606 { 1607 String type = cp.getUtf8Info(typeDescriptor); 1608 String type2 = Descriptor.rename(type, oldName, newName); 1609 if (type != type2) 1610 if (cache == null) 1611 typeDescriptor = cp.addUtf8Info(type2); 1612 else { 1613 cache.remove(this); 1614 typeDescriptor = cp.addUtf8Info(type2); 1615 cache.put(this, this); 1616 } 1617 } 1618 1619 @Override renameClass(ConstPool cp, Map<String,String> map, Map<ConstInfo,ConstInfo> cache)1620 public void renameClass(ConstPool cp, Map<String,String> map, 1621 Map<ConstInfo,ConstInfo> cache) 1622 { 1623 String type = cp.getUtf8Info(typeDescriptor); 1624 String type2 = Descriptor.rename(type, map); 1625 if (type != type2) 1626 if (cache == null) 1627 typeDescriptor = cp.addUtf8Info(type2); 1628 else { 1629 cache.remove(this); 1630 typeDescriptor = cp.addUtf8Info(type2); 1631 cache.put(this, this); 1632 } 1633 } 1634 1635 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)1636 public int copy(ConstPool src, ConstPool dest, Map<String,String> map) 1637 { 1638 String mname = src.getUtf8Info(memberName); 1639 String tdesc = src.getUtf8Info(typeDescriptor); 1640 tdesc = Descriptor.rename(tdesc, map); 1641 return dest.addNameAndTypeInfo(dest.addUtf8Info(mname), 1642 dest.addUtf8Info(tdesc)); 1643 } 1644 1645 @Override write(DataOutputStream out)1646 public void write(DataOutputStream out) throws IOException { 1647 out.writeByte(tag); 1648 out.writeShort(memberName); 1649 out.writeShort(typeDescriptor); 1650 } 1651 1652 @Override print(PrintWriter out)1653 public void print(PrintWriter out) { 1654 out.print("NameAndType #"); 1655 out.print(memberName); 1656 out.print(", type #"); 1657 out.println(typeDescriptor); 1658 } 1659 } 1660 1661 abstract class MemberrefInfo extends ConstInfo 1662 { 1663 int classIndex; 1664 int nameAndTypeIndex; 1665 MemberrefInfo(int cindex, int ntindex, int thisIndex)1666 public MemberrefInfo(int cindex, int ntindex, int thisIndex) 1667 { 1668 super(thisIndex); 1669 classIndex = cindex; 1670 nameAndTypeIndex = ntindex; 1671 } 1672 MemberrefInfo(DataInputStream in, int thisIndex)1673 public MemberrefInfo(DataInputStream in, int thisIndex) 1674 throws IOException 1675 { 1676 super(thisIndex); 1677 classIndex = in.readUnsignedShort(); 1678 nameAndTypeIndex = in.readUnsignedShort(); 1679 } 1680 1681 @Override hashCode()1682 public int hashCode() { return (classIndex << 16) ^ nameAndTypeIndex; } 1683 1684 @Override equals(Object obj)1685 public boolean equals(Object obj) { 1686 if (obj instanceof MemberrefInfo) { 1687 MemberrefInfo mri = (MemberrefInfo)obj; 1688 return mri.classIndex == classIndex 1689 && mri.nameAndTypeIndex == nameAndTypeIndex 1690 && mri.getClass() == this.getClass(); 1691 } 1692 return false; 1693 } 1694 1695 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)1696 public int copy(ConstPool src, ConstPool dest, Map<String,String> map) 1697 { 1698 int classIndex2 = src.getItem(classIndex).copy(src, dest, map); 1699 int ntIndex2 = src.getItem(nameAndTypeIndex).copy(src, dest, map); 1700 return copy2(dest, classIndex2, ntIndex2); 1701 } 1702 copy2(ConstPool dest, int cindex, int ntindex)1703 abstract protected int copy2(ConstPool dest, int cindex, int ntindex); 1704 1705 @Override write(DataOutputStream out)1706 public void write(DataOutputStream out) throws IOException 1707 { 1708 out.writeByte(getTag()); 1709 out.writeShort(classIndex); 1710 out.writeShort(nameAndTypeIndex); 1711 } 1712 1713 @Override print(PrintWriter out)1714 public void print(PrintWriter out) 1715 { 1716 out.print(getTagName() + " #"); 1717 out.print(classIndex); 1718 out.print(", name&type #"); 1719 out.println(nameAndTypeIndex); 1720 } 1721 getTagName()1722 public abstract String getTagName(); 1723 } 1724 1725 class FieldrefInfo extends MemberrefInfo 1726 { 1727 static final int tag = 9; 1728 FieldrefInfo(int cindex, int ntindex, int thisIndex)1729 public FieldrefInfo(int cindex, int ntindex, int thisIndex) 1730 { 1731 super(cindex, ntindex, thisIndex); 1732 } 1733 FieldrefInfo(DataInputStream in, int thisIndex)1734 public FieldrefInfo(DataInputStream in, int thisIndex) 1735 throws IOException 1736 { 1737 super(in, thisIndex); 1738 } 1739 1740 @Override getTag()1741 public int getTag() { return tag; } 1742 1743 @Override getTagName()1744 public String getTagName() { return "Field"; } 1745 1746 @Override copy2(ConstPool dest, int cindex, int ntindex)1747 protected int copy2(ConstPool dest, int cindex, int ntindex) 1748 { 1749 return dest.addFieldrefInfo(cindex, ntindex); 1750 } 1751 } 1752 1753 class MethodrefInfo extends MemberrefInfo 1754 { 1755 static final int tag = 10; 1756 MethodrefInfo(int cindex, int ntindex, int thisIndex)1757 public MethodrefInfo(int cindex, int ntindex, int thisIndex) 1758 { 1759 super(cindex, ntindex, thisIndex); 1760 } 1761 MethodrefInfo(DataInputStream in, int thisIndex)1762 public MethodrefInfo(DataInputStream in, int thisIndex) 1763 throws IOException 1764 { 1765 super(in, thisIndex); 1766 } 1767 1768 @Override getTag()1769 public int getTag() { return tag; } 1770 1771 @Override getTagName()1772 public String getTagName() { return "Method"; } 1773 1774 @Override copy2(ConstPool dest, int cindex, int ntindex)1775 protected int copy2(ConstPool dest, int cindex, int ntindex) 1776 { 1777 return dest.addMethodrefInfo(cindex, ntindex); 1778 } 1779 } 1780 1781 class InterfaceMethodrefInfo extends MemberrefInfo 1782 { 1783 static final int tag = 11; 1784 InterfaceMethodrefInfo(int cindex, int ntindex, int thisIndex)1785 public InterfaceMethodrefInfo(int cindex, int ntindex, int thisIndex) 1786 { 1787 super(cindex, ntindex, thisIndex); 1788 } 1789 InterfaceMethodrefInfo(DataInputStream in, int thisIndex)1790 public InterfaceMethodrefInfo(DataInputStream in, int thisIndex) 1791 throws IOException 1792 { 1793 super(in, thisIndex); 1794 } 1795 1796 @Override getTag()1797 public int getTag() { return tag; } 1798 1799 @Override getTagName()1800 public String getTagName() { return "Interface"; } 1801 1802 @Override copy2(ConstPool dest, int cindex, int ntindex)1803 protected int copy2(ConstPool dest, int cindex, int ntindex) 1804 { 1805 return dest.addInterfaceMethodrefInfo(cindex, ntindex); 1806 } 1807 } 1808 1809 class StringInfo extends ConstInfo 1810 { 1811 static final int tag = 8; 1812 int string; 1813 StringInfo(int str, int index)1814 public StringInfo(int str, int index) 1815 { 1816 super(index); 1817 string = str; 1818 } 1819 StringInfo(DataInputStream in, int index)1820 public StringInfo(DataInputStream in, int index) throws IOException 1821 { 1822 super(index); 1823 string = in.readUnsignedShort(); 1824 } 1825 1826 @Override hashCode()1827 public int hashCode() { return string; } 1828 1829 @Override equals(Object obj)1830 public boolean equals(Object obj) 1831 { 1832 return obj instanceof StringInfo && ((StringInfo)obj).string == string; 1833 } 1834 1835 @Override getTag()1836 public int getTag() { return tag; } 1837 1838 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)1839 public int copy(ConstPool src, ConstPool dest, Map<String,String> map) 1840 { 1841 return dest.addStringInfo(src.getUtf8Info(string)); 1842 } 1843 1844 @Override write(DataOutputStream out)1845 public void write(DataOutputStream out) throws IOException 1846 { 1847 out.writeByte(tag); 1848 out.writeShort(string); 1849 } 1850 1851 @Override print(PrintWriter out)1852 public void print(PrintWriter out) 1853 { 1854 out.print("String #"); 1855 out.println(string); 1856 } 1857 } 1858 1859 class IntegerInfo extends ConstInfo 1860 { 1861 static final int tag = 3; 1862 int value; 1863 IntegerInfo(int v, int index)1864 public IntegerInfo(int v, int index) 1865 { 1866 super(index); 1867 value = v; 1868 } 1869 IntegerInfo(DataInputStream in, int index)1870 public IntegerInfo(DataInputStream in, int index) throws IOException 1871 { 1872 super(index); 1873 value = in.readInt(); 1874 } 1875 1876 @Override hashCode()1877 public int hashCode() { return value; } 1878 1879 @Override equals(Object obj)1880 public boolean equals(Object obj) 1881 { 1882 return obj instanceof IntegerInfo && ((IntegerInfo)obj).value == value; 1883 } 1884 1885 @Override getTag()1886 public int getTag() { return tag; } 1887 1888 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)1889 public int copy(ConstPool src, ConstPool dest, Map<String,String> map) 1890 { 1891 return dest.addIntegerInfo(value); 1892 } 1893 1894 @Override write(DataOutputStream out)1895 public void write(DataOutputStream out) throws IOException 1896 { 1897 out.writeByte(tag); 1898 out.writeInt(value); 1899 } 1900 1901 @Override print(PrintWriter out)1902 public void print(PrintWriter out) 1903 { 1904 out.print("Integer "); 1905 out.println(value); 1906 } 1907 } 1908 1909 class FloatInfo extends ConstInfo 1910 { 1911 static final int tag = 4; 1912 float value; 1913 FloatInfo(float f, int index)1914 public FloatInfo(float f, int index) 1915 { 1916 super(index); 1917 value = f; 1918 } 1919 FloatInfo(DataInputStream in, int index)1920 public FloatInfo(DataInputStream in, int index) throws IOException 1921 { 1922 super(index); 1923 value = in.readFloat(); 1924 } 1925 1926 @Override hashCode()1927 public int hashCode() { return Float.floatToIntBits(value); } 1928 1929 @Override equals(Object obj)1930 public boolean equals(Object obj) 1931 { 1932 return obj instanceof FloatInfo && ((FloatInfo)obj).value == value; 1933 } 1934 1935 @Override getTag()1936 public int getTag() { return tag; } 1937 1938 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)1939 public int copy(ConstPool src, ConstPool dest, Map<String,String> map) 1940 { 1941 return dest.addFloatInfo(value); 1942 } 1943 1944 @Override write(DataOutputStream out)1945 public void write(DataOutputStream out) throws IOException 1946 { 1947 out.writeByte(tag); 1948 out.writeFloat(value); 1949 } 1950 1951 @Override print(PrintWriter out)1952 public void print(PrintWriter out) 1953 { 1954 out.print("Float "); 1955 out.println(value); 1956 } 1957 } 1958 1959 class LongInfo extends ConstInfo 1960 { 1961 static final int tag = 5; 1962 long value; 1963 LongInfo(long l, int index)1964 public LongInfo(long l, int index) 1965 { 1966 super(index); 1967 value = l; 1968 } 1969 LongInfo(DataInputStream in, int index)1970 public LongInfo(DataInputStream in, int index) throws IOException 1971 { 1972 super(index); 1973 value = in.readLong(); 1974 } 1975 1976 @Override hashCode()1977 public int hashCode() { return (int)(value ^ (value >>> 32)); } 1978 1979 @Override equals(Object obj)1980 public boolean equals(Object obj) { 1981 return obj instanceof LongInfo && ((LongInfo)obj).value == value; 1982 } 1983 1984 @Override getTag()1985 public int getTag() { return tag; } 1986 1987 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)1988 public int copy(ConstPool src, ConstPool dest, Map<String,String> map) 1989 { 1990 return dest.addLongInfo(value); 1991 } 1992 1993 @Override write(DataOutputStream out)1994 public void write(DataOutputStream out) throws IOException 1995 { 1996 out.writeByte(tag); 1997 out.writeLong(value); 1998 } 1999 2000 @Override print(PrintWriter out)2001 public void print(PrintWriter out) 2002 { 2003 out.print("Long "); 2004 out.println(value); 2005 } 2006 } 2007 2008 class DoubleInfo extends ConstInfo 2009 { 2010 static final int tag = 6; 2011 double value; 2012 DoubleInfo(double d, int index)2013 public DoubleInfo(double d, int index) 2014 { 2015 super(index); 2016 value = d; 2017 } 2018 DoubleInfo(DataInputStream in, int index)2019 public DoubleInfo(DataInputStream in, int index) throws IOException 2020 { 2021 super(index); 2022 value = in.readDouble(); 2023 } 2024 2025 @Override hashCode()2026 public int hashCode() { 2027 long v = Double.doubleToLongBits(value); 2028 return (int)(v ^ (v >>> 32)); 2029 } 2030 2031 @Override equals(Object obj)2032 public boolean equals(Object obj) 2033 { 2034 return obj instanceof DoubleInfo 2035 && ((DoubleInfo)obj).value == value; 2036 } 2037 2038 @Override getTag()2039 public int getTag() { return tag; } 2040 2041 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)2042 public int copy(ConstPool src, ConstPool dest, Map<String,String> map) 2043 { 2044 return dest.addDoubleInfo(value); 2045 } 2046 2047 @Override write(DataOutputStream out)2048 public void write(DataOutputStream out) throws IOException 2049 { 2050 out.writeByte(tag); 2051 out.writeDouble(value); 2052 } 2053 2054 @Override print(PrintWriter out)2055 public void print(PrintWriter out) 2056 { 2057 out.print("Double "); 2058 out.println(value); 2059 } 2060 } 2061 2062 class Utf8Info extends ConstInfo 2063 { 2064 static final int tag = 1; 2065 String string; 2066 Utf8Info(String utf8, int index)2067 public Utf8Info(String utf8, int index) 2068 { 2069 super(index); 2070 string = utf8; 2071 } 2072 Utf8Info(DataInputStream in, int index)2073 public Utf8Info(DataInputStream in, int index) 2074 throws IOException 2075 { 2076 super(index); 2077 string = in.readUTF(); 2078 } 2079 2080 @Override hashCode()2081 public int hashCode() { 2082 return string.hashCode(); 2083 } 2084 2085 @Override equals(Object obj)2086 public boolean equals(Object obj) { 2087 return obj instanceof Utf8Info 2088 && ((Utf8Info)obj).string.equals(string); 2089 } 2090 2091 @Override getTag()2092 public int getTag() { return tag; } 2093 2094 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)2095 public int copy(ConstPool src, ConstPool dest, 2096 Map<String,String> map) 2097 { 2098 return dest.addUtf8Info(string); 2099 } 2100 2101 @Override write(DataOutputStream out)2102 public void write(DataOutputStream out) 2103 throws IOException 2104 { 2105 out.writeByte(tag); 2106 out.writeUTF(string); 2107 } 2108 2109 @Override print(PrintWriter out)2110 public void print(PrintWriter out) { 2111 out.print("UTF8 \""); 2112 out.print(string); 2113 out.println("\""); 2114 } 2115 } 2116 2117 class MethodHandleInfo extends ConstInfo { 2118 static final int tag = 15; 2119 int refKind, refIndex; 2120 MethodHandleInfo(int kind, int referenceIndex, int index)2121 public MethodHandleInfo(int kind, int referenceIndex, int index) { 2122 super(index); 2123 refKind = kind; 2124 refIndex = referenceIndex; 2125 } 2126 MethodHandleInfo(DataInputStream in, int index)2127 public MethodHandleInfo(DataInputStream in, int index) 2128 throws IOException 2129 { 2130 super(index); 2131 refKind = in.readUnsignedByte(); 2132 refIndex = in.readUnsignedShort(); 2133 } 2134 2135 @Override hashCode()2136 public int hashCode() { return (refKind << 16) ^ refIndex; } 2137 2138 @Override equals(Object obj)2139 public boolean equals(Object obj) 2140 { 2141 if (obj instanceof MethodHandleInfo) { 2142 MethodHandleInfo mh = (MethodHandleInfo)obj; 2143 return mh.refKind == refKind && mh.refIndex == refIndex; 2144 } 2145 return false; 2146 } 2147 2148 @Override getTag()2149 public int getTag() { return tag; } 2150 2151 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)2152 public int copy(ConstPool src, ConstPool dest, 2153 Map<String,String> map) 2154 { 2155 return dest.addMethodHandleInfo(refKind, 2156 src.getItem(refIndex).copy(src, dest, map)); 2157 } 2158 2159 @Override write(DataOutputStream out)2160 public void write(DataOutputStream out) throws IOException 2161 { 2162 out.writeByte(tag); 2163 out.writeByte(refKind); 2164 out.writeShort(refIndex); 2165 } 2166 2167 @Override print(PrintWriter out)2168 public void print(PrintWriter out) { 2169 out.print("MethodHandle #"); 2170 out.print(refKind); 2171 out.print(", index #"); 2172 out.println(refIndex); 2173 } 2174 } 2175 2176 class MethodTypeInfo extends ConstInfo 2177 { 2178 static final int tag = 16; 2179 int descriptor; 2180 MethodTypeInfo(int desc, int index)2181 public MethodTypeInfo(int desc, int index) 2182 { 2183 super(index); 2184 descriptor = desc; 2185 } 2186 MethodTypeInfo(DataInputStream in, int index)2187 public MethodTypeInfo(DataInputStream in, int index) 2188 throws IOException 2189 { 2190 super(index); 2191 descriptor = in.readUnsignedShort(); 2192 } 2193 2194 @Override hashCode()2195 public int hashCode() { return descriptor; } 2196 2197 @Override equals(Object obj)2198 public boolean equals(Object obj) 2199 { 2200 if (obj instanceof MethodTypeInfo) 2201 return ((MethodTypeInfo)obj).descriptor == descriptor; 2202 return false; 2203 } 2204 2205 @Override getTag()2206 public int getTag() { return tag; } 2207 2208 @Override renameClass(ConstPool cp, String oldName, String newName, Map<ConstInfo,ConstInfo> cache)2209 public void renameClass(ConstPool cp, String oldName, String newName, 2210 Map<ConstInfo,ConstInfo> cache) 2211 { 2212 String desc = cp.getUtf8Info(descriptor); 2213 String desc2 = Descriptor.rename(desc, oldName, newName); 2214 if (desc != desc2) 2215 if (cache == null) 2216 descriptor = cp.addUtf8Info(desc2); 2217 else { 2218 cache.remove(this); 2219 descriptor = cp.addUtf8Info(desc2); 2220 cache.put(this, this); 2221 } 2222 } 2223 2224 @Override renameClass(ConstPool cp, Map<String,String> map, Map<ConstInfo,ConstInfo> cache)2225 public void renameClass(ConstPool cp, Map<String,String> map, 2226 Map<ConstInfo,ConstInfo> cache) 2227 { 2228 String desc = cp.getUtf8Info(descriptor); 2229 String desc2 = Descriptor.rename(desc, map); 2230 if (desc != desc2) 2231 if (cache == null) 2232 descriptor = cp.addUtf8Info(desc2); 2233 else { 2234 cache.remove(this); 2235 descriptor = cp.addUtf8Info(desc2); 2236 cache.put(this, this); 2237 } 2238 } 2239 2240 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)2241 public int copy(ConstPool src, ConstPool dest, Map<String,String> map) 2242 { 2243 String desc = src.getUtf8Info(descriptor); 2244 desc = Descriptor.rename(desc, map); 2245 return dest.addMethodTypeInfo(dest.addUtf8Info(desc)); 2246 } 2247 2248 @Override write(DataOutputStream out)2249 public void write(DataOutputStream out) throws IOException 2250 { 2251 out.writeByte(tag); 2252 out.writeShort(descriptor); 2253 } 2254 2255 @Override print(PrintWriter out)2256 public void print(PrintWriter out) { 2257 out.print("MethodType #"); 2258 out.println(descriptor); 2259 } 2260 } 2261 2262 class InvokeDynamicInfo extends ConstInfo 2263 { 2264 static final int tag = 18; 2265 int bootstrap, nameAndType; 2266 InvokeDynamicInfo(int bootstrapMethod, int ntIndex, int index)2267 public InvokeDynamicInfo(int bootstrapMethod, 2268 int ntIndex, int index) 2269 { 2270 super(index); 2271 bootstrap = bootstrapMethod; 2272 nameAndType = ntIndex; 2273 } 2274 InvokeDynamicInfo(DataInputStream in, int index)2275 public InvokeDynamicInfo(DataInputStream in, int index) 2276 throws IOException 2277 { 2278 super(index); 2279 bootstrap = in.readUnsignedShort(); 2280 nameAndType = in.readUnsignedShort(); 2281 } 2282 2283 @Override hashCode()2284 public int hashCode() { return (bootstrap << 16) ^ nameAndType; } 2285 2286 @Override equals(Object obj)2287 public boolean equals(Object obj) 2288 { 2289 if (obj instanceof InvokeDynamicInfo) { 2290 InvokeDynamicInfo iv = (InvokeDynamicInfo)obj; 2291 return iv.bootstrap == bootstrap 2292 && iv.nameAndType == nameAndType; 2293 } 2294 return false; 2295 } 2296 2297 @Override getTag()2298 public int getTag() { return tag; } 2299 2300 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)2301 public int copy(ConstPool src, ConstPool dest, 2302 Map<String,String> map) 2303 { 2304 return dest.addInvokeDynamicInfo(bootstrap, 2305 src.getItem(nameAndType).copy(src, dest, map)); 2306 } 2307 2308 @Override write(DataOutputStream out)2309 public void write(DataOutputStream out) throws IOException 2310 { 2311 out.writeByte(tag); 2312 out.writeShort(bootstrap); 2313 out.writeShort(nameAndType); 2314 } 2315 2316 @Override print(PrintWriter out)2317 public void print(PrintWriter out) { 2318 out.print("InvokeDynamic #"); 2319 out.print(bootstrap); 2320 out.print(", name&type #"); 2321 out.println(nameAndType); 2322 } 2323 } 2324 2325 class ModuleInfo extends ConstInfo 2326 { 2327 static final int tag = 19; 2328 int name; 2329 ModuleInfo(int moduleName, int index)2330 public ModuleInfo(int moduleName, int index) 2331 { 2332 super(index); 2333 name = moduleName; 2334 } 2335 ModuleInfo(DataInputStream in, int index)2336 public ModuleInfo(DataInputStream in, int index) 2337 throws IOException 2338 { 2339 super(index); 2340 name = in.readUnsignedShort(); 2341 } 2342 2343 @Override hashCode()2344 public int hashCode() { return name; } 2345 2346 @Override equals(Object obj)2347 public boolean equals(Object obj) 2348 { 2349 return obj instanceof ModuleInfo 2350 && ((ModuleInfo)obj).name == name; 2351 } 2352 2353 @Override getTag()2354 public int getTag() { return tag; } 2355 getModuleName(ConstPool cp)2356 public String getModuleName(ConstPool cp) 2357 { 2358 return cp.getUtf8Info(name); 2359 } 2360 2361 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)2362 public int copy(ConstPool src, ConstPool dest, 2363 Map<String,String> map) 2364 { 2365 String moduleName = src.getUtf8Info(name); 2366 int newName = dest.addUtf8Info(moduleName); 2367 return dest.addModuleInfo(newName); 2368 } 2369 2370 @Override write(DataOutputStream out)2371 public void write(DataOutputStream out) throws IOException 2372 { 2373 out.writeByte(tag); 2374 out.writeShort(name); 2375 } 2376 2377 @Override print(PrintWriter out)2378 public void print(PrintWriter out) { 2379 out.print("Module #"); 2380 out.println(name); 2381 } 2382 } 2383 2384 class PackageInfo extends ConstInfo 2385 { 2386 static final int tag = 20; 2387 int name; 2388 PackageInfo(int moduleName, int index)2389 public PackageInfo(int moduleName, int index) 2390 { 2391 super(index); 2392 name = moduleName; 2393 } 2394 PackageInfo(DataInputStream in, int index)2395 public PackageInfo(DataInputStream in, int index) 2396 throws IOException 2397 { 2398 super(index); 2399 name = in.readUnsignedShort(); 2400 } 2401 2402 @Override hashCode()2403 public int hashCode() { return name; } 2404 2405 @Override equals(Object obj)2406 public boolean equals(Object obj) { 2407 return obj instanceof PackageInfo 2408 && ((PackageInfo)obj).name == name; 2409 } 2410 2411 @Override getTag()2412 public int getTag() { return tag; } 2413 getPackageName(ConstPool cp)2414 public String getPackageName(ConstPool cp) 2415 { 2416 return cp.getUtf8Info(name); 2417 } 2418 2419 @Override copy(ConstPool src, ConstPool dest, Map<String,String> map)2420 public int copy(ConstPool src, ConstPool dest, 2421 Map<String,String> map) 2422 { 2423 String packageName = src.getUtf8Info(name); 2424 int newName = dest.addUtf8Info(packageName); 2425 return dest.addModuleInfo(newName); 2426 } 2427 2428 @Override write(DataOutputStream out)2429 public void write(DataOutputStream out) throws IOException 2430 { 2431 out.writeByte(tag); 2432 out.writeShort(name); 2433 } 2434 2435 @Override print(PrintWriter out)2436 public void print(PrintWriter out) 2437 { 2438 out.print("Package #"); 2439 out.println(name); 2440 } 2441 } 2442