Skip to content

Commit

Permalink
simplify java command parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
zxh0 committed May 16, 2019
1 parent e5f32d6 commit 58a552e
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 172 deletions.
4 changes: 2 additions & 2 deletions jvmgo/classfile/constant_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ func (self *ConstantPool) getConstantInfo(index uint16) ConstantInfo {
}

func (self *ConstantPool) getNameAndType(index uint16) (name, _type string) {
ntInfo := self.getConstantInfo(index).(*ConstantNameAndTypeInfo)
ntInfo := self.getConstantInfo(index).(ConstantNameAndTypeInfo)
name = self.getUtf8(ntInfo.nameIndex)
_type = self.getUtf8(ntInfo.descriptorIndex)
return
}

func (self *ConstantPool) getClassName(index uint16) string {
classInfo := self.getConstantInfo(index).(*ConstantClassInfo)
classInfo := self.getConstantInfo(index).(ConstantClassInfo)
return self.getUtf8(classInfo.nameIndex)
}

Expand Down
20 changes: 20 additions & 0 deletions jvmgo/classpath/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package classpath

/*
+-------+ *
| Entry |<------------------------+
+-------+ |
△ |
| |
+-------------+----------------+ |
| | |
+----------+ +----------+ +----------------+ |
| DirEntry | | ZipEntry | | CompositeEntry |<>--+
+----------+ +----------+ +----------------+
|
+----------------+
| WildcardEntry |
+----------------+
*/
15 changes: 0 additions & 15 deletions jvmgo/cmd/java/arg_reader.go

This file was deleted.

120 changes: 90 additions & 30 deletions jvmgo/cmd/java/command.go
Original file line number Diff line number Diff line change
@@ -1,48 +1,108 @@
package main

import (
"fmt"
"errors"
"strconv"
"strings"
)

const (
_1k = 1024
_1m = _1k * _1k
_1g = _1k * _1m
)

type Options struct {
Classpath string
VerboseClass bool
Xss int
Xcpuprofile string
XuseJavaHome bool
}

// java [ options ] class [ arguments ]
type Command struct {
options *Options
class string
args []string
Options Options
Class string
Args []string
}

// getters
func (self *Command) Class() string {
return self.class
}
func (self *Command) Args() []string {
return self.args
}
func (self *Command) Options() *Options {
return self.options
func parseCommand(osArgs []string) (Command, error) {
args := osArgs[1:]
options, err := parseOptions(&args)
if err != nil {
return Command{}, err
}

class := removeFirst(&args)
cmd := Command{
Options: options,
Class: class,
Args: args,
}
return cmd, nil
}

func ParseCommand(osArgs []string) (cmd *Command, err error) {
defer func() {
if r := recover(); r != nil {
var ok bool
err, ok = r.(error)
if !ok {
err = fmt.Errorf("%v", r)
func parseOptions(args *[]string) (Options, error) {
options := Options{
Xss: 16 * _1k,
}

for hasMoreOptions(*args) {
optionName := removeFirst(args)
switch optionName {
case "-cp", "-classpath":
options.Classpath = removeFirst(args)
case "-verbose", "-verbose:class":
options.VerboseClass = true
case "-Xcpuprofile":
options.Xcpuprofile = removeFirst(args)
case "-XuseJavaHome":
options.XuseJavaHome = true
default:
if !strings.HasPrefix(optionName, "-Xss") {
return options, errors.New("Unrecognized option: " + optionName)
}
ss, err := parseXss(optionName)
if err != nil {
return options, err
}
options.Xss = ss
}
}()

argReader := &ArgReader{osArgs[1:]}
cmd = &Command{
options: parseOptions(argReader),
class: argReader.removeFirst(),
args: argReader.args,
}

return
return options, nil
}

func hasMoreOptions(args []string) bool {
return len(args) > 0 && args[0][0] == '-'
}

func removeFirst(args *[]string) string {
first := (*args)[0]
*args = (*args)[1:]
return first
}

func PrintUsage() {
fmt.Println("usage: jvmgo [-options] class [args...]")
// -Xss<size>[g|G|m|M|k|K]
func parseXss(optionName string) (int, error) {
size := optionName[4:] // remove -Xss
if len(size) > 0 {
switch size[len(size)-1] {
case 'g', 'G':
return parseSS(size[:len(size)-1], _1g)
case 'm', 'M':
return parseSS(size[:len(size)-1], _1m)
case 'k', 'K':
return parseSS(size[:len(size)-1], _1k)
}
}
return parseSS(size, 1)
}

func parseSS(size string, unit int) (int, error) {
if i, err := strconv.Atoi(size); err == nil {
return i * unit, nil
}
return 0, errors.New("Invalid thread stack size: -Xss")
}
44 changes: 0 additions & 44 deletions jvmgo/cmd/java/jvm.go

This file was deleted.

49 changes: 47 additions & 2 deletions jvmgo/cmd/java/main.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,59 @@
package main

import (
"fmt"
"os"
"runtime/pprof"

"github.com/zxh0/jvm.go/jvmgo/classpath"
"github.com/zxh0/jvm.go/jvmgo/interpreter"
"github.com/zxh0/jvm.go/jvmgo/jutil"
_ "github.com/zxh0/jvm.go/jvmgo/native"
"github.com/zxh0/jvm.go/jvmgo/options"
"github.com/zxh0/jvm.go/jvmgo/rtda"
"github.com/zxh0/jvm.go/jvmgo/rtda/heap"
)

func main() {
cmd, err := ParseCommand(os.Args)
cmd, err := parseCommand(os.Args)
if err != nil {
PrintUsage()
fmt.Println(err)
printUsage()
} else {
startJVM(cmd)
}
}

func printUsage() {
fmt.Println("usage: jvmgo [-options] class [args...]")
}

func startJVM(cmd Command) {
Xcpuprofile := cmd.Options.Xcpuprofile
if Xcpuprofile != "" {
f, err := os.Create(Xcpuprofile)
if err != nil {
panic(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}

options.InitOptions(cmd.Options.VerboseClass, cmd.Options.Xss, cmd.Options.XuseJavaHome)

cp := classpath.Parse(cmd.Options.Classpath)
heap.InitBootLoader(cp)

mainClassName := jutil.ReplaceAll(cmd.Class, ".", "/")
mainThread := createMainThread(mainClassName, cmd.Args)
interpreter.Loop(mainThread)
interpreter.KeepAlive()
}

func createMainThread(className string, args []string) *rtda.Thread {
mainThread := rtda.NewThread(nil)
bootMethod := heap.BootstrapMethod()
bootArgs := []interface{}{className, args}
mainThread.InvokeMethodWithShim(bootMethod, bootArgs)
return mainThread
}
79 changes: 0 additions & 79 deletions jvmgo/cmd/java/options.go

This file was deleted.

0 comments on commit 58a552e

Please sign in to comment.