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; |
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) { |
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; |
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()]; |