Exception tableがついちゃってました

バイトコードを見てみよう

前回のエントリー
id:kya-zinc:20091204
コンパイラにバグがあったことを知った。
何が違ったのかな、と思い、Javapコマンドでバイトコードを見てみた。
問題の関数のみ抜粋。

バグあり版

public void finally_rec(int);
  Code:
   0:	iload_1
   1:	iconst_0
   2:	if_icmpge	6
   5:	return
   6:	getstatic	#26; //Field scala/Predef$.MODULE$:Lscala/Predef$;
   9:	iload_1
   10:	invokestatic	#32; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
   13:	invokevirtual	#36; //Method scala/Predef$.println:(Ljava/lang/Object;)V
   16:	aload_0
   17:	iload_1
   18:	iconst_1
   19:	isub
   20:	invokevirtual	#38; //Method finally_rec:(I)V
   23:	return
   24:	astore_2
   25:	aload_0
   26:	iload_1
   27:	iconst_1
   28:	isub
   29:	invokevirtual	#38; //Method finally_rec:(I)V
   32:	aload_2
   33:	athrow
  Exception table:
   from   to  target type
    16    23    24   any

バグ解決版

public void finally_rec(int);
  Code:
   0:	iload_1
(中略)
   33:	athrow

違いは、前者にException tableがついていることだけで、あとは同じのようだった。

関連知識

invokevirtual #38; //Method finally_rec:(I)Vが二行あるのは、
正常終了した場合(23のreturnまで)と、
例外が発生した場合(33のathrowまで)に展開されるかららしい。
参考:Javaの場合
http://d.hatena.ne.jp/kmaebashi/20080720
バグあり版で2回実行されていたのは
正常終了ケースで例外が発生したら、例外発生ケースにジャンプしていたからのようだ。