Storyyeller / Krakatau

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

checkcast causes code to not be shown #74

Closed samczsun closed 8 years ago

samczsun commented 8 years ago
.method public static main : ([Ljava/lang/String;)V 
    .code stack 10 locals 10 
        iconst_2
        anewarray java/io/Serializable
        astore_0
        aload_0
        iconst_0
        new java/util/concurrent/atomic/AtomicReference
        dup
        aload_0
        invokespecial Method java/util/concurrent/atomic/AtomicReference <init> (Ljava/lang/Object;)V
        checkcast java/io/Serializable
        aastore
        aload_0
        iconst_1
        aconst_null
        aastore
        getstatic java/lang/System out Ljava/io/PrintStream;
        aload_0
        iconst_1
        aaload
        invokevirtual Method java/io/PrintStream println (Ljava/lang/Object;)V
        return
    .end code 
.end method 

Output:

    public static void main(String[] a)
    {
        java.io.Serializable a0 = (java.io.Serializable)(Object)new java.util.concurrent.atomic.AtomicReference((Object)new java.io.Serializable[2]);
    }

Removing the checkcast fixes the problem

Storyyeller commented 8 years ago

Looks like the problem is that it thinks that the cast will always fail because it doesn't understand interfaces and hence optimizes away everything after the cast. Unfortunately, this is one of those things that will take a lot of work to fix.

Storyyeller commented 8 years ago

As a temporary workaround, I could disable optimization of checkcasts. That might lead to other problems though. What do you think?

samczsun commented 8 years ago

I'm a bit lacking in sleep now, so you'll have to remind me what problems could arise from disabling optimization of checkcasts.

Nothing comes to mind so my first suggestion would have been to disable optimization by default and have a flag to enable (this isnt as difficult to replicate as the exception bug so I don't think it should be disabled by default)

Storyyeller commented 8 years ago

On further thought, I think it could be disabled in a way that wouldn't cause additional problems. So I'll go ahead and do that tomorrow.

Storyyeller commented 8 years ago

As I feared, simply disabling the check won't work. I'd have to essentially disable optimization of objects entirely.

Edit: After further experimentation, I can't find any simple way to fix this at all. Sorry.

samczsun commented 8 years ago

I'm not too familiar with how Krakatau handles interfaces. Perhaps you could point me to the file where the eager optimization occurs and I can try to make some sense of it? Or if you have time a quick explanation would work too.

Storyyeller commented 8 years ago

Nevermind, I managed to get it working. The solution is pretty hackish, but at least I got it so it works on your examples without breaking any of the existing tests.

One of the issues here is that you can't just rid of cast optimization entirely, because in the case where the cast really is invalid, that will leave variables that have no possible type, and Krakatau can't handle that.