Home | History | Annotate | Download | only in editor
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2014 Eric Lafortune (eric (at) 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      */
     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      */
     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      */
     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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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