diff --git a/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/StackUtil.java b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/StackUtil.java new file mode 100644 index 0000000000..1e43329fcc --- /dev/null +++ b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/StackUtil.java @@ -0,0 +1,132 @@ +package com.github.wdn.coding2017.basic.stack; + +import com.github.wdn.coding2017.basic.Stack; + +public class StackUtil { + + + /** + * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后, 元素次序变为: 1,2,3,4,5 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + */ + public static void reverse(Stack s) { + Stack stack = new Stack(); + Stack stack1 = new Stack(); + while (!s.isEmpty()){ + stack.push(s.pop()); + } + while (!stack.isEmpty()){ + stack1.push(stack.pop()); + } + while (!stack1.isEmpty()){ + s.push(stack1.pop()); + } + } + + /** + * 删除栈中的某个元素 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * + * @param o + */ + public static void remove(Stack s,Object o) { + Stack stack = new Stack(); + while (!s.isEmpty()) { + Object popObject = s.pop(); + if(popObject.equals(o)){ + break; + } + stack.push(popObject); + } + while (!stack.isEmpty()){ + s.push(stack.pop()); + } + } + + /** + * 从栈顶取得len个元素, 原来的栈中元素保持不变 + * 注意:只能使用Stack的基本操作,即push,pop,peek,isEmpty, 可以使用另外一个栈来辅助 + * @param len + * @return + */ + public static Object[] getTop(Stack s,int len) { + if (len > s.size() || len < 0) { + throw new IndexOutOfBoundsException(); + } + Object[] result = new Object[len]; + Stack stack = new Stack(); + for (int i = 0; i < len; i++) { + Object o = s.pop(); + result[i]=o; + stack.push(o); + } + while (!stack.isEmpty()){ + s.push(stack.pop()); + } + return result; + } + /** + * 字符串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){ + if(s.length()<2){ + return false; + } + Stack s1 = new Stack(); + Stack s2 = new Stack(); + char[] chars = s.toCharArray(); + int charsLength = chars.length; + if(charsLength%2==1 && isBrackets(chars[charsLength / 2])){ + return false; + } + for (int i = 0; i < charsLength/2; i++) { + char c = chars[i]; + if (isBrackets(c)) { + s1.push(c); + } + } + for (int i = charsLength-1; i > charsLength/2; i--) { + char c = chars[i]; + if (isBrackets(c)) { + s2.push(c); + } + } + if (s1.size() != s2.size()) { + return false; + } + for (int i = 0; i < s1.size(); i++) { + if (!isPairing((Character) s1.pop(), (Character) s2.pop())) { + return false; + } + } + return true; + } + // parenthesis 圆括号 + // square brackets 方括号 + // braces 大括号 + // 这里用bracket表示统称 + private static boolean isBrackets(char c){ + if('['==c||']'==c|| + '('==c||')'==c|| + '{'==c||'}'==c){ + return true; + } + return false; + } + + private static boolean isPairing(char left, char right) { + if(left=='(' && right==')'){ + return true; + }else if(left=='[' && right==']'){ + return true; + }else if(left=='{' && right=='}'){ + return true; + }else { + return false; + } + } +} diff --git a/group24/626451284/data-structure/src/main/test/com/github/wdn/coding2017/basic/StackUtilTest.java b/group24/626451284/data-structure/src/main/test/com/github/wdn/coding2017/basic/StackUtilTest.java new file mode 100644 index 0000000000..7e56bbf345 --- /dev/null +++ b/group24/626451284/data-structure/src/main/test/com/github/wdn/coding2017/basic/StackUtilTest.java @@ -0,0 +1,57 @@ +package com.github.wdn.coding2017.basic; + +import com.github.wdn.coding2017.basic.stack.StackUtil; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +public class StackUtilTest { + + @Test + public void testReverse(){ + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + StackUtil.reverse(stack); + while (!stack.isEmpty()){ + System.out.println(stack.pop()); + } + } + @Test + public void testRemove(){ + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + StackUtil.remove(stack,4); + while (!stack.isEmpty()){ + System.out.println(stack.pop()); + } + } + @Test + public void testGetTop(){ + Stack stack = new Stack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + Object[] o = StackUtil.getTop(stack,0); + System.out.println(Arrays.toString(o)); + while (!stack.isEmpty()){ + System.out.println(stack.pop()); + } + } + @Test + public void testIsValidPairs(){ + Assert.assertEquals(true,StackUtil.isValidPairs("([e{d}f])")); + Assert.assertEquals(false,StackUtil.isValidPairs("([b{x]y})")); + Assert.assertEquals(false,StackUtil.isValidPairs("([({e}f])")); + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/AccessFlag.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/AccessFlag.java new file mode 100644 index 0000000000..b6968a64e5 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/AccessFlag.java @@ -0,0 +1,7 @@ +package com.github.wdn.coding2017.jvm.clz; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +public class AccessFlag { +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java new file mode 100644 index 0000000000..3b321732ce --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java @@ -0,0 +1,60 @@ +package com.github.wdn.coding2017.jvm.clz; + +import com.github.wdn.coding2017.jvm.constant.ConstantPool; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +public class ClassFile { + private int minorVersion; + private int majorVersion; + private ConstantPool constantPool; + private AccessFlag accessFlag; + private ClassIndex classIndex; + public void print() { + } + + public int getMinorVersion() { + return minorVersion; + } + + public int getMajorVersion() { + return majorVersion; + } + + public void setMinorVersion(int minorVersion) { + this.minorVersion = minorVersion; + } + + public void setMajorVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + + public ConstantPool getConstantPool() { + return constantPool; + } + + public void setConstantPool(ConstantPool constantPool) { + this.constantPool = constantPool; + } + + public AccessFlag getAccessFlag() { + return accessFlag; + } + + public void setAccessFlag(AccessFlag accessFlag) { + this.accessFlag = accessFlag; + } + + public ClassIndex getClassIndex() { + return classIndex; + } + + public void setClassIndex(ClassIndex classIndex) { + this.classIndex = classIndex; + } + + public ClassIndex getClzIndex() { + return null; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassIndex.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassIndex.java new file mode 100644 index 0000000000..f65a403d0a --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassIndex.java @@ -0,0 +1,20 @@ +package com.github.wdn.coding2017.jvm.clz; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +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 int getSuperClassIndex() { + return superClassIndex; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ClassInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ClassInfo.java new file mode 100644 index 0000000000..358f935e75 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ClassInfo.java @@ -0,0 +1,35 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +public class ClassInfo extends ConstantInfo{ + private int nameIndex; + public ClassInfo(ConstantPool constantPool){ + super(constantPool); + } + @Override + public int getType() { + return CLASS_INFO; + } + @Override + public String getValue() { + return getConstantPool().getConstantInfo(nameIndex).getValue(); + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getUtf8Index() { + return 0; + } + + public String getClassName() { + return getConstantPool().getConstantInfo(nameIndex).getValue(); + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantInfo.java new file mode 100644 index 0000000000..24975d30c8 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantInfo.java @@ -0,0 +1,30 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +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 constantPool){ + this.constantPool = constantPool; + } + public abstract int getType(); + public abstract String getValue(); + public ConstantPool getConstantPool(){ + return constantPool; + } + public ConstantInfo getConstantInfo(int index){ + return constantPool.getConstantInfo(index); + } + +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantPool.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantPool.java new file mode 100644 index 0000000000..3a3f4e03e4 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/ConstantPool.java @@ -0,0 +1,32 @@ +package com.github.wdn.coding2017.jvm.constant; + + +import java.util.ArrayList; + +/** + * Created by Administrator on 2017/4/6 0006. + */ +public class ConstantPool { + public static ArrayList constantPool = new ArrayList(); + static{ + constantPool.add(new NullConstantInfo()); + } + public void put(ConstantInfo info){ + constantPool.add(info); + } + public int getSize() { + return constantPool.size()-1; + } + + public ConstantInfo getConstantInfo(int i) { + return constantPool.get(i); + } + @Override + public String toString(){ + StringBuffer stringBuffer = new StringBuffer(); + for (int i = 1; i < constantPool.size(); i++) { + stringBuffer.append("#"+i+"=>"+constantPool.get(i).getValue()); + } + return stringBuffer.toString(); + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/FieldRefInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/FieldRefInfo.java new file mode 100644 index 0000000000..86c89dc9c3 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/FieldRefInfo.java @@ -0,0 +1,39 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class FieldRefInfo extends ConstantInfo { + private int classInfoIndex; + private int nameAndTypeIndex; + + public FieldRefInfo(ConstantPool constantPool) { + super(constantPool); + } + + @Override + public int getType() { + return FIELD_INFO; + } + + @Override + public String getValue() { + return getConstantPool().getConstantInfo(classInfoIndex).getValue()+getConstantPool().getConstantInfo(nameAndTypeIndex).getValue(); + } + + 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; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/MethodRefInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/MethodRefInfo.java new file mode 100644 index 0000000000..e4d6412cd1 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/MethodRefInfo.java @@ -0,0 +1,37 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class MethodRefInfo extends ConstantInfo { + private int classInfoIndex; + private int nameAndTypeIndex; + + public MethodRefInfo(ConstantPool constantPool) { + super(constantPool); + } + @Override + public int getType() { + return METHOD_INFO; + } + @Override + public String getValue() { + return getConstantPool().getConstantInfo(classInfoIndex).getValue()+getConstantPool().getConstantInfo(nameAndTypeIndex).getValue(); + } + + 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; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NameAndTypeInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NameAndTypeInfo.java new file mode 100644 index 0000000000..3a3f1bf4c8 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NameAndTypeInfo.java @@ -0,0 +1,38 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class NameAndTypeInfo extends ConstantInfo{ + private int nameIndex; + private int descriptorIndex; + + public NameAndTypeInfo(ConstantPool constantPool) { + super(constantPool); + } + + @Override + public int getType() { + return 0; + } + @Override + public String getValue() { + return getConstantPool().getConstantInfo(nameIndex).getValue()+getConstantPool().getConstantInfo(descriptorIndex).getValue(); + } + + public int getNameIndex() { + return nameIndex; + } + + public void setNameIndex(int nameIndex) { + this.nameIndex = nameIndex; + } + + public int getDescriptorIndex() { + return descriptorIndex; + } + + public void setDescriptorIndex(int descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NullConstantInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NullConstantInfo.java new file mode 100644 index 0000000000..bea4eb973f --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/NullConstantInfo.java @@ -0,0 +1,14 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class NullConstantInfo extends ConstantInfo { + public int getType() { + return 0; + } + + public String getValue() { + return null; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/StringInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/StringInfo.java new file mode 100644 index 0000000000..a4cbd7bb5d --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/StringInfo.java @@ -0,0 +1,30 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class StringInfo extends ConstantInfo { + public StringInfo(ConstantPool constantPool) { + super(constantPool); + } + + private int stringIndex; + + @Override + public int getType() { + return 0; + } + + @Override + public String getValue() { + return getConstantPool().getConstantInfo(stringIndex).getValue(); + } + + public int getStringIndex() { + return stringIndex; + } + + public void setStringIndex(int stringIndex) { + this.stringIndex = stringIndex; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/UTF8Info.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/UTF8Info.java new file mode 100644 index 0000000000..bf5efd842a --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/constant/UTF8Info.java @@ -0,0 +1,23 @@ +package com.github.wdn.coding2017.jvm.constant; + +/** + * Created by Administrator on 2017/4/8 0008. + */ +public class UTF8Info extends ConstantInfo{ + private String value; + public UTF8Info(ConstantPool constantPool){ + super(constantPool); + } + @Override + public int getType() { + return UTF8_INFO; + } + @Override + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ByteCodeIterator.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ByteCodeIterator.java new file mode 100644 index 0000000000..1185f5040e --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ByteCodeIterator.java @@ -0,0 +1,39 @@ +package com.github.wdn.coding2017.jvm.loader; + + +import com.github.wdn.coding2017.jvm.util.Util; + +public class ByteCodeIterator { + private byte[] bytes; + private int index; + + public ByteCodeIterator(byte[] bytes){ + this.bytes = bytes; + } + + public byte[] read(){ + return new byte[]{bytes[index++]}; + } + public int readToInt(){ + return Util.byteToInt(new byte[]{bytes[index++]}); + } + public int readU2ToInt(){ + return Util.byteToInt(new byte[]{bytes[index++],bytes[index++]}); + } + public String readU2ToString(){ + return Util.byteToHexString(new byte[]{bytes[index++],bytes[index++]}); + } + public int readU4ToInt(){ + return Util.byteToInt(new byte[]{bytes[index++],bytes[index++],bytes[index++],bytes[index++]}); + } + public String readU4ToString(){ + return Util.byteToHexString(new byte[]{bytes[index++],bytes[index++],bytes[index++],bytes[index++]}); + } + public String readCustomToString(int len){ + byte[] b = new byte[len]; + for (int i = 0; i < len; i++) { + b[i] = bytes[index++]; + } + return new String(b); + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileLoader.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileLoader.java index 20c8183f3a..6f29b692d4 100644 --- a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileLoader.java +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileLoader.java @@ -1,5 +1,6 @@ package com.github.wdn.coding2017.jvm.loader; +import com.github.wdn.coding2017.jvm.clz.ClassFile; import org.apache.commons.io.FileUtils; import java.io.File; @@ -38,7 +39,7 @@ public byte[] readBinaryCode(String className) { int offset=0; // for循环使用inputStream api读取 一次读完。。 for(offset = 0; offset < fileLength && (len = inputStream.read(fileBytes, offset, (int)fileLength - offset)) != -1; offset += len) { - System.out.println("dd"); + ; } // while循环使用System.arraycopy读取 /*while ((len = inputStream.read(bytes))>-1){ @@ -73,8 +74,10 @@ public String getClassPath(){ return stringBuffer.toString(); } - - - + public ClassFile loadClass(String className) { + ClassFileParser classFileParser = new ClassFileParser(); + ClassFile classFile = classFileParser.parse(readBinaryCode(className)); + return classFile; + } } diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileParser.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileParser.java new file mode 100644 index 0000000000..fe2bcc52e3 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/loader/ClassFileParser.java @@ -0,0 +1,76 @@ +package com.github.wdn.coding2017.jvm.loader; + +import com.github.wdn.coding2017.jvm.clz.AccessFlag; +import com.github.wdn.coding2017.jvm.clz.ClassFile; +import com.github.wdn.coding2017.jvm.clz.ClassIndex; +import com.github.wdn.coding2017.jvm.constant.*; + +public class ClassFileParser { + + public ClassFile parse(byte[] codes) { + ByteCodeIterator iter = new ByteCodeIterator(codes); + String magic = iter.readU4ToString(); + if(!"cafebabe".equals(magic)){ + throw new Error(); + } + ClassFile classFile = new ClassFile(); + classFile.setMinorVersion(iter.readU2ToInt()); + classFile.setMajorVersion(iter.readU2ToInt()); + classFile.setConstantPool(parseConstantPool(iter)); + classFile.setAccessFlag(parseAccessFlag(iter)); + classFile.setClassIndex(parseClassIndex(iter)); + return classFile; + } + + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + + return null; + } + + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + + return null; + + } + + public ConstantPool parseConstantPool(ByteCodeIterator iter) { + ConstantPool pool = new ConstantPool(); + int constantPoolNum = iter.readU2ToInt(); + for (int i = 0; i < constantPoolNum-1; i++) { + int type = iter.readToInt(); + if(type==7){// class + ClassInfo classInfo = new ClassInfo(pool); + classInfo.setNameIndex(iter.readU2ToInt()); + pool.put(classInfo); + }else if(type==9){// Fieldref + FieldRefInfo fieldRefInfo = new FieldRefInfo(pool); + fieldRefInfo.setClassInfoIndex(iter.readU2ToInt()); + fieldRefInfo.setNameAndTypeIndex(iter.readU2ToInt()); + pool.put(fieldRefInfo); + }else if(type==10){// Methodref + MethodRefInfo methodRefInfo = new MethodRefInfo(pool); + methodRefInfo.setClassInfoIndex(iter.readU2ToInt()); + methodRefInfo.setNameAndTypeIndex(iter.readU2ToInt()); + pool.put(methodRefInfo); + }else if(type==1){// Utf8 + int length = iter.readU2ToInt(); + String value = iter.readCustomToString(length); + UTF8Info utf8Info = new UTF8Info(pool); + utf8Info.setValue(value); + pool.put(utf8Info); + }else if(type==8){// String + StringInfo stringInfo = new StringInfo(pool); + stringInfo.setStringIndex(iter.readU2ToInt()); + pool.put(stringInfo); + }else if(type==12){// NameAndType + NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(pool); + nameAndTypeInfo.setNameIndex(iter.readU2ToInt()); + nameAndTypeInfo.setDescriptorIndex(iter.readU2ToInt()); + pool.put(nameAndTypeInfo); + }else{ + System.out.println("未知类型"+type); + } + } + return pool; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/test/ClassFileloaderTest.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/test/ClassFileloaderTest.java index 346159abb5..907a480480 100644 --- a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/test/ClassFileloaderTest.java +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/test/ClassFileloaderTest.java @@ -1,6 +1,10 @@ package com.github.wdn.coding2017.jvm.test; +import com.github.wdn.coding2017.jvm.clz.ClassFile; +import com.github.wdn.coding2017.jvm.clz.ClassIndex; +import com.github.wdn.coding2017.jvm.constant.*; import com.github.wdn.coding2017.jvm.loader.ClassFileLoader; +import com.github.wdn.coding2017.jvm.util.Util; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -16,8 +20,17 @@ public class ClassFileloaderTest { static String path1 = "E:\\softdata\\ideaworkspace\\self\\coding2017\\group24\\626451284\\mini-jvm\\target\\classes"; static String path2 = "E:\\temp"; - - + + static ClassFile clzFile = null; + static final String FULL_QUALIFIED_CLASS_NAME=""; + static { + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path1); + String className = "com.github.wdn.coding2017.jvm.test.EmployeeV1"; + + clzFile = loader.loadClass(className); + clzFile.print(); + } @Before public void setUp() throws Exception { @@ -55,7 +68,6 @@ public void testClassFileLength() { } - @Test public void testMagicNumber(){ ClassFileLoader loader = new ClassFileLoader(); @@ -65,27 +77,93 @@ public void testMagicNumber(){ byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; - String acctualValue = this.byteToHexString(codes); + String acctualValue = Util.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.getNameIndex()); + Assert.assertEquals(14, nameAndType.getDescriptorIndex()); + } + //抽查几个吧 + { + 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()); } - return buffer.toString(); } + @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()); + } } diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/util/Util.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/util/Util.java new file mode 100644 index 0000000000..1e54f24a79 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/util/Util.java @@ -0,0 +1,24 @@ +package com.github.wdn.coding2017.jvm.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