/*
 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
 */
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.sun.org.apache.bcel.internal.generic;

import java.util.HashMap;
import java.util.Map;

import com.sun.org.apache.bcel.internal.Const;
import com.sun.org.apache.bcel.internal.classfile.Constant;
import com.sun.org.apache.bcel.internal.classfile.ConstantCP;
import com.sun.org.apache.bcel.internal.classfile.ConstantClass;
import com.sun.org.apache.bcel.internal.classfile.ConstantDouble;
import com.sun.org.apache.bcel.internal.classfile.ConstantFieldref;
import com.sun.org.apache.bcel.internal.classfile.ConstantFloat;
import com.sun.org.apache.bcel.internal.classfile.ConstantInteger;
import com.sun.org.apache.bcel.internal.classfile.ConstantInterfaceMethodref;
import com.sun.org.apache.bcel.internal.classfile.ConstantInvokeDynamic;
import com.sun.org.apache.bcel.internal.classfile.ConstantLong;
import com.sun.org.apache.bcel.internal.classfile.ConstantMethodref;
import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType;
import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
import com.sun.org.apache.bcel.internal.classfile.ConstantString;
import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8;

This class is used to build up a constant pool. The user adds constants via `addXXX' methods, `addString', `addClass', etc.. These methods return an index into the constant pool. Finally, `getFinalConstantPool()' returns the constant pool built up. Intermediate versions of the constant pool can be obtained with `getConstantPool()'. A constant pool has capacity for Constants.MAX_SHORT entries. Note that the first (0) is used by the JVM and that Double and Long constants need two slots.
See Also:
Version:$Id: ConstantPoolGen.java 1749603 2016-06-21 20:50:19Z ggregory $
/** * This class is used to build up a constant pool. The user adds constants via * `addXXX' methods, `addString', `addClass', etc.. These methods return an * index into the constant pool. Finally, `getFinalConstantPool()' returns the * constant pool built up. Intermediate versions of the constant pool can be * obtained with `getConstantPool()'. A constant pool has capacity for * Constants.MAX_SHORT entries. Note that the first (0) is used by the JVM and * that Double and Long constants need two slots. * * @version $Id: ConstantPoolGen.java 1749603 2016-06-21 20:50:19Z ggregory $ * @see Constant */
public class ConstantPoolGen { private static final int DEFAULT_BUFFER_SIZE = 256; private int size; private Constant[] constants; private int index = 1; // First entry (0) used by JVM private static final String METHODREF_DELIM = ":"; private static final String IMETHODREF_DELIM = "#"; private static final String FIELDREF_DELIM = "&"; private static final String NAT_DELIM = "%"; // Name and Type private static class Index { final int index; Index(final int i) { index = i; } }
Initialize with given array of constants.
Params:
  • cs – array of given constants, new ones will be appended
/** * Initialize with given array of constants. * * @param cs array of given constants, new ones will be appended */
public ConstantPoolGen(final Constant[] cs) { final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE); size = Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64); constants = new Constant[size]; System.arraycopy(cs, 0, constants, 0, cs.length); if (cs.length > 0) { index = cs.length; } for (int i = 1; i < index; i++) { final Constant c = constants[i]; if (c instanceof ConstantString) { final ConstantString s = (ConstantString) c; final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; final String key = u8.getBytes(); if (!string_table.containsKey(key)) { string_table.put(key, new Index(i)); } } else if (c instanceof ConstantClass) { final ConstantClass s = (ConstantClass) c; final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; final String key = u8.getBytes(); if (!class_table.containsKey(key)) { class_table.put(key, new Index(i)); } } else if (c instanceof ConstantNameAndType) { final ConstantNameAndType n = (ConstantNameAndType) c; final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; sb.append(u8.getBytes()); sb.append(NAT_DELIM); sb.append(u8_2.getBytes()); final String key = sb.toString(); sb.delete(0, sb.length()); if (!n_a_t_table.containsKey(key)) { n_a_t_table.put(key, new Index(i)); } } else if (c instanceof ConstantUtf8) { final ConstantUtf8 u = (ConstantUtf8) c; final String key = u.getBytes(); if (!utf8_table.containsKey(key)) { utf8_table.put(key, new Index(i)); } } else if (c instanceof ConstantCP) { final ConstantCP m = (ConstantCP) c; String class_name; ConstantUtf8 u8; if (c instanceof ConstantInvokeDynamic) { class_name = Integer.toString(((ConstantInvokeDynamic) m).getBootstrapMethodAttrIndex()); // since name can't begin with digit, can use // METHODREF_DELIM with out fear of duplicates. } else { final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; class_name = u8.getBytes().replace('/', '.'); } final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; u8 = (ConstantUtf8) constants[n.getNameIndex()]; final String method_name = u8.getBytes(); u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; final String signature = u8.getBytes(); String delim = METHODREF_DELIM; if (c instanceof ConstantInterfaceMethodref) { delim = IMETHODREF_DELIM; } else if (c instanceof ConstantFieldref) { delim = FIELDREF_DELIM; } sb.append(class_name); sb.append(delim); sb.append(method_name); sb.append(delim); sb.append(signature); final String key = sb.toString(); sb.delete(0, sb.length()); if (!cp_table.containsKey(key)) { cp_table.put(key, new Index(i)); } } else if (c == null) { // entries may be null // nothing to do } else if (c instanceof ConstantInteger) { // nothing to do } else if (c instanceof ConstantLong) { // nothing to do } else if (c instanceof ConstantFloat) { // nothing to do } else if (c instanceof ConstantDouble) { // nothing to do } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodType) { // TODO should this be handled somehow? } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodHandle) { // TODO should this be handled somehow? } else { assert false : "Unexpected constant type: " + c.getClass().getName(); } } }
Initialize with given constant pool.
/** * Initialize with given constant pool. */
public ConstantPoolGen(final ConstantPool cp) { this(cp.getConstantPool()); }
Create empty constant pool.
/** * Create empty constant pool. */
public ConstantPoolGen() { size = DEFAULT_BUFFER_SIZE; constants = new Constant[size]; }
Resize internal array of constants.
/** * Resize internal array of constants. */
protected void adjustSize() { if (index + 3 >= size) { final Constant[] cs = constants; size *= 2; constants = new Constant[size]; System.arraycopy(cs, 0, constants, 0, index); } } private final Map<String, Index> string_table = new HashMap<>();
Look for ConstantString in ConstantPool containing String `str'.
Params:
  • str – String to search for
Returns:index on success, -1 otherwise
/** * Look for ConstantString in ConstantPool containing String `str'. * * @param str String to search for * @return index on success, -1 otherwise */
public int lookupString(final String str) { final Index index = string_table.get(str); return (index != null) ? index.index : -1; }
Add a new String constant to the ConstantPool, if it is not already in there.
Params:
  • str – String to add
Returns:index of entry
/** * Add a new String constant to the ConstantPool, if it is not already in * there. * * @param str String to add * @return index of entry */
public int addString(final String str) { int ret; if ((ret = lookupString(str)) != -1) { return ret; // Already in CP } final int utf8 = addUtf8(str); adjustSize(); final ConstantString s = new ConstantString(utf8); ret = index; constants[index++] = s; if (!string_table.containsKey(str)) { string_table.put(str, new Index(ret)); } return ret; } private final Map<String, Index> class_table = new HashMap<>();
Look for ConstantClass in ConstantPool named `str'.
Params:
  • str – String to search for
Returns:index on success, -1 otherwise
/** * Look for ConstantClass in ConstantPool named `str'. * * @param str String to search for * @return index on success, -1 otherwise */
public int lookupClass(final String str) { final Index index = class_table.get(str.replace('.', '/')); return (index != null) ? index.index : -1; } private int addClass_(final String clazz) { int ret; if ((ret = lookupClass(clazz)) != -1) { return ret; // Already in CP } adjustSize(); final ConstantClass c = new ConstantClass(addUtf8(clazz)); ret = index; constants[index++] = c; if (!class_table.containsKey(clazz)) { class_table.put(clazz, new Index(ret)); } return ret; }
Add a new Class reference to the ConstantPool, if it is not already in there.
Params:
  • str – Class to add
Returns:index of entry
/** * Add a new Class reference to the ConstantPool, if it is not already in * there. * * @param str Class to add * @return index of entry */
public int addClass(final String str) { return addClass_(str.replace('.', '/')); }
Add a new Class reference to the ConstantPool for a given type.
Params:
  • type – Class to add
Returns:index of entry
/** * Add a new Class reference to the ConstantPool for a given type. * * @param type Class to add * @return index of entry */
public int addClass(final ObjectType type) { return addClass(type.getClassName()); }
Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY instruction, e.g. to the ConstantPool.
Params:
  • type – type of array class
Returns:index of entry
/** * Add a reference to an array class (e.g. String[][]) as needed by * MULTIANEWARRAY instruction, e.g. to the ConstantPool. * * @param type type of array class * @return index of entry */
public int addArrayClass(final ArrayType type) { return addClass_(type.getSignature()); }
Look for ConstantInteger in ConstantPool.
Params:
  • n – integer number to look for
Returns:index on success, -1 otherwise
/** * Look for ConstantInteger in ConstantPool. * * @param n integer number to look for * @return index on success, -1 otherwise */
public int lookupInteger(final int n) { for (int i = 1; i < index; i++) { if (constants[i] instanceof ConstantInteger) { final ConstantInteger c = (ConstantInteger) constants[i]; if (c.getBytes() == n) { return i; } } } return -1; }
Add a new Integer constant to the ConstantPool, if it is not already in there.
Params:
  • n – integer number to add
Returns:index of entry
/** * Add a new Integer constant to the ConstantPool, if it is not already in * there. * * @param n integer number to add * @return index of entry */
public int addInteger(final int n) { int ret; if ((ret = lookupInteger(n)) != -1) { return ret; // Already in CP } adjustSize(); ret = index; constants[index++] = new ConstantInteger(n); return ret; }
Look for ConstantFloat in ConstantPool.
Params:
  • n – Float number to look for
Returns:index on success, -1 otherwise
/** * Look for ConstantFloat in ConstantPool. * * @param n Float number to look for * @return index on success, -1 otherwise */
public int lookupFloat(final float n) { final int bits = Float.floatToIntBits(n); for (int i = 1; i < index; i++) { if (constants[i] instanceof ConstantFloat) { final ConstantFloat c = (ConstantFloat) constants[i]; if (Float.floatToIntBits(c.getBytes()) == bits) { return i; } } } return -1; }
Add a new Float constant to the ConstantPool, if it is not already in there.
Params:
  • n – Float number to add
Returns:index of entry
/** * Add a new Float constant to the ConstantPool, if it is not already in * there. * * @param n Float number to add * @return index of entry */
public int addFloat(final float n) { int ret; if ((ret = lookupFloat(n)) != -1) { return ret; // Already in CP } adjustSize(); ret = index; constants[index++] = new ConstantFloat(n); return ret; } private final Map<String, Index> utf8_table = new HashMap<>();
Look for ConstantUtf8 in ConstantPool.
Params:
  • n – Utf8 string to look for
Returns:index on success, -1 otherwise
/** * Look for ConstantUtf8 in ConstantPool. * * @param n Utf8 string to look for * @return index on success, -1 otherwise */
public int lookupUtf8(final String n) { final Index index = utf8_table.get(n); return (index != null) ? index.index : -1; }
Add a new Utf8 constant to the ConstantPool, if it is not already in there.
Params:
  • n – Utf8 string to add
Returns:index of entry
/** * Add a new Utf8 constant to the ConstantPool, if it is not already in * there. * * @param n Utf8 string to add * @return index of entry */
public int addUtf8(final String n) { int ret; if ((ret = lookupUtf8(n)) != -1) { return ret; // Already in CP } adjustSize(); ret = index; constants[index++] = new ConstantUtf8(n); if (!utf8_table.containsKey(n)) { utf8_table.put(n, new Index(ret)); } return ret; }
Look for ConstantLong in ConstantPool.
Params:
  • n – Long number to look for
Returns:index on success, -1 otherwise
/** * Look for ConstantLong in ConstantPool. * * @param n Long number to look for * @return index on success, -1 otherwise */
public int lookupLong(final long n) { for (int i = 1; i < index; i++) { if (constants[i] instanceof ConstantLong) { final ConstantLong c = (ConstantLong) constants[i]; if (c.getBytes() == n) { return i; } } } return -1; }
Add a new long constant to the ConstantPool, if it is not already in there.
Params:
  • n – Long number to add
Returns:index of entry
/** * Add a new long constant to the ConstantPool, if it is not already in * there. * * @param n Long number to add * @return index of entry */
public int addLong(final long n) { int ret; if ((ret = lookupLong(n)) != -1) { return ret; // Already in CP } adjustSize(); ret = index; constants[index] = new ConstantLong(n); index += 2; // Wastes one entry according to spec return ret; }
Look for ConstantDouble in ConstantPool.
Params:
  • n – Double number to look for
Returns:index on success, -1 otherwise
/** * Look for ConstantDouble in ConstantPool. * * @param n Double number to look for * @return index on success, -1 otherwise */
public int lookupDouble(final double n) { final long bits = Double.doubleToLongBits(n); for (int i = 1; i < index; i++) { if (constants[i] instanceof ConstantDouble) { final ConstantDouble c = (ConstantDouble) constants[i]; if (Double.doubleToLongBits(c.getBytes()) == bits) { return i; } } } return -1; }
Add a new double constant to the ConstantPool, if it is not already in there.
Params:
  • n – Double number to add
Returns:index of entry
/** * Add a new double constant to the ConstantPool, if it is not already in * there. * * @param n Double number to add * @return index of entry */
public int addDouble(final double n) { int ret; if ((ret = lookupDouble(n)) != -1) { return ret; // Already in CP } adjustSize(); ret = index; constants[index] = new ConstantDouble(n); index += 2; // Wastes one entry according to spec return ret; } private final Map<String, Index> n_a_t_table = new HashMap<>();
Look for ConstantNameAndType in ConstantPool.
Params:
  • name – of variable/method
  • signature – of variable/method
Returns:index on success, -1 otherwise
/** * Look for ConstantNameAndType in ConstantPool. * * @param name of variable/method * @param signature of variable/method * @return index on success, -1 otherwise */
public int lookupNameAndType(final String name, final String signature) { final Index _index = n_a_t_table.get(name + NAT_DELIM + signature); return (_index != null) ? _index.index : -1; }
Add a new NameAndType constant to the ConstantPool if it is not already in there.
Params:
  • name – Name string to add
  • signature – signature string to add
Returns:index of entry
/** * Add a new NameAndType constant to the ConstantPool if it is not already * in there. * * @param name Name string to add * @param signature signature string to add * @return index of entry */
public int addNameAndType(final String name, final String signature) { int ret; int name_index; int signature_index; if ((ret = lookupNameAndType(name, signature)) != -1) { return ret; // Already in CP } adjustSize(); name_index = addUtf8(name); signature_index = addUtf8(signature); ret = index; constants[index++] = new ConstantNameAndType(name_index, signature_index); final String key = name + NAT_DELIM + signature; if (!n_a_t_table.containsKey(key)) { n_a_t_table.put(key, new Index(ret)); } return ret; } private final Map<String, Index> cp_table = new HashMap<>();
Look for ConstantMethodref in ConstantPool.
Params:
  • class_name – Where to find method
  • method_name – Guess what
  • signature – return and argument types
Returns:index on success, -1 otherwise
/** * Look for ConstantMethodref in ConstantPool. * * @param class_name Where to find method * @param method_name Guess what * @param signature return and argument types * @return index on success, -1 otherwise */
public int lookupMethodref(final String class_name, final String method_name, final String signature) { final Index index = cp_table.get(class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature); return (index != null) ? index.index : -1; } public int lookupMethodref(final MethodGen method) { return lookupMethodref(method.getClassName(), method.getName(), method.getSignature()); }
Add a new Methodref constant to the ConstantPool, if it is not already in there.
Params:
  • class_name – class name string to add
  • method_name – method name string to add
  • signature – method signature string to add
Returns:index of entry
/** * Add a new Methodref constant to the ConstantPool, if it is not already in * there. * * @param class_name class name string to add * @param method_name method name string to add * @param signature method signature string to add * @return index of entry */
public int addMethodref(final String class_name, final String method_name, final String signature) { int ret; int class_index; int name_and_type_index; if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) { return ret; // Already in CP } adjustSize(); name_and_type_index = addNameAndType(method_name, signature); class_index = addClass(class_name); ret = index; constants[index++] = new ConstantMethodref(class_index, name_and_type_index); final String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature; if (!cp_table.containsKey(key)) { cp_table.put(key, new Index(ret)); } return ret; } public int addMethodref(final MethodGen method) { return addMethodref(method.getClassName(), method.getName(), method.getSignature()); }
Look for ConstantInterfaceMethodref in ConstantPool.
Params:
  • class_name – Where to find method
  • method_name – Guess what
  • signature – return and argument types
Returns:index on success, -1 otherwise
/** * Look for ConstantInterfaceMethodref in ConstantPool. * * @param class_name Where to find method * @param method_name Guess what * @param signature return and argument types * @return index on success, -1 otherwise */
public int lookupInterfaceMethodref(final String class_name, final String method_name, final String signature) { final Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature); return (index != null) ? index.index : -1; } public int lookupInterfaceMethodref(final MethodGen method) { return lookupInterfaceMethodref(method.getClassName(), method.getName(), method .getSignature()); }
Add a new InterfaceMethodref constant to the ConstantPool, if it is not already in there.
Params:
  • class_name – class name string to add
  • method_name – method name string to add
  • signature – signature string to add
Returns:index of entry
/** * Add a new InterfaceMethodref constant to the ConstantPool, if it is not * already in there. * * @param class_name class name string to add * @param method_name method name string to add * @param signature signature string to add * @return index of entry */
public int addInterfaceMethodref(final String class_name, final String method_name, final String signature) { int ret; int class_index; int name_and_type_index; if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) { return ret; // Already in CP } adjustSize(); class_index = addClass(class_name); name_and_type_index = addNameAndType(method_name, signature); ret = index; constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); final String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature; if (!cp_table.containsKey(key)) { cp_table.put(key, new Index(ret)); } return ret; } public int addInterfaceMethodref(final MethodGen method) { return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature()); }
Look for ConstantFieldref in ConstantPool.
Params:
  • class_name – Where to find method
  • field_name – Guess what
  • signature – return and argument types
Returns:index on success, -1 otherwise
/** * Look for ConstantFieldref in ConstantPool. * * @param class_name Where to find method * @param field_name Guess what * @param signature return and argument types * @return index on success, -1 otherwise */
public int lookupFieldref(final String class_name, final String field_name, final String signature) { final Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature); return (index != null) ? index.index : -1; }
Add a new Fieldref constant to the ConstantPool, if it is not already in there.
Params:
  • class_name – class name string to add
  • field_name – field name string to add
  • signature – signature string to add
Returns:index of entry
/** * Add a new Fieldref constant to the ConstantPool, if it is not already in * there. * * @param class_name class name string to add * @param field_name field name string to add * @param signature signature string to add * @return index of entry */
public int addFieldref(final String class_name, final String field_name, final String signature) { int ret; int class_index; int name_and_type_index; if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) { return ret; // Already in CP } adjustSize(); class_index = addClass(class_name); name_and_type_index = addNameAndType(field_name, signature); ret = index; constants[index++] = new ConstantFieldref(class_index, name_and_type_index); final String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature; if (!cp_table.containsKey(key)) { cp_table.put(key, new Index(ret)); } return ret; }
Params:
  • i – index in constant pool
Returns:constant pool entry at index i
/** * @param i index in constant pool * @return constant pool entry at index i */
public Constant getConstant(final int i) { return constants[i]; }
Use with care!
Params:
  • i – index in constant pool
  • c – new constant pool entry at index i
/** * Use with care! * * @param i index in constant pool * @param c new constant pool entry at index i */
public void setConstant(final int i, final Constant c) { constants[i] = c; }
Returns:intermediate constant pool
/** * @return intermediate constant pool */
public ConstantPool getConstantPool() { return new ConstantPool(constants); }
Returns:current size of constant pool
/** * @return current size of constant pool */
public int getSize() { return index; }
Returns:constant pool with proper length
/** * @return constant pool with proper length */
public ConstantPool getFinalConstantPool() { final Constant[] cs = new Constant[index]; System.arraycopy(constants, 0, cs, 0, index); return new ConstantPool(cs); }
Returns:String representation.
/** * @return String representation. */
@Override public String toString() { final StringBuilder buf = new StringBuilder(); for (int i = 1; i < index; i++) { buf.append(i).append(")").append(constants[i]).append("\n"); } return buf.toString(); }
Import constant from another ConstantPool and return new index.
/** * Import constant from another ConstantPool and return new index. */
public int addConstant(final Constant c, final ConstantPoolGen cp) { final Constant[] constants = cp.getConstantPool().getConstantPool(); switch (c.getTag()) { case Const.CONSTANT_String: { final ConstantString s = (ConstantString) c; final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; return addString(u8.getBytes()); } case Const.CONSTANT_Class: { final ConstantClass s = (ConstantClass) c; final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; return addClass(u8.getBytes()); } case Const.CONSTANT_NameAndType: { final ConstantNameAndType n = (ConstantNameAndType) c; final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; return addNameAndType(u8.getBytes(), u8_2.getBytes()); } case Const.CONSTANT_Utf8: return addUtf8(((ConstantUtf8) c).getBytes()); case Const.CONSTANT_Double: return addDouble(((ConstantDouble) c).getBytes()); case Const.CONSTANT_Float: return addFloat(((ConstantFloat) c).getBytes()); case Const.CONSTANT_Long: return addLong(((ConstantLong) c).getBytes()); case Const.CONSTANT_Integer: return addInteger(((ConstantInteger) c).getBytes()); case Const.CONSTANT_InterfaceMethodref: case Const.CONSTANT_Methodref: case Const.CONSTANT_Fieldref: { final ConstantCP m = (ConstantCP) c; final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; final String class_name = u8.getBytes().replace('/', '.'); u8 = (ConstantUtf8) constants[n.getNameIndex()]; final String name = u8.getBytes(); u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; final String signature = u8.getBytes(); switch (c.getTag()) { case Const.CONSTANT_InterfaceMethodref: return addInterfaceMethodref(class_name, name, signature); case Const.CONSTANT_Methodref: return addMethodref(class_name, name, signature); case Const.CONSTANT_Fieldref: return addFieldref(class_name, name, signature); default: // Never reached throw new RuntimeException("Unknown constant type " + c); } } default: // Never reached throw new RuntimeException("Unknown constant type " + c); } } }