symbolTable = classReader == null ? new SymbolTable(this) : new SymbolTable(this, classReader); if ((flags & COMPUTE_FRAMES) != 0) { this.compute = MethodWriter.COMPUTE_ALL_FRAMES;
/** * 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 addConstantIntegerOrFloat(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 final void visitOuterClass( final String owner, final String name, final String descriptor) { enclosingClassIndex = symbolTable.addConstantClass(owner).index; if (name != null && descriptor != null) { enclosingMethodIndex = symbolTable.addConstantNameAndType(name, descriptor); } }
@Override public final void visit( final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) { this.version = version; this.accessFlags = access; this.thisClass = symbolTable.setMajorVersionAndClassName(version & 0xFFFF, name); if (signature != null) { this.signatureIndex = symbolTable.addConstantUtf8(signature); } this.superClass = superName == null ? 0 : symbolTable.addConstantClass(superName).index; if (interfaces != null && interfaces.length > 0) { interfaceCount = interfaces.length; this.interfaces = new int[interfaceCount]; for (int i = 0; i < interfaceCount; ++i) { this.interfaces[i] = symbolTable.addConstantClass(interfaces[i]).index; } } if (compute == MethodWriter.COMPUTE_MAX_STACK_AND_LOCAL && (version & 0xFFFF) >= Opcodes.V1_7) { compute = MethodWriter.COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES; } }
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: addConstantIntegerOrFloat(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: addConstantLongOrDouble(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),
annotation.putShort(symbolTable.addConstantUtf8(name)); annotation.put12('s', symbolTable.addConstantUtf8((String) value)); } else if (value instanceof Byte) { annotation.put12('B', symbolTable.addConstantInteger(((Byte) value).byteValue()).index); } else if (value instanceof Boolean) { int booleanValue = ((Boolean) value).booleanValue() ? 1 : 0; annotation.put12('Z', symbolTable.addConstantInteger(booleanValue).index); } else if (value instanceof Character) { annotation.put12('C', symbolTable.addConstantInteger(((Character) value).charValue()).index); } else if (value instanceof Short) { annotation.put12('S', symbolTable.addConstantInteger(((Short) value).shortValue()).index); } else if (value instanceof Type) { annotation.put12('c', symbolTable.addConstantUtf8(((Type) value).getDescriptor())); } else if (value instanceof byte[]) { byte[] byteArray = (byte[]) value; annotation.put12('[', byteArray.length); for (byte byteValue : byteArray) { annotation.put12('B', symbolTable.addConstantInteger(byteValue).index); annotation.put12('[', booleanArray.length); for (boolean booleanValue : booleanArray) { annotation.put12('Z', symbolTable.addConstantInteger(booleanValue ? 1 : 0).index); annotation.put12('[', shortArray.length); for (short shortValue : shortArray) { annotation.put12('S', symbolTable.addConstantInteger(shortValue).index); annotation.put12('[', charArray.length);
/** * 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));
/** * Adds a class reference to the constant pool of the class being build. Does nothing if the * constant pool already contains a similar item. <i>This method is intended for {@link Attribute} * sub classes, and is normally not needed by class generators or adapters.</i> * * @param value the internal name of the class. * @return the index of a new or already existing class reference item. */ public int newClass(final String value) { return symbolTable.addConstantClass(value).index; }
addConstant(bootstrapMethodArgument); addConstantMethodHandle( bootstrapMethodHandle.getTag(), bootstrapMethodHandle.getOwner(), bootstrapMethodsAttribute.putShort(numBootstrapArguments); for (Object bootstrapMethodArgument : bootstrapMethodArguments) { bootstrapMethodsAttribute.putShort(addConstant(bootstrapMethodArgument).index); return addBootstrapMethod(bootstrapMethodOffset, bootstrapMethodlength, hashCode);
this.symbolTable = symbolTable; this.accessFlags = "<init>".equals(name) ? access | Constants.ACC_CONSTRUCTOR : access; this.nameIndex = symbolTable.addConstantUtf8(name); this.name = name; this.descriptorIndex = symbolTable.addConstantUtf8(descriptor); this.descriptor = descriptor; this.signatureIndex = signature == null ? 0 : symbolTable.addConstantUtf8(signature); if (exceptions != null && exceptions.length > 0) { numberOfExceptions = exceptions.length; this.exceptionIndexTable = new int[numberOfExceptions]; for (int i = 0; i < numberOfExceptions; ++i) { this.exceptionIndexTable[i] = symbolTable.addConstantClass(exceptions[i]).index;
/** * Constructs a new {@link FieldWriter}. * * @param symbolTable where the constants used in this FieldWriter must be stored. * @param access the field's access flags (see {@link Opcodes}). * @param name the field's name. * @param descriptor the field's descriptor (see {@link Type}). * @param signature the field's signature. May be {@literal null}. * @param constantValue the field's constant value. May be {@literal null}. */ FieldWriter( final SymbolTable symbolTable, final int access, final String name, final String descriptor, final String signature, final Object constantValue) { super(Opcodes.ASM7); this.symbolTable = symbolTable; this.accessFlags = access; this.nameIndex = symbolTable.addConstantUtf8(name); this.descriptorIndex = symbolTable.addConstantUtf8(descriptor); if (signature != null) { this.signatureIndex = symbolTable.addConstantUtf8(signature); } if (constantValue != null) { this.constantValueIndex = symbolTable.addConstant(constantValue).index; } }
output .putByte(ITEM_OBJECT) .putShort(symbolTable.addConstantClass(symbolTable.getType(typeValue).value).index); break; case UNINITIALIZED_KIND: output.putByte(ITEM_UNINITIALIZED).putShort((int) symbolTable.getType(typeValue).data); break; default: typeDescriptor .append('L') .append(symbolTable.getType(abstractType & VALUE_MASK).value) .append(';'); } else { .putShort(symbolTable.addConstantClass(typeDescriptor.toString()).index);
/** * Adds a number or string constant to the constant pool of the class being build. Does nothing if * the constant pool already contains a similar item. <i>This method is intended for {@link * Attribute} sub classes, and is normally not needed by class generators or adapters.</i> * * @param value the value of the constant to be added to the constant pool. This parameter must be * an {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double} or a {@link String}. * @return the index of a new or already existing constant item with the given value. */ public int newConst(final Object value) { return symbolTable.addConstant(value).index; }
/** * Adds a field reference to the constant pool of the class being build. Does nothing if the * constant pool already contains a similar item. <i>This method is intended for {@link Attribute} * sub classes, and is normally not needed by class generators or adapters.</i> * * @param owner the internal name of the field's owner class. * @param name the field's name. * @param descriptor the field's descriptor. * @return the index of a new or already existing field reference item. */ public int newField(final String owner, final String name, final String descriptor) { return symbolTable.addConstantFieldref(owner, name, descriptor).index; }
/** * Adds a dynamic constant reference to the constant pool of the class being build. Does nothing * if the constant pool already contains a similar item. <i>This method is intended for {@link * Attribute} sub classes, and is normally not needed by class generators or adapters.</i> * * @param name name of the invoked method. * @param descriptor field descriptor of the constant type. * @param bootstrapMethodHandle the bootstrap method. * @param bootstrapMethodArguments the bootstrap method constant arguments. * @return the index of a new or already existing dynamic constant reference item. */ public int newConstantDynamic( final String name, final String descriptor, final Handle bootstrapMethodHandle, final Object... bootstrapMethodArguments) { return symbolTable.addConstantDynamic( name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments) .index; }
hashCode ^= classReader.readConst(bootstrapArgument, charBuffer).hashCode(); add(new Entry(i, Symbol.BOOTSTRAP_METHOD_TAG, offset, hashCode & 0x7FFFFFFF));
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(),