栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

2.从0开始的手写java虚拟机 - 解析class文件 -2

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2.从0开始的手写java虚拟机 - 解析class文件 -2

前言:

续上一篇文章

2.2.4.获取class文件访问权限,当前class,超类class



access_flags = 33 = 0x21 = 0x0020 + 0x0001
this_class = 5

super_class = 6

2.2.5.获取接口数量及接口信息

根据解释可以看出,[]interface里面存放的应该是一个下标,指向常量池;

2.2.6.获取字段数量及字段信息
func readMembers(count uint16, reader *ClassReader) []*MemberInfo {
	members := make([]*MemberInfo, count)
	for i := range members {
		members[i] = readMember(reader)
	}
	return members
}

func readMember(reader *ClassReader) *MemberInfo {
	access_flags := reader.readUint16()
	name_index := reader.readUint16()
	descriptor_index:=reader.readUint16()
	attributes_count:=reader.readUint16()
	return &MemberInfo{
		access_flags:     access_flags,
		name_index:      name_index,
		descriptor_index: descriptor_index,
		attributes_count: attributes_count,
		attributes:       readAttributes(attributes_count, reader),
	}
}

func readAttributes(count uint16, reader *ClassReader) []AttributeInfo {
	attributes := make([]AttributeInfo, count)
	for i := range attributes {
		attributes[i] = readAttribute(reader)
	}
	return attributes
}

func readAttribute(reader *ClassReader) AttributeInfo {
	attrIndex := reader.readUint16()
	attrLen := reader.readUint32()
	attrInfo := newAttributeInfo(attrIndex, attrLen)
	attrInfo.readInfo(reader)
	return attrInfo
}

func newAttributeInfo(attribute_name_index uint16, attribute_length uint32) AttributeInfo {
	attributeName := ConstantPoolInstance.getUtf8(attribute_name_index)
	switch attributeName {
	case Code_String:
		return &CodeAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length} //ok
	case ConstantValue_String:
		return &ConstantValueAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length} //ok
	case Deprecated_String:
		return &DeprecatedAttribute{MarkerAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length}} //ok
	case Exceptions_String:
		return &ExceptionsAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length} //ok
	case LineNumberTable_String:
		return &LineNumberTableAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length} //ok
	case LocalVariableTable_String:
		return &LocalVariableTableAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length} //ok
	case SourceFile_String:
		return &SourceFileAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length} //ok
	case Synthetic_String:
		return &SyntheticAttribute{MarkerAttribute{attribute_name_index: attribute_name_index, attribute_length: attribute_length}}
	default:
		return &UnparsedAttribute{attributeName, attribute_length, nil}
	}
2.2.6.1.Code

type CodeAttribute struct {
	attribute_name_index   uint16
	attribute_length       uint32
	max_stack              uint16
	max_locals             uint16
	code_length            uint32
	code                   []byte
	exception_table_length uint16
	exception_table        []*ExceptionTableEntry
	attribute_count        uint16
	attribute_info         []AttributeInfo
}

type ExceptionTableEntry struct {
	startPc   uint16
	endPc     uint16
	handlerPc uint16
	catchType uint16
}

func (self *CodeAttribute) readInfo(reader *ClassReader) {
	//self.attribute_name_index = reader.readUint16()
	//self.attribute_length = reader.readUint32()
	self.max_stack = reader.readUint16()
	self.max_locals = reader.readUint16()
	self.code_length = reader.readUint32()
	self.code = reader.readBytes(self.code_length)
	self.exception_table_length = reader.readUint16()
	self.exception_table = readExceptionTable(self.exception_table_length, reader)
	self.attribute_count = reader.readUint16()
	self.attribute_info = readAttributes(self.attribute_count, reader)
}
func readExceptionTable(length uint16, reader *ClassReader) []*ExceptionTableEntry {
	exceptionTable := make([]*ExceptionTableEntry, length)
	for i := range exceptionTable {
		exceptionTable[i] = &ExceptionTableEntry{
			startPc:   reader.readUint16(),
			endPc:     reader.readUint16(),
			handlerPc: reader.readUint16(),
			catchType: reader.readUint16(),
		}
	}
	return exceptionTable
}
2.2.6.2.ConstantValue
type ConstantValueAttribute struct {
	attribute_name_index uint16
	attribute_length     uint32
	constantvalue_index  uint16
}

func (self *ConstantValueAttribute) readInfo(reader *ClassReader) {
	self.constantvalue_index = reader.readUint16()
}
2.2.6.3.Deprecated

type MarkerAttribute struct {
	attribute_name_index uint16
	attribute_length     uint32
}

type DeprecatedAttribute struct {
	MarkerAttribute
}

type SyntheticAttribute struct {
	MarkerAttribute
}

func (self *MarkerAttribute) readInfo(reader *ClassReader) {

}
2.2.6.4.Exceptions

type ExceptionsAttribute struct {
	attribute_name_index  uint16
	attribute_length      uint32
	number_of_exceptions  uint16
	exception_index_table []uint16
}

func (self *ExceptionsAttribute) readInfo(reader *ClassReader) {
	//self.attribute_name_index = reader.readUint16()
	//self.attribute_length = reader.readUint32()
	self.number_of_exceptions = reader.readUint16()
	self.exception_index_table = readExceptionIndexTable(self.number_of_exceptions, reader)
}

func readExceptionIndexTable(count uint16, reader *ClassReader) []uint16 {
	ret := make([]uint16, count)
	for i := range ret {
		ret[i] = reader.readUint16()
	}
	return ret
}
2.2.6.5.LineNumberTable

type LineNumberTableAttribute struct {
	attribute_name_index     uint16
	attribute_length         uint32
	line_number_table_length uint16
	lineNumberTable          []*LineNumberTableEntry
}

type LineNumberTableEntry struct {
	startPc    uint16
	lineNumber uint16
}

func (self *LineNumberTableAttribute) readInfo(reader *ClassReader) {
	//self.attribute_name_index = reader.readUint16()
	self.line_number_table_length = reader.readUint16()
	self.lineNumberTable = make([]*LineNumberTableEntry, self.line_number_table_length)
	for i := range self.lineNumberTable {
		self.lineNumberTable[i] = &LineNumberTableEntry{
			startPc:    reader.readUint16(),
			lineNumber: reader.readUint16(),
		}
	}
}
2.2.6.6.LocalVariableTable

type LocalVariableTableAttribute struct {
	attribute_name_index        uint16
	attribute_length            uint32
	local_variable_table_length uint16
	localVariableTable          []*LocalVariableTableEntry
}

type LocalVariableTableEntry struct {
	startPc          uint16
	length           uint16
	name_index       uint16
	descriptor_index uint16
	index            uint16
}

func (self *LocalVariableTableAttribute) readInfo(reader *ClassReader) {
	//self.attribute_name_index = reader.readUint16()
	//self.attribute_length = reader.readUint32()
	self.local_variable_table_length = reader.readUint16()
	self.localVariableTable = make([]*LocalVariableTableEntry, self.local_variable_table_length)
	for i := range self.localVariableTable {
		self.localVariableTable[i] = &LocalVariableTableEntry{
			startPc:          reader.readUint16(),
			length:           reader.readUint16(),
			name_index:       reader.readUint16(),
			descriptor_index: reader.readUint16(),
			index:            reader.readUint16(),
		}
	}
}
2.2.6.7.SourceFile

type SourceFileAttribute struct {
	attribute_name_index uint16
	attribute_length     uint32
	sourcefile_index     uint16
}

func (self *SourceFileAttribute) readInfo(reader *ClassReader) {
	//self.attribute_name_index = reader.readUint16()
	//self.attribute_length = reader.readUint32()
	self.sourcefile_index = reader.readUint16()
}
2.2.6.8.Synthetic

type MarkerAttribute struct {
	attribute_name_index uint16
	attribute_length     uint32
}

type DeprecatedAttribute struct {
	MarkerAttribute
}

type SyntheticAttribute struct {
	MarkerAttribute
}

func (self *MarkerAttribute) readInfo(reader *ClassReader) {

}
2.2.6.9.Unparsed(未识别成功的)
type UnparsedAttribute struct {
	name   string
	length uint32
	info   []byte
}

func (self *UnparsedAttribute) readInfo(reader *ClassReader) {
	self.info = reader.readBytes(self.length)
}
2.2.7.获取方法数量及方法信息

//同获取字段数量及其信息
//从下我们可以看出字段信息和方法信息结构一致;

field_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}


method_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}
2.2.8.获取属性数量及属性信息

//同上的readAttributes,因为method_info, field_info中已经包含了attribute信息

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/585320.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号