As for SAM wrappers, the bytecode sequence
new A
dup
new B
dup
invokespecial B.<init>
invokespecial A.<init>
breaks the inliner, so instead we do
new B
dup
invokespecial B.<init>
store x
new A
dup
load x
invokespecial A.<init>
Otherwise, the cached instances cannot be reused for different wrapped
types. Also, if the wrapped type is regenerated during inlining, the
inliner would produce a call to a nonexistent constructor that takes the
regenerated type as an argument.
To avoid bytecode sequences like
new _1Kt$sam$i$java_lang_Runnable$0
dup
new _1Kt$f$1
dup
invokespecial _1Kt$f$1.<init>()V
invokespecial _1Kt$sam$i$java_lang_Runnable$0.<init>(...)V
as the different order of `new` and `<init>` confuses the inliner.
Consider a file with only private top-level properties compiled into
a klib. If this klib is deserialized with deserializationStrategy.ALL
(e.g. if this library if passed using the -Xinclude flag),
initializers of these properties will not be generated in a final
binary.
This patch fixes this error by unconditionally adding IrFiles into
deserialization queue if deserializationStrategy.ALL is specified.
Issue #KT-34722 fixed
Top-level initializers must be deserialized in the same order they
where in the original source file. Before this patch this rule might
be violated. Consider the following case:
// lib1.kt
val a = 5
val b = a * 5
// lib2.kt
fun foo() = println(b)
Compile both files into libraries and then link an application
against them. During deserialization of lib2 'b' will be added
to the deserialization queue of lib1. After that we will add 'a'
to this queue too. Thus 'b' and 'a' will be in a wrong order
in this queue resulting in a wrong order of corresponding
top-level initializers in a final executable.
This patch fixes this issue by adding all top-level initializers
to a deserialization queue before all other declarations.
These changes allow us to accurately distinguish between statements and
expressions in the IR.
This also fixes the types of non-exhaustive conditional statements.
We should only insert a return statement at the end of a lambda or
function if the final statement is used as an expression (slice
USED_AS_RESULT_OF_LAMBDA and USED_AS_EXPRESSION).
- Added tests to demonstrate broken behaviour: the interaction of inline
functions and callable references with varargs and defaults in various
combinations.
- Refactored InlineCallableReferencesToLambdaPhase to look like and use
some of the infrastructure from CallableReferenceLowering.
- Lifted some of this infrastructure out to be broadly reusable.
Take branching and method calls into account when finding the line
number of the continuation. If there is no line number before
branching instructions or method calls, the following code is
still on the line of the suspend call itself.
This fixes a couple of issues with incorrect line numbers for
multiple throws on the same line or multipe suspend calls on
the same line.
In addition, it avoids the need to spam the method node with
repeated line number instructions in the IR backend.
In constructor stubs for default arguments, a marker parameter used
to have a non-null type, but null was passed as the corresponding
argument. This patch corrects the type.