package com.coderising.jvm.test; import java.util.List; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; //import com.coderising.jvm.clz.ClassFile; //import com.coderising.jvm.clz.ClassIndex; //import com.coderising.jvm.cmd.BiPushCmd; //import com.coderising.jvm.cmd.ByteCodeCommand; //import com.coderising.jvm.cmd.OneOperandCmd; //import com.coderising.jvm.cmd.TwoOperandCmd; //import com.coderising.jvm.constant.ClassInfo; //import com.coderising.jvm.constant.ConstantPool; //import com.coderising.jvm.constant.MethodRefInfo; //import com.coderising.jvm.constant.NameAndTypeInfo; //import com.coderising.jvm.constant.UTF8Info; //import com.coderising.jvm.field.Field; import com.coderising.jvm.loader.ClassFileLoader; //import com.coderising.jvm.method.Method; public class ClassFileloaderTest { private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1"; static String path1 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; static String path2 = "C:\temp"; // static ClassFile clzFile = null; // static { // ClassFileLoader loader = new ClassFileLoader(); // loader.addClassPath(path1); // String className = "com.coderising.jvm.test.EmployeeV1"; // // clzFile = loader.loadClass(className); // // } // @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void testClassPath(){ ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path1); loader.addClassPath(path2); String clzPath = loader.getClassPath(); Assert.assertEquals(path1+";"+path2,clzPath); } @Test public void testClassFileLength() { ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path1); String className = "com.coderising.jvm.test.EmployeeV1"; byte[] byteCodes = loader.readBinaryCode(className); // 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 Assert.assertEquals(1056, byteCodes.length); } @Test public void testMagicNumber(){ ClassFileLoader loader = new ClassFileLoader(); loader.addClassPath(path1); String className = "com.coderising.jvm.test.EmployeeV1"; byte[] byteCodes = loader.readBinaryCode(className); byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; String acctualValue = this.byteToHexString(codes); Assert.assertEquals("cafebabe", acctualValue); } private String byteToHexString(byte[] codes ){ StringBuffer buffer = new StringBuffer(); for(int i=0;i<codes.length;i++){ byte b = codes[i]; int value = b & 0xFF; String strHex = Integer.toHexString(value); if(strHex.length()< 2){ strHex = "0" + strHex; } buffer.append(strHex); } return buffer.toString(); } // add comment for behind test // /** // * ---------------------------------------------------------------------- // */ // // // @Test // public void testVersion(){ // // Assert.assertEquals(0, clzFile.getMinorVersion()); // Assert.assertEquals(52, clzFile.getMajorVersion()); // // } // // @Test // public void testConstantPool(){ // // // ConstantPool pool = clzFile.getConstantPool(); // // Assert.assertEquals(53, pool.getSize()); // // { // ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1); // Assert.assertEquals(2, clzInfo.getUtf8Index()); // // UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2); // Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue()); // } // { // ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3); // Assert.assertEquals(4, clzInfo.getUtf8Index()); // // UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4); // Assert.assertEquals("java/lang/Object", utf8Info.getValue()); // } // { // UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5); // Assert.assertEquals("name", utf8Info.getValue()); // // utf8Info = (UTF8Info) pool.getConstantInfo(6); // Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue()); // // utf8Info = (UTF8Info) pool.getConstantInfo(7); // Assert.assertEquals("age", utf8Info.getValue()); // // utf8Info = (UTF8Info) pool.getConstantInfo(8); // Assert.assertEquals("I", utf8Info.getValue()); // // utf8Info = (UTF8Info) pool.getConstantInfo(9); // Assert.assertEquals("<init>", utf8Info.getValue()); // // utf8Info = (UTF8Info) pool.getConstantInfo(10); // Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue()); // // utf8Info = (UTF8Info) pool.getConstantInfo(11); // Assert.assertEquals("Code", utf8Info.getValue()); // } // // { // MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12); // Assert.assertEquals(3, methodRef.getClassInfoIndex()); // Assert.assertEquals(13, methodRef.getNameAndTypeIndex()); // } // // { // NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13); // Assert.assertEquals(9, nameAndType.getIndex1()); // Assert.assertEquals(14, nameAndType.getIndex2()); // } // //抽查几个吧 // { // MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45); // Assert.assertEquals(1, methodRef.getClassInfoIndex()); // Assert.assertEquals(46, methodRef.getNameAndTypeIndex()); // } // // { // UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53); // Assert.assertEquals("EmployeeV1.java", utf8Info.getValue()); // } // } // @Test // public void testClassIndex(){ // // ClassIndex clzIndex = clzFile.getClzIndex(); // ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex()); // ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex()); // // // Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName()); // Assert.assertEquals("java/lang/Object", superClassInfo.getClassName()); // } // // /** // * 下面是第三次JVM课应实现的测试用例 // */ // @Test // public void testReadFields(){ // // List<Field> fields = clzFile.getFields(); // Assert.assertEquals(2, fields.size()); // { // Field f = fields.get(0); // Assert.assertEquals("name:Ljava/lang/String;", f.toString()); // } // { // Field f = fields.get(1); // Assert.assertEquals("age:I", f.toString()); // } // } // @Test // public void testMethods(){ // // List<Method> methods = clzFile.getMethods(); // ConstantPool pool = clzFile.getConstantPool(); // // { // Method m = methods.get(0); // assertMethodEquals(pool,m, // "<init>", // "(Ljava/lang/String;I)V", // "2ab7000c2a2bb5000f2a1cb50011b1"); // // } // { // Method m = methods.get(1); // assertMethodEquals(pool,m, // "setName", // "(Ljava/lang/String;)V", // "2a2bb5000fb1"); // // } // { // Method m = methods.get(2); // assertMethodEquals(pool,m, // "setAge", // "(I)V", // "2a1bb50011b1"); // } // { // Method m = methods.get(3); // assertMethodEquals(pool,m, // "sayHello", // "()V", // "b2001c1222b60024b1"); // // } // { // Method m = methods.get(4); // assertMethodEquals(pool,m, // "main", // "([Ljava/lang/String;)V", // "bb000159122b101db7002d4c2bb6002fb1"); // } // } // // private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){ // String methodName = pool.getUTF8String(m.getNameIndex()); // String methodDesc = pool.getUTF8String(m.getDescriptorIndex()); // String code = m.getCodeAttr().getCode(); // Assert.assertEquals(expectedName, methodName); // Assert.assertEquals(expectedDesc, methodDesc); // Assert.assertEquals(expectedCode, code); // } // // @Test // public void testByteCodeCommand(){ // { // Method initMethod = this.clzFile.getMethod("<init>", "(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); // } }