Open

Description
Compiler version
3.2.0
Comparing to Scala 2.13.10
object main {
def main(args: Array[String]): Unit = {
lazy val str = "abc"
println(str)
}
}
The main
method compiles to the following bytecode:
public void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0001) ACC_PUBLIC
Code:
stack=2, locals=3, args_size=2
0: new #19 // class scala/runtime/LazyRef
3: dup
4: invokespecial #20 // Method scala/runtime/LazyRef."<init>":()V
7: astore_2
8: getstatic #25 // Field scala/Predef$.MODULE$:Lscala/Predef$;
11: aload_2
12: invokestatic #29 // Method str$1:(Lscala/runtime/LazyRef;)Ljava/lang/String;
15: invokevirtual #33 // Method scala/Predef$.println:(Ljava/lang/Object;)V
18: return
LineNumberTable:
line 3: 0
line 4: 8
LocalVariableTable:
Start Length Slot Name Signature
8 11 2 str$lzy Lscala/runtime/LazyRef;
0 19 0 this Lmain$;
0 19 1 args [Ljava/lang/String;
MethodParameters:
Name Flags
args final
str$lzy
is a scala.runtime.LazyRef
local variable. This variable can be passed to the synthetic getter str$1
(signature: java.lang.String str$1(scala.runtime.LazyRef)
) and the lazy value initialized.
Scala 3.2.0 bytecode
The exact same code is compiled in the following way:
public void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0001) ACC_PUBLIC
Code:
stack=3, locals=3, args_size=2
0: new #30 // class scala/runtime/LazyRef
3: dup
4: invokespecial #31 // Method scala/runtime/LazyRef."<init>":()V
7: astore_2
8: getstatic #36 // Field scala/Predef$.MODULE$:Lscala/Predef$;
11: aload_0
12: aload_2
13: invokespecial #40 // Method str$1:(Lscala/runtime/LazyRef;)Ljava/lang/String;
16: invokevirtual #44 // Method scala/Predef$.println:(Ljava/lang/Object;)V
19: return
LineNumberTable:
line 2: 0
line 3: 0
line 4: 8
LocalVariableTable:
Start Length Slot Name Signature
0 20 0 this Lmain$;
0 20 1 args [Ljava/lang/String;
Signature: #27 // ([Ljava/lang/String;)V
MethodParameters:
Name Flags
args final
where there is no entry for the scala.runtime.LazyRef
wrapper variable.
If this variable is surfaced (like in Scala 2.13), additional debugger functionality can be built on top of it. For example, IDEA is able to present lazy values like the following:
And after initializing the lazy value on demand by clicking on the initialize prompt:
Thanks.