Skip to content

Commit

Permalink
jvm 执行引擎2
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickfeng committed Apr 26, 2017
1 parent 0b36bd7 commit 9c1f2f4
Show file tree
Hide file tree
Showing 14 changed files with 386 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.github.ipk2015.coding2017.minijvm.clz.ClassFile;
import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool;
import com.github.ipk2015.coding2017.minijvm.engine.ExecutionResult;
import com.github.ipk2015.coding2017.minijvm.engine.Heap;
import com.github.ipk2015.coding2017.minijvm.engine.JavaObject;
import com.github.ipk2015.coding2017.minijvm.engine.StackFrame;

public class BiPushCmd extends OneOperandCmd {
Expand All @@ -20,8 +22,9 @@ public String toString(ConstantPool pool) {

@Override
public void execute(StackFrame frame, ExecutionResult result) {
// TODO Auto-generated method stub

int operand = this.getOperand();
JavaObject newInt = Heap.getInstance().newInt(operand);
frame.getOprandStack().push(newInt);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,41 @@ public abstract class ByteCodeCommand {
ClassFile clzFile;
private int offset;

public static final String aconst_null = "01";
public static final String new_object = "BB";
public static final String lstore = "37";
public static final String invokespecial = "B7";
public static final String invokevirtual = "B6";
public static final String getfield = "B4";
public static final String putfield = "B5";
public static final String getstatic = "B2";
public static final String ldc = "12";
public static final String dup = "59";
public static final String bipush = "10";
public static final String aload_0 = "2A";
public static final String aload_1 = "2B";
public static final String aload_2 = "2C";
public static final String iload = "15";
public static final String iload_1 = "1B";
public static final String iload_2 = "1C";
public static final String iload_3 = "1D";
public static final String fload_3 = "25";

public static final String voidreturn = "B1";
public static final String ireturn = "AC";
public static final String freturn = "AE";

public static final String astore_1 = "4C";
public static final String if_icmp_ge = "A2";
public static final String if_icmple = "A4";
public static final String goto_no_condition = "A7";
public static final String iconst_0 = "03";
public static final String iconst_1 = "04";
public static final String istore_1 = "3C";
public static final String istore_2 = "3D";
public static final String iadd = "60";
public static final String iinc = "84";

private static Map<String,String> codeMap = new HashMap<String,String>();

static{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.github.ipk2015.coding2017.minijvm.clz.ClassFile;
import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool;
import com.github.ipk2015.coding2017.minijvm.constant.FieldRefInfo;
import com.github.ipk2015.coding2017.minijvm.engine.ExecutionResult;
import com.github.ipk2015.coding2017.minijvm.engine.JavaObject;
import com.github.ipk2015.coding2017.minijvm.engine.StackFrame;

public class GetFieldCmd extends TwoOperandCmd {
Expand All @@ -19,8 +21,12 @@ public String toString(ConstantPool pool) {

@Override
public void execute(StackFrame frame, ExecutionResult result) {
// TODO Auto-generated method stub

FieldRefInfo fieldRefInfo = (FieldRefInfo)this.getConstantInfo(this.getIndex());
String fieldName = fieldRefInfo.getFieldName();
JavaObject javaObject = frame.getOprandStack().pop();
JavaObject fieldValue = javaObject.getFieldValue(fieldName);
frame.getOprandStack().push(fieldValue);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

import com.github.ipk2015.coding2017.minijvm.clz.ClassFile;
import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool;
import com.github.ipk2015.coding2017.minijvm.constant.FieldRefInfo;
import com.github.ipk2015.coding2017.minijvm.engine.ExecutionResult;
import com.github.ipk2015.coding2017.minijvm.engine.Heap;
import com.github.ipk2015.coding2017.minijvm.engine.JavaObject;
import com.github.ipk2015.coding2017.minijvm.engine.StackFrame;

public class GetStaticFieldCmd extends TwoOperandCmd {
Expand All @@ -20,7 +23,22 @@ public String toString(ConstantPool pool) {

@Override
public void execute(StackFrame frame, ExecutionResult result) {
// TODO Auto-generated method stub
FieldRefInfo info = (FieldRefInfo)this.getConstantInfo(this.getIndex());
String className = info.getClassName();
String fieldName = info.getFieldName();
String fieldType = info.getFieldType();

if("java/lang/System".equals(className)
&& "out".equals(fieldName)
&& "Ljava/io/PrintStream;".equals(fieldType)){
JavaObject jo = Heap.getInstance().newObject(className);
frame.getOprandStack().push(jo);
}else{
throw new RuntimeException("className:"+className
+",fieldName:"+fieldName
+",fieldType:"+fieldType
+",not included");
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import com.github.ipk2015.coding2017.minijvm.clz.ClassFile;
import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool;
import com.github.ipk2015.coding2017.minijvm.constant.MethodRefInfo;
import com.github.ipk2015.coding2017.minijvm.engine.ExecutionResult;
import com.github.ipk2015.coding2017.minijvm.engine.MethodArea;
import com.github.ipk2015.coding2017.minijvm.engine.StackFrame;
import com.github.ipk2015.coding2017.minijvm.method.Method;

public class InvokeSpecialCmd extends TwoOperandCmd {

Expand All @@ -20,8 +23,16 @@ public String toString(ConstantPool pool) {

@Override
public void execute(StackFrame frame, ExecutionResult result) {
// TODO Auto-generated method stub

MethodRefInfo methodRefInfo = (MethodRefInfo)this.getConstantInfo(this.getIndex());
// 我们不用实现jang.lang.Object 的init方法
if(methodRefInfo.getClassName().equals("java/lang/Object")
&& methodRefInfo.getMethodName().equals("<init>")){
return ;

}
Method method = MethodArea.getInstance().getMethod(methodRefInfo);
result.setNextAction(ExecutionResult.PAUSE_AND_RUN_NEW_FRAME);
result.setNextMethod(method);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

import com.github.ipk2015.coding2017.minijvm.clz.ClassFile;
import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool;
import com.github.ipk2015.coding2017.minijvm.constant.MethodRefInfo;
import com.github.ipk2015.coding2017.minijvm.engine.ExecutionResult;
import com.github.ipk2015.coding2017.minijvm.engine.JavaObject;
import com.github.ipk2015.coding2017.minijvm.engine.MethodArea;
import com.github.ipk2015.coding2017.minijvm.engine.StackFrame;
import com.github.ipk2015.coding2017.minijvm.method.Method;

public class InvokeVirtualCmd extends TwoOperandCmd {

Expand All @@ -19,8 +23,36 @@ public String toString(ConstantPool pool) {

@Override
public void execute(StackFrame frame, ExecutionResult result) {
// TODO Auto-generated method stub

MethodRefInfo methodRefInfo = (MethodRefInfo)this.getConstantInfo(this.getIndex());
String className = methodRefInfo.getClassName();
String methodName = methodRefInfo.getMethodName();
// 我们没有实现System.out.println方法, 所以也不用建立新的栈帧, 直接调用Java的方法, 打印出来即可。
if("java/io/PrintStream".equals(className) && "println".equals(methodName)){
JavaObject jo = (JavaObject)frame.getOprandStack().pop();
System.err.println("-------------------"+jo.toString()+"----------------");
// 这里就是那个out对象, 因为是个假的,直接pop出来
frame.getOprandStack().pop();
return;
}
//注意:多态, 这才是真正的对象, 先从该对象的class 中去找对应的方法,找不到的话再去找父类的方法
JavaObject javaObject = frame.getOprandStack().peek();
MethodArea methodArea = MethodArea.getInstance();
Method m = null;
String currentClassName = javaObject.getClassName();
while(null != currentClassName){
ClassFile currentClassFile = methodArea.findClassFile(currentClassName);
m = currentClassFile.getMethod(methodRefInfo.getClassName(), methodRefInfo.getParamAndReturnType());
if(null != m){
break;
}else{
currentClassName = currentClassFile.getSuperClassName();
}
}
if(null == m){
throw new RuntimeException("Can't find method for :" + methodRefInfo.toString());
}
result.setNextAction(ExecutionResult.PAUSE_AND_RUN_NEW_FRAME);
result.setNextMethod(m);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool;
import com.github.ipk2015.coding2017.minijvm.constant.StringInfo;
import com.github.ipk2015.coding2017.minijvm.engine.ExecutionResult;
import com.github.ipk2015.coding2017.minijvm.engine.Heap;
import com.github.ipk2015.coding2017.minijvm.engine.JavaObject;
import com.github.ipk2015.coding2017.minijvm.engine.StackFrame;

public class LdcCmd extends OneOperandCmd {
Expand All @@ -30,8 +32,17 @@ public String toString(ConstantPool pool) {

@Override
public void execute(StackFrame frame, ExecutionResult result) {
// TODO Auto-generated method stub

ConstantPool pool = this.getConstantPool();
ConstantInfo constantInfo = pool.getConstantInfo(this.getOperand());
if(constantInfo instanceof StringInfo){
StringInfo stringInfo = (StringInfo)constantInfo;
String value = stringInfo.toString();
JavaObject javaObject = Heap.getInstance().newString(value);
frame.getOprandStack().push(javaObject);
}else{
//TBD 处理其他类型
throw new RuntimeException("Only support StringInfo constant");
}
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.github.ipk2015.coding2017.minijvm.cmd;

import com.github.ipk2015.coding2017.minijvm.clz.ClassFile;
import com.github.ipk2015.coding2017.minijvm.constant.ClassInfo;
import com.github.ipk2015.coding2017.minijvm.constant.ConstantInfo;
import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool;
import com.github.ipk2015.coding2017.minijvm.engine.ExecutionResult;
import com.github.ipk2015.coding2017.minijvm.engine.Heap;
import com.github.ipk2015.coding2017.minijvm.engine.JavaObject;
import com.github.ipk2015.coding2017.minijvm.engine.StackFrame;

public class NewObjectCmd extends TwoOperandCmd{
Expand All @@ -19,8 +23,9 @@ public String toString(ConstantPool pool) {

@Override
public void execute(StackFrame frame, ExecutionResult result) {
// TODO Auto-generated method stub

ClassInfo classInfo = (ClassInfo)this.getConstantInfo(this.getIndex());
JavaObject newObject = Heap.getInstance().newObject(classInfo.getClassName());
frame.getOprandStack().push(newObject);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.github.ipk2015.coding2017.minijvm.clz.ClassFile;
import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool;
import com.github.ipk2015.coding2017.minijvm.engine.ExecutionResult;
import com.github.ipk2015.coding2017.minijvm.engine.Heap;
import com.github.ipk2015.coding2017.minijvm.engine.JavaObject;
import com.github.ipk2015.coding2017.minijvm.engine.StackFrame;

public class NoOperandCmd extends ByteCodeCommand{
Expand All @@ -24,7 +26,119 @@ public int getLength(){

@Override
public void execute(StackFrame frame, ExecutionResult result) {
// TODO Auto-generated method stub
String opCode = this.getOpCode();

if(ByteCodeCommand.aload_0.equals(opCode)){

JavaObject jo = frame.getLocalVariableValue(0);

frame.getOprandStack().push(jo);

} else if(ByteCodeCommand.aload_1.equals(opCode)){

JavaObject jo = frame.getLocalVariableValue(1);

frame.getOprandStack().push(jo);

} else if(ByteCodeCommand.aload_2.equals(opCode)){

JavaObject jo = frame.getLocalVariableValue(2);

frame.getOprandStack().push(jo);

}else if(ByteCodeCommand.iload_1.equals(opCode)){

JavaObject jo = frame.getLocalVariableValue(1);

frame.getOprandStack().push(jo);

} else if (ByteCodeCommand.iload_2.equals(opCode)){

JavaObject jo = frame.getLocalVariableValue(2);

frame.getOprandStack().push(jo);

} else if (ByteCodeCommand.iload_3.equals(opCode)){

JavaObject jo = frame.getLocalVariableValue(3);

frame.getOprandStack().push(jo);

}else if (ByteCodeCommand.fload_3.equals(opCode)){

JavaObject jo = frame.getLocalVariableValue(3);

frame.getOprandStack().push(jo);

}
else if (ByteCodeCommand.voidreturn.equals(opCode)){

result.setNextAction(ExecutionResult.EXIT_CURRENT_FRAME);

} else if(ByteCodeCommand.ireturn.equals(opCode)){
StackFrame callerFrame = frame.getCallerFrame();
JavaObject jo = frame.getOprandStack().pop();
callerFrame.getOprandStack().push(jo);

} else if(ByteCodeCommand.freturn.equals(opCode)){

StackFrame callerFrame = frame.getCallerFrame();
JavaObject jo = frame.getOprandStack().pop();
callerFrame.getOprandStack().push(jo);
}

else if(ByteCodeCommand.astore_1.equals(opCode)){

JavaObject jo = frame.getOprandStack().pop();

frame.setLocalVariableValue(1, jo);

} else if(ByteCodeCommand.dup.equals(opCode)){

JavaObject jo = frame.getOprandStack().peek();
frame.getOprandStack().push(jo);

} else if(ByteCodeCommand.iconst_0.equals(opCode)){

JavaObject jo = Heap.getInstance().newInt(0);

frame.getOprandStack().push(jo);

} else if(ByteCodeCommand.iconst_1.equals(opCode)){

JavaObject jo = Heap.getInstance().newInt(1);

frame.getOprandStack().push(jo);

} else if(ByteCodeCommand.istore_1.equals(opCode)){

JavaObject jo = frame.getOprandStack().pop();

frame.setLocalVariableValue(1, jo);

} else if(ByteCodeCommand.istore_2.equals(opCode)){

JavaObject jo = frame.getOprandStack().pop();

frame.setLocalVariableValue(2, jo);

} else if(ByteCodeCommand.iadd.equals(opCode)){

JavaObject jo1 = frame.getOprandStack().pop();
JavaObject jo2 = frame.getOprandStack().pop();

JavaObject sum = Heap.getInstance().newInt(jo1.getIntValue()+jo2.getIntValue());

frame.getOprandStack().push(sum);

} else if (ByteCodeCommand.aconst_null.equals(opCode)){

frame.getOprandStack().push(null);

}
else{
throw new RuntimeException("you must forget to implement the operation :" + opCode);
}

}

Expand Down
Loading

0 comments on commit 9c1f2f4

Please sign in to comment.