new Entry(constantPoolCount++, tag, owner, name, descriptor, referenceKind, hashCode));
hashCode ^= classReader.readConst(bootstrapArgument, charBuffer).hashCode(); add(new Entry(i, Symbol.BOOTSTRAP_METHOD_TAG, offset, hashCode & 0x7FFFFFFF));
return put(new Entry(bootstrapMethodCount++, Symbol.BOOTSTRAP_METHOD_TAG, offset, hashCode));
new Entry( constantPoolCount++, tag, null, name, descriptor, bootstrapMethodIndex, hashCode));
/** * Adds a merged type in the type table of this symbol table. Does nothing if the type table * already contains a similar type. * * @param typeTableIndex1 a {@link Symbol#TYPE_TAG} type, specified by its index in the type * table. * @param typeTableIndex2 another {@link Symbol#TYPE_TAG} type, specified by its index in the type * table. * @return the index of a new or already existing {@link Symbol#TYPE_TAG} type Symbol, * corresponding to the common super class of the given types. */ int addMergedType(final int typeTableIndex1, final int typeTableIndex2) { // TODO sort the arguments? The merge result should be independent of their order. long data = typeTableIndex1 | (((long) typeTableIndex2) << 32); int hashCode = hash(Symbol.MERGED_TYPE_TAG, typeTableIndex1 + typeTableIndex2); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == Symbol.MERGED_TYPE_TAG && entry.hashCode == hashCode && entry.data == data) { return entry.info; } entry = entry.next; } String type1 = typeTable[typeTableIndex1].value; String type2 = typeTable[typeTableIndex2].value; int commonSuperTypeIndex = addType(classWriter.getCommonSuperClass(type1, type2)); put(new Entry(typeCount, Symbol.MERGED_TYPE_TAG, data, hashCode)).info = commonSuperTypeIndex; return commonSuperTypeIndex; }
/** * Adds a CONSTANT_Fieldref_info, CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info to * the constant pool of this symbol table. Does nothing if the constant pool already contains a * similar item. * * @param tag one of {@link Symbol#CONSTANT_FIELDREF_TAG}, {@link Symbol#CONSTANT_METHODREF_TAG} * or {@link Symbol#CONSTANT_INTERFACE_METHODREF_TAG}. * @param owner the internal name of a class. * @param name a field or method name. * @param descriptor a field or method descriptor. * @return a new or already existing Symbol with the given value. */ private Entry addConstantMemberReference( final int tag, final String owner, final String name, final String descriptor) { int hashCode = hash(tag, owner, name, descriptor); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == tag && entry.hashCode == hashCode && entry.owner.equals(owner) && entry.name.equals(name) && entry.value.equals(descriptor)) { return entry; } entry = entry.next; } constantPool.put122( tag, addConstantClass(owner).index, addConstantNameAndType(name, descriptor)); return put(new Entry(constantPoolCount++, tag, owner, name, descriptor, 0, hashCode)); }
/** * Adds a CONSTANT_NameAndType_info to the constant pool of this symbol table. Does nothing if the * constant pool already contains a similar item. * * @param name a field or method name. * @param descriptor a field or method descriptor. * @return a new or already existing Symbol with the given value. */ int addConstantNameAndType(final String name, final String descriptor) { final int tag = Symbol.CONSTANT_NAME_AND_TYPE_TAG; int hashCode = hash(tag, name, descriptor); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == tag && entry.hashCode == hashCode && entry.name.equals(name) && entry.value.equals(descriptor)) { return entry.index; } entry = entry.next; } constantPool.put122(tag, addConstantUtf8(name), addConstantUtf8(descriptor)); return put(new Entry(constantPoolCount++, tag, name, descriptor, hashCode)).index; }
/** * Adds a CONSTANT_Class_info, CONSTANT_String_info, CONSTANT_MethodType_info, * CONSTANT_Module_info or CONSTANT_Package_info to the constant pool of this symbol table. Does * nothing if the constant pool already contains a similar item. * * @param tag one of {@link Symbol#CONSTANT_CLASS_TAG}, {@link Symbol#CONSTANT_STRING_TAG}, {@link * Symbol#CONSTANT_METHOD_TYPE_TAG}, {@link Symbol#CONSTANT_MODULE_TAG} or {@link * Symbol#CONSTANT_PACKAGE_TAG}. * @param value an internal class name, an arbitrary string, a method descriptor, a module or a * package name, depending on tag. * @return a new or already existing Symbol with the given value. */ private Symbol addConstantUtf8Reference(final int tag, final String value) { int hashCode = hash(tag, value); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == tag && entry.hashCode == hashCode && entry.value.equals(value)) { return entry; } entry = entry.next; } constantPool.put12(tag, addConstantUtf8(value)); return put(new Entry(constantPoolCount++, tag, value, hashCode)); }
/** * Adds an {@link Frame#ITEM_UNINITIALIZED} type in the type table of this symbol table. Does * nothing if the type table already contains a similar type. * * @param value an internal class name. * @param bytecodeOffset the bytecode offset of the NEW instruction that created this {@link * Frame#ITEM_UNINITIALIZED} type value. * @return the index of a new or already existing type Symbol with the given value. */ int addUninitializedType(final String value, final int bytecodeOffset) { int hashCode = hash(Symbol.UNINITIALIZED_TYPE_TAG, value, bytecodeOffset); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == Symbol.UNINITIALIZED_TYPE_TAG && entry.hashCode == hashCode && entry.data == bytecodeOffset && entry.value.equals(value)) { return entry.index; } entry = entry.next; } return addType( new Entry(typeCount, Symbol.UNINITIALIZED_TYPE_TAG, value, bytecodeOffset, hashCode)); }
/** * Adds a new CONSTANT_MethodHandle_info to the constant pool of this symbol table. * * @param index the constant pool index of the new Symbol. * @param referenceKind one of {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link * Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link * Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, {@link * Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. * @param owner the internal name of a class of interface. * @param name a field or method name. * @param descriptor a field or method descriptor. */ private void addConstantMethodHandle( final int index, final int referenceKind, final String owner, final String name, final String descriptor) { final int tag = Symbol.CONSTANT_METHOD_HANDLE_TAG; int hashCode = hash(tag, owner, name, descriptor, referenceKind); add(new Entry(index, tag, owner, name, descriptor, referenceKind, hashCode)); }
/** * Adds a CONSTANT_Utf8_info to the constant pool of this symbol table. Does nothing if the * constant pool already contains a similar item. * * @param value a string. * @return a new or already existing Symbol with the given value. */ int addConstantUtf8(final String value) { int hashCode = hash(Symbol.CONSTANT_UTF8_TAG, value); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == Symbol.CONSTANT_UTF8_TAG && entry.hashCode == hashCode && entry.value.equals(value)) { return entry.index; } entry = entry.next; } constantPool.putByte(Symbol.CONSTANT_UTF8_TAG).putUTF8(value); return put(new Entry(constantPoolCount++, Symbol.CONSTANT_UTF8_TAG, value, hashCode)).index; }
/** * Adds a CONSTANT_Long_info or CONSTANT_Double_info to the constant pool of this symbol table. * Does nothing if the constant pool already contains a similar item. * * @param tag one of {@link Symbol#CONSTANT_LONG_TAG} or {@link Symbol#CONSTANT_DOUBLE_TAG}. * @param value a long or double. * @return a constant pool constant with the given tag and primitive values. */ private Symbol addConstantLong(final int tag, final long value) { int hashCode = hash(tag, value); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == tag && entry.hashCode == hashCode && entry.data == value) { return entry; } entry = entry.next; } int index = constantPoolCount; constantPool.putByte(tag).putLong(value); constantPoolCount += 2; return put(new Entry(index, tag, value, hashCode)); }
/** * Adds a new CONSTANT_Dynamic_info or CONSTANT_InvokeDynamic_info to the constant pool of this * symbol table. * * @param tag one of {@link Symbol#CONSTANT_DYNAMIC_TAG} or {@link * Symbol#CONSTANT_INVOKE_DYNAMIC_TAG}. * @param index the constant pool index of the new Symbol. * @param name a method name. * @param descriptor a field descriptor for CONSTANT_DYNAMIC_TAG or a method descriptor for * CONSTANT_INVOKE_DYNAMIC_TAG. * @param bootstrapMethodIndex the index of a bootstrap method in the BootstrapMethods attribute. */ private void addConstantDynamicOrInvokeDynamicReference( final int tag, final int index, final String name, final String descriptor, final int bootstrapMethodIndex) { int hashCode = hash(tag, name, descriptor, bootstrapMethodIndex); add(new Entry(index, tag, null, name, descriptor, bootstrapMethodIndex, hashCode)); }
/** * Adds a new CONSTANT_Fieldref_info, CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info * to the constant pool of this symbol table. * * @param index the constant pool index of the new Symbol. * @param tag one of {@link Symbol#CONSTANT_FIELDREF_TAG}, {@link Symbol#CONSTANT_METHODREF_TAG} * or {@link Symbol#CONSTANT_INTERFACE_METHODREF_TAG}. * @param owner the internal name of a class. * @param name a field or method name. * @param descriptor a field or method descriptor. */ private void addConstantMemberReference( final int index, final int tag, final String owner, final String name, final String descriptor) { add(new Entry(index, tag, owner, name, descriptor, 0, hash(tag, owner, name, descriptor))); }
/** * Adds a CONSTANT_Integer_info or CONSTANT_Float_info to the constant pool of this symbol table. * Does nothing if the constant pool already contains a similar item. * * @param tag one of {@link Symbol#CONSTANT_INTEGER_TAG} or {@link Symbol#CONSTANT_FLOAT_TAG}. * @param value an int or float. * @return a constant pool constant with the given tag and primitive values. */ private Symbol addConstantInteger(final int tag, final int value) { int hashCode = hash(tag, value); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == tag && entry.hashCode == hashCode && entry.data == value) { return entry; } entry = entry.next; } constantPool.putByte(tag).putInt(value); return put(new Entry(constantPoolCount++, tag, value, hashCode)); }
/** * Adds a type in the type table of this symbol table. Does nothing if the type table already * contains a similar type. * * @param value an internal class name. * @return the index of a new or already existing type Symbol with the given value. */ int addType(final String value) { int hashCode = hash(Symbol.TYPE_TAG, value); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == Symbol.TYPE_TAG && entry.hashCode == hashCode && entry.value.equals(value)) { return entry.index; } entry = entry.next; } return addType(new Entry(typeCount, Symbol.TYPE_TAG, value, hashCode)); }
/** * Adds a new CONSTANT_Class_info, CONSTANT_String_info, CONSTANT_MethodType_info, * CONSTANT_Module_info or CONSTANT_Package_info to the constant pool of this symbol table. * * @param index the constant pool index of the new Symbol. * @param tag one of {@link Symbol#CONSTANT_CLASS_TAG}, {@link Symbol#CONSTANT_STRING_TAG}, {@link * Symbol#CONSTANT_METHOD_TYPE_TAG}, {@link Symbol#CONSTANT_MODULE_TAG} or {@link * Symbol#CONSTANT_PACKAGE_TAG}. * @param value an internal class name, an arbitrary string, a method descriptor, a module or a * package name, depending on tag. */ private void addConstantUtf8Reference(final int index, final int tag, final String value) { add(new Entry(index, tag, value, hash(tag, value))); }
/** * Adds a new CONSTANT_NameAndType_info to the constant pool of this symbol table. * * @param index the constant pool index of the new Symbol. * @param name a field or method name. * @param descriptor a field or method descriptor. */ private void addConstantNameAndType(final int index, final String name, final String descriptor) { final int tag = Symbol.CONSTANT_NAME_AND_TYPE_TAG; add(new Entry(index, tag, name, descriptor, hash(tag, name, descriptor))); }
/** * Adds a new CONSTANT_Double_info to the constant pool of this symbol table. * * @param index the constant pool index of the new Symbol. * @param tag one of {@link Symbol#CONSTANT_LONG_TAG} or {@link Symbol#CONSTANT_DOUBLE_TAG}. * @param value a long or double. */ private void addConstantLong(final int index, final int tag, final long value) { add(new Entry(index, tag, value, hash(tag, value))); }
/** * Adds a new CONSTANT_String_info to the constant pool of this symbol table. * * @param index the constant pool index of the new Symbol. * @param value a string. */ private void addConstantUtf8(final int index, final String value) { add(new Entry(index, Symbol.CONSTANT_UTF8_TAG, value, hash(Symbol.CONSTANT_UTF8_TAG, value))); }