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