このKotlinのコードにjavap(逆アセンブラ)、jad(逆コンパイラ)を使ってみる実験です。
hello.kt
fun main(args: Array<String>) {
println("Hello, World!")
}
コードの出典
https://kotlinlang.org/docs/tutorials/command-line.html
Kotlinは他のJVM言語と同じく、Javaとして実行可能なクラスファイルにコンパイルされます。
そちらをjavapでJVMのニーモニックを表示したりjadでjavaのソースコードとして逆コンパイルすることができるので検証してみました。
コンパイル
kotlinc hello.kt -include-runtime -d hello.jar
jarを展開してhello.classに対してjavap,jadを使います
jar xf hello.jar
環境
macOS High Sierra 10
javap(逆アセンブラ)
用意
JDKに最初から入っているので不要
実行
コマンド
javap -c HelloKt.class
結果
Compiled from "hello.kt"
public final class HelloKt {
public static final void main(java.lang.String[]);
Code:
0: aload_0
1: ldc #9 // String args
3: invokestatic #15 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
6: ldc #17 // String Hello, World!
8: astore_1
9: getstatic #23 // Field java/lang/System.out:Ljava/io/PrintStream;
12: aload_1
13: invokevirtual #29 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
16: return
}
jad(逆コンパイラ)
用意
jadの導入方法
brew tap caskroom/cask
brew install caskroom/cask/jad
参考にしたサイトhttp://inarizuuuushi.hatenablog.com/entry/2017/05/09/231600
実行
-aオプションでニーモニックをコメントとして表示できます。
コマンド
$ jad -a HelloKt.class
$ cat HelloKt.jad
import java.io.PrintStream;
import kotlin.jvm.internal.Intrinsics;
public final class HelloKt
{
public static final void main(String args[])
{
Intrinsics.checkParameterIsNotNull(args, "args");
// 0 0:aload_0
// 1 1:ldc1 #9 <String "args">
// 2 3:invokestatic #15 <Method void Intrinsics.checkParameterIsNotNull(Object, String)>
String s = "Hello, World!";
// 3 6:ldc1 #17 <String "Hello, World!">
// 4 8:astore_1
System.out.println(s);
// 5 9:getstatic #23 <Field PrintStream System.out>
// 6 12:aload_1
// 7 13:invokevirtual #29 <Method void PrintStream.println(Object)>
// 8 16:return
}
}
結構簡単に導入・解析することができました。
今後Kotlin特有の機能がどのようにJavaとして表現・変換されているのか手元で検証しようと思います。