diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/EmployeeV1.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/EmployeeV1.java new file mode 100644 index 0000000000..e6bc33f6b0 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/EmployeeV1.java @@ -0,0 +1,28 @@ +package com.coding.mini_jvm.src.com.coderising.jvm; + +public class EmployeeV1 { + + + private String name; + private int age; + + public EmployeeV1(String name, int age) { + this.name = name; + this.age = age; + } + + public void setName(String name) { + this.name = name; + } + public void setAge(int age){ + this.age = age; + } + public void sayHello() { + System.out.println("Hello , this is class Employee "); + } + public static void main(String[] args){ + EmployeeV1 p = new EmployeeV1("Andy",29); + p.sayHello(); + + } +} \ No newline at end of file diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/BiPushCmd.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/BiPushCmd.java index eb7dafa79d..fd60d0ea7b 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/BiPushCmd.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/BiPushCmd.java @@ -2,6 +2,10 @@ import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.ExecutionResult; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.Heap; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.JavaObject; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.StackFrame; public class BiPushCmd extends OneOperandCmd { @@ -15,7 +19,13 @@ public String toString(ConstantPool pool) { return this.getOffset()+": "+ this.getOpCode()+" " + this.getReadableCodeText() + " " + this.getOperand(); } - - + + @Override + public void execute(StackFrame frame, ExecutionResult result) { + int value = this.getOperand(); + JavaObject jo = Heap.getInstance().newInt(value); + frame.getOprandStack().push(jo); + } + } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/ByteCodeCommand.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/ByteCodeCommand.java index b44d66c880..d22bd332ba 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/ByteCodeCommand.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/ByteCodeCommand.java @@ -3,6 +3,8 @@ import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantInfo; import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.ExecutionResult; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.StackFrame; import java.util.HashMap; import java.util.Map; @@ -123,5 +125,5 @@ public String getReadableCodeText(){ return txt; } - //public abstract void execute(StackFrame frame,FrameResult result); + public abstract void execute(StackFrame frame,ExecutionResult result); } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/GetFieldCmd.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/GetFieldCmd.java index 5801068cb0..113f8d7702 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/GetFieldCmd.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/GetFieldCmd.java @@ -2,6 +2,10 @@ import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool; +import com.coding.mini_jvm.src.com.coderising.jvm.constant.FieldRefInfo; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.ExecutionResult; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.JavaObject; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.StackFrame; public class GetFieldCmd extends TwoOperandCmd { @@ -15,7 +19,13 @@ public String toString(ConstantPool pool) { return super.getOperandAsField(pool); } - - + @Override + public void execute(StackFrame frame, ExecutionResult result) { + FieldRefInfo fieldRefInfo = (FieldRefInfo)this.getConstantInfo(this.getIndex()); + String fieldName = fieldRefInfo.getFieldName(); + JavaObject jo = frame.getOprandStack().pop(); + frame.getOprandStack().push(jo.getFieldValue(fieldName)); + } + } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/GetStaticFieldCmd.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/GetStaticFieldCmd.java index e577d1b56c..dfcd905c52 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/GetStaticFieldCmd.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/GetStaticFieldCmd.java @@ -3,6 +3,11 @@ import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool; +import com.coding.mini_jvm.src.com.coderising.jvm.constant.FieldRefInfo; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.ExecutionResult; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.Heap; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.JavaObject; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.StackFrame; public class GetStaticFieldCmd extends TwoOperandCmd { @@ -17,4 +22,20 @@ public String toString(ConstantPool pool) { return super.getOperandAsField(pool); } + @Override + public void execute(StackFrame frame, ExecutionResult result) { + FieldRefInfo fieldRefInfo = (FieldRefInfo)this.getConstantInfo(this.getIndex()); + String fieldName = fieldRefInfo.getFieldName(); + String className = fieldRefInfo.getClassName(); + String fieldType = fieldRefInfo.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); + } +// JavaObject jo = Heap.getInstance().newObject(className); +// frame.getOprandStack().push(jo); + } + } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/InvokeSpecialCmd.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/InvokeSpecialCmd.java index 2900bb2c60..c402bfbba9 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/InvokeSpecialCmd.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/InvokeSpecialCmd.java @@ -3,6 +3,11 @@ import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool; +import com.coding.mini_jvm.src.com.coderising.jvm.constant.MethodRefInfo; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.ExecutionResult; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.MethodArea; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.StackFrame; +import com.coding.mini_jvm.src.com.coderising.jvm.method.Method; public class InvokeSpecialCmd extends TwoOperandCmd { @@ -17,6 +22,17 @@ public String toString(ConstantPool pool) { return super.getOperandAsMethod(pool); } - + @Override + public void execute(StackFrame frame, ExecutionResult result) { + MethodRefInfo methodRefInfo = (MethodRefInfo) this.getConstantInfo(this.getIndex()); + if (methodRefInfo.getClassName().equals("java/lang/Object") + && methodRefInfo.getMethodName().equals("")) { + return; + } + Method nextMethod = MethodArea.getInstance().getMethod(methodRefInfo); + result.setNextAction(ExecutionResult.PAUSE_AND_RUN_NEW_FRAME); + result.setNextMethod(nextMethod); + } + } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/InvokeVirtualCmd.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/InvokeVirtualCmd.java index ff7f0fdf14..fe95c356c7 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/InvokeVirtualCmd.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/InvokeVirtualCmd.java @@ -3,6 +3,12 @@ import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool; +import com.coding.mini_jvm.src.com.coderising.jvm.constant.MethodRefInfo; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.ExecutionResult; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.JavaObject; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.MethodArea; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.StackFrame; +import com.coding.mini_jvm.src.com.coderising.jvm.method.Method; public class InvokeVirtualCmd extends TwoOperandCmd { @@ -12,11 +18,25 @@ public InvokeVirtualCmd(ClassFile clzFile,String opCode) { @Override public String toString(ConstantPool pool) { - return super.getOperandAsMethod(pool); } - - + @Override + public void execute(StackFrame frame, ExecutionResult result) { + MethodRefInfo methodRefInfo = (MethodRefInfo) this.getConstantInfo(this.getIndex()); + String methodName = methodRefInfo.getMethodName(); + String className = methodRefInfo.getClassName(); + if ("java/io/PrintStream".equals(className) && "println".equals(methodName)) { + JavaObject jo = frame.getOprandStack().pop(); + System.out.println("***********"+jo.toString()+"***********"); + + frame.getOprandStack().pop(); + return; + } + Method nextMethod = MethodArea.getInstance().getMethod(methodRefInfo); + result.setNextAction(ExecutionResult.PAUSE_AND_RUN_NEW_FRAME); + result.setNextMethod(nextMethod); + } + } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/LdcCmd.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/LdcCmd.java index abaeae3a9e..63492570ee 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/LdcCmd.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/LdcCmd.java @@ -5,6 +5,9 @@ import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantInfo; import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool; import com.coding.mini_jvm.src.com.coderising.jvm.constant.StringInfo; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.ExecutionResult; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.JavaObject; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.StackFrame; public class LdcCmd extends OneOperandCmd { @@ -26,5 +29,19 @@ public String toString(ConstantPool pool) { return this.getOffset()+":"+this.getOpCode()+" " + this.getReadableCodeText() + " "+ value; } - + + @Override + public void execute(StackFrame frame, ExecutionResult result) { + ClassFile clzFile = this.getClassFile(); + ConstantInfo info = (ConstantInfo)clzFile.getConstantPool().getConstantInfo(this.getOperand()); + String value = "TBD"; + if (info instanceof StringInfo) { + StringInfo strInfo = (StringInfo)info; + value = strInfo.toString(); + } + JavaObject jo = new JavaObject(JavaObject.STRING); + jo.setStringValue(value); + frame.getOprandStack().push(jo); + } + } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/NewObjectCmd.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/NewObjectCmd.java index db90b82a35..40c5008a9d 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/NewObjectCmd.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/NewObjectCmd.java @@ -1,7 +1,12 @@ package com.coding.mini_jvm.src.com.coderising.jvm.cmd; import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; +import com.coding.mini_jvm.src.com.coderising.jvm.constant.ClassInfo; import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.ExecutionResult; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.Heap; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.JavaObject; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.StackFrame; public class NewObjectCmd extends TwoOperandCmd{ @@ -15,5 +20,12 @@ public String toString(ConstantPool pool) { return super.getOperandAsClassInfo(pool); } - + @Override + public void execute(StackFrame frame, ExecutionResult result) { + ClassInfo clzInfo = (ClassInfo) clzFile.getConstantPool().getConstantInfo(getIndex()); + JavaObject jo = Heap.getInstance().newObject(clzInfo.getClassName()); + frame.getOprandStack().push(jo); + } + + } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/NoOperandCmd.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/NoOperandCmd.java index 3cd045f6d3..afbbd6248e 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/NoOperandCmd.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/NoOperandCmd.java @@ -3,6 +3,9 @@ import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.ExecutionResult; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.JavaObject; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.StackFrame; public class NoOperandCmd extends ByteCodeCommand{ @@ -15,8 +18,37 @@ public String toString(ConstantPool pool) { return this.getOffset()+":" +this.getOpCode() + " "+ this.getReadableCodeText(); } - - + @Override + public void execute(StackFrame frame, ExecutionResult result) { + if (CommandParser.astore_1.equals(this.getOpCode())) { + JavaObject jo = frame.getOprandStack().pop(); + frame.setLocalVariableValue(1, jo); + } else if (CommandParser.aload_0.equals(this.getOpCode())) { + JavaObject jo = frame.getLocalVariableValue(0); + frame.getOprandStack().push(jo); + } else if (CommandParser.aload_1.equals(this.getOpCode())) { + JavaObject jo = frame.getLocalVariableValue(1); + frame.getOprandStack().push(jo); + } else if (CommandParser.iload_1.equals(this.getOpCode())) { + JavaObject jo = frame.getLocalVariableValue(1); + frame.getOprandStack().push(jo); + } else if (CommandParser.iload_2.equals(this.getOpCode())) { + JavaObject jo = frame.getLocalVariableValue(2); + frame.getOprandStack().push(jo); + } else if (CommandParser.istore_1.equals(this.getOpCode())) { + JavaObject jo = frame.getOprandStack().pop(); + frame.setLocalVariableValue(1, jo); + } else if (CommandParser.voidreturn.equals(this.getOpCode())) { + result.setNextAction(ExecutionResult.EXIT_CURRENT_FRAME); + } else if (CommandParser.dup.equals(this.getOpCode())) { + JavaObject jo = frame.getOprandStack().peek(); + frame.getOprandStack().push(jo); + } else { + throw new RuntimeException("this operator ["+this.getOpCode()+"] not support yet"); + } + } + + public int getLength(){ return 1; } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/PutFieldCmd.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/PutFieldCmd.java index 6f6ecd0eb1..894e8ed53b 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/PutFieldCmd.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/cmd/PutFieldCmd.java @@ -3,6 +3,11 @@ import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; import com.coding.mini_jvm.src.com.coderising.jvm.constant.ConstantPool; +import com.coding.mini_jvm.src.com.coderising.jvm.constant.FieldRefInfo; +import com.coding.mini_jvm.src.com.coderising.jvm.constant.NameAndTypeInfo; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.ExecutionResult; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.JavaObject; +import com.coding.mini_jvm.src.com.coderising.jvm.engine.StackFrame; public class PutFieldCmd extends TwoOperandCmd { @@ -16,5 +21,15 @@ public String toString(ConstantPool pool) { return super.getOperandAsField(pool); } + @Override + public void execute(StackFrame frame, ExecutionResult result) { + FieldRefInfo fieldRefInfo = (FieldRefInfo)this.getConstantInfo(this.getIndex()); + NameAndTypeInfo nameAndTypeInfo = (NameAndTypeInfo)this.getConstantInfo(fieldRefInfo.getNameAndTypeIndex()); + String fieldName = nameAndTypeInfo.getName(); + JavaObject fieldValue = frame.getOprandStack().pop(); + JavaObject objectRef = frame.getOprandStack().pop(); + objectRef.setFieldValue(fieldName, fieldValue); + } + } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/ExecutionResult.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/ExecutionResult.java new file mode 100644 index 0000000000..81c353dd32 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/ExecutionResult.java @@ -0,0 +1,57 @@ +package com.coding.mini_jvm.src.com.coderising.jvm.engine; + + +import com.coding.mini_jvm.src.com.coderising.jvm.method.Method; + +public class ExecutionResult { + public static final int RUN_NEXT_CMD = 1; + public static final int JUMP = 2; + public static final int EXIT_CURRENT_FRAME = 3; + public static final int PAUSE_AND_RUN_NEW_FRAME = 4; + + private int nextAction = RUN_NEXT_CMD; + + private int nextCmdOffset = 0; + + private Method nextMethod; + + public Method getNextMethod() { + return nextMethod; + } + + public void setNextMethod(Method nextMethod) { + this.nextMethod = nextMethod; + } + + + public void setNextAction(int action){ + this.nextAction = action; + } + public boolean isPauseAndRunNewFrame(){ + return this.nextAction == PAUSE_AND_RUN_NEW_FRAME; + } + public boolean isExitCurrentFrame(){ + return this.nextAction == EXIT_CURRENT_FRAME; + } + + public boolean isRunNextCmd(){ + return this.nextAction == RUN_NEXT_CMD; + } + + public boolean isJump(){ + return this.nextAction == JUMP; + } + + public int getNextCmdOffset() { + return nextCmdOffset; + } + + public void setNextCmdOffset(int nextCmdOffset) { + this.nextCmdOffset = nextCmdOffset; + } + + + + + +} diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/ExecutorEngine.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/ExecutorEngine.java new file mode 100644 index 0000000000..3ada1ae371 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/ExecutorEngine.java @@ -0,0 +1,56 @@ +package com.coding.mini_jvm.src.com.coderising.jvm.engine; + + +import com.coding.mini_jvm.src.com.coderising.jvm.method.Method; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Stack; + +public class ExecutorEngine { + + private Stack stack = new Stack(); + + public ExecutorEngine() { + + } + + public void execute(Method mainMethod) { + stack.push(StackFrame.create(mainMethod)); + while (!stack.isEmpty()) { + //1 执行栈帧 + StackFrame frame = stack.peek(); + ExecutionResult executionResult = frame.execute(); + if (executionResult.isPauseAndRunNewFrame()) { + Method method = executionResult.getNextMethod(); + StackFrame nextFrame = StackFrame.create(method); + nextFrame.setCallerFrame(frame); + setupFunctionCallParams(frame, nextFrame); + stack.push(nextFrame); + } else { + stack.pop(); + } + } + + } + + + private void setupFunctionCallParams(StackFrame currentFrame,StackFrame nextFrame) { + + Method method = nextFrame.getMethod(); + List params = method.getParameterList(); + int paramNum = params.size(); + if (!method.isStatic()) { + paramNum++; + } + List args = new ArrayList<>(); + while (paramNum > 0) { + args.add(currentFrame.getOprandStack().pop()); + paramNum--; + } + Collections.reverse(args); + nextFrame.setLocalVariableTable(args); + } + +} diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/Heap.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/Heap.java new file mode 100644 index 0000000000..2da0ef9e6b --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/Heap.java @@ -0,0 +1,39 @@ +package com.coding.mini_jvm.src.com.coderising.jvm.engine; + +public class Heap { + + /** + * 没有实现垃圾回收, 所以对于下面新创建的对象, 并没有记录到一个数据结构当中 + */ + + private static Heap instance = new Heap(); + private Heap() { + } + public static Heap getInstance(){ + return instance; + } + public JavaObject newObject(String clzName){ + + JavaObject jo = new JavaObject(JavaObject.OBJECT); + jo.setClassName(clzName); + return jo; + } + + public JavaObject newString(String value){ + JavaObject jo = new JavaObject(JavaObject.STRING); + jo.setStringValue(value); + return jo; + } + + public JavaObject newFloat(float value){ + JavaObject jo = new JavaObject(JavaObject.FLOAT); + jo.setFloatValue(value); + return jo; + } + public JavaObject newInt(int value){ + JavaObject jo = new JavaObject(JavaObject.INT); + jo.setIntValue(value); + return jo; + } + +} diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/JavaObject.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/JavaObject.java new file mode 100644 index 0000000000..471bd874d1 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/JavaObject.java @@ -0,0 +1,71 @@ +package com.coding.mini_jvm.src.com.coderising.jvm.engine; + +import java.util.HashMap; +import java.util.Map; + +public class JavaObject { + public static final int OBJECT = 1; + public static final int STRING = 2; + public static final int INT = 3; + public static final int FLOAT = 4; + + int type; + private String className; + + private Map fieldValues = new HashMap(); + + private String stringValue; + + private int intValue; + + private float floatValue; + + public void setFieldValue(String fieldName, JavaObject fieldValue){ + fieldValues.put(fieldName, fieldValue); + } + public JavaObject(int type){ + this.type = type; + } + public void setClassName(String className){ + this.className = className; + } + public void setStringValue(String value){ + stringValue = value; + } + public String getStringValue(){ + return this.stringValue; + } + public void setIntValue(int value) { + this.intValue = value; + } + public int getIntValue(){ + return this.intValue; + } + public int getType(){ + return type; + } + public JavaObject getFieldValue(String fieldName){ + return this.fieldValues.get(fieldName); + } + public String toString(){ + switch(this.getType()){ + case INT: + return String.valueOf(this.intValue); + case STRING: + return this.stringValue; + case OBJECT: + return this.className +":"+ this.fieldValues; + case FLOAT : + return String.valueOf(this.floatValue); + default: + return null; + } + } + public String getClassName(){ + return this.className; + } + public void setFloatValue(float value) { + this.floatValue = value; + } + +} diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/MethodArea.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/MethodArea.java new file mode 100644 index 0000000000..5abaa40308 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/MethodArea.java @@ -0,0 +1,71 @@ +package com.coding.mini_jvm.src.com.coderising.jvm.engine; + + +import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; +import com.coding.mini_jvm.src.com.coderising.jvm.constant.MethodRefInfo; +import com.coding.mini_jvm.src.com.coderising.jvm.loader.ClassFileLoader; +import com.coding.mini_jvm.src.com.coderising.jvm.method.Method; + +import java.util.HashMap; +import java.util.Map; + +public class MethodArea { + + public static final MethodArea instance = new MethodArea(); + + /** + * 注意:我们做了极大的简化, ClassLoader 只有一个, 实际JVM中的ClassLoader,是一个双亲委托的模型 + */ + + private ClassFileLoader clzLoader = null; + + Map map = new HashMap(); + + private MethodArea() { + } + + public static MethodArea getInstance() { + return instance; + } + + public void setClassFileLoader(ClassFileLoader clzLoader) { + this.clzLoader = clzLoader; + } + + public Method getMainMethod(String className) { + + ClassFile clzFile = this.findClassFile(className); + + return clzFile.getMainMethod(); + } + + + public ClassFile findClassFile(String className){ + + if(map.get(className) != null){ + return map.get(className); + } + // 看来该class 文件还没有load过 + ClassFile clzFile = this.clzLoader.loadClass(className); + map.put(className, clzFile); + + return clzFile; + + } + + + public Method getMethod(String className, String methodName, String paramAndReturnType){ + ClassFile classFile = findClassFile(className); + Method method = classFile.getMethod(methodName, paramAndReturnType); + if (method == null) { + throw new RuntimeException("method "+methodName+ "can't found"); + } + return method; + } + + + public Method getMethod(MethodRefInfo methodRef){ + return getMethod(methodRef.getClassName(), + methodRef.getMethodName(), methodRef.getParamAndReturnType()); + } +} diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/MiniJVM.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/MiniJVM.java new file mode 100644 index 0000000000..164943f694 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/engine/MiniJVM.java @@ -0,0 +1,29 @@ +package com.coding.mini_jvm.src.com.coderising.jvm.engine; + +import com.coding.mini_jvm.src.com.coderising.jvm.loader.ClassFileLoader; + +import java.io.FileNotFoundException; +import java.io.IOException; + + +public class MiniJVM { + + public void run(String[] classPaths , String className) throws FileNotFoundException, IOException{ + + ClassFileLoader loader = new ClassFileLoader(); + for(int i=0;i localVariableTable = new ArrayList(); + private Stack oprandStack = new Stack(); + + int index = 0; + + private Method m = null; + + private StackFrame callerFrame = null; + + public StackFrame getCallerFrame() { + return callerFrame; + } + + public void setCallerFrame(StackFrame callerFrame) { + this.callerFrame = callerFrame; + } + + + public static StackFrame create(Method m) { + + StackFrame frame = new StackFrame(m); + + return frame; + } + + + private StackFrame(Method m) { + this.m = m; + + } + + + + public JavaObject getLocalVariableValue(int index){ + return this.localVariableTable.get(index); + } + + public Stack getOprandStack(){ + return this.oprandStack; + } + + public int getNextCommandIndex(int offset){ + + ByteCodeCommand[] cmds = m.getCodeAttr().getCmds(); + for(int i=0;i 0) { + ExecutionResult result = new ExecutionResult(); + + while (index < commands.length){ + ByteCodeCommand command = commands[index]; + System.out.println("\t " + command.toString(this.getMethod().getClzFile().getConstantPool())); + command.execute(this, result); + if (result.isPauseAndRunNewFrame()) { + index++; + return result; + } + else if (result.isExitCurrentFrame()) { + return result; + } + else if (result.isRunNextCmd()) { + index++; + } + else if (result.isJump()) { + int offset = result.getNextCmdOffset(); + index = this.getNextCommandIndex(offset); + } else { + index++; + } + } + return result; + } + ExecutionResult result = new ExecutionResult(); + result.setNextAction(ExecutionResult.EXIT_CURRENT_FRAME); + return result; + } + + + + + public void setLocalVariableTable(List values){ + this.localVariableTable = values; + } + + public void setLocalVariableValue(int index, JavaObject jo){ + //问题: 为什么要这么做?? + if(this.localVariableTable.size()-1 < index){ + for(int i=this.localVariableTable.size(); i<=index; i++){ + this.localVariableTable.add(null); + } + } + this.localVariableTable.set(index, jo); + + + } + + public Method getMethod(){ + return m; + } + + +} diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileLoader.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileLoader.java index 452f6bce7d..db2d2ff467 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileLoader.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/loader/ClassFileLoader.java @@ -2,10 +2,7 @@ import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; import java.util.List; @@ -13,9 +10,11 @@ public class ClassFileLoader { + private ClassLoader classLoader; + private static final String CLASS_FILE_SUFFIX = ".class"; - private List clzPaths = new ArrayList(); - + private static List clzPaths = new ArrayList(); + public byte[] readBinaryCode(String className) { String classPath = getClassPath(); String[] paths = classPath.split(File.pathSeparator); @@ -42,6 +41,7 @@ private byte[] loadClassFile(String clzFileName) { e.printStackTrace(); return null; } + } public void addClassPath(String path) { @@ -49,8 +49,10 @@ public void addClassPath(String path) { return; } clzPaths.add(path); + + } - + public String getClassPath(){ @@ -69,4 +71,38 @@ public ClassFile loadClass(String className) { ClassFileParser classFileParser = new ClassFileParser(); return classFileParser.parse(data); } + +// public static void main(String[] args) { +// +// +// System.out.println(System.getProperty("java.library.path")); +// System.out.println(System.getProperty("java.class.path")); +// System.out.println(System.getProperty("java.home")); +//// System.getProperty("java.class.path"); +//// System.getProperty("java.class.path"); +//// System.getProperty("java.class.path"); +//// System.getProperty("java.class.path"); +// +// } + + private class MyClassLoader extends ClassLoader { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + String filename = name.substring(name.lastIndexOf(".")+1) + ".class"; + try { + InputStream is = getClass().getResourceAsStream(filename); + if (is == null) { + return super.loadClass(name); + } + + byte[] b = new byte[is.available()]; + is.read(b); + return defineClass(name, b, 0, b.length); + } catch (IOException e) { + e.printStackTrace(); + } + + return super.loadClass(name); + } + } } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/method/Method.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/method/Method.java index b848e6b515..d00ec4ac1c 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/method/Method.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/method/Method.java @@ -4,8 +4,12 @@ import com.coding.mini_jvm.src.com.coderising.jvm.attr.CodeAttr; import com.coding.mini_jvm.src.com.coderising.jvm.clz.ClassFile; import com.coding.mini_jvm.src.com.coderising.jvm.cmd.ByteCodeCommand; +import com.coding.mini_jvm.src.com.coderising.jvm.constant.UTF8Info; import com.coding.mini_jvm.src.com.coderising.jvm.loader.ByteCodeIterator; +import java.util.ArrayList; +import java.util.List; + public class Method { private int accessFlag; @@ -66,4 +70,46 @@ public static Method parse(ClassFile clzFile, ByteCodeIterator iter){ public ByteCodeCommand[] getCmds() { return this.getCodeAttr().getCmds(); } + + public List getParameterList() { + String desc = clzFile.getConstantPool().getUTF8String(descriptorIndex); + int startIndex = desc.indexOf("(") + 1; + int endIndex = desc.lastIndexOf(")") ; + String paramStr = desc.substring(startIndex, endIndex); + List params = new ArrayList<>(); + if ("".equals(paramStr)) { + return params; + } + int pos = 0; + int length = paramStr.length(); + while (pos < length) { + if ('L' == paramStr.charAt(pos) || '['== paramStr.charAt(pos)) { + for (int i = pos; i < length; i++) { + if (paramStr.charAt(i) == ';') { + params.add(paramStr.substring(pos, i)); + pos = ++i; + break; + } + } + } else if ('I' == paramStr.charAt(pos)) { + params.add("int"); + pos++; + } else if ('F' == paramStr.charAt(pos)) { + params.add("float"); + pos++; + } else { + throw new RuntimeException("not impl param type ["+ paramStr.charAt(pos) +"] yet"); + } + } + return params; + } + + public boolean isStatic() { + return (accessFlag & 0x0004) != 0; + } + + public String getName() { + UTF8Info utf8Info = (UTF8Info)clzFile.getConstantPool().getConstantInfo(nameIndex); + return utf8Info.getValue(); + } } diff --git a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/print/SimpleVistor.java b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/print/SimpleVistor.java index e10e7885ba..96920a9c68 100644 --- a/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/print/SimpleVistor.java +++ b/group24/494800949/src/main/java/com/coding/mini_jvm/src/com/coderising/jvm/print/SimpleVistor.java @@ -10,47 +10,44 @@ public class SimpleVistor implements ConstantInfo.Visitor { private Formatter formatter = new Formatter(System.out); private String format = " = %-20s %-20s %-100s\n"; - private static final String HASH_KEY = "#"; - private static final String DOUBLE_SLASH = "// "; - private static final String DOT = "."; - private static final String COLON = ":"; @Override public void visitClassInfo(ClassInfo info) { formatter.format(format, "Class", - HASH_KEY + info.getUtf8Index(), - DOUBLE_SLASH + info.getClassName()); + "#" + info.getUtf8Index(), + "// " + info.getClassName()); } @Override public void visitFieldRef(FieldRefInfo info) { NameAndTypeInfo nameAndTypeInfo = (NameAndTypeInfo)info.getConstantInfo(info.getNameAndTypeIndex()); formatter.format(format, "Fieldref", - HASH_KEY + info.getClassInfoIndex() + DOT + HASH_KEY + info.getNameAndTypeIndex(), - DOUBLE_SLASH + info.getClassName() + DOT + nameAndTypeInfo.getName() + COLON + nameAndTypeInfo.getTypeInfo()); + "#" + info.getClassInfoIndex() + "." + "#" + info.getNameAndTypeIndex(), + "// " + info.getClassName() + "." + nameAndTypeInfo.getName() + ":" + nameAndTypeInfo.getTypeInfo()); } @Override public void visitMethodRef(MethodRefInfo info) { formatter.format(format, "Methodref", - HASH_KEY + info.getClassInfoIndex() + DOT + HASH_KEY + info.getNameAndTypeIndex(), - DOUBLE_SLASH + info.getClassName() + DOT + info.getMethodName()); + "#" + info.getClassInfoIndex() + "." + "#" + info.getNameAndTypeIndex(), + "// " + info.getClassName() + "." + info.getMethodName()); } @Override public void visitNameAndType(NameAndTypeInfo info) { formatter.format(format, "NameAndType", - HASH_KEY + info.getIndex1() + COLON + HASH_KEY + info.getIndex2(), - DOUBLE_SLASH + info.getName() + COLON + info.getTypeInfo()); + "#" + info.getIndex1() + ":" + "#" + info.getIndex2(), + "// " + info.getName() + ":" + info.getTypeInfo()); } @Override public void visitString(StringInfo info) { - formatter.format(format, "String", HASH_KEY + info.getIndex(), DOUBLE_SLASH + info.toString()); + formatter.format(format, "String", "#" + info.getIndex(), "// " + info.toString()); } @Override public void visistUTF8(UTF8Info info) { formatter.format(format, "Utf8", info.getValue(), ""); } + } diff --git a/group24/494800949/src/main/java/com/coding/week8/CircleQueue.java b/group24/494800949/src/main/java/com/coding/week8/CircleQueue.java new file mode 100644 index 0000000000..06f73cad5b --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/week8/CircleQueue.java @@ -0,0 +1,70 @@ +package com.coding.week8; + +/** + * 用数组实现循环队列 + * @author liuxin + * + * @param + */ +public class CircleQueue { + + private final static int DEFAULT_SIZE = 10; + + //用数组来保存循环队列的元素 + private Object[] elementData = new Object[DEFAULT_SIZE] ; + + private int size; + //队头 + private int front = 0; + //队尾 + private int rear = 0; + + public boolean isEmpty() { + return size == 0; + } + + public int size() { + return size; + } + + + + public void enQueue(E data) { + if (data == null) { + throw new IllegalArgumentException("data can't be null"); + } + elementData[rear] = data; + size++; + if ((rear = (rear + 1) % elementData.length) == front) { + doubleCapacity(); + } + } + + private void doubleCapacity() { + int oldCapacity = elementData.length; + int newCapacity = oldCapacity << 1; + Object[] elementDataNew = new Object[newCapacity]; + if (newCapacity < 0) { + throw new RuntimeException("capacitity is too big"); + } + System.arraycopy(elementData, rear, elementDataNew, 0, oldCapacity - rear ); + System.arraycopy(elementData, 0, elementDataNew, front, front ); + elementData = elementDataNew; + front = 0; + rear = oldCapacity; + } + + public E deQueue() { + if (size == 0) + return null; + @SuppressWarnings("unchecked") + E e = (E)elementData[front]; + //let gc work + elementData[front] = null; + //下标越界处理 + front = ++front % elementData.length; + size--; + return e; + } + +} diff --git a/group24/494800949/src/main/java/com/coding/week8/Josephus.java b/group24/494800949/src/main/java/com/coding/week8/Josephus.java new file mode 100644 index 0000000000..8b17a17ebb --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/week8/Josephus.java @@ -0,0 +1,41 @@ +package com.coding.week8; + +import java.util.ArrayList; +import java.util.List; + +/** + * 用Queue来实现Josephus问题 + * 在这个古老的问题当中, N个深陷绝境的人一致同意用这种方式减少生存人数: N个人围成一圈(位置记为0到N-1), 并且从第一个人报数, 报到M的人会被杀死, 直到最后一个人留下来 + * 该方法返回一个List, 包含了被杀死人的次序 + * @author liuxin + * + */ +public class Josephus { + + public static List execute(int n, int m){ + CircleQueue queue = new CircleQueue(); + for (int i = 0; i < n; i++) { + queue.enQueue(i); + } + List list = new ArrayList<>(); + int j = 1; + /* + 循环将队首的元素弹出, + 若j=m则当前元素放入集合,j=1 + 若j0) { + Integer r = queue.deQueue(); + if (j == m) { + list.add(r); + j = 1; + } else if (j < m) { + queue.enQueue(r); + j++; + } + } + return list; + } + + +} diff --git a/group24/494800949/src/main/java/com/coding/week8/QueueWithTwoStacks.java b/group24/494800949/src/main/java/com/coding/week8/QueueWithTwoStacks.java new file mode 100644 index 0000000000..fa30ad36f6 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/week8/QueueWithTwoStacks.java @@ -0,0 +1,58 @@ +package com.coding.week8; + +import java.util.Stack; + +/** + * 用两个栈来实现一个队列 + * @author liuxin + * + * @param + */ +public class QueueWithTwoStacks { + private Stack stack1; + private Stack stack2; + + + public QueueWithTwoStacks() { + stack1 = new Stack(); + stack2 = new Stack(); + } + + + + public boolean isEmpty() { + return stack1.isEmpty() && stack2.isEmpty(); + } + + + + public int size() { + return stack1.size() + stack2.size(); + } + + + + public void enQueue(E item) { + if(item == null){ + throw new RuntimeException("item cant be null"); + } + stack1.push(item); + } + + public E deQueue() { + if (isEmpty()) { + throw new RuntimeException("no data in queue"); + } + + if (stack2.isEmpty()) { + while (!stack1.isEmpty()) { + stack2.push(stack1.pop()); + } + } + return stack2.pop(); + } + + + + } + diff --git a/group24/494800949/src/main/java/com/coding/week9/QuickMinStack.java b/group24/494800949/src/main/java/com/coding/week9/QuickMinStack.java new file mode 100644 index 0000000000..7aea9e57be --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/week9/QuickMinStack.java @@ -0,0 +1,45 @@ +package com.coding.week9; + + +//import java.util.Stack; + + +import java.util.ArrayList; +import java.util.List; + +/** + * 设计一个栈,支持栈的push和pop操作,以及第三种操作findMin, 它返回改数据结构中的最小元素 + * finMin操作最坏的情形下时间复杂度应该是O(1) , 简单来讲,操作一次就可以得到最小值 + * @author liuxin + * + */ +public class QuickMinStack { + + List elements = new ArrayList<>(); + private int minNumIndex = 0; + + private boolean isSmaller(int data) { + if (elements.isEmpty()) { + return true; + } + if (data < elements.get(minNumIndex)) { + return true; + } + return false; + } + public void push(int data) { + elements.add(data); + if (isSmaller(data)) { + minNumIndex = elements.size() - 1; + } + + } + + public int pop() { + return elements.remove(elements.size() - 1); + } + + public int findMin() { + return elements.get(minNumIndex); + } +} diff --git a/group24/494800949/src/main/java/com/coding/week9/StackWithTwoQueues.java b/group24/494800949/src/main/java/com/coding/week9/StackWithTwoQueues.java new file mode 100644 index 0000000000..f55bad77ca --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/week9/StackWithTwoQueues.java @@ -0,0 +1,38 @@ +package com.coding.week9; + + +import com.coding.week8.CircleQueue; + +public class StackWithTwoQueues { + private CircleQueue queue1 = new CircleQueue<>(); + private CircleQueue queue2 = new CircleQueue<>(); + + public void push(int data) { + if (queue1.isEmpty()) { + queue1.enQueue(data); + } else { + queue2.enQueue(data); + } + } + + public int pop() { + if (queue1.isEmpty() && queue2.isEmpty()) { + throw new RuntimeException("stack is empty"); + } + if (queue2.isEmpty()) { + while (queue1.size() > 1) { + queue2.enQueue(queue1.deQueue()); + } + return queue1.deQueue(); + } else { + while (queue2.size() > 1) { + queue1.enQueue(queue2.deQueue()); + } + return queue2.deQueue(); + } + + + } + + +} diff --git a/group24/494800949/src/main/java/com/coding/week9/TwoStackInOneArray.java b/group24/494800949/src/main/java/com/coding/week9/TwoStackInOneArray.java new file mode 100644 index 0000000000..1d7d613452 --- /dev/null +++ b/group24/494800949/src/main/java/com/coding/week9/TwoStackInOneArray.java @@ -0,0 +1,102 @@ +package com.coding.week9; + +/** + * 用一个数组实现两个栈 + * 将数组的起始位置看作是第一个栈的栈底,将数组的尾部看作第二个栈的栈底,压栈时,栈顶指针分别向中间移动,直到两栈顶指针相遇,则扩容。 + * @author liuxin + * + */ +public class TwoStackInOneArray { + Object[] data = new Object[10]; + private int pos1 = 0; + private int pos2 = data.length - 1; + /** + * 向第一个栈中压入元素 + * @param o + */ + public void push1(Object o){ + if (o == null) { + throw new RuntimeException("data can not be null"); + } + data[pos1++] = o; + if (pos1 == pos2) { + doubleCapacity(); + } + } + + private void doubleCapacity(){ + int oldCapacity = data.length; + int newCapacity = oldCapacity << 1; + if (newCapacity < 0) { + throw new RuntimeException("capacity is too large"); + } + Object[] dataNew = new Object[newCapacity]; + System.arraycopy(data, 0, dataNew, 0, pos1); + int moveNum = oldCapacity - pos2; + int newPos2 = newCapacity - moveNum; + System.arraycopy(data, pos2, dataNew, newPos2, moveNum); + pos2 = newPos2; + data = dataNew; + } + + /** + * 从第一个栈中弹出元素 + * @return + */ + public Object pop1(){ + if (pos1 == 0) { + throw new RuntimeException("stack1 is empty"); + } + Object e = data[--pos1]; + data[pos1] = null; + return e; + } + + /** + * 获取第一个栈的栈顶元素 + * @return + */ + + public Object peek1(){ + if (pos1 == 0) { + return null; + } + return data[pos1 - 1]; + } + /* + * 向第二个栈压入元素 + */ + public void push2(Object o){ + if (o == null) { + throw new RuntimeException("data can not be null"); + } + data[pos2--] = o; + if (pos1 == pos2) { + doubleCapacity(); + } + } + /** + * 从第二个栈弹出元素 + * @return + */ + public Object pop2(){ + if (pos2 == data.length - 1) { + throw new RuntimeException("stack2 is empty"); + } + Object e = data[++pos2]; + data[pos2] = null; + return e; + } + /** + * 获取第二个栈的栈顶元素 + * @return + */ + + public Object peek2(){ + if (pos2 == data.length - 1) { + return null; + } + return data[pos2 + 1]; + } + +} diff --git a/group24/494800949/src/test/java/com/coding/mini_jvm/test/MiniJVMTest.java b/group24/494800949/src/test/java/com/coding/mini_jvm/test/MiniJVMTest.java new file mode 100644 index 0000000000..53694f30a4 --- /dev/null +++ b/group24/494800949/src/test/java/com/coding/mini_jvm/test/MiniJVMTest.java @@ -0,0 +1,32 @@ +package com.coding.mini_jvm.test; + +import com.coding.mini_jvm.src.com.coderising.jvm.engine.MiniJVM; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class MiniJVMTest { + + // static final String PATH = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\answer\\bin"; +// static String PATH = "H:\\sourceCode\\coding2017\\group24\\494800949"; + static String PATH = "H:\\sourceCode\\coding2017\\group24\\494800949\\build\\classes\\main"; + static String PATH1 = "D:\\Java\\jdk1.8.0_25\\lib\\rt.jar"; + static String PATH2 = "D:\\Java\\jdk1.8.0_25\\jre\\lib\\rt"; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testMain() throws Exception { + String[] classPaths = {PATH, PATH1, PATH2}; + MiniJVM jvm = new MiniJVM(); + jvm.run(classPaths, "com.coding.mini_jvm.src.com.coderising.jvm.EmployeeV1"); + + } + +} diff --git a/group24/494800949/src/test/java/com/coding/week8/CircleQueueTest.java b/group24/494800949/src/test/java/com/coding/week8/CircleQueueTest.java new file mode 100644 index 0000000000..239599e125 --- /dev/null +++ b/group24/494800949/src/test/java/com/coding/week8/CircleQueueTest.java @@ -0,0 +1,55 @@ +package com.coding.week8; + + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by Administrator on 2017/5/3 0003. + */ +public class CircleQueueTest { + private CircleQueue queue; + + @Before + public void setup(){ + queue = new CircleQueue<>(); + + } + @Test + public void testIsEmpty() throws Exception { + Assert.assertTrue(queue.isEmpty()); + queue.enQueue(10); + Assert.assertTrue(!queue.isEmpty()); + } + + @Test + public void testSize() throws Exception { + queue.enQueue(10); + queue.enQueue(2); + Assert.assertEquals(queue.size(), 2); + queue.deQueue(); + Assert.assertEquals(queue.size(), 1); + } + + @Test + public void testEnQueue() throws Exception { + for (int i = 0; i < 11; i++) { + queue.enQueue(i*i); + } + Assert.assertEquals((int)queue.deQueue(), 0); + Assert.assertEquals((int)queue.deQueue(), 1); + Assert.assertEquals((int)queue.deQueue(), 4); + Assert.assertEquals((int)queue.deQueue(), 9); + Assert.assertEquals((int)queue.deQueue(), 16); + Assert.assertEquals((int)queue.deQueue(), 25); + Assert.assertEquals((int)queue.deQueue(), 36); + Assert.assertEquals((int)queue.deQueue(), 49); + Assert.assertEquals((int)queue.deQueue(), 64); + Assert.assertEquals((int)queue.deQueue(), 81); + Assert.assertEquals((int)queue.deQueue(), 100); + Assert.assertEquals(queue.deQueue(), null); + } + + +} \ No newline at end of file diff --git a/group24/494800949/src/test/java/com/coding/week8/JosephusTest.java b/group24/494800949/src/test/java/com/coding/week8/JosephusTest.java new file mode 100644 index 0000000000..9fa029f027 --- /dev/null +++ b/group24/494800949/src/test/java/com/coding/week8/JosephusTest.java @@ -0,0 +1,27 @@ +package com.coding.week8; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class JosephusTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testExecute() { + + Assert.assertEquals("[1, 3, 5, 0, 4, 2, 6]", Josephus.execute(7, 2).toString()); + + } + +} diff --git a/group24/494800949/src/test/java/com/coding/week8/QueueWithTwoStacksTest.java b/group24/494800949/src/test/java/com/coding/week8/QueueWithTwoStacksTest.java new file mode 100644 index 0000000000..86ae2b57c9 --- /dev/null +++ b/group24/494800949/src/test/java/com/coding/week8/QueueWithTwoStacksTest.java @@ -0,0 +1,31 @@ +package com.coding.week8; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by Administrator on 2017/5/6 0006. + */ +public class QueueWithTwoStacksTest { + + private QueueWithTwoStacks queue; + + @Before + public void setup(){ + queue = new QueueWithTwoStacks<>(); + } + @Test + public void testEnQueue() throws Exception { + queue.enQueue(1); + queue.enQueue(5); + queue.enQueue(8); + + Assert.assertEquals((int) queue.deQueue(), 1); + queue.enQueue(10); + Assert.assertEquals((int) queue.deQueue(), 5); + Assert.assertEquals((int) queue.deQueue(), 8); + Assert.assertEquals((int)queue.deQueue(), 10); + + } +} \ No newline at end of file diff --git a/group24/494800949/src/test/java/com/coding/week9/QuickMinStackTest.java b/group24/494800949/src/test/java/com/coding/week9/QuickMinStackTest.java new file mode 100644 index 0000000000..a88ae6208f --- /dev/null +++ b/group24/494800949/src/test/java/com/coding/week9/QuickMinStackTest.java @@ -0,0 +1,20 @@ +package com.coding.week9; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by Administrator on 2017/5/7 0007. + */ +public class QuickMinStackTest { + + @Test + public void testFindMin() throws Exception { + QuickMinStack quickMinStack = new QuickMinStack(); + quickMinStack.push(10); + quickMinStack.push(9); + quickMinStack.push(100); + quickMinStack.push(19); + Assert.assertEquals(quickMinStack.findMin(), 9); + } +} \ No newline at end of file diff --git a/group24/494800949/src/test/java/com/coding/week9/StackWithTwoQueuesTest.java b/group24/494800949/src/test/java/com/coding/week9/StackWithTwoQueuesTest.java new file mode 100644 index 0000000000..0d7913883e --- /dev/null +++ b/group24/494800949/src/test/java/com/coding/week9/StackWithTwoQueuesTest.java @@ -0,0 +1,29 @@ +package com.coding.week9; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by Administrator on 2017/5/7 0007. + */ +public class StackWithTwoQueuesTest { + + + + + @Test + public void testPush() throws Exception { + StackWithTwoQueues stackWithTwoQueues = new StackWithTwoQueues(); + stackWithTwoQueues.push(1); + stackWithTwoQueues.push(2); + stackWithTwoQueues.push(3); + stackWithTwoQueues.push(4); + stackWithTwoQueues.push(5); + Assert.assertEquals(stackWithTwoQueues.pop(), 5); + Assert.assertEquals(stackWithTwoQueues.pop(), 4); + Assert.assertEquals(stackWithTwoQueues.pop(), 3); + Assert.assertEquals(stackWithTwoQueues.pop(), 2); + Assert.assertEquals(stackWithTwoQueues.pop(), 1); + } + +} \ No newline at end of file diff --git a/group24/494800949/src/test/java/com/coding/week9/TwoStackInOneArrayTest.java b/group24/494800949/src/test/java/com/coding/week9/TwoStackInOneArrayTest.java new file mode 100644 index 0000000000..b3481715ec --- /dev/null +++ b/group24/494800949/src/test/java/com/coding/week9/TwoStackInOneArrayTest.java @@ -0,0 +1,43 @@ +package com.coding.week9; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by Administrator on 2017/5/7 0007. + */ +public class TwoStackInOneArrayTest { + + private TwoStackInOneArray stackInOneArray; + + @Before + public void setup(){ + stackInOneArray = new TwoStackInOneArray(); + } + @Test + public void testPush1() throws Exception { + stackInOneArray.push1(10); + stackInOneArray.push1(20); + stackInOneArray.push1(30); + stackInOneArray.push1(88); + stackInOneArray.push1(30); + stackInOneArray.push1(99); + stackInOneArray.push2(100); + stackInOneArray.push2(90); + stackInOneArray.push2(80); + stackInOneArray.push2(77); + stackInOneArray.push2(66); + Assert.assertEquals(stackInOneArray.peek1(), 99); + Assert.assertEquals(stackInOneArray.pop1(), 99); + Assert.assertEquals(stackInOneArray.pop1(), 30); + + Assert.assertEquals(stackInOneArray.peek2(), 66); + Assert.assertEquals(stackInOneArray.pop2(), 66); + Assert.assertEquals(stackInOneArray.pop2(), 77); + Assert.assertEquals(stackInOneArray.pop2(), 80); + Assert.assertEquals(stackInOneArray.pop2(), 90); + } + + +} \ No newline at end of file