invokedynamic
ASM を使用して命令を生成するための次のコードを考えてみましょう。
// BOOTSTRAP = new Handle(->
// CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType methodType, Class<?> someClass)
mv.visitInvokeDynamicInsn("foo", "(I)I", BOOTSTRAP, Type.INT_TYPE);
生成されたクラスをASMifierで逆コンパイルすると該当行が
mv.visitInvokeDynamicInsn("foo", "(I)I", new Handle(/* SNIP (same as BOOTSTRAP) */),
Type.getType("LI;"));
¯¯¯¯¯
ご覧のとおり、Type.INT_TYPE
は という名前の参照型へのリテラル参照に変わりましたI
。これが存在しないため、JVM は実行時にjava.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: I
.
私が代わりにやりたかったのは、 int.class
(Class
プリミティブ型のインスタンスint
、またはInteger.TYPE
定数の値)bootstrap
の引数としてメソッドに渡すことでしたsomeClass
。ただし、ASM はこれを適切に理解またはサポートしていないようです。
これは ASM のバグと見なすことができますか? また、回避策はありますか?