From 628d189aee35bf4c13b9127a49c4503cfcdf6769 Mon Sep 17 00:00:00 2001 From: wdn <626451284@163.com> Date: Sun, 7 May 2017 00:07:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0QuickMinStack=E3=80=81StackWi?= =?UTF-8?q?thTwoQueues=E3=80=81TwoStackInOneArray?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coding2017/basic/stack/QuickMinStack.java | 60 ++++++++++++ .../basic/stack/StackWithTwoQueues.java | 57 +++++++++++ .../basic/stack/TwoStackInOneArray.java | 73 ++++++++++++++ .../wdn/coding2017/jvm/clz/ClassFile.java | 4 + .../jvm/engine/ExecutionResult.java | 57 +++++++++++ .../coding2017/jvm/engine/ExecutorEngine.java | 35 +++++++ .../wdn/coding2017/jvm/engine/Heap.java | 39 ++++++++ .../wdn/coding2017/jvm/engine/JavaObject.java | 71 ++++++++++++++ .../wdn/coding2017/jvm/engine/MethodArea.java | 68 +++++++++++++ .../wdn/coding2017/jvm/engine/MiniJVM.java | 29 ++++++ .../wdn/coding2017/jvm/engine/StackFrame.java | 96 +++++++++++++++++++ .../wdn/coding2017/jvm/method/Method.java | 15 +-- 12 files changed, 597 insertions(+), 7 deletions(-) create mode 100644 group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/QuickMinStack.java create mode 100644 group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/StackWithTwoQueues.java create mode 100644 group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/TwoStackInOneArray.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/ExecutionResult.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/ExecutorEngine.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/Heap.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/JavaObject.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/MethodArea.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/MiniJVM.java create mode 100644 group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/StackFrame.java diff --git a/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/QuickMinStack.java b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/QuickMinStack.java new file mode 100644 index 0000000000..642a75c90a --- /dev/null +++ b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/QuickMinStack.java @@ -0,0 +1,60 @@ +package com.github.wdn.coding2017.basic.stack; + +import java.util.*; + +/** + * 设计一个栈,支持栈的push和pop操作,以及第三种操作findMin, 它返回改数据结构中的最小元素 + * finMin操作最坏的情形下时间复杂度应该是O(1) , 简单来讲,操作一次就可以得到最小值 + * Created by Administrator on 2017/5/6 0006. + */ +public class QuickMinStack { + private Stack stack = new Stack<>(); + private Map minIndexMap = new HashMap<>(); + private List minIndexs = new ArrayList<>(); + + public static void main(String[] args) { + QuickMinStack quickMinStack = new QuickMinStack(); + //int[] ints = {5,4,3,2,1,0}; + int[] ints = {4,1,2,5,3,0}; + for (int i = 0; i < ints.length; i++) { + quickMinStack.push(ints[i]); + } + quickMinStack.status(); + while (!quickMinStack.isEmpty()){ + System.out.print("min:"+quickMinStack.findMin()); + System.out.println(" pop:"+quickMinStack.pop()); + } + } + public void push(E data){ + stack.push(data); + if(minIndexs.size()==0){ + minIndexMap.put(0,data); + minIndexs.add(0); + }else { + if(findMin().compareTo(data)>0){ + minIndexMap.put(stack.size()-1,data); + minIndexs.add(stack.size()-1); + } + } + } + public E pop(){ + E min = findMin(); + E result = stack.peek(); + if(min==result){ + minIndexMap.remove(minIndexs.get(minIndexs.size()-1)); + minIndexs.remove(minIndexs.size()-1); + } + return stack.pop(); + } + public E findMin(){ + return minIndexMap.get(minIndexs.get(minIndexs.size()-1)); + } + public boolean isEmpty(){ + return stack.isEmpty(); + } + public void status(){ + System.out.println(stack); + System.out.println(minIndexs); + System.out.println(minIndexMap); + } +} diff --git a/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/StackWithTwoQueues.java b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/StackWithTwoQueues.java new file mode 100644 index 0000000000..0a7fe2176c --- /dev/null +++ b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/StackWithTwoQueues.java @@ -0,0 +1,57 @@ +package com.github.wdn.coding2017.basic.stack; + + +import com.github.wdn.coding2017.basic.Queue; + +/** + * Created by Administrator on 2017/5/6 0006. + */ +public class StackWithTwoQueues { + Queue queue1 = new Queue(); + Queue queue2 = new Queue(); + + public static void main(String[] args) { + StackWithTwoQueues stack = new StackWithTwoQueues<>(); + for (int i = 0; i < 5; i++) { + stack.push(i); + } + for (int i = 0; i < 3; i++) { + System.out.println(stack.pop()); + } + System.out.println(""); + for (int i = 0; i < 5; i++) { + stack.push(i); + } + while (!stack.isEmpty()) { + System.out.println(stack.pop()); + } + } + public void push(E data){ + if(queue1.isEmpty()){ + queue2.enQueue(data); + }else{ + queue1.enQueue(data); + } + } + public E pop(){ + if(isEmpty()){ + throw new RuntimeException("stack is empty"); + } + if(queue1.isEmpty()){ + int len = queue2.size(); + for (int i = 0; i < len-1; i++) { + queue1.enQueue(queue2.deQueue()); + } + return (E)queue2.deQueue(); + }else{ + int len = queue1.size(); + for (int i = 0; i < len-1; i++) { + queue2.enQueue(queue1.deQueue()); + } + return (E)queue1.deQueue(); + } + } + public boolean isEmpty(){ + return queue1.isEmpty() && queue2.isEmpty(); + } +} diff --git a/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/TwoStackInOneArray.java b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/TwoStackInOneArray.java new file mode 100644 index 0000000000..935611d9c8 --- /dev/null +++ b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/TwoStackInOneArray.java @@ -0,0 +1,73 @@ +package com.github.wdn.coding2017.basic.stack; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * 用一个数组实现两个栈 + * 将数组的起始位置看作是第一个栈的栈底,将数组的尾部看作第二个栈的栈底, + * 压栈时,栈顶指针分别向中间移动,直到两栈顶指针相遇,则扩容。 + * Created by Administrator on 2017/5/6 0006. + */ +public class TwoStackInOneArray { + private Object[] ints = new Object[10]; + private int head1 = -1; + private int head2 = ints.length; + + public static void main(String[] args) { + TwoStackInOneArray stack = new TwoStackInOneArray(); + for (int i = 11; i > 0; i--) { + stack.push2(i); + } + for (int i = 0; i < 8; i++) { + stack.push1(i); + } + stack.pop1(); + for (int i = 0; i < 4; i++) { + stack.push1(i); + } + + System.out.println(Arrays.toString(stack.ints)); + } + public void push1(Object data){ + if(head1+1=0 && ints[head2-1]==null){ + ints[--head2] = data; + }else{ + grow(); + ints[--head2] = data; + } + } + public Object pop1(){ + if(head1<0){ + throw new RuntimeException("stack1 is empty"); + } + Object result = ints[head1]; + ints[head1] = null; + head1--; + return result; + } + public Object pop2(){ + if(head2>=ints.length){ + throw new RuntimeException("stack2 is empty"); + } + Object result = ints[head2]; + ints[head2] = null; + head2++; + return result; + } + public void grow(){ + Object[] newArr = new Object[ints.length * 2]; + System.arraycopy(ints,0,newArr,0,head1+1); + System.arraycopy(ints, head2, newArr, newArr.length-(ints.length-head2), ints.length-head2); + head2 = newArr.length-(ints.length-head2); + ints = newArr; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java index 564078a52e..a9a58d375a 100644 --- a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java @@ -79,4 +79,8 @@ public List getMethods() { public void setMethods(List methods) { this.methods = methods; } + + public Method getMainMethod() { + return null; + } } diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/ExecutionResult.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/ExecutionResult.java new file mode 100644 index 0000000000..0637b52f78 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/ExecutionResult.java @@ -0,0 +1,57 @@ +package com.github.wdn.coding2017.jvm.engine; + + +import com.github.wdn.coding2017.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/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/ExecutorEngine.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/ExecutorEngine.java new file mode 100644 index 0000000000..51feb78e2e --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/ExecutorEngine.java @@ -0,0 +1,35 @@ +package com.github.wdn.coding2017.jvm.engine; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +import com.github.wdn.coding2017.jvm.attr.CodeAttr; +import com.github.wdn.coding2017.jvm.clz.ClassFile; +import com.github.wdn.coding2017.jvm.cmd.ByteCodeCommand; +import com.github.wdn.coding2017.jvm.constant.MethodRefInfo; +import com.github.wdn.coding2017.jvm.method.Method; + +public class ExecutorEngine { + + private Stack stack = new Stack(); + + public ExecutorEngine() { + + } + + public void execute(Method mainMethod){ + + + + } + + + + private void setupFunctionCallParams(StackFrame currentFrame,StackFrame nextFrame) { + + + + } + +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/Heap.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/Heap.java new file mode 100644 index 0000000000..5fb9effe59 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/Heap.java @@ -0,0 +1,39 @@ +package com.github.wdn.coding2017.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/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/JavaObject.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/JavaObject.java new file mode 100644 index 0000000000..43c9e3130e --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/JavaObject.java @@ -0,0 +1,71 @@ +package com.github.wdn.coding2017.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/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/MethodArea.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/MethodArea.java new file mode 100644 index 0000000000..7c3a85e80d --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/MethodArea.java @@ -0,0 +1,68 @@ +package com.github.wdn.coding2017.jvm.engine; + +import java.util.HashMap; +import java.util.Map; + +import com.github.wdn.coding2017.jvm.clz.ClassFile; +import com.github.wdn.coding2017.jvm.constant.MethodRefInfo; +import com.github.wdn.coding2017.jvm.loader.ClassFileLoader; +import com.github.wdn.coding2017.jvm.method.Method; + +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){ + + return null; + } + + + public Method getMethod(MethodRefInfo methodRef){ + + return null; + + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/MiniJVM.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/MiniJVM.java new file mode 100644 index 0000000000..148dfdedb5 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/engine/MiniJVM.java @@ -0,0 +1,29 @@ +package com.github.wdn.coding2017.jvm.engine; +import com.github.wdn.coding2017.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 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/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/method/Method.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/method/Method.java index 0c0551b227..a741c83142 100644 --- a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/method/Method.java +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/method/Method.java @@ -15,7 +15,7 @@ public class Method { private AccessFlag accessFlags; private int nameIndex; private int descriptorIndex; - private CodeAttr code; + private CodeAttr codeAttr; //attributes[attributes_count]; private ConstantPool pool; public static Method parse(ClassFile clzFile, ByteCodeIterator iter) { @@ -30,7 +30,7 @@ public static Method parse(ClassFile clzFile, ByteCodeIterator iter) { methodAttributeType = Util.hexString2String(methodAttributeType); iter.back(2); if (methodAttributeType.equals(AttributeInfo.CODE)) { - method.setCode(CodeAttr.parse(clzFile,iter)); + method.setCodeAttr(CodeAttr.parse(clzFile,iter)); } else { throw new RuntimeException("未知的方法属性类型" + methodAttributeType); } @@ -42,7 +42,7 @@ public String toString(){ StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(pool.getConstantInfo(nameIndex).getValue()); stringBuffer.append(pool.getConstantInfo(descriptorIndex).getValue()); - stringBuffer.append(code); + stringBuffer.append(codeAttr); return stringBuffer.toString(); } public AccessFlag getAccessFlags() { @@ -69,15 +69,16 @@ public void setDescriptorIndex(int descriptorIndex) { this.descriptorIndex = descriptorIndex; } - public CodeAttr getCode() { - return code; + public CodeAttr getCodeAttr() { + return codeAttr; } - public void setCode(CodeAttr code) { - this.code = code; + public void setCodeAttr(CodeAttr codeAttr) { + this.codeAttr = codeAttr; } public void setPool(ConstantPool pool) { this.pool = pool; } + }