Javaの前置・後置インクリメントの内部実装を読みたい・その2
先日書いたJavaの前置インクリメントと後置インクリメントの件について、id:Nagiseさんからヒントを頂きました。
Javaではどうなるかという問題が未解決だったのでうれしいです。
が、JDKのコードを掘っているうちに寝落ちしてしまいました。
あまり成果はないですが、考えたことを忘れそうなので、分かったところまでメモしておきます。
Javaのコンパイル動作メモ
Javaをコンパイルすると、Javaコード→中間コード→マシンコードという変換が行われます。これをもう少し詳細に見てみます。
一般的に、コンパイラは次の動作を行います。
上のリストは、『コンパイラの構成と最適化』で説明されているコンパイラの論理的構造をもとに記述しています。下へいくほどマシンに近くなります。
字句解析、構文解析を経て、中間コードが得られます。中間コードの形式はランタイム次第で、抽象構文木、有効非循環グラフ、また別のもの(たとえば、上の本では3アドレスコードやRTLが紹介されています)など、様々です。
ここで、Javaでは木であるという話になるのでしょうが、自分はJava仮想マシン仕様を読んだことがないのでよくわかりませんどう見てもモグリです。本当にありがとうございました。今日から読みます。
上のリストの4番で作成された木を確認して、7番でどのような命令語にマッピングされかを把握できれば、幸福実現するということですね。
(追記)Javaの中間コードは、木構造ではないそうです。id:m11m さんからコメントで教えていただきました。(が、自分は実装レベルでまだ確認できていません。一応追記まで)
チラ見した箇所のメモ
# 以下の文章は不正確かもしれないので、信じないでください。
上記のoptディレクトリ以下に格納されているのは、オペランドスタックの操作を実現するコードです。自分が間違って読んだのは、構文木の形をした中間語からマシン語を得る部分(たぶん)でした。
たとえば・・・
forやwhileなどの繰り返し構文では、ブロックの最後までいったら最初に戻る必要があります。つまり、ジャンプが繰り返し発生します。ジャンプを実現するために、アドレスのテーブルを生成します。
pars2.cppには、Parse::do_tableswitch関数と、Parse::do_lookupswitch関数があります。これら2つの関数は、ディシジョンツリーを形成し、最後にjump_switch_ranges関数を呼び出しています。jump_switch_ranges関数というのは再帰構造を持ち、ディシジョンツリーを切り替える動作をします。
・・・というようなコードが書かれています。木と関係ないですね。