/** * 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 CONSTANT_InvokeDynamic_info to the constant pool of this symbol table. Also adds the * related bootstrap method to the BootstrapMethods of this symbol table. Does nothing if the * constant pool already contains a similar item. * * @param name a method name. * @param descriptor a method descriptor. * @param bootstrapMethodHandle a bootstrap method handle. * @param bootstrapMethodArguments the bootstrap method arguments. * @return a new or already existing Symbol with the given value. */ Symbol addConstantInvokeDynamic( final String name, final String descriptor, final Handle bootstrapMethodHandle, final Object... bootstrapMethodArguments) { Symbol bootstrapMethod = addBootstrapMethod(bootstrapMethodHandle, bootstrapMethodArguments); return addConstantDynamicOrInvokeDynamicReference( Symbol.CONSTANT_INVOKE_DYNAMIC_TAG, name, descriptor, bootstrapMethod.index); }
/** * Sets the major version and the name of the class to which this symbol table belongs. Also adds * the class name to the constant pool. * * @param majorVersion a major ClassFile version number. * @param className an internal class name. * @return the constant pool index of a new or already existing Symbol with the given class name. */ int setMajorVersionAndClassName(final int majorVersion, final String className) { this.majorVersion = majorVersion; this.className = className; return addConstantClass(className).index; }
return addConstantInteger(((Integer) value).intValue()); } else if (value instanceof Byte) { return addConstantInteger(((Byte) value).intValue()); } else if (value instanceof Character) { return addConstantInteger(((Character) value).charValue()); } else if (value instanceof Short) { return addConstantInteger(((Short) value).intValue()); } else if (value instanceof Boolean) { return addConstantInteger(((Boolean) value).booleanValue() ? 1 : 0); } else if (value instanceof Float) { return addConstantFloat(((Float) value).floatValue()); } else if (value instanceof Long) { return addConstantLong(((Long) value).longValue()); } else if (value instanceof Double) { return addConstantDouble(((Double) value).doubleValue()); } else if (value instanceof String) { return addConstantString((String) value); } else if (value instanceof Type) { Type type = (Type) value; int typeSort = type.getSort(); if (typeSort == Type.OBJECT) { return addConstantClass(type.getInternalName()); } else if (typeSort == Type.METHOD) { return addConstantMethodType(type.getDescriptor()); } else { // type is a primitive or array type. return addConstantClass(type.getDescriptor()); return addConstantMethodHandle( handle.getTag(),
nameAndTypeItemOffset = classReader.getItem(classReader.readUnsignedShort(itemOffset + 2)); addConstantMemberReference( itemIndex, itemTag, case Symbol.CONSTANT_INTEGER_TAG: case Symbol.CONSTANT_FLOAT_TAG: addConstantInteger(itemIndex, itemTag, classReader.readInt(itemOffset)); break; case Symbol.CONSTANT_NAME_AND_TYPE_TAG: addConstantNameAndType( itemIndex, classReader.readUTF8(itemOffset, charBuffer), case Symbol.CONSTANT_LONG_TAG: case Symbol.CONSTANT_DOUBLE_TAG: addConstantLong(itemIndex, itemTag, classReader.readLong(itemOffset)); break; case Symbol.CONSTANT_UTF8_TAG: addConstantUtf8(itemIndex, classReader.readUTF(itemIndex, charBuffer)); break; case Symbol.CONSTANT_METHOD_HANDLE_TAG: nameAndTypeItemOffset = classReader.getItem(classReader.readUnsignedShort(memberRefItemOffset + 2)); addConstantMethodHandle( itemIndex, classReader.readByte(itemOffset),
/** * 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)); }
int hashCode = hash(tag, owner, name, descriptor, referenceKind); Entry entry = get(hashCode); while (entry != null) { if (entry.tag == tag constantPool.put112(tag, referenceKind, addConstantFieldref(owner, name, descriptor).index); } else { constantPool.put112( tag, referenceKind, addConstantMethodref(owner, name, descriptor, isInterface).index); return put( new Entry(constantPoolCount++, tag, owner, name, descriptor, referenceKind, hashCode));
addConstant(bootstrapMethodArgument); addConstantMethodHandle( bootstrapMethodHandle.getTag(), bootstrapMethodHandle.getOwner(), bootstrapMethodsAttribute.putShort(numBootstrapArguments); for (Object bootstrapMethodArgument : bootstrapMethodArguments) { bootstrapMethodsAttribute.putShort(addConstant(bootstrapMethodArgument).index); return addBootstrapMethod(bootstrapMethodOffset, bootstrapMethodlength, hashCode);
/** * Adds a CONSTANT_Integer_info to the constant pool of this symbol table. Does nothing if the * constant pool already contains a similar item. * * @param value an int. * @return a new or already existing Symbol with the given value. */ Symbol addConstantInteger(final int value) { return addConstantInteger(Symbol.CONSTANT_INTEGER_TAG, value); }
/** * Adds a CONSTANT_Float_info to the constant pool of this symbol table. Does nothing if the * constant pool already contains a similar item. * * @param value a float. * @return a new or already existing Symbol with the given value. */ Symbol addConstantFloat(final float value) { return addConstantInteger(Symbol.CONSTANT_FLOAT_TAG, Float.floatToRawIntBits(value)); }
/** * Adds a new CONSTANT_Integer_info or CONSTANT_Float_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_INTEGER_TAG} or {@link Symbol#CONSTANT_FLOAT_TAG}. * @param value an int or float. */ private void addConstantInteger(final int index, final int tag, final int value) { add(new Entry(index, tag, value, hash(tag, value))); }
/** * Adds a CONSTANT_Dynamic_info to the constant pool of this symbol table. Also adds the related * bootstrap method to the BootstrapMethods of this symbol table. Does nothing if the constant * pool already contains a similar item. * * @param name a method name. * @param descriptor a field descriptor. * @param bootstrapMethodHandle a bootstrap method handle. * @param bootstrapMethodArguments the bootstrap method arguments. * @return a new or already existing Symbol with the given value. */ Symbol addConstantDynamic( final String name, final String descriptor, final Handle bootstrapMethodHandle, final Object... bootstrapMethodArguments) { Symbol bootstrapMethod = addBootstrapMethod(bootstrapMethodHandle, bootstrapMethodArguments); return addConstantDynamicOrInvokeDynamicReference( Symbol.CONSTANT_DYNAMIC_TAG, name, descriptor, bootstrapMethod.index); }
@Override public void visitMainClass(final String mainClass) { this.mainClassIndex = symbolTable.addConstantClass(mainClass).index; }
/** * 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))); }
@Override public void visitUse(final String service) { usesIndex.putShort(symbolTable.addConstantClass(service).index); usesCount++; }
/** * 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))); }
@Override public void visitProvide(final String service, final String... providers) { provides.putShort(symbolTable.addConstantClass(service).index); provides.putShort(providers.length); for (String provider : providers) { provides.putShort(symbolTable.addConstantClass(provider).index); } providesCount++; }
/** * 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_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 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)); }