指令集和解释器

Java虚拟机指的是一台虚拟的机器,字节码就是运行在这台虚拟机器上的机器码。

每个类或者接口都会被Java编译器编译成一个class文件,类或者接口的方法信息放在class文件的method_info结构中,如果方法不是抽象方法,也不是本地方法,方法的Java代码就会被编译器编译成字节码,存放在method_info结构体的Code属性中。

每条字节码指令是以一个单字节的操作码(opcode)开头,这就是字节码名称的由来。

由于只使用一个字节来显示操作码,所以Java虚拟机最多支持256条指令。

虚拟机栈中的帧包括局部变量表和操作数栈,局部变量表和操作数栈中只保存数据的值,并不揭露操作数的类型,因此需要将变量的类型信息放在操作码的助记符号上。

助计符首字母和变量类型对应表如下所示

Java虚拟机把已经定义的205条指令按用途分类共有如下十一类:

指令和指令解码

Java虚拟机解释器大致逻辑如下所示:

计算PC、指令解码、指令执行。

使用Go语言实现指令,需要抽象出一个接口,解码和执行逻辑写在具体指令实现中。类似于下面的伪代码中的inst

for {
    pc := calculatePC()
    opcode := bytecode[pc]
    inst := createInst(opcode)
    inst.fetchOperands(bytecode)
    inst.execute()
}

go语言定义创建Instruction接口如下所示

type Instruction interface {

    // 从节码中提取操作数
    FetchOperands(reader *BytecodeReader)

    // 执行指令逻辑
    Execute(frame *rtda.Frame)
}

指令的具体实现见代码

解释器具体实现见代码 jvmgo/ch05/interpreter.go实现