Come evitare “tipo illegale di piscina costante” usando “ldc_w ” in Jasmine?
Domanda
Sto scrivendo un compilatore che genera codice Jasmin e vuole richiamare un metodo che prende una classe come parametro.
public class CTest
{
public static void main(String[] args)
throws Exception
{
java.lang.reflect.Array.newInstance(CTest.class, 0);
}
}
Quindi, in Jasmin, penso che dovrebbe essere:
.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
Quando ho assemblare ed eseguirlo ottengo:
Exception in thread "main" java.lang.VerifyError: (classe: CTest2, metodo: firma main: ([Ljava / lang / String;) V) Tipo illegale di pool di costanti
Guardando il codice smontato sia per CTest.class (versione Java) e CTest2.class (la versione Jasmin) con "javap -c -verbose" entrambi sembrano montare la piscina costante allo stesso modo:
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
ho risolto due bug nel Jasmin già, ma non riesco a vedere che cosa è facendo male quando mette la classe nella piscina costante per "ldc_w" mette classi in piscina costante per altre istruzioni, come "Nuovo" e "anewarray" in modo corretto.
Ho provato a guardare i file .class con TraceClassVisitor in ASM, ma non il dump del pool di costanti.
Tutte le idee che posso provare dopo?
Soluzione
È necessario garantire che il numero di versione della classe è di almeno 49 (vedi la visitLdcInsn su questo ASM pagina Javadoc ).