He modificado la línea 15 del código de bytes a continuación y lo cambió formar invokevirtual a invokespecial (JAVA 8). Por desgracia, me sale un error de verificar (Tipo incorrecto de pila de operandos)
Yo sé que el valor de la pila operando debe ser una subclase de la clase especificada en el ObjectRef pero en este caso # 18 está Tipo y no de tipo $ ClassType como sugiere el error. O para decirlo de otra manera no debería el stackmapframe en la línea 15 tiene Tipo y no Tipo $ ClassType en la pila [0]? ¿Qué me estoy perdiendo?
editar: stackmapframes son los mismos antes y después del cambio. (En caso de ASM CÓMPUTO MARCOS que utilicé lo habrían cambiado)
Exception Details:
Location:
com/sun/tools/javac/code/Type$ClassType.toString()Ljava/lang/String; @15: invokespecial
Reason:
Type 'com/sun/tools/javac/code/Type' (current frame, stack[0]) is not assignable to 'com/sun/tools/javac/code/Type$ClassType'
Current Frame:
bci: @15
flags: { }
locals: { 'com/sun/tools/javac/code/Type$ClassType', 'java/lang/StringBuilder' }
stack: { 'com/sun/tools/javac/code/Type', 'com/sun/tools/javac/code/TypeTag' }
...
Stackmap Table:
append_frame(@71,Object[#108])
same_frame(@85)
same_frame(@121)
Aquí es de código. Escriba $ ClassType es una subclase directa de Tipo y com / sun / herramientas / javac / código / Tipo $ ClassType es la clase actual, que nos permite llamar a una superclase (como el tipo) con invokespecial
public class com.sun.tools.javac.code.Type$ClassType extends com.sun.tools.javac.code.Type implements
javax.lang.model.type.DeclaredType
....
public java.lang.String toString();
descriptor: ()Ljava/lang/String;
flags: ACC_PUBLIC
Code:
stack=4, locals=2, args_size=1
0: new #108 // class java/lang/StringBuilder
3: dup
4: invokespecial #17 // Method java/lang/StringBuilder."<init>":()V
7: astore_1
8: aload_0
9: invokevirtual #13 // Method com/sun/tools/javac/code/Type$ClassType.getEnclosingType:()Lcom/sun/tools/javac/code/Type;
12: getstatic #10 // Field com/sun/tools/javac/code/TypeTag.CLASS:Lcom/sun/tools/javac/code/TypeTag;
15: invokespecial #18 // Method com/sun/tools/javac/code/Type.hasTag:(Lcom/sun/tools/javac/code/TypeTag;)Z
18: ifeq 71
.....
StackMapTable: number_of_entries = 3
frame_type = 252 /* append */
offset_delta = 71
locals = [ class java/lang/StringBuilder ]
frame_type = 13 /* same */
frame_type = 35 /* same */
Intenta ejecutar invokespecial
en una instancia de Type
(devuelto por invokevirtual
@ 9), mientras que el verificador espera que la referencia de la clase actual, es decir Type$ClassType
.
Ver las JVM §4.10.1.9 :
Uno puede sustituir válidamente tipos que concuerden con la clase actual y los tipos de argumentos dados en el descriptor de la pila de operandos entrante con el tipo de retorno proporcionado en el descriptor, produciendo el estado de tipo saliente.