2014-09-17

Jasmin ― Javaバイトコードアセンブリ言語

Categories: Java JVM Jasmin
jvm.png

[ PR ]


Java仮想マシン(JVM)について知ることは、Javaのプロコーダーとして理解度を向上させ、革新的なライブラリや言語を作る助けになります。

代表的なライブラリに、ASMがありますが、基本的な仕組みはJava Virtual Machine Specificationに記載されているように、ほとんど同じような形で記述します。

そこで、JVMバイトコードの基礎的な学習に便利な、JasminというJVMアセンブラがあります。

例えば、Hello Worldは以下のようになります。

.class public Hello
.super java/lang/Object

.method public <init>()V
    aload_0
    invokenonvirtual java/lang/Object/<init>()V
    return
.end method

.method public static main([Ljava/lang/String;)V
    .limit stack 2
    getstatic java/lang/System/out Ljava/io/PrintStream;
    ldc "Hello, Jasmin!"
    invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
    return
.end method

これをJasminでコンパイルすると、クラスファイル(.class)が出力されます。

説明

クラス

まず、.class public HelloでHelloクラスを定義します。(この名前が出力されるファイル名になります)

コンストラクタ

次に、.method文でメソッドを定義します。()Vというシグネチャを指定することで、引数なしのコンストラクタが作成されます。

Helloは java.lang.Object を継承してできているので、.super文で定義します。

それ以下は内容を定義していますが、invokenonvirtual(invokespecial)でスーパークラスのコンストラクタを呼んでいます(super();)。

メソッド定義

次に、main関数(エントリポイント)を定義しています。先程同様に.methodで定義します。

ここで、[Ljava/lang/String;というのは、String[]を表しており、[ は配列、L ... ; でクラスのシグネチャとなります。(ちなみにVはvoidです)

残りは内容を定義していますが、

  • .limit stack 2でスタックの最大値を設定
  • getstatic java/lang/System/out Ljava/io/PrintStream; でSystem.outをスタックに格納
  • ldc "Hello, Jasmin!" で文字列をスタックに格納
  • invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V で、スタックを使って void println(String s) を実行

といった内容になっています。

特にシグネチャ(クラス、プリミティブ型)は他のJVMバイトコード定義(ASMなど)でも使います。

シンタックスハイライト

なお、Sublime Text 2では自作のハイライトが使えます。

Jasmin JVM Assenbler - Package Control

[Ctrl + Shift + P]で "Package Control - Install" を選択し、Jasmin JVM Assemblerを選ぶと適用されます。(拡張子は .j )

コメントはTwitterアカウントにお願いします。

RECENT POSTS


[ PR ]

.