読者です 読者をやめる 読者になる 読者になる

JasminによるJava Bytecode入門(とりあえずHelloWorldまで)

コンパイラをつくりましょう、と思って、GASのコードを吐き出したりしてもいいのでしょうが、あまりきれいじゃないし、リンクとかよく分からなくて難しいし、動くところが限られるし、ということでJava Bytecodeをはき出すコンパイラを作ることにしました。

そこで、今回はJava BytecodeのアセンブラであるJasminを使うための環境構築(簡単だけど)の方法を書いておこうかと思います。


Jasminを始めるための説明としては Javaアセンブラ「Jasmin」を使おう [Javaプログラミング] All About にすごくわかりやすくまとまっているものがあるのですが、残念ながら最初にダウンロードできるものも、ここにあるものも、HelloWorldサンプルプログラムがうまく動かない。
というわけで、まだぜんぜん知識がないためにWeb上の情報をかき集めただけになりますが、JasminでHello Worldを表示するまでを、とりあえず記事にしておきます。

Jasminのダウンロード

JasminはJavaで書かれているので、 Jasmin Home Page からJarファイルをダウンロードすれば、JVMが入っている環境では簡単に動いてくれます。
この記事を書いている時点での最新版はjasmin-2.4です。

実際に動かすためにはダウンロードしたZIPファイルを解凍してjasmin.jarのあるディレクトリにcdし、

$ java -jar jasmin.jar xxx.j

と普通に引数にアセンブルするファイルを指定してJarファイルを実行するだけです。

HelloWorld.jを試す

早速解凍された中にあったexsampleディレクトリの中のHelloWorld.jをアセンブルすると

$ java -jar jasmin.jar exsample/HelloWorld.j
Generated: NoJad/j.class

"Generated"とうまくいった感じになります。
ん、でもなんで名前が"j.class"なんだろう。とか思いながら実行してみると

$ java NoJad.j
Exception in thread "main" java.lang.VerifyError: (class: NoJad/j, method: main signature: ([Ljava/lang/String;)V) Expecting to find object/array on stack

うまくいかない。
というわけで、ちょっと調べてみると、やはり全く同じお困り事を持った人が SourceForge.net: Jasmin - a Java assembler: stuck at HelloWorld step :-S にいた。

ここの回答によるとどうやらJasmin付属のHelloWorld.jはバージョン2.0から壊れているらしい。なんのこっちゃ。
でも結局、私の場合はバージョン1.1のHelloWorld.jを使っても結局同じエラーが出てしまったので、最終的には上のスレッドの回答に載っているコードをコピペして、ようやく実行することができました。

最終的なHelloWorldプログラムは以下。

.class public examples/HelloWorld
.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, World!"
   invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
   return
.end method

まだほとんど意味はわからないけど、嬉しいな。

おまけ

ちなみに、今はワークスペースディレクトリとjasmin.jarのあるディレクトリとを別にしているので、jasmin.jarのあるディレクトリをPATHの通っているところに移して、そこに"jasmin"という名前のシェルスクリプトファイルを作成し、

#!/bin/sh
java -jar [jasmin.jarへの絶対パス]/jasmin.jar $1

として、どこからでも

$ jasmin xxx.j

アセンブルできるようにしてみています。
うん、ぽいな。