iconst_3 istore_1 Label1: iload_1 ifle Label2 iinc 1 -1 goto Label1 Label2: returnこの表記に従い フレーム内の動作を記述すると,
iconst_3 local=[, ] stack=[3] isotre_1 local=[, 3] stack=[] iload_1 local=[, 3] stack=[3] ifle Label2 local=[, 3] stack=[] iinc 1 -1 local=[, 2] stack=[] goto Label1 local=[, 2] stack=[] iload_1 local=[, 2] stack=[2] ifle Label2 local=[, 2] stack=[] iinc 1 -1 local=[, 1] stack=[] goto Label1 local=[, 1] stack=[] iload_1 local=[, 1] stack=[1] ifle Label2 local=[, 1] stack=[] iinc 1 -1 local=[, 0] stack=[] goto Label1 local=[, 0] stack=[] iload_1 local=[, 0] stack=[0] ifle Label2 local=[, 0] stack=[] return例えば,もっとも危なそうな Label1の時点での型の状態は,
iconst_0 astore_1という命令列が変なのは明白である. この表記に従うと,
iconst_1 local=[ ] stack=[... 1] astore_1 local=[ ] stack=[... 1] ???? 1は参照じゃないゾってことで誤りなのは,明白である. 要は 参照型に整数を代入しようとしている誤りである.
iconst_3 istore_1 Label1: aconst_null iinc 1 -1 iload_1 ifne Label1 続くこれも, この表記に従うと,
iconst_3 local=[this, ] stack=[3, , , ] istore_1 local=[this, 3] stack=[, , , ] aconst_null local=[this, 3] stack=[null, , , ] iinc 1 -1 local=[this, 2] stack=[null, , , ] iload_1 local=[this, 2] stack=[null, 2, , ] 参照, int ifne Label1 local=[this, 2] stack=[null, , , ] aconst_null local=[this, 2] stack=[null, null, , ] iinc 1 -1 local=[this, 1] stack=[null, null, , ] iload_1 local=[this, 1] stack=[null, null, 1, ] 参照, 参照, int ifne Label1 local=[this, 1] stack=[null, null, , ] aconst_null local=[this, 1] stack=[null, null, null, ] iinc 1 -1 local=[this, 0] stack=[null, null, null, ] iload_1 local=[this, 0] stack=[null, null, null, 0] 参照, 参照, 参照, int ifne Label1 local=[this, 0] stack=[null, null, null, ] 続く上記計算は,単にスタックにnullを3つ積むだけの処理であるが, アルゴリズム的には何の問題もない. しかし,例えば,上記 赤字で示しているifne直前のスタックの型の状態は, 毎回異なっていることがわかる.
ちなみにこれをもっとも安直に書き正す例は,
aconst_null aconst_null aconst_nullである(笑)
$Id: ex.html,v 1.2 2000-07-02 20:30:33+09 kaiya Exp kaiya $