use of com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute in project graal by oracle.
the class ObjectKlass method getNestedTypeNames.
@TruffleBoundary
public List<Symbol<Name>> getNestedTypeNames() {
ArrayList<Symbol<Name>> result = new ArrayList<>();
InnerClassesAttribute innerClasses = getKlassVersion().innerClasses;
if (innerClasses != null) {
for (InnerClassesAttribute.Entry entry : innerClasses.entries()) {
if (entry.innerClassIndex != 0) {
result.add(getConstantPool().classAt(entry.innerClassIndex).getName(getConstantPool()));
}
}
}
return result;
}
use of com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute 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;
}
use of com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute in project graal by oracle.
the class VM method JVM_GetSimpleBinaryName.
@VmImpl(isJni = true)
@JavaType(String.class)
public StaticObject JVM_GetSimpleBinaryName(@JavaType(Class.class) StaticObject self) {
Klass k = self.getMirrorKlass();
if (k.isPrimitive() || k.isArray()) {
return StaticObject.NULL;
}
ObjectKlass klass = (ObjectKlass) k;
RuntimeConstantPool pool = klass.getConstantPool();
InnerClassesAttribute inner = klass.getInnerClasses();
for (InnerClassesAttribute.Entry entry : inner.entries()) {
int innerClassIndex = entry.innerClassIndex;
if (innerClassIndex != 0) {
if (pool.classAt(innerClassIndex).getName(pool) == klass.getName()) {
if (pool.resolvedKlassAt(k, innerClassIndex) == k) {
if (entry.innerNameIndex != 0) {
Symbol<Name> innerName = pool.symbolAt(entry.innerNameIndex);
return getMeta().toGuestString(innerName);
} else {
break;
}
}
}
}
}
return StaticObject.NULL;
}
use of com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute in project graal by oracle.
the class VM method computeEnclosingClass.
/**
* Return the enclosing class; or null for: primitives, arrays, anonymous classes (declared
* inside methods).
*/
private static Klass computeEnclosingClass(ObjectKlass klass) {
InnerClassesAttribute innerClasses = (InnerClassesAttribute) klass.getAttribute(InnerClassesAttribute.NAME);
if (innerClasses == null) {
return null;
}
RuntimeConstantPool pool = klass.getConstantPool();
boolean found = false;
Klass outerKlass = null;
for (InnerClassesAttribute.Entry entry : innerClasses.entries()) {
if (entry.innerClassIndex != 0) {
Symbol<Name> innerDescriptor = pool.classAt(entry.innerClassIndex).getName(pool);
// Check decriptors/names before resolving.
if (innerDescriptor.equals(klass.getName())) {
Klass innerKlass = pool.resolvedKlassAt(klass, entry.innerClassIndex);
found = (innerKlass == klass);
if (found && entry.outerClassIndex != 0) {
outerKlass = pool.resolvedKlassAt(klass, entry.outerClassIndex);
}
}
}
if (found) {
break;
}
}
// the system could allow a spoof of an inner class to gain access rights.
return outerKlass;
}
use of com.oracle.truffle.espresso.classfile.attributes.InnerClassesAttribute in project graal by oracle.
the class VM method JVM_GetDeclaredClasses.
@VmImpl(isJni = true)
@JavaType(Class[].class)
public StaticObject JVM_GetDeclaredClasses(@JavaType(Class.class) StaticObject self) {
Meta meta = getMeta();
Klass klass = self.getMirrorKlass();
if (klass.isPrimitive() || klass.isArray()) {
return meta.java_lang_Class.allocateReferenceArray(0);
}
ObjectKlass instanceKlass = (ObjectKlass) klass;
InnerClassesAttribute innerClasses = (InnerClassesAttribute) instanceKlass.getAttribute(InnerClassesAttribute.NAME);
if (innerClasses == null || innerClasses.entries().length == 0) {
return meta.java_lang_Class.allocateReferenceArray(0);
}
RuntimeConstantPool pool = instanceKlass.getConstantPool();
List<Klass> innerKlasses = new ArrayList<>();
for (InnerClassesAttribute.Entry entry : innerClasses.entries()) {
if (entry.innerClassIndex != 0 && entry.outerClassIndex != 0) {
// Check to see if the name matches the class we're looking for
// before attempting to find the class.
Symbol<Name> outerDescriptor = pool.classAt(entry.outerClassIndex).getName(pool);
// Check decriptors/names before resolving.
if (outerDescriptor.equals(instanceKlass.getName())) {
Klass outerKlass = pool.resolvedKlassAt(instanceKlass, entry.outerClassIndex);
if (outerKlass == instanceKlass) {
Klass innerKlass = pool.resolvedKlassAt(instanceKlass, entry.innerClassIndex);
// HotSpot:
// Throws an exception if outer klass has not declared k as
// an inner klass
// Reflection::check_for_inner_class(k, inner_klass, true, CHECK_NULL);
// TODO(peterssen): The check in HotSpot is redundant.
innerKlasses.add(innerKlass);
}
}
}
}
return meta.java_lang_Class.allocateReferenceArray(innerKlasses.size(), new IntFunction<StaticObject>() {
@Override
public StaticObject apply(int index) {
return innerKlasses.get(index).mirror();
}
});
}
Aggregations