goto
Java言語では予約済みのキーワードですが、実際には使用されていません。そして、あなたはおそらくそれgoto
がJava仮想マシン(JVM)オペコードであることも知っています。私は、Java、ScalaのとKotlinのすべての高度な制御フロー構造は、JVMレベルで、いくつかの組み合わせを使用して実装されて数えるgoto
とifeq
、ifle
、iflt
など、
JVM仕様https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.goto_wを見ると、goto_w
オペコードもあることがわかります。一方、goto
オフセット2バイトの分岐を取り、goto_w
オフセット4バイトの分岐を取ります。仕様には、
がgoto_w命令はオフセット4バイトの分岐を取り、他の要因は、65535バイト(§4.11)のメソッドのサイズを制限します。この制限は、Java仮想マシンの将来のリリースで引き上げられる可能性があります。
goto_w
他のいくつかの*_w
オペコードのように、将来に備えているように思えます。しかし、私goto_w
はgoto
、必要に応じて調整を行って、上位2バイトをゼロにし、下位2バイトをと同じように使用して、必要に応じて調整することもできます。
たとえば、次のJava Switch-Case(またはScala Match-Case)があるとします。
12: lookupswitch {
112785: 48 // case "red"
3027034: 76 // case "green"
98619139: 62 // case "blue"
default: 87
}
48: aload_2
49: ldc #17 // String red
51: invokevirtual #18
// Method java/lang/String.equals:(Ljava/lang/Object;)Z
54: ifeq 87
57: iconst_0
58: istore_3
59: goto 87
62: aload_2
63: ldc #19 // String green
65: invokevirtual #18
// Method java/lang/String.equals:(Ljava/lang/Object;)Z
68: ifeq 87
71: iconst_1
72: istore_3
73: goto 87
76: aload_2
77: ldc #20 // String blue
79: invokevirtual #18
// etc.
次のように書き直すことができます
12: lookupswitch {
112785: 48
3027034: 78
98619139: 64
default: 91
}
48: aload_2
49: ldc #17 // String red
51: invokevirtual #18
// Method java/lang/String.equals:(Ljava/lang/Object;)Z
54: ifeq 91 // 00 5B
57: iconst_0
58: istore_3
59: goto_w 91 // 00 00 00 5B
64: aload_2
65: ldc #19 // String green
67: invokevirtual #18
// Method java/lang/String.equals:(Ljava/lang/Object;)Z
70: ifeq 91
73: iconst_1
74: istore_3
75: goto_w 91
79: aload_2
81: ldc #20 // String blue
83: invokevirtual #18
// etc.
goto_w
s に対応するために「行番号」の変更を誤った可能性があるため、実際にはこれを試していません。しかし、それは仕様に含まれているので、それを行うことが可能であるはずです。
私の質問は、コンパイラーまたはバイトコードのその他のジェネレーターがgoto_w
現在の65535の制限で使用できる理由があるかどうか、それが実行できることを示すこと以外にあるのかどうかです。
// ... repeat 10K times ...
コンパイルできますか?単一のソースクラスのサイズには制限があることはわかっていますが、正確に何なのかはわかりません(コード生成は、何かが実際にヒットするのを見たときだけです)。