1 /* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 package proguard.classfile.editor; 22 23 import proguard.classfile.*; 24 import proguard.classfile.constant.*; 25 26 /** 27 * This class can add constant pool entries to a given class. 28 * 29 * @author Eric Lafortune 30 */ 31 public class ConstantPoolEditor 32 { 33 private static final boolean DEBUG = false; 34 35 private ProgramClass targetClass; 36 37 38 /** 39 * Creates a new ConstantPoolEditor that will edit constants in the given 40 * target class. 41 */ ConstantPoolEditor(ProgramClass targetClass)42 public ConstantPoolEditor(ProgramClass targetClass) 43 { 44 this.targetClass = targetClass; 45 } 46 47 48 /** 49 * Finds or creates a IntegerConstant constant pool entry with the given 50 * value. 51 * @return the constant pool index of the Utf8Constant. 52 */ addIntegerConstant(int value)53 public int addIntegerConstant(int value) 54 { 55 int constantPoolCount = targetClass.u2constantPoolCount; 56 Constant[] constantPool = targetClass.constantPool; 57 58 // Check if the entry already exists. 59 for (int index = 1; index < constantPoolCount; index++) 60 { 61 Constant constant = constantPool[index]; 62 63 if (constant != null && 64 constant.getTag() == ClassConstants.CONSTANT_Integer) 65 { 66 IntegerConstant integerConstant = (IntegerConstant)constant; 67 if (integerConstant.getValue() == value) 68 { 69 return index; 70 } 71 } 72 } 73 74 return addConstant(new IntegerConstant(value)); 75 } 76 77 78 /** 79 * Finds or creates a LongConstant constant pool entry with the given value. 80 * @return the constant pool index of the LongConstant. 81 */ addLongConstant(long value)82 public int addLongConstant(long value) 83 { 84 int constantPoolCount = targetClass.u2constantPoolCount; 85 Constant[] constantPool = targetClass.constantPool; 86 87 // Check if the entry already exists. 88 for (int index = 1; index < constantPoolCount; index++) 89 { 90 Constant constant = constantPool[index]; 91 92 if (constant != null && 93 constant.getTag() == ClassConstants.CONSTANT_Long) 94 { 95 LongConstant longConstant = (LongConstant)constant; 96 if (longConstant.getValue() == value) 97 { 98 return index; 99 } 100 } 101 } 102 103 return addConstant(new LongConstant(value)); 104 } 105 106 107 /** 108 * Finds or creates a FloatConstant constant pool entry with the given 109 * value. 110 * @return the constant pool index of the FloatConstant. 111 */ addFloatConstant(float value)112 public int addFloatConstant(float value) 113 { 114 int constantPoolCount = targetClass.u2constantPoolCount; 115 Constant[] constantPool = targetClass.constantPool; 116 117 // Check if the entry already exists. 118 for (int index = 1; index < constantPoolCount; index++) 119 { 120 Constant constant = constantPool[index]; 121 122 if (constant != null && 123 constant.getTag() == ClassConstants.CONSTANT_Float) 124 { 125 FloatConstant floatConstant = (FloatConstant)constant; 126 if (floatConstant.getValue() == value) 127 { 128 return index; 129 } 130 } 131 } 132 133 return addConstant(new FloatConstant(value)); 134 } 135 136 137 /** 138 * Finds or creates a DoubleConstant constant pool entry with the given 139 * value. 140 * @return the constant pool index of the DoubleConstant. 141 */ addDoubleConstant(double value)142 public int addDoubleConstant(double value) 143 { 144 int constantPoolCount = targetClass.u2constantPoolCount; 145 Constant[] constantPool = targetClass.constantPool; 146 147 // Check if the entry already exists. 148 for (int index = 1; index < constantPoolCount; index++) 149 { 150 Constant constant = constantPool[index]; 151 152 if (constant != null && 153 constant.getTag() == ClassConstants.CONSTANT_Double) 154 { 155 DoubleConstant doubleConstant = (DoubleConstant)constant; 156 if (doubleConstant.getValue() == value) 157 { 158 return index; 159 } 160 } 161 } 162 163 return addConstant(new DoubleConstant(value)); 164 } 165 166 167 /** 168 * Finds or creates a StringConstant constant pool entry with the given 169 * value. 170 * @return the constant pool index of the StringConstant. 171 */ addStringConstant(String string, Clazz referencedClass, Member referencedMember)172 public int addStringConstant(String string, 173 Clazz referencedClass, 174 Member referencedMember) 175 { 176 int constantPoolCount = targetClass.u2constantPoolCount; 177 Constant[] constantPool = targetClass.constantPool; 178 179 // Check if the entry already exists. 180 for (int index = 1; index < constantPoolCount; index++) 181 { 182 Constant constant = constantPool[index]; 183 184 if (constant != null && 185 constant.getTag() == ClassConstants.CONSTANT_String) 186 { 187 StringConstant stringConstant = (StringConstant)constant; 188 if (stringConstant.getString(targetClass).equals(string)) 189 { 190 return index; 191 } 192 } 193 } 194 195 return addConstant(new StringConstant(addUtf8Constant(string), 196 referencedClass, 197 referencedMember)); 198 } 199 200 201 /** 202 * Finds or creates a InvokeDynamicConstant constant pool entry with the 203 * given bootstrap method constant pool entry index, method name, and 204 * descriptor. 205 * @return the constant pool index of the InvokeDynamicConstant. 206 */ addInvokeDynamicConstant(int bootstrapMethodIndex, String name, String descriptor, Clazz[] referencedClasses)207 public int addInvokeDynamicConstant(int bootstrapMethodIndex, 208 String name, 209 String descriptor, 210 Clazz[] referencedClasses) 211 { 212 return addInvokeDynamicConstant(bootstrapMethodIndex, 213 addNameAndTypeConstant(name, descriptor), 214 referencedClasses); 215 } 216 217 218 /** 219 * Finds or creates a InvokeDynamicConstant constant pool entry with the given 220 * class constant pool entry index and name and type constant pool entry 221 * index. 222 * @return the constant pool index of the InvokeDynamicConstant. 223 */ addInvokeDynamicConstant(int bootstrapMethodIndex, int nameAndTypeIndex, Clazz[] referencedClasses)224 public int addInvokeDynamicConstant(int bootstrapMethodIndex, 225 int nameAndTypeIndex, 226 Clazz[] referencedClasses) 227 { 228 int constantPoolCount = targetClass.u2constantPoolCount; 229 Constant[] constantPool = targetClass.constantPool; 230 231 // Check if the entry already exists. 232 for (int index = 1; index < constantPoolCount; index++) 233 { 234 Constant constant = constantPool[index]; 235 236 if (constant != null && 237 constant.getTag() == ClassConstants.CONSTANT_InvokeDynamic) 238 { 239 InvokeDynamicConstant invokeDynamicConstant = (InvokeDynamicConstant)constant; 240 if (invokeDynamicConstant.u2bootstrapMethodAttributeIndex == bootstrapMethodIndex && 241 invokeDynamicConstant.u2nameAndTypeIndex == nameAndTypeIndex) 242 { 243 return index; 244 } 245 } 246 } 247 248 return addConstant(new InvokeDynamicConstant(bootstrapMethodIndex, 249 nameAndTypeIndex, 250 referencedClasses)); 251 } 252 253 254 /** 255 * Finds or creates a MethodHandleConstant constant pool entry of the 256 * specified kind and with the given field ref, interface method ref, 257 * or method ref constant pool entry index. 258 * @return the constant pool index of the MethodHandleConstant. 259 */ addMethodHandleConstant(int referenceKind, int referenceIndex)260 public int addMethodHandleConstant(int referenceKind, 261 int referenceIndex) 262 { 263 int constantPoolCount = targetClass.u2constantPoolCount; 264 Constant[] constantPool = targetClass.constantPool; 265 266 // Check if the entry already exists. 267 for (int index = 1; index < constantPoolCount; index++) 268 { 269 Constant constant = constantPool[index]; 270 271 if (constant != null && 272 constant.getTag() == ClassConstants.CONSTANT_MethodHandle) 273 { 274 MethodHandleConstant methodHandleConstant = (MethodHandleConstant)constant; 275 if (methodHandleConstant.u1referenceKind == referenceKind && 276 methodHandleConstant.u2referenceIndex == referenceIndex) 277 { 278 return index; 279 } 280 } 281 } 282 283 return addConstant(new MethodHandleConstant(referenceKind, 284 referenceIndex)); 285 } 286 287 288 /** 289 * Finds or creates a FieldrefConstant constant pool entry for the given 290 * class and field. 291 * @return the constant pool index of the FieldrefConstant. 292 */ addFieldrefConstant(Clazz referencedClass, Member referencedMember)293 public int addFieldrefConstant(Clazz referencedClass, 294 Member referencedMember) 295 { 296 return addFieldrefConstant(referencedClass.getName(), 297 referencedMember.getName(referencedClass), 298 referencedMember.getDescriptor(referencedClass), 299 referencedClass, 300 referencedMember); 301 } 302 303 304 /** 305 * Finds or creates a FieldrefConstant constant pool entry with the given 306 * class name, field name, and descriptor. 307 * @return the constant pool index of the FieldrefConstant. 308 */ addFieldrefConstant(String className, String name, String descriptor, Clazz referencedClass, Member referencedMember)309 public int addFieldrefConstant(String className, 310 String name, 311 String descriptor, 312 Clazz referencedClass, 313 Member referencedMember) 314 { 315 return addFieldrefConstant(className, 316 addNameAndTypeConstant(name, descriptor), 317 referencedClass, 318 referencedMember); 319 } 320 321 322 /** 323 * Finds or creates a FieldrefConstant constant pool entry with the given 324 * class name, field name, and descriptor. 325 * @return the constant pool index of the FieldrefConstant. 326 */ addFieldrefConstant(String className, int nameAndTypeIndex, Clazz referencedClass, Member referencedMember)327 public int addFieldrefConstant(String className, 328 int nameAndTypeIndex, 329 Clazz referencedClass, 330 Member referencedMember) 331 { 332 return addFieldrefConstant(addClassConstant(className, referencedClass), 333 nameAndTypeIndex, 334 referencedClass, 335 referencedMember); 336 } 337 338 339 /** 340 * Finds or creates a FieldrefConstant constant pool entry with the given 341 * class constant pool entry index, field name, and descriptor. 342 * @return the constant pool index of the FieldrefConstant. 343 */ addFieldrefConstant(int classIndex, String name, String descriptor, Clazz referencedClass, Member referencedMember)344 public int addFieldrefConstant(int classIndex, 345 String name, 346 String descriptor, 347 Clazz referencedClass, 348 Member referencedMember) 349 { 350 return addFieldrefConstant(classIndex, 351 addNameAndTypeConstant(name, descriptor), 352 referencedClass, 353 referencedMember); 354 } 355 356 357 /** 358 * Finds or creates a FieldrefConstant constant pool entry with the given 359 * class constant pool entry index and name and type constant pool entry 360 * index. 361 * @return the constant pool index of the FieldrefConstant. 362 */ addFieldrefConstant(int classIndex, int nameAndTypeIndex, Clazz referencedClass, Member referencedMember)363 public int addFieldrefConstant(int classIndex, 364 int nameAndTypeIndex, 365 Clazz referencedClass, 366 Member referencedMember) 367 { 368 int constantPoolCount = targetClass.u2constantPoolCount; 369 Constant[] constantPool = targetClass.constantPool; 370 371 // Check if the entry already exists. 372 for (int index = 1; index < constantPoolCount; index++) 373 { 374 Constant constant = constantPool[index]; 375 376 if (constant != null && 377 constant.getTag() == ClassConstants.CONSTANT_Fieldref) 378 { 379 FieldrefConstant fieldrefConstant = (FieldrefConstant)constant; 380 if (fieldrefConstant.u2classIndex == classIndex && 381 fieldrefConstant.u2nameAndTypeIndex == nameAndTypeIndex) 382 { 383 return index; 384 } 385 } 386 } 387 388 return addConstant(new FieldrefConstant(classIndex, 389 nameAndTypeIndex, 390 referencedClass, 391 referencedMember)); 392 } 393 394 395 /** 396 * Finds or creates a InterfaceMethodrefConstant constant pool entry with the 397 * given class name, method name, and descriptor. 398 * @return the constant pool index of the InterfaceMethodrefConstant. 399 */ addInterfaceMethodrefConstant(String className, String name, String descriptor, Clazz referencedClass, Member referencedMember)400 public int addInterfaceMethodrefConstant(String className, 401 String name, 402 String descriptor, 403 Clazz referencedClass, 404 Member referencedMember) 405 { 406 return addInterfaceMethodrefConstant(className, 407 addNameAndTypeConstant(name, descriptor), 408 referencedClass, 409 referencedMember); 410 } 411 412 413 /** 414 * Finds or creates a InterfaceMethodrefConstant constant pool entry with the 415 * given class name, method name, and descriptor. 416 * @return the constant pool index of the InterfaceMethodrefConstant. 417 */ addInterfaceMethodrefConstant(String className, int nameAndTypeIndex, Clazz referencedClass, Member referencedMember)418 public int addInterfaceMethodrefConstant(String className, 419 int nameAndTypeIndex, 420 Clazz referencedClass, 421 Member referencedMember) 422 { 423 return addInterfaceMethodrefConstant(addClassConstant(className, referencedClass), 424 nameAndTypeIndex, 425 referencedClass, 426 referencedMember); 427 } 428 429 430 /** 431 * Finds or creates a InterfaceMethodrefConstant constant pool entry for the 432 * given class and method. 433 * @return the constant pool index of the InterfaceMethodrefConstant. 434 */ addInterfaceMethodrefConstant(Clazz referencedClass, Member referencedMember)435 public int addInterfaceMethodrefConstant(Clazz referencedClass, 436 Member referencedMember) 437 { 438 return addInterfaceMethodrefConstant(referencedClass.getName(), 439 referencedMember.getName(referencedClass), 440 referencedMember.getDescriptor(referencedClass), 441 referencedClass, 442 referencedMember); 443 } 444 445 446 /** 447 * Finds or creates a InterfaceMethodrefConstant constant pool entry with the 448 * given class constant pool entry index, method name, and descriptor. 449 * @return the constant pool index of the InterfaceMethodrefConstant. 450 */ addInterfaceMethodrefConstant(int classIndex, String name, String descriptor, Clazz referencedClass, Member referencedMember)451 public int addInterfaceMethodrefConstant(int classIndex, 452 String name, 453 String descriptor, 454 Clazz referencedClass, 455 Member referencedMember) 456 { 457 return addInterfaceMethodrefConstant(classIndex, 458 addNameAndTypeConstant(name, descriptor), 459 referencedClass, 460 referencedMember); 461 } 462 463 464 /** 465 * Finds or creates a InterfaceMethodrefConstant constant pool entry with the 466 * given class constant pool entry index and name and type constant pool 467 * entry index. 468 * @return the constant pool index of the InterfaceMethodrefConstant. 469 */ addInterfaceMethodrefConstant(int classIndex, int nameAndTypeIndex, Clazz referencedClass, Member referencedMember)470 public int addInterfaceMethodrefConstant(int classIndex, 471 int nameAndTypeIndex, 472 Clazz referencedClass, 473 Member referencedMember) 474 { 475 int constantPoolCount = targetClass.u2constantPoolCount; 476 Constant[] constantPool = targetClass.constantPool; 477 478 // Check if the entry already exists. 479 for (int index = 1; index < constantPoolCount; index++) 480 { 481 Constant constant = constantPool[index]; 482 483 if (constant != null && 484 constant.getTag() == ClassConstants.CONSTANT_InterfaceMethodref) 485 { 486 InterfaceMethodrefConstant methodrefConstant = (InterfaceMethodrefConstant)constant; 487 if (methodrefConstant.u2classIndex == classIndex && 488 methodrefConstant.u2nameAndTypeIndex == nameAndTypeIndex) 489 { 490 return index; 491 } 492 } 493 } 494 495 return addConstant(new InterfaceMethodrefConstant(classIndex, 496 nameAndTypeIndex, 497 referencedClass, 498 referencedMember)); 499 } 500 501 502 /** 503 * Finds or creates a MethodrefConstant constant pool entry for the given 504 * class and method. 505 * @return the constant pool index of the MethodrefConstant. 506 */ addMethodrefConstant(Clazz referencedClass, Member referencedMember)507 public int addMethodrefConstant(Clazz referencedClass, 508 Member referencedMember) 509 { 510 return addMethodrefConstant(referencedClass.getName(), 511 referencedMember.getName(referencedClass), 512 referencedMember.getDescriptor(referencedClass), 513 referencedClass, 514 referencedMember); 515 } 516 517 518 /** 519 * Finds or creates a MethodrefConstant constant pool entry with the given 520 * class name, method name, and descriptor. 521 * @return the constant pool index of the MethodrefConstant. 522 */ addMethodrefConstant(String className, String name, String descriptor, Clazz referencedClass, Member referencedMember)523 public int addMethodrefConstant(String className, 524 String name, 525 String descriptor, 526 Clazz referencedClass, 527 Member referencedMember) 528 { 529 return addMethodrefConstant(className, 530 addNameAndTypeConstant(name, descriptor), 531 referencedClass, 532 referencedMember); 533 } 534 535 536 /** 537 * Finds or creates a MethodrefConstant constant pool entry with the given 538 * class name, method name, and descriptor. 539 * @return the constant pool index of the MethodrefConstant. 540 */ addMethodrefConstant(String className, int nameAndTypeIndex, Clazz referencedClass, Member referencedMember)541 public int addMethodrefConstant(String className, 542 int nameAndTypeIndex, 543 Clazz referencedClass, 544 Member referencedMember) 545 { 546 return addMethodrefConstant(addClassConstant(className, referencedClass), 547 nameAndTypeIndex, 548 referencedClass, 549 referencedMember); 550 } 551 552 553 /** 554 * Finds or creates a MethodrefConstant constant pool entry with the given 555 * class constant pool entry index, method name, and descriptor. 556 * @return the constant pool index of the MethodrefConstant. 557 */ addMethodrefConstant(int classIndex, String name, String descriptor, Clazz referencedClass, Member referencedMember)558 public int addMethodrefConstant(int classIndex, 559 String name, 560 String descriptor, 561 Clazz referencedClass, 562 Member referencedMember) 563 { 564 return addMethodrefConstant(classIndex, 565 addNameAndTypeConstant(name, descriptor), 566 referencedClass, 567 referencedMember); 568 } 569 570 571 /** 572 * Finds or creates a MethodrefConstant constant pool entry with the given 573 * class constant pool entry index and name and type constant pool entry 574 * index. 575 * @return the constant pool index of the MethodrefConstant. 576 */ addMethodrefConstant(int classIndex, int nameAndTypeIndex, Clazz referencedClass, Member referencedMember)577 public int addMethodrefConstant(int classIndex, 578 int nameAndTypeIndex, 579 Clazz referencedClass, 580 Member referencedMember) 581 { 582 int constantPoolCount = targetClass.u2constantPoolCount; 583 Constant[] constantPool = targetClass.constantPool; 584 585 // Check if the entry already exists. 586 for (int index = 1; index < constantPoolCount; index++) 587 { 588 Constant constant = constantPool[index]; 589 590 if (constant != null && 591 constant.getTag() == ClassConstants.CONSTANT_Methodref) 592 { 593 MethodrefConstant methodrefConstant = (MethodrefConstant)constant; 594 if (methodrefConstant.u2classIndex == classIndex && 595 methodrefConstant.u2nameAndTypeIndex == nameAndTypeIndex) 596 { 597 return index; 598 } 599 } 600 } 601 602 return addConstant(new MethodrefConstant(classIndex, 603 nameAndTypeIndex, 604 referencedClass, 605 referencedMember)); 606 } 607 608 609 /** 610 * Finds or creates a ClassConstant constant pool entry for the given class. 611 * @return the constant pool index of the ClassConstant. 612 */ addClassConstant(Clazz referencedClass)613 public int addClassConstant(Clazz referencedClass) 614 { 615 return addClassConstant(referencedClass.getName(), 616 referencedClass); 617 } 618 619 620 /** 621 * Finds or creates a ClassConstant constant pool entry with the given name. 622 * @return the constant pool index of the ClassConstant. 623 */ addClassConstant(String name, Clazz referencedClass)624 public int addClassConstant(String name, 625 Clazz referencedClass) 626 { 627 int constantPoolCount = targetClass.u2constantPoolCount; 628 Constant[] constantPool = targetClass.constantPool; 629 630 // Check if the entry already exists. 631 for (int index = 1; index < constantPoolCount; index++) 632 { 633 Constant constant = constantPool[index]; 634 635 if (constant != null && 636 constant.getTag() == ClassConstants.CONSTANT_Class) 637 { 638 ClassConstant classConstant = (ClassConstant)constant; 639 if (classConstant.getName(targetClass).equals(name)) 640 { 641 return index; 642 } 643 } 644 } 645 646 int nameIndex = addUtf8Constant(name); 647 648 return addConstant(new ClassConstant(nameIndex, referencedClass)); 649 } 650 651 652 /** 653 * Finds or creates a MethodTypeConstant constant pool entry with the given 654 * type. 655 * @return the constant pool index of the MethodTypeConstant. 656 */ addMethodTypeConstant(String type)657 public int addMethodTypeConstant(String type) 658 { 659 int constantPoolCount = targetClass.u2constantPoolCount; 660 Constant[] constantPool = targetClass.constantPool; 661 662 // Check if the entry already exists. 663 for (int index = 1; index < constantPoolCount; index++) 664 { 665 Constant constant = constantPool[index]; 666 667 if (constant != null && 668 constant.getTag() == ClassConstants.CONSTANT_MethodType) 669 { 670 MethodTypeConstant methodTypeConstant = (MethodTypeConstant)constant; 671 if (methodTypeConstant.getType(targetClass).equals(type)) 672 { 673 return index; 674 } 675 } 676 } 677 678 return addConstant(new MethodTypeConstant(addUtf8Constant(type))); 679 } 680 681 682 /** 683 * Finds or creates a NameAndTypeConstant constant pool entry with the given 684 * name and type. 685 * @return the constant pool index of the NameAndTypeConstant. 686 */ addNameAndTypeConstant(String name, String type)687 public int addNameAndTypeConstant(String name, 688 String type) 689 { 690 int constantPoolCount = targetClass.u2constantPoolCount; 691 Constant[] constantPool = targetClass.constantPool; 692 693 // Check if the entry already exists. 694 for (int index = 1; index < constantPoolCount; index++) 695 { 696 Constant constant = constantPool[index]; 697 698 if (constant != null && 699 constant.getTag() == ClassConstants.CONSTANT_NameAndType) 700 { 701 NameAndTypeConstant nameAndTypeConstant = (NameAndTypeConstant)constant; 702 if (nameAndTypeConstant.getName(targetClass).equals(name) && 703 nameAndTypeConstant.getType(targetClass).equals(type)) 704 { 705 return index; 706 } 707 } 708 } 709 710 return addConstant(new NameAndTypeConstant(addUtf8Constant(name), 711 addUtf8Constant(type))); 712 } 713 714 715 /** 716 * Finds or creates a Utf8Constant constant pool entry for the given string. 717 * @return the constant pool index of the Utf8Constant. 718 */ addUtf8Constant(String string)719 public int addUtf8Constant(String string) 720 { 721 int constantPoolCount = targetClass.u2constantPoolCount; 722 Constant[] constantPool = targetClass.constantPool; 723 724 // Check if the entry already exists. 725 for (int index = 1; index < constantPoolCount; index++) 726 { 727 Constant constant = constantPool[index]; 728 729 if (constant != null && 730 constant.getTag() == ClassConstants.CONSTANT_Utf8) 731 { 732 Utf8Constant utf8Constant = (Utf8Constant)constant; 733 if (utf8Constant.getString().equals(string)) 734 { 735 return index; 736 } 737 } 738 } 739 740 return addConstant(new Utf8Constant(string)); 741 } 742 743 744 /** 745 * Adds a given constant pool entry to the end of the constant pool/ 746 * @return the constant pool index for the added entry. 747 */ addConstant(Constant constant)748 public int addConstant(Constant constant) 749 { 750 int constantPoolCount = targetClass.u2constantPoolCount; 751 Constant[] constantPool = targetClass.constantPool; 752 753 // Make sure there is enough space for another constant pool entry. 754 if (constantPool.length < constantPoolCount+2) 755 { 756 targetClass.constantPool = new Constant[constantPoolCount+2]; 757 System.arraycopy(constantPool, 0, 758 targetClass.constantPool, 0, 759 constantPoolCount); 760 constantPool = targetClass.constantPool; 761 } 762 763 if (DEBUG) 764 { 765 System.out.println(targetClass.getName()+": adding ["+constant.getClass().getName()+"] at index "+targetClass.u2constantPoolCount); 766 } 767 768 // Create a new Utf8Constant for the given string. 769 constantPool[targetClass.u2constantPoolCount++] = constant; 770 771 // Long constants and double constants take up two entries in the 772 // constant pool. 773 int tag = constant.getTag(); 774 if (tag == ClassConstants.CONSTANT_Long || 775 tag == ClassConstants.CONSTANT_Double) 776 { 777 constantPool[targetClass.u2constantPoolCount++] = null; 778 } 779 780 return constantPoolCount; 781 } 782 } 783