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する命令を複数個試してみたのでした。