From 02a464b518276d6ab4d3aa194dafb96fe4f55ba7 Mon Sep 17 00:00:00 2001 From: Patrick Date: Wed, 19 Apr 2017 23:36:52 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=90=8E=E5=89=8D=E7=BC=80=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../basic/stack/expr/InfixExpr.java | 19 +-- .../basic/stack/expr/InfixToPostfix.java | 67 +++++++++ .../basic/stack/expr/InfixToPostfixTest.java | 32 +++++ .../basic/stack/expr/PostfixExpr.java | 35 +++++ .../basic/stack/expr/PostfixExprTest.java | 41 ++++++ .../basic/stack/expr/PrefixExpr.java | 36 +++++ .../basic/stack/expr/PrefixExprTest.java | 44 ++++++ .../coding2017/basic/stack/expr/Token.java | 64 +++++++++ .../basic/stack/expr/TokenParser.java | 57 ++++++++ .../basic/stack/expr/TokenParserTest.java | 41 ++++++ .../coding2017/minijvm/attr/CodeAttr.java | 24 +++- .../minijvm/attr/LineNumberTable.java | 12 +- .../minijvm/attr/LocalVariableTable.java | 15 +- .../coding2017/minijvm/clz/ClassFile.java | 13 +- .../coding2017/minijvm/cmd/BiPushCmd.java | 21 +++ .../minijvm/cmd/ByteCodeCommand.java | 132 ++++++++++++++++++ .../coding2017/minijvm/cmd/CommandParser.java | 84 +++++++++++ .../coding2017/minijvm/cmd/GetFieldCmd.java | 21 +++ .../minijvm/cmd/GetStaticFieldCmd.java | 19 +++ .../minijvm/cmd/InvokeSpecialCmd.java | 21 +++ .../minijvm/cmd/InvokeVirtualCmd.java | 21 +++ .../coding2017/minijvm/cmd/LdcCmd.java | 29 ++++ .../coding2017/minijvm/cmd/NewObjectCmd.java | 19 +++ .../coding2017/minijvm/cmd/NoOperandCmd.java | 23 +++ .../coding2017/minijvm/cmd/OneOperandCmd.java | 29 ++++ .../coding2017/minijvm/cmd/PutFieldCmd.java | 19 +++ .../coding2017/minijvm/cmd/TwoOperandCmd.java | 67 +++++++++ .../coding2017/minijvm/method/Method.java | 4 + .../minijvm/print/ClassFilePrinter.java | 45 ++++++ .../minijvm/print/ConstantPoolPrinter.java | 18 +++ .../minijvm/test/ClassFileloaderTest.java | 77 ++++++++++ 31 files changed, 1121 insertions(+), 28 deletions(-) create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixToPostfix.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixToPostfixTest.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/PostfixExpr.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/PostfixExprTest.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/PrefixExpr.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/PrefixExprTest.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/Token.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/TokenParser.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/TokenParserTest.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/BiPushCmd.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/ByteCodeCommand.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/CommandParser.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/GetFieldCmd.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/GetStaticFieldCmd.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/InvokeSpecialCmd.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/InvokeVirtualCmd.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/LdcCmd.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/NewObjectCmd.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/NoOperandCmd.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/OneOperandCmd.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/PutFieldCmd.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/TwoOperandCmd.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ClassFilePrinter.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ConstantPoolPrinter.java diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixExpr.java b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixExpr.java index 1e597a2b24..87344ca452 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixExpr.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixExpr.java @@ -33,7 +33,7 @@ private void manageMultiAndDivOper(String[] elements,Stack numStack,Stack operSt preElement = (Float)numStack.pop(); i++; nextElement = Float.valueOf(elements[i]); - numStack.push(doBaseOper(preElement,nextElement,elements[i-1])); + numStack.push(Token.doBaseOper(preElement,nextElement,elements[i-1])); } } } @@ -42,27 +42,12 @@ private void manageMultiAndDivOper(String[] elements,Stack numStack,Stack operSt private float manageAddAndMinusOper(Stack numStack,Stack operStack){ float result = 0f;; while(!operStack.isEmpty()){ - result = doBaseOper(result,(Float)numStack.pop(),(String)operStack.pop()); + result = Token.doBaseOper(result,(Float)numStack.pop(),(String)operStack.pop()); } result += (Float)numStack.pop(); return result; } - private float doBaseOper(float preData,float nextData,String oper){ - switch(oper){ - case "+": - return preData+nextData; - case "-": - return preData-nextData; - case "*": - return preData*nextData; - case "/": - return preData/nextData; - default: - throw new RuntimeException("could not recognise oper:"+oper); - } - } - public String[] getElementArray(String expression){ char[] charArray = expression.toCharArray(); StringBuffer stringBuffer = new StringBuffer(); diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixToPostfix.java b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixToPostfix.java new file mode 100644 index 0000000000..d444fef039 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/InfixToPostfix.java @@ -0,0 +1,67 @@ +package com.github.ipk2015.coding2017.basic.stack.expr; + + + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Stack; + +public class InfixToPostfix { + + public static List convert(String expr) { + int len = expr.length(); + char c,temp; + Stack stack = new Stack(); + StringBuffer buffer = new StringBuffer(); + for(int i = 0;i tokens = InfixToPostfix.convert("3+(2-5)*6/3"); + + Assert.assertEquals(3, tokens.get(0).getIntValue()); + Assert.assertEquals(2, tokens.get(1).getIntValue()); + Assert.assertEquals(5, tokens.get(2).getIntValue()); + Assert.assertEquals("-", tokens.get(3).toString()); + Assert.assertEquals(6, tokens.get(4).getIntValue()); + Assert.assertEquals("*", tokens.get(5).toString()); + Assert.assertEquals(3, tokens.get(6).getIntValue()); + Assert.assertEquals("/", tokens.get(7).toString()); + Assert.assertEquals("+", tokens.get(8).toString()); + } + +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/PostfixExpr.java b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/PostfixExpr.java new file mode 100644 index 0000000000..af427fa948 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/PostfixExpr.java @@ -0,0 +1,35 @@ +package com.github.ipk2015.coding2017.basic.stack.expr; + +import java.util.List; +import java.util.Stack; + +public class PostfixExpr { +String expr = null; + + public PostfixExpr(String expr) { + this.expr = expr; + } + + public float evaluate() { + TokenParser parser = new TokenParser(); + List list = parser.parse(expr); + + Stack stack = new Stack(); + int len = list.size(); + float preNum,afterNum; + Token token; + for(int i = 0;i list = parser.parse(expr); + + Stack stack = new Stack(); + int len = list.size(); + float preNum,afterNum; + Token token; + for(int i = 0;i 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; + 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 int getIntValue() { + return Integer.valueOf(value).intValue(); + } + 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; + } + + public static float doBaseOper(float preData,float nextData,String oper){ + switch(oper){ + case "+": + return preData+nextData; + case "-": + return preData-nextData; + case "*": + return preData*nextData; + case "/": + return preData/nextData; + default: + throw new RuntimeException("could not recognise oper:"+oper); + } + } + + +} \ No newline at end of file diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/TokenParser.java b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/TokenParser.java new file mode 100644 index 0000000000..998d1e4c8e --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/TokenParser.java @@ -0,0 +1,57 @@ +package com.github.ipk2015.coding2017.basic.stack.expr; + +import java.util.ArrayList; +import java.util.List; + +public class TokenParser { + + + public 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{ + System.out.println("char :["+c+"] is not number or operator,ignore"); + i++; + } + + } + return tokens; + } + + private int indexOfNextOperator(int i, String expr) { + + while (Character.isDigit(expr.charAt(i))) { + i++; + if (i == expr.length()) { + break; + } + } + return i; + + } + + private boolean isOperator(char c) { + String sc = String.valueOf(c); + return Token.OPERATORS.contains(sc); + } +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/TokenParserTest.java b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/TokenParserTest.java new file mode 100644 index 0000000000..2543baec60 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/basic/stack/expr/TokenParserTest.java @@ -0,0 +1,41 @@ +package com.github.ipk2015.coding2017.basic.stack.expr; + +import static org.junit.Assert.*; + +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +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/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/CodeAttr.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/CodeAttr.java index 2f141a20a3..ff7fcc4294 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/CodeAttr.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/CodeAttr.java @@ -1,6 +1,8 @@ package com.github.ipk2015.coding2017.minijvm.attr; import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.minijvm.cmd.ByteCodeCommand; +import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; import com.github.ipk2015.coding2017.minijvm.loader.ByteCodeIterator; public class CodeAttr extends AttributeInfo { @@ -12,10 +14,10 @@ public String getCode() { return code; } - //private ByteCodeCommand[] cmds ; - //public ByteCodeCommand[] getCmds() { - // return cmds; - //} + private ByteCodeCommand[] cmds ; + public ByteCodeCommand[] getCmds() { + return cmds; + } private LineNumberTable lineNumTable; private LocalVariableTable localVarTable; private StackMapTable stackMapTable; @@ -26,7 +28,7 @@ public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int this.maxLocals = maxLocals; this.codeLen = codeLen; this.code = code; - //this.cmds = cmds; + this.cmds = cmds; } public void setLineNumberTable(LineNumberTable t) { @@ -78,7 +80,17 @@ private static void addSonAttr(ClassFile clzFile,CodeAttr codeAttr,ByteCodeItera } } - + public String toString(ConstantPool pool){ + StringBuilder buffer = new StringBuilder(); + //buffer.append("Code:").append(code).append("\n"); + for(int i=0;i 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.opCode); + + return buffer.toString(); + } + public abstract String toString(ConstantPool pool); + + public String getReadableCodeText(){ + String txt = codeMap.get(opCode); + if(txt == null){ + return opCode; + } + return txt; + } + + //public abstract void execute(StackFrame frame,FrameResult result); +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/CommandParser.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/CommandParser.java new file mode 100644 index 0000000000..23b2859e6a --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/CommandParser.java @@ -0,0 +1,84 @@ +package com.github.ipk2015.coding2017.minijvm.cmd; + +import java.util.List; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; + +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) { + + + return null; + } + + private static void calcuateOffset(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/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/GetFieldCmd.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/GetFieldCmd.java new file mode 100644 index 0000000000..ad694d7eec --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/GetFieldCmd.java @@ -0,0 +1,21 @@ +package com.github.ipk2015.coding2017.minijvm.cmd; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.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/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/GetStaticFieldCmd.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/GetStaticFieldCmd.java new file mode 100644 index 0000000000..87bfca3c7f --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/GetStaticFieldCmd.java @@ -0,0 +1,19 @@ +package com.github.ipk2015.coding2017.minijvm.cmd; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.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/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/InvokeSpecialCmd.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/InvokeSpecialCmd.java new file mode 100644 index 0000000000..e573129d76 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/InvokeSpecialCmd.java @@ -0,0 +1,21 @@ +package com.github.ipk2015.coding2017.minijvm.cmd; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.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/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/InvokeVirtualCmd.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/InvokeVirtualCmd.java new file mode 100644 index 0000000000..989c3f6fae --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/InvokeVirtualCmd.java @@ -0,0 +1,21 @@ +package com.github.ipk2015.coding2017.minijvm.cmd; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.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/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/LdcCmd.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/LdcCmd.java new file mode 100644 index 0000000000..bc72a9f300 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/LdcCmd.java @@ -0,0 +1,29 @@ +package com.github.ipk2015.coding2017.minijvm.cmd; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.minijvm.constant.ConstantInfo; +import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; +import com.github.ipk2015.coding2017.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/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/NewObjectCmd.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/NewObjectCmd.java new file mode 100644 index 0000000000..973061d110 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/NewObjectCmd.java @@ -0,0 +1,19 @@ +package com.github.ipk2015.coding2017.minijvm.cmd; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.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/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/NoOperandCmd.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/NoOperandCmd.java new file mode 100644 index 0000000000..62c51c2b3a --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/NoOperandCmd.java @@ -0,0 +1,23 @@ +package com.github.ipk2015.coding2017.minijvm.cmd; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.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/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/OneOperandCmd.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/OneOperandCmd.java new file mode 100644 index 0000000000..ca6052b34c --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/OneOperandCmd.java @@ -0,0 +1,29 @@ +package com.github.ipk2015.coding2017.minijvm.cmd; + + + +import com.github.ipk2015.coding2017.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/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/PutFieldCmd.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/PutFieldCmd.java new file mode 100644 index 0000000000..e73ff203d5 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/PutFieldCmd.java @@ -0,0 +1,19 @@ +package com.github.ipk2015.coding2017.minijvm.cmd; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.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/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/TwoOperandCmd.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/TwoOperandCmd.java new file mode 100644 index 0000000000..99c6b99455 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/TwoOperandCmd.java @@ -0,0 +1,67 @@ +package com.github.ipk2015.coding2017.minijvm.cmd; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.minijvm.constant.ClassInfo; +import com.github.ipk2015.coding2017.minijvm.constant.ConstantInfo; +import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; +import com.github.ipk2015.coding2017.minijvm.constant.FieldRefInfo; +import com.github.ipk2015.coding2017.minijvm.constant.MethodRefInfo; + +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/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java index 3298a36d6b..61b91fa7b9 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java @@ -3,6 +3,7 @@ import com.github.ipk2015.coding2017.minijvm.attr.AttributeInfo; import com.github.ipk2015.coding2017.minijvm.attr.CodeAttr; import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.minijvm.cmd.ByteCodeCommand; import com.github.ipk2015.coding2017.minijvm.loader.ByteCodeIterator; public class Method { @@ -67,4 +68,7 @@ private static void addAttr(ClassFile clzFile,Method method,ByteCodeIterator ite throw new RuntimeException("方法的此属性不存在:"+attrName); } } + public ByteCodeCommand[] getCmds() { + return this.getCodeAttr().getCmds(); + } } diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ClassFilePrinter.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ClassFilePrinter.java new file mode 100644 index 0000000000..6615a189f5 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ClassFilePrinter.java @@ -0,0 +1,45 @@ +package com.github.ipk2015.coding2017.minijvm.print; + +import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; +import com.github.ipk2015.coding2017.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 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; + ClassFileLoader loader = new ClassFileLoader(); + loader.addClassPath(path); + String className = "com.coderising.jvm.test.EmployeeV1"; + + ClassFile clzFile = loader.loadClass(className); + + ClassFilePrinter printer = new ClassFilePrinter(clzFile); + + printer.print(); + } +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ConstantPoolPrinter.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ConstantPoolPrinter.java new file mode 100644 index 0000000000..295c509941 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ConstantPoolPrinter.java @@ -0,0 +1,18 @@ +package com.github.ipk2015.coding2017.minijvm.print; + +import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; + +public class ConstantPoolPrinter { + ConstantPool pool; + ConstantPoolPrinter(ConstantPool pool){ + this.pool = pool; + } + public void print(){ + + System.out.println("Constant Pool:"); + + + + + } +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/test/ClassFileloaderTest.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/test/ClassFileloaderTest.java index 0a3979119d..213046188c 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/test/ClassFileloaderTest.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/test/ClassFileloaderTest.java @@ -12,6 +12,10 @@ import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; import com.github.ipk2015.coding2017.minijvm.clz.ClassIndex; +import com.github.ipk2015.coding2017.minijvm.cmd.BiPushCmd; +import com.github.ipk2015.coding2017.minijvm.cmd.ByteCodeCommand; +import com.github.ipk2015.coding2017.minijvm.cmd.OneOperandCmd; +import com.github.ipk2015.coding2017.minijvm.cmd.TwoOperandCmd; import com.github.ipk2015.coding2017.minijvm.constant.ClassInfo; import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; import com.github.ipk2015.coding2017.minijvm.constant.MethodRefInfo; @@ -279,5 +283,78 @@ private void assertMethodEquals(ConstantPool pool,Method m , String expectedName 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); + } } From bf84de24d57c4a3857bc508d8a243049db555084 Mon Sep 17 00:00:00 2001 From: Patrick Date: Fri, 21 Apr 2017 00:23:51 +0800 Subject: [PATCH 2/3] =?UTF-8?q?jvm=20=E5=AD=97=E8=8A=82=E7=A0=81=E6=8C=87?= =?UTF-8?q?=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coding2017/minijvm/attr/CodeAttr.java | 8 ++- .../coding2017/minijvm/clz/ClassFile.java | 15 +++-- .../coding2017/minijvm/cmd/CommandParser.java | 65 ++++++++++++++++++- .../coding2017/minijvm/method/Method.java | 13 ++++ 4 files changed, 92 insertions(+), 9 deletions(-) diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/CodeAttr.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/CodeAttr.java index ff7fcc4294..c4455c6b2a 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/CodeAttr.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/attr/CodeAttr.java @@ -2,6 +2,7 @@ import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; import com.github.ipk2015.coding2017.minijvm.cmd.ByteCodeCommand; +import com.github.ipk2015.coding2017.minijvm.cmd.CommandParser; import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; import com.github.ipk2015.coding2017.minijvm.loader.ByteCodeIterator; @@ -22,7 +23,7 @@ public ByteCodeCommand[] getCmds() { private LocalVariableTable localVarTable; private StackMapTable stackMapTable; - public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code /*ByteCodeCommand[] cmds*/) { + 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; @@ -46,7 +47,10 @@ public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){ int maxLocals = iter.nextUNToInt(2); int codeLen = iter.nextUNToInt(4); String code = iter.nextUNToHexString(codeLen); - CodeAttr codeAttr = new CodeAttr(attrNameIndex,attrLen,maxStack,maxLocals,codeLen,code); + + ByteCodeCommand[] commands = CommandParser.parse(clzFile, code); + + CodeAttr codeAttr = new CodeAttr(attrNameIndex,attrLen,maxStack,maxLocals,codeLen,code,commands); int exceptionTableLen = iter.nextUNToInt(2); if(exceptionTableLen != 0){ throw new RuntimeException("code属性里的异常table长度为:"+exceptionTableLen); diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassFile.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassFile.java index 5c3706b76f..3a267144af 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassFile.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/clz/ClassFile.java @@ -5,6 +5,7 @@ import com.github.ipk2015.coding2017.minijvm.constant.ClassInfo; import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; +import com.github.ipk2015.coding2017.minijvm.constant.UTF8Info; import com.github.ipk2015.coding2017.minijvm.field.Field; import com.github.ipk2015.coding2017.minijvm.method.Method; @@ -90,12 +91,18 @@ public String getSuperClassName(){ return superClass.getClassName(); } public Method getMethod(String methodName, String paramAndReturnType){ - - + List list = getMethods(); + for(Method m : list){ + String name = ((UTF8Info)pool.getConstantInfo(m.getNameIndex())).getValue(); + String desc = ((UTF8Info)pool.getConstantInfo(m.getDescriptorIndex())).getValue(); + if(name.equalsIgnoreCase(methodName) && desc.equalsIgnoreCase(paramAndReturnType)){ + return m; + } + } return null; } public Method getMainMethod(){ - - return null; +// main:([Ljava/lang/String;)V + return getMethod("main","([Ljava/lang/String;)V"); } } diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/CommandParser.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/CommandParser.java index 23b2859e6a..d9c3c619e2 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/CommandParser.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/cmd/CommandParser.java @@ -1,5 +1,6 @@ package com.github.ipk2015.coding2017.minijvm.cmd; +import java.util.ArrayList; import java.util.List; import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; @@ -42,9 +43,67 @@ public class CommandParser { public static final String iinc = "84"; public static ByteCodeCommand[] parse(ClassFile clzFile, String codes) { - - - return null; + if(null == codes || codes.length() == 0){ + throw new RuntimeException("字节码不存在"); + } + codes = codes.toUpperCase(); + CommandIterator iterator = new CommandIterator(codes); + List commands = new ArrayList(); + while(iterator.hasNext()){ + String operatorCode = iterator.next2CharAsString(); + if(ldc.equals(operatorCode)){ + LdcCmd cmd = new LdcCmd(clzFile,operatorCode); + cmd.setOperand(iterator.next2CharAsInt()); + commands.add(cmd); + }else if(bipush.equals(operatorCode)){ + BiPushCmd cmd = new BiPushCmd(clzFile,operatorCode); + cmd.setOperand(iterator.next2CharAsInt()); + commands.add(cmd); + }else if(new_object.equals(operatorCode)){ + NewObjectCmd cmd = new NewObjectCmd(clzFile,operatorCode); + cmd.setOprand1(iterator.next2CharAsInt()); + cmd.setOprand2(iterator.next2CharAsInt()); + commands.add(cmd); + }else if(invokespecial.equals(operatorCode)){ + InvokeSpecialCmd cmd = new InvokeSpecialCmd(clzFile,operatorCode); + cmd.setOprand1(iterator.next2CharAsInt()); + cmd.setOprand2(iterator.next2CharAsInt()); + commands.add(cmd); + }else if(invokevirtual.equals(operatorCode)){ + InvokeVirtualCmd cmd = new InvokeVirtualCmd(clzFile,operatorCode); + cmd.setOprand1(iterator.next2CharAsInt()); + cmd.setOprand2(iterator.next2CharAsInt()); + commands.add(cmd); + }else if(putfield.equals(operatorCode)){ + PutFieldCmd cmd = new PutFieldCmd(clzFile,operatorCode); + cmd.setOprand1(iterator.next2CharAsInt()); + cmd.setOprand2(iterator.next2CharAsInt()); + commands.add(cmd); + }else if(getfield.equals(operatorCode)){ + GetFieldCmd cmd = new GetFieldCmd(clzFile,operatorCode); + cmd.setOprand1(iterator.next2CharAsInt()); + cmd.setOprand2(iterator.next2CharAsInt()); + commands.add(cmd); + }else if(getstatic.equals(operatorCode)){ + GetStaticFieldCmd cmd = new GetStaticFieldCmd(clzFile,operatorCode); + cmd.setOprand1(iterator.next2CharAsInt()); + cmd.setOprand2(iterator.next2CharAsInt()); + commands.add(cmd); + }else if(dup.equals(operatorCode) || aload_0.equals(operatorCode) || aload_1.equals(operatorCode) || + aload_2.equals(operatorCode) || astore_1.equals(operatorCode) || voidreturn.equals(operatorCode) + || iload.equals(operatorCode) || iload_1.equals(operatorCode) || iload_2.equals(operatorCode) + || iload_3.equals(operatorCode) || fload_3.equals(operatorCode) || iconst_0.equals(operatorCode) + || iconst_1.equals(operatorCode) || istore_1.equals(operatorCode) || istore_2.equals(operatorCode) + || iadd.equals(operatorCode)|| iinc.equals(operatorCode)){ + NoOperandCmd command = new NoOperandCmd(clzFile,operatorCode); + commands.add(command); + }else{ + throw new RuntimeException("this operator code not includes yet:"+operatorCode); + } + } + calcuateOffset(commands); + ByteCodeCommand[] result = new ByteCodeCommand[commands.size()]; + return commands.toArray(result); } private static void calcuateOffset(List cmds) { diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java index 61b91fa7b9..b8a3d7dca2 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/method/Method.java @@ -4,6 +4,8 @@ import com.github.ipk2015.coding2017.minijvm.attr.CodeAttr; import com.github.ipk2015.coding2017.minijvm.clz.ClassFile; import com.github.ipk2015.coding2017.minijvm.cmd.ByteCodeCommand; +import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; +import com.github.ipk2015.coding2017.minijvm.constant.UTF8Info; import com.github.ipk2015.coding2017.minijvm.loader.ByteCodeIterator; public class Method { @@ -71,4 +73,15 @@ private static void addAttr(ClassFile clzFile,Method method,ByteCodeIterator ite public ByteCodeCommand[] getCmds() { return this.getCodeAttr().getCmds(); } + + 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(); + } } From 704d4b0db05aca95d9e3a24c6529dfb3b61713a0 Mon Sep 17 00:00:00 2001 From: Patrick Date: Sun, 23 Apr 2017 21:24:20 +0800 Subject: [PATCH 3/3] printer --- .../minijvm/constant/ClassInfo.java | 4 ++ .../minijvm/constant/ConstantInfo.java | 11 +++ .../minijvm/constant/ConstantPool.java | 2 +- .../minijvm/constant/FieldRefInfo.java | 5 ++ .../minijvm/constant/MethodRefInfo.java | 5 ++ .../minijvm/constant/NameAndTypeInfo.java | 5 ++ .../minijvm/constant/NullConstantInfo.java | 4 ++ .../minijvm/constant/StringInfo.java | 6 ++ .../coding2017/minijvm/constant/UTF8Info.java | 4 ++ .../minijvm/print/ClassFilePrinter.java | 8 ++- .../minijvm/print/ConstantPoolPrinter.java | 72 ++++++++++++++++++- 11 files changed, 121 insertions(+), 5 deletions(-) diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ClassInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ClassInfo.java index e2e0f50f61..d8cba51f62 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ClassInfo.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ClassInfo.java @@ -23,4 +23,8 @@ public String getClassName() { UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index); return utf8Info.getValue(); } + @Override + public void accept(Visitor visitor) { + visitor.visitClassInfo(this); + } } diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantInfo.java index 663c493b57..9275387556 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantInfo.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantInfo.java @@ -25,5 +25,16 @@ public ConstantPool getConstantPool() { public ConstantInfo getConstantInfo(int index){ return this.constantPool.getConstantInfo(index); } + public abstract void accept(Visitor visitor); + + public static interface Visitor{ + public void visitClassInfo(ClassInfo info); + public void visitFieldRef(FieldRefInfo info); + public void visitMethodRef(MethodRefInfo info); + public void visitNameAndType(NameAndTypeInfo info); + public void visitString(StringInfo info); + public void visistUTF8(UTF8Info info); + + } } diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantPool.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantPool.java index ea0e135a23..d28601f4ba 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantPool.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/ConstantPool.java @@ -23,7 +23,7 @@ public ConstantInfo getConstantInfo(int index){ public String getUTF8String(int index){ return ((UTF8Info)this.constantInfos.get(index)).getValue(); } - public Object getSize() { + public int getSize() { return this.constantInfos.size() -1; } } diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/FieldRefInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/FieldRefInfo.java index b74fb427ba..521c010f7b 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/FieldRefInfo.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/FieldRefInfo.java @@ -51,4 +51,9 @@ 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/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/MethodRefInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/MethodRefInfo.java index cc5352db6e..287c907259 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/MethodRefInfo.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/MethodRefInfo.java @@ -49,6 +49,11 @@ public String getParamAndReturnType(){ NameAndTypeInfo typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex()); return typeInfo.getTypeInfo(); } + + @Override + public void accept(Visitor visitor) { + visitor.visitMethodRef(this); + } diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NameAndTypeInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NameAndTypeInfo.java index d1cd005111..990c0f6a01 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NameAndTypeInfo.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NameAndTypeInfo.java @@ -42,4 +42,9 @@ public String getTypeInfo(){ public String toString(){ return "(" + getName() + "," + getTypeInfo()+")"; } + + @Override + public void accept(Visitor visitor) { + visitor.visitNameAndType(this); + } } diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NullConstantInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NullConstantInfo.java index 38eef91f32..06c20e5b4f 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NullConstantInfo.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/NullConstantInfo.java @@ -9,5 +9,9 @@ public NullConstantInfo(){ public int getType() { return -1; } + @Override + public void accept(Visitor visitor) { + + } } diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/StringInfo.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/StringInfo.java index 8f23231e72..00b9b9b706 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/StringInfo.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/StringInfo.java @@ -22,5 +22,11 @@ public void setIndex(int index) { public String toString(){ return this.getConstantPool().getUTF8String(index); } + + @Override + public void accept(Visitor visitor) { + visitor.visitString(this); + + } } diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/UTF8Info.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/UTF8Info.java index d94a267bbc..c0a7b4e0c5 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/UTF8Info.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/constant/UTF8Info.java @@ -26,6 +26,10 @@ public String getValue() { public void setValue(String value) { this.value = value; } + @Override + public void accept(Visitor visitor) { + visitor.visistUTF8(this); + } diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ClassFilePrinter.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ClassFilePrinter.java index 6615a189f5..2d7967cb41 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ClassFilePrinter.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ClassFilePrinter.java @@ -20,7 +20,7 @@ public void print(){ System.out.println("minor version:" + clzFile.getMinorVersion()); - System.out.println("major version:" + clzFile.getMinorVersion()); + System.out.println("major version:" + clzFile.getMajorVersion()); ConstantPoolPrinter cnstPoolPrinter = new ConstantPoolPrinter(clzFile.getConstantPool()); cnstPoolPrinter.print(); @@ -31,10 +31,12 @@ public void print(){ } public static void main(String[] args){ - String path = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; +// String path = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; + String path = "E:\\javaImprove\\git\\group24\\121111914\\src\\com\\github\\ipk2015\\coding2017\\minijvm\\bin"; ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path); - String className = "com.coderising.jvm.test.EmployeeV1"; +// String className = "com.coderising.jvm.test.EmployeeV1"; + String className = "EmployeeV1"; ClassFile clzFile = loader.loadClass(className); diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ConstantPoolPrinter.java b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ConstantPoolPrinter.java index 295c509941..17b88d9932 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ConstantPoolPrinter.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/minijvm/print/ConstantPoolPrinter.java @@ -1,6 +1,13 @@ package com.github.ipk2015.coding2017.minijvm.print; +import com.github.ipk2015.coding2017.minijvm.constant.ClassInfo; +import com.github.ipk2015.coding2017.minijvm.constant.ConstantInfo; import com.github.ipk2015.coding2017.minijvm.constant.ConstantPool; +import com.github.ipk2015.coding2017.minijvm.constant.FieldRefInfo; +import com.github.ipk2015.coding2017.minijvm.constant.MethodRefInfo; +import com.github.ipk2015.coding2017.minijvm.constant.NameAndTypeInfo; +import com.github.ipk2015.coding2017.minijvm.constant.StringInfo; +import com.github.ipk2015.coding2017.minijvm.constant.UTF8Info; public class ConstantPoolPrinter { ConstantPool pool; @@ -11,8 +18,71 @@ public void print(){ System.out.println("Constant Pool:"); + ConstantInfo.Visitor visitor = new ConstantInfo.Visitor(){ + + @Override + public void visitClassInfo(ClassInfo info) { + int utf8Index = info.getUtf8Index(); + String className = info.getClassName(); + sop("Class\t\t"+"#"+utf8Index+"\t\t// "+className); + } + + @Override + public void visitFieldRef(FieldRefInfo info) { + int classInfoIndex = info.getClassInfoIndex(); + int nameAndTypeIndex = info.getNameAndTypeIndex(); + String className = info.getClassName(); + String fieldName = info.getFieldName(); + String fieldType = info.getFieldType(); + sop("Fieldref\t\t"+"#"+classInfoIndex+".#"+nameAndTypeIndex+"\t\t// " + +className+"."+fieldName+":"+fieldType); + } + + @Override + public void visitMethodRef(MethodRefInfo info) { + int classInfoIndex = info.getClassInfoIndex(); + int nameAndTypeIndex = info.getNameAndTypeIndex(); + String className = info.getClassName(); + String methodName = info.getMethodName(); + String paramAndReturnType = info.getParamAndReturnType(); + sop("Methodref\t\t"+"#"+classInfoIndex+".#"+nameAndTypeIndex+"\t\t// " + +className+"."+methodName+":"+paramAndReturnType); + + } + + @Override + public void visitNameAndType(NameAndTypeInfo info) { + int index1 = info.getIndex1(); + int index2 = info.getIndex2(); + String name = info.getName(); + String typeInfo = info.getTypeInfo(); + sop("NameAndType\t"+"#"+index1+".#"+index2+"\t\t// "+name+":"+typeInfo); + } + + @Override + public void visitString(StringInfo info) { + int index = info.getIndex(); + String utf8String = info.getConstantPool().getUTF8String(index); + sop("String\t\t"+"#"+index+"\t\t// "+utf8String); + } + + @Override + public void visistUTF8(UTF8Info info) { + sop("Utf8\t\t"+info.getValue()); + } + + }; + int size = pool.getSize(); + for(int i = 1;i < size+1;i++){ + ConstantInfo constantInfo = pool.getConstantInfo(i); + System.out.print("\t"+"#"+i+" = "); + constantInfo.accept(visitor); + } - + } + + public static void sop(String s){ + System.out.println(s); } }