src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java
changeset 55496 8e0ae3830fca
parent 47216 71c04702a3d5
equal deleted inserted replaced
55495:badfa812b82a 55496:8e0ae3830fca
     1 /*
     1 /*
     2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
     3  */
     3  */
     4 /*
     4 /*
     5  * Licensed to the Apache Software Foundation (ASF) under one or more
     5  * Licensed to the Apache Software Foundation (ASF) under one or more
     6  * contributor license agreements.  See the NOTICE file distributed with
     6  * contributor license agreements.  See the NOTICE file distributed with
     7  * this work for additional information regarding copyright ownership.
     7  * this work for additional information regarding copyright ownership.
    38 import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
    38 import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
    39 import com.sun.org.apache.bcel.internal.classfile.ConstantString;
    39 import com.sun.org.apache.bcel.internal.classfile.ConstantString;
    40 import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8;
    40 import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8;
    41 
    41 
    42 /**
    42 /**
    43  * This class is used to build up a constant pool. The user adds constants via
    43  * This class is used to build up a constant pool. The user adds
    44  * `addXXX' methods, `addString', `addClass', etc.. These methods return an
    44  * constants via `addXXX' methods, `addString', `addClass',
    45  * index into the constant pool. Finally, `getFinalConstantPool()' returns the
    45  * etc.. These methods return an index into the constant
    46  * constant pool built up. Intermediate versions of the constant pool can be
    46  * pool. Finally, `getFinalConstantPool()' returns the constant pool
       
    47  * built up. Intermediate versions of the constant pool can be
    47  * obtained with `getConstantPool()'. A constant pool has capacity for
    48  * obtained with `getConstantPool()'. A constant pool has capacity for
    48  * Constants.MAX_SHORT entries. Note that the first (0) is used by the JVM and
    49  * Constants.MAX_SHORT entries. Note that the first (0) is used by the
    49  * that Double and Long constants need two slots.
    50  * JVM and that Double and Long constants need two slots.
    50  *
    51  *
    51  * @version $Id: ConstantPoolGen.java 1749603 2016-06-21 20:50:19Z ggregory $
    52  * @version $Id$
    52  * @see Constant
    53  * @see Constant
       
    54  * @LastModified: Jun 2019
    53  */
    55  */
    54 public class ConstantPoolGen {
    56 public class ConstantPoolGen {
    55 
    57 
    56     private static final int DEFAULT_BUFFER_SIZE = 256;
    58     private static final int DEFAULT_BUFFER_SIZE = 256;
    57     private int size;
    59     private int size;
    65 
    67 
    66     private static class Index {
    68     private static class Index {
    67 
    69 
    68         final int index;
    70         final int index;
    69 
    71 
       
    72 
    70         Index(final int i) {
    73         Index(final int i) {
    71             index = i;
    74             index = i;
    72         }
    75         }
    73     }
    76     }
       
    77 
    74 
    78 
    75     /**
    79     /**
    76      * Initialize with given array of constants.
    80      * Initialize with given array of constants.
    77      *
    81      *
    78      * @param cs array of given constants, new ones will be appended
    82      * @param cs array of given constants, new ones will be appended
    85 
    89 
    86         System.arraycopy(cs, 0, constants, 0, cs.length);
    90         System.arraycopy(cs, 0, constants, 0, cs.length);
    87         if (cs.length > 0) {
    91         if (cs.length > 0) {
    88             index = cs.length;
    92             index = cs.length;
    89         }
    93         }
       
    94 
    90 
    95 
    91         for (int i = 1; i < index; i++) {
    96         for (int i = 1; i < index; i++) {
    92             final Constant c = constants[i];
    97             final Constant c = constants[i];
    93             if (c instanceof ConstantString) {
    98             if (c instanceof ConstantString) {
    94                 final ConstantString s = (ConstantString) c;
    99                 final ConstantString s = (ConstantString) c;
   132                 if (c instanceof ConstantInvokeDynamic) {
   137                 if (c instanceof ConstantInvokeDynamic) {
   133                     class_name = Integer.toString(((ConstantInvokeDynamic) m).getBootstrapMethodAttrIndex());
   138                     class_name = Integer.toString(((ConstantInvokeDynamic) m).getBootstrapMethodAttrIndex());
   134                     // since name can't begin with digit, can  use
   139                     // since name can't begin with digit, can  use
   135                     // METHODREF_DELIM with out fear of duplicates.
   140                     // METHODREF_DELIM with out fear of duplicates.
   136                 } else {
   141                 } else {
   137                     final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
   142                 final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
   138                     u8 = (ConstantUtf8) constants[clazz.getNameIndex()];
   143                     u8 = (ConstantUtf8) constants[clazz.getNameIndex()];
   139                     class_name = u8.getBytes().replace('/', '.');
   144                     class_name = u8.getBytes().replace('/', '.');
   140                 }
   145                 }
   141 
   146 
   142                 final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()];
   147                 final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()];
   181                 assert false : "Unexpected constant type: " + c.getClass().getName();
   186                 assert false : "Unexpected constant type: " + c.getClass().getName();
   182             }
   187             }
   183         }
   188         }
   184     }
   189     }
   185 
   190 
       
   191 
   186     /**
   192     /**
   187      * Initialize with given constant pool.
   193      * Initialize with given constant pool.
   188      */
   194      */
   189     public ConstantPoolGen(final ConstantPool cp) {
   195     public ConstantPoolGen(final ConstantPool cp) {
   190         this(cp.getConstantPool());
   196         this(cp.getConstantPool());
   191     }
   197     }
       
   198 
   192 
   199 
   193     /**
   200     /**
   194      * Create empty constant pool.
   201      * Create empty constant pool.
   195      */
   202      */
   196     public ConstantPoolGen() {
   203     public ConstantPoolGen() {
   197         size = DEFAULT_BUFFER_SIZE;
   204         size = DEFAULT_BUFFER_SIZE;
   198         constants = new Constant[size];
   205         constants = new Constant[size];
   199     }
   206     }
   200 
   207 
   201     /**
   208 
   202      * Resize internal array of constants.
   209     /** Resize internal array of constants.
   203      */
   210      */
   204     protected void adjustSize() {
   211     protected void adjustSize() {
   205         if (index + 3 >= size) {
   212         if (index + 3 >= size) {
   206             final Constant[] cs = constants;
   213             final Constant[] cs = constants;
   207             size *= 2;
   214             size *= 2;
   210         }
   217         }
   211     }
   218     }
   212 
   219 
   213     private final Map<String, Index> string_table = new HashMap<>();
   220     private final Map<String, Index> string_table = new HashMap<>();
   214 
   221 
       
   222 
   215     /**
   223     /**
   216      * Look for ConstantString in ConstantPool containing String `str'.
   224      * Look for ConstantString in ConstantPool containing String `str'.
   217      *
   225      *
   218      * @param str String to search for
   226      * @param str String to search for
   219      * @return index on success, -1 otherwise
   227      * @return index on success, -1 otherwise
   220      */
   228      */
   221     public int lookupString(final String str) {
   229     public int lookupString( final String str ) {
   222         final Index index = string_table.get(str);
   230         final Index index = string_table.get(str);
   223         return (index != null) ? index.index : -1;
   231         return (index != null) ? index.index : -1;
   224     }
   232     }
   225 
   233 
   226     /**
   234 
   227      * Add a new String constant to the ConstantPool, if it is not already in
   235     /**
   228      * there.
   236      * Add a new String constant to the ConstantPool, if it is not already in there.
   229      *
   237      *
   230      * @param str String to add
   238      * @param str String to add
   231      * @return index of entry
   239      * @return index of entry
   232      */
   240      */
   233     public int addString(final String str) {
   241     public int addString( final String str ) {
   234         int ret;
   242         int ret;
   235         if ((ret = lookupString(str)) != -1) {
   243         if ((ret = lookupString(str)) != -1) {
   236             return ret; // Already in CP
   244             return ret; // Already in CP
   237         }
   245         }
   238         final int utf8 = addUtf8(str);
   246         final int utf8 = addUtf8(str);
   246         return ret;
   254         return ret;
   247     }
   255     }
   248 
   256 
   249     private final Map<String, Index> class_table = new HashMap<>();
   257     private final Map<String, Index> class_table = new HashMap<>();
   250 
   258 
       
   259 
   251     /**
   260     /**
   252      * Look for ConstantClass in ConstantPool named `str'.
   261      * Look for ConstantClass in ConstantPool named `str'.
   253      *
   262      *
   254      * @param str String to search for
   263      * @param str String to search for
   255      * @return index on success, -1 otherwise
   264      * @return index on success, -1 otherwise
   256      */
   265      */
   257     public int lookupClass(final String str) {
   266     public int lookupClass( final String str ) {
   258         final Index index = class_table.get(str.replace('.', '/'));
   267         final Index index = class_table.get(str.replace('.', '/'));
   259         return (index != null) ? index.index : -1;
   268         return (index != null) ? index.index : -1;
   260     }
   269     }
   261 
   270 
   262     private int addClass_(final String clazz) {
   271 
       
   272     private int addClass_( final String clazz ) {
   263         int ret;
   273         int ret;
   264         if ((ret = lookupClass(clazz)) != -1) {
   274         if ((ret = lookupClass(clazz)) != -1) {
   265             return ret; // Already in CP
   275             return ret; // Already in CP
   266         }
   276         }
   267         adjustSize();
   277         adjustSize();
   272             class_table.put(clazz, new Index(ret));
   282             class_table.put(clazz, new Index(ret));
   273         }
   283         }
   274         return ret;
   284         return ret;
   275     }
   285     }
   276 
   286 
   277     /**
   287 
   278      * Add a new Class reference to the ConstantPool, if it is not already in
   288     /**
   279      * there.
   289      * Add a new Class reference to the ConstantPool, if it is not already in there.
   280      *
   290      *
   281      * @param str Class to add
   291      * @param str Class to add
   282      * @return index of entry
   292      * @return index of entry
   283      */
   293      */
   284     public int addClass(final String str) {
   294     public int addClass( final String str ) {
   285         return addClass_(str.replace('.', '/'));
   295         return addClass_(str.replace('.', '/'));
   286     }
   296     }
   287 
   297 
       
   298 
   288     /**
   299     /**
   289      * Add a new Class reference to the ConstantPool for a given type.
   300      * Add a new Class reference to the ConstantPool for a given type.
   290      *
   301      *
   291      * @param type Class to add
   302      * @param type Class to add
   292      * @return index of entry
   303      * @return index of entry
   293      */
   304      */
   294     public int addClass(final ObjectType type) {
   305     public int addClass( final ObjectType type ) {
   295         return addClass(type.getClassName());
   306         return addClass(type.getClassName());
   296     }
   307     }
   297 
   308 
   298     /**
   309 
   299      * Add a reference to an array class (e.g. String[][]) as needed by
   310     /**
   300      * MULTIANEWARRAY instruction, e.g. to the ConstantPool.
   311      * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY
       
   312      * instruction, e.g. to the ConstantPool.
   301      *
   313      *
   302      * @param type type of array class
   314      * @param type type of array class
   303      * @return index of entry
   315      * @return index of entry
   304      */
   316      */
   305     public int addArrayClass(final ArrayType type) {
   317     public int addArrayClass( final ArrayType type ) {
   306         return addClass_(type.getSignature());
   318         return addClass_(type.getSignature());
   307     }
   319     }
   308 
   320 
       
   321 
   309     /**
   322     /**
   310      * Look for ConstantInteger in ConstantPool.
   323      * Look for ConstantInteger in ConstantPool.
   311      *
   324      *
   312      * @param n integer number to look for
   325      * @param n integer number to look for
   313      * @return index on success, -1 otherwise
   326      * @return index on success, -1 otherwise
   314      */
   327      */
   315     public int lookupInteger(final int n) {
   328     public int lookupInteger( final int n ) {
   316         for (int i = 1; i < index; i++) {
   329         for (int i = 1; i < index; i++) {
   317             if (constants[i] instanceof ConstantInteger) {
   330             if (constants[i] instanceof ConstantInteger) {
   318                 final ConstantInteger c = (ConstantInteger) constants[i];
   331                 final ConstantInteger c = (ConstantInteger) constants[i];
   319                 if (c.getBytes() == n) {
   332                 if (c.getBytes() == n) {
   320                     return i;
   333                     return i;
   322             }
   335             }
   323         }
   336         }
   324         return -1;
   337         return -1;
   325     }
   338     }
   326 
   339 
   327     /**
   340 
   328      * Add a new Integer constant to the ConstantPool, if it is not already in
   341     /**
   329      * there.
   342      * Add a new Integer constant to the ConstantPool, if it is not already in there.
   330      *
   343      *
   331      * @param n integer number to add
   344      * @param n integer number to add
   332      * @return index of entry
   345      * @return index of entry
   333      */
   346      */
   334     public int addInteger(final int n) {
   347     public int addInteger( final int n ) {
   335         int ret;
   348         int ret;
   336         if ((ret = lookupInteger(n)) != -1) {
   349         if ((ret = lookupInteger(n)) != -1) {
   337             return ret; // Already in CP
   350             return ret; // Already in CP
   338         }
   351         }
   339         adjustSize();
   352         adjustSize();
   340         ret = index;
   353         ret = index;
   341         constants[index++] = new ConstantInteger(n);
   354         constants[index++] = new ConstantInteger(n);
   342         return ret;
   355         return ret;
   343     }
   356     }
   344 
   357 
       
   358 
   345     /**
   359     /**
   346      * Look for ConstantFloat in ConstantPool.
   360      * Look for ConstantFloat in ConstantPool.
   347      *
   361      *
   348      * @param n Float number to look for
   362      * @param n Float number to look for
   349      * @return index on success, -1 otherwise
   363      * @return index on success, -1 otherwise
   350      */
   364      */
   351     public int lookupFloat(final float n) {
   365     public int lookupFloat( final float n ) {
   352         final int bits = Float.floatToIntBits(n);
   366         final int bits = Float.floatToIntBits(n);
   353         for (int i = 1; i < index; i++) {
   367         for (int i = 1; i < index; i++) {
   354             if (constants[i] instanceof ConstantFloat) {
   368             if (constants[i] instanceof ConstantFloat) {
   355                 final ConstantFloat c = (ConstantFloat) constants[i];
   369                 final ConstantFloat c = (ConstantFloat) constants[i];
   356                 if (Float.floatToIntBits(c.getBytes()) == bits) {
   370                 if (Float.floatToIntBits(c.getBytes()) == bits) {
   359             }
   373             }
   360         }
   374         }
   361         return -1;
   375         return -1;
   362     }
   376     }
   363 
   377 
   364     /**
   378 
   365      * Add a new Float constant to the ConstantPool, if it is not already in
   379     /**
   366      * there.
   380      * Add a new Float constant to the ConstantPool, if it is not already in there.
   367      *
   381      *
   368      * @param n Float number to add
   382      * @param n Float number to add
   369      * @return index of entry
   383      * @return index of entry
   370      */
   384      */
   371     public int addFloat(final float n) {
   385     public int addFloat( final float n ) {
   372         int ret;
   386         int ret;
   373         if ((ret = lookupFloat(n)) != -1) {
   387         if ((ret = lookupFloat(n)) != -1) {
   374             return ret; // Already in CP
   388             return ret; // Already in CP
   375         }
   389         }
   376         adjustSize();
   390         adjustSize();
   379         return ret;
   393         return ret;
   380     }
   394     }
   381 
   395 
   382     private final Map<String, Index> utf8_table = new HashMap<>();
   396     private final Map<String, Index> utf8_table = new HashMap<>();
   383 
   397 
       
   398 
   384     /**
   399     /**
   385      * Look for ConstantUtf8 in ConstantPool.
   400      * Look for ConstantUtf8 in ConstantPool.
   386      *
   401      *
   387      * @param n Utf8 string to look for
   402      * @param n Utf8 string to look for
   388      * @return index on success, -1 otherwise
   403      * @return index on success, -1 otherwise
   389      */
   404      */
   390     public int lookupUtf8(final String n) {
   405     public int lookupUtf8( final String n ) {
   391         final Index index = utf8_table.get(n);
   406         final Index index = utf8_table.get(n);
   392         return (index != null) ? index.index : -1;
   407         return (index != null) ? index.index : -1;
   393     }
   408     }
   394 
   409 
   395     /**
   410 
   396      * Add a new Utf8 constant to the ConstantPool, if it is not already in
   411     /**
   397      * there.
   412      * Add a new Utf8 constant to the ConstantPool, if it is not already in there.
   398      *
   413      *
   399      * @param n Utf8 string to add
   414      * @param n Utf8 string to add
   400      * @return index of entry
   415      * @return index of entry
   401      */
   416      */
   402     public int addUtf8(final String n) {
   417     public int addUtf8( final String n ) {
   403         int ret;
   418         int ret;
   404         if ((ret = lookupUtf8(n)) != -1) {
   419         if ((ret = lookupUtf8(n)) != -1) {
   405             return ret; // Already in CP
   420             return ret; // Already in CP
   406         }
   421         }
   407         adjustSize();
   422         adjustSize();
   411             utf8_table.put(n, new Index(ret));
   426             utf8_table.put(n, new Index(ret));
   412         }
   427         }
   413         return ret;
   428         return ret;
   414     }
   429     }
   415 
   430 
       
   431 
   416     /**
   432     /**
   417      * Look for ConstantLong in ConstantPool.
   433      * Look for ConstantLong in ConstantPool.
   418      *
   434      *
   419      * @param n Long number to look for
   435      * @param n Long number to look for
   420      * @return index on success, -1 otherwise
   436      * @return index on success, -1 otherwise
   421      */
   437      */
   422     public int lookupLong(final long n) {
   438     public int lookupLong( final long n ) {
   423         for (int i = 1; i < index; i++) {
   439         for (int i = 1; i < index; i++) {
   424             if (constants[i] instanceof ConstantLong) {
   440             if (constants[i] instanceof ConstantLong) {
   425                 final ConstantLong c = (ConstantLong) constants[i];
   441                 final ConstantLong c = (ConstantLong) constants[i];
   426                 if (c.getBytes() == n) {
   442                 if (c.getBytes() == n) {
   427                     return i;
   443                     return i;
   429             }
   445             }
   430         }
   446         }
   431         return -1;
   447         return -1;
   432     }
   448     }
   433 
   449 
   434     /**
   450 
   435      * Add a new long constant to the ConstantPool, if it is not already in
   451     /**
   436      * there.
   452      * Add a new long constant to the ConstantPool, if it is not already in there.
   437      *
   453      *
   438      * @param n Long number to add
   454      * @param n Long number to add
   439      * @return index of entry
   455      * @return index of entry
   440      */
   456      */
   441     public int addLong(final long n) {
   457     public int addLong( final long n ) {
   442         int ret;
   458         int ret;
   443         if ((ret = lookupLong(n)) != -1) {
   459         if ((ret = lookupLong(n)) != -1) {
   444             return ret; // Already in CP
   460             return ret; // Already in CP
   445         }
   461         }
   446         adjustSize();
   462         adjustSize();
   448         constants[index] = new ConstantLong(n);
   464         constants[index] = new ConstantLong(n);
   449         index += 2; // Wastes one entry according to spec
   465         index += 2; // Wastes one entry according to spec
   450         return ret;
   466         return ret;
   451     }
   467     }
   452 
   468 
       
   469 
   453     /**
   470     /**
   454      * Look for ConstantDouble in ConstantPool.
   471      * Look for ConstantDouble in ConstantPool.
   455      *
   472      *
   456      * @param n Double number to look for
   473      * @param n Double number to look for
   457      * @return index on success, -1 otherwise
   474      * @return index on success, -1 otherwise
   458      */
   475      */
   459     public int lookupDouble(final double n) {
   476     public int lookupDouble( final double n ) {
   460         final long bits = Double.doubleToLongBits(n);
   477         final long bits = Double.doubleToLongBits(n);
   461         for (int i = 1; i < index; i++) {
   478         for (int i = 1; i < index; i++) {
   462             if (constants[i] instanceof ConstantDouble) {
   479             if (constants[i] instanceof ConstantDouble) {
   463                 final ConstantDouble c = (ConstantDouble) constants[i];
   480                 final ConstantDouble c = (ConstantDouble) constants[i];
   464                 if (Double.doubleToLongBits(c.getBytes()) == bits) {
   481                 if (Double.doubleToLongBits(c.getBytes()) == bits) {
   467             }
   484             }
   468         }
   485         }
   469         return -1;
   486         return -1;
   470     }
   487     }
   471 
   488 
   472     /**
   489 
   473      * Add a new double constant to the ConstantPool, if it is not already in
   490     /**
   474      * there.
   491      * Add a new double constant to the ConstantPool, if it is not already in there.
   475      *
   492      *
   476      * @param n Double number to add
   493      * @param n Double number to add
   477      * @return index of entry
   494      * @return index of entry
   478      */
   495      */
   479     public int addDouble(final double n) {
   496     public int addDouble( final double n ) {
   480         int ret;
   497         int ret;
   481         if ((ret = lookupDouble(n)) != -1) {
   498         if ((ret = lookupDouble(n)) != -1) {
   482             return ret; // Already in CP
   499             return ret; // Already in CP
   483         }
   500         }
   484         adjustSize();
   501         adjustSize();
   488         return ret;
   505         return ret;
   489     }
   506     }
   490 
   507 
   491     private final Map<String, Index> n_a_t_table = new HashMap<>();
   508     private final Map<String, Index> n_a_t_table = new HashMap<>();
   492 
   509 
       
   510 
   493     /**
   511     /**
   494      * Look for ConstantNameAndType in ConstantPool.
   512      * Look for ConstantNameAndType in ConstantPool.
   495      *
   513      *
   496      * @param name of variable/method
   514      * @param name of variable/method
   497      * @param signature of variable/method
   515      * @param signature of variable/method
   498      * @return index on success, -1 otherwise
   516      * @return index on success, -1 otherwise
   499      */
   517      */
   500     public int lookupNameAndType(final String name, final String signature) {
   518     public int lookupNameAndType( final String name, final String signature ) {
   501         final Index _index = n_a_t_table.get(name + NAT_DELIM + signature);
   519         final Index _index = n_a_t_table.get(name + NAT_DELIM + signature);
   502         return (_index != null) ? _index.index : -1;
   520         return (_index != null) ? _index.index : -1;
   503     }
   521     }
   504 
   522 
       
   523 
   505     /**
   524     /**
   506      * Add a new NameAndType constant to the ConstantPool if it is not already
   525      * Add a new NameAndType constant to the ConstantPool if it is not already
   507      * in there.
   526      * in there.
   508      *
   527      *
   509      * @param name Name string to add
   528      * @param name Name string to add
   510      * @param signature signature string to add
   529      * @param signature signature string to add
   511      * @return index of entry
   530      * @return index of entry
   512      */
   531      */
   513     public int addNameAndType(final String name, final String signature) {
   532     public int addNameAndType( final String name, final String signature ) {
   514         int ret;
   533         int ret;
   515         int name_index;
   534         int name_index;
   516         int signature_index;
   535         int signature_index;
   517         if ((ret = lookupNameAndType(name, signature)) != -1) {
   536         if ((ret = lookupNameAndType(name, signature)) != -1) {
   518             return ret; // Already in CP
   537             return ret; // Already in CP
   529         return ret;
   548         return ret;
   530     }
   549     }
   531 
   550 
   532     private final Map<String, Index> cp_table = new HashMap<>();
   551     private final Map<String, Index> cp_table = new HashMap<>();
   533 
   552 
       
   553 
   534     /**
   554     /**
   535      * Look for ConstantMethodref in ConstantPool.
   555      * Look for ConstantMethodref in ConstantPool.
   536      *
   556      *
   537      * @param class_name Where to find method
   557      * @param class_name Where to find method
   538      * @param method_name Guess what
   558      * @param method_name Guess what
   539      * @param signature return and argument types
   559      * @param signature return and argument types
   540      * @return index on success, -1 otherwise
   560      * @return index on success, -1 otherwise
   541      */
   561      */
   542     public int lookupMethodref(final String class_name, final String method_name, final String signature) {
   562     public int lookupMethodref( final String class_name, final String method_name, final String signature ) {
   543         final Index index = cp_table.get(class_name + METHODREF_DELIM + method_name
   563         final Index index = cp_table.get(class_name + METHODREF_DELIM + method_name
   544                 + METHODREF_DELIM + signature);
   564                 + METHODREF_DELIM + signature);
   545         return (index != null) ? index.index : -1;
   565         return (index != null) ? index.index : -1;
   546     }
   566     }
   547 
   567 
   548     public int lookupMethodref(final MethodGen method) {
   568 
       
   569     public int lookupMethodref( final MethodGen method ) {
   549         return lookupMethodref(method.getClassName(), method.getName(), method.getSignature());
   570         return lookupMethodref(method.getClassName(), method.getName(), method.getSignature());
   550     }
   571     }
   551 
   572 
   552     /**
   573 
   553      * Add a new Methodref constant to the ConstantPool, if it is not already in
   574     /**
   554      * there.
   575      * Add a new Methodref constant to the ConstantPool, if it is not already
       
   576      * in there.
   555      *
   577      *
   556      * @param class_name class name string to add
   578      * @param class_name class name string to add
   557      * @param method_name method name string to add
   579      * @param method_name method name string to add
   558      * @param signature method signature string to add
   580      * @param signature method signature string to add
   559      * @return index of entry
   581      * @return index of entry
   560      */
   582      */
   561     public int addMethodref(final String class_name, final String method_name, final String signature) {
   583     public int addMethodref( final String class_name, final String method_name, final String signature ) {
   562         int ret;
   584         int ret;
   563         int class_index;
   585         int class_index;
   564         int name_and_type_index;
   586         int name_and_type_index;
   565         if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) {
   587         if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) {
   566             return ret; // Already in CP
   588             return ret; // Already in CP
   575             cp_table.put(key, new Index(ret));
   597             cp_table.put(key, new Index(ret));
   576         }
   598         }
   577         return ret;
   599         return ret;
   578     }
   600     }
   579 
   601 
   580     public int addMethodref(final MethodGen method) {
   602 
       
   603     public int addMethodref( final MethodGen method ) {
   581         return addMethodref(method.getClassName(), method.getName(), method.getSignature());
   604         return addMethodref(method.getClassName(), method.getName(), method.getSignature());
   582     }
   605     }
       
   606 
   583 
   607 
   584     /**
   608     /**
   585      * Look for ConstantInterfaceMethodref in ConstantPool.
   609      * Look for ConstantInterfaceMethodref in ConstantPool.
   586      *
   610      *
   587      * @param class_name Where to find method
   611      * @param class_name Where to find method
   588      * @param method_name Guess what
   612      * @param method_name Guess what
   589      * @param signature return and argument types
   613      * @param signature return and argument types
   590      * @return index on success, -1 otherwise
   614      * @return index on success, -1 otherwise
   591      */
   615      */
   592     public int lookupInterfaceMethodref(final String class_name, final String method_name, final String signature) {
   616     public int lookupInterfaceMethodref( final String class_name, final String method_name, final String signature ) {
   593         final Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name
   617         final Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name
   594                 + IMETHODREF_DELIM + signature);
   618                 + IMETHODREF_DELIM + signature);
   595         return (index != null) ? index.index : -1;
   619         return (index != null) ? index.index : -1;
   596     }
   620     }
   597 
   621 
   598     public int lookupInterfaceMethodref(final MethodGen method) {
   622 
       
   623     public int lookupInterfaceMethodref( final MethodGen method ) {
   599         return lookupInterfaceMethodref(method.getClassName(), method.getName(), method
   624         return lookupInterfaceMethodref(method.getClassName(), method.getName(), method
   600                 .getSignature());
   625                 .getSignature());
   601     }
   626     }
   602 
   627 
   603     /**
   628 
   604      * Add a new InterfaceMethodref constant to the ConstantPool, if it is not
   629     /**
   605      * already in there.
   630      * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already
       
   631      * in there.
   606      *
   632      *
   607      * @param class_name class name string to add
   633      * @param class_name class name string to add
   608      * @param method_name method name string to add
   634      * @param method_name method name string to add
   609      * @param signature signature string to add
   635      * @param signature signature string to add
   610      * @return index of entry
   636      * @return index of entry
   611      */
   637      */
   612     public int addInterfaceMethodref(final String class_name, final String method_name, final String signature) {
   638     public int addInterfaceMethodref( final String class_name, final String method_name, final String signature ) {
   613         int ret;
   639         int ret;
   614         int class_index;
   640         int class_index;
   615         int name_and_type_index;
   641         int name_and_type_index;
   616         if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) {
   642         if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) {
   617             return ret; // Already in CP
   643             return ret; // Already in CP
   626             cp_table.put(key, new Index(ret));
   652             cp_table.put(key, new Index(ret));
   627         }
   653         }
   628         return ret;
   654         return ret;
   629     }
   655     }
   630 
   656 
   631     public int addInterfaceMethodref(final MethodGen method) {
   657 
       
   658     public int addInterfaceMethodref( final MethodGen method ) {
   632         return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature());
   659         return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature());
   633     }
   660     }
       
   661 
   634 
   662 
   635     /**
   663     /**
   636      * Look for ConstantFieldref in ConstantPool.
   664      * Look for ConstantFieldref in ConstantPool.
   637      *
   665      *
   638      * @param class_name Where to find method
   666      * @param class_name Where to find method
   639      * @param field_name Guess what
   667      * @param field_name Guess what
   640      * @param signature return and argument types
   668      * @param signature return and argument types
   641      * @return index on success, -1 otherwise
   669      * @return index on success, -1 otherwise
   642      */
   670      */
   643     public int lookupFieldref(final String class_name, final String field_name, final String signature) {
   671     public int lookupFieldref( final String class_name, final String field_name, final String signature ) {
   644         final Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name
   672         final Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name
   645                 + FIELDREF_DELIM + signature);
   673                 + FIELDREF_DELIM + signature);
   646         return (index != null) ? index.index : -1;
   674         return (index != null) ? index.index : -1;
   647     }
   675     }
   648 
   676 
   649     /**
   677 
   650      * Add a new Fieldref constant to the ConstantPool, if it is not already in
   678     /**
   651      * there.
   679      * Add a new Fieldref constant to the ConstantPool, if it is not already
       
   680      * in there.
   652      *
   681      *
   653      * @param class_name class name string to add
   682      * @param class_name class name string to add
   654      * @param field_name field name string to add
   683      * @param field_name field name string to add
   655      * @param signature signature string to add
   684      * @param signature signature string to add
   656      * @return index of entry
   685      * @return index of entry
   657      */
   686      */
   658     public int addFieldref(final String class_name, final String field_name, final String signature) {
   687     public int addFieldref( final String class_name, final String field_name, final String signature ) {
   659         int ret;
   688         int ret;
   660         int class_index;
   689         int class_index;
   661         int name_and_type_index;
   690         int name_and_type_index;
   662         if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) {
   691         if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) {
   663             return ret; // Already in CP
   692             return ret; // Already in CP
   672             cp_table.put(key, new Index(ret));
   701             cp_table.put(key, new Index(ret));
   673         }
   702         }
   674         return ret;
   703         return ret;
   675     }
   704     }
   676 
   705 
       
   706 
   677     /**
   707     /**
   678      * @param i index in constant pool
   708      * @param i index in constant pool
   679      * @return constant pool entry at index i
   709      * @return constant pool entry at index i
   680      */
   710      */
   681     public Constant getConstant(final int i) {
   711     public Constant getConstant( final int i ) {
   682         return constants[i];
   712         return constants[i];
   683     }
   713     }
       
   714 
   684 
   715 
   685     /**
   716     /**
   686      * Use with care!
   717      * Use with care!
   687      *
   718      *
   688      * @param i index in constant pool
   719      * @param i index in constant pool
   689      * @param c new constant pool entry at index i
   720      * @param c new constant pool entry at index i
   690      */
   721      */
   691     public void setConstant(final int i, final Constant c) {
   722     public void setConstant( final int i, final Constant c ) {
   692         constants[i] = c;
   723         constants[i] = c;
   693     }
   724     }
       
   725 
   694 
   726 
   695     /**
   727     /**
   696      * @return intermediate constant pool
   728      * @return intermediate constant pool
   697      */
   729      */
   698     public ConstantPool getConstantPool() {
   730     public ConstantPool getConstantPool() {
   699         return new ConstantPool(constants);
   731         return new ConstantPool(constants);
   700     }
   732     }
   701 
   733 
       
   734 
   702     /**
   735     /**
   703      * @return current size of constant pool
   736      * @return current size of constant pool
   704      */
   737      */
   705     public int getSize() {
   738     public int getSize() {
   706         return index;
   739         return index;
   707     }
   740     }
       
   741 
   708 
   742 
   709     /**
   743     /**
   710      * @return constant pool with proper length
   744      * @return constant pool with proper length
   711      */
   745      */
   712     public ConstantPool getFinalConstantPool() {
   746     public ConstantPool getFinalConstantPool() {
   713         final Constant[] cs = new Constant[index];
   747         final Constant[] cs = new Constant[index];
   714         System.arraycopy(constants, 0, cs, 0, index);
   748         System.arraycopy(constants, 0, cs, 0, index);
   715         return new ConstantPool(cs);
   749         return new ConstantPool(cs);
   716     }
   750     }
       
   751 
   717 
   752 
   718     /**
   753     /**
   719      * @return String representation.
   754      * @return String representation.
   720      */
   755      */
   721     @Override
   756     @Override
   725             buf.append(i).append(")").append(constants[i]).append("\n");
   760             buf.append(i).append(")").append(constants[i]).append("\n");
   726         }
   761         }
   727         return buf.toString();
   762         return buf.toString();
   728     }
   763     }
   729 
   764 
   730     /**
   765 
   731      * Import constant from another ConstantPool and return new index.
   766     /** Import constant from another ConstantPool and return new index.
   732      */
   767      */
   733     public int addConstant(final Constant c, final ConstantPoolGen cp) {
   768     public int addConstant( final Constant c, final ConstantPoolGen cp ) {
   734         final Constant[] constants = cp.getConstantPool().getConstantPool();
   769         final Constant[] constants = cp.getConstantPool().getConstantPool();
   735         switch (c.getTag()) {
   770         switch (c.getTag()) {
   736             case Const.CONSTANT_String: {
   771             case Const.CONSTANT_String: {
   737                 final ConstantString s = (ConstantString) c;
   772                 final ConstantString s = (ConstantString) c;
   738                 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()];
   773                 final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()];