类和字段符号引用解析
类符号引用解析
先修改class.go文件,添加判断是否能访问其他类的函数:
修改cp_symref.go文件,添加类符号解析方法:
字段符号引用解析
先修改class_member.go文件,添加判断是否能访问其他字段的函数:
修改cp_fieldref.go文件,添加解析方法:
类和对象相关指令
下面我们来实现10条类和对象相关指令。new指令用来创建类实例;putstatic和getstatic指令用于存取静态变量;putfield和getfield用于存取实例变量;instanceof和checkcast指令用于判断对象是否属于某种类型;ldc系列指令把运行时常量池中的常量推到操作数栈顶。本节部分实现代码位于/instructions/references包下,ldc系列的指令实现代码位于/instructions/constants包下。下面先建一个用于测试的java文件,在java项目中新建MyObject.java:
这里稍微补充下之前的iconst指令和ldc系列指令的区别:当int取值-1 ~ 5采用iconst指令,取值-128 ~ 127采用bipush指令,取值-32768 ~ 32767采用sipush指令,取值-2147483648 ~ 2147483647采用 ldc 指令。
new指令
new指令专门用来创建类实例,在实现new指令之前有两个地方需要完善:
修改/rtdata/frame.go文件,给Frame结构体添加方法区的方法信息指针属性,并且修改newFrame()函数:
123456789101112131415161718type Frame struct {...// 方法区的方法信息指针method *heap.Method}// 实例化栈帧(此时有两个newFrame函数,并且编译有错,暂时先不管)func newFrame(thread *Thread, method *heap.Method) *Frame {return &Frame{thread: thread,method: method,localVars: newLocalVars(method.MaxLocals()),operandStack: newOperandStack(method.MaxStack()),}}// 省略Getter方法...修改thread.go文件,修改NewFrame()函数:
1234// 为线程创建新的栈帧func (self *Thread) NewFrame(method *heap.Method) *Frame {return newFrame(self, method)}修改class.go文件,添加初始化类的方法:
12345// 创建对象引用func (self *Class) NewObject() *Object {// 调用Object结构体return newObject(self)}
new指令实现代码位于new.go文件中: