diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java new file mode 100644 index 0000000000..2a3f0e26d5 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTree.java @@ -0,0 +1,131 @@ +package com.github.miniyk2012.coding2017.basic.tree; + +import java.util.List; +import java.util.NoSuchElementException; + +public class BinarySearchTree { + + BinaryTreeNode root; + public BinarySearchTree(BinaryTreeNode root){ + this.root = root; + } + public BinaryTreeNode getRoot(){ + return root; + } + + public T findMin() { + if (root == null) { + throw new NoSuchElementException("根节点为空"); + } + + return findMin(root); + } + + private T findMin(BinaryTreeNode root) { + BinaryTreeNode p = root; + while (p.left!=null) { + p = p.left; + } + return p.getData(); + } + + public T findMax(){ + if (root == null) { + throw new NoSuchElementException("根节点为空"); + } + return findMax(root); + } + + private T findMax(BinaryTreeNode root) { + BinaryTreeNode p = root; + while (p.right!=null) { + p = p.right; + } + return p.getData(); + } + + public int height() { + if (root == null) { + return 0; + } + return getHeight(root); + } + + private int getHeight(BinaryTreeNode root) { + if (root == null) { + return 0; + } + int leftHeight = getHeight(root.left); + int rightHeight = getHeight(root.right); + return 1 + (leftHeight>rightHeight?leftHeight:rightHeight); + } + + public int size() { + if (root == null) { + return 0; + } + return getSize(root); + } + + private int getSize(BinaryTreeNode root) { + if (root == null) { + return 0; + } + int leftSize = getSize(root.left); + int rightSize = getSize(root.right); + return 1 + leftSize + rightSize; + } + public void remove(T e){ + if (root == null) { + throw new NoSuchElementException("根节点为空"); + } + root = remove(e, root); + } + + private BinaryTreeNode remove(T e, BinaryTreeNode root) { + if (root == null) { + throw new NoSuchElementException("不存在该元素,删除失败"); + } + int cmp = root.data.compareTo(e); + if (cmp == 0) { + if (root.left == null) { + return root.right; + } + if (root.right == null) { + return root.left; + } + T min = findMin(root.right); + root.data = min; + root.right = deleteMin(root.right); + } else if (cmp < 0) { + root.right = remove(e, root.right); + } else { + root.left = remove(e, root.left); + } + return root; + } + + private BinaryTreeNode deleteMin(BinaryTreeNode root) { + if (root.left == null) { + return root.right; + } + root.left = deleteMin(root.left); + return root; + } + + public List levelVisit(){ + + return null; + } + public boolean isValid(){ + return false; + } + public T getLowestCommonAncestor(T n1, T n2){ + return null; + + } + public List getNodesBetween(T n1, T n2){ + return null; + } +} + diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTreeTest.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTreeTest.java new file mode 100644 index 0000000000..127064a721 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinarySearchTreeTest.java @@ -0,0 +1,79 @@ +package com.github.miniyk2012.coding2017.basic.tree; + +import static org.junit.Assert.fail; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class BinarySearchTreeTest { + + BinarySearchTree tree = null; + + @Before + public void setUp() throws Exception { + BinaryTreeNode root = new BinaryTreeNode(6); + root.left = new BinaryTreeNode(2); + root.right = new BinaryTreeNode(8); + root.left.left = new BinaryTreeNode(1); + root.left.right = new BinaryTreeNode(4); + root.left.right.left = new BinaryTreeNode(3); + tree = new BinarySearchTree(root); + } + + @After + public void tearDown() throws Exception { + tree = null; + } + + @Test + public void testFindMin() { + Assert.assertEquals(1, tree.findMin().intValue()); + + } + + @Test + public void testFindMax() { + Assert.assertEquals(8, tree.findMax().intValue()); + } + + @Test + public void testHeight() { + Assert.assertEquals(4, tree.height()); + } + + @Test + public void testSize() { + Assert.assertEquals(6, tree.size()); + } + + @Test + public void testRemoveLeaf() { + tree.remove(4); + BinaryTreeNode root= tree.getRoot(); + Assert.assertEquals(3, root.left.right.data.intValue()); + + } + @Test + public void testRemoveMiddleNode() { + tree.remove(2); + BinaryTreeNode root= tree.getRoot(); + Assert.assertEquals(3, root.left.data.intValue()); + Assert.assertEquals(4, root.left.right.data.intValue()); + } + + @Test + public void testRemoveRoot() { + tree.remove(6); + BinaryTreeNode root= tree.getRoot(); + Assert.assertEquals(8, root.data.intValue()); + Assert.assertEquals(2, root.left.data.intValue()); + Assert.assertNull(root.right); + Assert.assertEquals(3, root.left.right.left.data.intValue()); + + } + +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeNode.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeNode.java new file mode 100644 index 0000000000..82e3957e7f --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeNode.java @@ -0,0 +1,35 @@ +package com.github.miniyk2012.coding2017.basic.tree; + +public class BinaryTreeNode { + + protected T data; + protected BinaryTreeNode left; + protected BinaryTreeNode right; + + public BinaryTreeNode(T data){ + this.data=data; + } + public T getData() { + return data; + } + public void setData(T data) { + this.data = data; + } + public BinaryTreeNode getLeft() { + return left; + } + public void setLeft(BinaryTreeNode left) { + this.left = left; + } + public BinaryTreeNode getRight() { + return right; + } + public void setRight(BinaryTreeNode right) { + this.right = right; + } + + public BinaryTreeNode insert(Object o){ + return null; + } + +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtil.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtil.java new file mode 100644 index 0000000000..184936cde8 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtil.java @@ -0,0 +1,119 @@ +package com.github.miniyk2012.coding2017.basic.tree; + + +import java.util.*; + +public class BinaryTreeUtil { + /** + * 用递归的方式实现对二叉树的前序遍历, 需要通过BinaryTreeUtilTest测试 + * 先访问root,再访问左子树,再访问右子树 + * @param root + * @return + */ + public static List preOrderVisit(BinaryTreeNode root) { + List result = new ArrayList<>(); + if (root == null) { + return result; + } + result.add(root.getData()); + BinaryTreeNode leftTreeNode = root.getLeft(); + result.addAll(preOrderVisit(leftTreeNode)); + BinaryTreeNode rightTreeNode = root.getRight(); + result.addAll(preOrderVisit(rightTreeNode)); + return result; + } + + /** + * 用递归的方式实现对二叉树的中遍历 + * 先左后根再右 + * @param root + * @return + */ + public static List inOrderVisit(BinaryTreeNode root) { + List result = new ArrayList<>(); + if (root == null) { + return result; + } + BinaryTreeNode leftTreeNode = root.getLeft(); + result.addAll(inOrderVisit(leftTreeNode)); + result.add(root.getData()); + BinaryTreeNode rightTreeNode = root.getRight(); + result.addAll(inOrderVisit(rightTreeNode)); + return result; + } + + /** + * 用递归的方式实现对二叉树的后遍历 + * 左右根 + * @param root + * @return + */ + public static List postOrderVisit(BinaryTreeNode root) { + List result = new ArrayList<>(); + if (root == null) { + return result; + } + BinaryTreeNode leftTreeNode = root.getLeft(); + result.addAll(postOrderVisit(leftTreeNode)); + BinaryTreeNode rightTreeNode = root.getRight(); + result.addAll(postOrderVisit(rightTreeNode)); + result.add(root.getData()); + return result; + } + /** + * 用非递归的方式实现对二叉树的前序遍历 + * @param root + * @return + */ + public static List preOrderWithoutRecursion(BinaryTreeNode root) { + + List result = new ArrayList(); + Stack> stack = new Stack<>(); // 存放接下来要访问的节点 + if (root == null) { + return result; + } + stack.push(root); + while(!stack.isEmpty()) { + BinaryTreeNode top = stack.pop(); + result.add(top.getData()); + if (top.getRight() != null) { + stack.add(top.getRight()); + } + if (top.getLeft() != null) { + stack.add(top.getLeft()); + } + } + return result; + } + /** + * 用非递归的方式实现对二叉树的中序遍历 + * 先左后根再右 + * @param root + * @return + */ + public static List inOrderWithoutRecursion(BinaryTreeNode root) { + + List result = new ArrayList(); + if (root == null) { + return result; + } + Stack> stack = new Stack<>(); + stack.push(root); + BinaryTreeNode top = stack.peek(); + while (!stack.isEmpty()) { + if (top.getLeft() != null) { + stack.push(top.getLeft()); + top = top.getLeft(); + } else { + top = stack.pop(); + result.add(top.getData()); + if (top.getRight() != null) { + stack.push(top.getRight()); + top = top.getRight(); + } + } + } + return result; + } + +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtilTest.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtilTest.java new file mode 100644 index 0000000000..09137b0cfb --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/BinaryTreeUtilTest.java @@ -0,0 +1,75 @@ +package com.github.miniyk2012.coding2017.basic.tree; + +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class BinaryTreeUtilTest { + + BinaryTreeNode root = null; + @Before + public void setUp() throws Exception { + root = new BinaryTreeNode(1); + root.setLeft(new BinaryTreeNode(2)); + root.setRight(new BinaryTreeNode(5)); + root.getLeft().setLeft(new BinaryTreeNode(3)); + root.getLeft().setRight(new BinaryTreeNode(4)); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testPreOrderVisit() { + + List result = BinaryTreeUtil.preOrderVisit(root); + Assert.assertEquals("[1, 2, 3, 4, 5]", result.toString()); + + + } + @Test + public void testInOrderVisit() { + + + List result = BinaryTreeUtil.inOrderVisit(root); + Assert.assertEquals("[3, 2, 4, 1, 5]", result.toString()); + + } + + @Test + public void testPostOrderVisit() { + + + List result = BinaryTreeUtil.postOrderVisit(root); + Assert.assertEquals("[3, 4, 2, 5, 1]", result.toString()); + + } + + + @Test + public void testInOrderVisitWithoutRecursion() { + BinaryTreeNode node = root.getLeft().getRight(); + node.setLeft(new BinaryTreeNode(6)); + node.setRight(new BinaryTreeNode(7)); + + List result = BinaryTreeUtil.inOrderWithoutRecursion(root); + Assert.assertEquals("[3, 2, 6, 4, 7, 1, 5]", result.toString()); + + } + @Test + public void testPreOrderVisitWithoutRecursion() { + BinaryTreeNode node = root.getLeft().getRight(); + node.setLeft(new BinaryTreeNode(6)); + node.setRight(new BinaryTreeNode(7)); + + List result = BinaryTreeUtil.preOrderWithoutRecursion(root); + Assert.assertEquals("[1, 2, 3, 4, 6, 7, 5]", result.toString()); + + } +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java new file mode 100644 index 0000000000..c2422df4cd --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/basic/tree/FileList.java @@ -0,0 +1,42 @@ +package com.github.miniyk2012.coding2017.basic.tree; + +import java.io.File; +import java.io.FileNotFoundException; + +public class FileList { + public void list(File f) throws FileNotFoundException { + if (!f.exists()) { + throw new FileNotFoundException("该文件不存在"); + } + list(f, 0); + } + + private void list(File f, int depth) { + printName(f, depth); + if (f.isDirectory()) { + for (File subFile: f.listFiles()) { + list(subFile, depth+1); + } + } + } + + private void printName(File f, int depth) { + String name = f.getName(); + for (int i=0; i stack = new Stack(); + + public ExecutorEngine() { + + } + + public void execute(Method mainMethod){ + + + + } + + + + private void setupFunctionCallParams(StackFrame currentFrame,StackFrame nextFrame) { + + + + } + +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/Heap.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/Heap.java new file mode 100644 index 0000000000..3e346a1a6d --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/Heap.java @@ -0,0 +1,39 @@ +package com.github.miniyk2012.coding2017.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/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/JavaObject.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/JavaObject.java new file mode 100644 index 0000000000..aaf606464b --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/JavaObject.java @@ -0,0 +1,71 @@ +package com.github.miniyk2012.coding2017.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/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MethodArea.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MethodArea.java new file mode 100644 index 0000000000..dded057e1d --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MethodArea.java @@ -0,0 +1,68 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.engine; + +import java.util.HashMap; +import java.util.Map; + +import com.github.miniyk2012.coding2017.coderising.jvm.clz.ClassFile; +import com.github.miniyk2012.coding2017.coderising.jvm.constant.MethodRefInfo; +import com.github.miniyk2012.coding2017.coderising.jvm.loader.ClassFileLoader; +import com.github.miniyk2012.coding2017.coderising.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/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MiniJVM.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MiniJVM.java new file mode 100644 index 0000000000..fa88ff2235 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/engine/MiniJVM.java @@ -0,0 +1,28 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.engine; +import java.io.FileNotFoundException; +import java.io.IOException; + +import com.github.miniyk2012.coding2017.coderising.jvm.loader.ClassFileLoader; + + +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/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/field/Field.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/field/Field.java index 7507e0a2af..f65d0f0f74 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/field/Field.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/field/Field.java @@ -5,11 +5,20 @@ import com.github.miniyk2012.coding2017.coderising.jvm.constant.UTF8Info; import com.github.miniyk2012.coding2017.coderising.jvm.loader.ByteCodeIterator; +import java.util.HashMap; +import java.util.Map; + public class Field { private int accessFlag; private int nameIndex; private int descriptorIndex; private ConstantPool pool; + + private static Map flagNameMap = new HashMap<>(); + { + flagNameMap.put(0x0001, "public-ACC_PUBLIC"); + flagNameMap.put(0x0002, "private-ACC_PRIVATE"); + } public Field(int accessFlag, int nameIndex, int descriptorIndex, ConstantPool pool) { @@ -27,7 +36,21 @@ public String toString() { String desc = pool.getUTF8String(descriptorIndex); return name +":"+ desc; } - + + public String getAccessFlagDescription() { + String accessFlag = flagNameMap.get(this.accessFlag); + // TODO: 6/5/2017 访问标志补全 + if (accessFlag == null) throw new RuntimeException("访问标志还未实现"); + return accessFlag; + } + + public String getType() { + return pool.getUTF8String(descriptorIndex); + } + + public String getName() { + return pool.getUTF8String(nameIndex); + } public static Field parse(ConstantPool pool, ByteCodeIterator iter){ diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java index b2887df85e..687e031280 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ClassFilePrinter.java @@ -23,9 +23,20 @@ public void print(){ System.out.println("major version:" + clzFile.getMinorVersion()); ConstantPoolPrinter cnstPoolPrinter = new ConstantPoolPrinter(clzFile.getConstantPool()); - cnstPoolPrinter.print(); - - } + cnstPoolPrinter.print(); // 打印常量池 + + System.out.println("{\n"); + + FieldPrinter fieldPrinter = new FieldPrinter(clzFile); + fieldPrinter.print(); // 打印字段 + + + MethodPrinter methodPrinter = new MethodPrinter(clzFile); + methodPrinter.print(); // 打印方法 + + System.out.println("}"); + + } public static void main(String[] args){ String path = ClassFilePrinter.class.getClassLoader().getResource("jvm").getPath(); diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java index f3c164be13..7a27464830 100644 --- a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/ConstantPoolPrinter.java @@ -1,7 +1,9 @@ package com.github.miniyk2012.coding2017.coderising.jvm.print; -import com.github.miniyk2012.coding2017.coderising.jvm.constant.ConstantPool; +import com.github.miniyk2012.coding2017.coderising.jvm.clz.ClassFile; +import com.github.miniyk2012.coding2017.coderising.jvm.constant.*; +import com.github.miniyk2012.coding2017.coderising.jvm.loader.ClassFileLoader; public class ConstantPoolPrinter { ConstantPool pool; @@ -10,9 +12,74 @@ public class ConstantPoolPrinter { } public void print(){ - // todo: 实现javap System.out.println("Constant Pool:"); - - + Visitor visitor = new Visitor(); + for (int i=1; i<=pool.getSize(); i++) { + System.out.printf(" #"+(i)+" = "); + ConstantInfo constantInfo = pool.getConstantInfo(i); + try { + constantInfo.accept(visitor); + } catch (Exception e) { + } + System.out.printf("\n"); + } } + + public static class Visitor { + public void visitClassInfo(ClassInfo classInfo) { + System.out.printf("CLASS #" + classInfo.getUtf8Index()+" "); + System.out.printf("// "+classInfo.getClassName()); + } + public void visitFieldRefInfo(FieldRefInfo fieldRefInfo) { + System.out.printf("Fieldref #" + + fieldRefInfo.getClassInfoIndex() + ".#" + + fieldRefInfo.getNameAndTypeIndex() + + " "); + System.out.printf("// "+fieldRefInfo.getClassName()+ + "."+fieldRefInfo.getFieldName()+ + ":"+fieldRefInfo.getFieldType() + ); + } + public void visitMethodRefInfo(MethodRefInfo methodRefInfo) { + System.out.printf("Methodref #" + + methodRefInfo.getClassInfoIndex()+".#" + + methodRefInfo.getNameAndTypeIndex() + + " "); + System.out.printf("// "+methodRefInfo.getClassName()+"."+ + methodRefInfo.getMethodName()+":"+ + methodRefInfo.getParamAndReturnType() + ); + } + public void visitNameAndTypeInfo(NameAndTypeInfo nameAndTypeInfo) { + System.out.printf("NameAndType #" + + nameAndTypeInfo.getIndex1()+":#" + + nameAndTypeInfo.getIndex2() + + " "); + System.out.printf("// "+nameAndTypeInfo.getName()+":"+nameAndTypeInfo.getTypeInfo()); + + } + public void visitNullConstantInfo(NullConstantInfo nullConstantInfo) { + // 啥事都不干 + } + public void visitStringInfo(StringInfo stringInfo) { + System.out.printf("String #" + + stringInfo.getIndex() + + " "); + System.out.printf("// "+stringInfo.toString()); + } + public void visitUTF8Info(UTF8Info utf8Info) { + System.out.printf("Utf8 "+utf8Info.getValue()); + } + } + + public static void main(String[] args) { + String path = ClassFilePrinter.class.getClassLoader().getResource("jvm").getPath(); + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path); + String className = "com.github.miniyk2012.coding2017.jvm.test.EmployeeV1"; + + ClassFile clzFile = loader.loadClass(className); + ConstantPoolPrinter poolPrinter = new ConstantPoolPrinter(clzFile.getConstantPool()); + poolPrinter.print(); + } } diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/FieldPrinter.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/FieldPrinter.java new file mode 100644 index 0000000000..c77aa48fef --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/FieldPrinter.java @@ -0,0 +1,44 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.print; + +import com.github.miniyk2012.coding2017.coderising.jvm.clz.ClassFile; +import com.github.miniyk2012.coding2017.coderising.jvm.field.Field; +import com.github.miniyk2012.coding2017.coderising.jvm.loader.ClassFileLoader; + +/** + * Created by thomas_young on 6/5/2017. + */ +public class FieldPrinter { + + private ClassFile classFile; + FieldPrinter(ClassFile classFile) { + this.classFile = classFile; + } + + public void print() { + for (Field field: classFile.getFields()) { + printSingleField(field); + System.out.println(); + } + } + + private void printSingleField(Field field) { + String accessFlag = field.getAccessFlagDescription(); + String type = field.getType(); + String name = field.getName(); + System.out.println(" " + accessFlag.split("-")[0] + " " + type.replace("/", ".") + " " + name + ";"); + System.out.println(" descriptor: " + type); + System.out.println(" flags: " + accessFlag.split("-")[1]); + } + + public static void main(String[] args) { + String path = ClassFilePrinter.class.getClassLoader().getResource("jvm").getPath(); + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path); + String className = "com.github.miniyk2012.coding2017.jvm.test.EmployeeV1"; + + ClassFile clzFile = loader.loadClass(className); + FieldPrinter fdPrinter = new FieldPrinter(clzFile); + fdPrinter.print(); + } +} + diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/MethodPrinter.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/MethodPrinter.java new file mode 100644 index 0000000000..9661bffe20 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/MethodPrinter.java @@ -0,0 +1,17 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.print; + +import com.github.miniyk2012.coding2017.coderising.jvm.clz.ClassFile; + +/** + * Created by thomas_young on 6/5/2017. + */ +public class MethodPrinter { + private ClassFile classFile; + MethodPrinter(ClassFile classFile) { + this.classFile = classFile; + } + + public void print() { + + } +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/Visitable.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/Visitable.java new file mode 100644 index 0000000000..3c8b8017db --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/print/Visitable.java @@ -0,0 +1,8 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.print; + +/** + * Created by thomas_young on 6/5/2017. + */ +public interface Visitable { + public void accept(ConstantPoolPrinter.Visitor visitor); +} diff --git a/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/test/MiniJVMTest.java b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/test/MiniJVMTest.java new file mode 100644 index 0000000000..f05f973294 --- /dev/null +++ b/group02/812350401/src/main/java/com/github/miniyk2012/coding2017/coderising/jvm/test/MiniJVMTest.java @@ -0,0 +1,28 @@ +package com.github.miniyk2012.coding2017.coderising.jvm.test; + +import com.github.miniyk2012.coding2017.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"; + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testMain() throws Exception{ + String[] classPaths = {PATH}; + MiniJVM jvm = new MiniJVM(); + jvm.run(classPaths, "com.coderising.jvm.test.EmployeeV1"); + + } + +} diff --git a/group02/812350401/src/main/resources/jvm/com/github/miniyk2012/coding2017/jvm/test/EmployeeV2.class b/group02/812350401/src/main/resources/jvm/com/github/miniyk2012/coding2017/jvm/test/EmployeeV2.class new file mode 100644 index 0000000000..67ff119a68 Binary files /dev/null and b/group02/812350401/src/main/resources/jvm/com/github/miniyk2012/coding2017/jvm/test/EmployeeV2.class differ diff --git a/group02/812350401/src/main/resources/jvm/com/github/miniyk2012/coding2017/jvm/test/HourlyEmployee.class b/group02/812350401/src/main/resources/jvm/com/github/miniyk2012/coding2017/jvm/test/HourlyEmployee.class new file mode 100644 index 0000000000..db50d6c35f Binary files /dev/null and b/group02/812350401/src/main/resources/jvm/com/github/miniyk2012/coding2017/jvm/test/HourlyEmployee.class differ