Copyright (c) 2000, 2019 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation Jesper S Moller - Contributions for Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335 Bug 406982 - [1.8][compiler] Generation of MethodParameters Attribute in classfile Bug 416885 - [1.8][compiler]IncompatibleClassChange error (edit) Bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas Bug 439889 - [1.8][compiler] [lambda] Deserializing lambda fails with IllegalArgumentException: "Invalid lambda deserialization"
/******************************************************************************* * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation * Jesper S Moller - Contributions for * Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335 * Bug 406982 - [1.8][compiler] Generation of MethodParameters Attribute in classfile * Bug 416885 - [1.8][compiler]IncompatibleClassChange error (edit) * Bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for * Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas * Bug 439889 - [1.8][compiler] [lambda] Deserializing lambda fails with IllegalArgumentException: "Invalid lambda deserialization" *******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.ClassFile; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.TagBits; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.eclipse.jdt.internal.compiler.util.HashtableOfInteger; import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; import org.eclipse.jdt.internal.compiler.util.Util;
This type is used to store all the constant pool entries.
/** * This type is used to store all the constant pool entries. */
public class ConstantPool implements ClassFileConstants, TypeIds { public static final int DOUBLE_INITIAL_SIZE = 5; public static final int FLOAT_INITIAL_SIZE = 3; public static final int INT_INITIAL_SIZE = 248; public static final int LONG_INITIAL_SIZE = 5; public static final int UTF8_INITIAL_SIZE = 778; public static final int STRING_INITIAL_SIZE = 761; public static final int METHODS_AND_FIELDS_INITIAL_SIZE = 450; public static final int CLASS_INITIAL_SIZE = 86; public static final int NAMEANDTYPE_INITIAL_SIZE = 272; public static final int CONSTANTPOOL_INITIAL_SIZE = 2000; public static final int CONSTANTPOOL_GROW_SIZE = 6000; public static final int DYNAMIC_INITIAL_SIZE = 10; protected DoubleCache doubleCache; protected FloatCache floatCache; protected IntegerCache intCache; protected LongCache longCache; public CharArrayCache UTF8Cache; protected CharArrayCache stringCache; protected HashtableOfObject methodsAndFieldsCache; protected CharArrayCache classCache; protected CharArrayCache moduleCache; protected CharArrayCache packageCache; protected HashtableOfObject nameAndTypeCacheForFieldsAndMethods; protected HashtableOfInteger dynamicCache; public byte[] poolContent; public int currentIndex = 1; public int currentOffset; public int[] offsets; public ClassFile classFile; public static final char[] Append = "append".toCharArray(); //$NON-NLS-1$ public static final char[] ARRAY_NEWINSTANCE_NAME = "newInstance".toCharArray(); //$NON-NLS-1$ public static final char[] ARRAY_NEWINSTANCE_SIGNATURE = "(Ljava/lang/Class;[I)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$ public static final char[] ArrayCopy = "arraycopy".toCharArray(); //$NON-NLS-1$ public static final char[] ArrayCopySignature = "(Ljava/lang/Object;ILjava/lang/Object;II)V".toCharArray(); //$NON-NLS-1$ public static final char[] ArrayJavaLangClassConstantPoolName = "[Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$ public static final char[] ArrayJavaLangObjectConstantPoolName = "[Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$ public static final char[] booleanBooleanSignature = "(Z)Ljava/lang/Boolean;".toCharArray(); //$NON-NLS-1$ public static final char[] BooleanConstrSignature = "(Z)V".toCharArray(); //$NON-NLS-1$ public static final char[] BOOLEANVALUE_BOOLEAN_METHOD_NAME = "booleanValue".toCharArray(); //$NON-NLS-1$ public static final char[] BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE = "()Z".toCharArray(); //$NON-NLS-1$ public static final char[] byteByteSignature = "(B)Ljava/lang/Byte;".toCharArray(); //$NON-NLS-1$ public static final char[] ByteConstrSignature = "(B)V".toCharArray(); //$NON-NLS-1$ public static final char[] BYTEVALUE_BYTE_METHOD_NAME = "byteValue".toCharArray(); //$NON-NLS-1$ public static final char[] BYTEVALUE_BYTE_METHOD_SIGNATURE = "()B".toCharArray(); //$NON-NLS-1$ public static final char[] charCharacterSignature = "(C)Ljava/lang/Character;".toCharArray(); //$NON-NLS-1$ public static final char[] CharConstrSignature = "(C)V".toCharArray(); //$NON-NLS-1$ public static final char[] CHARVALUE_CHARACTER_METHOD_NAME = "charValue".toCharArray(); //$NON-NLS-1$ public static final char[] CHARVALUE_CHARACTER_METHOD_SIGNATURE = "()C".toCharArray(); //$NON-NLS-1$ public static final char[] Clinit = "<clinit>".toCharArray(); //$NON-NLS-1$ public static final char[] DefaultConstructorSignature = "()V".toCharArray(); //$NON-NLS-1$ public static final char[] ClinitSignature = DefaultConstructorSignature; public static final char[] Close = "close".toCharArray(); //$NON-NLS-1$ public static final char[] CloseSignature = "()V".toCharArray(); //$NON-NLS-1$ public static final char[] DesiredAssertionStatus = "desiredAssertionStatus".toCharArray(); //$NON-NLS-1$ public static final char[] DesiredAssertionStatusSignature = "()Z".toCharArray(); //$NON-NLS-1$ public static final char[] DoubleConstrSignature = "(D)V".toCharArray(); //$NON-NLS-1$ public static final char[] doubleDoubleSignature = "(D)Ljava/lang/Double;".toCharArray(); //$NON-NLS-1$ public static final char[] DOUBLEVALUE_DOUBLE_METHOD_NAME = "doubleValue".toCharArray(); //$NON-NLS-1$ public static final char[] DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE = "()D".toCharArray(); //$NON-NLS-1$ public static final char[] EnumName = "$enum$name".toCharArray();//$NON-NLS-1$ public static final char[] EnumOrdinal = "$enum$ordinal".toCharArray();//$NON-NLS-1$ public static final char[] Exit = "exit".toCharArray(); //$NON-NLS-1$ public static final char[] ExitIntSignature = "(I)V".toCharArray(); //$NON-NLS-1$ public static final char[] FloatConstrSignature = "(F)V".toCharArray(); //$NON-NLS-1$ public static final char[] floatFloatSignature = "(F)Ljava/lang/Float;".toCharArray(); //$NON-NLS-1$ public static final char[] FLOATVALUE_FLOAT_METHOD_NAME = "floatValue".toCharArray(); //$NON-NLS-1$ public static final char[] FLOATVALUE_FLOAT_METHOD_SIGNATURE = "()F".toCharArray(); //$NON-NLS-1$ public static final char[] ForName = "forName".toCharArray(); //$NON-NLS-1$ public static final char[] ForNameSignature = "(Ljava/lang/String;)Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$ public static final char[] GET_BOOLEAN_METHOD_NAME = "getBoolean".toCharArray(); //$NON-NLS-1$ public static final char[] GET_BOOLEAN_METHOD_SIGNATURE = "(Ljava/lang/Object;)Z".toCharArray(); //$NON-NLS-1$ public static final char[] GET_BYTE_METHOD_NAME = "getByte".toCharArray(); //$NON-NLS-1$ public static final char[] GET_BYTE_METHOD_SIGNATURE = "(Ljava/lang/Object;)B".toCharArray(); //$NON-NLS-1$ public static final char[] GET_CHAR_METHOD_NAME = "getChar".toCharArray(); //$NON-NLS-1$ public static final char[] GET_CHAR_METHOD_SIGNATURE = "(Ljava/lang/Object;)C".toCharArray(); //$NON-NLS-1$ public static final char[] GET_DOUBLE_METHOD_NAME = "getDouble".toCharArray(); //$NON-NLS-1$ public static final char[] GET_DOUBLE_METHOD_SIGNATURE = "(Ljava/lang/Object;)D".toCharArray(); //$NON-NLS-1$ public static final char[] GET_FLOAT_METHOD_NAME = "getFloat".toCharArray(); //$NON-NLS-1$ public static final char[] GET_FLOAT_METHOD_SIGNATURE = "(Ljava/lang/Object;)F".toCharArray(); //$NON-NLS-1$ public static final char[] GET_INT_METHOD_NAME = "getInt".toCharArray(); //$NON-NLS-1$ public static final char[] GET_INT_METHOD_SIGNATURE = "(Ljava/lang/Object;)I".toCharArray(); //$NON-NLS-1$ public static final char[] GET_LONG_METHOD_NAME = "getLong".toCharArray(); //$NON-NLS-1$ public static final char[] GET_LONG_METHOD_SIGNATURE = "(Ljava/lang/Object;)J".toCharArray(); //$NON-NLS-1$ public static final char[] GET_OBJECT_METHOD_NAME = "get".toCharArray(); //$NON-NLS-1$ public static final char[] GET_OBJECT_METHOD_SIGNATURE = "(Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$ public static final char[] GET_SHORT_METHOD_NAME = "getShort".toCharArray(); //$NON-NLS-1$ public static final char[] GET_SHORT_METHOD_SIGNATURE = "(Ljava/lang/Object;)S".toCharArray(); //$NON-NLS-1$ public static final char[] GetClass = "getClass".toCharArray(); //$NON-NLS-1$ public static final char[] GetClassSignature = "()Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$ public static final char[] GetComponentType = "getComponentType".toCharArray(); //$NON-NLS-1$ public static final char[] GetComponentTypeSignature = GetClassSignature; public static final char[] GetConstructor = "getConstructor".toCharArray(); //$NON-NLS-1$ public static final char[] GetConstructorSignature = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;".toCharArray(); //$NON-NLS-1$ public static final char[] GETDECLAREDCONSTRUCTOR_NAME = "getDeclaredConstructor".toCharArray(); //$NON-NLS-1$ public static final char[] GETDECLAREDCONSTRUCTOR_SIGNATURE = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;".toCharArray(); //$NON-NLS-1$ // predefined methods constant names public static final char[] GETDECLAREDFIELD_NAME = "getDeclaredField".toCharArray(); //$NON-NLS-1$ public static final char[] GETDECLAREDFIELD_SIGNATURE = "(Ljava/lang/String;)Ljava/lang/reflect/Field;".toCharArray(); //$NON-NLS-1$ public static final char[] GETDECLAREDMETHOD_NAME = "getDeclaredMethod".toCharArray(); //$NON-NLS-1$ public static final char[] GETDECLAREDMETHOD_SIGNATURE = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;".toCharArray(); //$NON-NLS-1$ public static final char[] GetMessage = "getMessage".toCharArray(); //$NON-NLS-1$ public static final char[] GetMessageSignature = "()Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] HasNext = "hasNext".toCharArray();//$NON-NLS-1$ public static final char[] HasNextSignature = "()Z".toCharArray();//$NON-NLS-1$ public static final char[] Init = "<init>".toCharArray(); //$NON-NLS-1$ public static final char[] IntConstrSignature = "(I)V".toCharArray(); //$NON-NLS-1$ public static final char[] ITERATOR_NAME = "iterator".toCharArray(); //$NON-NLS-1$ public static final char[] ITERATOR_SIGNATURE = "()Ljava/util/Iterator;".toCharArray(); //$NON-NLS-1$ public static final char[] Intern = "intern".toCharArray(); //$NON-NLS-1$ public static final char[] InternSignature = GetMessageSignature; public static final char[] IntIntegerSignature = "(I)Ljava/lang/Integer;".toCharArray(); //$NON-NLS-1$ public static final char[] INTVALUE_INTEGER_METHOD_NAME = "intValue".toCharArray(); //$NON-NLS-1$ public static final char[] INTVALUE_INTEGER_METHOD_SIGNATURE = "()I".toCharArray(); //$NON-NLS-1$ public static final char[] INVOKE_METHOD_METHOD_NAME = "invoke".toCharArray(); //$NON-NLS-1$ public static final char[] INVOKE_METHOD_METHOD_SIGNATURE = "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$ public static final char[][] JAVA_LANG_REFLECT_ACCESSIBLEOBJECT = new char[][] {TypeConstants.JAVA, TypeConstants.LANG, TypeConstants.REFLECT, "AccessibleObject".toCharArray()}; //$NON-NLS-1$ public static final char[][] JAVA_LANG_REFLECT_ARRAY = new char[][] {TypeConstants.JAVA, TypeConstants.LANG, TypeConstants.REFLECT, "Array".toCharArray()}; //$NON-NLS-1$ public static final char[] IllegalArgumentExceptionConstructorSignature = "(Ljava/lang/String;)V".toCharArray(); //$NON-NLS-1$ // predefined type constant names public static final char[] JavaIoPrintStreamSignature = "Ljava/io/PrintStream;".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangAssertionErrorConstantPoolName = "java/lang/AssertionError".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangBooleanConstantPoolName = "java/lang/Boolean".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangByteConstantPoolName = "java/lang/Byte".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangCharacterConstantPoolName = "java/lang/Character".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangClassConstantPoolName = "java/lang/Class".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangClassNotFoundExceptionConstantPoolName = "java/lang/ClassNotFoundException".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangClassSignature = "Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangDoubleConstantPoolName = "java/lang/Double".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangEnumConstantPoolName = "java/lang/Enum".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangErrorConstantPoolName = "java/lang/Error".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangIncompatibleClassChangeErrorConstantPoolName = "java/lang/IncompatibleClassChangeError".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangExceptionConstantPoolName = "java/lang/Exception".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangFloatConstantPoolName = "java/lang/Float".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangIntegerConstantPoolName = "java/lang/Integer".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangLongConstantPoolName = "java/lang/Long".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangNoClassDefFoundErrorConstantPoolName = "java/lang/NoClassDefFoundError".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangNoSuchFieldErrorConstantPoolName = "java/lang/NoSuchFieldError".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangObjectConstantPoolName = "java/lang/Object".toCharArray(); //$NON-NLS-1$ public static final char[] JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME = "java/lang/reflect/AccessibleObject".toCharArray(); //$NON-NLS-1$ public static final char[] JAVALANGREFLECTARRAY_CONSTANTPOOLNAME = "java/lang/reflect/Array".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangReflectConstructorConstantPoolName = "java/lang/reflect/Constructor".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangReflectConstructorNewInstanceSignature = "([Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$ public static final char[] JAVALANGREFLECTFIELD_CONSTANTPOOLNAME = "java/lang/reflect/Field".toCharArray(); //$NON-NLS-1$ public static final char[] JAVALANGREFLECTMETHOD_CONSTANTPOOLNAME = "java/lang/reflect/Method".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangShortConstantPoolName = "java/lang/Short".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangStringBufferConstantPoolName = "java/lang/StringBuffer".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangStringBuilderConstantPoolName = "java/lang/StringBuilder".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangStringConstantPoolName = "java/lang/String".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangStringSignature = "Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangObjectSignature = "Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangSystemConstantPoolName = "java/lang/System".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangThrowableConstantPoolName = "java/lang/Throwable".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangIllegalArgumentExceptionConstantPoolName = "java/lang/IllegalArgumentException".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangVoidConstantPoolName = "java/lang/Void".toCharArray(); //$NON-NLS-1$ public static final char[] JavaUtilIteratorConstantPoolName = "java/util/Iterator".toCharArray(); //$NON-NLS-1$ public static final char[] LongConstrSignature = "(J)V".toCharArray(); //$NON-NLS-1$ public static final char[] longLongSignature = "(J)Ljava/lang/Long;".toCharArray(); //$NON-NLS-1$ public static final char[] LONGVALUE_LONG_METHOD_NAME = "longValue".toCharArray(); //$NON-NLS-1$ public static final char[] LONGVALUE_LONG_METHOD_SIGNATURE = "()J".toCharArray(); //$NON-NLS-1$ public static final char[] Name = "name".toCharArray();//$NON-NLS-1$ public static final char[] NewInstance = "newInstance".toCharArray(); //$NON-NLS-1$ public static final char[] NewInstanceSignature = "(Ljava/lang/Class;[I)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$ public static final char[] Next = "next".toCharArray();//$NON-NLS-1$ public static final char[] NextSignature = "()Ljava/lang/Object;".toCharArray();//$NON-NLS-1$ public static final char[] ObjectConstrSignature = "(Ljava/lang/Object;)V".toCharArray(); //$NON-NLS-1$ public static final char[] ObjectSignature = "Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$ public static final char[] Ordinal = "ordinal".toCharArray(); //$NON-NLS-1$ public static final char[] OrdinalSignature = "()I".toCharArray(); //$NON-NLS-1$ public static final char[] Out = "out".toCharArray(); //$NON-NLS-1$ public static final char[] SET_BOOLEAN_METHOD_NAME = "setBoolean".toCharArray(); //$NON-NLS-1$ public static final char[] SET_BOOLEAN_METHOD_SIGNATURE = "(Ljava/lang/Object;Z)V".toCharArray(); //$NON-NLS-1$ public static final char[] SET_BYTE_METHOD_NAME = "setByte".toCharArray(); //$NON-NLS-1$ public static final char[] SET_BYTE_METHOD_SIGNATURE = "(Ljava/lang/Object;B)V".toCharArray(); //$NON-NLS-1$ public static final char[] SET_CHAR_METHOD_NAME = "setChar".toCharArray(); //$NON-NLS-1$ public static final char[] SET_CHAR_METHOD_SIGNATURE = "(Ljava/lang/Object;C)V".toCharArray(); //$NON-NLS-1$ public static final char[] SET_DOUBLE_METHOD_NAME = "setDouble".toCharArray(); //$NON-NLS-1$ public static final char[] SET_DOUBLE_METHOD_SIGNATURE = "(Ljava/lang/Object;D)V".toCharArray(); //$NON-NLS-1$ public static final char[] SET_FLOAT_METHOD_NAME = "setFloat".toCharArray(); //$NON-NLS-1$ public static final char[] SET_FLOAT_METHOD_SIGNATURE = "(Ljava/lang/Object;F)V".toCharArray(); //$NON-NLS-1$ public static final char[] SET_INT_METHOD_NAME = "setInt".toCharArray(); //$NON-NLS-1$ public static final char[] SET_INT_METHOD_SIGNATURE = "(Ljava/lang/Object;I)V".toCharArray(); //$NON-NLS-1$ public static final char[] SET_LONG_METHOD_NAME = "setLong".toCharArray(); //$NON-NLS-1$ public static final char[] SET_LONG_METHOD_SIGNATURE = "(Ljava/lang/Object;J)V".toCharArray(); //$NON-NLS-1$ public static final char[] SET_OBJECT_METHOD_NAME = "set".toCharArray(); //$NON-NLS-1$ public static final char[] SET_OBJECT_METHOD_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/Object;)V".toCharArray(); //$NON-NLS-1$ public static final char[] SET_SHORT_METHOD_NAME = "setShort".toCharArray(); //$NON-NLS-1$ public static final char[] SET_SHORT_METHOD_SIGNATURE = "(Ljava/lang/Object;S)V".toCharArray(); //$NON-NLS-1$ public static final char[] SETACCESSIBLE_NAME = "setAccessible".toCharArray(); //$NON-NLS-1$ public static final char[] SETACCESSIBLE_SIGNATURE = "(Z)V".toCharArray(); //$NON-NLS-1$ public static final char[] ShortConstrSignature = "(S)V".toCharArray(); //$NON-NLS-1$ public static final char[] shortShortSignature = "(S)Ljava/lang/Short;".toCharArray(); //$NON-NLS-1$ public static final char[] SHORTVALUE_SHORT_METHOD_NAME = "shortValue".toCharArray(); //$NON-NLS-1$ public static final char[] SHORTVALUE_SHORT_METHOD_SIGNATURE = "()S".toCharArray(); //$NON-NLS-1$ public static final char[] StringBufferAppendBooleanSignature = "(Z)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBufferAppendCharSignature = "(C)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBufferAppendDoubleSignature = "(D)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBufferAppendFloatSignature = "(F)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBufferAppendIntSignature = "(I)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBufferAppendLongSignature = "(J)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBufferAppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBufferAppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBuilderAppendBooleanSignature = "(Z)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBuilderAppendCharSignature = "(C)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBuilderAppendDoubleSignature = "(D)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBuilderAppendFloatSignature = "(F)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBuilderAppendIntSignature = "(I)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBuilderAppendLongSignature = "(J)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBuilderAppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$ public static final char[] StringBuilderAppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$ public static final char[] StringConstructorSignature = "(Ljava/lang/String;)V".toCharArray(); //$NON-NLS-1$ public static final char[] This = "this".toCharArray(); //$NON-NLS-1$ public static final char[] ToString = "toString".toCharArray(); //$NON-NLS-1$ public static final char[] ToStringSignature = GetMessageSignature; public static final char[] TYPE = "TYPE".toCharArray(); //$NON-NLS-1$ public static final char[] ValueOf = "valueOf".toCharArray(); //$NON-NLS-1$ public static final char[] ValueOfBooleanSignature = "(Z)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] ValueOfCharSignature = "(C)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] ValueOfDoubleSignature = "(D)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] ValueOfFloatSignature = "(F)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] ValueOfIntSignature = "(I)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] ValueOfLongSignature = "(J)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] ValueOfObjectSignature = "(Ljava/lang/Object;)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] ValueOfStringClassSignature = "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;".toCharArray(); //$NON-NLS-1$ public static final char[] JAVA_LANG_ANNOTATION_DOCUMENTED = "Ljava/lang/annotation/Documented;".toCharArray(); //$NON-NLS-1$ public static final char[] JAVA_LANG_ANNOTATION_ELEMENTTYPE = "Ljava/lang/annotation/ElementType;".toCharArray(); //$NON-NLS-1$ public static final char[] JAVA_LANG_ANNOTATION_RETENTION = "Ljava/lang/annotation/Retention;".toCharArray(); //$NON-NLS-1$ public static final char[] JAVA_LANG_ANNOTATION_RETENTIONPOLICY = "Ljava/lang/annotation/RetentionPolicy;".toCharArray(); //$NON-NLS-1$ public static final char[] JAVA_LANG_ANNOTATION_TARGET = "Ljava/lang/annotation/Target;".toCharArray(); //$NON-NLS-1$ public static final char[] JAVA_LANG_DEPRECATED = "Ljava/lang/Deprecated;".toCharArray(); //$NON-NLS-1$ public static final char[] JAVA_LANG_ANNOTATION_INHERITED = "Ljava/lang/annotation/Inherited;".toCharArray(); //$NON-NLS-1$ // java 7 java.lang.SafeVarargs public static final char[] JAVA_LANG_SAFEVARARGS = "Ljava/lang/SafeVarargs;".toCharArray(); //$NON-NLS-1$ // java 7 java.lang.invoke.MethodHandle.invokeExact(..)/invoke(..) public static final char[] JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE = "Ljava/lang/invoke/MethodHandle$PolymorphicSignature;".toCharArray(); //$NON-NLS-1$ // Java 8 lambda support public static final char[] METAFACTORY = "metafactory".toCharArray(); //$NON-NLS-1$ public static final char[] JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_METAFACTORY_SIGNATURE = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;".toCharArray(); //$NON-NLS-1$ public static final char[] ALTMETAFACTORY = "altMetafactory".toCharArray(); //$NON-NLS-1$ public static final char[] JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_ALTMETAFACTORY_SIGNATURE = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangInvokeSerializedLambda = "Ljava/lang/invoke/SerializedLambda;".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangInvokeSerializedLambdaConstantPoolName = "java/lang/invoke/SerializedLambda".toCharArray(); //$NON-NLS-1$ public static final char[] GetImplMethodName = "getImplMethodName".toCharArray(); //$NON-NLS-1$ public static final char[] GetImplMethodNameSignature = "()Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] GetImplMethodKind = "getImplMethodKind".toCharArray(); //$NON-NLS-1$ public static final char[] GetImplMethodKindSignature = "()I".toCharArray(); //$NON-NLS-1$ public static final char[] GetFunctionalInterfaceClass = "getFunctionalInterfaceClass".toCharArray(); //$NON-NLS-1$ public static final char[] GetFunctionalInterfaceClassSignature = "()Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] GetFunctionalInterfaceMethodName = "getFunctionalInterfaceMethodName".toCharArray(); //$NON-NLS-1$ public static final char[] GetFunctionalInterfaceMethodNameSignature = "()Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] GetFunctionalInterfaceMethodSignature = "getFunctionalInterfaceMethodSignature".toCharArray(); //$NON-NLS-1$ public static final char[] GetFunctionalInterfaceMethodSignatureSignature = "()Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] GetImplClass = "getImplClass".toCharArray(); //$NON-NLS-1$ public static final char[] GetImplClassSignature = "()Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] GetImplMethodSignature = "getImplMethodSignature".toCharArray(); //$NON-NLS-1$ public static final char[] GetImplMethodSignatureSignature = "()Ljava/lang/String;".toCharArray(); //$NON-NLS-1$ public static final char[] GetCapturedArg = "getCapturedArg".toCharArray(); //$NON-NLS-1$ public static final char[] GetCapturedArgSignature = "(I)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$ // Java 8 repeatable annotation support public static final char[] JAVA_LANG_ANNOTATION_REPEATABLE = "Ljava/lang/annotation/Repeatable;".toCharArray(); //$NON-NLS-1$ public static final char[] HashCode = "hashCode".toCharArray(); //$NON-NLS-1$ public static final char[] HashCodeSignature = "()I".toCharArray(); //$NON-NLS-1$; public static final char[] Equals = "equals".toCharArray(); //$NON-NLS-1$ public static final char[] EqualsSignature = "(Ljava/lang/Object;)Z".toCharArray(); //$NON-NLS-1$; public static final char[] AddSuppressed = "addSuppressed".toCharArray(); //$NON-NLS-1$; public static final char[] AddSuppressedSignature = "(Ljava/lang/Throwable;)V".toCharArray(); //$NON-NLS-1$ public static final char[] Clone = "clone".toCharArray(); //$NON-NLS-1$ public static final char[] CloneSignature = "()Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
ConstantPool constructor comment.
/** * ConstantPool constructor comment. */
public ConstantPool(ClassFile classFile) { this.UTF8Cache = new CharArrayCache(UTF8_INITIAL_SIZE); this.stringCache = new CharArrayCache(STRING_INITIAL_SIZE); this.methodsAndFieldsCache = new HashtableOfObject(METHODS_AND_FIELDS_INITIAL_SIZE); this.classCache = new CharArrayCache(CLASS_INITIAL_SIZE); this.moduleCache = new CharArrayCache(5); this.packageCache = new CharArrayCache(5); this.nameAndTypeCacheForFieldsAndMethods = new HashtableOfObject(NAMEANDTYPE_INITIAL_SIZE); this.dynamicCache = new HashtableOfInteger(DYNAMIC_INITIAL_SIZE); this.offsets = new int[5]; initialize(classFile); } public void initialize(ClassFile givenClassFile) { this.poolContent = givenClassFile.header; this.currentOffset = givenClassFile.headerOffset; // currentOffset is initialized to 0 by default this.currentIndex = 1; this.classFile = givenClassFile; }
Return the content of the receiver
/** * Return the content of the receiver */
public byte[] dumpBytes() { System.arraycopy(this.poolContent, 0, (this.poolContent = new byte[this.currentOffset]), 0, this.currentOffset); return this.poolContent; } public int literalIndex(byte[] utf8encoding, char[] stringCharArray) { int index; if ((index = this.UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { // The entry doesn't exit yet if ((index = -index)> 0xFFFF) { this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } this.currentIndex++; // Write the tag first int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(Utf8Tag); int utf8encodingLength = utf8encoding.length; if (this.currentOffset + 2 + utf8encodingLength >= this.poolContent.length) { // we need to resize the poolContent array because we won't have // enough space to write the length resizePoolContents(2 + utf8encodingLength); } this.poolContent[this.currentOffset++] = (byte) (utf8encodingLength >> 8); this.poolContent[this.currentOffset++] = (byte) utf8encodingLength; // add in once the whole byte array System.arraycopy(utf8encoding, 0, this.poolContent, this.currentOffset, utf8encodingLength); this.currentOffset += utf8encodingLength; } return index; } public int literalIndex(TypeBinding binding) { TypeBinding typeBinding = binding.leafComponentType(); if ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { Util.recordNestedType(this.classFile, typeBinding); } return literalIndex(binding.signature()); }
This method returns the index into the constantPool corresponding to the type descriptor.
Params:
  • utf8Constant – char[]
Returns:int
/** * This method returns the index into the constantPool corresponding to the type descriptor. * * @param utf8Constant char[] * @return <CODE>int</CODE> */
public int literalIndex(char[] utf8Constant) { int index; if ((index = this.UTF8Cache.putIfAbsent(utf8Constant, this.currentIndex)) < 0) { if ((index = -index)> 0xFFFF) { this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // The entry doesn't exit yet // Write the tag first int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(Utf8Tag); // Then the size of the stringName array int savedCurrentOffset = this.currentOffset; if (this.currentOffset + 2 >= this.poolContent.length) { // we need to resize the poolContent array because we won't have // enough space to write the length resizePoolContents(2); } this.currentOffset += 2; length = 0; for (int i = 0; i < utf8Constant.length; i++) { char current = utf8Constant[i]; if ((current >= 0x0001) && (current <= 0x007F)) { // we only need one byte: ASCII table writeU1(current); length++; } else { if (current > 0x07FF) { // we need 3 bytes length += 3; writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000 writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000 writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000 } else { // we can be 0 or between 0x0080 and 0x07FF // In that case we only need 2 bytes length += 2; writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000 writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000 } } } if (length >= 65535) { this.currentOffset = savedCurrentOffset - 1; this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceForConstant(this.classFile.referenceBinding.scope.referenceType()); } if (index > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } this.currentIndex++; // Now we know the length that we have to write in the constant pool // we use savedCurrentOffset to do that this.poolContent[savedCurrentOffset] = (byte) (length >> 8); this.poolContent[savedCurrentOffset + 1] = (byte) length; } return index; } public int literalIndex(char[] stringCharArray, byte[] utf8encoding) { int index; if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { // The entry doesn't exit yet this.currentIndex++; if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // Write the tag first int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(StringTag); // Then the string index int stringIndexOffset = this.currentOffset; if (this.currentOffset + 2 >= this.poolContent.length) { resizePoolContents(2); } this.currentOffset+=2; final int stringIndex = literalIndex(utf8encoding, stringCharArray); this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); this.poolContent[stringIndexOffset] = (byte) stringIndex; } return index; }
This method returns the index into the constantPool corresponding to the double value. If the double is not already present into the pool, it is added. The double cache is updated and it returns the right index.
Params:
  • key – double
Returns:int
/** * This method returns the index into the constantPool corresponding to the double * value. If the double is not already present into the pool, it is added. The * double cache is updated and it returns the right index. * * @param key <CODE>double</CODE> * @return <CODE>int</CODE> */
public int literalIndex(double key) { //Retrieve the index from the cache // The double constant takes two indexes into the constant pool, but we only store // the first index into the long table int index; // lazy initialization for base type caches // If it is null, initialize it, otherwise use it if (this.doubleCache == null) { this.doubleCache = new DoubleCache(DOUBLE_INITIAL_SIZE); } if ((index = this.doubleCache.putIfAbsent(key, this.currentIndex)) < 0) { if ((index = -index)> 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } this.currentIndex += 2; // a double needs an extra place into the constant pool // Write the double into the constant pool // First add the tag int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(DoubleTag); // Then add the 8 bytes representing the double long temp = java.lang.Double.doubleToLongBits(key); length = this.poolContent.length; if (this.currentOffset + 8 >= length) { resizePoolContents(8); } this.poolContent[this.currentOffset++] = (byte) (temp >>> 56); this.poolContent[this.currentOffset++] = (byte) (temp >>> 48); this.poolContent[this.currentOffset++] = (byte) (temp >>> 40); this.poolContent[this.currentOffset++] = (byte) (temp >>> 32); this.poolContent[this.currentOffset++] = (byte) (temp >>> 24); this.poolContent[this.currentOffset++] = (byte) (temp >>> 16); this.poolContent[this.currentOffset++] = (byte) (temp >>> 8); this.poolContent[this.currentOffset++] = (byte) temp; } return index; }
This method returns the index into the constantPool corresponding to the float value. If the float is not already present into the pool, it is added. The int cache is updated and it returns the right index.
Params:
  • key – float
Returns:int
/** * This method returns the index into the constantPool corresponding to the float * value. If the float is not already present into the pool, it is added. The * int cache is updated and it returns the right index. * * @param key <CODE>float</CODE> * @return <CODE>int</CODE> */
public int literalIndex(float key) { //Retrieve the index from the cache int index; // lazy initialization for base type caches // If it is null, initialize it, otherwise use it if (this.floatCache == null) { this.floatCache = new FloatCache(FLOAT_INITIAL_SIZE); } if ((index = this.floatCache.putIfAbsent(key, this.currentIndex)) < 0) { if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } this.currentIndex++; // Write the float constant entry into the constant pool // First add the tag int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(FloatTag); // Then add the 4 bytes representing the float int temp = java.lang.Float.floatToIntBits(key); if (this.currentOffset + 4 >= this.poolContent.length) { resizePoolContents(4); } this.poolContent[this.currentOffset++] = (byte) (temp >>> 24); this.poolContent[this.currentOffset++] = (byte) (temp >>> 16); this.poolContent[this.currentOffset++] = (byte) (temp >>> 8); this.poolContent[this.currentOffset++] = (byte) temp; } return index; }
This method returns the index into the constantPool corresponding to the int value. If the int is not already present into the pool, it is added. The int cache is updated and it returns the right index.
Params:
  • key – int
Returns:int
/** * This method returns the index into the constantPool corresponding to the int * value. If the int is not already present into the pool, it is added. The * int cache is updated and it returns the right index. * * @param key <CODE>int</CODE> * @return <CODE>int</CODE> */
public int literalIndex(int key) { //Retrieve the index from the cache int index; // lazy initialization for base type caches // If it is null, initialize it, otherwise use it if (this.intCache == null) { this.intCache = new IntegerCache(INT_INITIAL_SIZE); } if ((index = this.intCache.putIfAbsent(key, this.currentIndex)) < 0) { this.currentIndex++; if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // Write the integer constant entry into the constant pool // First add the tag int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(IntegerTag); // Then add the 4 bytes representing the int if (this.currentOffset + 4 >= this.poolContent.length) { resizePoolContents(4); } this.poolContent[this.currentOffset++] = (byte) (key >>> 24); this.poolContent[this.currentOffset++] = (byte) (key >>> 16); this.poolContent[this.currentOffset++] = (byte) (key >>> 8); this.poolContent[this.currentOffset++] = (byte) key; } return index; }
This method returns the index into the constantPool corresponding to the long value. If the long is not already present into the pool, it is added. The long cache is updated and it returns the right index.
Params:
  • key – long
Returns:int
/** * This method returns the index into the constantPool corresponding to the long * value. If the long is not already present into the pool, it is added. The * long cache is updated and it returns the right index. * * @param key <CODE>long</CODE> * @return <CODE>int</CODE> */
public int literalIndex(long key) { // Retrieve the index from the cache // The long constant takes two indexes into the constant pool, but we only store // the first index into the long table int index; // lazy initialization for base type caches // If it is null, initialize it, otherwise use it if (this.longCache == null) { this.longCache = new LongCache(LONG_INITIAL_SIZE); } if ((index = this.longCache.putIfAbsent(key, this.currentIndex)) < 0) { if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } this.currentIndex+= 2; // long value need an extra place into thwe constant pool // Write the long into the constant pool // First add the tag int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(LongTag); // Then add the 8 bytes representing the long if (this.currentOffset + 8 >= this.poolContent.length) { resizePoolContents(8); } this.poolContent[this.currentOffset++] = (byte) (key >>> 56); this.poolContent[this.currentOffset++] = (byte) (key >>> 48); this.poolContent[this.currentOffset++] = (byte) (key >>> 40); this.poolContent[this.currentOffset++] = (byte) (key >>> 32); this.poolContent[this.currentOffset++] = (byte) (key >>> 24); this.poolContent[this.currentOffset++] = (byte) (key >>> 16); this.poolContent[this.currentOffset++] = (byte) (key >>> 8); this.poolContent[this.currentOffset++] = (byte) key; } return index; }
This method returns the index into the constantPool corresponding to the type descriptor.
Params:
  • stringConstant – java.lang.String
Returns:int
/** * This method returns the index into the constantPool corresponding to the type descriptor. * * @param stringConstant java.lang.String * @return <CODE>int</CODE> */
public int literalIndex(String stringConstant) { int index; char[] stringCharArray = stringConstant.toCharArray(); if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { // The entry doesn't exit yet this.currentIndex++; if ((index = -index)> 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // Write the tag first int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(StringTag); // Then the string index int stringIndexOffset = this.currentOffset; if (this.currentOffset + 2 >= this.poolContent.length) { resizePoolContents(2); } this.currentOffset+=2; final int stringIndex = literalIndex(stringCharArray); this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); this.poolContent[stringIndexOffset] = (byte) stringIndex; } return index; } public int literalIndexForModule(final char[] moduleName) { int index; if ((index = this.moduleCache.putIfAbsent(moduleName, this.currentIndex)) < 0) { // The entry doesn't exit yet this.currentIndex++; if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // Write the tag first int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(ModuleTag); // Then the string index int stringIndexOffset = this.currentOffset; if (this.currentOffset + 2 >= this.poolContent.length) { resizePoolContents(2); } this.currentOffset+=2; final int stringIndex = literalIndex(moduleName); this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); this.poolContent[stringIndexOffset] = (byte) stringIndex; } return index; } public int literalIndexForPackage(final char[] packageName) { int index; if ((index = this.packageCache.putIfAbsent(packageName, this.currentIndex)) < 0) { // The entry doesn't exit yet this.currentIndex++; if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // Write the tag first int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(PackageTag); // Then the string index int stringIndexOffset = this.currentOffset; if (this.currentOffset + 2 >= this.poolContent.length) { resizePoolContents(2); } this.currentOffset+=2; final int stringIndex = literalIndex(packageName); this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); this.poolContent[stringIndexOffset] = (byte) stringIndex; } return index; } public int literalIndexForType(final char[] constantPoolName) { int index; if ((index = this.classCache.putIfAbsent(constantPoolName, this.currentIndex)) < 0) { // The entry doesn't exit yet this.currentIndex++; if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(ClassTag); // Then the name index int nameIndexOffset = this.currentOffset; if (this.currentOffset + 2 >= this.poolContent.length) { resizePoolContents(2); } this.currentOffset+=2; final int nameIndex = literalIndex(constantPoolName); this.poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8); this.poolContent[nameIndexOffset] = (byte) nameIndex; } return index; } /* * This method returns the index into the constantPool corresponding to the type descriptor * corresponding to a type constant pool name * binding must not be an array type. */ public int literalIndexForType(final TypeBinding binding) { TypeBinding typeBinding = binding.leafComponentType(); if ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { Util.recordNestedType(this.classFile, typeBinding); } return this.literalIndexForType(binding.constantPoolName()); } public int literalIndexForMethod(char[] declaringClass, char[] selector, char[] signature, boolean isInterface) { int index; if ((index = putInCacheIfAbsent(declaringClass, selector, signature, this.currentIndex)) < 0) { // it doesn't exist yet this.currentIndex++; if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // Write the interface method ref constant into the constant pool // First add the tag int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(isInterface ? InterfaceMethodRefTag : MethodRefTag); int classIndexOffset = this.currentOffset; if (this.currentOffset + 4 >= this.poolContent.length) { resizePoolContents(4); } this.currentOffset+=4; final int classIndex = literalIndexForType(declaringClass); final int nameAndTypeIndex = literalIndexForNameAndType(selector, signature); this.poolContent[classIndexOffset++] = (byte) (classIndex >> 8); this.poolContent[classIndexOffset++] = (byte) classIndex; this.poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8); this.poolContent[classIndexOffset] = (byte) nameAndTypeIndex; } return index; } public int literalIndexForMethod(TypeBinding declaringClass, char[] selector, char[] signature, boolean isInterface) { if ((declaringClass.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { Util.recordNestedType(this.classFile, declaringClass); } return this.literalIndexForMethod(declaringClass.constantPoolName(), selector, signature, isInterface); } public int literalIndexForNameAndType(char[] name, char[] signature) { int index; if ((index = putInNameAndTypeCacheIfAbsent(name, signature, this.currentIndex)) < 0) { // The entry doesn't exit yet this.currentIndex++; if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(NameAndTypeTag); int nameIndexOffset = this.currentOffset; if (this.currentOffset + 4 >= this.poolContent.length) { resizePoolContents(4); } this.currentOffset+=4; final int nameIndex = literalIndex(name); final int typeIndex = literalIndex(signature); this.poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8); this.poolContent[nameIndexOffset++] = (byte) nameIndex; this.poolContent[nameIndexOffset++] = (byte) (typeIndex >> 8); this.poolContent[nameIndexOffset] = (byte) typeIndex; } return index; } public int literalIndexForMethodHandle(MethodBinding binding) { boolean isInterface = binding.declaringClass.isInterface(); int referenceKind = isInterface ? binding.isStatic() ? MethodHandleRefKindInvokeStatic : binding.isPrivate() ? MethodHandleRefKindInvokeSpecial : MethodHandleRefKindInvokeInterface : binding.isConstructor() ? MethodHandleRefKindNewInvokeSpecial : binding.isStatic() ? MethodHandleRefKindInvokeStatic : binding.isPrivate() ? MethodHandleRefKindInvokeSpecial : MethodHandleRefKindInvokeVirtual; return literalIndexForMethodHandle(referenceKind, binding.declaringClass, binding.selector, binding.signature(), isInterface); } public int literalIndexForMethodHandle(int referenceKind, TypeBinding declaringClass, char[] selector, char[] signature, boolean isInterface) { int indexForMethod = literalIndexForMethod(declaringClass, selector, signature, isInterface); int index = this.currentIndex++; int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(MethodHandleTag); writeU1(referenceKind); writeU2(indexForMethod); return index; } public int literalIndexForMethodType(char[] descriptor) { int signatureIndex = literalIndex(descriptor); int index = this.currentIndex++; int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(MethodTypeTag); writeU2(signatureIndex); return index; } private int literalIndexForInvokeAndConstantDynamic(int bootStrapIndex, char[] selector, char[] descriptor, int tag) { int index; if ((index = putInDynamicCacheIfAbsent(bootStrapIndex, selector, descriptor, this.currentIndex)) < 0) { this.currentIndex++; if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(tag); int classIndexOffset = this.currentOffset; if (this.currentOffset + 4 >= this.poolContent.length) { resizePoolContents(4); } this.currentOffset+=4; int nameAndTypeIndex = literalIndexForNameAndType(selector, descriptor); this.poolContent[classIndexOffset++] = (byte) (bootStrapIndex >> 8); this.poolContent[classIndexOffset++] = (byte) bootStrapIndex; this.poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8); this.poolContent[classIndexOffset] = (byte) nameAndTypeIndex; } return index; } // CONSTANT_Dynamic_info JVMS 4.4.10 /jep 309 public int literalIndexForDynamic(int bootStrapIndex, char[] selector, char[] descriptor) { return literalIndexForInvokeAndConstantDynamic(bootStrapIndex, selector, descriptor, DynamicTag); } public int literalIndexForInvokeDynamic(int bootStrapIndex, char[] selector, char[] descriptor) { return literalIndexForInvokeAndConstantDynamic(bootStrapIndex, selector, descriptor, InvokeDynamicTag); } public int literalIndexForField(char[] declaringClass, char[] name, char[] signature) { int index; if ((index = putInCacheIfAbsent(declaringClass, name, signature, this.currentIndex)) < 0) { this.currentIndex++; // doesn't exist yet if ((index = -index) > 0xFFFF){ this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // Write the interface method ref constant into the constant pool // First add the tag int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(FieldRefTag); int classIndexOffset = this.currentOffset; if (this.currentOffset + 4 >= this.poolContent.length) { resizePoolContents(4); } this.currentOffset+=4; final int classIndex = literalIndexForType(declaringClass); final int nameAndTypeIndex = literalIndexForNameAndType(name, signature); this.poolContent[classIndexOffset++] = (byte) (classIndex >> 8); this.poolContent[classIndexOffset++] = (byte) classIndex; this.poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8); this.poolContent[classIndexOffset] = (byte) nameAndTypeIndex; } return index; }
This method returns the index into the constantPool corresponding to the type descriptor.
Params:
  • stringCharArray – char[]
Returns:int
/** * This method returns the index into the constantPool corresponding to the type descriptor. * * @param stringCharArray char[] * @return <CODE>int</CODE> */
public int literalIndexForLdc(char[] stringCharArray) { int savedCurrentIndex = this.currentIndex; int savedCurrentOffset = this.currentOffset; int index; if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { if ((index = -index)> 0xFFFF) { this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // The entry doesn't exit yet this.currentIndex++; // Write the tag first int length = this.offsets.length; if (length <= index) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length); } this.offsets[index] = this.currentOffset; writeU1(StringTag); // Then the string index int stringIndexOffset = this.currentOffset; if (this.currentOffset + 2 >= this.poolContent.length) { resizePoolContents(2); } this.currentOffset+=2; int stringIndex; if ((stringIndex = this.UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) { if ((stringIndex = -stringIndex)> 0xFFFF) { this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType()); } // The entry doesn't exit yet this.currentIndex++; // Write the tag first length = this.offsets.length; if (length <= stringIndex) { // resize System.arraycopy(this.offsets, 0, (this.offsets = new int[stringIndex * 2]), 0, length); } this.offsets[stringIndex] = this.currentOffset; writeU1(Utf8Tag); // Then the size of the stringName array int lengthOffset = this.currentOffset; if (this.currentOffset + 2 >= this.poolContent.length) { // we need to resize the poolContent array because we won't have // enough space to write the length resizePoolContents(2); } this.currentOffset += 2; length = 0; for (int i = 0; i < stringCharArray.length; i++) { char current = stringCharArray[i]; if ((current >= 0x0001) && (current <= 0x007F)) { // we only need one byte: ASCII table length++; if (this.currentOffset + 1 >= this.poolContent.length) { // we need to resize the poolContent array because we won't have // enough space to write the length resizePoolContents(1); } this.poolContent[this.currentOffset++] = (byte)(current); } else if (current > 0x07FF) { // we need 3 bytes length += 3; if (this.currentOffset + 3 >= this.poolContent.length) { // we need to resize the poolContent array because we won't have // enough space to write the length resizePoolContents(3); } this.poolContent[this.currentOffset++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000 this.poolContent[this.currentOffset++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000 this.poolContent[this.currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000 } else { if (this.currentOffset + 2 >= this.poolContent.length) { // we need to resize the poolContent array because we won't have // enough space to write the length resizePoolContents(2); } // we can be 0 or between 0x0080 and 0x07FF // In that case we only need 2 bytes length += 2; this.poolContent[this.currentOffset++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000 this.poolContent[this.currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000 } } if (length >= 65535) { this.currentOffset = savedCurrentOffset; this.currentIndex = savedCurrentIndex; this.stringCache.remove(stringCharArray); this.UTF8Cache.remove(stringCharArray); return 0; } this.poolContent[lengthOffset++] = (byte) (length >> 8); this.poolContent[lengthOffset] = (byte) length; } this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8); this.poolContent[stringIndexOffset] = (byte) stringIndex; } return index; }
Params:
  • key1 – the given name
  • key2 – the given signature
  • value – the given index
Returns:the new index
/** * @param key1 the given name * @param key2 the given signature * @param value the given index * @return the new index */
private int putInNameAndTypeCacheIfAbsent(final char[] key1, final char[] key2, int value) { int index ; Object key1Value = this.nameAndTypeCacheForFieldsAndMethods.get(key1); if (key1Value == null) { CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key2, value); index = -value; this.nameAndTypeCacheForFieldsAndMethods.put(key1, cachedIndexEntry); } else if (key1Value instanceof CachedIndexEntry) { // adding a second entry CachedIndexEntry entry = (CachedIndexEntry) key1Value; if (CharOperation.equals(key2, entry.signature)) { index = entry.index; } else { CharArrayCache charArrayCache = new CharArrayCache(); charArrayCache.putIfAbsent(entry.signature, entry.index); index = charArrayCache.putIfAbsent(key2, value); this.nameAndTypeCacheForFieldsAndMethods.put(key1, charArrayCache); } } else { CharArrayCache charArrayCache = (CharArrayCache) key1Value; index = charArrayCache.putIfAbsent(key2, value); } return index; }
Params:
  • bootstrapIndex – the given bootstrap index
  • selector – the given method selector
  • descriptor – the given signature
  • value – the new index
Returns:the given index
/** * @param bootstrapIndex the given bootstrap index * @param selector the given method selector * @param descriptor the given signature * @param value the new index * @return the given index */
private int putInDynamicCacheIfAbsent(int bootstrapIndex, final char[] selector, final char[] descriptor, final int value) { int index; HashtableOfObject key1Value = (HashtableOfObject) this.dynamicCache.get(bootstrapIndex); if (key1Value == null) { key1Value = new HashtableOfObject(); this.dynamicCache.put(bootstrapIndex, key1Value); CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(descriptor, value); index = -value; key1Value.put(selector, cachedIndexEntry); } else { Object key2Value = key1Value.get(selector); if (key2Value == null) { CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(descriptor, value); index = -value; key1Value.put(selector, cachedIndexEntry); } else if (key2Value instanceof CachedIndexEntry) { // adding a second entry CachedIndexEntry entry = (CachedIndexEntry) key2Value; if (CharOperation.equals(descriptor, entry.signature)) { index = entry.index; } else { CharArrayCache charArrayCache = new CharArrayCache(); charArrayCache.putIfAbsent(entry.signature, entry.index); index = charArrayCache.putIfAbsent(descriptor, value); key1Value.put(selector, charArrayCache); } } else { CharArrayCache charArrayCache = (CharArrayCache) key2Value; index = charArrayCache.putIfAbsent(descriptor, value); } } return index; }
Params:
  • key1 – the given declaring class name
  • key2 – the given field name or method selector
  • key3 – the given signature
  • value – the new index
Returns:the given index
/** * @param key1 the given declaring class name * @param key2 the given field name or method selector * @param key3 the given signature * @param value the new index * @return the given index */
private int putInCacheIfAbsent(final char[] key1, final char[] key2, final char[] key3, int value) { int index; HashtableOfObject key1Value = (HashtableOfObject) this.methodsAndFieldsCache.get(key1); if (key1Value == null) { key1Value = new HashtableOfObject(); this.methodsAndFieldsCache.put(key1, key1Value); CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key3, value); index = -value; key1Value.put(key2, cachedIndexEntry); } else { Object key2Value = key1Value.get(key2); if (key2Value == null) { CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key3, value); index = -value; key1Value.put(key2, cachedIndexEntry); } else if (key2Value instanceof CachedIndexEntry) { // adding a second entry CachedIndexEntry entry = (CachedIndexEntry) key2Value; if (CharOperation.equals(key3, entry.signature)) { index = entry.index; } else { CharArrayCache charArrayCache = new CharArrayCache(); charArrayCache.putIfAbsent(entry.signature, entry.index); index = charArrayCache.putIfAbsent(key3, value); key1Value.put(key2, charArrayCache); } } else { CharArrayCache charArrayCache = (CharArrayCache) key2Value; index = charArrayCache.putIfAbsent(key3, value); } } return index; }
This method is used to clean the receiver in case of a clinit header is generated, but the clinit has no code. This implementation assumes that the clinit is the first method to be generated.
See Also:
  • addClinit.addClinit()
/** * This method is used to clean the receiver in case of a clinit header is generated, but the * clinit has no code. * This implementation assumes that the clinit is the first method to be generated. * @see org.eclipse.jdt.internal.compiler.ast.TypeDeclaration#addClinit() */
public void resetForClinit(int constantPoolIndex, int constantPoolOffset) { this.currentIndex = constantPoolIndex; this.currentOffset = constantPoolOffset; if (this.UTF8Cache.get(AttributeNamesConstants.CodeName) >= constantPoolIndex) { this.UTF8Cache.remove(AttributeNamesConstants.CodeName); } if (this.UTF8Cache.get(ConstantPool.ClinitSignature) >= constantPoolIndex) { this.UTF8Cache.remove(ConstantPool.ClinitSignature); } if (this.UTF8Cache.get(ConstantPool.Clinit) >= constantPoolIndex) { this.UTF8Cache.remove(ConstantPool.Clinit); } }
Resize the pool contents
/** * Resize the pool contents */
private final void resizePoolContents(int minimalSize) { int length = this.poolContent.length; int toAdd = length; if (toAdd < minimalSize) toAdd = minimalSize; System.arraycopy(this.poolContent, 0, this.poolContent = new byte[length + toAdd], 0, length); }
Write a unsigned byte into the byte array
Params:
  • value – int The value to write into the byte array
/** * Write a unsigned byte into the byte array * * @param value <CODE>int</CODE> The value to write into the byte array */
protected final void writeU1(int value) { if (this.currentOffset + 1 >= this.poolContent.length) { resizePoolContents(1); } this.poolContent[this.currentOffset++] = (byte) value; }
Write a unsigned byte into the byte array
Params:
  • value – int The value to write into the byte array
/** * Write a unsigned byte into the byte array * * @param value <CODE>int</CODE> The value to write into the byte array */
protected final void writeU2(int value) { if (this.currentOffset + 2 >= this.poolContent.length) { resizePoolContents(2); } this.poolContent[this.currentOffset++] = (byte) (value >>> 8); this.poolContent[this.currentOffset++] = (byte) value; } public void reset() { if (this.doubleCache != null) this.doubleCache.clear(); if (this.floatCache != null) this.floatCache.clear(); if (this.intCache != null) this.intCache.clear(); if (this.longCache != null) this.longCache.clear(); this.UTF8Cache.clear(); this.stringCache.clear(); this.methodsAndFieldsCache.clear(); this.classCache.clear(); this.packageCache.clear(); this.moduleCache.clear(); this.nameAndTypeCacheForFieldsAndMethods.clear(); this.dynamicCache.clear(); this.currentIndex = 1; this.currentOffset = 0; } }