Comment éviter « Type illégal dans la piscine constante » en utilisant « ldc_w » Jasmin?
Question
J'écris un compilateur qui génère du code Jasmin et veulent invoquer une méthode qui prend une classe en tant que paramètre.
public class CTest
{
public static void main(String[] args)
throws Exception
{
java.lang.reflect.Array.newInstance(CTest.class, 0);
}
}
Alors Jasmin, je pense que cela devrait être:
.class public CTest2
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 2
.limit locals 1
ldc_w CTest2
iconst_0
invokestatic java/lang/reflect/Array/newInstance(Ljava/lang/Class;I)Ljava/lang/Object;
pop
return
.end method
Quand j'assemblez et exécutez-je obtenir:
Exception in thread "main" java.lang.VerifyError: (classe: CTest2, méthode: signature principale: ([Ljava / lang / String;) V) Type illégal dans la piscine constante
En regardant le code désassemblé pour les deux CTest.class (la version Java) et CTest2.class (la version Jasmin) avec "javap -c verbose" ils semblent tous deux mis en place la piscine constante de la même façon:
const #2 = class #16; // CTest
const #16 = Asciz CTest;
0: ldc_w #2; //class CTest
const #14 = Asciz CTest2;
const #17 = class #14; // CTest2
0: ldc_w #17; //class CTest2
Je l'ai fixé deux bugs dans Jasmin déjà, mais je ne peux pas voir ce qu'il est faire mal lors de la mise de la classe dans la piscine constante pour « ldc_w » il met les classes dans la piscine constante pour d'autres instructions, comme "Nouveau" et "anewarray" correctement.
Je l'ai essayé de regarder les fichiers .class avec TraceClassVisitor dans ASM, mais il ne pas la piscine de vidage constante.
Toutes les idées ce que je peux essayer ensuite?
La solution
Vous devez vous assurer que le numéro de version de la classe est d'au moins 49 (voir le visitLdcInsn sur cette ASM Javadoc ).