バックパッチ
Ifブロックや、Forブロックや、Whileブロックを
コード生成する時の話
前提知識が必要なので、一旦ここに示す。
しかもelse節のない時の話限定(?)
いや、たぶんだが、elseがあっても必要だな

(JVMでは?)ASTから以下のような構成のコードを生成する
gen0: <condition>のオブジェクトコード
// ここに条件比較などの処理を生成する
n: (条件付き分岐命令) goto @next // else節にあたる`next`に飛ぶだけ
j: <statement>のオブジェクトコード
// ここにthen節の処理を生成する
k: @next
// ここにこのifブロックの次の処理が生成される
実際のコードとの対応はこんなイメージ
左が実際のコード、右がIR
@nextは番地。
0
, n
, j
, k
は番地
goto Nでオフセットで飛び先を指定する
このとき、上から生成していくわけだが、「(条件付き分岐命令)」のところを生成する時に @next
の番地がわかっていないといけない
が、まだstatementのところを生成していないので、@nextが幾つになるのかが判断できない
じゃあどうするか?
ここでバックパッチです
一旦 goto 0;
としてstatementのオブジェクトコードの生成に取り掛かる
つまり、offsetが0なので、自分自身を指していることになる
本来は goto k-n
としたい
取り掛かる前にここの番地nをローカル変数として保持しておく
あとで戻るために
satementの生成が終わり@nextの番地が確定したら、0からk-nに修正する
この一旦進めて、あとで戻って修正する方法をバックパッチという
この@nextの番地が1byteで足りるのか問題も起こり得る
statementのところが長すぎると1byteでは足りない
対処法 ref

p.83