JVM: restore call site line number after inlining lambda
E.g. in `x + f()` where `f` is an inline lambda, the instructions for `+` should have the line number of that expression (while previously they instead had the line number of the last line of the lambda). ^KT-51738 Fixed
This commit is contained in:
@@ -262,12 +262,12 @@ class MethodInliner(
|
||||
}
|
||||
|
||||
val firstLine = info.node.node.instructions.asSequence().mapNotNull { it as? LineNumberNode }.firstOrNull()?.line ?: -1
|
||||
if (currentLineNumber >= 0 && firstLine == currentLineNumber) {
|
||||
if ((info is DefaultLambda != overrideLineNumber) && currentLineNumber >= 0 && firstLine == currentLineNumber) {
|
||||
// This can happen in two cases:
|
||||
// 1. `someInlineOnlyFunction { singleLineLambda }`: in this case line numbers are removed
|
||||
// from the inline function, so the entirety of its bytecode has the line number of
|
||||
// the call site;
|
||||
// 2. `inline fun someFunction(defaultLambda: ... = { ... }) = singleLineExpression`:
|
||||
// 2. `inline fun someFunction(defaultLambda: ... = { ... }) = something(defaultLambda())`:
|
||||
// all of `someFunction`, including `defaultLambda` if no value is provided at call site,
|
||||
// has the line number of the declaration.
|
||||
// In those cases the debugger is unable to observe the boundary between the body of the function
|
||||
@@ -312,10 +312,16 @@ class MethodInliner(
|
||||
setLambdaInlining(false)
|
||||
addInlineMarker(this, false)
|
||||
|
||||
if (overrideLineNumber) {
|
||||
if (currentLineNumber != -1) {
|
||||
val endLabel = Label()
|
||||
mv.visitLabel(endLabel)
|
||||
mv.visitLineNumber(currentLineNumber, endLabel)
|
||||
if (overrideLineNumber) {
|
||||
// This is from the function we're inlining into, so no need to remap.
|
||||
mv.visitLineNumber(currentLineNumber, endLabel)
|
||||
} else {
|
||||
// Need to go through the superclass here to properly remap the line number via `sourceMapper`.
|
||||
super.visitLineNumber(currentLineNumber, endLabel)
|
||||
}
|
||||
}
|
||||
} else if (isAnonymousConstructorCall(owner, name)) { //TODO add method
|
||||
//TODO add proper message
|
||||
|
||||
+3
-3
@@ -12,7 +12,7 @@ inline fun inlineFunInt(f: () -> Int): Int {
|
||||
|
||||
inline fun inlineFunVoid(f: () -> Unit): Unit {
|
||||
val a = 1
|
||||
return f()
|
||||
return f() // return replaced with nop to stop here *after* calling f
|
||||
}
|
||||
|
||||
fun simpleFunInt(f: () -> Int): Int {
|
||||
@@ -20,7 +20,7 @@ fun simpleFunInt(f: () -> Int): Int {
|
||||
}
|
||||
|
||||
fun simpleFunVoid(f: () -> Unit): Unit {
|
||||
return f()
|
||||
return f() // return replaced with nop to stop here *after* calling f
|
||||
}
|
||||
|
||||
// 0 NOP
|
||||
// 2 NOP
|
||||
|
||||
+7
-7
@@ -1,13 +1,13 @@
|
||||
|
||||
fun box() {
|
||||
lookAtMe {
|
||||
val c = "c"
|
||||
}
|
||||
lookAtMe { // 1
|
||||
val c = "c" // 4
|
||||
} // 5 (nop)
|
||||
}
|
||||
|
||||
inline fun lookAtMe(f: (String) -> Unit) {
|
||||
val a = "a"
|
||||
f(a) // Should be no unneeded nops on this line, that might be generated for zero-parameters lambda
|
||||
}
|
||||
val a = "a" // 2
|
||||
f(a) // 3 before call, 6 after call (nop)
|
||||
} // 7 (nop)
|
||||
|
||||
// 2 NOP
|
||||
// 3 NOP
|
||||
|
||||
@@ -21,11 +21,13 @@ inline fun foo(f: () -> Unit) {
|
||||
// test.kt:15 box
|
||||
// test.kt:5 box
|
||||
// test.kt:6 box
|
||||
// test.kt:15 box
|
||||
// test.kt:16 box
|
||||
// test.kt:8 box
|
||||
// test.kt:14 box
|
||||
// test.kt:15 box
|
||||
// test.kt:9 box
|
||||
// test.kt:10 box
|
||||
// test.kt:15 box
|
||||
// test.kt:16 box
|
||||
// test.kt:11 box
|
||||
|
||||
@@ -30,5 +30,6 @@ fun nop() {}
|
||||
// test.kt:19 nop
|
||||
// test.kt:17 box
|
||||
// test.kt:7 box
|
||||
// test.kt:12 box
|
||||
// test.kt:13 box
|
||||
// test.kt:8 box
|
||||
|
||||
@@ -21,6 +21,7 @@ inline fun f(block: () -> Unit) {
|
||||
// test.kt:15 box
|
||||
// test.kt:5 box
|
||||
// test.kt:6 box
|
||||
// test.kt:15 box
|
||||
// test.kt:16 box
|
||||
// test.kt:7 box
|
||||
// test.kt:8 box
|
||||
@@ -29,5 +30,6 @@ inline fun f(block: () -> Unit) {
|
||||
// test.kt:15 box
|
||||
// test.kt:10 box
|
||||
// test.kt:11 box
|
||||
// test.kt:15 box
|
||||
// test.kt:16 box
|
||||
// test.kt:12 box
|
||||
@@ -16,5 +16,6 @@ fun g() {}
|
||||
// test.kt:8 box
|
||||
// test.kt:4 box
|
||||
// test.kt:11 g
|
||||
// test.kt:8 box
|
||||
// test.kt:9 box
|
||||
// test.kt:5 box
|
||||
|
||||
@@ -27,11 +27,13 @@ fun box() {
|
||||
// test.kt:4 box
|
||||
// test.kt:9 box
|
||||
// test.kt:10 box
|
||||
// test.kt:4 box
|
||||
// test.kt:5 box
|
||||
// test.kt:12 box
|
||||
// test.kt:4 box
|
||||
// test.kt:13 box
|
||||
// test.kt:14 box
|
||||
// test.kt:4 box
|
||||
// test.kt:5 box
|
||||
// test.kt:16 box
|
||||
// test.kt:4 box
|
||||
@@ -40,7 +42,9 @@ fun box() {
|
||||
// test.kt:4 box
|
||||
// test.kt:20 box
|
||||
// test.kt:21 box
|
||||
// test.kt:4 box
|
||||
// test.kt:5 box
|
||||
// test.kt:22 box
|
||||
// test.kt:4 box
|
||||
// test.kt:5 box
|
||||
// test.kt:23 box
|
||||
|
||||
@@ -17,7 +17,9 @@ fun box(): String {
|
||||
// test.kt:8 box
|
||||
// test.kt:4 box
|
||||
// test.kt:8 box
|
||||
// test.kt:4 box
|
||||
// test.kt:9 box
|
||||
// test.kt:4 box
|
||||
// test.kt:10 box
|
||||
// test.kt:4 box
|
||||
// test.kt:13 box
|
||||
|
||||
@@ -22,8 +22,10 @@ fun box(): String {
|
||||
// test.kt:3 box
|
||||
// test.kt:4 box
|
||||
// test.kt:3 box
|
||||
// test.kt:4 box
|
||||
// test.kt:16 box
|
||||
// test.kt:7 box
|
||||
// test.kt:11 box
|
||||
// test.kt:8 box
|
||||
// test.kt:11 box
|
||||
// test.kt:17 box
|
||||
|
||||
@@ -17,5 +17,6 @@ inline fun lookAtMe(f: (String) -> Unit) {
|
||||
// test.kt:11 box
|
||||
// test.kt:5 box
|
||||
// test.kt:6 box
|
||||
// test.kt:11 box
|
||||
// test.kt:12 box
|
||||
// test.kt:7 box
|
||||
@@ -53,9 +53,11 @@ inline fun html(init: () -> Unit) {
|
||||
// 1.kt:34 box
|
||||
// test.kt:11 box
|
||||
// test.kt:12 box
|
||||
// 1.kt:34 box
|
||||
// 1.kt:35 box
|
||||
// 1.kt:37 box
|
||||
// test.kt:13 box
|
||||
// 1.kt:29 box
|
||||
// 1.kt:30 box
|
||||
// 1.kt:41 box
|
||||
// test.kt:15 box
|
||||
|
||||
@@ -16,5 +16,6 @@ inline fun lookAtMe(f: () -> Int) {
|
||||
// test.kt:10 box
|
||||
// test.kt:11 box
|
||||
// test.kt:5 box
|
||||
// test.kt:11 box
|
||||
// test.kt:12 box
|
||||
// test.kt:7 box
|
||||
|
||||
@@ -15,5 +15,6 @@ fun box() {
|
||||
// test.kt:4 box
|
||||
// test.kt:9 box
|
||||
// test.kt:10 box
|
||||
// test.kt:4 box
|
||||
// test.kt:5 box
|
||||
// test.kt:11 box
|
||||
|
||||
Reference in New Issue
Block a user