Storyyeller / Krakatau

Java decompiler, assembler, and disassembler
GNU General Public License v3.0
1.97k stars 220 forks source link

Error in inference verifier #71

Closed samczsun closed 8 years ago

samczsun commented 8 years ago
.method public static main : ([Ljava/lang/String;)V 
    .code stack 10 locals 10
        .catch java/lang/Throwable from L0 to L1 using L0
        new java/lang/Integer
        astore_1
        aconst_null
L0:     
        pop
        aload_1
        ifnonnull L3
        new java/lang/Long
        astore_1     
L1:
        return
L3:
        aload_1
        dup
        iconst_0
        invokespecial Method java/lang/Integer <init> (I)V
        getstatic java/lang/System out Ljava/io/PrintStream;
        swap
        invokevirtual java/io/PrintStream println (Ljava/lang/Object;)V
        return
    .end code 
.end method

Code runs fine on 1.8.0_74. May be a bug in the jre but it doesn't feel like it

EDIT: Here's one with stackmapframes (I was testing on major 49)

.method public static main : ([Ljava/lang/String;)V 
    .code stack 10 locals 10
        .catch java/lang/Throwable from L0 to L1 using L0
Linit:     new java/lang/Integer
        astore_1
        aconst_null
        .stack full
            locals Object [Ljava/lang/String; Uninitialized Linit
            stack Object java/lang/Object
        .end stack
L0:     
        pop
        aload_1
        ifnonnull L3
        new java/lang/Long
        astore_1     
L1:
        return        
        .stack full
            locals Object [Ljava/lang/String; Uninitialized Linit
            stack
        .end stack
L3:
        aload_1
        dup
        iconst_0
        invokespecial Method java/lang/Integer <init> (I)V
        getstatic java/lang/System out Ljava/io/PrintStream;
        swap
        invokevirtual java/io/PrintStream println (Ljava/lang/Object;)V
        return
    .end code 
.end method
Storyyeller commented 8 years ago

I'm pretty sure this code should be invalid. It might be a bug in the JVM. I'll have to investigate in more detail later.

Storyyeller commented 8 years ago

I just checked the JVM's verifier code again and it turns out that when merging into an exception handler, it uses the old register state, rather than the new register state like I thought. A pretty subtle mistake. Thanks for catching it.