diff --git a/src/main/java/haidnor/jvm/instruction/comparisons/DCMPG.java b/src/main/java/haidnor/jvm/instruction/comparisons/DCMPG.java index 79e4f09..3fe4f61 100644 --- a/src/main/java/haidnor/jvm/instruction/comparisons/DCMPG.java +++ b/src/main/java/haidnor/jvm/instruction/comparisons/DCMPG.java @@ -4,6 +4,9 @@ import haidnor.jvm.instruction.Instruction; import haidnor.jvm.runtime.Frame; import haidnor.jvm.util.CodeStream; +/** + * @author wang xiang + */ public class DCMPG extends Instruction { public DCMPG(CodeStream codeStream) { diff --git a/src/main/java/haidnor/jvm/instruction/comparisons/DCMPL.java b/src/main/java/haidnor/jvm/instruction/comparisons/DCMPL.java index ef7156b..0f2b8f3 100644 --- a/src/main/java/haidnor/jvm/instruction/comparisons/DCMPL.java +++ b/src/main/java/haidnor/jvm/instruction/comparisons/DCMPL.java @@ -4,6 +4,9 @@ import haidnor.jvm.instruction.Instruction; import haidnor.jvm.runtime.Frame; import haidnor.jvm.util.CodeStream; +/** + * @author wang xiang + */ public class DCMPL extends Instruction { public DCMPL(CodeStream codeStream) { diff --git a/src/main/java/haidnor/jvm/instruction/comparisons/FCMPG.java b/src/main/java/haidnor/jvm/instruction/comparisons/FCMPG.java index eb0ecc9..d57fd7e 100644 --- a/src/main/java/haidnor/jvm/instruction/comparisons/FCMPG.java +++ b/src/main/java/haidnor/jvm/instruction/comparisons/FCMPG.java @@ -3,7 +3,9 @@ package haidnor.jvm.instruction.comparisons; import haidnor.jvm.instruction.Instruction; import haidnor.jvm.runtime.Frame; import haidnor.jvm.util.CodeStream; - +/** + * @author wang xiang + */ public class FCMPG extends Instruction { public FCMPG(CodeStream codeStream) { diff --git a/src/main/java/haidnor/jvm/instruction/comparisons/FCMPL.java b/src/main/java/haidnor/jvm/instruction/comparisons/FCMPL.java index 9c4adf5..5dba400 100644 --- a/src/main/java/haidnor/jvm/instruction/comparisons/FCMPL.java +++ b/src/main/java/haidnor/jvm/instruction/comparisons/FCMPL.java @@ -3,7 +3,9 @@ package haidnor.jvm.instruction.comparisons; import haidnor.jvm.instruction.Instruction; import haidnor.jvm.runtime.Frame; import haidnor.jvm.util.CodeStream; - +/** + * @author wang xiang + */ public class FCMPL extends Instruction { public FCMPL(CodeStream codeStream) { diff --git a/src/main/java/haidnor/jvm/instruction/comparisons/IF_ACMPEQ.java b/src/main/java/haidnor/jvm/instruction/comparisons/IF_ACMPEQ.java index e0b9f0a..2d9fb6f 100644 --- a/src/main/java/haidnor/jvm/instruction/comparisons/IF_ACMPEQ.java +++ b/src/main/java/haidnor/jvm/instruction/comparisons/IF_ACMPEQ.java @@ -3,7 +3,9 @@ package haidnor.jvm.instruction.comparisons; import haidnor.jvm.instruction.Instruction; import haidnor.jvm.runtime.Frame; import haidnor.jvm.util.CodeStream; - +/** + * @author wang xiang + */ public class IF_ACMPEQ extends Instruction { /** * 下次再执行的偏移量 diff --git a/src/main/java/haidnor/jvm/instruction/comparisons/IF_ACMPNE.java b/src/main/java/haidnor/jvm/instruction/comparisons/IF_ACMPNE.java index d260876..0579494 100644 --- a/src/main/java/haidnor/jvm/instruction/comparisons/IF_ACMPNE.java +++ b/src/main/java/haidnor/jvm/instruction/comparisons/IF_ACMPNE.java @@ -3,7 +3,9 @@ package haidnor.jvm.instruction.comparisons; import haidnor.jvm.instruction.Instruction; import haidnor.jvm.runtime.Frame; import haidnor.jvm.util.CodeStream; - +/** + * @author wang xiang + */ public class IF_ACMPNE extends Instruction { /** * 下次再执行的偏移量 diff --git a/src/main/java/haidnor/jvm/instruction/comparisons/IF_ICMPEQ.java b/src/main/java/haidnor/jvm/instruction/comparisons/IF_ICMPEQ.java index 00f624b..dd64736 100644 --- a/src/main/java/haidnor/jvm/instruction/comparisons/IF_ICMPEQ.java +++ b/src/main/java/haidnor/jvm/instruction/comparisons/IF_ICMPEQ.java @@ -8,6 +8,7 @@ import haidnor.jvm.util.CodeStream; /** * Java VM opcode. * + * @author wang xiang * @see Opcode * definitions in The Java Virtual Machine Specification */ @@ -36,6 +37,6 @@ public class IF_ICMPEQ extends Instruction { @Override public String toString() { - return super.index() + " " + this.getClass().getSimpleName() + " " + offSet; + return super.index() + " " + this.getClass().getSimpleName() + " " + offSet; } } diff --git a/src/main/java/haidnor/jvm/instruction/comparisons/IF_ICMPLE.java b/src/main/java/haidnor/jvm/instruction/comparisons/IF_ICMPLE.java index e15d932..73d7768 100644 --- a/src/main/java/haidnor/jvm/instruction/comparisons/IF_ICMPLE.java +++ b/src/main/java/haidnor/jvm/instruction/comparisons/IF_ICMPLE.java @@ -34,9 +34,4 @@ public class IF_ICMPLE extends Instruction { } } - @Override - public String toString() { - return super.index() + " " + this.getClass().getSimpleName() + " " + offSet; - } - } diff --git a/src/test/java/haidnor/jvm/test/TestJVM.java b/src/test/java/haidnor/jvm/test/TestJVM.java index a12fab0..b5541e5 100644 --- a/src/test/java/haidnor/jvm/test/TestJVM.java +++ b/src/test/java/haidnor/jvm/test/TestJVM.java @@ -14,7 +14,6 @@ import haidnor.jvm.test.instruction.math.LSUB; import haidnor.jvm.test.instruction.references.NEW; import haidnor.jvm.util.JavaClassUtil; import haidnor.jvm.util.JvmThreadHolder; -import lombok.SneakyThrows; import org.junit.Test; import java.io.IOException; @@ -25,8 +24,7 @@ import java.util.jar.Manifest; public class TestJVM { - @SneakyThrows - public static void runMainClass(java.lang.Class mainClass) { + public static void runMainClass(java.lang.Class mainClass) throws IOException { JvmThreadHolder.set(new JVMThread()); ClassLoader bootClassLoader = new ClassLoader("ApplicationClassLoader"); Klass mainMeteKlass = bootClassLoader.loadClass(mainClass.getName().replace('.', '/')); @@ -41,7 +39,7 @@ public class TestJVM { */ @Test public void test_1() throws Exception { - runMainClass(Demo1.class); + runMainClass(demo_helloWorld.class); } @Test @@ -79,6 +77,42 @@ public class TestJVM { runMainClass(Demo8.class); } + @Test(expected = ArithmeticException.class) + public void demo_exception_1() throws Exception { + runMainClass(demo_exception_1.class); + } + + @Test + public void demo_exception_2() throws Exception { + runMainClass(demo_exception_2.class); + } + + @Test + public void demo_exception_3() throws Exception { + runMainClass(demo_exception_3.class); + } + + @Test(expected = ArithmeticException.class) + public void demo_exception_4() throws Exception { + runMainClass(demo_exception_4.class); + } + + @Test + public void demo_finally_1() throws Exception { + runMainClass(demo_finally_1.class); + } + + @Test(expected = ArithmeticException.class) + public void demo_finally_2() throws Exception { + runMainClass(demo_finally_2.class); + } + + @Test + public void demo_finally_3() throws Exception { + runMainClass(demo_finally_3.class); + } + + @Test public void test_NEW() throws Exception { runMainClass(NEW.class); diff --git a/src/test/java/haidnor/jvm/test/demo/Demo1.java b/src/test/java/haidnor/jvm/test/demo/Demo1.java deleted file mode 100644 index 8abfedb..0000000 --- a/src/test/java/haidnor/jvm/test/demo/Demo1.java +++ /dev/null @@ -1,7 +0,0 @@ -package haidnor.jvm.test.demo; - -public class Demo1 { - public static void main(String[] args) { - System.out.println("hello,world"); - } -} diff --git a/src/test/java/haidnor/jvm/test/demo/demo_exception_1.java b/src/test/java/haidnor/jvm/test/demo/demo_exception_1.java new file mode 100644 index 0000000..4fd0885 --- /dev/null +++ b/src/test/java/haidnor/jvm/test/demo/demo_exception_1.java @@ -0,0 +1,37 @@ +package haidnor.jvm.test.demo; + +/** + * 调用方没有捕获调用方法的异常 + */ +public class demo_exception_1 { + + public static void main(String[] args) { + int a = 0; + fun(a); + } + + public static void fun(int a) { + if (a == 0) { + throw new ArithmeticException(); + } + } + +} +/* +main(String[] args) + 0 iconst_0 + 1 istore_1 + 2 iload_1 + 3 invokestatic #7 + 6 return + +fun(int a) + 0 iload_0 + 1 ifne 12 (+11) + 4 new #29 + 7 dup + 8 invokespecial #31 : ()V> + 11 athrow + 12 return + +*/ \ No newline at end of file diff --git a/src/test/java/haidnor/jvm/test/demo/demo_exception_2.java b/src/test/java/haidnor/jvm/test/demo/demo_exception_2.java new file mode 100644 index 0000000..d9dc426 --- /dev/null +++ b/src/test/java/haidnor/jvm/test/demo/demo_exception_2.java @@ -0,0 +1,53 @@ +package haidnor.jvm.test.demo; + +/** + * 调用方捕获调用方法的异常 + */ +public class demo_exception_2 { + + public static void main(String[] args) { + int a = 0; + try { + fun(a); + } catch (Exception exception) { + System.out.println("catch Exception"); + } + } + + public static void fun(int a) { + if (a == 0) { + throw new ArithmeticException(); + } + } + +} +/* +main(String[] args) + 0 iconst_0 + 1 istore_1 + 2 iload_1 + 3 invokestatic #7 + 6 goto 18 (+12) + 9 astore_2 + 10 getstatic #15 + 13 ldc #21 + 15 invokevirtual #23 + 18 return + ++--------+-------+--------+--------+---------------------+ +| Nr. | 起始PC | 结束PC | 跳转PC | 捕获类型 | ++--------+-------+--------+--------+---------------------+ +| 0 | 2 | 6 | 9 | java/lang/Exception | ++--------+-------+--------+--------+---------------------+ + + +fun(int a) + 0 iload_0 + 1 ifne 12 (+11) + 4 new #29 + 7 dup + 8 invokespecial #31 : ()V> + 11 athrow + 12 return + +*/ \ No newline at end of file diff --git a/src/test/java/haidnor/jvm/test/demo/demo_exception_3.java b/src/test/java/haidnor/jvm/test/demo/demo_exception_3.java new file mode 100644 index 0000000..f86fd8c --- /dev/null +++ b/src/test/java/haidnor/jvm/test/demo/demo_exception_3.java @@ -0,0 +1,51 @@ +package haidnor.jvm.test.demo; + +/** + * 调用方捕获调用方法的异常的父类 + */ +public class demo_exception_3 { + + public static void main(String[] args) { + int a = 0; + try { + fun(a); + } catch (Exception exception) { + System.out.println("catch Exception"); + } + } + + public static void fun(int a) { + System.out.println(1 / a); + } + +} +/* +main(String[] args) + 0 iconst_0 + 1 istore_1 + 2 iload_1 + 3 invokestatic #7 + 6 goto 18 (+12) + 9 astore_2 + 10 getstatic #15 + 13 ldc #21 + 15 invokevirtual #23 + 18 return + ++--------+-------+--------+--------+---------------------+ +| Nr. | 起始PC | 结束PC | 跳转PC | 捕获类型 | ++--------+-------+--------+--------+---------------------+ +| 0 | 2 | 6 | 9 | java/lang/Exception | ++--------+-------+--------+--------+---------------------+ + + +fun(int a) + 0 iload_0 + 1 ifne 12 (+11) + 4 new #29 + 7 dup + 8 invokespecial #31 : ()V> + 11 athrow + 12 return + +*/ \ No newline at end of file diff --git a/src/test/java/haidnor/jvm/test/demo/demo_exception_4.java b/src/test/java/haidnor/jvm/test/demo/demo_exception_4.java new file mode 100644 index 0000000..12fa687 --- /dev/null +++ b/src/test/java/haidnor/jvm/test/demo/demo_exception_4.java @@ -0,0 +1,51 @@ +package haidnor.jvm.test.demo; + +/** + * 调用方没有捕获调用方法抛出的异常类型 + */ +public class demo_exception_4 { + + public static void main(String[] args) { + int a = 0; + try { + fun(a); + } catch (NullPointerException exception) { + System.out.println("catch Exception"); + } + } + + public static void fun(int a) { + System.out.println(1 / a); + } + +} +/* +main(String[] args) + 0 iconst_0 + 1 istore_1 + 2 iload_1 + 3 invokestatic #7 + 6 goto 18 (+12) + 9 astore_2 + 10 getstatic #15 + 13 ldc #21 + 15 invokevirtual #23 + 18 return + ++--------+-------+--------+--------+--------------------------------+ +| Nr. | 起始PC | 结束PC | 跳转PC | 捕获类型 | ++--------+-------+--------+--------+--------------------------------+ +| 0 | 2 | 6 | 9 | java/lang/NullPointerException | ++--------+-------+--------+--------+--------------------------------+ + + +fun(int a) + 0 iload_0 + 1 ifne 12 (+11) + 4 new #29 + 7 dup + 8 invokespecial #31 : ()V> + 11 athrow + 12 return + +*/ \ No newline at end of file diff --git a/src/test/java/haidnor/jvm/test/demo/demo_finally_1.java b/src/test/java/haidnor/jvm/test/demo/demo_finally_1.java new file mode 100644 index 0000000..23398c3 --- /dev/null +++ b/src/test/java/haidnor/jvm/test/demo/demo_finally_1.java @@ -0,0 +1,51 @@ +package haidnor.jvm.test.demo; + +public class demo_finally_1 { + + public static void main(String[] args) { + String name = fun(); + System.out.println(name); + } + + public static String fun() { + String str = "zhang san"; + try { + return str; + } finally { + str = "li si"; + } + } + +} +/* +main(String[] args): + 0 invokestatic #7 + 3 astore_1 + 4 getstatic #13 + 7 aload_1 + 8 invokevirtual #19 + 11 return + +fun(): + 0 ldc #25 + 2 astore_0 + 3 aload_0 + 4 astore_1 + 5 ldc #27
  • + 7 astore_0 + 8 aload_1 + 9 areturn + 10 astore_2 < 如果 3-5 指令出现了异常时才会跳转到 10. 如果出现了异常会把异常压入操作数栈,这里的 astore_2 就是把异常先存储起来。 + 11 ldc #27
  • + 13 astore_0 + 14 aload_2 < 执行完 finally 把 astore_2 的异常压入操作树栈 + 15 athrow < 把操作数栈上的异常抛出 + +Exception Table: ++--------+-------+--------+--------+---------+ +| Nr. | 起始PC | 结束PC | 跳转PC | 捕获类型 | ++--------+-------+--------+--------+---------+ +| 0 | 3 | 5 | 10 | any | ++--------+-------+--------+--------+---------+ + +*/ \ No newline at end of file diff --git a/src/test/java/haidnor/jvm/test/demo/demo_finally_2.java b/src/test/java/haidnor/jvm/test/demo/demo_finally_2.java new file mode 100644 index 0000000..4474c5e --- /dev/null +++ b/src/test/java/haidnor/jvm/test/demo/demo_finally_2.java @@ -0,0 +1,55 @@ +package haidnor.jvm.test.demo; + +/** + * try 异常后执行 finally + */ +public class demo_finally_2 { + + public static void main(String[] args) { + fun(); + } + + public static void fun() { + try { + System.out.println(1 / 0); + } finally { + System.out.println("此时应该执行 finally"); + } + } + +} +/* +main(String[] args): + 0 invokestatic #7 + 3 return + + +fun(): + 0 getstatic #12 + 3 iconst_1 + 4 iconst_0 + 5 idiv + 6 invokevirtual #18 + 9 getstatic #12 + 12 ldc #24 + 14 invokevirtual #26 + 17 getstatic #12 + 20 ldc #29 <此时不应该执行 finally> + 22 invokevirtual #26 + 25 goto 39 (+14) + 28 astore_0 + 29 getstatic #12 + 32 ldc #29 <此时不应该执行 finally> + 34 invokevirtual #26 + 37 aload_0 + 38 athrow + 39 return + +Exception Table: ++--------+-------+--------+--------+---------+ +| Nr. | 起始PC | 结束PC | 跳转PC | 捕获类型 | ++--------+-------+--------+--------+---------+ +| 0 | 9 | 17 | 28 | any | ++--------+-------+--------+--------+---------+ + +*/ \ No newline at end of file diff --git a/src/test/java/haidnor/jvm/test/demo/demo_finally_3.java b/src/test/java/haidnor/jvm/test/demo/demo_finally_3.java new file mode 100644 index 0000000..f854020 --- /dev/null +++ b/src/test/java/haidnor/jvm/test/demo/demo_finally_3.java @@ -0,0 +1,55 @@ +package haidnor.jvm.test.demo; + +/** + * try 异常前不应该执行 finally + */ +public class demo_finally_3 { + + public static void main(String[] args) { + fun(); + } + + public static void fun() { + System.out.println(1 / 0); + try { + System.out.println("try"); + } finally { + System.out.println("finally"); + } + } + +} +/* +main(String[] args): + 0 invokestatic #7 + 3 return + +fun(): + 0 getstatic #12 + 3 iconst_1 + 4 iconst_0 + 5 idiv + 6 invokevirtual #18 + 9 getstatic #12 + 12 ldc #24 + 14 invokevirtual #26 + 17 getstatic #12 + 20 ldc #29 + 22 invokevirtual #26 + 25 goto 39 (+14) + 28 astore_0 + 29 getstatic #12 + 32 ldc #29 + 34 invokevirtual #26 + 37 aload_0 + 38 athrow + 39 return + +Exception Table: ++--------+-------+--------+--------+---------+ +| Nr. | 起始PC | 结束PC | 跳转PC | 捕获类型 | ++--------+-------+--------+--------+---------+ +| 0 | 9 | 17 | 28 | any | ++--------+-------+--------+--------+---------+ + +*/ \ No newline at end of file diff --git a/src/test/java/haidnor/jvm/test/demo/demo_helloWorld.java b/src/test/java/haidnor/jvm/test/demo/demo_helloWorld.java new file mode 100644 index 0000000..5d1b057 --- /dev/null +++ b/src/test/java/haidnor/jvm/test/demo/demo_helloWorld.java @@ -0,0 +1,18 @@ +package haidnor.jvm.test.demo; + +public class demo_helloWorld { + + public static void main(String[] args) { + System.out.println("hello,world"); + } + +} +/* + +main(String[] args) + 0 getstatic #7 + 3 ldc #13 + 5 invokevirtual #15 + 8 return + + */ \ No newline at end of file diff --git a/src/test/java/haidnor/jvm/test/instruction/extended/GOTO.java b/src/test/java/haidnor/jvm/test/instruction/GOTO.java similarity index 79% rename from src/test/java/haidnor/jvm/test/instruction/extended/GOTO.java rename to src/test/java/haidnor/jvm/test/instruction/GOTO.java index 36309df..bbe4134 100644 --- a/src/test/java/haidnor/jvm/test/instruction/extended/GOTO.java +++ b/src/test/java/haidnor/jvm/test/instruction/GOTO.java @@ -1,4 +1,4 @@ -package haidnor.jvm.test.instruction.extended; +package haidnor.jvm.test.instruction; public class GOTO {