diff --git a/.gitignore b/.gitignore
index 156b10d1f1..6988a7c6d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -215,7 +215,7 @@ pip-log.txt
#Mr Developer
.mr.developer.cfg
-.gitignore
+#.gitignore
=======
@@ -235,7 +235,7 @@ hs_err_pid*
.recommenders
-*.xml
+#*.xml
*.iml
.idea
*.iml
@@ -248,7 +248,7 @@ rebel-remote.xml
.metadata
target
-*.class
+#*.class
log
*.log
@@ -257,7 +257,7 @@ tmp
.metadata
RemoteSystemsTempFiles
-.gitignore
+#.gitignore
.recommenders
.idea/
diff --git a/group24/75939388/.gitignore b/group24/75939388/.gitignore
new file mode 100644
index 0000000000..596bd7346d
--- /dev/null
+++ b/group24/75939388/.gitignore
@@ -0,0 +1,4 @@
+*.class
+target/
+*.iml
+.idea/
\ No newline at end of file
diff --git a/group24/75939388/learning2017/pom.xml b/group24/75939388/learning2017/pom.xml
new file mode 100644
index 0000000000..ebdd03610c
--- /dev/null
+++ b/group24/75939388/learning2017/pom.xml
@@ -0,0 +1,100 @@
+
+
+ 4.0.0
+
+ tee.w
+ learning2017
+ 1.0
+ learning2017
+ pom
+
+ https://github.com/macvis/coding2017
+ 码农翻身
+
+
+
+ TerrenceWen
+ https://github.com/macvis/
+ macvis@126.com
+
+
+
+
+
+
+ aliyun
+ aliyun
+ http://maven.aliyun.com/nexus/content/groups/public
+
+ true
+ never
+
+
+ false
+
+
+
+
+
+
+ aliyun
+ aliyun
+ http://maven.aliyun.com/nexus/content/groups/public
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+ junit
+ junit
+ 4.12
+
+
+
+
+ dom4j
+ dom4j
+ 1.6.1
+
+
+
+
+ jaxen
+ jaxen
+ 1.1.6
+
+
+
+
+ commons-io
+ commons-io
+ 2.5
+
+
+ org.apache.commons
+ commons-lang3
+ 3.5
+
+
+ commons-codec
+ commons-codec
+ 1.10
+
+
+ org.apache.commons
+ commons-collections4
+ 4.1
+
+
+
+
\ No newline at end of file
diff --git a/group24/75939388/learning2017/resources/classes/miniJVM/EmployeeV1 verbose.txt b/group24/75939388/learning2017/resources/classes/miniJVM/EmployeeV1 verbose.txt
new file mode 100644
index 0000000000..b161a0cd6e
--- /dev/null
+++ b/group24/75939388/learning2017/resources/classes/miniJVM/EmployeeV1 verbose.txt
@@ -0,0 +1,164 @@
+youchaowendeMacBook-Pro:Downloads Tee$ javap -verbose EmployeeV1.class
+Classfile /Users/Tee/Downloads/EmployeeV1.class
+ Last modified 2017-4-27; size 1056 bytes
+ MD5 checksum 8454b8999ccc9a2ae26a405d47558825
+ Compiled from "EmployeeV1.java"
+public class com.coderising.jvm.test.EmployeeV1
+ minor version: 0
+ major version: 52
+ flags: ACC_PUBLIC, ACC_SUPER
+Constant pool:
+ #1 = Class #2 // com/coderising/jvm/test/EmployeeV1
+ #2 = Utf8 com/coderising/jvm/test/EmployeeV1
+ #3 = Class #4 // java/lang/Object
+ #4 = Utf8 java/lang/Object
+ #5 = Utf8 name
+ #6 = Utf8 Ljava/lang/String;
+ #7 = Utf8 age
+ #8 = Utf8 I
+ #9 = Utf8
+ #10 = Utf8 (Ljava/lang/String;I)V
+ #11 = Utf8 Code
+ #12 = Methodref #3.#13 // java/lang/Object."":()V
+ #13 = NameAndType #9:#14 // "":()V
+ #14 = Utf8 ()V
+ #15 = Fieldref #1.#16 // com/coderising/jvm/test/EmployeeV1.name:Ljava/lang/String;
+ #16 = NameAndType #5:#6 // name:Ljava/lang/String;
+ #17 = Fieldref #1.#18 // com/coderising/jvm/test/EmployeeV1.age:I
+ #18 = NameAndType #7:#8 // age:I
+ #19 = Utf8 LineNumberTable
+ #20 = Utf8 LocalVariableTable
+ #21 = Utf8 this
+ #22 = Utf8 Lcom/coderising/jvm/test/EmployeeV1;
+ #23 = Utf8 setName
+ #24 = Utf8 (Ljava/lang/String;)V
+ #25 = Utf8 setAge
+ #26 = Utf8 (I)V
+ #27 = Utf8 sayHello
+ #28 = Fieldref #29.#31 // java/lang/System.out:Ljava/io/PrintStream;
+ #29 = Class #30 // java/lang/System
+ #30 = Utf8 java/lang/System
+ #31 = NameAndType #32:#33 // out:Ljava/io/PrintStream;
+ #32 = Utf8 out
+ #33 = Utf8 Ljava/io/PrintStream;
+ #34 = String #35 // Hello , this is class Employee
+ #35 = Utf8 Hello , this is class Employee
+ #36 = Methodref #37.#39 // java/io/PrintStream.println:(Ljava/lang/String;)V
+ #37 = Class #38 // java/io/PrintStream
+ #38 = Utf8 java/io/PrintStream
+ #39 = NameAndType #40:#24 // println:(Ljava/lang/String;)V
+ #40 = Utf8 println
+ #41 = Utf8 main
+ #42 = Utf8 ([Ljava/lang/String;)V
+ #43 = String #44 // Andy
+ #44 = Utf8 Andy
+ #45 = Methodref #1.#46 // com/coderising/jvm/test/EmployeeV1."":(Ljava/lang/String;I)V
+ #46 = NameAndType #9:#10 // "":(Ljava/lang/String;I)V
+ #47 = Methodref #1.#48 // com/coderising/jvm/test/EmployeeV1.sayHello:()V
+ #48 = NameAndType #27:#14 // sayHello:()V
+ #49 = Utf8 args
+ #50 = Utf8 [Ljava/lang/String;
+ #51 = Utf8 p
+ #52 = Utf8 SourceFile
+ #53 = Utf8 EmployeeV1.java
+{
+ public com.coderising.jvm.test.EmployeeV1(java.lang.String, int);
+ descriptor: (Ljava/lang/String;I)V
+ flags: ACC_PUBLIC
+ Code:
+ stack=2, locals=3, args_size=3
+ 0: aload_0
+ 1: invokespecial #12 // Method java/lang/Object."":()V
+ 4: aload_0
+ 5: aload_1
+ 6: putfield #15 // Field name:Ljava/lang/String;
+ 9: aload_0
+ 10: iload_2
+ 11: putfield #17 // Field age:I
+ 14: return
+ LineNumberTable:
+ line 9: 0
+ line 10: 4
+ line 11: 9
+ line 12: 14
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 15 0 this Lcom/coderising/jvm/test/EmployeeV1;
+ 0 15 1 name Ljava/lang/String;
+ 0 15 2 age I
+
+ public void setName(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ 0: aload_0
+ 1: aload_1
+ 2: putfield #15 // Field name:Ljava/lang/String;
+ 5: return
+ LineNumberTable:
+ line 15: 0
+ line 16: 5
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/coderising/jvm/test/EmployeeV1;
+ 0 6 1 name Ljava/lang/String;
+
+ public void setAge(int);
+ descriptor: (I)V
+ flags: ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ 0: aload_0
+ 1: iload_1
+ 2: putfield #17 // Field age:I
+ 5: return
+ LineNumberTable:
+ line 18: 0
+ line 19: 5
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/coderising/jvm/test/EmployeeV1;
+ 0 6 1 age I
+
+ public void sayHello();
+ descriptor: ()V
+ flags: ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ 0: getstatic #28 // Field java/lang/System.out:Ljava/io/PrintStream;
+ 3: ldc #34 // String Hello , this is class Employee
+ 5: invokevirtual #36 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
+ 8: return
+ LineNumberTable:
+ line 21: 0
+ line 22: 8
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 9 0 this Lcom/coderising/jvm/test/EmployeeV1;
+
+ public static void main(java.lang.String[]);
+ descriptor: ([Ljava/lang/String;)V
+ flags: ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=2, args_size=1
+ 0: new #1 // class com/coderising/jvm/test/EmployeeV1
+ 3: dup
+ 4: ldc #43 // String Andy
+ 6: bipush 29
+ 8: invokespecial #45 // Method "":(Ljava/lang/String;I)V
+ 11: astore_1
+ 12: aload_1
+ 13: invokevirtual #47 // Method sayHello:()V
+ 16: return
+ LineNumberTable:
+ line 24: 0
+ line 25: 12
+ line 27: 16
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 17 0 args [Ljava/lang/String;
+ 12 5 1 p Lcom/coderising/jvm/test/EmployeeV1;
+}
+SourceFile: "EmployeeV1.java"
+youchaowendeMacBook-Pro:Downloads Tee$
\ No newline at end of file
diff --git a/group24/75939388/learning2017/resources/classes/miniJVM/EmployeeV1.class b/group24/75939388/learning2017/resources/classes/miniJVM/EmployeeV1.class
new file mode 100644
index 0000000000..c6c3c4a415
Binary files /dev/null and b/group24/75939388/learning2017/resources/classes/miniJVM/EmployeeV1.class differ
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayList.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/array/ArrayList.java
similarity index 97%
rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayList.java
rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/array/ArrayList.java
index 8ae862da33..246641cb4a 100644
--- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/ArrayList.java
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/array/ArrayList.java
@@ -1,4 +1,6 @@
-package basic.dataStructure;
+package basic.dataStructure.array;
+
+import basic.dataStructure.List;
/**
* Created by macvi on 2017/4/2.
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LRUPageFrame.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LRUPageFrame.java
new file mode 100644
index 0000000000..8746fc44a0
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LRUPageFrame.java
@@ -0,0 +1,163 @@
+package basic.dataStructure.linkedList;
+
+/**
+ * @author : 温友朝
+ */
+public class LRUPageFrame {
+ private static class Node {
+
+ Node prev;
+ Node next;
+ int pageNum;
+
+ Node() {}
+
+ Node(Node prev, Node next, int pageNum){
+ this.prev = prev;
+ this.next = next;
+ this.pageNum = pageNum;
+ }
+ }
+
+ private int capacity;
+
+ private int currentSize;
+ private Node first;// 链表头
+ private Node last;// 链表尾
+
+
+ public LRUPageFrame(int capacity) {
+ this.currentSize = 0;
+ this.capacity = capacity;
+ }
+
+ /**
+ * 获取缓存中对象
+ *
+ * @param pageNum
+ */
+ public void access(int pageNum){
+ if(first == null){
+ last = first = new Node(null, null, pageNum);
+ this.currentSize++;
+ return;
+ }
+
+ if(first.pageNum == pageNum){
+ return;
+ }
+
+ if(currentSize < capacity){
+ addToFirst(pageNum);
+ this.currentSize ++;
+ }else{
+ //遍历
+ boolean flag = false;
+ for(int i = 0; i < capacity; i++){
+ if(get(i) == pageNum){
+ flag = true;
+ break;
+ }
+ }
+
+ //有相同的,交换该数据至栈顶
+ if(flag){
+ this.moveToFirst(pageNum);
+ }else{
+ //没有相同的,移除栈底元素
+ removeLast();
+ //添加
+ addToFirst(pageNum);
+ }
+ }
+ }
+
+ /**
+ * 新增至栈底
+ * @param pageNum
+ */
+ private void addToLast(int pageNum){
+ Node node = new Node(last, null, pageNum);
+ last.next = node;
+ this.last = node;
+ this.currentSize++;
+ }
+
+ /**
+ * 新增值栈顶
+ * @param pageNum
+ */
+ private void addToFirst(int pageNum){
+ Node node = new Node(null, first, pageNum);
+ first.prev = node;
+ this.first = node;
+ this.currentSize++;
+ }
+
+ /**
+ * 移除栈底的元素
+ */
+ public void removeLast(){
+ Node node = last.prev;
+ node.next = null;
+ this.last = node;
+ this.currentSize--;
+ }
+
+ /**
+ * 从栈底数起,取数
+ */
+ public int get(int index){
+ int in = 0;
+ Node temp = last;
+ int res = -1;
+ while (temp != null){
+ if(index == in){
+ res = temp.pageNum;
+ }
+ in++;
+ temp = temp.prev;
+ }
+
+ return res;
+ }
+
+ public void moveToFirst(int pageNum){
+ Node temp = last;
+ while (temp != null){
+ if(temp.pageNum == pageNum){
+ break;
+ }
+ temp = temp.prev;
+ }
+
+ //处理节点,任意位置时重组链接
+ if(temp.next != null){
+ temp.prev.next = temp.next;
+ temp.next.prev = temp.prev;
+ }else{
+ //栈底remove调
+ removeLast();
+ }
+
+ addToFirst(pageNum);
+ }
+
+ public int size(){
+ return this.currentSize;
+ }
+
+ public String toString(){
+ StringBuilder buffer = new StringBuilder();
+ Node node = first;
+ while(node != null){
+ buffer.append(node.pageNum);
+
+ node = node.next;
+ if(node != null){
+ buffer.append(",");
+ }
+ }
+ return buffer.toString();
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LinkedList.java
similarity index 97%
rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java
rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LinkedList.java
index 3ac85ad37b..aa19b4cef5 100644
--- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/LinkedList.java
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/linkedList/LinkedList.java
@@ -1,4 +1,8 @@
-package basic.dataStructure;
+package basic.dataStructure.linkedList;
+
+import basic.dataStructure.ArrayUtil;
+import basic.dataStructure.List;
+import basic.dataStructure.array.ArrayList;
/**
* Created by macvi on 2017/4/3.
@@ -169,7 +173,7 @@ public void reverse(){
/**
* 删除一个单链表的前半部分
- * 例如:list = 2->5->7->8 , 删除以后的值为 7->8
+ * 例如:array = 2->5->7->8 , 删除以后的值为 7->8
* 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
*/
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/Queue.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/queue/Queue.java
similarity index 97%
rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/Queue.java
rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/queue/Queue.java
index 36ca7e9647..5096f9297c 100644
--- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/Queue.java
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/queue/Queue.java
@@ -1,4 +1,4 @@
-package basic.dataStructure;
+package basic.dataStructure.queue;
/**
* Created by macvi on 2017/4/4.
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/Stack.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/Stack.java
similarity index 60%
rename from group24/75939388/learning2017/src/main/java/basic/dataStructure/Stack.java
rename to group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/Stack.java
index bea16033fa..ea83d96e2b 100644
--- a/group24/75939388/learning2017/src/main/java/basic/dataStructure/Stack.java
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/Stack.java
@@ -1,4 +1,6 @@
-package basic.dataStructure;
+package basic.dataStructure.stack;
+
+import basic.dataStructure.array.ArrayList;
/**
* Created by macvi on 2017/4/4.
@@ -7,6 +9,14 @@ public class Stack {
private ArrayList elementData = new ArrayList();
+ public Stack(){}
+
+ public Stack(Object...objs){
+ for(int i = 0; i < objs.length; i++){
+ this.push(objs[i]);
+ }
+ }
+
public void push(Object o){
this.elementData.add(o);
}
@@ -20,7 +30,7 @@ public Object pop(){
public Object peek(){
int index = elementData.size() - 1;
- return elementData.get(index);
+ return index == -1 ? null : elementData.get(index);
}
public boolean isEmpty(){
return peek() == null;
@@ -33,7 +43,11 @@ public int size(){
public String toString() {
StringBuffer sb = new StringBuffer();
for(int i = this.size() - 1; i >= 0; i--){
- sb.append(elementData.get(i).toString()).append(",");
+ if(i != 0){
+ sb.append(elementData.get(i).toString()).append(",");
+ }else{
+ sb.append(elementData.get(i).toString());
+ }
}
return sb.toString();
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/StackUtil.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/StackUtil.java
new file mode 100644
index 0000000000..1d55a2d47e
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/StackUtil.java
@@ -0,0 +1,105 @@
+package basic.dataStructure.stack;
+
+public class StackUtil {
+
+
+
+ /**
+ * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5
+ * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助
+ */
+ public static Stack reverse(Stack s) {
+ Stack st = new Stack();
+ int size = s.size();
+ for(int i = 0; i < size; i++){
+ st.push(s.pop());
+ }
+ return st;
+ }
+
+ /**
+ * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助
+ *
+ * @param o
+ */
+ public static Stack remove(Stack s,Object o) {
+ Stack tmp = new Stack();
+ int size = s.size();
+ for(int i = 0; i < size; i++){
+ Object obj = s.peek();
+ if(obj != o && !obj.equals(o)){
+ tmp.push(s.pop());
+ }else{
+ s.pop();
+ }
+ }
+ return tmp;
+ }
+
+ /**
+ * 从栈顶取得len个元素, 原来的栈中元素保持不变
+ * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助
+ * @param len
+ * @return
+ */
+ public static Object[] getTop(Stack s,int len) {
+ Stack temp = new Stack();
+ int size = s.size();
+ Object[] objs = new Object[len];
+ for(int i = 0; i < size; i++){
+ Object obj = s.pop();
+ if(i < len){
+ objs[i] = obj;
+ }
+ temp.push(obj);
+ }
+
+ for(int i = 0 ; i < size; i ++){
+ s.push(temp.pop());
+ }
+
+ return objs;
+ }
+ /**
+ * 字符串s 可能包含这些字符: ( ) [ ] { }, a,b,c... x,yz
+ * 使用堆栈检查字符串s中的括号是不是成对出现的。
+ * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现, 该方法返回true
+ * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的, 该方法返回false;
+ * @param s
+ * @return
+ */
+ public static boolean isValidPairs(String s){
+ //括号
+ Stack bracket = new Stack(")", "(");
+
+ //方括号
+ Stack brackets = new Stack("]", "[");
+
+ //花括号
+ Stack braces = new Stack("}", "{");
+
+ char[] symArr = s.toCharArray();
+ int length = symArr.length;
+ for(int i = 0; i < length/2; i++){
+ String sym = String.valueOf(symArr[i]);
+ String endSym = String.valueOf(symArr[length - i -1]);
+ if(sym.equals(bracket.peek())){
+ bracket = remove(bracket, sym);
+ bracket = remove(bracket, endSym);
+ }
+
+ if(sym.equals(brackets.peek())){
+ brackets = remove(brackets, sym);
+ brackets = remove(brackets, endSym);
+ }
+
+ if(sym.equals(braces.peek())){
+ braces = remove(braces, sym);
+ braces = remove(braces, endSym);
+ }
+ }
+ return bracket.isEmpty() && brackets.isEmpty() && braces.isEmpty();
+ }
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/Calculator.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/Calculator.java
new file mode 100644
index 0000000000..fe6510b532
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/Calculator.java
@@ -0,0 +1,23 @@
+package basic.dataStructure.stack.expr;
+
+/**
+ * @author : 温友朝
+ * @date : 2017/4/27
+ */
+public class Calculator {
+ public static float getFloat(float val1, float val2, String oper) {
+ float res = 0l;
+ if (oper.equals("*")) {
+ res = val1 * val2;
+ } else if (oper.equals("+")) {
+ res = val1 + val2;
+ } else if (oper.equals("-")) {
+ res = val1 - val2;
+ } else {
+ if (val2 == 0) throw new RuntimeException("cannot divide 0, calculation canceled");
+ res = val1 / val2;
+ }
+// System.out.println("计算结果: " + val1 + oper + val2 + "=" + res);
+ return res;
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/InfixExpr.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/InfixExpr.java
new file mode 100644
index 0000000000..c31fe35737
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/InfixExpr.java
@@ -0,0 +1,65 @@
+package basic.dataStructure.stack.expr;
+
+import basic.dataStructure.stack.Stack;
+
+import java.util.List;
+
+public class InfixExpr {
+ String expr = null;
+
+ public InfixExpr(String expr) {
+ this.expr = expr;
+ }
+
+ public float evaluate() {
+ List tokens = TokenParser.parse(expr);
+ Stack numbers = new Stack();
+ Stack operators = new Stack();
+
+ int temp = 0;
+
+ for (Token token : tokens) {
+ if (token.isOperator()) {
+ operators.push(token);
+ }
+
+ if (token.isNumber()) {
+ numbers.push(token);
+ }
+
+ //先计算
+ int opeSize = operators.size();
+ int numSize = numbers.size();
+
+ float val1 = ((Token) numbers.pop()).getFloatValue();
+ float val2 = ((Token) numbers.pop()).getFloatValue();
+ if (numSize == 3 && opeSize == 2) {
+ Token tmp = (Token) operators.pop();
+ if (tmp.hasHigherPriority((Token) operators.peek())) {
+ //如果1+2*3,先计算numbers后两位
+ numbers.push(new Token(Token.NUMBER, Calculator.getFloat(val1, val2, tmp.toString()) + ""));
+ } else {
+ //如果1*2+3,先计算numbers栈前两位
+ //先保存数字和运算符
+ Token sNum = (Token) numbers.pop();
+ Token sOper = tmp;
+
+ //需要进行计算的运算符
+ Token oper = (Token) operators.pop();
+ numbers.push(new Token(Token.NUMBER, Calculator.getFloat(val1, val2, oper.toString()) + ""));
+ numbers.push(new Token(Token.NUMBER, sNum + ""));
+ operators.push(new Token(Token.OPERATOR, sOper.toString()));
+ }
+ }
+ }
+
+ if (numbers.size() == 2 && operators.size() == 1) {
+ float val1 = ((Token) numbers.pop()).getFloatValue();
+ float val2 = ((Token) numbers.pop()).getFloatValue();
+ return Calculator.getFloat(val1, val2, (operators.pop()).toString());
+ } else {
+ throw new RuntimeException("last calculation exception, numbers.size=" + numbers.size() + ", operators.size=" + operators.size());
+ }
+ }
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/InfixToPostfix.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/InfixToPostfix.java
new file mode 100644
index 0000000000..b5b9552013
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/InfixToPostfix.java
@@ -0,0 +1,73 @@
+package basic.dataStructure.stack.expr;
+
+import basic.dataStructure.stack.Stack;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 中序转后序
+ */
+public class InfixToPostfix {
+
+ public static List convert(String expr) {
+ List postfixTokenList = new ArrayList();
+
+ List original = TokenParser.parse(expr);
+ Stack buffer = new Stack();
+ for(Token t : original){
+ //数字直接放入结果
+ if(t.isNumber()) postfixTokenList.add(t);
+
+ //左括号,放入缓存
+ if(t.isLBracket()) buffer.push(t);
+
+ //右括号, 遍历完成后不用放入结果集
+ if(t.isRBracket()){
+ if(buffer.size() == 0){
+ throw new RuntimeException("brackets are not in pair, check your expression");
+ }else{
+ //遍历直至左括号
+ Token tmp = (Token) buffer.peek();
+ while (!tmp.isLBracket()){
+ if(buffer.size() == 1 && !tmp.isLBracket()) throw new RuntimeException("brackets are not in pair, check your expression");
+ //放入结果list
+ postfixTokenList.add((Token) buffer.pop());
+ tmp = (Token)buffer.peek();
+ }
+ }
+ }
+
+ //处理运算符,若缓存栈顶的运算符优先级高于或等于该运算符时,则进行遍历:
+ //缓存中找出的运算符直接入结果list,遍历完成后当前运算符压进缓存栈中
+ if(t.isOperator()){
+ Token tmp = (Token) buffer.peek();
+ while(tmp != null && tmp.isOperator() && tmp.hasHigherPriority(t)){
+ //弹出至结果list
+ postfixTokenList.add((Token) buffer.pop());
+ tmp = (Token) buffer.peek();
+ }
+ buffer.push(t);
+ }
+ }
+
+ //遍历完成后,若缓存还有值,则直接放到结果集,并去掉左括号
+ while (buffer.size() > 0){
+ Token t = (Token) buffer.pop();
+ if(!t.isBracket()){
+ postfixTokenList.add(t);
+ }
+ }
+
+ return postfixTokenList;
+ }
+
+
+ public static void main(String[] args) {
+// convert("9+(3-1)*3+10/2");
+ List list = convert("1+(2+3*4-5)/2+10-1");
+ System.out.println(list.toString());
+// convert("2+3*4-5");
+ }
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/PostfixExpr.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/PostfixExpr.java
new file mode 100644
index 0000000000..cfbd67c5bf
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/PostfixExpr.java
@@ -0,0 +1,43 @@
+package basic.dataStructure.stack.expr;
+
+import basic.dataStructure.stack.Stack;
+
+import java.util.List;
+
+/**
+ * 后序表达式
+ */
+public class PostfixExpr {
+ String expr = null;
+
+ /**
+ * 23*21-/341-*+
+ */
+ public PostfixExpr(String expr) {
+ this.expr = expr;
+ }
+
+ public float evaluate() {
+ List tokens = TokenParser.parse(expr);
+
+ Stack numbers = new Stack();
+ Stack opers = new Stack();
+
+ for(Token t : tokens){
+ if(t.isNumber()) numbers.push(t);
+ if(t.isOperator()) opers.push(t);
+
+ if(opers.size() == 1){
+ float num1 = ((Token)numbers.pop()).getFloatValue();
+ float num2 = ((Token)numbers.pop()).getFloatValue();
+ String oper = (opers.pop()).toString();
+ float res = Calculator.getFloat(num1, num2, oper);
+ numbers.push(new Token(Token.NUMBER, res + ""));
+ }
+ }
+
+ return ((Token) numbers.pop()).getFloatValue();
+ }
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/PrefixExpr.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/PrefixExpr.java
new file mode 100644
index 0000000000..0f85c42f47
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/PrefixExpr.java
@@ -0,0 +1,22 @@
+package basic.dataStructure.stack.expr;
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 前序表达式
+ */
+public class PrefixExpr {
+ String expr = null;
+
+ /**
+ * +/*23-21*3-41
+ * @param expr
+ */
+ public PrefixExpr(String expr) {
+ this.expr = expr;
+ }
+
+ public float evaluate() {
+ return new PostfixExpr(StringUtils.reverse(expr)).evaluate();
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/Token.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/Token.java
new file mode 100644
index 0000000000..0c105d76a4
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/Token.java
@@ -0,0 +1,69 @@
+package basic.dataStructure.stack.expr;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Token {
+ public static final List OPERATORS = Arrays.asList("+", "-", "*", "/");
+ private static final Map priorities = new HashMap();
+ static {
+ priorities.put("+", 1);
+ priorities.put("-", 1);
+ priorities.put("*", 2);
+ priorities.put("/", 2);
+ }
+ static final int OPERATOR = 1;
+ static final int NUMBER = 2;
+ static final int LBRACKET = -1;
+ static final int RBRACKET = -2;
+ String value;
+ int type;
+ public Token(int type, String value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ public boolean isNumber() {
+ return type == NUMBER;
+ }
+
+ public boolean isOperator() {
+ return type == OPERATOR;
+ }
+
+ public boolean isLBracket(){
+ return type == LBRACKET;
+ }
+
+ public boolean isRBracket(){
+ return type == RBRACKET;
+ }
+
+ public boolean isBracket(){
+ return type == LBRACKET || type == RBRACKET;
+ }
+
+ public int getIntValue() {
+ return Integer.valueOf(value).intValue();
+ }
+
+ public float getFloatValue(){
+ return Float.valueOf(value).floatValue();
+ }
+
+ public String toString(){
+ return value;
+ }
+
+ public boolean hasHigherPriority(Token t){
+ if(!this.isOperator() && !t.isOperator()){
+ throw new RuntimeException("numbers can't compare priority");
+ }
+ return priorities.get(this.value) - priorities.get(t.value) > 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/TokenParser.java b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/TokenParser.java
new file mode 100644
index 0000000000..0f3169c27e
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/basic/dataStructure/stack/expr/TokenParser.java
@@ -0,0 +1,74 @@
+package basic.dataStructure.stack.expr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TokenParser {
+
+
+ public static List parse(String expr) {
+ List tokens = new ArrayList();
+
+ int i = 0;
+
+ while (i < expr.length()) {
+
+ char c = expr.charAt(i);
+
+ if (isOperator(c)) {
+
+ Token t = new Token(Token.OPERATOR, String.valueOf(c));
+ tokens.add(t);
+ i++;
+
+ } else if (Character.isDigit(c)) {
+
+ int nextOperatorIndex = indexOfNextOperator(i, expr);
+ String value = expr.substring(i, nextOperatorIndex);
+ Token t = new Token(Token.NUMBER, value);
+ tokens.add(t);
+ i = nextOperatorIndex;
+
+ } else if (isLeftBracket(String.valueOf(c))) {
+ Token t = new Token(Token.LBRACKET, String.valueOf(c));
+ tokens.add(t);
+ i++;
+ } else if (isRightBracket(String.valueOf(c))) {
+ Token t = new Token(Token.RBRACKET, String.valueOf(c));
+ tokens.add(t);
+ i++;
+ } else {
+ System.out.println("char :[" + c + "] is not number or operator,ignore");
+ i++;
+ }
+
+ }
+ return tokens;
+ }
+
+ private static int indexOfNextOperator(int i, String expr) {
+
+ while (Character.isDigit(expr.charAt(i))) {
+ i++;
+ if (i == expr.length()) {
+ break;
+ }
+ }
+ return i;
+
+ }
+
+ private static boolean isOperator(char c) {
+ String sc = String.valueOf(c);
+ return Token.OPERATORS.contains(sc);
+ }
+
+ private static boolean isLeftBracket(String s) {
+ return s.equals("(");
+ }
+
+ private static boolean isRightBracket(String s) {
+ return s.equals(")");
+ }
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/Demo.java b/group24/75939388/learning2017/src/main/java/miniJVM/Demo.java
deleted file mode 100644
index 565983ab06..0000000000
--- a/group24/75939388/learning2017/src/main/java/miniJVM/Demo.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package miniJVM;
-
-/**
- * Created by macvi on 2017/4/11.
- */
-public class Demo {
-}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/attr/AttributeInfo.java b/group24/75939388/learning2017/src/main/java/miniJVM/attr/AttributeInfo.java
new file mode 100644
index 0000000000..a35c1bc7e1
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/attr/AttributeInfo.java
@@ -0,0 +1,19 @@
+package miniJVM.attr;
+
+public abstract class AttributeInfo {
+ public static final String CODE = "Code";
+ public static final String CONST_VALUE = "ConstantValue";
+ public static final String EXCEPTIONS = "Exceptions";
+ public static final String LINE_NUM_TABLE = "LineNumberTable";
+ public static final String LOCAL_VAR_TABLE = "LocalVariableTable";
+ public static final String STACK_MAP_TABLE = "StackMapTable";
+ int attrNameIndex;
+ int attrLen ;
+ public AttributeInfo(int attrNameIndex, int attrLen) {
+
+ this.attrNameIndex = attrNameIndex;
+ this.attrLen = attrLen;
+ }
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/attr/CodeAttr.java b/group24/75939388/learning2017/src/main/java/miniJVM/attr/CodeAttr.java
new file mode 100644
index 0000000000..9c6147cdb4
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/attr/CodeAttr.java
@@ -0,0 +1,71 @@
+package miniJVM.attr;
+
+import miniJVM.clz.ClassFile;
+import miniJVM.cmd.ByteCodeCommand;
+import miniJVM.cmd.CommandParser;
+import miniJVM.constant.ConstantPool;
+import miniJVM.loader.ByteCodeIterator;
+
+public class CodeAttr extends AttributeInfo {
+ private int maxStack ;
+ private int maxLocals ;
+ private int codeLen ;
+ private String code;
+ public String getCode() {
+ return code;
+ }
+
+ private ByteCodeCommand[] cmds ;
+ public ByteCodeCommand[] getCmds() {
+ return cmds;
+ }
+ private LineNumberTable lineNumTable;
+ private LocalVariableTable localVarTable;
+ private StackMapTable stackMapTable;
+
+ public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code, ByteCodeCommand[] cmds) {
+ super(attrNameIndex, attrLen);
+ this.maxStack = maxStack;
+ this.maxLocals = maxLocals;
+ this.codeLen = codeLen;
+ this.code = code;
+ this.cmds = cmds;
+ }
+
+ public void setLineNumberTable(LineNumberTable t) {
+ this.lineNumTable = t;
+ }
+
+ public void setLocalVariableTable(LocalVariableTable t) {
+ this.localVarTable = t;
+ }
+
+ public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){
+ int attributeNameIndex = iter.nextU2ToInt();
+ int attributeLength = iter.nextU4ToInt();
+ int maxStack = iter.nextU2ToInt();
+ int maxLocals = iter.nextU2ToInt();
+ int codeLength = iter.nextU4ToInt();
+ String cmdCodes = iter.nextUxToHexString(codeLength);
+ ByteCodeCommand[] cmds = CommandParser.parse(clzFile, cmdCodes);
+
+ return new CodeAttr(attributeNameIndex, attributeLength, maxStack, maxLocals, codeLength, cmdCodes, cmds);
+ }
+
+ public String toString(ConstantPool pool){
+ StringBuilder buffer = new StringBuilder();
+ //buffer.append("Code:").append(code).append("\n");
+ for(int i=0;i items = new ArrayList();
+
+ private static class LineNumberItem{
+ int startPC;
+ int lineNum;
+ public LineNumberItem(int startPC, int lineNum){
+ this.startPC = startPC;
+ this.lineNum = lineNum;
+ }
+
+ public int getStartPC() {
+ return startPC;
+ }
+ public void setStartPC(int startPC) {
+ this.startPC = startPC;
+ }
+ public int getLineNum() {
+ return lineNum;
+ }
+ public void setLineNum(int lineNum) {
+ this.lineNum = lineNum;
+ }
+ }
+ public void addLineNumberItem(LineNumberItem item){
+ this.items.add(item);
+ }
+ public LineNumberTable(int attrNameIndex, int attrLen) {
+ super(attrNameIndex, attrLen);
+
+ }
+
+ public static LineNumberTable parse(ByteCodeIterator iter){
+ int attributeNameIndex = iter.nextU2ToInt();
+ int attributeLength = iter.nextU4ToInt();
+ int lineNumberTableLength = iter.nextU2ToInt();
+ LineNumberTable table = new LineNumberTable(attributeNameIndex, attributeLength);
+ for(int i = 0; i < lineNumberTableLength; i ++){
+ int startPC = iter.nextU2ToInt();
+ int lineNum = iter.nextU2ToInt();
+ LineNumberItem item = new LineNumberItem(startPC, lineNum);
+ table.addLineNumberItem(item);
+ }
+ return table;
+ }
+
+ public String toString(){
+ StringBuilder buffer = new StringBuilder();
+ buffer.append("Line Number Table:\n");
+ for(LineNumberItem item : items){
+ buffer.append("startPC:"+item.getStartPC()).append(",");
+ buffer.append("lineNum:"+item.getLineNum()).append("\n");
+ }
+ buffer.append("\n");
+ return buffer.toString();
+
+ }
+
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/attr/LocalVariableItem.java b/group24/75939388/learning2017/src/main/java/miniJVM/attr/LocalVariableItem.java
new file mode 100644
index 0000000000..7a2794dee7
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/attr/LocalVariableItem.java
@@ -0,0 +1,39 @@
+package miniJVM.attr;
+
+public class LocalVariableItem {
+ private int startPC;
+ private int length;
+ private int nameIndex;
+ private int descIndex;
+ private int index;
+ public int getStartPC() {
+ return startPC;
+ }
+ public void setStartPC(int startPC) {
+ this.startPC = startPC;
+ }
+ public int getLength() {
+ return length;
+ }
+ public void setLength(int length) {
+ this.length = length;
+ }
+ public int getNameIndex() {
+ return nameIndex;
+ }
+ public void setNameIndex(int nameIndex) {
+ this.nameIndex = nameIndex;
+ }
+ public int getDescIndex() {
+ return descIndex;
+ }
+ public void setDescIndex(int descIndex) {
+ this.descIndex = descIndex;
+ }
+ public int getIndex() {
+ return index;
+ }
+ public void setIndex(int index) {
+ this.index = index;
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/attr/LocalVariableTable.java b/group24/75939388/learning2017/src/main/java/miniJVM/attr/LocalVariableTable.java
new file mode 100644
index 0000000000..0b46d90c3d
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/attr/LocalVariableTable.java
@@ -0,0 +1,55 @@
+package miniJVM.attr;
+
+
+import miniJVM.constant.ConstantPool;
+import miniJVM.loader.ByteCodeIterator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class LocalVariableTable extends AttributeInfo{
+
+ List items = new ArrayList();
+
+ public LocalVariableTable(int attrNameIndex, int attrLen) {
+ super(attrNameIndex, attrLen);
+ }
+
+
+ private void addLocalVariableItem(LocalVariableItem item) {
+ this.items.add(item);
+ }
+
+ public static LocalVariableTable parse(ByteCodeIterator iter){
+ int attributeNameIndex = iter.nextU2ToInt();
+ int attributeLength = iter.nextU4ToInt();
+ LocalVariableTable table = new LocalVariableTable(attributeNameIndex, attributeLength);
+ int localVariableTableLength = iter.nextU2ToInt();
+ for(int i = 0; i < localVariableTableLength; i++){
+ int startPC = iter.nextU2ToInt();
+ int length = iter.nextU2ToInt();
+ int nameIndex = iter.nextU2ToInt();
+ int descriptorIndex = iter.nextU2ToInt();
+ int index = iter.nextU2ToInt();
+ LocalVariableItem item = new LocalVariableItem();
+ table.addLocalVariableItem(item);
+ }
+
+ return table;
+ }
+
+
+ public String toString(ConstantPool pool){
+ StringBuilder buffer = new StringBuilder();
+ buffer.append("Local Variable Table:\n");
+ for(LocalVariableItem item : items){
+ buffer.append("startPC:"+item.getStartPC()).append(",");
+ buffer.append("name:"+pool.getUTF8String(item.getNameIndex())).append(",");
+ buffer.append("desc:"+pool.getUTF8String(item.getDescIndex())).append(",");
+ buffer.append("slotIndex:"+ item.getIndex()).append("\n");
+ }
+ buffer.append("\n");
+ return buffer.toString();
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/attr/StackMapTable.java b/group24/75939388/learning2017/src/main/java/miniJVM/attr/StackMapTable.java
new file mode 100644
index 0000000000..ffe45f2a73
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/attr/StackMapTable.java
@@ -0,0 +1,30 @@
+package miniJVM.attr;
+
+
+import miniJVM.loader.ByteCodeIterator;
+
+public class StackMapTable extends AttributeInfo{
+
+ private String originalCode;
+
+ public StackMapTable(int attrNameIndex, int attrLen) {
+ super(attrNameIndex, attrLen);
+ }
+
+ public static StackMapTable parse(ByteCodeIterator iter){
+ int index = iter.nextU2ToInt();
+ int len = iter.nextU4ToInt();
+ StackMapTable t = new StackMapTable(index,len);
+
+ //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存
+ String code = iter.nextUxToHexString(len);
+ t.setOriginalCode(code);
+
+ return t;
+ }
+
+ private void setOriginalCode(String code) {
+ this.originalCode = code;
+
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/clz/AccessFlag.java b/group24/75939388/learning2017/src/main/java/miniJVM/clz/AccessFlag.java
new file mode 100644
index 0000000000..72ac22ec3b
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/clz/AccessFlag.java
@@ -0,0 +1,25 @@
+package miniJVM.clz;
+
+public class AccessFlag {
+ private int flagValue;
+
+ public AccessFlag(int value) {
+ this.flagValue = value;
+ }
+
+ public int getFlagValue() {
+ return flagValue;
+ }
+
+ public void setFlagValue(int flag) {
+ this.flagValue = flag;
+ }
+
+ public boolean isPublicClass(){
+ return (this.flagValue & 0x0001) != 0;
+ }
+ public boolean isFinalClass(){
+ return (this.flagValue & 0x0010) != 0;
+ }
+
+}
\ No newline at end of file
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/clz/ClassFile.java b/group24/75939388/learning2017/src/main/java/miniJVM/clz/ClassFile.java
new file mode 100644
index 0000000000..7e723f4a24
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/clz/ClassFile.java
@@ -0,0 +1,107 @@
+package miniJVM.clz;
+
+
+import miniJVM.constant.ClassInfo;
+import miniJVM.constant.ConstantPool;
+import miniJVM.field.Field;
+import miniJVM.method.Method;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClassFile {
+
+ private int minorVersion;
+ private int majorVersion;
+
+ private AccessFlag accessFlag;
+ private ClassIndex clzIndex;
+ private ConstantPool pool;
+ private List fields = new ArrayList();
+ private List methods = new ArrayList();
+
+ public ClassIndex getClzIndex() {
+ return clzIndex;
+ }
+ public AccessFlag getAccessFlag() {
+ return accessFlag;
+ }
+ public void setAccessFlag(AccessFlag accessFlag) {
+ this.accessFlag = accessFlag;
+ }
+
+
+
+ public ConstantPool getConstantPool() {
+ return pool;
+ }
+ public int getMinorVersion() {
+ return minorVersion;
+ }
+ public void setMinorVersion(int minorVersion) {
+ this.minorVersion = minorVersion;
+ }
+ public int getMajorVersion() {
+ return majorVersion;
+ }
+ public void setMajorVersion(int majorVersion) {
+ this.majorVersion = majorVersion;
+ }
+ public void setConstPool(ConstantPool pool) {
+ this.pool = pool;
+
+ }
+ public void setClassIndex(ClassIndex clzIndex) {
+ this.clzIndex = clzIndex;
+ }
+
+ public void addField(Field f){
+ this.fields.add(f);
+ }
+ public List getFields(){
+ return this.fields;
+ }
+ public void addMethod(Method m){
+ this.methods.add(m);
+ }
+ public List getMethods() {
+ return methods;
+ }
+
+
+ public void print(){
+
+ if(this.accessFlag.isPublicClass()){
+ System.out.println("Access flag : public ");
+ }
+ System.out.println("Class Name:"+ getClassName());
+
+ System.out.println("Super Class Name:"+ getSuperClassName());
+
+
+ }
+
+ public String getClassName(){
+ int thisClassIndex = this.clzIndex.getThisClassIndex();
+ ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex);
+ return thisClass.getClassName();
+ }
+ public String getSuperClassName(){
+ ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex());
+ return superClass.getClassName();
+ }
+
+ public Method getMethod(String methodName, String paramAndReturnType){
+ for(Method me : methods){
+ String meName = pool.getUTF8String(me.getNameIndex());
+ String meParamReturnType = pool.getUTF8String(me.getDescriptorIndex());
+ if (meName.equals(methodName) && meParamReturnType.equals(paramAndReturnType)){
+ return me;
+ }
+ }
+ throw new RuntimeException("methodName = " + methodName + " and paramAndReturnType=" + paramAndReturnType + "'s method not found");
+ }
+ public Method getMainMethod(){
+ return getMethod("main", "([Ljava/lang/String;)V");
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/clz/ClassIndex.java b/group24/75939388/learning2017/src/main/java/miniJVM/clz/ClassIndex.java
new file mode 100644
index 0000000000..5c406c3e66
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/clz/ClassIndex.java
@@ -0,0 +1,24 @@
+package miniJVM.clz;
+
+public class ClassIndex {
+ private int thisClassIndex;
+ private int superClassIndex;
+
+ public ClassIndex(int thisClassIndex, int superClassIndex){
+ this.thisClassIndex = thisClassIndex;
+ this.superClassIndex = superClassIndex;
+ }
+
+ public int getThisClassIndex() {
+ return thisClassIndex;
+ }
+ public void setThisClassIndex(int thisClassIndex) {
+ this.thisClassIndex = thisClassIndex;
+ }
+ public int getSuperClassIndex() {
+ return superClassIndex;
+ }
+ public void setSuperClassIndex(int superClassIndex) {
+ this.superClassIndex = superClassIndex;
+ }
+}
\ No newline at end of file
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/BiPushCmd.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/BiPushCmd.java
new file mode 100644
index 0000000000..c14e56b185
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/BiPushCmd.java
@@ -0,0 +1,22 @@
+package miniJVM.cmd;
+
+
+import miniJVM.clz.ClassFile;
+import miniJVM.constant.ConstantPool;
+
+public class BiPushCmd extends OneOperandCmd {
+
+ public BiPushCmd(ClassFile clzFile, String opCode) {
+ super(clzFile,opCode);
+
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return this.getOffset()+": "+ this.getOpCode()+" " + this.getReadableCodeText() + " " + this.getOperand();
+ }
+
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/ByteCodeCommand.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/ByteCodeCommand.java
new file mode 100644
index 0000000000..294add94b5
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/ByteCodeCommand.java
@@ -0,0 +1,118 @@
+package miniJVM.cmd;
+
+import miniJVM.clz.ClassFile;
+import miniJVM.constant.ConstantInfo;
+import miniJVM.constant.ConstantPool;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class ByteCodeCommand {
+
+ String opCode;
+ ClassFile clzFile;
+ private int offset;
+
+ private static Map codeMap = new HashMap();
+
+ static{
+ codeMap.put("01", "aconst_null");
+
+ codeMap.put("BB", "new");
+ codeMap.put("37", "lstore");
+ codeMap.put("B7", "invokespecial");
+ codeMap.put("B6", "invokevirtual");
+ codeMap.put("B4", "getfield");
+ codeMap.put("B5", "putfield");
+ codeMap.put("B2", "getstatic");
+
+ codeMap.put("2A", "aload_0");
+ codeMap.put("2B", "aload_1");
+ codeMap.put("2C", "aload_2");
+
+ codeMap.put("10", "bipush");
+ codeMap.put("15", "iload");
+ codeMap.put("1A", "iload_0");
+ codeMap.put("1B", "iload_1");
+ codeMap.put("1C", "iload_2");
+ codeMap.put("1D", "iload_3");
+
+ codeMap.put("25", "fload_3");
+
+ codeMap.put("1E", "lload_0");
+
+ codeMap.put("24", "fload_2");
+ codeMap.put("4C", "astore_1");
+
+ codeMap.put("A2", "if_icmp_ge");
+ codeMap.put("A4", "if_icmple");
+
+ codeMap.put("A7", "goto");
+
+ codeMap.put("B1", "return");
+ codeMap.put("AC", "ireturn");
+ codeMap.put("AE", "freturn");
+
+ codeMap.put("03", "iconst_0");
+ codeMap.put("04", "iconst_1");
+
+ codeMap.put("3C", "istore_1");
+ codeMap.put("3D", "istore_2");
+
+ codeMap.put("59", "dup");
+
+ codeMap.put("60", "iadd");
+ codeMap.put("84", "iinc");
+
+ codeMap.put("12", "ldc");
+ }
+
+ protected ByteCodeCommand(ClassFile clzFile, String opCode){
+ this.clzFile = clzFile;
+ this.opCode = opCode;
+ }
+
+ protected ClassFile getClassFile() {
+ return clzFile;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public void setOffset(int offset) {
+ this.offset = offset;
+ }
+ protected ConstantInfo getConstantInfo(int index){
+ return this.getClassFile().getConstantPool().getConstantInfo(index);
+ }
+
+ protected ConstantPool getConstantPool(){
+ return this.getClassFile().getConstantPool();
+ }
+
+ public String getOpCode() {
+ return opCode;
+ }
+
+ public abstract int getLength();
+
+ public String toString(){
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(this.offset).append(": ").append(getReadableCodeText());
+
+ return buffer.toString();
+ }
+ public abstract String toString(ConstantPool pool);
+
+ public String getReadableCodeText(){
+ String txt = codeMap.get(opCode.toUpperCase());
+ if(txt == null){
+ return this.opCode;
+ }
+ return txt;
+ }
+
+ //public abstract void execute(StackFrame frame,FrameResult result);
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/CommandParser.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/CommandParser.java
new file mode 100644
index 0000000000..1d45ffc35b
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/CommandParser.java
@@ -0,0 +1,147 @@
+package miniJVM.cmd;
+
+
+import miniJVM.clz.ClassFile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CommandParser {
+
+ public static final String aconst_null = "01";
+ public static final String new_object = "BB";
+ public static final String lstore = "37";
+ public static final String invokespecial = "B7";
+ public static final String invokevirtual = "B6";
+ public static final String getfield = "B4";
+ public static final String putfield = "B5";
+ public static final String getstatic = "B2";
+ public static final String ldc = "12";
+ public static final String dup = "59";
+ public static final String bipush = "10";
+ public static final String aload_0 = "2A";
+ public static final String aload_1 = "2B";
+ public static final String aload_2 = "2C";
+ public static final String iload = "15";
+ public static final String iload_1 = "1B";
+ public static final String iload_2 = "1C";
+ public static final String iload_3 = "1D";
+ public static final String fload_3 = "25";
+
+ public static final String voidreturn = "B1";
+ public static final String ireturn = "AC";
+ public static final String freturn = "AE";
+
+ public static final String astore_1 = "4C";
+ public static final String if_icmp_ge = "A2";
+ public static final String if_icmple = "A4";
+ public static final String goto_no_condition = "A7";
+ public static final String iconst_0 = "03";
+ public static final String iconst_1 = "04";
+ public static final String istore_1 = "3C";
+ public static final String istore_2 = "3D";
+ public static final String iadd = "60";
+ public static final String iinc = "84";
+
+
+ public static ByteCodeCommand[] parse(ClassFile clzFile, String codes) {
+ CommandIterator ci = new CommandIterator(codes);
+ List cmds = new ArrayList();
+ while (ci.hasNext()){
+ String command = ci.next2CharAsString();
+ if(command.equalsIgnoreCase(new_object)){
+ NewObjectCmd cmd = new NewObjectCmd(clzFile, command);
+ cmd.setOprand1(ci.next2CharAsInt());
+ cmd.setOprand2(ci.next2CharAsInt());
+ cmds.add(cmd);
+ }else if(command.equalsIgnoreCase(invokespecial)){
+ InvokeSpecialCmd cmd = new InvokeSpecialCmd(clzFile, command);
+ cmd.setOprand1(ci.next2CharAsInt());
+ cmd.setOprand2(ci.next2CharAsInt());
+ cmds.add(cmd);
+ }else if(command.equalsIgnoreCase(invokevirtual)){
+ InvokeVirtualCmd cmd = new InvokeVirtualCmd(clzFile, command);
+ cmd.setOprand1(ci.next2CharAsInt());
+ cmd.setOprand2(ci.next2CharAsInt());
+ cmds.add(cmd);
+ }else if(command.equalsIgnoreCase(getfield)){
+ GetFieldCmd cmd = new GetFieldCmd(clzFile, command);
+ cmd.setOprand1(ci.next2CharAsInt());
+ cmd.setOprand2(ci.next2CharAsInt());
+ cmds.add(cmd);
+ }else if(command.equalsIgnoreCase(getstatic)){
+ GetStaticFieldCmd cmd = new GetStaticFieldCmd(clzFile, command);
+ cmd.setOprand1(ci.next2CharAsInt());
+ cmd.setOprand2(ci.next2CharAsInt());
+ cmds.add(cmd);
+ }else if(command.equalsIgnoreCase(putfield)){
+ PutFieldCmd cmd = new PutFieldCmd(clzFile, command);
+ cmd.setOprand1(ci.next2CharAsInt());
+ cmd.setOprand2(ci.next2CharAsInt());
+ cmds.add(cmd);
+ }else if(command.equalsIgnoreCase(ldc)){
+ LdcCmd cmd = new LdcCmd(clzFile, command);
+ cmd.setOperand(ci.next2CharAsInt());
+ cmds.add(cmd);
+ }else if(command.equalsIgnoreCase(bipush)){
+ BiPushCmd cmd = new BiPushCmd(clzFile, command);
+ cmd.setOperand(ci.next2CharAsInt());
+ cmds.add(cmd);
+ }else if (command.equalsIgnoreCase(dup) ||
+ command.equalsIgnoreCase(aload_0) ||
+ command.equalsIgnoreCase(aload_1) ||
+ command.equalsIgnoreCase(aload_2) ||
+ command.equalsIgnoreCase(iload_1) ||
+ command.equalsIgnoreCase(iload_2) ||
+ command.equalsIgnoreCase(iload_3) ||
+ command.equalsIgnoreCase(fload_3) ||
+ command.equalsIgnoreCase(voidreturn) ||
+ command.equalsIgnoreCase(astore_1)) {
+ NoOperandCmd cmd = new NoOperandCmd(clzFile, command);
+ cmds.add(cmd);
+ }else{
+ throw new RuntimeException("没有对指令=" + command + "进行处理");
+ }
+ }
+ calculateOffset(cmds);
+
+ ByteCodeCommand[] cmdArr = new ByteCodeCommand[cmds.size()];
+ cmds.toArray(cmdArr);
+ return cmdArr;
+ }
+
+ private static void calculateOffset(List cmds) {
+
+ int offset = 0;
+ for (ByteCodeCommand cmd : cmds) {
+ cmd.setOffset(offset);
+ offset += cmd.getLength();
+ }
+
+ }
+
+ private static class CommandIterator {
+ String codes = null;
+ int pos = 0;
+
+ CommandIterator(String codes) {
+ this.codes = codes;
+ }
+
+ public boolean hasNext() {
+ return pos < this.codes.length();
+ }
+
+ public String next2CharAsString() {
+ String result = codes.substring(pos, pos + 2);
+ pos += 2;
+ return result;
+ }
+
+ public int next2CharAsInt() {
+ String s = this.next2CharAsString();
+ return Integer.valueOf(s, 16).intValue();
+ }
+
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/GetFieldCmd.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/GetFieldCmd.java
new file mode 100644
index 0000000000..67e734e5f1
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/GetFieldCmd.java
@@ -0,0 +1,22 @@
+package miniJVM.cmd;
+
+
+import miniJVM.clz.ClassFile;
+import miniJVM.constant.ConstantPool;
+
+public class GetFieldCmd extends TwoOperandCmd {
+
+ public GetFieldCmd(ClassFile clzFile, String opCode) {
+ super(clzFile,opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsField(pool);
+ }
+
+
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/GetStaticFieldCmd.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/GetStaticFieldCmd.java
new file mode 100644
index 0000000000..95ad38e806
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/GetStaticFieldCmd.java
@@ -0,0 +1,20 @@
+package miniJVM.cmd;
+
+
+import miniJVM.clz.ClassFile;
+import miniJVM.constant.ConstantPool;
+
+public class GetStaticFieldCmd extends TwoOperandCmd {
+
+ public GetStaticFieldCmd(ClassFile clzFile, String opCode) {
+ super(clzFile,opCode);
+
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsField(pool);
+ }
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/InvokeSpecialCmd.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/InvokeSpecialCmd.java
new file mode 100644
index 0000000000..d4f401f26d
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/InvokeSpecialCmd.java
@@ -0,0 +1,21 @@
+package miniJVM.cmd;
+
+import miniJVM.clz.ClassFile;
+import miniJVM.constant.ConstantPool;
+
+public class InvokeSpecialCmd extends TwoOperandCmd {
+
+ public InvokeSpecialCmd(ClassFile clzFile, String opCode) {
+ super(clzFile,opCode);
+
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsMethod(pool);
+ }
+
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/InvokeVirtualCmd.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/InvokeVirtualCmd.java
new file mode 100644
index 0000000000..37ebbf4cc2
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/InvokeVirtualCmd.java
@@ -0,0 +1,21 @@
+package miniJVM.cmd;
+
+import miniJVM.clz.ClassFile;
+import miniJVM.constant.ConstantPool;
+
+public class InvokeVirtualCmd extends TwoOperandCmd {
+
+ public InvokeVirtualCmd(ClassFile clzFile, String opCode) {
+ super(clzFile,opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsMethod(pool);
+ }
+
+
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/LdcCmd.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/LdcCmd.java
new file mode 100644
index 0000000000..c56b294f4d
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/LdcCmd.java
@@ -0,0 +1,30 @@
+package miniJVM.cmd;
+
+
+import miniJVM.clz.ClassFile;
+import miniJVM.constant.ConstantInfo;
+import miniJVM.constant.ConstantPool;
+import miniJVM.constant.StringInfo;
+
+public class LdcCmd extends OneOperandCmd {
+
+ public LdcCmd(ClassFile clzFile, String opCode) {
+ super(clzFile,opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ ConstantInfo info = (ConstantInfo)pool.getConstantInfo(this.getOperand());
+
+ String value = "TBD";
+ if(info instanceof StringInfo){
+ StringInfo strInfo = (StringInfo)info;
+ value = strInfo.toString();
+ }
+
+ return this.getOffset()+":"+this.getOpCode()+" " + this.getReadableCodeText() + " "+ value;
+
+ }
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/NewObjectCmd.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/NewObjectCmd.java
new file mode 100644
index 0000000000..d2e28c5eea
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/NewObjectCmd.java
@@ -0,0 +1,20 @@
+package miniJVM.cmd;
+
+
+import miniJVM.clz.ClassFile;
+import miniJVM.constant.ConstantPool;
+
+public class NewObjectCmd extends TwoOperandCmd{
+
+ public NewObjectCmd(ClassFile clzFile, String opCode){
+ super(clzFile,opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsClassInfo(pool);
+ }
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/NoOperandCmd.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/NoOperandCmd.java
new file mode 100644
index 0000000000..e10bbabb66
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/NoOperandCmd.java
@@ -0,0 +1,23 @@
+package miniJVM.cmd;
+
+
+import miniJVM.clz.ClassFile;
+import miniJVM.constant.ConstantPool;
+
+public class NoOperandCmd extends ByteCodeCommand {
+
+ public NoOperandCmd(ClassFile clzFile, String opCode) {
+ super(clzFile, opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+ return this.getOffset() + ":" + this.getOpCode() + " " + this.getReadableCodeText();
+ }
+
+
+ public int getLength() {
+ return 1;
+ }
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/OneOperandCmd.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/OneOperandCmd.java
new file mode 100644
index 0000000000..6736c608b9
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/OneOperandCmd.java
@@ -0,0 +1,27 @@
+package miniJVM.cmd;
+
+import miniJVM.clz.ClassFile;
+
+public abstract class OneOperandCmd extends ByteCodeCommand {
+
+ private int operand;
+
+ public OneOperandCmd(ClassFile clzFile, String opCode) {
+ super(clzFile, opCode);
+
+ }
+ public int getOperand() {
+
+ return this.operand;
+ }
+
+ public void setOperand(int oprand1) {
+ this.operand = oprand1;
+
+ }
+ public int getLength(){
+ return 2;
+ }
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/PutFieldCmd.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/PutFieldCmd.java
new file mode 100644
index 0000000000..066f37dd01
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/PutFieldCmd.java
@@ -0,0 +1,20 @@
+package miniJVM.cmd;
+
+
+import miniJVM.clz.ClassFile;
+import miniJVM.constant.ConstantPool;
+
+public class PutFieldCmd extends TwoOperandCmd {
+
+ public PutFieldCmd(ClassFile clzFile, String opCode) {
+ super(clzFile,opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsField(pool);
+ }
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/cmd/TwoOperandCmd.java b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/TwoOperandCmd.java
new file mode 100644
index 0000000000..400fdb0350
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/cmd/TwoOperandCmd.java
@@ -0,0 +1,64 @@
+package miniJVM.cmd;
+
+
+import miniJVM.clz.ClassFile;
+import miniJVM.constant.*;
+
+public abstract class TwoOperandCmd extends ByteCodeCommand{
+
+ int oprand1 = -1;
+ int oprand2 = -1;
+
+ public int getOprand1() {
+ return oprand1;
+ }
+
+ public void setOprand1(int oprand1) {
+ this.oprand1 = oprand1;
+ }
+
+ public void setOprand2(int oprand2) {
+ this.oprand2 = oprand2;
+ }
+
+ public int getOprand2() {
+ return oprand2;
+ }
+
+ public TwoOperandCmd(ClassFile clzFile, String opCode) {
+ super(clzFile, opCode);
+ }
+
+ public int getIndex(){
+ int oprand1 = this.getOprand1();
+ int oprand2 = this.getOprand2();
+ int index = oprand1 << 8 | oprand2;
+ return index;
+ }
+
+ protected String getOperandAsClassInfo(ConstantPool pool){
+ int index = getIndex();
+ String codeTxt = getReadableCodeText();
+ ClassInfo info = (ClassInfo)pool.getConstantInfo(index);
+ return this.getOffset()+":"+this.getOpCode()+" "+ codeTxt +" "+ info.getClassName();
+ }
+
+ protected String getOperandAsMethod(ConstantPool pool){
+ int index = getIndex();
+ String codeTxt = getReadableCodeText();
+ ConstantInfo constInfo = this.getConstantInfo(index);
+ MethodRefInfo info = (MethodRefInfo)this.getConstantInfo(index);
+ return this.getOffset()+":"+this.getOpCode()+" " + codeTxt +" "+ info.toString();
+ }
+
+ protected String getOperandAsField(ConstantPool pool){
+ int index = getIndex();
+
+ String codeTxt = getReadableCodeText();
+ FieldRefInfo info = (FieldRefInfo)this.getConstantInfo(index);
+ return this.getOffset()+":"+this.getOpCode()+" " + codeTxt +" "+ info.toString();
+ }
+ public int getLength(){
+ return 3;
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/constant/ClassInfo.java b/group24/75939388/learning2017/src/main/java/miniJVM/constant/ClassInfo.java
new file mode 100644
index 0000000000..735ae4eace
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/constant/ClassInfo.java
@@ -0,0 +1,28 @@
+package miniJVM.constant;
+
+public class ClassInfo extends ConstantInfo {
+ private int type = ConstantInfo.CLASS_INFO;
+ private int utf8Index ;
+ public ClassInfo(ConstantPool pool) {
+ super(pool);
+ }
+ public int getUtf8Index() {
+ return utf8Index;
+ }
+ public void setUtf8Index(int utf8Index) {
+ this.utf8Index = utf8Index;
+ }
+ public int getType() {
+ return type;
+ }
+
+ public String getClassName() {
+ int index = getUtf8Index();
+ UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index);
+ return utf8Info.getValue();
+ }
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visitClassInfo(this);
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/constant/ConstantInfo.java b/group24/75939388/learning2017/src/main/java/miniJVM/constant/ConstantInfo.java
new file mode 100644
index 0000000000..6ab8326c7f
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/constant/ConstantInfo.java
@@ -0,0 +1,39 @@
+package miniJVM.constant;
+
+public abstract class ConstantInfo {
+ public static final int UTF8_INFO = 1;
+ public static final int FLOAT_INFO = 4;
+ public static final int CLASS_INFO = 7;
+ public static final int STRING_INFO = 8;
+ public static final int FIELD_INFO = 9;
+ public static final int METHOD_INFO = 10;
+ public static final int NAME_AND_TYPE_INFO = 12;
+ protected ConstantPool constantPool;
+
+ public ConstantInfo(){
+
+ }
+
+ public ConstantInfo(ConstantPool pool) {
+ this.constantPool = pool;
+ }
+ public abstract int getType();
+
+ public ConstantPool getConstantPool() {
+ return constantPool;
+ }
+ public ConstantInfo getConstantInfo(int index){
+ return this.constantPool.getConstantInfo(index);
+ }
+
+ public abstract void accept(Visitor visitor);
+
+ public interface Visitor{
+ void visitClassInfo(ClassInfo info);
+ void visitFieldRef(FieldRefInfo info);
+ void visitMethodRef(MethodRefInfo info);
+ void visitNameAndType(NameAndTypeInfo info);
+ void visitString(StringInfo info);
+ void visitUTF8(UTF8Info info);
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/constant/ConstantPool.java b/group24/75939388/learning2017/src/main/java/miniJVM/constant/ConstantPool.java
new file mode 100644
index 0000000000..50042ec97d
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/constant/ConstantPool.java
@@ -0,0 +1,29 @@
+package miniJVM.constant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ConstantPool {
+
+ private List constantInfos = new ArrayList();
+
+
+ public ConstantPool(){
+
+ }
+ public void addConstantInfo(ConstantInfo info){
+ this.constantInfos.add(info);
+ }
+
+ public ConstantInfo getConstantInfo(int index){
+ return this.constantInfos.get(index);
+ }
+ public String getUTF8String(int index){
+ return ((UTF8Info)this.constantInfos.get(index)).getValue();
+ }
+ public int getSize() {
+ return this.constantInfos.size() - 1;
+ }
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/constant/FieldRefInfo.java b/group24/75939388/learning2017/src/main/java/miniJVM/constant/FieldRefInfo.java
new file mode 100644
index 0000000000..47603e4e13
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/constant/FieldRefInfo.java
@@ -0,0 +1,58 @@
+package miniJVM.constant;
+
+public class FieldRefInfo extends ConstantInfo{
+ private int type = ConstantInfo.FIELD_INFO;
+ private int classInfoIndex;
+ private int nameAndTypeIndex;
+
+ public FieldRefInfo(ConstantPool pool) {
+ super(pool);
+ }
+ public int getType() {
+ return type;
+ }
+
+ public int getClassInfoIndex() {
+ return classInfoIndex;
+ }
+ public void setClassInfoIndex(int classInfoIndex) {
+ this.classInfoIndex = classInfoIndex;
+ }
+ public int getNameAndTypeIndex() {
+ return nameAndTypeIndex;
+ }
+ public void setNameAndTypeIndex(int nameAndTypeIndex) {
+ this.nameAndTypeIndex = nameAndTypeIndex;
+ }
+
+ public String toString(){
+
+ NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex());
+
+ return getClassName() +" : "+ typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]";
+ }
+
+ public String getClassName(){
+
+ ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex());
+
+ UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index());
+
+ return utf8Info.getValue();
+
+ }
+
+ public String getFieldName(){
+ NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex());
+ return typeInfo.getName();
+ }
+
+ public String getFieldType(){
+ NameAndTypeInfo typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex());
+ return typeInfo.getTypeInfo();
+ }
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visitFieldRef(this);
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/constant/MethodRefInfo.java b/group24/75939388/learning2017/src/main/java/miniJVM/constant/MethodRefInfo.java
new file mode 100644
index 0000000000..cd2f012b68
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/constant/MethodRefInfo.java
@@ -0,0 +1,60 @@
+package miniJVM.constant;
+
+public class MethodRefInfo extends ConstantInfo {
+
+ private int type = ConstantInfo.METHOD_INFO;
+
+ private int classInfoIndex;
+ private int nameAndTypeIndex;
+
+ public MethodRefInfo(ConstantPool pool) {
+ super(pool);
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public int getClassInfoIndex() {
+ return classInfoIndex;
+ }
+ public void setClassInfoIndex(int classInfoIndex) {
+ this.classInfoIndex = classInfoIndex;
+ }
+ public int getNameAndTypeIndex() {
+ return nameAndTypeIndex;
+ }
+ public void setNameAndTypeIndex(int nameAndTypeIndex) {
+ this.nameAndTypeIndex = nameAndTypeIndex;
+ }
+
+ public String toString(){
+
+ return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ;
+ }
+ public String getClassName(){
+ ConstantPool pool = this.getConstantPool();
+ ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex());
+ return clzInfo.getClassName();
+ }
+
+ public String getMethodName(){
+ ConstantPool pool = this.getConstantPool();
+ NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex());
+ return typeInfo.getName();
+ }
+
+ public String getParamAndReturnType(){
+ ConstantPool pool = this.getConstantPool();
+ NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex());
+ return typeInfo.getTypeInfo();
+ }
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visitMethodRef(this);
+ }
+
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/constant/NameAndTypeInfo.java b/group24/75939388/learning2017/src/main/java/miniJVM/constant/NameAndTypeInfo.java
new file mode 100644
index 0000000000..eddb11b6f5
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/constant/NameAndTypeInfo.java
@@ -0,0 +1,51 @@
+package miniJVM.constant;
+
+public class NameAndTypeInfo extends ConstantInfo{
+ public int type = ConstantInfo.NAME_AND_TYPE_INFO;
+
+ private int index1;
+ private int index2;
+
+ public NameAndTypeInfo(ConstantPool pool) {
+ super(pool);
+ }
+
+ public int getIndex1() {
+ return index1;
+ }
+ public void setIndex1(int index1) {
+ this.index1 = index1;
+ }
+ public int getIndex2() {
+ return index2;
+ }
+ public void setIndex2(int index2) {
+ this.index2 = index2;
+ }
+ public int getType() {
+ return type;
+ }
+
+
+ public String getName(){
+ ConstantPool pool = this.getConstantPool();
+ UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1);
+ return utf8Info1.getValue();
+ }
+
+ public String getTypeInfo(){
+ ConstantPool pool = this.getConstantPool();
+ UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2);
+ return utf8Info2.getValue();
+ }
+
+ public String toString(){
+ return "(" + getName() + "," + getTypeInfo()+")";
+ }
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visitNameAndType(this);
+
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/constant/NullConstantInfo.java b/group24/75939388/learning2017/src/main/java/miniJVM/constant/NullConstantInfo.java
new file mode 100644
index 0000000000..7df8b59156
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/constant/NullConstantInfo.java
@@ -0,0 +1,17 @@
+package miniJVM.constant;
+
+public class NullConstantInfo extends ConstantInfo {
+
+ public NullConstantInfo(){
+
+ }
+ @Override
+ public int getType() {
+ return -1;
+ }
+ @Override
+ public void accept(Visitor visitor) {
+
+ }
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/constant/StringInfo.java b/group24/75939388/learning2017/src/main/java/miniJVM/constant/StringInfo.java
new file mode 100644
index 0000000000..07be339e0a
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/constant/StringInfo.java
@@ -0,0 +1,32 @@
+package miniJVM.constant;
+
+public class StringInfo extends ConstantInfo{
+ private int type = ConstantInfo.STRING_INFO;
+ private int index;
+ public StringInfo(ConstantPool pool) {
+ super(pool);
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+ public void setIndex(int index) {
+ this.index = index;
+ }
+
+
+ public String toString(){
+ return this.getConstantPool().getUTF8String(index);
+ }
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visitString(this);
+
+ }
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/constant/UTF8Info.java b/group24/75939388/learning2017/src/main/java/miniJVM/constant/UTF8Info.java
new file mode 100644
index 0000000000..ff3518e492
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/constant/UTF8Info.java
@@ -0,0 +1,37 @@
+package miniJVM.constant;
+
+public class UTF8Info extends ConstantInfo{
+ private int type = ConstantInfo.UTF8_INFO;
+ private int length ;
+ private String value;
+ public UTF8Info(ConstantPool pool) {
+ super(pool);
+ }
+ public int getLength() {
+ return length;
+ }
+ public void setLength(int length) {
+ this.length = length;
+ }
+ public int getType() {
+ return type;
+ }
+ @Override
+ public String toString() {
+ return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]";
+ }
+ public String getValue() {
+ return value;
+ }
+ public void setValue(String value) {
+ this.value = value;
+ }
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visitUTF8(this);
+
+ }
+
+
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/field/Field.java b/group24/75939388/learning2017/src/main/java/miniJVM/field/Field.java
new file mode 100644
index 0000000000..cfaccf116c
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/field/Field.java
@@ -0,0 +1,46 @@
+package miniJVM.field;
+
+import miniJVM.constant.ConstantPool;
+import miniJVM.constant.UTF8Info;
+
+public class Field {
+ private int accessFlag;
+ private int nameIndex;
+ private int descriptorIndex;
+ private int attributeCount;
+
+ private ConstantPool pool;
+
+ public Field( int accessFlag, int nameIndex, int descriptorIndex, int attributeCount, ConstantPool pool) {
+ this.accessFlag = accessFlag;
+ this.nameIndex = nameIndex;
+ this.descriptorIndex = descriptorIndex;
+ this.attributeCount = attributeCount;
+ this.pool = pool;
+ }
+
+ public String toString() {
+ String name = ((UTF8Info)pool.getConstantInfo(this.nameIndex)).getValue();
+ String desc = ((UTF8Info)pool.getConstantInfo(this.descriptorIndex)).getValue();
+ return name +":"+ desc;
+ }
+
+
+// public static Field parse(ConstantPool pool,ByteCodeIterator iter){
+//
+// int accessFlag = iter.nextU2ToInt();
+// int nameIndex = iter.nextU2ToInt();
+// int descIndex = iter.nextU2ToInt();
+// int attrCount = iter.nextU2ToInt();
+// //System.out.println("field attribute count:"+ attribCount);
+//
+// Field f = new Field(accessFlag, nameIndex, descIndex,pool);
+//
+// if(attrCount > 0){
+// throw new RuntimeException("Field Attribute has not been implemented");
+// }
+//
+// return f;
+// }
+
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/loader/ByteCodeIterator.java b/group24/75939388/learning2017/src/main/java/miniJVM/loader/ByteCodeIterator.java
new file mode 100644
index 0000000000..7ab4e6cc97
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/loader/ByteCodeIterator.java
@@ -0,0 +1,57 @@
+package miniJVM.loader;
+
+import miniJVM.util.Util;
+
+import java.util.Arrays;
+
+public class ByteCodeIterator {
+ byte[] codes;
+ int pos = 0;
+
+ ByteCodeIterator(byte[] codes) {
+ this.codes = codes;
+ }
+
+
+
+ public byte[] getBytes(int len) {
+ if (pos + len >= codes.length) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ byte[] data = Arrays.copyOfRange(codes, pos, pos + len);
+ pos += len;
+ return data;
+ }
+
+ public int nextU1ToInt() {
+
+ return Util.byteToInt(new byte[] { codes[pos++] });
+ }
+
+ public int nextU2ToInt() {
+ return Util.byteToInt(new byte[] { codes[pos++], codes[pos++] });
+ }
+
+ public int nextU4ToInt() {
+ return Util.byteToInt(new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] });
+ }
+
+ public String nextU4ToHexString() {
+ return Util.byteToHexString((new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] }));
+ }
+
+ public String nextUxToHexString(int len) {
+ byte[] tmp = new byte[len];
+
+ for (int i = 0; i < len; i++) {
+ tmp[i] = codes[pos++];
+ }
+ return Util.byteToHexString(tmp).toLowerCase();
+
+ }
+
+ public void back(int n) {
+ this.pos -= n;
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/loader/ClassFileLoader.java b/group24/75939388/learning2017/src/main/java/miniJVM/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..a96143321a
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/loader/ClassFileLoader.java
@@ -0,0 +1,131 @@
+package miniJVM.loader;
+
+
+import miniJVM.clz.ClassFile;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClassFileLoader {
+
+ private List clzPaths = new ArrayList();
+
+ public byte[] readBinaryCode(String className) {
+
+ className = className.replace('.', File.separatorChar) +".class";
+
+ for(String path : this.clzPaths){
+
+ String clzFileName = path + File.separatorChar + className;
+ byte[] codes = loadClassFile(clzFileName);
+ if(codes != null){
+ return codes;
+ }
+ }
+
+ return null;
+
+
+
+ }
+
+ private byte[] loadClassFile(String clzFileName) {
+
+ File f = new File(clzFileName);
+
+ try {
+
+ return IOUtils.toByteArray(new FileInputStream(f));
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+
+
+ public void addClassPath(String path) {
+ if(this.clzPaths.contains(path)){
+ return;
+ }
+
+ this.clzPaths.add(path);
+
+ }
+
+
+
+ public String getClassPath(){
+ return StringUtils.join(this.clzPaths,";");
+ }
+
+ public ClassFile loadClass(String className) {
+ byte[] codes = this.readBinaryCode(className);
+ ClassFileParser parser = new ClassFileParser();
+ return parser.parse(codes);
+ }
+
+
+
+ // ------------------------------backup------------------------
+ public String getClassPath_V1(){
+
+ StringBuffer buffer = new StringBuffer();
+ for(int i=0;i " + i + ", index -> " + index);
+ if (index == ConstantInfo.CLASS_INFO) {
+ ClassInfo classInfo = new ClassInfo(pool);
+ classInfo.setUtf8Index(iter.nextU2ToInt());
+ pool.addConstantInfo(classInfo);
+ } else if (index == ConstantInfo.UTF8_INFO) {
+ UTF8Info utf8Info = new UTF8Info(pool);
+ int length = iter.nextU2ToInt();
+ utf8Info.setLength(length);
+ utf8Info.setValue(new String(iter.getBytes(length), "utf8"));
+ pool.addConstantInfo(utf8Info);
+ } else if (index == ConstantInfo.METHOD_INFO) {
+ MethodRefInfo methodRefInfo = new MethodRefInfo(pool);
+ methodRefInfo.setClassInfoIndex(iter.nextU2ToInt());
+ methodRefInfo.setNameAndTypeIndex(iter.nextU2ToInt());
+ pool.addConstantInfo(methodRefInfo);
+ } else if (index == ConstantInfo.NAME_AND_TYPE_INFO) {
+ NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool);
+ nameAndTypeInfo.setIndex1(iter.nextU2ToInt());
+ nameAndTypeInfo.setIndex2(iter.nextU2ToInt());
+ pool.addConstantInfo(nameAndTypeInfo);
+ } else if (index == ConstantInfo.FIELD_INFO) {
+ FieldRefInfo fieldRefInfo = new FieldRefInfo(pool);
+ fieldRefInfo.setClassInfoIndex(iter.nextU2ToInt());
+ fieldRefInfo.setNameAndTypeIndex(iter.nextU2ToInt());
+ pool.addConstantInfo(fieldRefInfo);
+ } else if (index == ConstantInfo.STRING_INFO) {
+ StringInfo stringInfo = new StringInfo(pool);
+ stringInfo.setIndex(iter.nextU2ToInt());
+ pool.addConstantInfo(stringInfo);
+ } else if (index == 0) {
+ pool.addConstantInfo(null);
+ } else {
+ throw new Exception("没有针对tag=" + index + "的数据进行处理");
+ }
+ }
+ clzFile.setConstPool(pool);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void parseInterfaces(ByteCodeIterator iter) {
+ int interfaceCount = iter.nextU2ToInt();
+// System.out.println("interfaceCount:" + interfaceCount);
+ // TODO : 如果实现了interface, 这里需要解析
+ }
+
+ private void parseFields(ByteCodeIterator iter) {
+ int fieldsCount = iter.nextU2ToInt();
+
+ for (int i = 0; i < fieldsCount; i++) {
+ int accessFlag = iter.nextU2ToInt();
+ int nameIndex = iter.nextU2ToInt();
+ int descriptorIndex = iter.nextU2ToInt();
+ int attributeCount = iter.nextU2ToInt();
+
+ Field field = new Field(accessFlag, nameIndex, descriptorIndex, attributeCount, pool);
+ clzFile.addField(field);
+ }
+ }
+
+ private void parseMethods(ByteCodeIterator iter) {
+ int methodCount = iter.nextU2ToInt();
+
+ for (int i = 0; i < methodCount; i++) {
+ int accessFlag = iter.nextU2ToInt();
+ int nameIndex = iter.nextU2ToInt();
+ int descriptorIndex = iter.nextU2ToInt();
+ Method method = new Method(clzFile, accessFlag, nameIndex, descriptorIndex);
+ int attributeCount = iter.nextU2ToInt();//=1
+ while(attributeCount > 0){
+ CodeAttr codeAttr = CodeAttr.parse(clzFile, iter);
+ int exceptionTableLength = iter.nextU2ToInt();
+ //异常先不处理
+ String exceptionTable = iter.nextUxToHexString(exceptionTableLength);
+
+ int subAttributeCount = iter.nextU2ToInt();
+ while(subAttributeCount > 0){
+ LineNumberTable lineNumberTable = LineNumberTable.parse(iter);
+ codeAttr.setLineNumberTable(lineNumberTable);
+ subAttributeCount--;
+ LocalVariableTable localVariableTable = LocalVariableTable.parse(iter);
+ codeAttr.setLocalVariableTable(localVariableTable);
+ subAttributeCount--;
+ }
+ method.setCodeAttr(codeAttr);
+ attributeCount--;
+ }
+ clzFile.addMethod(method);
+ }
+ }
+
+ private void parseStackMapTable(ByteCodeIterator iter){
+ int stackMapCount = iter.nextU2ToInt();
+ StackMapTable table = StackMapTable.parse(iter);
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/method/Method.java b/group24/75939388/learning2017/src/main/java/miniJVM/method/Method.java
new file mode 100644
index 0000000000..d2e2ae2a27
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/method/Method.java
@@ -0,0 +1,77 @@
+package miniJVM.method;
+
+import miniJVM.attr.CodeAttr;
+import miniJVM.clz.ClassFile;
+import miniJVM.cmd.ByteCodeCommand;
+import miniJVM.constant.ConstantPool;
+import miniJVM.constant.UTF8Info;
+
+public class Method {
+
+ private int accessFlag;
+ private int nameIndex;
+ private int descriptorIndex;
+
+ private CodeAttr codeAttr;
+
+ private ClassFile clzFile;
+
+
+ public ClassFile getClzFile() {
+ return clzFile;
+ }
+
+ public int getNameIndex() {
+ return nameIndex;
+ }
+ public int getDescriptorIndex() {
+ return descriptorIndex;
+ }
+
+ public CodeAttr getCodeAttr() {
+ return codeAttr;
+ }
+
+ public void setCodeAttr(CodeAttr code) {
+ this.codeAttr = code;
+ }
+
+
+
+ public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) {
+ this.clzFile = clzFile;
+ this.accessFlag = accessFlag;
+ this.nameIndex = nameIndex;
+ this.descriptorIndex = descriptorIndex;
+ }
+
+
+
+
+
+ public String toString() {
+
+ ConstantPool pool = this.clzFile.getConstantPool();
+ StringBuilder buffer = new StringBuilder();
+
+ String name = ((UTF8Info)pool.getConstantInfo(this.nameIndex)).getValue();
+
+ String desc = ((UTF8Info)pool.getConstantInfo(this.descriptorIndex)).getValue();
+
+ buffer.append(name).append(":").append(desc).append("\n");
+
+ buffer.append(this.codeAttr.toString(pool));
+
+ return buffer.toString();
+ }
+
+// public static Method parse(ClassFile clzFile, ByteCodeIterator iter){
+// return null;
+// }
+
+ public ByteCodeCommand[] getCmds() {
+ ByteCodeCommand[] cmds = this.getCodeAttr().getCmds();
+
+ return cmds;
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/print/ClassFilePrinter.java b/group24/75939388/learning2017/src/main/java/miniJVM/print/ClassFilePrinter.java
new file mode 100644
index 0000000000..9d3d79bc85
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/print/ClassFilePrinter.java
@@ -0,0 +1,42 @@
+package miniJVM.print;
+
+
+import miniJVM.clz.ClassFile;
+import miniJVM.loader.ClassFileLoader;
+
+public class ClassFilePrinter {
+ ClassFile clzFile = null;
+ public ClassFilePrinter(ClassFile clzFile){
+ this.clzFile = clzFile;
+ }
+
+ public void print(){
+
+ if(clzFile.getAccessFlag().isPublicClass()){
+ System.out.println("Access flag : public ");
+ }
+ System.out.println("Class Name:"+ clzFile.getClassName());
+
+ System.out.println("Super Class Name:"+ clzFile.getSuperClassName());
+
+ System.out.println("minor version:" + clzFile.getMinorVersion());
+
+ System.out.println("major version:" + clzFile.getMinorVersion());
+
+ ConstantPoolPrinter cnstPoolPrinter = new ConstantPoolPrinter(clzFile.getConstantPool());
+ cnstPoolPrinter.print();
+ }
+
+ public static void main(String[] args){
+ String path = "resources/classes/miniJVM";
+ ClassFileLoader loader = new ClassFileLoader();
+ loader.addClassPath(path);
+ String className = "EmployeeV1";
+
+ ClassFile clzFile = loader.loadClass(className);
+
+ ClassFilePrinter printer = new ClassFilePrinter(clzFile);
+
+ printer.print();
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/print/ConstantPoolPrinter.java b/group24/75939388/learning2017/src/main/java/miniJVM/print/ConstantPoolPrinter.java
new file mode 100644
index 0000000000..c776f49f01
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/print/ConstantPoolPrinter.java
@@ -0,0 +1,114 @@
+package miniJVM.print;
+
+
+import miniJVM.constant.*;
+
+public class ConstantPoolPrinter {
+ ConstantPool pool;
+ ConstantPoolPrinter(ConstantPool pool){
+ this.pool = pool;
+ }
+ public void print(){
+ System.out.println("Constant Pool:");
+ int poolSize = pool.getSize();
+
+ ConstantInfo.Visitor visitor = new ConstantInfo.Visitor() {
+ public void visitClassInfo(ClassInfo info) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Class ");
+ sb.append("#" + info.getUtf8Index());
+ sb.append(" //" + info.getClassName());
+ System.out.println(sb.toString());
+ }
+
+ public void visitFieldRef(FieldRefInfo info) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Fieldref ");
+ sb.append("#" + info.getClassInfoIndex());
+ sb.append("." + info.getNameAndTypeIndex());
+ sb.append(" //" + info.getClassName());
+ sb.append("." + info.getFieldName());
+ sb.append(":" + info.getFieldType());
+ System.out.println(sb.toString());
+ }
+
+ public void visitMethodRef(MethodRefInfo info) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("MethodRef ");
+ sb.append("#" + info.getClassInfoIndex());
+ sb.append(".").append("#" + info.getNameAndTypeIndex());
+ sb.append(" //" + info.getClassName());
+ sb.append("." + info.getMethodName());
+ sb.append(":" + info.getParamAndReturnType());
+ System.out.println(sb.toString());
+ }
+
+ public void visitNameAndType(NameAndTypeInfo info) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("NameAndType ");
+ sb.append("#" + info.getIndex1());
+ sb.append(":#" + info.getIndex2());
+ sb.append(" //" + info.getName());
+ sb.append(":" + info.getTypeInfo());
+ System.out.println(sb.toString());
+ }
+
+ public void visitString(StringInfo info) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("String ");
+ sb.append("#" + info.getIndex());
+ sb.append(" //" + info.toString());
+ System.out.println(sb.toString());
+ }
+
+ public void visitUTF8(UTF8Info info) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Utf8 ");
+ sb.append(info.getValue());
+ System.out.println(sb.toString());
+ }
+ };
+
+ for(int i = 1; i < poolSize; i++){
+ System.out.print(i + "# = ");
+ ConstantInfo cnst = pool.getConstantInfo(i);
+ cnst.accept(visitor);
+// if(cnst instanceof ClassInfo){
+// sb.append("Class ");
+// sb.append("#" + ((ClassInfo) cnst).getUtf8Index());
+// sb.append(" //" + ((ClassInfo) cnst).getClassName());
+// }else if(cnst instanceof UTF8Info){
+// sb.append("Utf8 ");
+// sb.append(((UTF8Info) cnst).getValue());
+// }else if(cnst instanceof MethodRefInfo){
+// sb.append("MethodRef ");
+// sb.append("#" + ((MethodRefInfo) cnst).getClassInfoIndex());
+// sb.append(".").append("#" + ((MethodRefInfo) cnst).getNameAndTypeIndex());
+// sb.append(" //" + ((MethodRefInfo) cnst).getClassName());
+// sb.append("." + ((MethodRefInfo) cnst).getMethodName());
+// sb.append(":" + ((MethodRefInfo) cnst).getParamAndReturnType());
+// }else if(cnst instanceof NameAndTypeInfo){
+// sb.append("NameAndType ");
+// sb.append("#" + ((NameAndTypeInfo) cnst).getIndex1());
+// sb.append(":#" + ((NameAndTypeInfo) cnst).getIndex2());
+// sb.append(" //" + ((NameAndTypeInfo) cnst).getName());
+// sb.append(":" + ((NameAndTypeInfo) cnst).getTypeInfo());
+// }else if(cnst instanceof FieldRefInfo){
+// sb.append("Fieldref ");
+// sb.append("#" + ((FieldRefInfo) cnst).getClassInfoIndex());
+// sb.append("." + ((FieldRefInfo) cnst).getNameAndTypeIndex());
+// sb.append(" //" + ((FieldRefInfo) cnst).getClassName());
+// sb.append("." + ((FieldRefInfo) cnst).getFieldName());
+// sb.append(":" + ((FieldRefInfo) cnst).getFieldType());
+// }else if(cnst instanceof StringInfo){
+// sb.append("String ");
+// sb.append("#" + ((StringInfo) cnst).getIndex());
+// sb.append(" //" + cnst.toString());
+// }else{
+// throw new RuntimeException(cnst.getType() + "not processed");
+// }
+
+// System.out.println(sb.toString());
+ }
+ }
+}
diff --git a/group24/75939388/learning2017/src/main/java/miniJVM/util/Util.java b/group24/75939388/learning2017/src/main/java/miniJVM/util/Util.java
new file mode 100644
index 0000000000..ab4b651873
--- /dev/null
+++ b/group24/75939388/learning2017/src/main/java/miniJVM/util/Util.java
@@ -0,0 +1,24 @@
+package miniJVM.util;
+
+public class Util {
+ public static int byteToInt(byte[] codes){
+ String s1 = byteToHexString(codes);
+ return Integer.valueOf(s1, 16).intValue();
+ }
+
+
+
+ public static String byteToHexString(byte[] codes ){
+ StringBuffer buffer = new StringBuffer();
+ for(int i=0;i" + s.toString());
- }
-
- @Test
- public void testSize(){
- Stack s = getStack();
-
- Assert.assertEquals(14, s.size());
+ public void test1(){
+ Assert.assertEquals("4,3,2,1,0", s.toString());
+ Assert.assertEquals("13", s.pop());
+ Assert.assertEquals(13, s.size());
+ Assert.assertEquals("12", s.peek());
}
@Test
- public void testPeek(){
- Stack s = getStack();
+ public void test2(){
+// Assert.assertEquals("0,1,2,3,4", StackUtil.reverse(s).toString());
+// Assert.assertEquals("0,1,3,4", StackUtil.remove(s, "2").toString());
+// Assert.assertEquals("[4, 3]", Arrays.toString(StackUtil.getTop(s, 2)));
+// Assert.assertEquals(true, StackUtil.isValidPairs("([e{d}f])"));
+ Assert.assertEquals(false, StackUtil.isValidPairs("([b{x]y})"));
- Assert.assertEquals("13", s.peek());
}
- @Test
- public void testPop(){
- Stack s = getStack();
-
- Assert.assertEquals("13", s.pop());
- Assert.assertEquals(13, s.size());
- }
}
diff --git a/group24/75939388/learning2017/src/test/java/data_structure/TokenParserTest.java b/group24/75939388/learning2017/src/test/java/data_structure/TokenParserTest.java
new file mode 100644
index 0000000000..b8cde0cbed
--- /dev/null
+++ b/group24/75939388/learning2017/src/test/java/data_structure/TokenParserTest.java
@@ -0,0 +1,42 @@
+package data_structure;
+
+
+import basic.dataStructure.stack.expr.Token;
+import basic.dataStructure.stack.expr.TokenParser;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+public class TokenParserTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void test() {
+
+ TokenParser parser = new TokenParser();
+ List tokens = parser.parse("300*20+12*5-20/4");
+
+ Assert.assertEquals(300, tokens.get(0).getIntValue());
+ Assert.assertEquals("*", tokens.get(1).toString());
+ Assert.assertEquals(20, tokens.get(2).getIntValue());
+ Assert.assertEquals("+", tokens.get(3).toString());
+ Assert.assertEquals(12, tokens.get(4).getIntValue());
+ Assert.assertEquals("*", tokens.get(5).toString());
+ Assert.assertEquals(5, tokens.get(6).getIntValue());
+ Assert.assertEquals("-", tokens.get(7).toString());
+ Assert.assertEquals(20, tokens.get(8).getIntValue());
+ Assert.assertEquals("/", tokens.get(9).toString());
+ Assert.assertEquals(4, tokens.get(10).getIntValue());
+ }
+
+}
diff --git a/group24/75939388/learning2017/src/test/java/miniJVM/ClassFileloaderTest.java b/group24/75939388/learning2017/src/test/java/miniJVM/ClassFileloaderTest.java
new file mode 100644
index 0000000000..a1e230b9f0
--- /dev/null
+++ b/group24/75939388/learning2017/src/test/java/miniJVM/ClassFileloaderTest.java
@@ -0,0 +1,346 @@
+package miniJVM;
+
+import miniJVM.clz.ClassFile;
+import miniJVM.clz.ClassIndex;
+import miniJVM.cmd.BiPushCmd;
+import miniJVM.cmd.ByteCodeCommand;
+import miniJVM.cmd.OneOperandCmd;
+import miniJVM.cmd.TwoOperandCmd;
+import miniJVM.constant.*;
+import miniJVM.field.Field;
+import miniJVM.loader.ClassFileLoader;
+import miniJVM.method.Method;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+public class ClassFileloaderTest {
+
+
+ private static final String FULL_QUALIFIED_CLASS_NAME = "miniJVM.EmployeeV1";
+
+ static String path1 = "resources/classes";
+ static String path2 = "resources/classes";
+
+ static ClassFile clzFile = null;
+ static {
+ ClassFileLoader loader = new ClassFileLoader();
+ loader.addClassPath(path1);
+// String className = "com.coderising.jvm.test.EmployeeV1";
+// String path = "resources/classes/EmployeeV1.class";
+ String className = "miniJVM.EmployeeV1";
+ clzFile = loader.loadClass(className);
+ }
+
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testClassPath(){
+
+ ClassFileLoader loader = new ClassFileLoader();
+ loader.addClassPath(path1);
+ loader.addClassPath(path2);
+
+ String clzPath = loader.getClassPath();
+
+ Assert.assertEquals(path1+";"+path2,clzPath);
+
+ }
+
+ @Test
+ public void testClassFileLength() {
+
+ ClassFileLoader loader = new ClassFileLoader();
+ loader.addClassPath(path1);
+
+// String className = "miniJVM.EmployeeV1";
+
+ byte[] byteCodes = loader.readBinaryCode(FULL_QUALIFIED_CLASS_NAME);
+
+ // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大
+ Assert.assertEquals(1024, byteCodes.length);
+
+ }
+
+
+ @Test
+ public void testMagicNumber(){
+ ClassFileLoader loader = new ClassFileLoader();
+ loader.addClassPath(path1);
+// String className = "com.coderising.jvm.test.EmployeeV1";
+ byte[] byteCodes = loader.readBinaryCode(FULL_QUALIFIED_CLASS_NAME);
+ byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+
+
+ String acctualValue = this.byteToHexString(codes);
+
+ Assert.assertEquals("cafebabe", acctualValue);
+ }
+
+
+
+ private String byteToHexString(byte[] codes ){
+ StringBuffer buffer = new StringBuffer();
+ for(int i=0;i", utf8Info.getValue());
+
+ utf8Info = (UTF8Info) pool.getConstantInfo(10);
+ Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue());
+
+ utf8Info = (UTF8Info) pool.getConstantInfo(11);
+ Assert.assertEquals("Code", utf8Info.getValue());
+ }
+
+ {
+ MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12);
+ Assert.assertEquals(3, methodRef.getClassInfoIndex());
+ Assert.assertEquals(13, methodRef.getNameAndTypeIndex());
+ }
+
+ {
+ NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13);
+ Assert.assertEquals(9, nameAndType.getIndex1());
+ Assert.assertEquals(14, nameAndType.getIndex2());
+ }
+ //抽查几个吧
+ {
+ MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45);
+ Assert.assertEquals(1, methodRef.getClassInfoIndex());
+ Assert.assertEquals(46, methodRef.getNameAndTypeIndex());
+ }
+
+ {
+ UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53);
+ Assert.assertEquals("EmployeeV1.java", utf8Info.getValue());
+ }
+ }
+
+ @Test
+ public void testClassIndex(){
+
+ ClassIndex clzIndex = clzFile.getClzIndex();
+ ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex());
+ ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex());
+
+
+ Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName());
+ Assert.assertEquals("java/lang/Object", superClassInfo.getClassName());
+ }
+
+ /**
+ * 下面是第三次JVM课应实现的测试用例
+ */
+ @Test
+ public void testReadFields(){
+
+ List fields = clzFile.getFields();
+ Assert.assertEquals(2, fields.size());
+ {
+ Field f = fields.get(0);
+ Assert.assertEquals("name:Ljava/lang/String;", f.toString());
+ }
+ {
+ Field f = fields.get(1);
+ Assert.assertEquals("age:I", f.toString());
+ }
+ }
+ @Test
+ public void testMethods(){
+
+ List methods = clzFile.getMethods();
+ ConstantPool pool = clzFile.getConstantPool();
+
+ {
+ Method m = methods.get(0);
+ assertMethodEquals(pool,m,
+ "",
+ "(Ljava/lang/String;I)V",
+ "2ab7000c2a2bb5000f2a1cb50011b1");
+
+ }
+ {
+ Method m = methods.get(1);
+ assertMethodEquals(pool,m,
+ "setName",
+ "(Ljava/lang/String;)V",
+ "2a2bb5000fb1");
+
+ }
+ {
+ Method m = methods.get(2);
+ assertMethodEquals(pool,m,
+ "setAge",
+ "(I)V",
+ "2a1bb50011b1");
+ }
+ {
+ Method m = methods.get(3);
+ assertMethodEquals(pool,m,
+ "sayHello",
+ "()V",
+ "b2001c1222b60024b1");
+
+ }
+ {
+ Method m = methods.get(4);
+ assertMethodEquals(pool,m,
+ "main",
+ "([Ljava/lang/String;)V",
+ "bb000159122b101db7002d4c2bb6002fb1");
+ }
+ }
+
+ private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){
+ String methodName = pool.getUTF8String(m.getNameIndex());
+ String methodDesc = pool.getUTF8String(m.getDescriptorIndex());
+ String code = m.getCodeAttr().getCode();
+ Assert.assertEquals(expectedName, methodName);
+ Assert.assertEquals(expectedDesc, methodDesc);
+ Assert.assertEquals(expectedCode, code);
+ }
+
+ @Test
+ public void testByteCodeCommand(){
+ {
+ Method initMethod = this.clzFile.getMethod("", "(Ljava/lang/String;I)V");
+ ByteCodeCommand [] cmds = initMethod.getCmds();
+
+ assertOpCodeEquals("0: aload_0", cmds[0]);
+ assertOpCodeEquals("1: invokespecial #12", cmds[1]);
+ assertOpCodeEquals("4: aload_0", cmds[2]);
+ assertOpCodeEquals("5: aload_1", cmds[3]);
+ assertOpCodeEquals("6: putfield #15", cmds[4]);
+ assertOpCodeEquals("9: aload_0", cmds[5]);
+ assertOpCodeEquals("10: iload_2", cmds[6]);
+ assertOpCodeEquals("11: putfield #17", cmds[7]);
+ assertOpCodeEquals("14: return", cmds[8]);
+ }
+
+ {
+ Method setNameMethod = this.clzFile.getMethod("setName", "(Ljava/lang/String;)V");
+ ByteCodeCommand [] cmds = setNameMethod.getCmds();
+
+ assertOpCodeEquals("0: aload_0", cmds[0]);
+ assertOpCodeEquals("1: aload_1", cmds[1]);
+ assertOpCodeEquals("2: putfield #15", cmds[2]);
+ assertOpCodeEquals("5: return", cmds[3]);
+
+ }
+
+ {
+ Method sayHelloMethod = this.clzFile.getMethod("sayHello", "()V");
+ ByteCodeCommand [] cmds = sayHelloMethod.getCmds();
+
+ assertOpCodeEquals("0: getstatic #28", cmds[0]);
+ assertOpCodeEquals("3: ldc #34", cmds[1]);
+ assertOpCodeEquals("5: invokevirtual #36", cmds[2]);
+ assertOpCodeEquals("8: return", cmds[3]);
+
+ }
+
+ {
+ Method mainMethod = this.clzFile.getMainMethod();
+
+ ByteCodeCommand[] cmds = mainMethod.getCmds();
+
+ assertOpCodeEquals("0: new #1", cmds[0]);
+ assertOpCodeEquals("3: dup", cmds[1]);
+ assertOpCodeEquals("4: ldc #43", cmds[2]);
+ assertOpCodeEquals("6: bipush 29", cmds[3]);
+ assertOpCodeEquals("8: invokespecial #45", cmds[4]);
+ assertOpCodeEquals("11: astore_1", cmds[5]);
+ assertOpCodeEquals("12: aload_1", cmds[6]);
+ assertOpCodeEquals("13: invokevirtual #47", cmds[7]);
+ assertOpCodeEquals("16: return", cmds[8]);
+ }
+
+ }
+
+ private void assertOpCodeEquals(String expected, ByteCodeCommand cmd){
+
+ String acctual = cmd.getOffset()+": "+cmd.getReadableCodeText();
+
+ if(cmd instanceof OneOperandCmd){
+ if(cmd instanceof BiPushCmd){
+ acctual += " " + ((OneOperandCmd)cmd).getOperand();
+ } else{
+ acctual += " #" + ((OneOperandCmd)cmd).getOperand();
+ }
+ }
+ if(cmd instanceof TwoOperandCmd){
+ acctual += " #" + ((TwoOperandCmd)cmd).getIndex();
+ }
+ Assert.assertEquals(expected, acctual);
+ }
+
+}
diff --git a/group24/75939388/learning2017/src/test/java/miniJVM/EmployeeV1.java b/group24/75939388/learning2017/src/test/java/miniJVM/EmployeeV1.java
new file mode 100644
index 0000000000..e345de37ae
--- /dev/null
+++ b/group24/75939388/learning2017/src/test/java/miniJVM/EmployeeV1.java
@@ -0,0 +1,28 @@
+package miniJVM;
+
+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/75939388/learning2017/src/test/java/miniJVM/miniJVMTest.java b/group24/75939388/learning2017/src/test/java/miniJVM/miniJVMTest.java
new file mode 100644
index 0000000000..9fb146de10
--- /dev/null
+++ b/group24/75939388/learning2017/src/test/java/miniJVM/miniJVMTest.java
@@ -0,0 +1,19 @@
+package miniJVM;
+
+import thread.download.ClassFileReader;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author : 温友朝
+ * @date : 2017/4/18
+ */
+public class miniJVMTest {
+
+ @Test
+ public void readCafebabe(){
+ Assert.assertEquals("cafebabe", ClassFileReader.readNextU4Bytes(0));
+ }
+
+
+}