-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
135 lines (121 loc) · 3.37 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package main
import (
"fmt"
"github.com/jvm-in-go/classfile"
"github.com/jvm-in-go/classpath"
"github.com/jvm-in-go/rtda"
"strings"
_ "strings"
)
// cmd test code
// run go install jvm-in-go will create jvm-in-go.exe in classpath/bin/
func main() {
cmd := parseCmd()
if cmd.versionFlag {
fmt.Printf("version 0.0.1")
} else if cmd.helpFlag || cmd.class == "" {
printUsage()
} else {
startJVM(cmd)
}
}
func startJVM(cmd *Cmd) {
//fmt.Printf("classpath: %s class: %s args: %v\n",
// cmd.cpOption, cmd.class, cmd.args)
//cp := classpath.Parse(cmd.XjreOption, cmd.cpOption)
//fmt.Printf("classpath:%v class: %v args:%v\n",
// cp, cmd.class, cmd.args)
//
//className := strings.Replace(cmd.class, ".", "/", -1)
//classData, _, err := cp.ReadClass(className)
//if err != nil {
// fmt.Printf("Could not find or load main class %s\n", cmd.class)
// return
//}
//fmt.Printf("class data:%v\n", classData)
//cp := classpath.Parse(cmd.XjreOption, cmd.cpOption)
//className := strings.Replace(cmd.class, ".", "/", -1)
//cf := loadClass(className, cp)
//fmt.Println(className, cp)
//printClassInfo(cf)
//frame := rtda.NewFrame(100, 100)
//testLocalVars(frame.LocalVars())
//testOperandStack(frame.OperandStack())
cp := classpath.Parse(cmd.XjreOption, cmd.cpOption)
className := strings.Replace(cmd.class, ".", "/", -1)
cf := loadClass(className, cp)
// find main method
mainMethod := getMainMethod(cf)
if mainMethod != nil {
interpret(mainMethod)
} else {
fmt.Printf("Main method not found in class %s\n", cmd.class)
}
}
func testLocalVars(vars rtda.LocalVars) {
vars.SetInt(0, 100)
vars.SetInt(1, -100)
vars.SetLong(2, 2997924580)
vars.SetLong(4, -2997924580)
vars.SetFloat(6, 3.1415926)
vars.SetDouble(7, 2.7182818245)
vars.SetRef(9, nil)
println(vars.GetInt(0))
println(vars.GetInt(1))
println(vars.GetInt(2))
println(vars.GetLong(2))
println(vars.GetFloat(6))
println(vars.GetDouble(7))
println(vars.GetRef(9))
}
func testOperandStack(ops *rtda.OperandStack) {
ops.PushInt(100)
ops.PushInt(-100)
ops.PushLong(2997924580)
ops.PushLong(-2997924580)
ops.PushFloat(3.1415926)
ops.PushDouble(2.71828182845)
ops.PushRef(nil)
println(ops.PopRef())
println(ops.PopDouble())
println(ops.PopFloat())
println(ops.PopLong())
println(ops.PopLong())
println(ops.PopInt())
println(ops.PopInt())
}
func loadClass(className string, cp *classpath.Classpath) *classfile.ClassFile {
classData, _, err := cp.ReadClass(className)
if err != nil {
panic(err)
}
cf, err := classfile.Parse(classData)
if err != nil {
panic(err)
}
return cf
}
func getMainMethod(cf *classfile.ClassFile) *classfile.MemberInfo {
for _, m := range cf.Methods() {
if m.Name() == "main" && m.Descriptor() == "([Ljava/lang/String;)V" {
return m
}
}
return nil
}
func printClassInfo(cf *classfile.ClassFile) {
fmt.Printf("version: %v.%v\n", cf.MajorVersion(), cf.MinorVersion())
fmt.Printf("constans count: %v\n", len(cf.ConstantPool()))
fmt.Printf("access flags: %v\n", cf.AccessFlags())
fmt.Printf("this class: %v\n", cf.ClassName())
fmt.Printf("super class: %v\n", cf.SuperClassName())
fmt.Printf("interface: %v\n", cf.InterfaceNames())
fmt.Printf("fields count: %v\n", len(cf.Fields()))
for _, f := range cf.Fields() {
fmt.Printf(" %s\n", f.Name())
}
fmt.Printf("Methods count: %v\n", len(cf.Methods()))
for _, m := range cf.Methods() {
fmt.Printf(" %s\n", m.Name())
}
}