InstructionList に Select(LOOKUPTABLE, SWITCHTABLE) が含まれている場合に,その InstructionList に対して insert や append をした時,Select の getTargets で得られる InstructionHandle の配列は insert や append する前の状態のまま.
困るなぁ.どうしよう・・・.
解決策・・・と言っても確認はこれから.LOOKUPTABLE や SWITCHTABLE の正規の飛び先の targeter を調べると,ちゃんと switch を指している.
また,switch で飛ぶ先は必ず LOOKUPTABLE や SWITCHTABLE の後になる.加えて,targeter が switch を指すエントリは必ず,キーの数 + 1 となる(+1 は default case).なので,全ての targeter を調べ,targeter が switch であれば,最初から順番に target の位置を修正していくのはどうか.
ここまで書いて思ったが,
switch(value1){
case 1:
switch(value2){
case 10:
:
}
}
なんてのはどうしよう.
ダメだ.NullPointerException が InstructionHandle#removeTargeter で起こる.
スタックトレース.
Exception in thread "main" java.lang.NullPointerException at org.apache.bcel.generic.InstructionHandle.removeTargeter(InstructionHandle.java:197) at org.apache.bcel.generic.BranchInstruction.notifyTarget(BranchInstruction.java:215) at org.apache.bcel.generic.Select.setTarget(Select.java:189) at jp.ac.aist_nara.se.tama.tracer.AddTracer.updateSwitch(AddTracer.java:213)
それに,
switch(value){
case 1:
// some operation...
break;
case 3:
// some operation...
break;
case 5:
// some operation...
break;
case 7:
// some operation...
break;
default:
// some operation...
break;
}
は LOOKUPSWITCH になると思ったら,TABLESWITCH になってしまう.
tableswitch
1: goto aaa
2: goto bbb
3: goto ccc
4: goto bbb
5: goto ddd
6: goto bbb
7: goto eee
みたいな感じ.
こんな場合はお手上げ.
で,色々と試したが,うまくいかん.
新たに LOOKUPSWITCH や TABLESWITCH を new して,InstructionList#swapInstruction すると,正常に終了したように見えるが,Select 内のインスタンス変数である position が protected で外側から代入できないので,ジャンプ先が相対値でなければならないのに,絶対値になってしまう.
protected ならサブクラスから代入できるので,LOOKUPSWITCH と TABLESWITCH のサブクラスを作成し,その opcode の position をコンストラクタに渡すようにして,position に代入した.この方法でも,VerifyError が起こる.クラスがロードできないので,何がおかしいのかが,よくわからない.
もう少しこの方法を試してみるかなぁ.