Search in sources :

Example 1 with ConstantValueAttribute

use of com.oracle.truffle.espresso.classfile.attributes.ConstantValueAttribute in project graal by oracle.

the class ClassfileParser method parseField.

private ParserField parseField(boolean isInterface) {
    int fieldFlags = stream.readU2();
    int nameIndex = stream.readU2();
    int typeIndex = stream.readU2();
    pool.utf8At(nameIndex).validateFieldName();
    final Symbol<Name> name = pool.symbolAt(nameIndex, "field name");
    verifyFieldFlags(name, fieldFlags, isInterface);
    final boolean isStatic = Modifier.isStatic(fieldFlags);
    pool.utf8At(typeIndex).validateType(false);
    Symbol<ModifiedUTF8> rawDescriptor = pool.symbolAt(typeIndex, "field descriptor");
    final Symbol<Type> descriptor = Types.fromSymbol(rawDescriptor);
    if (descriptor == null) {
        throw ConstantPool.classFormatError("Invalid descriptor: " + rawDescriptor);
    }
    final int attributeCount = stream.readU2();
    final Attribute[] fieldAttributes = spawnAttributesArray(attributeCount);
    ConstantValueAttribute constantValue = null;
    CommonAttributeParser commonAttributeParser = new CommonAttributeParser(InfoType.Field);
    for (int i = 0; i < attributeCount; ++i) {
        final int attributeNameIndex = stream.readU2();
        final Symbol<Name> attributeName = pool.symbolAt(attributeNameIndex, "attribute name");
        final int attributeSize = stream.readS4();
        final int startPosition = stream.getPosition();
        if (isStatic && attributeName.equals(Name.ConstantValue)) {
            if (constantValue != null) {
                throw ConstantPool.classFormatError("Duplicate ConstantValue attribute");
            }
            fieldAttributes[i] = constantValue = new ConstantValueAttribute(stream.readU2());
            if (constantValue.getConstantValueIndex() == 0) {
                throw ConstantPool.classFormatError("Invalid ConstantValue index");
            }
        } else if (attributeName.equals(Name.Synthetic)) {
            fieldFlags |= ACC_SYNTHETIC;
            fieldAttributes[i] = new Attribute(attributeName, null);
        } else if (majorVersion >= JAVA_1_5_VERSION) {
            Attribute attr = commonAttributeParser.parseCommonAttribute(attributeName, attributeSize);
            // stream.skip(attributeSize);
            fieldAttributes[i] = attr == null ? new Attribute(attributeName, stream.readByteArray(attributeSize)) : attr;
        } else {
            // stream.skip(attributeSize);
            fieldAttributes[i] = new Attribute(attributeName, stream.readByteArray(attributeSize));
        }
        if (attributeSize != stream.getPosition() - startPosition) {
            throw ConstantPool.classFormatError("Invalid attribute_length for " + attributeName + " attribute");
        }
    }
    final JavaKind kind = Types.getJavaKind(descriptor);
    if (kind == JavaKind.Void) {
        throw ConstantPool.classFormatError("Fields cannot be of type void");
    }
    if (constantValue != null) {
        Tag tag = pool.tagAt(constantValue.getConstantValueIndex());
        boolean valid = false;
        switch(kind) {
            // fall through
            case Boolean:
            // fall through
            case Byte:
            // fall through
            case Short:
            // fall through
            case Char:
            case // fall through
            Int:
                valid = (tag == Tag.INTEGER);
                break;
            case Float:
                valid = (tag == Tag.FLOAT);
                break;
            case Long:
                valid = (tag == Tag.LONG);
                break;
            case Double:
                valid = (tag == Tag.DOUBLE);
                break;
            case Object:
                valid = (tag == Tag.STRING) && descriptor.equals(Type.java_lang_String);
                break;
            default:
                {
                    throw ConstantPool.classFormatError("Cannot have ConstantValue for fields of type " + kind);
                }
        }
        if (!valid) {
            throw ConstantPool.classFormatError("ConstantValue attribute does not match field type");
        }
    }
    return new ParserField(fieldFlags, name, descriptor, fieldAttributes);
}
Also used : BootstrapMethodsAttribute(com.oracle.truffle.espresso.classfile.attributes.BootstrapMethodsAttribute) EnclosingMethodAttribute(com.oracle.truffle.espresso.classfile.attributes.EnclosingMethodAttribute) StackMapTableAttribute(com.oracle.truffle.espresso.classfile.attributes.StackMapTableAttribute) NestHostAttribute(com.oracle.truffle.espresso.classfile.attributes.NestHostAttribute) SourceFileAttribute(com.oracle.truffle.espresso.classfile.attributes.SourceFileAttribute) SourceDebugExtensionAttribute(com.oracle.truffle.espresso.classfile.attributes.SourceDebugExtensionAttribute) PermittedSubclassesAttribute(com.oracle.truffle.espresso.classfile.attributes.PermittedSubclassesAttribute) LineNumberTableAttribute(com.oracle.truffle.espresso.classfile.attributes.LineNumberTableAttribute) ExceptionsAttribute(com.oracle.truffle.espresso.classfile.attributes.ExceptionsAttribute) CodeAttribute(com.oracle.truffle.espresso.classfile.attributes.CodeAttribute) NestMembersAttribute(com.oracle.truffle.espresso.classfile.attributes.NestMembersAttribute) ConstantValueAttribute(com.oracle.truffle.espresso.classfile.attributes.ConstantValueAttribute) MethodParametersAttribute(com.oracle.truffle.espresso.classfile.attributes.MethodParametersAttribute) Attribute(com.oracle.truffle.espresso.runtime.Attribute) InnerClassesAttribute(com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute) RecordAttribute(com.oracle.truffle.espresso.classfile.attributes.RecordAttribute) SignatureAttribute(com.oracle.truffle.espresso.classfile.attributes.SignatureAttribute) ConstantValueAttribute(com.oracle.truffle.espresso.classfile.attributes.ConstantValueAttribute) ParserField(com.oracle.truffle.espresso.impl.ParserField) Name(com.oracle.truffle.espresso.descriptors.Symbol.Name) Type(com.oracle.truffle.espresso.descriptors.Symbol.Type) ModifiedUTF8(com.oracle.truffle.espresso.descriptors.Symbol.ModifiedUTF8) Tag(com.oracle.truffle.espresso.classfile.ConstantPool.Tag) JavaKind(com.oracle.truffle.espresso.meta.JavaKind)

Aggregations

Tag (com.oracle.truffle.espresso.classfile.ConstantPool.Tag)1 BootstrapMethodsAttribute (com.oracle.truffle.espresso.classfile.attributes.BootstrapMethodsAttribute)1 CodeAttribute (com.oracle.truffle.espresso.classfile.attributes.CodeAttribute)1 ConstantValueAttribute (com.oracle.truffle.espresso.classfile.attributes.ConstantValueAttribute)1 EnclosingMethodAttribute (com.oracle.truffle.espresso.classfile.attributes.EnclosingMethodAttribute)1 ExceptionsAttribute (com.oracle.truffle.espresso.classfile.attributes.ExceptionsAttribute)1 InnerClassesAttribute (com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute)1 LineNumberTableAttribute (com.oracle.truffle.espresso.classfile.attributes.LineNumberTableAttribute)1 MethodParametersAttribute (com.oracle.truffle.espresso.classfile.attributes.MethodParametersAttribute)1 NestHostAttribute (com.oracle.truffle.espresso.classfile.attributes.NestHostAttribute)1 NestMembersAttribute (com.oracle.truffle.espresso.classfile.attributes.NestMembersAttribute)1 PermittedSubclassesAttribute (com.oracle.truffle.espresso.classfile.attributes.PermittedSubclassesAttribute)1 RecordAttribute (com.oracle.truffle.espresso.classfile.attributes.RecordAttribute)1 SignatureAttribute (com.oracle.truffle.espresso.classfile.attributes.SignatureAttribute)1 SourceDebugExtensionAttribute (com.oracle.truffle.espresso.classfile.attributes.SourceDebugExtensionAttribute)1 SourceFileAttribute (com.oracle.truffle.espresso.classfile.attributes.SourceFileAttribute)1 StackMapTableAttribute (com.oracle.truffle.espresso.classfile.attributes.StackMapTableAttribute)1 ModifiedUTF8 (com.oracle.truffle.espresso.descriptors.Symbol.ModifiedUTF8)1 Name (com.oracle.truffle.espresso.descriptors.Symbol.Name)1 Type (com.oracle.truffle.espresso.descriptors.Symbol.Type)1