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;
}
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);
}
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;
}
Aggregations