やったこと。
ScalaとJavaのクラスファイルについてごにょごにょしていました。以下雑多なメモ。
- javac -gでデバッグ情報を出しつつコンパイル。
- なお、scalacは普通にデバッグ情報を出してくれるけど、詳しく調べなければならない。
- Scalaの関数にstaticはないので、JavaとScalaのデバッグ情報にズレが生じやすい。
- デバッグ情報とか無視したらトレイトもインターフェイスも一緒の逆アセンブル結果になる。
- ScalaのクラスファイルをJD-GUIで逆コンパイルしたらわけがわからないやつが出てくる。
シングルトン
ツイート
久々にJVM仕様の本を引っ張りだしていた
— しげちゃん (@shigemk2) May 24, 2015
Hello, World
単純な四則演算
文字列連結
階乗
階乗(末尾再帰)
トレイト
— しげちゃん (@shigemk2) May 24, 2015
謎のクラスファイルシリーズ
— しげちゃん (@shigemk2) May 24, 2015
コンスタントプール http://t.co/oKeT0qgPip
— しげちゃん (@shigemk2) May 24, 2015
ldcが重要
— しげちゃん (@shigemk2) May 24, 2015
JavaでもScalaでも文字列連結の部分は普通にコンパイラで最適化しているくさいな。変数定義してから文字列連結しても変数定義のときに文字列連結しても逆アセンブル結果は同じようにみえるから。
— しげちゃん (@shigemk2) May 24, 2015
Scalaの階乗プログラムでパターンマッチを使っているやつを逆アセンブルしてJD-GUIで逆コンパイルするとなかなか面白いと思いました。へぇ、こんなかんじなんだっていう
— しげちゃん (@shigemk2) May 24, 2015
逆アセンブル結果も若干トリッキーなんですが。
— しげちゃん (@shigemk2) May 24, 2015
JVMの命令セット一覧
http://t.co/V48kzRp9Mk
— しげちゃん (@shigemk2) May 24, 2015
来る6/6の探検隊のために発表資料の資料を用意する一日だった
http://t.co/6THedatlR4
— しげちゃん (@shigemk2) May 24, 2015
発表はググラビリティの低い泥臭いところから始めないといけなくって、それでいうと熱血アセンブラ入門は良い意味で大変に泥臭かったと記憶しております。
— しげちゃん (@shigemk2) May 24, 2015
ScalaのHello, Worldプログラムを逆コンパイルするのは結構やっている人いますし、LinuxでJD-GUIとか使っている人もいっぱいいらっしゃいますから、熱血アセンブラ入門のScala版的なものを目指していきたい。
— しげちゃん (@shigemk2) May 24, 2015
とすると、20分ではなく50分で勝負すべきではなかったのか
— しげちゃん (@shigemk2) May 24, 2015
なんだかんだで昨日の勉強会も前回のメモをブログに残していたので1時間くらいしゃべっていたし
— しげちゃん (@shigemk2) May 24, 2015
あっ、トレイトまだだ
— しげちゃん (@shigemk2) May 24, 2015
よくScalaのTraitはJavaでいうところのinterfaceに近いという説明を受けるけども、もしかしたらバイナリレベルでも同じようなことが起こるのではないか、という疑問が生まれる
— しげちゃん (@shigemk2) May 24, 2015
さすがに全く一緒ってことはないですな
— しげちゃん (@shigemk2) May 24, 2015
TraitとInterfaceを逆コンパイルするとどっちもInterfaceだった
— しげちゃん (@shigemk2) May 24, 2015
ここでふと思ったけど、JD-GUIを過信しすぎなのではないかという疑問
— しげちゃん (@shigemk2) May 24, 2015
クラスファイルだとレジスタに相当するものがなく、すべてスタックでごにょごにょしているとのこと。 http://t.co/WYQj5IgXNv
— しげちゃん (@shigemk2) May 24, 2015
えっ、レジスタがない…?
— しげちゃん (@shigemk2) May 24, 2015
stack=2, locals=3, args_size=2
0: iconst_1
1: istore_2
2: iload_2
3: iconst_2
4: iadd
5: istore_2
— しげちゃん (@shigemk2) May 24, 2015
stack=2, locals=2, args_size=1
0: iconst_1
1: istore_1
2: iload_1
3: iconst_2
4: iadd
5: istore_1
— しげちゃん (@shigemk2) 2015, 5月 24
Scalaだとローカル変数がこの段階で既に2つ入っている
— しげちゃん (@shigemk2) 2015, 5月 24
と思われる
— しげちゃん (@shigemk2) 2015, 5月 24
てゆーかprint邪魔だから外したほうがいいと思った
— しげちゃん (@shigemk2) 2015, 5月 24
JVMのバイトコードでは、データをスタックに退避しつつ、ローカル変数に突っ込むという作業を行っているらしく、Javaだとローカル変数0番目にthisが入るけど、Scalaだとローカル変数に何が入っているのか
— しげちゃん (@shigemk2) 2015, 5月 24
はてなブログに投稿しました #はてなブログ
クラスファイルの LineNumberTableとLocalVariableTableについて - by shigemk2
http://t.co/efwKDM55CC
— しげちゃん (@shigemk2) 2015, 5月 24