Verificar invokespecial de error: Tipo no es asignable

user3161227:

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 */
apangin:

Intenta ejecutar invokespecialen 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.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=178279&siteId=1
Recomendado
Clasificación