[JVM IR] Ensure an instruction for the line number for a break.

This ensures that the debugger always has a bytecode offset for
the line number of a break/continue so that you step there and
so that you can set breakpoints there.

The `nop` instruction is optimized out if it has no line number
information.

^KT-46450 Fixed
This commit is contained in:
Mads Ager
2021-08-18 13:26:23 +02:00
committed by Alexander Udalov
parent 894a446585
commit d33b70af1a
5 changed files with 12 additions and 2 deletions

View File

@@ -1159,6 +1159,11 @@ class ExpressionCodegen(
override fun visitBreakContinue(jump: IrBreakContinue, data: BlockInfo): PromisedValue {
jump.markLineNumber(startOffset = true)
// Make sure that the line number has an instruction so that the debugger can always
// break on the break/continue. As an example, unwindBlockStack could otherwise
// generate a new line number immediately which would lead to the line number for
// the break/continue being ignored.
mv.nop()
val endLabel = Label()
val stackElement = unwindBlockStack(endLabel, data) { it.loop == jump.loop }
if (stackElement == null) {

View File

@@ -23,6 +23,7 @@ fun box() {
// test.kt:5 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String
// test.kt:6 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String
// test.kt:7 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String, y:java.lang.String="y":java.lang.String
// test.kt:8 box: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String, y:java.lang.String="y":java.lang.String
// test.kt:11 box: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String
// test.kt:12 box: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String, z:java.lang.String="z":java.lang.String
// test.kt:15 box: result:java.lang.String="yz":java.lang.String

View File

@@ -9,7 +9,7 @@ fun box(): String {
} catch (e: Exception) {
val y = "y"
val z = "z"
break // TODO: why does the break not have a line number so we can stop on it?
break
} finally {
throw RuntimeException("$i")
}
@@ -32,5 +32,6 @@ fun box(): String {
// test.kt:9 box: i:int=0:int
// test.kt:10 box: i:int=0:int, e:java.lang.Exception=java.lang.RuntimeException
// test.kt:11 box: i:int=0:int, e:java.lang.Exception=java.lang.RuntimeException, y:java.lang.String="y":java.lang.String
// test.kt:12 box: i:int=0:int, e:java.lang.Exception=java.lang.RuntimeException, y:java.lang.String="y":java.lang.String, z:java.lang.String="z":java.lang.String
// test.kt:14 box: i:int=0:int
// test.kt:18 box:

View File

@@ -9,7 +9,7 @@ fun box(): String {
} catch (e: Exception) {
val y = "y"
val z = "z"
continue // TODO: why does the continue not have a line number so we stop here?
continue
} finally {
throw RuntimeException("$i")
}
@@ -32,5 +32,6 @@ fun box(): String {
// test.kt:9 box: i:int=0:int
// test.kt:10 box: i:int=0:int, e:java.lang.Exception=java.lang.RuntimeException
// test.kt:11 box: i:int=0:int, e:java.lang.Exception=java.lang.RuntimeException, y:java.lang.String="y":java.lang.String
// test.kt:12 box: i:int=0:int, e:java.lang.Exception=java.lang.RuntimeException, y:java.lang.String="y":java.lang.String, z:java.lang.String="z":java.lang.String
// test.kt:14 box: i:int=0:int
// test.kt:18 box:

View File

@@ -23,12 +23,14 @@ fun box() {
// test.kt:5 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String
// test.kt:6 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String
// test.kt:7 box: result:java.lang.String="":java.lang.String, x:java.lang.String="A":java.lang.String, y:java.lang.String="y":java.lang.String
// test.kt:8 box: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String, y:java.lang.String="y":java.lang.String
// test.kt:11 box: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String
// test.kt:12 box: result:java.lang.String="y":java.lang.String, x:java.lang.String="A":java.lang.String, z:java.lang.String="z":java.lang.String
// test.kt:4 box: result:java.lang.String="yz":java.lang.String
// test.kt:5 box: result:java.lang.String="yz":java.lang.String, x:java.lang.String="B":java.lang.String
// test.kt:6 box: result:java.lang.String="yz":java.lang.String, x:java.lang.String="B":java.lang.String
// test.kt:7 box: result:java.lang.String="yz":java.lang.String, x:java.lang.String="B":java.lang.String, y:java.lang.String="y":java.lang.String
// test.kt:8 box: result:java.lang.String="yzy":java.lang.String, x:java.lang.String="B":java.lang.String, y:java.lang.String="y":java.lang.String
// test.kt:11 box: result:java.lang.String="yzy":java.lang.String, x:java.lang.String="B":java.lang.String
// test.kt:12 box: result:java.lang.String="yzy":java.lang.String, x:java.lang.String="B":java.lang.String, z:java.lang.String="z":java.lang.String
// test.kt:4 box: result:java.lang.String="yzyz":java.lang.String