gojvm目录
1、搭建go环境
2、cmd命令行参数解析
3、搜索class文件
4、添加testOption 便于单元测试
5、解析classfile文件
6、运行时数据区
7、指令集
8、解释器
9、创建Class
10、类加载器
11、对象实例化new object
12、方法调用和返回
13 类初始化
14、jvm支持数组
15、jvm支持字符串-数组扩展
16、本地方法调用
17、ClassLoader原理
18、异常处理
19、 启动jvm
采用hook方式生成字符串
1、加载java/lang/String => jstr
2、ClassLoader加载'[C' char数组
3、将go 字符串utf-8 转换为 java utf-16格式
3、反射修改string value字段
// go string -> java.lang.String
func JString(loader *ClassLoader, goStr string) *Object {
if internedStr, ok := internedStrings[goStr]; ok {
return internedStr
}
//go 字符串 utf-8 => java utf-16
chars := stringToUtf16(goStr)
//加载 java类 char数组
jChars := &Object{loader.LoadClass("[C"), chars}
//加载java类 String
jStr := loader.LoadClass("java/lang/String").NewObject()
//反射设置
jStr.SetRefVar("value", "[C", jChars)
internedStrings[goStr] = jStr
return jStr
}
反射支持
object.go
func (self *Object) GetRefVar(name, descriptor string) *Object {
field := self.class.getField(name, descriptor, false)
slots := self.data.(Slots)
return slots.GetRef(field.slotId)
}
func (self *Object) SetRefVar(name, descriptor string, ref *Object) {
field := self.class.getField(name, descriptor, false)
slots := self.data.(Slots)
slots.SetRef(field.slotId, ref)
}
class.go
func (self *Class) getField(name, descriptor string, isStatic bool) *Field {
for c := self; c != nil; c = c.superClass {
for _, field := range c.fields {
if field.IsStatic() == isStatic &&
field.name == name &&
field.descriptor == descriptor {
return field
}
}
}
return nil
}
// todo 支持反射 reflection
func (self *Class) GetRefVar(fieldName, fieldDescriptor string) *Object {
field := self.getField(fieldName, fieldDescriptor, true)
return self.staticVars.GetRef(field.slotId)
}
func (self *Class) SetRefVar(fieldName, fieldDescriptor string, ref *Object) {
field := self.getField(fieldName, fieldDescriptor, true)
self.staticVars.SetRef(field.slotId, ref)
}
idc扩展
//todo 特别支持
case string: //todo 支持字符串 压栈
internedStr := heap.JString(class.Loader(),c.(string))
stack.PushRef(internedStr)
classloader扩展
func initStaticFinalVar(){
case "Ljava/lang/String;": //todo 支持字符串
goStr := cp.GetConstant(cpIndex).(string)
jStr := JString(class.Loader(),goStr)
vars.SetRef(slotId,jStr)
}
}
字符串测试
func Interpret(){
//字符串参数
jArgs := createArgsArray(method.Class().Loader(),args)
frame.LocalVars().SetRef(0,jArgs)
}
//创建args数组
func createArgsArray(loader *heap.ClassLoader, args []string) *heap.Object {
//加载class类
stringClass := loader.LoadClass("java/lang/String")
argsArr := stringClass.ArrayClass().NewArray(uint(len(args)))
jArgs := argsArr.Refs()
for i, arg := range args {
jArgs[i] = heap.JString(loader, arg)
}
return argsArr
}
shell脚本
#测试字符串数组
go run main -test "string" -cp test/lib/example.jar jvmgo.book.ch01.HelloWorld
#测试字符串参数
go run main -test "string" -cp test/lib/example.jar jvmgo.book.ch08.PrintArgs 'go jvm args' 'PrintArgs' 'Hello , World'
实战项目地址
https://github.com/yinlingchaoliu/jvmgo.git
提交标签 "array"
网友评论