zoukankan      html  css  js  c++  java
  • 四、运行时数据区

     一、运行时数据区

    https://blog.csdn.net/u011464536/article/details/78235438

    二、实现

    在jvmgo文件夹下面创建rtda文件夹,并在里面创建object.go文件

    1 package rtda
    2 
    3 type Object struct {
    4     // todo
    5 }

    1、线程

    创建thread.go文件

     1 package rtda
     2 
     3 /*
     4 JVM
     5   Thread
     6     pc
     7     Stack
     8       Frame
     9         LocalVars
    10         OperandStack
    11 */
    12 type Thread struct {
    13     pc    int // the address of the instruction currently being executed
    14     stack *Stack
    15     // todo
    16 }
    17 
    18 func NewThread() *Thread {
    19     return &Thread{
    20         stack: newStack(1024),
    21     }
    22 }
    23 
    24 func (self *Thread) PC() int {
    25     return self.pc
    26 }
    27 func (self *Thread) SetPC(pc int) {
    28     self.pc = pc
    29 }
    30 
    31 func (self *Thread) PushFrame(frame *Frame) {
    32     self.stack.push(frame)
    33 }
    34 func (self *Thread) PopFrame() *Frame {
    35     return self.stack.pop()
    36 }
    37 
    38 func (self *Thread) CurrentFrame() *Frame {
    39     return self.stack.top()
    40 }

    定义了pc和stack字段,stack是Stack结构体的指针。NewThread()创建Thread实例,newStack()创建Stack结构体实例,参数表示要创建的Stack最多容纳多少帧,PushFrame()和PopFrame()方法调用Stack结构体的相应方法。CurrentFrame()方法返回当前帧。

    2、java虚拟机栈

    创建jvm_stack.go文件

     1 package rtda
     2 
     3 // jvm stack
     4 type Stack struct {
     5     maxSize uint
     6     size    uint
     7     _top    *Frame // stack is implemented as linked list
     8 }
     9 
    10 func newStack(maxSize uint) *Stack {
    11     return &Stack{
    12         maxSize: maxSize,
    13     }
    14 }
    15 
    16 func (self *Stack) push(frame *Frame) {
    17     if self.size >= self.maxSize {
    18         panic("java.lang.StackOverflowError")
    19     }
    20 
    21     if self._top != nil {
    22         frame.lower = self._top
    23     }
    24 
    25     self._top = frame
    26     self.size++
    27 }
    28 
    29 func (self *Stack) pop() *Frame {
    30     if self._top == nil {
    31         panic("jvm stack is empty!")
    32     }
    33 
    34     top := self._top
    35     self._top = top.lower
    36     top.lower = nil
    37     self.size--
    38 
    39     return top
    40 }
    41 
    42 func (self *Stack) top() *Frame {
    43     if self._top == nil {
    44         panic("jvm stack is empty!")
    45     }
    46 
    47     return self._top
    48 }

    maxSize保存栈的容量,size是当前大小,_top字段保存栈顶指针。其他函数不做解释。

    3、帧

    建立frame.go文件

     1 package rtda
     2 
     3 // stack frame
     4 type Frame struct {
     5     lower        *Frame // stack is implemented as linked list
     6     localVars    LocalVars
     7     operandStack *OperandStack
     8     // todo
     9 }
    10 
    11 func NewFrame(maxLocals, maxStack uint) *Frame {
    12     return &Frame{
    13         localVars:    newLocalVars(maxLocals),
    14         operandStack: newOperandStack(maxStack),
    15     }
    16 }
    17 
    18 // getters
    19 func (self *Frame) LocalVars() LocalVars {
    20     return self.localVars
    21 }
    22 func (self *Frame) OperandStack() *OperandStack {
    23     return self.operandStack
    24 }

    lower用来实现链表数据结构,localVars字段保存局部变量表指针,operandStack字段保存操作数栈指针。

    4、局部变量表

    创建slot.go文件。

    1 package rtda
    2 
    3 type Slot struct {
    4     num int32
    5     ref *Object
    6 }

    num字段存放整数,ref存放引用。

    创建local_vars.go文件

     1 package rtda
     2 
     3 import "math"
     4 
     5 type LocalVars []Slot
     6 
     7 func newLocalVars(maxLocals uint) LocalVars {
     8     if maxLocals > 0 {
     9         return make([]Slot, maxLocals)
    10     }
    11     return nil
    12 }
    13 
    14 func (self LocalVars) SetInt(index uint, val int32) {
    15     self[index].num = val
    16 }
    17 func (self LocalVars) GetInt(index uint) int32 {
    18     return self[index].num
    19 }
    20 
    21 func (self LocalVars) SetFloat(index uint, val float32) {
    22     bits := math.Float32bits(val)
    23     self[index].num = int32(bits)
    24 }
    25 func (self LocalVars) GetFloat(index uint) float32 {
    26     bits := uint32(self[index].num)
    27     return math.Float32frombits(bits)
    28 }
    29 
    30 // long consumes two slots
    31 func (self LocalVars) SetLong(index uint, val int64) {
    32     self[index].num = int32(val)
    33     self[index+1].num = int32(val >> 32)
    34 }
    35 func (self LocalVars) GetLong(index uint) int64 {
    36     low := uint32(self[index].num)
    37     high := uint32(self[index+1].num)
    38     return int64(high)<<32 | int64(low)
    39 }
    40 
    41 // double consumes two slots
    42 func (self LocalVars) SetDouble(index uint, val float64) {
    43     bits := math.Float64bits(val)
    44     self.SetLong(index, int64(bits))
    45 }
    46 func (self LocalVars) GetDouble(index uint) float64 {
    47     bits := uint64(self.GetLong(index))
    48     return math.Float64frombits(bits)
    49 }
    50 
    51 func (self LocalVars) SetRef(index uint, ref *Object) {
    52     self[index].ref = ref
    53 }
    54 func (self LocalVars) GetRef(index uint) *Object {
    55     return self[index].ref
    56 }

    对不同的变量有不同的存取方法。

    5、操作数栈

    与局部变量表的实现方法类似。创建operand_stack.go文件

     1 package rtda
     2 
     3 import "math"
     4 
     5 type OperandStack struct {
     6     size  uint
     7     slots []Slot
     8 }
     9 
    10 func newOperandStack(maxStack uint) *OperandStack {
    11     if maxStack > 0 {
    12         return &OperandStack{
    13             slots: make([]Slot, maxStack),
    14         }
    15     }
    16     return nil
    17 }
    18 
    19 func (self *OperandStack) PushInt(val int32) {
    20     self.slots[self.size].num = val
    21     self.size++
    22 }
    23 func (self *OperandStack) PopInt() int32 {
    24     self.size--
    25     return self.slots[self.size].num
    26 }
    27 
    28 func (self *OperandStack) PushFloat(val float32) {
    29     bits := math.Float32bits(val)
    30     self.slots[self.size].num = int32(bits)
    31     self.size++
    32 }
    33 func (self *OperandStack) PopFloat() float32 {
    34     self.size--
    35     bits := uint32(self.slots[self.size].num)
    36     return math.Float32frombits(bits)
    37 }
    38 
    39 // long consumes two slots
    40 func (self *OperandStack) PushLong(val int64) {
    41     self.slots[self.size].num = int32(val)
    42     self.slots[self.size+1].num = int32(val >> 32)
    43     self.size += 2
    44 }
    45 func (self *OperandStack) PopLong() int64 {
    46     self.size -= 2
    47     low := uint32(self.slots[self.size].num)
    48     high := uint32(self.slots[self.size+1].num)
    49     return int64(high)<<32 | int64(low)
    50 }
    51 
    52 // double consumes two slots
    53 func (self *OperandStack) PushDouble(val float64) {
    54     bits := math.Float64bits(val)
    55     self.PushLong(int64(bits))
    56 }
    57 func (self *OperandStack) PopDouble() float64 {
    58     bits := uint64(self.PopLong())
    59     return math.Float64frombits(bits)
    60 }
    61 
    62 func (self *OperandStack) PushRef(ref *Object) {
    63     self.slots[self.size].ref = ref
    64     self.size++
    65 }
    66 func (self *OperandStack) PopRef() *Object {
    67     self.size--
    68     ref := self.slots[self.size].ref
    69     self.slots[self.size].ref = nil
    70     return ref
    71 }

    三、测试

    在main.go中加入import “jvmgo/rtda"

    修改startJVM()方法

     1 func startJVM(cmd *Cmd) {
     2     frame := rtda.NewFrame(100, 100)
     3     testLocalVars(frame.LocalVars())
     4     testOperandStack(frame.OperandStack())
     5 }
     6 
     7 func testLocalVars(vars rtda.LocalVars) {
     8     vars.SetInt(0, 100)
     9     vars.SetInt(1, -100)
    10     vars.SetLong(2, 2997924580)
    11     vars.SetLong(4, -2997924580)
    12     vars.SetFloat(6, 3.1415926)
    13     vars.SetDouble(7, 2.71828182845)
    14     vars.SetRef(9, nil)
    15     println(vars.GetInt(0))
    16     println(vars.GetInt(1))
    17     println(vars.GetLong(2))
    18     println(vars.GetLong(4))
    19     println(vars.GetFloat(6))
    20     println(vars.GetDouble(7))
    21     println(vars.GetRef(9))
    22 }
    23 
    24 func testOperandStack(ops *rtda.OperandStack) {
    25     ops.PushInt(100)
    26     ops.PushInt(-100)
    27     ops.PushLong(2997924580)
    28     ops.PushLong(-2997924580)
    29     ops.PushFloat(3.1415926)
    30     ops.PushDouble(2.71828182845)
    31     ops.PushRef(nil)
    32     println(ops.PopRef())
    33     println(ops.PopDouble())
    34     println(ops.PopFloat())
    35     println(ops.PopLong())
    36     println(ops.PopLong())
    37     println(ops.PopInt())
    38     println(ops.PopInt())
    39 }

    在命令行窗口执行 go install jvmgo,编译成功后对jvmgo.exe进行测试

    PS D:Program_Filesgoin> .jvmgo.exe test
    100
    -100
    2997924580
    -2997924580
    +3.141593e+000
    +2.718282e+000
    0x0
    0x0
    +2.718282e+000
    +3.141593e+000
    -2997924580
    2997924580
    -100
    100
  • 相关阅读:
    阅读 Android源码的一些姿势
    Unity3d UGUI 界面适配 实例解析 三种适配方式
    Unity3D Android手机开发环境配置
    DOTween教程
    DoTween 部分中文文档
    C# 委托、事件,lamda表达式
    EditText中输入信息的限制的方法
    Android中shape中的属性大全
    Android 高版本API方法在低版本系统上的兼容性处理
    python 绘制f(x)=x^2
  • 原文地址:https://www.cnblogs.com/pingxin/p/p00083.html
Copyright © 2011-2022 走看看