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
まだほとんど意味はわからないけど、嬉しいな。