internal MethodHandle(JavaClassImage image, MethodHandleInfo info) { Kind = info.ReferenceKind; switch (Kind) { case MethodReferenceKind.GetField: case MethodReferenceKind.GetStatic: case MethodReferenceKind.PutField: case MethodReferenceKind.PutStatic: _member = new LazyValue <IMemberReference>(() => image.ResolveField(info.ReferenceIndex)); break; case MethodReferenceKind.InvokeVirtual: case MethodReferenceKind.InvokeStatic: case MethodReferenceKind.InvokeSpecial: case MethodReferenceKind.NewInvokeSpecial: _member = new LazyValue <IMemberReference>(() => image.ResolveMethod(info.ReferenceIndex)); break; case MethodReferenceKind.InvokeInterface: throw new NotImplementedException(); default: throw new ArgumentOutOfRangeException(); } }
private static object ResolveArgument(JavaClassImage image, ushort index) { var constantInfo = image.ClassFile.ConstantPool.ResolveConstant(index); switch (constantInfo.Tag) { case ConstantPoolTag.String: constantInfo = image.ClassFile.ConstantPool.ResolveConstant(index); return(constantInfo is StringInfo stringInfo ? image.ClassFile.ConstantPool.ResolveString(stringInfo.StringIndex) : null); case ConstantPoolTag.Class: return(image.ResolveClass(index)); case ConstantPoolTag.Integer: case ConstantPoolTag.Long: case ConstantPoolTag.Float: case ConstantPoolTag.Double: return(((PrimitiveInfo)constantInfo).Value); case ConstantPoolTag.MethodType: var methodType = (MethodTypeInfo)constantInfo; string rawDescriptor = image.ClassFile.ConstantPool.ResolveString(methodType.DescriptorIndex); return(MethodDescriptor.FromString(rawDescriptor)); case ConstantPoolTag.MethodHandle: throw new NotImplementedException(); default: throw new ArgumentOutOfRangeException(); } }
internal ClassDefinition(JavaClassImage classImage) : base(classImage, (ClassInfo)classImage.ClassFile.ConstantPool.ResolveConstant(classImage.ClassFile.ThisClass)) { Image = classImage; // Super class _superClass = new LazyValue <ClassReference>(() => classImage.ClassFile.SuperClass != 0 ? new ClassReference(classImage, (ClassInfo)classImage.ClassFile.ConstantPool.ResolveConstant(classImage.ClassFile.SuperClass)) : null); // Flags AccessFlags = classImage.ClassFile.AccessFlags; // Fields Fields = new FieldCollection(this); foreach (var field in classImage.ClassFile.Fields) { Fields.Add(new FieldDefinition(classImage, field)); } // Methods Methods = new MethodCollection(this); foreach (var method in classImage.ClassFile.Methods) { Methods.Add(new MethodDefinition(classImage, method)); } }
internal FieldDefinition(JavaClassImage classImage, FieldInfo fieldInfo) { // Name _name = new LazyValue <string>(() => classImage.ClassFile.ConstantPool.ResolveString(fieldInfo.NameIndex) ?? $"<<<INVALID({fieldInfo.NameIndex})>>>"); // Access flags. AccessFlags = fieldInfo.AccessFlags; // Descriptor. _descriptor = new LazyValue <FieldDescriptor>(() => classImage.ResolveFieldDescriptor(fieldInfo.DescriptorIndex)); // Extra attributes. foreach (var attr in fieldInfo.Attributes) { string name = classImage.ClassFile.ConstantPool.ResolveString(attr.NameIndex); switch (name) { case SingleIndexAttribute.ConstantValueAttribute: // Constant _constant = new LazyValue <object>(() => { var contents = SingleIndexAttribute.FromReader(name, new MemoryBigEndianReader(attr.Contents)); var constantInfo = classImage.ClassFile.ConstantPool.ResolveConstant(contents.ConstantPoolIndex); switch (constantInfo) { case PrimitiveInfo primitiveInfo: return(primitiveInfo.Value); case StringInfo stringInfo: return(classImage.ClassFile.ConstantPool.ResolveString(stringInfo.StringIndex)); default: return(null); } }); break; default: // Fall back method: ExtraAttributes.Add(classImage.ClassFile.ConstantPool.ResolveString(attr.NameIndex), attr.Clone()); break; } } }
internal ClassDefinition(JavaClassImage classImage) : base(classImage, (ClassInfo)classImage.ClassFile.ConstantPool.ResolveConstant(classImage.ClassFile.ThisClass)) { Image = classImage; // Super class _superClass = new LazyValue <ClassReference>(() => classImage.ClassFile.SuperClass != 0 ? new ClassReference(classImage, (ClassInfo)classImage.ClassFile.ConstantPool.ResolveConstant(classImage.ClassFile.SuperClass)) : null); // Flags AccessFlags = classImage.ClassFile.AccessFlags; // Fields Fields = new FieldCollection(this); foreach (var field in classImage.ClassFile.Fields) { Fields.Add(new FieldDefinition(classImage, field)); } // Methods Methods = new MethodCollection(this); foreach (var method in classImage.ClassFile.Methods) { Methods.Add(new MethodDefinition(classImage, method)); } // Attributes foreach (var attr in classImage.ClassFile.Attributes) { string name = classImage.ClassFile.ConstantPool.ResolveString(attr.NameIndex); switch (name) { // Source file case SingleIndexAttribute.SourceFileAttribute: _sourceFile = new LazyValue <string>(() => { var sourceFile = SingleIndexAttribute.FromReader(name, new MemoryBigEndianReader(attr.Contents)); return(classImage.ClassFile.ConstantPool.ResolveString(sourceFile.ConstantPoolIndex)); }); break; default: ExtraAttributes.Add(name, attr.Clone()); break; } } }
internal BootstrapMethod(JavaClassImage image, BootstrapMethodInfo info) { _handle = new LazyValue <MethodHandle>(() => { var constantInfo = image.ClassFile.ConstantPool.ResolveConstant(info.MethodRefIndex); return(constantInfo is MethodHandleInfo methodHandleInfo ? new MethodHandle(image, methodHandleInfo) : null); }); Arguments = new List <object>(info.Arguments.Count); foreach (ushort argIndex in info.Arguments) { Arguments.Add(ResolveArgument(image, argIndex)); } }
internal MethodDefinition(JavaClassImage classImage, MethodInfo methodInfo) { // Name _name = new LazyValue <string>(() => classImage.ClassFile.ConstantPool.ResolveString(methodInfo.NameIndex) ?? $"<<<INVALID({methodInfo.NameIndex})>>>"); // Flags AccessFlags = methodInfo.AccessFlags; //Descriptor _descriptor = new LazyValue <MethodDescriptor>(() => classImage.ResolveMethodDescriptor(methodInfo.DescriptorIndex)); // Attributes foreach (var attribute in methodInfo.Attributes) { string name = classImage.ClassFile.ConstantPool.ResolveString(attribute.NameIndex); switch (name) { // Code case CodeAttribute.AttributeName: _body = new LazyValue <ByteCodeMethodBody>(() => { var reader = new MemoryBigEndianReader(attribute.Contents); return(new ByteCodeMethodBody(classImage, CodeAttribute.FromReader(reader))); }); break; // Exceptions case ExceptionsAttribute.AttributeName: _exceptions = new LazyValue <IList <ClassReference> >(() => { var reader = new MemoryBigEndianReader(attribute.Contents); var attr = ExceptionsAttribute.FromReader(reader); return(attr.Exceptions .Select(index => classImage.ResolveClass(index)) .ToList()); }); break; default: ExtraAttributes.Add(name, attribute.Clone()); break; } } }
internal DynamicInvocation(JavaClassImage image, InvokeDynamicInfo dynamicInfo) { _bootstrapMethod = new LazyValue <BootstrapMethod>( () => image.ResolveBootstrapMethod(dynamicInfo.BootstrapMethodIndex)); if (image.ClassFile.ConstantPool.ResolveConstant(dynamicInfo.NameAndTypeIndex) is NameAndTypeInfo nameAndType) { _methodName = new LazyValue <string>( () => image.ClassFile.ConstantPool.ResolveString(nameAndType.NameIndex)); _methodDescriptor = new LazyValue <MethodDescriptor>( () => MethodDescriptor.FromString(image.ClassFile.ConstantPool.ResolveString(nameAndType.DescriptorIndex))); } else { _methodName = new LazyValue <string>(); _methodDescriptor = new LazyValue <MethodDescriptor>(); } }
internal FieldReference(JavaClassImage classImage, FieldRefInfo fieldRefInfo) { _name = new LazyValue <string>(() => { var constantInfo = classImage.ClassFile.ConstantPool.ResolveConstant(fieldRefInfo.NameAndTypeIndex); return(constantInfo is NameAndTypeInfo nameAndTypeInfo ? classImage.ClassFile.ConstantPool.ResolveString(nameAndTypeInfo.NameIndex) ?? $"<<<INVALID({nameAndTypeInfo.NameIndex})>>>" : $"<<<INVALID({fieldRefInfo.NameAndTypeIndex})>>>"); }); _descriptor = new LazyValue <FieldDescriptor>(() => { var constantInfo = classImage.ClassFile.ConstantPool.ResolveConstant(fieldRefInfo.NameAndTypeIndex); return(constantInfo is NameAndTypeInfo nameAndTypeInfo ? classImage.ResolveFieldDescriptor(nameAndTypeInfo.DescriptorIndex) : null); }); _declaringClass = new LazyValue <ClassReference>(() => classImage.ResolveClass(fieldRefInfo.ClassIndex)); }
internal ClassReference(JavaClassImage classImage, ClassInfo classInfo) { _name = new LazyValue <string>(() => classImage.ClassFile.ConstantPool.ResolveString(classInfo.NameIndex) ?? $"<<<INVALID({classInfo.NameIndex})>>>"); }