Skip to content

Instantly share code, notes, and snippets.

@Deamon5550
Created March 27, 2017 19:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Deamon5550/18e2f1a88e89f89e75a19157d9777707 to your computer and use it in GitHub Desktop.
Save Deamon5550/18e2f1a88e89f89e75a19157d9777707 to your computer and use it in GitHub Desktop.
Kotlin Bytecode Issues
fun main(args: Array<String>) {
val x = 10
val y = 9
if(x == 6) {
if(y == 6) {
println("a")
} else {
println("b")
}
} else {
println("c")
}
}
/*
The goto at the end of the inner if block (instruction 34 in hello.kt.javap)
points directly at another goto (insn 47) which is the end of the outer if block.
In the equivalent compiled java you can see that the goto at the
end of the inner if (insn 26) targets directly the end of the outer else (insn 48).
Kotlin:
Code:
0: aload_0
1: ldc #50 // String args
3: invokestatic #29 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
6: bipush 10
8: istore_1
9: bipush 9
11: istore_2
12: iload_1
13: bipush 6
15: if_icmpne 50
18: iload_2
19: bipush 6
21: if_icmpne 37
24: ldc #51 // String a
26: astore_3
27: getstatic #57 // Field java/lang/System.out:Ljava/io/PrintStream;
30: aload_3
31: invokevirtual #63 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
34: goto 47
37: ldc #64 // String b
39: astore_3
40: getstatic #57 // Field java/lang/System.out:Ljava/io/PrintStream;
43: aload_3
44: invokevirtual #63 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
47: goto 60
50: ldc #66 // String c
52: astore_3
53: getstatic #57 // Field java/lang/System.out:Ljava/io/PrintStream;
56: aload_3
57: invokevirtual #63 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
60: return
Java:
Code:
0: bipush 9
2: istore_1
3: bipush 10
5: istore_2
6: iload_1
7: bipush 6
9: if_icmpne 40
12: iload_2
13: bipush 6
15: if_icmpne 29
18: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
21: ldc #3 // String a
23: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
26: goto 48
29: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
32: ldc #5 // String b
34: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
37: goto 48
40: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
43: ldc #6 // String c
45: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
48: return
*/
fun main(args: Array<String>) {
println("Hello World")
}
/*
As you can see in the bytecode below even in this most simple of cases the constant value
"Hello World" is assigned first to local 1 (which isn't actually defined in the lvt) and
then loaded again to be passed to the method.
I'm really not sure what this extra reassignment is, I suspect its an artifact of some other
part of their byte code generation that has to do some validate or something before its
passed, but I have yet to see any code that actually does anything with the value.
Code:
0: aload_0
1: ldc #9 // String args
3: invokestatic #15 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
6: ldc #17 // String Hello World
8: astore_1
9: getstatic #23 // Field java/lang/System.out:Ljava/io/PrintStream;
12: aload_1
13: invokevirtual #29 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
16: return
LineNumberTable:
line 4: 6
line 5: 16
LocalVariableTable:
Start Length Slot Name Signature
0 17 0 args [Ljava/lang/String;
*/
fun main(args: Array<String>) {
for (x in 1..5) {
print(x)
}
}
/*
Two issues here first of all theres a redundant condition. The generated code
is essentially a do-while in an if when it could just be a standard while loop.
The other issue is they're using the local slot 1 (which is the value within
the loop) before the lvt actually defines it. It is used in insn 10 below but not
defined until insn 15.
Code:
0: aload_0
1: ldc #9 // String args
3: invokestatic #15 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
6: iconst_1
7: istore_1
8: iconst_5
9: istore_2
10: iload_1
11: iload_2
12: if_icmpgt 33
15: getstatic #21 // Field java/lang/System.out:Ljava/io/PrintStream;
18: iload_1
19: invokevirtual #27 // Method java/io/PrintStream.print:(I)V
22: iload_1
23: iload_2
24: if_icmpeq 33
27: iinc 1, 1
30: goto 15
33: return
LineNumberTable:
line 4: 6
line 5: 15
line 4: 22
line 7: 33
LocalVariableTable:
Start Length Slot Name Signature
15 15 1 x I
0 34 0 args [Ljava/lang/String;
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment