Search in sources :

Example 11 with Symbol

use of com.oracle.truffle.espresso.descriptors.Symbol in project graal by oracle.

the class VM method defineModule.

@SuppressWarnings("try")
public void defineModule(StaticObject module, String moduleName, boolean is_open, String[] packages, SubstitutionProfiler profiler) {
    Meta meta = getMeta();
    StaticObject loader = meta.java_lang_Module_loader.getObject(module);
    if (loader != nonReflectionClassLoader(loader)) {
        profiler.profile(15);
        throw meta.throwExceptionWithMessage(meta.java_lang_IllegalArgumentException, "Class loader is an invalid delegating class loader");
    }
    // Prepare variables
    ClassRegistry registry = getRegistries().getClassRegistry(loader);
    assert registry != null;
    PackageTable packageTable = registry.packages();
    ModuleTable moduleTable = registry.modules();
    assert moduleTable != null && packageTable != null;
    boolean loaderIsBootOrPlatform = ClassRegistry.loaderIsBootOrPlatform(loader, meta);
    ArrayList<Symbol<Name>> pkgSymbols = new ArrayList<>();
    try (EntryTable.BlockLock block = packageTable.write()) {
        for (String str : packages) {
            // Extract the package symbols. Also checks for duplicates.
            if (!loaderIsBootOrPlatform && (str.equals("java") || str.startsWith("java/"))) {
                // Only modules defined to either the boot or platform class loader, can define
                // a "java/" package.
                profiler.profile(14);
                throw meta.throwExceptionWithMessage(meta.java_lang_IllegalArgumentException, cat("Class loader (", loader.getKlass().getType(), ") tried to define prohibited package name: ", str));
            }
            Symbol<Name> symbol = getNames().getOrCreate(str);
            if (packageTable.lookup(symbol) != null) {
                profiler.profile(13);
                throw meta.throwExceptionWithMessage(meta.java_lang_IllegalArgumentException, cat("Package ", str, " is already defined."));
            }
            pkgSymbols.add(symbol);
        }
        Symbol<Name> moduleSymbol = getNames().getOrCreate(moduleName);
        // Try define module
        ModuleEntry moduleEntry = moduleTable.createAndAddEntry(moduleSymbol, registry, is_open, module);
        if (moduleEntry == null) {
            // Module already defined
            profiler.profile(12);
            throw meta.throwExceptionWithMessage(meta.java_lang_IllegalArgumentException, cat("Module ", moduleName, " is already defined"));
        }
        // Register packages
        for (Symbol<Name> pkgSymbol : pkgSymbols) {
            PackageEntry pkgEntry = packageTable.createAndAddEntry(pkgSymbol, moduleEntry);
            // should have been checked before
            assert pkgEntry != null;
        }
        // Link guest module to its host representation
        meta.HIDDEN_MODULE_ENTRY.setHiddenObject(module, moduleEntry);
    }
    if (StaticObject.isNull(loader) && getContext().getVmProperties().bootClassPathType().isExplodedModule()) {
        profiler.profile(11);
        // If we have an exploded build, and the module is defined to the bootloader, prepend a
        // class path entry for this module.
        prependModuleClasspath(moduleName);
    }
}
Also used : Meta(com.oracle.truffle.espresso.meta.Meta) ClassRegistry(com.oracle.truffle.espresso.impl.ClassRegistry) Symbol(com.oracle.truffle.espresso.descriptors.Symbol) ModuleEntry(com.oracle.truffle.espresso.impl.ModuleTable.ModuleEntry) ArrayList(java.util.ArrayList) ModuleTable(com.oracle.truffle.espresso.impl.ModuleTable) PackageTable(com.oracle.truffle.espresso.impl.PackageTable) Name(com.oracle.truffle.espresso.descriptors.Symbol.Name) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) EntryTable(com.oracle.truffle.espresso.impl.EntryTable) PackageEntry(com.oracle.truffle.espresso.impl.PackageTable.PackageEntry)

Example 12 with Symbol

use of com.oracle.truffle.espresso.descriptors.Symbol in project graal by oracle.

the class ClassRegistry method createKlass.

@SuppressWarnings("try")
private ObjectKlass createKlass(Meta meta, ParserKlass parserKlass, Symbol<Type> type, Symbol<Type> superKlassType, ClassDefinitionInfo info) {
    EspressoThreadLocalState threadLocalState = meta.getContext().getLanguage().getThreadLocalState();
    TypeStack chain = threadLocalState.getTypeStack();
    ObjectKlass superKlass = null;
    ObjectKlass[] superInterfaces = null;
    LinkedKlass[] linkedInterfaces = null;
    chain.push(type);
    try {
        if (superKlassType != null) {
            if (chain.contains(superKlassType)) {
                throw meta.throwException(meta.java_lang_ClassCircularityError);
            }
            superKlass = loadKlassRecursively(meta, superKlassType, true);
        }
        final Symbol<Type>[] superInterfacesTypes = parserKlass.getSuperInterfaces();
        linkedInterfaces = superInterfacesTypes.length == 0 ? LinkedKlass.EMPTY_ARRAY : new LinkedKlass[superInterfacesTypes.length];
        superInterfaces = superInterfacesTypes.length == 0 ? ObjectKlass.EMPTY_ARRAY : new ObjectKlass[superInterfacesTypes.length];
        for (int i = 0; i < superInterfacesTypes.length; ++i) {
            if (chain.contains(superInterfacesTypes[i])) {
                throw meta.throwException(meta.java_lang_ClassCircularityError);
            }
            ObjectKlass interf = loadKlassRecursively(meta, superInterfacesTypes[i], false);
            superInterfaces[i] = interf;
            linkedInterfaces[i] = interf.getLinkedKlass();
        }
    } finally {
        chain.pop();
    }
    if (getContext().getJavaVersion().java16OrLater() && superKlass != null) {
        if (superKlass.isFinalFlagSet()) {
            throw meta.throwExceptionWithMessage(meta.java_lang_IncompatibleClassChangeError, "class " + type + " is a subclass of final class " + superKlassType);
        }
    }
    ObjectKlass klass;
    try (DebugCloseable define = KLASS_DEFINE.scope(context.getTimers())) {
        // FIXME(peterssen): Do NOT create a LinkedKlass every time, use a global cache.
        ContextDescription description = new ContextDescription(context.getLanguage(), context.getJavaVersion());
        LinkedKlass linkedKlass = LinkedKlass.create(description, parserKlass, superKlass == null ? null : superKlass.getLinkedKlass(), linkedInterfaces);
        klass = new ObjectKlass(context, linkedKlass, superKlass, superInterfaces, getClassLoader(), info);
    }
    if (superKlass != null) {
        if (!Klass.checkAccess(superKlass, klass)) {
            throw meta.throwExceptionWithMessage(meta.java_lang_IllegalAccessError, "class " + type + " cannot access its superclass " + superKlassType);
        }
        if (!superKlass.permittedSubclassCheck(klass)) {
            throw meta.throwExceptionWithMessage(meta.java_lang_IncompatibleClassChangeError, "class " + type + " is not a permitted subclass of class " + superKlassType);
        }
    }
    for (ObjectKlass interf : superInterfaces) {
        if (interf != null) {
            if (!Klass.checkAccess(interf, klass)) {
                throw meta.throwExceptionWithMessage(meta.java_lang_IllegalAccessError, "class " + type + " cannot access its superinterface " + interf.getType());
            }
            if (!interf.permittedSubclassCheck(klass)) {
                throw meta.throwExceptionWithMessage(meta.java_lang_IncompatibleClassChangeError, "class " + type + " is not a permitted subclass of interface " + superKlassType);
            }
        }
    }
    return klass;
}
Also used : EspressoThreadLocalState(com.oracle.truffle.espresso.runtime.EspressoThreadLocalState) Symbol(com.oracle.truffle.espresso.descriptors.Symbol) DebugCloseable(com.oracle.truffle.espresso.perf.DebugCloseable)

Example 13 with Symbol

use of com.oracle.truffle.espresso.descriptors.Symbol in project graal by oracle.

the class Target_sun_reflect_NativeMethodAccessorImpl method callMethodReflectively.

@JavaType(Object.class)
public static StaticObject callMethodReflectively(Meta meta, @JavaType(Object.class) StaticObject receiver, @JavaType(Object[].class) StaticObject args, Method m, Klass klass, @JavaType(Class[].class) StaticObject parameterTypes) {
    // Klass should be initialized if method is static, and could be delayed until method
    // invocation, according to specs. However, JCK tests that it is indeed always initialized
    // before doing anything, even if the method to be invoked is from another class.
    klass.safeInitialize();
    Method reflectedMethod = m;
    if (reflectedMethod.isRemovedByRedefition()) {
        reflectedMethod = m.getContext().getClassRedefinition().handleRemovedMethod(reflectedMethod, reflectedMethod.isStatic() ? reflectedMethod.getDeclaringKlass() : receiver.getKlass());
    }
    // actual method to invoke
    Method method;
    // target klass, receiver's klass for non-static
    Klass targetKlass;
    if (reflectedMethod.isStatic()) {
        // Ignore receiver argument;.
        method = reflectedMethod;
        targetKlass = klass;
    } else {
        if (StaticObject.isNull(receiver)) {
            throw meta.throwNullPointerException();
        }
        // Check class of receiver against class declaring method.
        if (!klass.isAssignableFrom(receiver.getKlass())) {
            throw meta.throwExceptionWithMessage(meta.java_lang_IllegalArgumentException, "object is not an instance of declaring class");
        }
        // target klass is receiver's klass
        targetKlass = receiver.getKlass();
        // no need to resolve if method is private or <init>
        if (reflectedMethod.isPrivate() || Name._init_.equals(reflectedMethod.getName())) {
            method = reflectedMethod;
        } else {
            // resolve based on the receiver
            if (reflectedMethod.getDeclaringKlass().isInterface()) {
                // resolve interface call
                // Match resolution errors with those thrown due to reflection inlining
                // Linktime resolution & IllegalAccessCheck already done by Class.getMethod()
                method = reflectedMethod;
                assert targetKlass instanceof ObjectKlass;
                method = ((ObjectKlass) targetKlass).itableLookup(method.getDeclaringKlass(), method.getITableIndex());
                if (method != null) {
                    // Check for abstract methods as well
                    if (!method.hasCode()) {
                        // new default: 65315
                        throw meta.throwExceptionWithCause(meta.java_lang_reflect_InvocationTargetException, Meta.initException(meta.java_lang_AbstractMethodError));
                    }
                }
            } else {
                // if the method can be overridden, we resolve using the vtable index.
                method = reflectedMethod;
                // VTable is live, use it
                method = targetKlass.vtableLookup(method.getVTableIndex());
                if (method != null) {
                    // Check for abstract methods as well
                    if (method.isAbstract()) {
                        // new default: 65315
                        throw meta.throwExceptionWithCause(meta.java_lang_reflect_InvocationTargetException, Meta.initException(meta.java_lang_AbstractMethodError));
                    }
                }
            }
        }
    }
    // an internal vtable bug. If you ever get this please let Karen know.
    if (method == null) {
        throw meta.throwExceptionWithMessage(meta.java_lang_NoSuchMethodError, "please let Karen know");
    }
    int argsLen = StaticObject.isNull(args) ? 0 : args.length();
    final Symbol<Type>[] signature = method.getParsedSignature();
    // Check number of arguments.
    if (Signatures.parameterCount(signature, false) != argsLen) {
        throw meta.throwExceptionWithMessage(meta.java_lang_IllegalArgumentException, "wrong number of arguments!");
    }
    Object[] adjustedArgs = new Object[argsLen];
    for (int i = 0; i < argsLen; ++i) {
        StaticObject arg = args.get(i);
        StaticObject paramTypeMirror = parameterTypes.get(i);
        Klass paramKlass = paramTypeMirror.getMirrorKlass();
        // Throws guest IllegallArgumentException if the parameter cannot be casted or widened.
        adjustedArgs[i] = checkAndWiden(meta, arg, paramKlass);
    }
    Object result;
    try {
        result = method.invokeDirect(receiver, adjustedArgs);
    } catch (EspressoException e) {
        throw meta.throwExceptionWithCause(meta.java_lang_reflect_InvocationTargetException, e.getGuestException());
    }
    if (reflectedMethod.getReturnKind() == JavaKind.Void) {
        return StaticObject.NULL;
    }
    if (reflectedMethod.getReturnKind().isPrimitive()) {
        return Meta.box(meta, result);
    }
    // Result is not void nor primitive, pass through.
    return (StaticObject) result;
}
Also used : Klass(com.oracle.truffle.espresso.impl.Klass) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) EspressoException(com.oracle.truffle.espresso.runtime.EspressoException) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) Symbol(com.oracle.truffle.espresso.descriptors.Symbol) ObjectKlass(com.oracle.truffle.espresso.impl.ObjectKlass) StaticObject(com.oracle.truffle.espresso.runtime.StaticObject) Method(com.oracle.truffle.espresso.impl.Method)

Example 14 with Symbol

use of com.oracle.truffle.espresso.descriptors.Symbol in project graal by oracle.

the class ClassfileParser method parseMethod.

private ParserMethod parseMethod(boolean isInterface) {
    int methodFlags = stream.readU2();
    int nameIndex = stream.readU2();
    int signatureIndex = stream.readU2();
    final Symbol<Name> name;
    final Symbol<Signature> signature;
    int attributeCount;
    Attribute[] methodAttributes;
    int extraFlags = methodFlags;
    boolean isClinit = false;
    boolean isInit = false;
    try (DebugCloseable closeable = METHOD_INIT.scope(context.getTimers())) {
        try (DebugCloseable nameCheck = NAME_CHECK.scope(context.getTimers())) {
            pool.utf8At(nameIndex).validateMethodName(true);
            name = pool.symbolAt(nameIndex, "method name");
            if (name.equals(Name._clinit_)) {
                // ACC_STRICT flag.
                if (majorVersion < JAVA_7_VERSION) {
                    // Backwards compatibility.
                    methodFlags = ACC_STATIC;
                } else if ((methodFlags & ACC_STATIC) == ACC_STATIC) {
                    methodFlags &= (ACC_STRICT | ACC_STATIC);
                } else if (context.getJavaVersion().java9OrLater()) {
                    throw ConstantPool.classFormatError("Method <clinit> is not static.");
                }
                // extraFlags = INITIALIZER | methodFlags;
                isClinit = true;
            } else if (name.equals(Name._init_)) {
                if (isInterface) {
                    throw ConstantPool.classFormatError("Method <init> is not valid in an interface.");
                }
                isInit = true;
            }
        }
        final boolean isStatic = Modifier.isStatic(extraFlags);
        verifyMethodFlags(methodFlags, isInterface, isInit, isClinit, majorVersion);
        /*
             * A method is a class or interface initialization method if all of the following are
             * true:
             *
             * It has the special name <clinit>.
             *
             * It is void (4.3.3). (checked earlier)
             *
             * In a class file whose version number is 51.0 or above, the method has its ACC_STATIC
             * flag set and takes no arguments (4.6).
             */
        try (DebugCloseable signatureCheck = SIGNATURE_CHECK.scope(context.getTimers())) {
            // Checks for void method if init or clinit.
            /*
                 * Obtain slot number for the signature. Forces a validation, but better in startup
                 * than going twice through the sequence, once for validation, once for slots.
                 */
            int slots = pool.utf8At(signatureIndex).validateSignatureGetSlots(isInit || isClinit);
            signature = Signatures.check(pool.symbolAt(signatureIndex, "method descriptor"));
            if (isClinit && majorVersion >= JAVA_7_VERSION) {
                // Checks clinit takes no arguments.
                if (!signature.equals(Signature._void)) {
                    throw ConstantPool.classFormatError("Method <clinit> has invalid signature: " + signature);
                }
            }
            if (slots + (isStatic ? 0 : 1) > 255) {
                throw ConstantPool.classFormatError("Too many arguments in method signature: " + signature);
            }
            if (name.equals(Name.finalize) && signature.equals(Signature._void) && !Modifier.isStatic(methodFlags) && !Type.java_lang_Object.equals(classType)) {
                // This class has a finalizer method implementation (ignore for
                // java.lang.Object).
                classFlags |= ACC_FINALIZER;
            }
        }
        attributeCount = stream.readU2();
        methodAttributes = spawnAttributesArray(attributeCount);
    }
    CodeAttribute codeAttribute = null;
    Attribute checkedExceptions = null;
    Attribute runtimeVisibleAnnotations = null;
    CommonAttributeParser commonAttributeParser = new CommonAttributeParser(InfoType.Method);
    MethodParametersAttribute methodParameters = null;
    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.Code)) {
            if (codeAttribute != null) {
                throw ConstantPool.classFormatError("Duplicate Code attribute");
            }
            try (DebugCloseable code = CODE_PARSE.scope(context.getTimers())) {
                methodAttributes[i] = codeAttribute = parseCodeAttribute(attributeName);
            }
        } else if (attributeName.equals(Name.Exceptions)) {
            if (checkedExceptions != null) {
                throw ConstantPool.classFormatError("Duplicate Exceptions attribute");
            }
            methodAttributes[i] = checkedExceptions = parseExceptions(attributeName);
        } else if (attributeName.equals(Name.Synthetic)) {
            methodFlags |= ACC_SYNTHETIC;
            methodAttributes[i] = checkedExceptions = new Attribute(attributeName, null);
        } else if (majorVersion >= JAVA_1_5_VERSION) {
            if (attributeName.equals(Name.RuntimeVisibleAnnotations)) {
                if (runtimeVisibleAnnotations != null) {
                    throw ConstantPool.classFormatError("Duplicate RuntimeVisibleAnnotations attribute");
                }
                // Check if java.lang.invoke.LambdaForm.Compiled is present here.
                byte[] data = stream.readByteArray(attributeSize);
                ClassfileStream subStream = new ClassfileStream(data, this.classfile);
                int count = subStream.readU2();
                for (int j = 0; j < count; j++) {
                    int typeIndex = parseAnnotation(subStream);
                    Utf8Constant constant = pool.utf8At(typeIndex, "annotation type");
                    // Validation of the type is done at runtime by guest java code.
                    Symbol<Type> annotType = constant.value();
                    if (Type.java_lang_invoke_LambdaForm$Compiled.equals(annotType)) {
                        methodFlags |= ACC_LAMBDA_FORM_COMPILED;
                    } else if (Type.java_lang_invoke_LambdaForm$Hidden.equals(annotType) || Type.jdk_internal_vm_annotation_Hidden.equals(annotType)) {
                        methodFlags |= ACC_HIDDEN;
                    } else if (Type.sun_reflect_CallerSensitive.equals(annotType) || Type.jdk_internal_reflect_CallerSensitive.equals(annotType)) {
                        methodFlags |= ACC_CALLER_SENSITIVE;
                    }
                }
                methodAttributes[i] = runtimeVisibleAnnotations = new Attribute(attributeName, data);
            } else if (attributeName.equals(Name.MethodParameters)) {
                if (methodParameters != null) {
                    throw ConstantPool.classFormatError("Duplicate MethodParameters attribute");
                }
                methodAttributes[i] = methodParameters = parseMethodParameters(attributeName);
            } else {
                Attribute attr = commonAttributeParser.parseCommonAttribute(attributeName, attributeSize);
                // stream.skip(attributeSize);
                methodAttributes[i] = attr == null ? new Attribute(attributeName, stream.readByteArray(attributeSize)) : attr;
            }
        } else {
            // stream.skip(attributeSize);
            methodAttributes[i] = new Attribute(attributeName, stream.readByteArray(attributeSize));
        }
        final int distance = stream.getPosition() - startPosition;
        if (attributeSize != distance) {
            final String message = "Invalid attribute_length for " + attributeName + " attribute (reported " + attributeSize + " != parsed " + distance + ")";
            throw ConstantPool.classFormatError(message);
        }
    }
    if (Modifier.isAbstract(methodFlags) || Modifier.isNative(methodFlags)) {
        if (codeAttribute != null) {
            throw ConstantPool.classFormatError("Code attribute supplied for native or abstract method");
        }
    } else {
        if (codeAttribute == null) {
            throw ConstantPool.classFormatError("Missing Code attribute");
        }
    }
    if (classDefinitionInfo.isHidden()) {
        methodFlags |= ACC_HIDDEN;
    }
    return ParserMethod.create(methodFlags, name, signature, methodAttributes);
}
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) Symbol(com.oracle.truffle.espresso.descriptors.Symbol) MethodParametersAttribute(com.oracle.truffle.espresso.classfile.attributes.MethodParametersAttribute) Name(com.oracle.truffle.espresso.descriptors.Symbol.Name) Utf8Constant(com.oracle.truffle.espresso.classfile.constantpool.Utf8Constant) CodeAttribute(com.oracle.truffle.espresso.classfile.attributes.CodeAttribute) Signature(com.oracle.truffle.espresso.descriptors.Symbol.Signature) DebugCloseable(com.oracle.truffle.espresso.perf.DebugCloseable)

Example 15 with Symbol

use of com.oracle.truffle.espresso.descriptors.Symbol in project graal by oracle.

the class ClassfileParser method parseClassImpl.

private ParserKlass parseClassImpl() {
    readMagic();
    minorVersion = stream.readU2();
    majorVersion = stream.readU2();
    verifyVersion(majorVersion, minorVersion);
    try (DebugCloseable closeable = CONSTANT_POOL.scope(context.getTimers())) {
        this.pool = ConstantPool.parse(context.getLanguage(), stream, this, classDefinitionInfo.patches, context, majorVersion, minorVersion);
    }
    // JVM_ACC_MODULE is defined in JDK-9 and later.
    if (majorVersion >= JAVA_9_VERSION) {
        classFlags = stream.readU2() & (JVM_RECOGNIZED_CLASS_MODIFIERS | ACC_MODULE);
    } else {
        classFlags = stream.readU2() & (JVM_RECOGNIZED_CLASS_MODIFIERS);
    }
    if ((classFlags & ACC_INTERFACE) != 0 && majorVersion < JAVA_6_VERSION) {
        // Set abstract bit for old class files for backward compatibility
        classFlags |= ACC_ABSTRACT;
    }
    boolean isModule = (classFlags & ACC_MODULE) != 0;
    if (isModule) {
        throw ConstantPool.noClassDefFoundError(classType + " is not a class because access_flag ACC_MODULE is set");
    }
    if (badConstantSeen != null) {
        // https://bugs.openjdk.java.net/browse/JDK-8175383
        throw ConstantPool.classFormatError(String.format("Unknown constant tag %s [in class file %s]", badConstantSeen, classfile));
    }
    verifyClassFlags(classFlags, majorVersion);
    // this class
    int thisKlassIndex = stream.readU2();
    Symbol<Name> thisKlassName = pool.classAt(thisKlassIndex).getName(pool);
    final boolean isInterface = Modifier.isInterface(classFlags);
    // TODO(peterssen): Verify class names.
    Symbol<Type> thisKlassType = context.getTypes().fromName(thisKlassName);
    if (Types.isPrimitive(thisKlassType) || Types.isArray(thisKlassType)) {
        throw ConstantPool.classFormatError(".this_class cannot be array nor primitive " + classType);
    }
    // Update classType which could be null previously to reflect the name in the constant pool.
    classType = thisKlassType;
    // Checks if name in class file matches requested name
    if (requestedClassType != null && !classDefinitionInfo.isHidden() && !requestedClassType.equals(classType)) {
        throw ConstantPool.noClassDefFoundError(classType + " (wrong name: " + requestedClassType + ")");
    }
    Symbol<Type> superKlass = parseSuperKlass();
    if (!Type.java_lang_Object.equals(classType) && superKlass == null) {
        throw ConstantPool.classFormatError("Class " + classType + " must have a superclass");
    }
    if (isInterface && !Type.java_lang_Object.equals(superKlass)) {
        throw ConstantPool.classFormatError("Interface " + classType + " must extend java.lang.Object");
    }
    Symbol<Type>[] superInterfaces;
    try (DebugCloseable closeable = PARSE_INTERFACES.scope(context.getTimers())) {
        superInterfaces = parseInterfaces();
    }
    final ParserField[] fields;
    try (DebugCloseable closeable = PARSE_FIELD.scope(context.getTimers())) {
        fields = parseFields(isInterface);
    }
    final ParserMethod[] methods;
    try (DebugCloseable closeable = PARSE_METHODS.scope(context.getTimers())) {
        methods = parseMethods(isInterface);
    }
    final Attribute[] attributes;
    try (DebugCloseable closeable = PARSE_CLASSATTR.scope(context.getTimers())) {
        attributes = parseClassAttributes();
    }
    // Ensure there are no trailing bytes
    stream.checkEndOfFile();
    if (classDefinitionInfo.isHidden()) {
        assert requestedClassType != null;
        int futureKlassID = context.getNewKlassId();
        classDefinitionInfo.initKlassID(futureKlassID);
        thisKlassName = context.getNames().getOrCreate(Types.hiddenClassName(requestedClassType, futureKlassID));
        thisKlassType = context.getTypes().fromName(thisKlassName);
        pool = pool.patchForHiddenClass(thisKlassIndex, thisKlassName);
    }
    return new ParserKlass(pool, classDefinitionInfo.patchFlags(classFlags), thisKlassName, thisKlassType, superKlass, superInterfaces, methods, fields, attributes, thisKlassIndex);
}
Also used : ParserMethod(com.oracle.truffle.espresso.impl.ParserMethod) 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) Symbol(com.oracle.truffle.espresso.descriptors.Symbol) ParserField(com.oracle.truffle.espresso.impl.ParserField) Name(com.oracle.truffle.espresso.descriptors.Symbol.Name) Type(com.oracle.truffle.espresso.descriptors.Symbol.Type) DebugCloseable(com.oracle.truffle.espresso.perf.DebugCloseable) ParserKlass(com.oracle.truffle.espresso.impl.ParserKlass)

Aggregations

Symbol (com.oracle.truffle.espresso.descriptors.Symbol)15 StaticObject (com.oracle.truffle.espresso.runtime.StaticObject)8 ArrayList (java.util.ArrayList)6 Name (com.oracle.truffle.espresso.descriptors.Symbol.Name)4 ObjectKlass (com.oracle.truffle.espresso.impl.ObjectKlass)4 InnerClassesAttribute (com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute)3 Type (com.oracle.truffle.espresso.descriptors.Symbol.Type)3 DebugCloseable (com.oracle.truffle.espresso.perf.DebugCloseable)3 BootstrapMethodsAttribute (com.oracle.truffle.espresso.classfile.attributes.BootstrapMethodsAttribute)2 CodeAttribute (com.oracle.truffle.espresso.classfile.attributes.CodeAttribute)2 ConstantValueAttribute (com.oracle.truffle.espresso.classfile.attributes.ConstantValueAttribute)2 EnclosingMethodAttribute (com.oracle.truffle.espresso.classfile.attributes.EnclosingMethodAttribute)2 ExceptionsAttribute (com.oracle.truffle.espresso.classfile.attributes.ExceptionsAttribute)2 LineNumberTableAttribute (com.oracle.truffle.espresso.classfile.attributes.LineNumberTableAttribute)2 MethodParametersAttribute (com.oracle.truffle.espresso.classfile.attributes.MethodParametersAttribute)2 NestHostAttribute (com.oracle.truffle.espresso.classfile.attributes.NestHostAttribute)2 NestMembersAttribute (com.oracle.truffle.espresso.classfile.attributes.NestMembersAttribute)2 PermittedSubclassesAttribute (com.oracle.truffle.espresso.classfile.attributes.PermittedSubclassesAttribute)2 RecordAttribute (com.oracle.truffle.espresso.classfile.attributes.RecordAttribute)2 SignatureAttribute (com.oracle.truffle.espresso.classfile.attributes.SignatureAttribute)2