View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License. 
16   *
17   */
18  package org.apache.bcel.generic;
19  
20  import java.util.HashMap;
21  import java.util.Map;
22  import org.apache.bcel.Constants;
23  import org.apache.bcel.classfile.Constant;
24  import org.apache.bcel.classfile.ConstantCP;
25  import org.apache.bcel.classfile.ConstantClass;
26  import org.apache.bcel.classfile.ConstantDouble;
27  import org.apache.bcel.classfile.ConstantFieldref;
28  import org.apache.bcel.classfile.ConstantFloat;
29  import org.apache.bcel.classfile.ConstantInteger;
30  import org.apache.bcel.classfile.ConstantInterfaceMethodref;
31  import org.apache.bcel.classfile.ConstantLong;
32  import org.apache.bcel.classfile.ConstantMethodref;
33  import org.apache.bcel.classfile.ConstantNameAndType;
34  import org.apache.bcel.classfile.ConstantPool;
35  import org.apache.bcel.classfile.ConstantString;
36  import org.apache.bcel.classfile.ConstantUtf8;
37  
38  /** 
39   * This class is used to build up a constant pool. The user adds
40   * constants via `addXXX' methods, `addString', `addClass',
41   * etc.. These methods return an index into the constant
42   * pool. Finally, `getFinalConstantPool()' returns the constant pool
43   * built up. Intermediate versions of the constant pool can be
44   * obtained with `getConstantPool()'. A constant pool has capacity for
45   * Constants.MAX_SHORT entries. Note that the first (0) is used by the
46   * JVM and that Double and Long constants need two slots.
47   *
48   * @version $Id: ConstantPoolGen.java 1152077 2011-07-29 02:29:42Z dbrosius $
49   * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
50   * @see Constant
51   */
52  public class ConstantPoolGen implements java.io.Serializable {
53  
54      private static final long serialVersionUID = 6664071417323174824L;
55      protected int size; 
56      protected Constant[] constants;
57      protected int index = 1; // First entry (0) used by JVM
58      private static final String METHODREF_DELIM = ":";
59      private static final String IMETHODREF_DELIM = "#";
60      private static final String FIELDREF_DELIM = "&";
61      private static final String NAT_DELIM = "%";
62  
63      private static class Index implements java.io.Serializable {
64  
65          private static final long serialVersionUID = -9187078620578535161L;
66          int index;
67  
68  
69          Index(int i) {
70              index = i;
71          }
72      }
73  
74  
75      /**
76       * Initialize with given array of constants.
77       *
78       * @param cs array of given constants, new ones will be appended
79       */
80      public ConstantPoolGen(Constant[] cs) {
81          StringBuilder sb = new StringBuilder(256);
82          
83          size = Math.max(256, cs.length + 64);
84          constants = new Constant[size];
85          
86          System.arraycopy(cs, 0, constants, 0, cs.length);
87          if (cs.length > 0) {
88              index = cs.length;
89          }
90      	
91      	
92          for (int i = 1; i < index; i++) {
93              Constant c = constants[i];
94              if (c instanceof ConstantString) {
95                  ConstantString s = (ConstantString) c;
96                  ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()];
97                  String key = u8.getBytes();
98                  if (!string_table.containsKey(key)) {
99                      string_table.put(key, new Index(i));
100                 }
101             } else if (c instanceof ConstantClass) {
102                 ConstantClass s = (ConstantClass) c;
103                 ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()];
104                 String key = u8.getBytes();
105                 if (!class_table.containsKey(key)) {
106                     class_table.put(key, new Index(i));
107                 }
108             } else if (c instanceof ConstantNameAndType) {
109                 ConstantNameAndType n = (ConstantNameAndType) c;
110                 ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()];
111                 ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()];
112                 
113                 sb.append(u8.getBytes());
114                 sb.append(NAT_DELIM);
115                 sb.append(u8_2.getBytes());
116                 String key = sb.toString();
117                 sb.delete(0, sb.length());
118                 
119                 if (!n_a_t_table.containsKey(key)) {
120                     n_a_t_table.put(key, new Index(i));
121                 }
122             } else if (c instanceof ConstantUtf8) {
123                 ConstantUtf8 u = (ConstantUtf8) c;
124                 String key = u.getBytes();
125                 if (!utf8_table.containsKey(key)) {
126                     utf8_table.put(key, new Index(i));
127                 }
128             } else if (c instanceof ConstantCP) {
129                 ConstantCP m = (ConstantCP) c;
130                 ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
131                 ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()];
132                 ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()];
133                 String class_name = u8.getBytes().replace('/', '.');
134                 u8 = (ConstantUtf8) constants[n.getNameIndex()];
135                 String method_name = u8.getBytes();
136                 u8 = (ConstantUtf8) constants[n.getSignatureIndex()];
137                 String signature = u8.getBytes();
138                 String delim = METHODREF_DELIM;
139                 if (c instanceof ConstantInterfaceMethodref) {
140                     delim = IMETHODREF_DELIM;
141                 } else if (c instanceof ConstantFieldref) {
142                     delim = FIELDREF_DELIM;
143                 }
144                 
145                 sb.append(class_name);
146                 sb.append(delim);
147                 sb.append(method_name);
148                 sb.append(delim);
149                 sb.append(signature);
150                 String key = sb.toString();
151                 sb.delete(0, sb.length());
152                 
153                 if (!cp_table.containsKey(key)) {
154                     cp_table.put(key, new Index(i));
155                 }
156             }
157         }
158     }
159 
160 
161     /**
162      * Initialize with given constant pool.
163      */
164     public ConstantPoolGen(ConstantPool cp) {
165         this(cp.getConstantPool());
166     }
167 
168 
169     /**
170      * Create empty constant pool.
171      */
172     public ConstantPoolGen() {
173     	size = 256;
174         constants = new Constant[size];
175     }
176 
177 
178     /** Resize internal array of constants.
179      */
180     protected void adjustSize() {
181         if (index + 3 >= size) {
182             Constant[] cs = constants;
183             size *= 2;
184             constants = new Constant[size];
185             System.arraycopy(cs, 0, constants, 0, index);
186         }
187     }
188 
189     private Map<String, Index> string_table = new HashMap<String, Index>();
190 
191 
192     /** 
193      * Look for ConstantString in ConstantPool containing String `str'.
194      *
195      * @param str String to search for
196      * @return index on success, -1 otherwise
197      */
198     public int lookupString( String str ) {
199         Index index = string_table.get(str);
200         return (index != null) ? index.index : -1;
201     }
202 
203 
204     /**
205      * Add a new String constant to the ConstantPool, if it is not already in there.
206      *
207      * @param str String to add
208      * @return index of entry
209      */
210     public int addString( String str ) {
211         int ret;
212         if ((ret = lookupString(str)) != -1) {
213             return ret; // Already in CP
214         }
215         int utf8 = addUtf8(str);
216         adjustSize();
217         ConstantString s = new ConstantString(utf8);
218         ret = index;
219         constants[index++] = s;
220         if (!string_table.containsKey(str)) {
221             string_table.put(str, new Index(ret));
222         }
223         return ret;
224     }
225 
226     private Map<String, Index> class_table = new HashMap<String, Index>();
227 
228 
229     /**
230      * Look for ConstantClass in ConstantPool named `str'.
231      *
232      * @param str String to search for
233      * @return index on success, -1 otherwise
234      */
235     public int lookupClass( String str ) {
236         Index index = class_table.get(str.replace('.', '/'));
237         return (index != null) ? index.index : -1;
238     }
239 
240 
241     private int addClass_( String clazz ) {
242         int ret;
243         if ((ret = lookupClass(clazz)) != -1) {
244             return ret; // Already in CP
245         }
246         adjustSize();
247         ConstantClass c = new ConstantClass(addUtf8(clazz));
248         ret = index;
249         constants[index++] = c;
250         if (!class_table.containsKey(clazz)) {
251             class_table.put(clazz, new Index(ret));
252         }
253         return ret;
254     }
255 
256 
257     /**
258      * Add a new Class reference to the ConstantPool, if it is not already in there.
259      *
260      * @param str Class to add
261      * @return index of entry
262      */
263     public int addClass( String str ) {
264         return addClass_(str.replace('.', '/'));
265     }
266 
267 
268     /**
269      * Add a new Class reference to the ConstantPool for a given type.
270      *
271      * @param type Class to add
272      * @return index of entry
273      */
274     public int addClass( ObjectType type ) {
275         return addClass(type.getClassName());
276     }
277 
278 
279     /**
280      * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY
281      * instruction, e.g. to the ConstantPool.
282      *
283      * @param type type of array class
284      * @return index of entry
285      */
286     public int addArrayClass( ArrayType type ) {
287         return addClass_(type.getSignature());
288     }
289 
290 
291     /** 
292      * Look for ConstantInteger in ConstantPool.
293      *
294      * @param n integer number to look for
295      * @return index on success, -1 otherwise
296      */
297     public int lookupInteger( int n ) {
298         for (int i = 1; i < index; i++) {
299             if (constants[i] instanceof ConstantInteger) {
300                 ConstantInteger c = (ConstantInteger) constants[i];
301                 if (c.getBytes() == n) {
302                     return i;
303                 }
304             }
305         }
306         return -1;
307     }
308 
309 
310     /**
311      * Add a new Integer constant to the ConstantPool, if it is not already in there.
312      *
313      * @param n integer number to add
314      * @return index of entry
315      */
316     public int addInteger( int n ) {
317         int ret;
318         if ((ret = lookupInteger(n)) != -1) {
319             return ret; // Already in CP
320         }
321         adjustSize();
322         ret = index;
323         constants[index++] = new ConstantInteger(n);
324         return ret;
325     }
326 
327 
328     /** 
329      * Look for ConstantFloat in ConstantPool.
330      *
331      * @param n Float number to look for
332      * @return index on success, -1 otherwise
333      */
334     public int lookupFloat( float n ) {
335         int bits = Float.floatToIntBits(n);
336         for (int i = 1; i < index; i++) {
337             if (constants[i] instanceof ConstantFloat) {
338                 ConstantFloat c = (ConstantFloat) constants[i];
339                 if (Float.floatToIntBits(c.getBytes()) == bits) {
340                     return i;
341                 }
342             }
343         }
344         return -1;
345     }
346 
347 
348     /**
349      * Add a new Float constant to the ConstantPool, if it is not already in there.
350      *
351      * @param n Float number to add
352      * @return index of entry
353      */
354     public int addFloat( float n ) {
355         int ret;
356         if ((ret = lookupFloat(n)) != -1) {
357             return ret; // Already in CP
358         }
359         adjustSize();
360         ret = index;
361         constants[index++] = new ConstantFloat(n);
362         return ret;
363     }
364 
365     private Map<String, Index> utf8_table = new HashMap<String, Index>();
366 
367 
368     /** 
369      * Look for ConstantUtf8 in ConstantPool.
370      *
371      * @param n Utf8 string to look for
372      * @return index on success, -1 otherwise
373      */
374     public int lookupUtf8( String n ) {
375         Index index = utf8_table.get(n);
376         return (index != null) ? index.index : -1;
377     }
378 
379 
380     /**
381      * Add a new Utf8 constant to the ConstantPool, if it is not already in there.
382      *
383      * @param n Utf8 string to add
384      * @return index of entry
385      */
386     public int addUtf8( String n ) {
387         int ret;
388         if ((ret = lookupUtf8(n)) != -1) {
389             return ret; // Already in CP
390         }
391         adjustSize();
392         ret = index;
393         constants[index++] = new ConstantUtf8(n);
394         if (!utf8_table.containsKey(n)) {
395             utf8_table.put(n, new Index(ret));
396         }
397         return ret;
398     }
399 
400 
401     /** 
402      * Look for ConstantLong in ConstantPool.
403      *
404      * @param n Long number to look for
405      * @return index on success, -1 otherwise
406      */
407     public int lookupLong( long n ) {
408         for (int i = 1; i < index; i++) {
409             if (constants[i] instanceof ConstantLong) {
410                 ConstantLong c = (ConstantLong) constants[i];
411                 if (c.getBytes() == n) {
412                     return i;
413                 }
414             }
415         }
416         return -1;
417     }
418 
419 
420     /**
421      * Add a new long constant to the ConstantPool, if it is not already in there.
422      *
423      * @param n Long number to add
424      * @return index of entry
425      */
426     public int addLong( long n ) {
427         int ret;
428         if ((ret = lookupLong(n)) != -1) {
429             return ret; // Already in CP
430         }
431         adjustSize();
432         ret = index;
433         constants[index] = new ConstantLong(n);
434         index += 2; // Wastes one entry according to spec
435         return ret;
436     }
437 
438 
439     /** 
440      * Look for ConstantDouble in ConstantPool.
441      *
442      * @param n Double number to look for
443      * @return index on success, -1 otherwise
444      */
445     public int lookupDouble( double n ) {
446         long bits = Double.doubleToLongBits(n);
447         for (int i = 1; i < index; i++) {
448             if (constants[i] instanceof ConstantDouble) {
449                 ConstantDouble c = (ConstantDouble) constants[i];
450                 if (Double.doubleToLongBits(c.getBytes()) == bits) {
451                     return i;
452                 }
453             }
454         }
455         return -1;
456     }
457 
458 
459     /**
460      * Add a new double constant to the ConstantPool, if it is not already in there.
461      *
462      * @param n Double number to add
463      * @return index of entry
464      */
465     public int addDouble( double n ) {
466         int ret;
467         if ((ret = lookupDouble(n)) != -1) {
468             return ret; // Already in CP
469         }
470         adjustSize();
471         ret = index;
472         constants[index] = new ConstantDouble(n);
473         index += 2; // Wastes one entry according to spec
474         return ret;
475     }
476 
477     private Map<String, Index> n_a_t_table = new HashMap<String, Index>();
478 
479 
480     /** 
481      * Look for ConstantNameAndType in ConstantPool.
482      *
483      * @param name of variable/method
484      * @param signature of variable/method
485      * @return index on success, -1 otherwise
486      */
487     public int lookupNameAndType( String name, String signature ) {
488         Index _index = n_a_t_table.get(name + NAT_DELIM + signature);
489         return (_index != null) ? _index.index : -1;
490     }
491 
492 
493     /**
494      * Add a new NameAndType constant to the ConstantPool if it is not already 
495      * in there.
496      *
497      * @param name Name string to add
498      * @param signature signature string to add
499      * @return index of entry
500      */
501     public int addNameAndType( String name, String signature ) {
502         int ret;
503         int name_index, signature_index;
504         if ((ret = lookupNameAndType(name, signature)) != -1) {
505             return ret; // Already in CP
506         }
507         adjustSize();
508         name_index = addUtf8(name);
509         signature_index = addUtf8(signature);
510         ret = index;
511         constants[index++] = new ConstantNameAndType(name_index, signature_index);
512         String key = name + NAT_DELIM + signature;
513         if (!n_a_t_table.containsKey(key)) {
514             n_a_t_table.put(key, new Index(ret));
515         }
516         return ret;
517     }
518 
519     private Map<String, Index> cp_table = new HashMap<String, Index>();
520 
521 
522     /** 
523      * Look for ConstantMethodref in ConstantPool.
524      *
525      * @param class_name Where to find method
526      * @param method_name Guess what
527      * @param signature return and argument types
528      * @return index on success, -1 otherwise
529      */
530     public int lookupMethodref( String class_name, String method_name, String signature ) {
531         Index index = cp_table.get(class_name + METHODREF_DELIM + method_name
532                 + METHODREF_DELIM + signature);
533         return (index != null) ? index.index : -1;
534     }
535 
536 
537     public int lookupMethodref( MethodGen method ) {
538         return lookupMethodref(method.getClassName(), method.getName(), method.getSignature());
539     }
540 
541 
542     /**
543      * Add a new Methodref constant to the ConstantPool, if it is not already 
544      * in there.
545      *
546      * @param class_name class name string to add
547      * @param method_name method name string to add
548      * @param signature method signature string to add
549      * @return index of entry
550      */
551     public int addMethodref( String class_name, String method_name, String signature ) {
552         int ret, class_index, name_and_type_index;
553         if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) {
554             return ret; // Already in CP
555         }
556         adjustSize();
557         name_and_type_index = addNameAndType(method_name, signature);
558         class_index = addClass(class_name);
559         ret = index;
560         constants[index++] = new ConstantMethodref(class_index, name_and_type_index);
561         String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature;
562         if (!cp_table.containsKey(key)) {
563             cp_table.put(key, new Index(ret));
564         }
565         return ret;
566     }
567 
568 
569     public int addMethodref( MethodGen method ) {
570         return addMethodref(method.getClassName(), method.getName(), method.getSignature());
571     }
572 
573 
574     /** 
575      * Look for ConstantInterfaceMethodref in ConstantPool.
576      *
577      * @param class_name Where to find method
578      * @param method_name Guess what
579      * @param signature return and argument types
580      * @return index on success, -1 otherwise
581      */
582     public int lookupInterfaceMethodref( String class_name, String method_name, String signature ) {
583         Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name
584                 + IMETHODREF_DELIM + signature);
585         return (index != null) ? index.index : -1;
586     }
587 
588 
589     public int lookupInterfaceMethodref( MethodGen method ) {
590         return lookupInterfaceMethodref(method.getClassName(), method.getName(), method
591                 .getSignature());
592     }
593 
594 
595     /**
596      * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already 
597      * in there.
598      *
599      * @param class_name class name string to add
600      * @param method_name method name string to add
601      * @param signature signature string to add
602      * @return index of entry
603      */
604     public int addInterfaceMethodref( String class_name, String method_name, String signature ) {
605         int ret, class_index, name_and_type_index;
606         if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) {
607             return ret; // Already in CP
608         }
609         adjustSize();
610         class_index = addClass(class_name);
611         name_and_type_index = addNameAndType(method_name, signature);
612         ret = index;
613         constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index);
614         String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature;
615         if (!cp_table.containsKey(key)) {
616             cp_table.put(key, new Index(ret));
617         }
618         return ret;
619     }
620 
621 
622     public int addInterfaceMethodref( MethodGen method ) {
623         return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature());
624     }
625 
626 
627     /** 
628      * Look for ConstantFieldref in ConstantPool.
629      *
630      * @param class_name Where to find method
631      * @param field_name Guess what
632      * @param signature return and argument types
633      * @return index on success, -1 otherwise
634      */
635     public int lookupFieldref( String class_name, String field_name, String signature ) {
636         Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name
637                 + FIELDREF_DELIM + signature);
638         return (index != null) ? index.index : -1;
639     }
640 
641 
642     /**
643      * Add a new Fieldref constant to the ConstantPool, if it is not already 
644      * in there.
645      *
646      * @param class_name class name string to add
647      * @param field_name field name string to add
648      * @param signature signature string to add
649      * @return index of entry
650      */
651     public int addFieldref( String class_name, String field_name, String signature ) {
652         int ret;
653         int class_index, name_and_type_index;
654         if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) {
655             return ret; // Already in CP
656         }
657         adjustSize();
658         class_index = addClass(class_name);
659         name_and_type_index = addNameAndType(field_name, signature);
660         ret = index;
661         constants[index++] = new ConstantFieldref(class_index, name_and_type_index);
662         String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature;
663         if (!cp_table.containsKey(key)) {
664             cp_table.put(key, new Index(ret));
665         }
666         return ret;
667     }
668 
669 
670     /**
671      * @param i index in constant pool
672      * @return constant pool entry at index i
673      */
674     public Constant getConstant( int i ) {
675         return constants[i];
676     }
677 
678 
679     /**
680      * Use with care!
681      *
682      * @param i index in constant pool
683      * @param c new constant pool entry at index i
684      */
685     public void setConstant( int i, Constant c ) {
686         constants[i] = c;
687     }
688 
689 
690     /**
691      * @return intermediate constant pool
692      */
693     public ConstantPool getConstantPool() {
694         return new ConstantPool(constants);
695     }
696 
697 
698     /**
699      * @return current size of constant pool
700      */
701     public int getSize() {
702         return index;
703     }
704 
705 
706     /**
707      * @return constant pool with proper length
708      */
709     public ConstantPool getFinalConstantPool() {
710         Constant[] cs = new Constant[index];
711         System.arraycopy(constants, 0, cs, 0, index);
712         return new ConstantPool(cs);
713     }
714 
715 
716     /**
717      * @return String representation.
718      */
719     @Override
720     public String toString() {
721         StringBuilder buf = new StringBuilder();
722         for (int i = 1; i < index; i++) {
723             buf.append(i).append(")").append(constants[i]).append("\n");
724         }
725         return buf.toString();
726     }
727 
728 
729     /** Import constant from another ConstantPool and return new index.
730      */
731     public int addConstant( Constant c, ConstantPoolGen cp ) {
732         Constant[] constants = cp.getConstantPool().getConstantPool();
733         switch (c.getTag()) {
734             case Constants.CONSTANT_String: {
735                 ConstantString s = (ConstantString) c;
736                 ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()];
737                 return addString(u8.getBytes());
738             }
739             case Constants.CONSTANT_Class: {
740                 ConstantClass s = (ConstantClass) c;
741                 ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()];
742                 return addClass(u8.getBytes());
743             }
744             case Constants.CONSTANT_NameAndType: {
745                 ConstantNameAndType n = (ConstantNameAndType) c;
746                 ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()];
747                 ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()];
748                 return addNameAndType(u8.getBytes(), u8_2.getBytes());
749             }
750             case Constants.CONSTANT_Utf8:
751                 return addUtf8(((ConstantUtf8) c).getBytes());
752             case Constants.CONSTANT_Double:
753                 return addDouble(((ConstantDouble) c).getBytes());
754             case Constants.CONSTANT_Float:
755                 return addFloat(((ConstantFloat) c).getBytes());
756             case Constants.CONSTANT_Long:
757                 return addLong(((ConstantLong) c).getBytes());
758             case Constants.CONSTANT_Integer:
759                 return addInteger(((ConstantInteger) c).getBytes());
760             case Constants.CONSTANT_InterfaceMethodref:
761             case Constants.CONSTANT_Methodref:
762             case Constants.CONSTANT_Fieldref: {
763                 ConstantCP m = (ConstantCP) c;
764                 ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
765                 ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()];
766                 ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()];
767                 String class_name = u8.getBytes().replace('/', '.');
768                 u8 = (ConstantUtf8) constants[n.getNameIndex()];
769                 String name = u8.getBytes();
770                 u8 = (ConstantUtf8) constants[n.getSignatureIndex()];
771                 String signature = u8.getBytes();
772                 switch (c.getTag()) {
773                     case Constants.CONSTANT_InterfaceMethodref:
774                         return addInterfaceMethodref(class_name, name, signature);
775                     case Constants.CONSTANT_Methodref:
776                         return addMethodref(class_name, name, signature);
777                     case Constants.CONSTANT_Fieldref:
778                         return addFieldref(class_name, name, signature);
779                     default: // Never reached
780                         throw new RuntimeException("Unknown constant type " + c);
781                 }
782             }
783             default: // Never reached
784                 throw new RuntimeException("Unknown constant type " + c);
785         }
786     }
787 }