This is the Jasmin (essentially Java "assembly language") source code for the exceptions decompiler test. It is an attempt at the test program from Figure 6 of the paper [[http://www.sable.mcgill.ca/publications/papers/#cc2002-2][Decompiling Java Bytecode: Problems, Traps and Pitfalls]], but since the results are so different to theirs, I must have failed to reproduce their original example. I should be pretty close, though, because the SourceTec decompiler produces results very similar to what their paper claims Wingdis produces. The control flow for this program is as follows: PitfallsFigure6.gif The solid lines represent normal control flow, and the labelled dotted lines represent execeptional control flow. The trick with this test is that the two areas of protection overlap (one area, for exception =RuntimeException=, covers blocks =b= and =c=, and the other area, for exception =Exception=, covers blocks =c= and =d=). The correct way to express this in Java is to split the two areas into three; one with block =b= alone, one with block =c= alone (which requires two =catch= statements), and one for block =d= alone. I wrote this program as follows. First, I wrote a Java program that comes close to the control flow required. I compiled this to bytecodes, and used Soot (see http://www.sable.mcgill.ca/soot/) to convert this to Jasmin. I then edited the Jasmin to have the control flow required, and edited the labels to be more readable. I then "assembled" this code with jasmin (a slightly modified version comes as part of Soot). .class foo .super java/lang/Object .method ()V .limit stack 1 .limit locals 1 aload_0 invokespecial java/lang/Object/()V return .end method .method public foo()V .catch java/lang/RuntimeException from label_b to after_c using catch_g .catch java/lang/RuntimeException from label_c to after_d using catch_e .limit stack 2 .limit locals 1 getstatic java/lang/System/out Ljava/io/PrintStream; ldc "a" invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V label_b: getstatic java/lang/System/out Ljava/io/PrintStream; ldc "b" invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V label_c: getstatic java/lang/System/out Ljava/io/PrintStream; ldc "c" invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V after_c: goto label_d catch_g: astore_0 getstatic java/lang/System/out Ljava/io/PrintStream; ldc "g" invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V goto label_f label_d: getstatic java/lang/System/out Ljava/io/PrintStream; ldc "d" invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V after_d: goto label_f catch_e: astore_0 getstatic java/lang/System/out Ljava/io/PrintStream; ldc "e" invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V label_f: getstatic java/lang/System/out Ljava/io/PrintStream; ldc "f" invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V return .end method .method public static main()V .limit stack 2 .limit locals 1 new foo dup invokespecial foo/()V astore_0 return .end method -- Main.MikeVanEmmerik - 12 Feb 2003