Search in sources :

Example 1 with EnclosingMethodAttribute

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

the class ClassfileParser method parseClassAttributes.

private Attribute[] parseClassAttributes() {
    int attributeCount = stream.readU2();
    if (attributeCount == 0) {
        if (maxBootstrapMethodAttrIndex >= 0) {
            throw ConstantPool.classFormatError("BootstrapMethods attribute is missing");
        }
        return Attribute.EMPTY_ARRAY;
    }
    SourceFileAttribute sourceFileName = null;
    SourceDebugExtensionAttribute sourceDebugExtensionAttribute = null;
    NestHostAttribute nestHost = null;
    NestMembersAttribute nestMembers = null;
    EnclosingMethodAttribute enclosingMethod = null;
    BootstrapMethodsAttribute bootstrapMethods = null;
    InnerClassesAttribute innerClasses = null;
    PermittedSubclassesAttribute permittedSubclasses = null;
    RecordAttribute record = null;
    CommonAttributeParser commonAttributeParser = new CommonAttributeParser(InfoType.Class);
    final Attribute[] classAttributes = spawnAttributesArray(attributeCount);
    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 (attributeName.equals(Name.SourceFile)) {
            if (sourceFileName != null) {
                throw ConstantPool.classFormatError("Duplicate SourceFile attribute");
            }
            classAttributes[i] = sourceFileName = parseSourceFileAttribute(attributeName);
        } else if (attributeName.equals(Name.SourceDebugExtension)) {
            if (sourceDebugExtensionAttribute != null) {
                throw ConstantPool.classFormatError("Duplicate SourceDebugExtension attribute");
            }
            classAttributes[i] = sourceDebugExtensionAttribute = parseSourceDebugExtensionAttribute(attributeName, attributeSize);
        } else if (attributeName.equals(Name.Synthetic)) {
            classFlags |= ACC_SYNTHETIC;
            classAttributes[i] = new Attribute(attributeName, null);
        } else if (attributeName.equals(Name.InnerClasses)) {
            if (innerClasses != null) {
                throw ConstantPool.classFormatError("Duplicate InnerClasses attribute");
            }
            classAttributes[i] = innerClasses = parseInnerClasses(attributeName);
        } else if (majorVersion >= JAVA_1_5_VERSION) {
            if (majorVersion >= JAVA_7_VERSION && attributeName.equals(Name.BootstrapMethods)) {
                if (bootstrapMethods != null) {
                    throw ConstantPool.classFormatError("Duplicate BootstrapMethods attribute");
                }
                classAttributes[i] = bootstrapMethods = parseBootstrapMethods(attributeName);
            } else if (attributeName.equals(Name.EnclosingMethod)) {
                if (enclosingMethod != null) {
                    throw ConstantPool.classFormatError("Duplicate EnclosingMethod attribute");
                }
                classAttributes[i] = enclosingMethod = parseEnclosingMethodAttribute(attributeName);
            } else if (majorVersion >= JAVA_11_VERSION && attributeName.equals(Name.NestHost)) {
                if (nestHost != null) {
                    throw ConstantPool.classFormatError("Duplicate NestHost attribute");
                }
                if (nestMembers != null) {
                    throw ConstantPool.classFormatError("Classfile cannot have both a nest members and a nest host attribute.");
                }
                if (attributeSize != 2) {
                    throw ConstantPool.classFormatError("Attribute length of NestHost must be 2");
                }
                classAttributes[i] = nestHost = parseNestHostAttribute(attributeName);
            } else if (majorVersion >= JAVA_11_VERSION && attributeName.equals(Name.NestMembers)) {
                if (nestMembers != null) {
                    throw ConstantPool.classFormatError("Duplicate NestMembers attribute");
                }
                if (nestHost != null) {
                    throw ConstantPool.classFormatError("Classfile cannot have both a nest members and a nest host attribute.");
                }
                classAttributes[i] = nestMembers = parseNestMembers(attributeName);
            } else if (majorVersion >= JAVA_14_VERSION && attributeName.equals(Name.Record)) {
                if (record != null) {
                    throw ConstantPool.classFormatError("Duplicate Record attribute");
                }
                classAttributes[i] = record = parseRecord(attributeName);
            } else if (majorVersion >= JAVA_17_VERSION && attributeName.equals(Name.PermittedSubclasses)) {
                if (permittedSubclasses != null) {
                    throw ConstantPool.classFormatError("Duplicate PermittedSubclasses attribute");
                }
                classAttributes[i] = permittedSubclasses = parsePermittedSubclasses(attributeName);
            } else {
                Attribute attr = commonAttributeParser.parseCommonAttribute(attributeName, attributeSize);
                // stream.skip(attributeSize);
                classAttributes[i] = attr == null ? new Attribute(attributeName, stream.readByteArray(attributeSize)) : attr;
            }
        } else {
            // stream.skip(attributeSize);
            classAttributes[i] = new Attribute(attributeName, stream.readByteArray(attributeSize));
        }
        if (attributeSize != stream.getPosition() - startPosition) {
            throw ConstantPool.classFormatError("Invalid attribute length for " + attributeName + " attribute");
        }
    }
    if (maxBootstrapMethodAttrIndex >= 0 && bootstrapMethods == null) {
        throw ConstantPool.classFormatError("BootstrapMethods attribute is missing");
    }
    return classAttributes;
}
Also used : NestHostAttribute(com.oracle.truffle.espresso.classfile.attributes.NestHostAttribute) BootstrapMethodsAttribute(com.oracle.truffle.espresso.classfile.attributes.BootstrapMethodsAttribute) PermittedSubclassesAttribute(com.oracle.truffle.espresso.classfile.attributes.PermittedSubclassesAttribute) 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) SourceDebugExtensionAttribute(com.oracle.truffle.espresso.classfile.attributes.SourceDebugExtensionAttribute) NestMembersAttribute(com.oracle.truffle.espresso.classfile.attributes.NestMembersAttribute) Name(com.oracle.truffle.espresso.descriptors.Symbol.Name) SourceFileAttribute(com.oracle.truffle.espresso.classfile.attributes.SourceFileAttribute) RecordAttribute(com.oracle.truffle.espresso.classfile.attributes.RecordAttribute) EnclosingMethodAttribute(com.oracle.truffle.espresso.classfile.attributes.EnclosingMethodAttribute) InnerClassesAttribute(com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute)

Example 2 with EnclosingMethodAttribute

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

the class ClassInfo method create.

public static HotSwapClassInfo create(ObjectKlass klass, Symbol<Name> name, byte[] bytes, StaticObject definingLoader, EspressoContext context) {
    Symbol<Type> type = context.getTypes().fromName(name);
    ParserKlass parserKlass = ClassfileParser.parse(new ClassfileStream(bytes, null), definingLoader, type, context);
    StringBuilder hierarchy = new StringBuilder();
    StringBuilder methods = new StringBuilder();
    StringBuilder fields = new StringBuilder();
    StringBuilder enclosing = new StringBuilder();
    Matcher matcher = InnerClassRedefiner.ANON_INNER_CLASS_PATTERN.matcher(name.toString());
    if (matcher.matches()) {
        // fingerprints are only relevant for inner classes
        hierarchy.append(parserKlass.getSuperKlass().toString()).append(";");
        for (Symbol<Type> itf : parserKlass.getSuperInterfaces()) {
            hierarchy.append(itf.toString()).append(";");
        }
        for (ParserMethod method : parserKlass.getMethods()) {
            methods.append(method.getName().toString()).append(";");
            methods.append(method.getSignature().toString()).append(";");
        }
        for (ParserField field : parserKlass.getFields()) {
            fields.append(field.getType().toString()).append(";");
            fields.append(field.getName().toString()).append(";");
        }
        ConstantPool pool = parserKlass.getConstantPool();
        EnclosingMethodAttribute attr = (EnclosingMethodAttribute) parserKlass.getAttribute(EnclosingMethodAttribute.NAME);
        NameAndTypeConstant nmt = pool.nameAndTypeAt(attr.getMethodIndex());
        enclosing.append(nmt.getName(pool)).append(";").append(nmt.getDescriptor(pool));
    }
    return new HotSwapClassInfo(klass, name, definingLoader, hierarchy.toString(), methods.toString(), fields.toString(), enclosing.toString(), new ArrayList<>(1), bytes);
}
Also used : ClassfileStream(com.oracle.truffle.espresso.classfile.ClassfileStream) Matcher(java.util.regex.Matcher) ParserMethod(com.oracle.truffle.espresso.impl.ParserMethod) NameAndTypeConstant(com.oracle.truffle.espresso.classfile.constantpool.NameAndTypeConstant) ParserField(com.oracle.truffle.espresso.impl.ParserField) Type(com.oracle.truffle.espresso.descriptors.Symbol.Type) ConstantPool(com.oracle.truffle.espresso.classfile.ConstantPool) ParserKlass(com.oracle.truffle.espresso.impl.ParserKlass) EnclosingMethodAttribute(com.oracle.truffle.espresso.classfile.attributes.EnclosingMethodAttribute)

Example 3 with EnclosingMethodAttribute

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

the class VM method JVM_GetEnclosingMethodInfo.

@VmImpl(isJni = true)
@JavaType(Object[].class)
public StaticObject JVM_GetEnclosingMethodInfo(@JavaType(Class.class) StaticObject self) {
    Meta meta = getMeta();
    InterpreterToVM vm = meta.getInterpreterToVM();
    if (self.getMirrorKlass() instanceof ObjectKlass) {
        ObjectKlass klass = (ObjectKlass) self.getMirrorKlass();
        EnclosingMethodAttribute enclosingMethodAttr = klass.getEnclosingMethod();
        if (enclosingMethodAttr == null) {
            return StaticObject.NULL;
        }
        int classIndex = enclosingMethodAttr.getClassIndex();
        if (classIndex == 0) {
            return StaticObject.NULL;
        }
        StaticObject arr = meta.java_lang_Object.allocateReferenceArray(3);
        RuntimeConstantPool pool = klass.getConstantPool();
        Klass enclosingKlass = pool.resolvedKlassAt(klass, classIndex);
        vm.setArrayObject(enclosingKlass.mirror(), 0, arr);
        int methodIndex = enclosingMethodAttr.getMethodIndex();
        if (methodIndex != 0) {
            NameAndTypeConstant nmt = pool.nameAndTypeAt(methodIndex);
            StaticObject name = meta.toGuestString(nmt.getName(pool));
            StaticObject desc = meta.toGuestString(nmt.getDescriptor(pool));
            vm.setArrayObject(name, 1, arr);
            vm.setArrayObject(desc, 2, arr);
        }
        return arr;
    }
    return StaticObject.NULL;
}
Also used : Meta(com.oracle.truffle.espresso.meta.Meta) RuntimeConstantPool(com.oracle.truffle.espresso.classfile.RuntimeConstantPool) Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) ArrayKlass(com.oracle.truffle.espresso.impl.ArrayKlass) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) NameAndTypeConstant(com.oracle.truffle.espresso.classfile.constantpool.NameAndTypeConstant) NoSafepoint(com.oracle.truffle.espresso.jni.NoSafepoint) EnclosingMethodAttribute(com.oracle.truffle.espresso.classfile.attributes.EnclosingMethodAttribute) JavaType(com.oracle.truffle.espresso.substitutions.JavaType)

Aggregations

EnclosingMethodAttribute (com.oracle.truffle.espresso.classfile.attributes.EnclosingMethodAttribute)3 NameAndTypeConstant (com.oracle.truffle.espresso.classfile.constantpool.NameAndTypeConstant)2 ClassfileStream (com.oracle.truffle.espresso.classfile.ClassfileStream)1 ConstantPool (com.oracle.truffle.espresso.classfile.ConstantPool)1 RuntimeConstantPool (com.oracle.truffle.espresso.classfile.RuntimeConstantPool)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 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