200 lines
8.0 KiB
Java
200 lines
8.0 KiB
Java
package com.gabongao.jvm;
|
||
|
||
import com.gabongao.jvm.classfile.ClassFile;
|
||
import com.gabongao.jvm.classfile.MemberInfo;
|
||
import com.gabongao.jvm.classpath.ClassPath;
|
||
import com.gabongao.jvm.rtda.Frame;
|
||
import com.gabongao.jvm.rtda.LocalVars;
|
||
import com.gabongao.jvm.rtda.OperandStack;
|
||
import com.gabongao.jvm.rtda.heap.ClassLoader;
|
||
import com.gabongao.jvm.rtda.heap.ClassStruct;
|
||
import com.gabongao.jvm.rtda.heap.Method;
|
||
|
||
/**
|
||
* ┏┓ ┏┓+ +
|
||
* ┏┛┻━━━┛┻┓ + +
|
||
* ┃ ┃
|
||
* ┃ ━ ┃ ++ + + +
|
||
* ████━████ ┃+
|
||
* ┃ ┃ +
|
||
* ┃ ┻ ┃
|
||
* ┃ ┃ + +
|
||
* ┗━┓ ┏━┛
|
||
* ┃ ┃
|
||
* ┃ ┃ + + + +
|
||
* ┃ ┃ Code is far away from bug with the animal protecting
|
||
* ┃ ┃ + 神兽保佑,代码无bug
|
||
* ┃ ┃
|
||
* ┃ ┃ +
|
||
* ┃ ┗━━━┓ + +
|
||
* ┃ ┣┓
|
||
* ┃ ┏┛
|
||
* ┗┓┓┏━┳┓┏┛ + + + +
|
||
* ┃┫┫ ┃┫┫
|
||
* ┗┻┛ ┗┻┛+ + + +
|
||
* Created by Imgaojp on 2017/2/16.
|
||
*/
|
||
public class Jvm {
|
||
public static void main(String[] args) throws Exception {
|
||
Cmd cmd = new Cmd();
|
||
cmd.parseCmd(args);
|
||
if (cmd.isVersionFlag()) {
|
||
System.out.println("version 0.0.1");
|
||
} else if (cmd.isHelpFlag()) {
|
||
Cmd.printUsage(args);
|
||
} else {
|
||
startJvm(cmd);
|
||
}
|
||
}
|
||
|
||
public static void startJvm(Cmd cmd) {
|
||
/* ch01
|
||
System.out.printf("classpath: %s class: %s args:%s\n", cmd.getCpOption(), cmd.getClassName(), Arrays.asList(cmd.getArgs()).toString());
|
||
*/
|
||
|
||
/* ch02
|
||
ClassPath cp = new ClassPath();
|
||
cp.parse(cmd.jreOption, cmd.cpOption);
|
||
System.out.printf("classpath: %s\tclass: %s\targs: %s\n",cmd.cpOption,cmd.getClassName, Arrays.asList(cmd.args));
|
||
String getClassName = cmd.getClassName.replace(".", "/").concat(".class");
|
||
byte[] classData = cp.readClass(getClassName);
|
||
if (classData == null) {
|
||
System.out.printf("Could not load main class %s\n",getClassName);
|
||
System.exit(1);
|
||
}
|
||
for (byte b:classData
|
||
) {
|
||
System.out.printf("%X",b);
|
||
}
|
||
*/
|
||
|
||
|
||
/* ch03
|
||
ClassPath cp = new ClassPath();
|
||
cp.parse(cmd.jreOption, cmd.cpOption);
|
||
String getClassName = cmd.getClassName.replace(".", "/").concat(".class");
|
||
ClassFile classFile = new ClassFile(cp.readClass(getClassName));
|
||
classFile.read();
|
||
System.out.println(cmd.getClassName);
|
||
printClassInfo(classFile);
|
||
}
|
||
|
||
public static void printClassInfo(ClassFile classFile) {
|
||
System.out.printf("version: %d.%d\n", (int) classFile.getMajorVersion(), (int) classFile.getMinorVersion());
|
||
System.out.printf("constants count: %d\n", (classFile.getConstantPool()).getConstantInfos().length);
|
||
System.out.printf("access flags: 0X%X\n", (int) classFile.getAccessFlags());
|
||
System.out.printf("this class: %s\n", classFile.thisClassName());
|
||
System.out.printf("super class: %s\n", classFile.superClassName());
|
||
if (classFile.interfaceNames().length > 0) {
|
||
System.out.printf("interfaces: %s\n", Arrays.asList(classFile.interfaceNames()));
|
||
}
|
||
System.out.printf("fields: %d\n", (classFile.getFields()).length);
|
||
for (int i = 0; i < classFile.getFields().length; i++) {
|
||
System.out.printf("\t\t%s\n", classFile.getFields()[i].getName());
|
||
}
|
||
System.out.println("methods count : " + classFile.getMethods().length);
|
||
for (int i = 0; i < classFile.getMethods().length; i++) {
|
||
System.out.printf("\t\t%s\n", classFile.getMethods()[i].getName());
|
||
}
|
||
*/
|
||
|
||
// ch04
|
||
/*
|
||
Frame frame = new Frame(100, 100);
|
||
testLocalVars(frame.getLocalVars());
|
||
testOperandStack(frame.getOperandStack());
|
||
*/
|
||
|
||
//ch05
|
||
|
||
// Interpreter interpreter = new Interpreter();
|
||
// ClassPath cp = new ClassPath();
|
||
// cp.parse(cmd.jreOption, cmd.cpOption);
|
||
// String className = cmd.className.replace(".", "/").concat(".class");
|
||
// ClassFile classFile = loadClass(className, cp);
|
||
// classFile.read();
|
||
// MemberInfo mainMethod = getMainMethod(classFile);
|
||
// if (mainMethod != null) {
|
||
// interpreter.doInterpreter(mainMethod);
|
||
// } else {
|
||
// System.out.printf("Main method not found in class %s\n", className);
|
||
// }
|
||
|
||
|
||
Interpreter interpreter = new Interpreter();
|
||
ClassPath cp = new ClassPath();
|
||
|
||
ClassLoader classLoader = new ClassLoader(cp);
|
||
cp.parse(cmd.jreOption, cmd.cpOption);
|
||
// String className = cmd.className.replace(".", "/").concat(".class");
|
||
String className = cmd.className;
|
||
ClassStruct mainClass = classLoader.loadClass(className);
|
||
Method mainMethod = mainClass.getMainMethod();
|
||
// ClassFile classFile = loadClass(className, cp);
|
||
// classFile.read();
|
||
// MemberInfo mainMethod = getMainMethod(classFile);
|
||
if (mainMethod != null) {
|
||
interpreter.doInterpreter(mainMethod);
|
||
} else {
|
||
System.out.printf("Main method not found in class %s\n", className);
|
||
}
|
||
|
||
|
||
}
|
||
|
||
public static MemberInfo getMainMethod(ClassFile classFile) {
|
||
for (MemberInfo methodInfo : classFile.getMethods()
|
||
) {
|
||
if ("main".equals(methodInfo.getName()) && methodInfo.getDescriptor().equals("([Ljava/lang/String;)V")) {
|
||
return methodInfo;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
|
||
public static ClassFile loadClass(String className, ClassPath classPath) {
|
||
byte[] classData = classPath.readClass(className);
|
||
return new ClassFile(classData);
|
||
}
|
||
|
||
private static void testLocalVars(LocalVars localVars) {
|
||
localVars.setInt(0, 100);
|
||
localVars.setInt(1, -100);
|
||
localVars.setInt(2, -100000);
|
||
localVars.setLong(3, 2997924580L);
|
||
localVars.setLong(5, -2997924580L);
|
||
localVars.setFloat(7, 3.1415926f);
|
||
localVars.setDouble(8, -2.7814897347028520974);
|
||
localVars.setRef(10, null);
|
||
System.out.println(localVars.getInt(0));
|
||
System.out.println(localVars.getInt(1));
|
||
System.out.println(localVars.getInt(2));
|
||
System.out.println(localVars.getLong(3));
|
||
System.out.println(localVars.getLong(5));
|
||
System.out.println(localVars.getFloat(7));
|
||
System.out.println(localVars.getDouble(8));
|
||
System.out.println(localVars.getRef(10));
|
||
}
|
||
|
||
private static void testOperandStack(OperandStack operandStack) {
|
||
operandStack.pushInt(100);
|
||
operandStack.pushInt(-100);
|
||
operandStack.pushInt(-100000);
|
||
operandStack.pushLong(2997924580L);
|
||
operandStack.pushLong(-2997924580L);
|
||
operandStack.pushFloat(3.1415926f);
|
||
operandStack.pushDouble(-2.7814897347028520974);
|
||
operandStack.pushRef(null);
|
||
System.out.println(operandStack.popRef());
|
||
System.out.println(operandStack.popDouble());
|
||
System.out.println(operandStack.popFloat());
|
||
System.out.println(operandStack.popLong());
|
||
System.out.println(operandStack.popLong());
|
||
System.out.println(operandStack.popInt());
|
||
System.out.println(operandStack.popInt());
|
||
System.out.println(operandStack.popInt());
|
||
}
|
||
|
||
}
|