Bytecode carving game - how to declare local variables inside a call to super() ?
Remi Forax
forax at univ-mlv.fr
Thu Apr 23 12:34:18 UTC 2020
I'm sure you want to play a game,
what about i give you the bytecode, show me the corresponding Java code :)
Let say i have this code:
public interface Fun {
record Point(int x, int y) { }
record Circle(Point center, int radius) { }
class Shape {
private final double distanceToOrigin;
public Shape(double distanceToOrigin) {
this.distanceToOrigin = distanceToOrigin;
}
}
class Disc extends Shape {
public Disc(Circle circle) {
super(Math.sqrt(circle.center.x * circle.center.x + circle.center.y * circle.center.y));
}
}
}
The code in super() has a lot of repetition, circle.center is used 4 times !
The generated bytecode for this example (it is the same using javac or ecj, the eclipse compiler),
shows 4 calls to getfield Fun$Circle.center:LFun$Point;
$ javap -c Fun\$Disc.class
Compiled from "Fun.java"
public class Fun$Disc extends Fun$Shape {
public Fun$Disc(Fun$Circle);
Code:
0: aload_0
1: aload_1
2: getfield #8 // Field Fun$Circle.center:LFun$Point;
5: getfield #14 // Field Fun$Point.x:I
8: aload_1
9: getfield #8 // Field Fun$Circle.center:LFun$Point;
12: getfield #14 // Field Fun$Point.x:I
15: imul
16: aload_1
17: getfield #8 // Field Fun$Circle.center:LFun$Point;
20: getfield #20 // Field Fun$Point.y:I
23: aload_1
24: getfield #8 // Field Fun$Circle.center:LFun$Point;
27: getfield #20 // Field Fun$Point.y:I
30: imul
31: iadd
32: i2d
33: invokestatic #23 // Method java/lang/Math.sqrt:(D)D
36: invokespecial #29 // Method Fun$Shape."<init>":(D)V
39: return
}
Now, refactoring the java source code using the jdk 14, I was able to get ecj to generate this bytecode:
$ javap -c Fun\$Disc.class
Compiled from "Fun.java"
public class Fun$Disc extends Fun$Shape {
public Fun$Disc(Fun$Circle);
Code:
0: aload_0
1: aload_1
2: getfield #8 // Field Fun$Circle.center:LFun$Point;
5: astore_2
6: aload_2
7: getfield #14 // Field Fun$Point.x:I
10: istore_3
11: aload_2
12: getfield #20 // Field Fun$Point.y:I
15: istore 4
17: iload_3
18: iload_3
19: imul
20: iload 4
22: iload 4
24: imul
25: iadd
26: i2d
27: invokestatic #23 // Method java/lang/Math.sqrt:(D)D
30: invokespecial #29 // Method Fun$Shape."<init>":(D)V
33: return
}
as you can see i'm able to declare local variables, the slot 2, 3 and 4, to store center, center.x and center.y, inside the call to super !
How to do declare a local variable inside a call to super (several solutions) ?
What is the Java code corresponding to the bytecode above ?
regards,
Rémi
More information about the amber-dev
mailing list