JVMで動作するプログラミング言語を作るにはどうしたらよいのだろう?(2)
とりあえず、JVMの仕様を勉強しないといけないっぽい。
本はあるようなのだけど、今は金欠なので本かわないで何とかしてみようと思う。
まず、JVMのバイトコードの種類の一覧が欲しいと思う。
なにやらバイトコードのバイトは命令が1バイトから来ているらしいので。
で、
http://www.asukaze.net/etc/cil/jvm_opcode.html
あすかぜさんというかたのサイトに一覧を見つけた。
この日本語訳も欲しいところなのだけど、まぁいいやと。
てことで、次にこれを試したいと思ったので、jasminとjasperを使って試してみる。
まず、試してみたのがiconst_1をiconst_0に変えるってこと。
javaのバイトコードは小さい数は1バイトで済むとかいうことをjavaで3Dをやってた人のホームページで
見た覚えがある。
おそらく、iconst_1は1をスタックマシンにpush、
iconst_0は0をスタックマシンにpushするという意味だろう。
ってことで、それを試すために、
a.java
class a { int n() { return 1; } }
s.java
class s { public static void main(String[] argv) { System.out.println(new a().n()); } }
等というプログラムを作って
javac a.java javac s.java
でコンパイルする。
java s
とすれば、1と表示された。
java -jar jasper.jar a.class
でa.jというファイルにディスアセンブルしてみると以下のようになった。
.source a.java .class a .super java/lang/Object .method <init>()V .limit stack 1 .limit locals 1 .line 1 aload_0 invokespecial java/lang/Object/<init>()V return .end method .method n()I .limit stack 1 .limit locals 1 .line 3 iconst_1 ireturn .end method
なんだかよく分からないけどとりあえず、出来たプログラムをjasminでアセンブルする。
java -jar jasmin.jar a.j
で、a.classが再生成される。
この後、
java s
で実行すると1と表示される。うまく行っているようだ。
さて、この中で一番下の
iconst_1 ireturn
ここが今回注目のiconst_1です。これをiconst_0に変えて
java -jar jasmin.jar a.j java s
として、コンパイル実行すると0と表示された成功だぁ!iconst_5まであるので、iconst_5とやってみると5と表示される。
さて、今a.classは226 バイトです。ここで、iconst_n以外のものを使ってみましょう。
a.javaを
class a { int n() { return 33; } }
とかして、コンパイル後、jasperでディスアセンブルすると、iconst_1だった部分が
bipush 33
となってました。どうも、bipushがintの値をスタックに積む命令のようです。
ということで、iconst_1の部分をbipush 33にして、アセンブルしなおすと、227バイトになりました。
1バイトしか増えてませんね。bipushは1バイトだけ余分に食うんですね。
てことは、sipushとかいうのだと2バイトとかあるんじゃなかろうかとやってみると、ありました。
バイトコード表にも載ってます。で、228バイトと2バイト増えました。
では4バイトだと、iipushとかlipushかなぁ思って見ますがありません。ムムム。
ではと、a.javaにreturn 3333333とか書いて、jasperでディスアセンブルしてみると。
ldc 333333
となってました。ldcか。ldcがどうやら、4バイトのものらしいです。232バイトなので4バイト増えてる。
間違いない。ということで、今日はintをスタックにpushする命令を複数個試してみたのでした。