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

4.从0开始的手写java虚拟机 - 指令集和解释器

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

4.从0开始的手写java虚拟机 - 指令集和解释器

4.从0开始的手写java虚拟机 - 指令集和解释器

上一节我们描述了jvm是通过一个死循环不断执行指令直至循环结束;
接下来我们将描述每一条指令

4.1.通用指令接口
package base

import "HandWritingJVM/rtda"

//指令通用接口
type Instruction interface {
	FetchOperands(reader *BytecodeReader)
	Execute(frame *rtda.frame)
}

//对应无操作数指令,如return, add, mul...
type NoOperandsInstruction struct {
}


func (self *NoOperandsInstruction) FetchOperands(reader *BytecodeReader) {
	//...

}
//分支跳转指令
type BranchInstruction struct {
	Offset int
}

func (self *BranchInstruction) FetchOperands(reader *BytecodeReader) {
	self.Offset = int(reader.ReadInt16())
}
//操作数长度为8的相关指令
type Index8Instruction struct {
	Index uint
}

func (self *Index8Instruction) FetchOperands(reader *BytecodeReader) {
	self.Index = uint(reader.ReadUint8())
}

//操作数长度为16的相关指令
type Index16Instruction struct {
	Index uint
}

func (self *Index16Instruction) FetchOperands(reader *BytecodeReader) {
	self.Index = uint(reader.ReadUint16())
}
4.2.读取字节码相关操作
package base

type BytecodeReader struct {
	code []byte
	pc   int
}
//重置当前栈帧的pc以及将要执行的方法
func (self *BytecodeReader) Reset(code []byte, pc int) {
	self.code = code
	self.pc = pc
}

func (self *BytecodeReader) PC() int {
	return self.pc
}
//获取当前代码块中pc所指向的字节码指令
func (self *BytecodeReader) ReadUint8() uint8 {
	i := self.code[self.pc]
	self.pc++
	return i
}

func (self *BytecodeReader) ReadInt8() int8 {
	return int8(self.ReadUint8())
}

func (self *BytecodeReader) ReadUint16() uint16 {
	byte1 := uint16(self.ReadUint8())
	byte2 := uint16(self.ReadUint8())
	return (byte1 << 8) | byte2
}

func (self *BytecodeReader) ReadInt16() int16 {
	return int16(self.ReadUint16())
}
func (self *BytecodeReader) ReadInt32() int32 {
	byte1 := int32(self.ReadUint8())
	byte2 := int32(self.ReadUint8())
	byte3 := int32(self.ReadUint8())
	byte4 := int32(self.ReadUint8())
	return (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4
}

func (self *BytecodeReader) ReadInt32s(count int32) []int32 {
	ret := make([]int32, count)
	for i := 0; i < int(count); i++ {
		ret[i] = self.ReadInt32()
	}
	return ret
}

func (self *BytecodeReader) SkipPadding() {
	for self.pc%4 != 0 {
		self.ReadUint8()
	}
}

4.3.常量指令 4.3.1.nop

解释:

package constants

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type NOP struct {
	base.NoOperandsInstruction
}

func (self *NOP) Execute(frame *rtda.frame) {
	//...
}

4.3.2.const

解释:将一个值推入操作数栈中

package constants

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

//将null推入操作数栈顶
type ACONST_NULL struct {
	base.NoOperandsInstruction
}


func (self *ACONST_NULL) Execute(frame *rtda.frame) {
	frame.OperandStack().PushRef(nil)
}

type DCONST_0 struct {
	base.NoOperandsInstruction
}

//将double 0推入操作数栈顶,其他以此类推
func (self *DCONST_0) Execute(frame *rtda.frame) {
	frame.OperandStack().PushDouble(0.0)
}
//将double 1推入操作数栈顶
type DCONST_1 struct {
	base.NoOperandsInstruction
}

func (self *DCONST_1) Execute(frame *rtda.frame) {
	frame.OperandStack().PushDouble(1.0)

}

//将float 0推入栈顶,其他以此类推
type FCONST_0 struct {
	base.NoOperandsInstruction
}

func (self *FCONST_0) Execute(frame *rtda.frame) {
	frame.OperandStack().PushFloat(0.0)
}

type FCONST_1 struct {
	base.NoOperandsInstruction
}

func (self *FCONST_1) Execute(frame *rtda.frame) {
	frame.OperandStack().PushFloat(1.0)
}

type FCONST_2 struct {
	base.NoOperandsInstruction
}

func (self *FCONST_2) Execute(frame *rtda.frame) {
	frame.OperandStack().PushFloat(2)
}
//将int -1 推入栈顶,其他以此类推
type ICONST_M1 struct {
	base.NoOperandsInstruction
}

func (self *ICONST_M1) Execute(frame *rtda.frame) {
	frame.OperandStack().PushInt(-1)
}
//将int 0推入栈顶,其他以此类推
type ICONST_0 struct {
	base.NoOperandsInstruction
}

func (self *ICONST_0) Execute(frame *rtda.frame) {
	frame.OperandStack().PushInt(0)
}

type ICONST_1 struct {
	base.NoOperandsInstruction
}

func (self *ICONST_1) Execute(frame *rtda.frame) {
	frame.OperandStack().PushInt(1)
}

type ICONST_2 struct {
	base.NoOperandsInstruction
}

func (self *ICONST_2) Execute(frame *rtda.frame) {
	frame.OperandStack().PushInt(2)
}

type ICONST_3 struct {
	base.NoOperandsInstruction
}

func (self *ICONST_3) Execute(frame *rtda.frame) {
	frame.OperandStack().PushInt(3)
}

type ICONST_4 struct {
	base.NoOperandsInstruction
}

func (self *ICONST_4) Execute(frame *rtda.frame) {
	frame.OperandStack().PushInt(4)
}

type ICONST_5 struct {
	base.NoOperandsInstruction
}

func (self *ICONST_5) Execute(frame *rtda.frame) {
	frame.OperandStack().PushInt(5)
}
//将long 0推入栈顶,其他以此类推
type LCONST_0 struct {
	base.NoOperandsInstruction
}

func (self *LCONST_0) Execute(frame *rtda.frame) {
	frame.OperandStack().PushLong(0)
}

type LCONST_1 struct {
	base.NoOperandsInstruction
}

func (self *LCONST_1) Execute(frame *rtda.frame) {
	frame.OperandStack().PushLong(1)
}
4.3.3.ipush

解释:读取一个值并推入操作数栈中

package constants

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)
type BIPUSH struct {
	val int8
}

//从操作数中获取一个byte类型数据,扩展成int,然后推入栈顶
func (self *BIPUSH) FetchOperands(reader *base.BytecodeReader) {
	self.val = reader.ReadInt8()
}

func (self *BIPUSH) Execute(frame *rtda.frame) {
	i := int32(self.val)
	frame.OperandStack().PushInt(i)
}

type SIPUSH struct {
	val int16
}

//从操作数中获取一个short类型数据,扩展成int,然后推入栈顶
func (self *SIPUSH) FetchOperands(reader *base.BytecodeReader) {
	self.val = reader.ReadInt16()
}

func (self *SIPUSH) Execute(frame *rtda.frame) {
	frame.OperandStack().PushInt(int32(self.val))
}
4.3.4.ldc

解释:从运行时常量池中取出元素并推入操作数栈顶

package constants

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
	"HandWritingJVM/rtda/heap"
)

//从常量池中取出元素然后推入操作数栈中,下标长度为8
//且推入的元素类型为int, float, string, classRef
type LDC struct {
	base.Index8Instruction
}

//从常量池中取出元素然后推入操作数栈中,下标长度为16
//且推入的元素类型为int, float, string, classRef
type LDC_W struct {
	base.Index16Instruction
}

//从常量池中取出元素然后推入操作数栈中,下标长度为16
//且推入的元素类型为long,double
type LDC2_W struct {
	base.Index16Instruction
}

func (self *LDC) Execute(frame *rtda.frame) {
	_ldc(frame, self.Index)
}

func (self *LDC_W) Execute(frame *rtda.frame) {
	_ldc(frame, self.Index)
}

func _ldc(frame *rtda.frame, index uint) {
	stack := frame.OperandStack()
	clazz := frame.Method().Class()
	cp := clazz.ConstantPool()
	c := cp.GetConstant(index)
	switch c.(type) {
	case int32:
		stack.PushInt(c.(int32))
	case float32:
		stack.PushFloat(c.(float32))
	case string:
		internedStr := heap.JString(clazz.Loader(), c.(string))
		stack.PushRef(internedStr)
	case *heap.ClassRef:
		classRef := c.(*heap.ClassRef)
		classObj := classRef.ResolvedClass().JClass()
		stack.PushRef(classObj)
	default:
		panic("todo: ldc!")
	}
}

func (self *LDC2_W) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	cp := frame.Method().Class().ConstantPool()
	c := cp.GetConstant(self.Index)
	switch c.(type) {
	case int64:
		stack.PushLong(c.(int64))
	case float64:
		stack.PushDouble(c.(float64))
	default:
		panic("java.lang.ClassFormatError")
	}
}
4.4.加载指令

解释:从局部变量表中取出指定下标的元素然后推入操作数栈中

4.4.1.aload

解释:从局部变量表中取出指定下标的元素然后推入操作数栈中(该元素类型需为引用类型)

package loads

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)
//取出局部变量表第index个元素,然后推入操作数栈中
type ALOAD struct {
	base.Index8Instruction
}

func (self *ALOAD) Execute(frame *rtda.frame) {
	_aload(frame, uint(self.Index))
}

//取出局部变量表第0个元素,然后推入操作数栈中
type ALOAD_0 struct {
	base.NoOperandsInstruction
}

func (self *ALOAD_0) Execute(frame *rtda.frame) {
	_aload(frame, 0)
}

//取出局部变量表中第一个元素然后推入操作数栈中
type ALOAD_1 struct {
	base.NoOperandsInstruction
}

func (self *ALOAD_1) Execute(frame *rtda.frame) {
	_aload(frame, 1)
}

//取出局部变量表第2个元素然后推入操作数栈中
type ALOAD_2 struct {
	base.NoOperandsInstruction
}

func (self *ALOAD_2) Execute(frame *rtda.frame) {
	_aload(frame, 2)
}

//取出局部变量表第3个元素然后推入操作数栈中
type ALOAD_3 struct {
	base.NoOperandsInstruction
}

func (self *ALOAD_3) Execute(frame *rtda.frame) {
	_aload(frame, 3)
}

func _aload(frame *rtda.frame, index uint) {
	ref := frame.LocalVars().GetRef(index)
	frame.OperandStack().PushRef(ref)
}
4.4.2.dload

解释:从局部变量表中取出指定下标的元素然后推入操作数栈中(该元素类型需为double类型)

package loads

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type DLOAD struct {
	base.Index8Instruction
}

func (self *DLOAD) Execute(frame *rtda.frame) {
	_dload(frame, uint(self.Index))
}

type DLOAD_0 struct {
	base.NoOperandsInstruction
}

func (self *DLOAD_0) Execute(frame *rtda.frame) {
	_dload(frame, 0)
}

type DLOAD_1 struct {
	base.NoOperandsInstruction
}

func (self *DLOAD_1) Execute(frame *rtda.frame) {
	_dload(frame, 1)
}

type DLOAD_2 struct {
	base.NoOperandsInstruction
}

func (self *DLOAD_2) Execute(frame *rtda.frame) {
	_dload(frame, 2)
}

type DLOAD_3 struct {
	base.NoOperandsInstruction
}

func (self *DLOAD_3) Execute(frame *rtda.frame) {
	_dload(frame, 3)
}

func _dload(frame *rtda.frame, index uint) {
	val := frame.LocalVars().GetDouble(index)
	frame.OperandStack().PushDouble(val)
}
4.4.3.fload

解释:从局部变量表中取出指定下标的元素然后推入操作数栈中(该元素类型需为float类型)

package loads

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type FLOAD struct {
	base.Index8Instruction
}

func (self *FLOAD) Execute(frame *rtda.frame) {
	_fload(frame, uint(self.Index))
}

type FLOAD_0 struct {
	base.NoOperandsInstruction
}

func (self *FLOAD_0) Execute(frame *rtda.frame) {
	_fload(frame, 0)
}

type FLOAD_1 struct {
	base.NoOperandsInstruction
}

func (self *FLOAD_1) Execute(frame *rtda.frame) {
	_fload(frame, 1)
}

type FLOAD_2 struct {
	base.NoOperandsInstruction
}

func (self *FLOAD_2) Execute(frame *rtda.frame) {
	_fload(frame, 2)
}

type FLOAD_3 struct {
	base.NoOperandsInstruction
}

func (self *FLOAD_3) Execute(frame *rtda.frame) {
	_fload(frame, 3)
}

func _fload(frame *rtda.frame, index uint) {
	val := frame.LocalVars().GetFloat(index)
	frame.OperandStack().PushFloat(val)
}

4.4.4.iload

解释:从局部变量表中取出指定下标的元素然后推入操作数栈中(该元素类型需为int类型)

package loads

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)
//获取局部变量表中元素并放入操作数栈中
func _iload(frame *rtda.frame, index uint) {
	val := frame.LocalVars().GetInt(index)
	frame.OperandStack().PushInt(val)
}

type ILOAD struct {
	base.Index8Instruction
}

func (self *ILOAD) Execute(frame *rtda.frame) {
	_iload(frame, self.Index)
}

type ILOAD_0 struct {
	base.NoOperandsInstruction
}

func (self *ILOAD_0) Execute(frame *rtda.frame) {
	_iload(frame, 0)
}

type ILOAD_1 struct {
	base.NoOperandsInstruction
}

func (self *ILOAD_1) Execute(frame *rtda.frame) {
	_iload(frame, 1)
}

type ILOAD_2 struct {
	base.NoOperandsInstruction
}

func (self *ILOAD_2) Execute(frame *rtda.frame) {
	_iload(frame, 2)
}

type ILOAD_3 struct {
	base.NoOperandsInstruction
}

func (self *ILOAD_3) Execute(frame *rtda.frame) {
	_iload(frame, 3)
}

4.4.5.lload

解释:从局部变量表中取出指定下标的元素然后推入操作数栈中(该元素类型需为long类型)

package loads

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type LLOAD struct {
	base.Index8Instruction
}

func (self *LLOAD) Execute(frame *rtda.frame) {
	_lload(frame, uint(self.Index))
}

type LLOAD_0 struct {
	base.NoOperandsInstruction
}

func (self *LLOAD_0) Execute(frame *rtda.frame) {
	_lload(frame, 0)
}

type LLOAD_1 struct {
	base.NoOperandsInstruction
}

func (self *LLOAD_1) Execute(frame *rtda.frame) {
	_lload(frame, 1)
}

type LLOAD_2 struct {
	base.NoOperandsInstruction
}

func (self *LLOAD_2) Execute(frame *rtda.frame) {
	_lload(frame, 2)
}

type LLOAD_3 struct {
	base.NoOperandsInstruction
}

func (self *LLOAD_3) Execute(frame *rtda.frame) {
	_lload(frame, 3)
}

func _lload(frame *rtda.frame, index uint) {
	val := frame.LocalVars().GetLong(index)
	frame.OperandStack().PushLong(val)
}
4.4.6.xaload

解释:从局部变量表中取出指定下标的数组中的元素然后推入操作数栈中(该元素类型需为数组类型)

package loads

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/instructions/constants"
	"HandWritingJVM/rtda"
	"HandWritingJVM/rtda/heap"
)

//load ref from array
type AALOAD struct {
	base.NoOperandsInstruction
}
//按索引取出数组元素值
func (self *AALOAD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	refs := arrRef.Refs()
	checkIndex(len(refs), index)
	stack.PushRef(refs[index])
}

type BALOAD struct {
	base.NoOperandsInstruction
}

func (self *BALOAD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	bytes := arrRef.Bytes()
	checkIndex(len(bytes), index)
	stack.PushInt(int32(bytes[index]))
}

type CALOAD struct {
	base.NoOperandsInstruction
}

func (self *CALOAD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	chars := arrRef.Chars()
	checkIndex(len(chars), index)
	stack.PushInt(int32(chars[index]))
}

type DALOAD struct {
	base.NoOperandsInstruction
}

func (self *DALOAD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	doubles := arrRef.Doubles()
	checkIndex(len(doubles), index)
	stack.PushDouble(doubles[index])
}

type FALOAD struct {
	base.NoOperandsInstruction
}

func (self *FALOAD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	floats := arrRef.Floats()
	checkIndex(len(floats), index)
	stack.PushFloat(floats[index])
}

type IALOAD struct {
	base.NoOperandsInstruction
}

func (self *IALOAD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	ints := arrRef.Ints()
	checkIndex(len(ints), index)
	stack.PushInt(ints[index])
}

type LALOAD struct {
	base.NoOperandsInstruction
}

func (self *LALOAD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	longs := arrRef.Longs()
	checkIndex(len(longs), index)
	stack.PushLong(longs[index])
}

type SALOAD struct {
	base.NoOperandsInstruction
}

func (self *SALOAD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	shorts := arrRef.Shorts()
	checkIndex(len(shorts), index)
	stack.PushInt(int32(shorts[index]))
}

func checkNotNil(ref *heap.Object) {
	if ref == nil {
		panic(constants.NullPointerException)
	}
}

func checkIndex(arrLen int, index int32) {
	if index < 0 || index > int32(arrLen) {
		panic(constants.ArrayIndexOutOfBoundsException)
	}
}

4.5.存储指令

解释:将栈顶元素存储到指定的局部变量表的指定位置;

4.5.1.astore

//将栈顶元素存储到局部变量表指定位置
//该元素类型需为ref

package stores

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type ASTORE struct {
	base.Index8Instruction
}

func (self *ASTORE) Execute(frame *rtda.frame) {
	_astore(frame, uint(self.Index))
}

type ASTORE_0 struct {
	base.NoOperandsInstruction
}

func (self *ASTORE_0) Execute(frame *rtda.frame) {
	_astore(frame, 0)
}

type ASTORE_1 struct {
	base.NoOperandsInstruction
}

func (self *ASTORE_1) Execute(frame *rtda.frame) {
	_astore(frame, 1)
}

type ASTORE_2 struct {
	base.NoOperandsInstruction
}

func (self *ASTORE_2) Execute(frame *rtda.frame) {
	_astore(frame, 2)
}

type ASTORE_3 struct {
	base.NoOperandsInstruction
}

func (self *ASTORE_3) Execute(frame *rtda.frame) {
	_astore(frame, 3)
}

func _astore(frame *rtda.frame, index uint) {
	ref := frame.OperandStack().PopRef()
	frame.LocalVars().SetRef(index, ref)
}
4.5.2.dstore

//将栈顶元素存储到局部变量表指定位置
//该元素类型需为double

package stores

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type DSTORE struct {
	base.Index8Instruction
}

func (self *DSTORE) Execute(frame *rtda.frame) {
	_dstore(frame, uint(self.Index))
}

type DSTORE_0 struct {
	base.NoOperandsInstruction
}

func (self *DSTORE_0) Execute(frame *rtda.frame) {
	_dstore(frame, 0)
}

type DSTORE_1 struct {
	base.NoOperandsInstruction
}

func (self *DSTORE_1) Execute(frame *rtda.frame) {
	_dstore(frame, 1)
}

type DSTORE_2 struct {
	base.NoOperandsInstruction
}

func (self *DSTORE_2) Execute(frame *rtda.frame) {
	_dstore(frame, 2)
}

type DSTORE_3 struct {
	base.NoOperandsInstruction
}

func (self *DSTORE_3) Execute(frame *rtda.frame) {
	_dstore(frame, 3)
}

func _dstore(frame *rtda.frame, index uint) {
	val := frame.OperandStack().PopDouble()
	frame.LocalVars().SetDouble(index, val)
}
4.5.3.fstore

//将栈顶元素存储到局部变量表指定位置
//该元素类型需为float

package stores

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type FSTORE struct {
	base.Index8Instruction
}

func (self *FSTORE) Execute(frame *rtda.frame) {
	_fstore(frame, uint(self.Index))
}

type FSTORE_0 struct {
	base.Index8Instruction
}

func (self *FSTORE_0) Execute(frame *rtda.frame) {
	_fstore(frame, 0)
}

type FSTORE_1 struct {
	base.Index8Instruction
}

func (self *FSTORE_1) Execute(frame *rtda.frame) {
	_fstore(frame, 1)
}

type FSTORE_2 struct {
	base.Index8Instruction
}

func (self *FSTORE_2) Execute(frame *rtda.frame) {
	_fstore(frame, 2)
}

type FSTORE_3 struct {
	base.Index8Instruction
}

func (self *FSTORE_3) Execute(frame *rtda.frame) {
	_fstore(frame, 3)
}

func _fstore(frame *rtda.frame, index uint) {
	val := frame.OperandStack().PopFloat()
	frame.LocalVars().SetFloat(index, val)
}

4.5.4.istore

//将栈顶元素存储到局部变量表指定位置
//该元素类型需为 int

package stores

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type ISTORE struct {
	base.Index8Instruction
}

func (self *ISTORE) Execute(frame *rtda.frame) {
	_istore(frame, uint(self.Index))
}

type ISTORE_0 struct {
	base.NoOperandsInstruction
}

func (self *ISTORE_0) Execute(frame *rtda.frame) {
	_istore(frame, 0)
}

type ISTORE_1 struct {
	base.NoOperandsInstruction
}

func (self *ISTORE_1) Execute(frame *rtda.frame) {
	_istore(frame, 1)
}

type ISTORE_2 struct {
	base.NoOperandsInstruction
}

func (self *ISTORE_2) Execute(frame *rtda.frame) {
	_istore(frame, 2)
}

type ISTORE_3 struct {
	base.NoOperandsInstruction
}

func (self *ISTORE_3) Execute(frame *rtda.frame) {
	_istore(frame, 3)
}

func _istore(frame *rtda.frame, index uint) {
	val := frame.OperandStack().PopInt()
	frame.LocalVars().SetInt(index, val)
}
4.5.5.lstore

//将栈顶元素存储到局部变量表指定位置
//该元素类型需为 long

package stores

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

//将变量从操作数栈栈顶弹出并存入局部变量表
func _lstore(frame *rtda.frame, index uint) {
	val := frame.OperandStack().PopLong()
	frame.LocalVars().SetLong(index, val)
}

type LSTORE struct {
	base.Index8Instruction
}

func (self *LSTORE) Execute(frame *rtda.frame) {
	_lstore(frame, uint(self.Index))
}

type LSTORE_0 struct {
	base.NoOperandsInstruction
}

func (self *LSTORE_0) Execute(frame *rtda.frame) {
	_lstore(frame, 0)
}

type LSTORE_1 struct {
	base.NoOperandsInstruction
}

func (self *LSTORE_1) Execute(frame *rtda.frame) {
	_lstore(frame, 1)
}

type LSTORE_2 struct {
	base.NoOperandsInstruction
}

func (self *LSTORE_2) Execute(frame *rtda.frame) {
	_lstore(frame, 2)

}

type LSTORE_3 struct {
	base.NoOperandsInstruction
}

func (self *LSTORE_3) Execute(frame *rtda.frame) {
	_lstore(frame, 2)
}

4.5.6.xastore

//将元素存储到数组指定下标位置

package stores

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/instructions/constants"
	"HandWritingJVM/rtda"
	"HandWritingJVM/rtda/heap"
)

//数组
type AASTORE struct {
	base.Index8Instruction
}

func (self *AASTORE) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	ref := stack.PopRef()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	refs := arrRef.Refs()
	checkIndex(len(refs), index)
	refs[index] = ref
}

type BASTORE struct {
	base.NoOperandsInstruction
}

func (self *BASTORE) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	val := stack.PopInt()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	bytes := arrRef.Bytes()
	checkIndex(len(bytes), index)
	bytes[index] = int8(val)
}

type CASTORE struct {
	base.NoOperandsInstruction
}

func (self *CASTORE) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	val := stack.PopInt()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	chars := arrRef.Chars()
	checkIndex(len(chars), index)
	chars[index] = uint16(val)
}

type DASTORE struct {
	base.NoOperandsInstruction
}

func (self *DASTORE) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	val := stack.PopDouble()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	doubles := arrRef.Doubles()
	checkIndex(len(doubles), index)
	doubles[index] = float64(val)
}

type FASTORE struct {
	base.NoOperandsInstruction
}

func (self *FASTORE) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	val := stack.PopFloat()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	floats := arrRef.Floats()
	checkIndex(len(floats), index)
	floats[index] = val
}

type IASTORE struct {
	base.NoOperandsInstruction
}

func (self *IASTORE) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	val := stack.PopInt()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	ints := arrRef.Ints()
	checkIndex(len(ints), index)
	ints[index] = int32(val)
}

type LASTORE struct {
	base.NoOperandsInstruction
}

func (self *LASTORE) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	val := stack.PopLong()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	longs := arrRef.Longs()
	checkIndex(len(longs), index)
	longs[index] = int64(val)
}

type SASTORE struct {
	base.NoOperandsInstruction
}

func (self *SASTORE) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	val := stack.PopInt()
	index := stack.PopInt()
	arrRef := stack.PopRef()
	checkNotNil(arrRef)
	shorts := arrRef.Shorts()
	checkIndex(len(shorts), index)
	shorts[index] = int16(val)
}

func checkNotNil(ref *heap.Object) {
	if ref == nil {
		panic(constants.NullPointerException)
	}
}

func checkIndex(arrLen int, index int32) {
	if index < 0 || index >= int32(arrLen) {
		panic(constants.ArrayIndexOutOfBoundsException)
	}
}

4.6.栈指令 4.6.1.dup

解释:栈中元素的复制

package stack

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

// ... 1 -> ... 1 1
type DUP struct {
	base.NoOperandsInstruction
}

//复制栈顶的变量
func (self *DUP) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	slot := stack.PopSlot()
	stack.PushSlot(slot)
	stack.PushSlot(slot)
}

//复制栈顶的下一个元素
// ... 2 1  -> ... 1 2 1  
type DUP_X1 struct {
	base.NoOperandsInstruction
}

func (self *DUP_X1) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	slot1 := stack.PopSlot()
	slot2 := stack.PopSlot()
	stack.PushSlot(slot1)
	stack.PushSlot(slot2)
	stack.PushSlot(slot1)
}

// ... 3 2 1 -> ... 1 3 2 1 
type DUP_X2 struct {
	base.NoOperandsInstruction
}

func (self *DUP_X2) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	slot1 := stack.PopSlot()
	slot2 := stack.PopSlot()
	slot3 := stack.PopSlot()
	stack.PushSlot(slot1)
	stack.PushSlot(slot3)
	stack.PushSlot(slot2)
	stack.PushSlot(slot1)
}

// ... 2 1 -> ... 2 1 2 1 
type DUP2 struct {
	base.NoOperandsInstruction
}


func (self *DUP2) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	slot1 := stack.PopSlot()
	slot2 := stack.PopSlot()
	stack.PushSlot(slot2)
	stack.PushSlot(slot1)
	stack.PushSlot(slot2)
	stack.PushSlot(slot1)
}

//... 3 2 1 -> ... 2 1 3 2 1 
type DUP2_X1 struct {
	base.NoOperandsInstruction
}

func (self *DUP2_X1) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	slot1 := stack.PopSlot()
	slot2 := stack.PopSlot()
	slot3 := stack.PopSlot()
	stack.PushSlot(slot2)
	stack.PushSlot(slot1)
	stack.PushSlot(slot3)
	stack.PushSlot(slot2)
	stack.PushSlot(slot1)
}

// ... 4 3 2 1 -> ... 2 1 4 3 2 1 
type DUP2_X2 struct {
	base.NoOperandsInstruction
}

func (self *DUP2_X2) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	slot1 := stack.PopSlot()
	slot2 := stack.PopSlot()
	slot3 := stack.PopSlot()
	slot4 := stack.PopSlot()
	stack.PushSlot(slot2)
	stack.PushSlot(slot1)
	stack.PushSlot(slot4)
	stack.PushSlot(slot3)
	stack.PushSlot(slot2)
	stack.PushSlot(slot1)
}


4.6.2.pop

解释:弹出栈顶元素

package stack

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

//弹出一个元素
type POP struct {
	base.NoOperandsInstruction
}

func (self *POP) Execute(frame *rtda.frame) {
	frame.OperandStack().PopSlot()
}

//弹出2个元素
type POP2 struct {
	base.NoOperandsInstruction
}

func (self *POP2) Execute(frame *rtda.frame) {
	frame.OperandStack().PopSlot()
	frame.OperandStack().PopSlot()
}

4.6.3.SWAP

解释:交换栈顶前2个元素

package stack

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

// ... 2 1 -> ... 1 2 
type SWAP struct {
	base.NoOperandsInstruction
}

func (self *SWAP) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	slot1 := stack.PopSlot()
	slot2 := stack.PopSlot()
	stack.PushSlot(slot2)
	stack.PushSlot(slot1)
}
4.7.数学指令 4.7.1.add

解释:从栈中弹出2个元素相加后重新推入栈中

package math

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type DADD struct {
	base.NoOperandsInstruction
}

func (self *DADD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v1 := stack.PopDouble()
	v2 := stack.PopDouble()
	res := v1 + v2
	stack.PushDouble(res)
}

type FADD struct {
	base.NoOperandsInstruction
}

func (self *FADD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v1 := stack.PopFloat()
	v2 := stack.PopFloat()
	res := v1 + v2
	stack.PushFloat(res)
}

type IADD struct {
	base.NoOperandsInstruction
}

func (self *IADD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v1 := stack.PopInt()
	v2 := stack.PopInt()
	res := v1 + v2
	stack.PushInt(res)
}

type LADD struct {
	base.NoOperandsInstruction
}

func (self *LADD) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v1 := stack.PopLong()
	v2 := stack.PopLong()
	res := v1 + v2
	stack.PushLong(res)
}
4.7.2.and

解释:从栈顶弹出2个元素相&后推入栈中

package math

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type IAND struct {
	base.NoOperandsInstruction
}

func (self *IAND) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopInt()
	result := v1 & v2
	stack.PushInt(result)
}

type LAND struct {
	base.NoOperandsInstruction
}

func (self *LAND) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	l2 := stack.PopLong()
	l1 := stack.PopLong()
	result := l1 & l2
	stack.PushLong(result)
}
4.7.3.div

解释:从栈中弹出2个元素相除后将结果推入栈中

package math

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type DDIV struct {
	base.NoOperandsInstruction
}

func (self *DDIV) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopDouble()
	v1 := stack.PopDouble()
	res := v1 / v2
	stack.PushDouble(res)
}

type FDIV struct {
	base.NoOperandsInstruction
}

func (self *FDIV) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopFloat()
	v1 := stack.PopFloat()
	res := v1 / v2
	stack.PushFloat(res)
}

type IDIV struct {
	base.NoOperandsInstruction
}

func (self *IDIV) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopInt()
	res := v1 / v2
	stack.PushInt(res)
}

type LDIV struct {
	base.NoOperandsInstruction
}

func (self *LDIV) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopLong()
	v1 := stack.PopLong()
	res := v1 / v2
	stack.PushLong(res)
}

4.7.4.iinc

解释:将局部变量表中指定下标的元素加上某一值

package math

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type IINC struct {
	base.Index8Instruction
	Const int32
}

func (self *IINC) FetchOperands(reader *base.BytecodeReader) {
	self.Index = uint(reader.ReadUint8())
	self.Const = int32(reader.ReadInt8())
}

func (self *IINC) Execute(frame *rtda.frame) {
	localVars := frame.LocalVars()
	val := localVars.GetInt(self.Index)
	val += self.Const
	localVars.SetInt(self.Index, val)
}

4.7.5.mul

解释:从栈中弹出2个元素后相乘后再推入栈中;

package math

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type DMUL struct {
	base.NoOperandsInstruction
}

func (self *DMUL) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v1 := stack.PopDouble()
	v2 := stack.PopDouble()
	res := v1 * v2
	stack.PushDouble(res)
}

type FMUL struct {
	base.NoOperandsInstruction
}

func (self *FMUL) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v1 := stack.PopFloat()
	v2 := stack.PopFloat()
	res := v1 * v2
	stack.PushFloat(res)
}

type IMUL struct {
	base.NoOperandsInstruction
}

func (self *IMUL) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v1 := stack.PopInt()
	v2 := stack.PopInt()
	res := v1 * v2
	stack.PushInt(res)
}

type LMUL struct {
	base.NoOperandsInstruction
}

func (self *LMUL) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v1 := stack.PopLong()
	v2 := stack.PopLong()
	res := v1 * v2
	stack.PushLong(res)
}

4.7.6.neg

解释:弹出栈顶元素取反后重新推入栈中

package math

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type DNEG struct {
	base.NoOperandsInstruction
}

func (self *DNEG) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	val := stack.PopDouble()
	stack.PushDouble(-val)
}

type FNEG struct {
	base.NoOperandsInstruction
}

func (self *FNEG) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	stack.PushFloat(-stack.PopFloat())
}

type INEG struct {
	base.NoOperandsInstruction
}

func (self *INEG) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	stack.PushInt(-stack.PopInt())
}

type LNEG struct {
	base.NoOperandsInstruction
}

func (self *LNEG) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	stack.PushLong(-stack.PopLong())
}
4.6.7.or

解释:弹出栈中的2个元素相或后重新推入栈中

package math

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type IOR struct {
	base.NoOperandsInstruction
}

func (self *IOR) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopInt()
	res := v1 | v2
	stack.PushInt(res)
}

type LOR struct {
	base.NoOperandsInstruction
}

func (self *LOR) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopLong()
	v1 := stack.PopLong()
	res := v1 | v2
	stack.PushLong(res)
}

4.6.8.rem

解释:弹出栈顶2个元素,取余后将结果重新推入栈中

package math

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
	"math"
)

type DREM struct {
	base.NoOperandsInstruction
}

func (self *DREM) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopDouble()
	v1 := stack.PopDouble()
	result := math.Mod(v1, v2)
	stack.PushDouble(result)
}

type IREM struct {
	base.NoOperandsInstruction
}

func (self *IREM) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopInt()
	if v2 == 0 {
		panic("java.lang.ArithmeticException: / by zero")
	}
	result := v1 % v2
	stack.PushInt(result)
}

type FREM struct {
	base.NoOperandsInstruction
}

func (self *FREM) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopFloat()
	v1 := stack.PopFloat()
	if v2 == 0 {
		panic("java.lang.ArithmeticException: / by zero")
	}
	result := float32(math.Mod(float64(v1), float64(v2)))
	stack.PushFloat(result)
}

type LREM struct {
	base.NoOperandsInstruction
}

func (self *LREM) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopLong()
	v1 := stack.PopLong()
	if v2 == 0 {
		panic("java.lang.ArithmeticException: / by zero")
	}
	result := v1 % v2
	stack.PushLong(result)
}

4.6.9.sh

解释:弹出栈顶2个元素,一个是值,一个是位移距离;

package math

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

//int左移位
type ISHL struct {
	base.NoOperandsInstruction
}

func (self *ISHL) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopInt()
	s := uint32(v2) & 0x1f
	result := v1 << s
	stack.PushInt(result)
}

//int 右移位
type ISHR struct {
	base.NoOperandsInstruction
}

func (self *ISHR) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopInt()
	s := uint32(v2) & 0x1f
	result := v1 >> s
	stack.PushInt(result)
}

//int 无符号右移位
type IUSHR struct {
	base.NoOperandsInstruction
}

func (self *IUSHR) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopInt()
	s := uint32(v2) & 0x1f
	result := int32(uint32(v1) >> s)
	stack.PushInt(result)
}

//long 左移位
type LSHL struct {
	base.NoOperandsInstruction
}

func (self *LSHL) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopLong()
	s := uint32(v2) & 0x3f
	result := v1 << s
	stack.PushLong(result)
}

//long右移位
type LSHR struct {
	base.NoOperandsInstruction
}

func (self *LSHR) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopLong()
	s := uint32(v2) & 0x3f
	result := v1 >> s
	stack.PushLong(result)
}

//long 无符号右移位
type LUSHR struct {
	base.NoOperandsInstruction
}

func (self *LUSHR) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopLong()
	s := uint32(v2) & 0x3f
	result := int64(uint64(v1) >> s)
	stack.PushLong(result)
}
4.6.10.sub

解释:弹出栈顶2个元素,相减后将结果推入栈中

package math

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type DSUB struct {
	base.NoOperandsInstruction
}

func (self *DSUB) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopDouble()
	v1 := stack.PopDouble()
	res := v1 - v2
	stack.PushDouble(res)
}

type FSUB struct {
	base.NoOperandsInstruction
}

func (self *FSUB) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopFloat()
	v1 := stack.PopFloat()
	res := v1 - v2
	stack.PushFloat(res)
}

type ISUB struct {
	base.NoOperandsInstruction
}

func (self *ISUB) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopInt()
	v1 := stack.PopInt()
	res := v1 - v2
	stack.PushInt(res)
}

type LSUB struct {
	base.NoOperandsInstruction
}

func (self *LSUB) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v2 := stack.PopLong()
	v1 := stack.PopLong()
	res := v1 - v2
	stack.PushLong(res)
}

4.6.11.xor

解释:弹出栈顶2个元素,相异或后将结果推入栈中

package math

import (
	"HandWritingJVM/instructions/base"
	"HandWritingJVM/rtda"
)

type IXOR struct {
	base.NoOperandsInstruction
}

func (self *IXOR) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v1 := stack.PopInt()
	v2 := stack.PopInt()
	res := v1 ^ v2
	stack.PushInt(res)
}

type LXOR struct {
	base.NoOperandsInstruction
}

func (self *LXOR) Execute(frame *rtda.frame) {
	stack := frame.OperandStack()
	v1 := stack.PopLong()
	v2 := stack.PopLong()
	res := v1 ^ v2
	stack.PushLong(res)
}

4.7.类型转换指令

//待续

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

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

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