diff --git a/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExpr.java b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExpr.java new file mode 100644 index 0000000000..3a8f013b78 --- /dev/null +++ b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExpr.java @@ -0,0 +1,90 @@ +package com.github.wdn.coding2017.basic.stack.expr; + +import com.github.wdn.coding2017.basic.Stack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by Administrator on 2017/4/13 0013. + */ +public class InfixExpr { + private String expr; + private static Map priorityMap = new HashMap(); + static{ + priorityMap.put("+",1); + priorityMap.put("-",1); + priorityMap.put("*",2); + priorityMap.put("/",2); + } + public InfixExpr(String expr) { + this.expr = expr; + } + public float calculate(float a,float b,String operator) throws IllegalAccessException { + float result; + switch (operator) { + case "+": + result = a+b; + break; + case "-": + result = a-b; + break; + case "*": + result = a*b; + break; + case "/": + result = a/b; + break; + default: + throw new IllegalAccessException(); + } + return result; + } + public float evaluate() { + try { + String[] numArr = expr.split("[+|\\-|*|/]"); + String[] operatorArr = expr.split("\\d+\\d*"); + Object[] operators = Arrays.stream(operatorArr).filter(x -> !"".equals(x.trim())).toArray(); + Stack numStack = new Stack(); + Stack operatorStack = new Stack(); + numStack.push(numArr[0]); + for (int i = 0; i < operators.length; i++) { + int number = Integer.parseInt(numArr[i + 1]); + String operator = operators[i].toString(); + if (!operatorStack.isEmpty() && priorityMap.get(operatorStack.peek()) < priorityMap.get(operator)) { + float currentResult = calculate(Integer.parseInt(numStack.pop().toString()), number, operator); + numStack.push(currentResult); + } else if(!operatorStack.isEmpty() && priorityMap.get(operatorStack.peek()) >= priorityMap.get(operator)){ + float b = Float.parseFloat(numStack.pop().toString()); + float a = Float.parseFloat(numStack.pop().toString()); + String currentOperator = operatorStack.pop().toString(); + float result = calculate(a, b, currentOperator); + numStack.push(result); + numStack.push(number); + operatorStack.push(operator); + }else { + numStack.push(number); + operatorStack.push(operator); + } + } + while (!operatorStack.isEmpty()) { + float b = Float.parseFloat(numStack.pop().toString()); + float a = Float.parseFloat(numStack.pop().toString()); + String operator = operatorStack.pop().toString(); + float result = calculate(a, b, operator); + numStack.push(result); + } + return Float.parseFloat(numStack.pop().toString()); + } catch (Exception e) { + e.printStackTrace(); + } + return 0; + } + + public static void main(String[] args) { + InfixExpr infixExpr = new InfixExpr("2+3*4+5"); + float r = infixExpr.evaluate(); + System.out.println(r); + } +} diff --git a/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExprTest.java b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExprTest.java new file mode 100644 index 0000000000..a05f9fd578 --- /dev/null +++ b/group24/626451284/data-structure/src/main/java/com/github/wdn/coding2017/basic/stack/expr/InfixExprTest.java @@ -0,0 +1,50 @@ +package com.github.wdn.coding2017.basic.stack.expr; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by Administrator on 2017/4/13 0013. + */ +public class InfixExprTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testEvaluate() { + //InfixExpr expr = new InfixExpr("300*20+12*5-20/4"); + { + InfixExpr expr = new InfixExpr("2+3*4+5"); + Assert.assertEquals(19.0, expr.evaluate(), 0.001f); + } + { + InfixExpr expr = new InfixExpr("3*20+12*5-40/2"); + Assert.assertEquals(100.0, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("3*20/2"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("20/2*3"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + { + InfixExpr expr = new InfixExpr("10-30+50"); + Assert.assertEquals(30, expr.evaluate(), 0.001f); + } + + } + +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/AttributeInfo.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/AttributeInfo.java new file mode 100644 index 0000000000..8ec8464918 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/AttributeInfo.java @@ -0,0 +1,20 @@ +package com.github.wdn.coding2017.jvm.attr; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +public 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"; + + private int attributeNameIndex;// u2 + private int attributeLength; //u4 + public AttributeInfo(int attributeNameIndex,int attributeLength){ + this.attributeNameIndex = attributeNameIndex; + this.attributeLength = attributeLength; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/CodeAttr.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/CodeAttr.java new file mode 100644 index 0000000000..9400b629b2 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/CodeAttr.java @@ -0,0 +1,58 @@ +package com.github.wdn.coding2017.jvm.attr; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +public class CodeAttr extends AttributeInfo { + private int maxStack; + private int maxLocals; + private String code; + private LineNumberTable lineNumTable; + private LocalVariableTable localVarTable; + private StackMapTable stackMapTable; + public CodeAttr(int attributeNameIndex, int attributeLength, int maxStack, int maxLocals, String code) { + super(attributeNameIndex, attributeLength); + this.maxStack = maxStack; + this.maxLocals = maxLocals; + this.code = code; + } + @Override + public String toString(){ + return code; + } + public int getMaxStack() { + return maxStack; + } + + public void setMaxStack(int maxStack) { + this.maxStack = maxStack; + } + + public int getMaxLocals() { + return maxLocals; + } + + public void setMaxLocals(int maxLocals) { + this.maxLocals = maxLocals; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public void setLineNumTable(LineNumberTable lineNumTable) { + this.lineNumTable = lineNumTable; + } + + public void setLocalVarTable(LocalVariableTable localVarTable) { + this.localVarTable = localVarTable; + } + + public void setStackMapTable(StackMapTable stackMapTable) { + this.stackMapTable = stackMapTable; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LineNumberTable.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LineNumberTable.java new file mode 100644 index 0000000000..594e574114 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LineNumberTable.java @@ -0,0 +1,48 @@ +package com.github.wdn.coding2017.jvm.attr; + +import com.github.wdn.coding2017.jvm.constant.ConstantPool; +import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +public class LineNumberTable extends AttributeInfo{ + public LineNumberTable(int attributeNameIndex, int attributeLength) { + super(attributeNameIndex, attributeLength); + } + List lineNumberItems = new ArrayList<>(); + private static class LineNumberItem{ + int startPC; + int 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.lineNumberItems.add(item); + } + + public static LineNumberTable parse(ByteCodeIterator iter){ + LineNumberTable lineNumberTable = new LineNumberTable(0, iter.readU4ToInt()); + int lineNumberTableCount = iter.readU2ToInt(); + for (int l = 0; l < lineNumberTableCount; l++) { + LineNumberItem lineNumberItem = new LineNumberItem(); + lineNumberItem.setStartPC(iter.readU2ToInt()); + lineNumberItem.setLineNum(iter.readU2ToInt()); + lineNumberTable.addLineNumberItem(lineNumberItem); + } + return lineNumberTable; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTable.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTable.java new file mode 100644 index 0000000000..f84a96e2d9 --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTable.java @@ -0,0 +1,80 @@ +package com.github.wdn.coding2017.jvm.attr; + +import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +public class LocalVariableTable extends AttributeInfo{ + List localVariableTableItems = new ArrayList<>(); + public LocalVariableTable(int attributeNameIndex, int attributeLength) { + super(attributeNameIndex, attributeLength); + } + private static class LocalVariableTableItem{ + int startPC; + int length; + int nameIndex; + int descriptorIndex; + 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 getDescriptorIndex() { + return descriptorIndex; + } + + public void setDescriptorIndex(int descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + } + private void addLocalVariableItem(LocalVariableTableItem item){ + this.localVariableTableItems.add(item); + } + public static LocalVariableTable parse(ByteCodeIterator iter) { + LocalVariableTable localVariableTable = new LocalVariableTable(iter.readU2ToInt(),iter.readU2ToInt()); + int LocalVariableTableCount = iter.readU2ToInt(); + for (int l = 0; l < LocalVariableTableCount; l++) { + LocalVariableTableItem item = new LocalVariableTableItem(); + item.setStartPC(iter.readU2ToInt()); + item.setLength(iter.readU2ToInt()); + item.setNameIndex(iter.readU2ToInt()); + item.setDescriptorIndex(iter.readU2ToInt()); + item.setIndex(iter.readU2ToInt()); + localVariableTable.addLocalVariableItem(item); + } + return localVariableTable; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTypeTable.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTypeTable.java new file mode 100644 index 0000000000..cb05a8074d --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/LocalVariableTypeTable.java @@ -0,0 +1,7 @@ +package com.github.wdn.coding2017.jvm.attr; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +public class LocalVariableTypeTable { +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/StackMapTable.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/StackMapTable.java new file mode 100644 index 0000000000..7c607031be --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/attr/StackMapTable.java @@ -0,0 +1,29 @@ +package com.github.wdn.coding2017.jvm.attr; + +import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator; + +/** + * Created by Administrator on 2017/4/12 0012. + */ +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.readU2ToInt(); + int len = iter.readU4ToInt(); + StackMapTable t = new StackMapTable(index,len); + //后面的StackMapTable太过复杂, 不再处理, 只把原始的代码读进来保存 + String code = iter.readCustomToString(len); + t.setOriginalCode(code); + return t; + } + + private void setOriginalCode(String code) { + this.originalCode = code; + + } +} 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 index b6968a64e5..a0fcba07f6 100644 --- 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 @@ -4,4 +4,34 @@ * Created by Administrator on 2017/4/6 0006. */ public class AccessFlag { + /* + enum { + ACC_PUBLIC,ACC_FINAL,ACC_SUPER,ACC_INTERFACE,ACC_ABSTRACT,ACC_SYNTHETIC + } + private int ACC_PUBLIC =0x0001; //可以被包的类外访问。 + private int ACC_FINAL =0x0010; //不允许有子类。 + private int ACC_SUPER =0x0020;//当用到invokespecial指令时,需要特殊处理③的父类方法。 + private int ACC_INTERFACE= 0x0200; //标识定义的是接口而不是类。 + private int ACC_ABSTRACT= 0x0400; //不能被实例化。 + private int ACC_SYNTHETIC= 0x1000; //标识并非Java源码生成的代码 + */ + 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; + } } diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java index 3b321732ce..813c050a53 100644 --- a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/ClassFile.java @@ -2,6 +2,8 @@ import com.github.wdn.coding2017.jvm.constant.ConstantPool; +import java.util.List; + /** * Created by Administrator on 2017/4/6 0006. */ @@ -11,6 +13,8 @@ public class ClassFile { private ConstantPool constantPool; private AccessFlag accessFlag; private ClassIndex classIndex; + private List fields; + private List methods; public void print() { } @@ -57,4 +61,20 @@ public void setClassIndex(ClassIndex classIndex) { public ClassIndex getClzIndex() { return null; } + + public List getFields() { + return fields; + } + + public void setFields(List fields) { + this.fields = fields; + } + + public List getMethods() { + return methods; + } + + public void setMethods(List methods) { + this.methods = methods; + } } diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Field.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Field.java new file mode 100644 index 0000000000..8d557b10de --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Field.java @@ -0,0 +1,74 @@ +package com.github.wdn.coding2017.jvm.clz; + +import com.github.wdn.coding2017.jvm.constant.ConstantPool; +import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Administrator on 2017/4/10 0010. + */ +public class Field { + private AccessFlag accessFlag; // 例如是public , private 等等 + private int nameIndex; // 指向常量池的入口 + private int descriptorIndex; //指向常量池的入口 + private int attributesCount; // 该字段的属性有多少个 + private ConstantPool pool; + // attribute_info attributes[attributes_count]; //属性信息 + private Field(){ + } + public Field(ConstantPool pool){ + this.pool = pool; + } + public static Field parse(ByteCodeIterator iter){ + Field field = new Field(); + field.setAccessFlags(new AccessFlag(iter.readU2ToInt())); + field.setNameIndex(iter.readU2ToInt()); + field.setDescriptorIndex(iter.readU2ToInt()); + int attCount = iter.readU2ToInt(); + if(attCount>0){ + throw new RuntimeException("字段属性数量大于0"); + } + field.setAttributesCount(attCount); + return field; + } + public String toString(){ + return pool.getConstantInfo(nameIndex).getValue()+pool.getConstantInfo(descriptorIndex).getValue(); + } + public AccessFlag getAccessFlags() { + return accessFlag; + } + + public void setAccessFlags(AccessFlag accessFlags) { + this.accessFlag = accessFlags; + } + + 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; + } + + public int getAttributesCount() { + return attributesCount; + } + + public void setAttributesCount(int attributesCount) { + this.attributesCount = attributesCount; + } + + public void setPool(ConstantPool pool) { + this.pool = pool; + } +} diff --git a/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Method.java b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Method.java new file mode 100644 index 0000000000..b6ace8ebce --- /dev/null +++ b/group24/626451284/mini-jvm/src/main/java/com/github/wdn/coding2017/jvm/clz/Method.java @@ -0,0 +1,99 @@ +package com.github.wdn.coding2017.jvm.clz; + +import com.github.wdn.coding2017.jvm.attr.*; +import com.github.wdn.coding2017.jvm.constant.ConstantPool; +import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator; + +/** + * Created by Administrator on 2017/4/10 0010. + */ +public class Method { + private AccessFlag accessFlags; + private int nameIndex; + private int descriptorIndex; + private CodeAttr code; + //attributes[attributes_count]; + private ConstantPool pool; + public static Method parse(ConstantPool pool, ByteCodeIterator iter) { + Method method = new Method(); + method.setAccessFlags(new AccessFlag(iter.readU2ToInt())); + method.setNameIndex(iter.readU2ToInt()); + method.setDescriptorIndex(iter.readU2ToInt()); + int methodAttributesCount = iter.readU2ToInt(); + for (int j = 0; j < methodAttributesCount; j++) { + int methodAttributeNameIndex = iter.readU2ToInt(); + String methodAttributeType = pool.getConstantInfo(methodAttributeNameIndex).getValue(); + if (methodAttributeType.equals(AttributeInfo.CODE)) { + CodeAttr codeAttr = new CodeAttr(methodAttributeNameIndex, iter.readU4ToInt(), iter.readU2ToInt(), iter.readU2ToInt(), iter.readCustomToString(iter.readU4ToInt())); + int ExceptionCount = iter.readU2ToInt(); + if (ExceptionCount > 0) { + throw new RuntimeException("方法有异常待解析"); + } + int codeAttributesCount = iter.readU2ToInt(); + for (int k = 0; k < codeAttributesCount; k++) { + int codeAttributeNameIndex = iter.readU2ToInt(); + String codeAttributeType = pool.getConstantInfo(codeAttributeNameIndex).getValue(); + if ("LineNumberTable".equals(codeAttributeType)) { + LineNumberTable lineNumberTable = LineNumberTable.parse(iter); + codeAttr.setLineNumTable(lineNumberTable); + } else if ("LocalVariableTable".equals(codeAttributeType)) { + LocalVariableTable localVariableTable = LocalVariableTable.parse(iter); + codeAttr.setLocalVarTable(localVariableTable); + }else if ("StackMapTable".equals(codeAttributeType)) { + StackMapTable stackMapTable = StackMapTable.parse(iter); + codeAttr.setStackMapTable(stackMapTable); + } else { + throw new RuntimeException("未知的Code附加属性类型" + codeAttributeType); + } + } + method.setCode(codeAttr); + } else { + throw new RuntimeException("未知的方法属性类型" + methodAttributeType); + } + } + return method; + } + @Override + public String toString(){ + StringBuffer stringBuffer = new StringBuffer(); + stringBuffer.append(pool.getConstantInfo(nameIndex).getValue()); + stringBuffer.append(pool.getConstantInfo(descriptorIndex).getValue()); + stringBuffer.append(code); + return stringBuffer.toString(); + } + public AccessFlag getAccessFlags() { + return accessFlags; + } + + public void setAccessFlags(AccessFlag accessFlags) { + this.accessFlags = accessFlags; + } + + 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; + } + + public CodeAttr getCode() { + return code; + } + + public void setCode(CodeAttr code) { + this.code = code; + } + + public void setPool(ConstantPool pool) { + this.pool = pool; + } +} 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 index 358f935e75..e4565e93b1 100644 --- 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 @@ -26,7 +26,7 @@ public void setNameIndex(int nameIndex) { } public int getUtf8Index() { - return 0; + return nameIndex; } public String getClassName() { 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 index 1185f5040e..dc4c1c0b54 100644 --- 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 @@ -3,6 +3,8 @@ import com.github.wdn.coding2017.jvm.util.Util; +import java.nio.charset.Charset; + public class ByteCodeIterator { private byte[] bytes; private int index; @@ -35,5 +37,6 @@ public String readCustomToString(int len){ b[i] = bytes[index++]; } return new String(b); + //return Util.byteToHexString(b); } } 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 index fe2bcc52e3..22d2e5bcd7 100644 --- 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 @@ -1,12 +1,13 @@ 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.clz.*; import com.github.wdn.coding2017.jvm.constant.*; -public class ClassFileParser { +import java.util.ArrayList; +import java.util.List; +public class ClassFileParser { + ConstantPool pool = new ConstantPool(); public ClassFile parse(byte[] codes) { ByteCodeIterator iter = new ByteCodeIterator(codes); String magic = iter.readU4ToString(); @@ -19,22 +20,50 @@ public ClassFile parse(byte[] codes) { classFile.setConstantPool(parseConstantPool(iter)); classFile.setAccessFlag(parseAccessFlag(iter)); classFile.setClassIndex(parseClassIndex(iter)); + parseInterface(iter); + classFile.setFields(parseField(iter)); + classFile.setMethods(parseMethod(iter)); return classFile; } - private AccessFlag parseAccessFlag(ByteCodeIterator iter) { - - return null; + private List parseMethod(ByteCodeIterator iter) { + int methodCount = iter.readU2ToInt(); + List methods = new ArrayList<>(methodCount); + for (int i = 0; i < methodCount; i++) { + Method method = Method.parse(pool, iter); + method.setPool(pool); + methods.add(method); + } + return methods; } - private ClassIndex parseClassIndex(ByteCodeIterator iter) { + private List parseField(ByteCodeIterator iter) { + int fieldsCount = iter.readU2ToInt(); + List fields = new ArrayList<>(fieldsCount); + for (int i = 0; i < fieldsCount; i++) { + Field field = Field.parse(iter); + field.setPool(pool); + fields.add(field); + } + return fields; + } - return null; + private void parseInterface(ByteCodeIterator iter){ + int interfaceNum = iter.readU2ToInt(); + if (interfaceNum > 0) { + throw new RuntimeException("接口数量>0"); + } + } + private AccessFlag parseAccessFlag(ByteCodeIterator iter) { + return new AccessFlag(iter.readU2ToInt()); + } + private ClassIndex parseClassIndex(ByteCodeIterator iter) { + return new ClassIndex(iter.readU2ToInt(),iter.readU2ToInt()); } 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(); @@ -68,7 +97,7 @@ public ConstantPool parseConstantPool(ByteCodeIterator iter) { nameAndTypeInfo.setDescriptorIndex(iter.readU2ToInt()); pool.put(nameAndTypeInfo); }else{ - System.out.println("未知类型"+type); + throw new RuntimeException("未知类型"+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 907a480480..9d2b468236 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 @@ -22,7 +22,7 @@ public class ClassFileloaderTest { static String path2 = "E:\\temp"; static ClassFile clzFile = null; - static final String FULL_QUALIFIED_CLASS_NAME=""; + static final String FULL_QUALIFIED_CLASS_NAME="com/coderising/jvm/test/EmployeeV1"; static { ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path1);