[JVM_IR] Fix line number information for try-catch.
In particular, the current line numbers could lead to stepping into the catch handler even when the code in the try did not throw an exception. This was caused by the code materializing the final value having the catch line number. This patch delays the materialization until the line number of the usage has been emitted.
This commit is contained in:
+18
-7
@@ -495,8 +495,9 @@ class ExpressionCodegen(
|
|||||||
|
|
||||||
val initializer = declaration.initializer
|
val initializer = declaration.initializer
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
initializer.accept(this, data).materializeAt(varType, declaration.type)
|
var value = initializer.accept(this, data)
|
||||||
initializer.markLineNumber(startOffset = true)
|
initializer.markLineNumber(startOffset = true)
|
||||||
|
value.materializeAt(varType, declaration.type)
|
||||||
mv.store(index, varType)
|
mv.store(index, varType)
|
||||||
} else if (declaration.isVisibleInLVT) {
|
} else if (declaration.isVisibleInLVT) {
|
||||||
pushDefaultValueOnStack(varType, mv)
|
pushDefaultValueOnStack(varType, mv)
|
||||||
@@ -980,14 +981,24 @@ class ExpressionCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mv.mark(tryCatchBlockEnd)
|
mv.mark(tryCatchBlockEnd)
|
||||||
|
|
||||||
// TODO: generate a common `finally` for try & catch blocks here? Right now this breaks the inliner.
|
// TODO: generate a common `finally` for try & catch blocks here? Right now this breaks the inliner.
|
||||||
if (savedValue != null) {
|
return object : PromisedValue(this, tryAsmType, aTry.type) {
|
||||||
mv.load(savedValue, tryAsmType)
|
override fun materializeAt(target: Type, irTarget: IrType) {
|
||||||
frameMap.leaveTemp(tryAsmType)
|
if (savedValue != null) {
|
||||||
return aTry.onStack
|
mv.load(savedValue, tryAsmType)
|
||||||
|
frameMap.leaveTemp(tryAsmType)
|
||||||
|
super.materializeAt(target, irTarget)
|
||||||
|
} else {
|
||||||
|
unitValue.materializeAt(target, irTarget)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun discard() {
|
||||||
|
if (savedValue != null) {
|
||||||
|
frameMap.leaveTemp(tryAsmType)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return unitValue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun genTryCatchCover(catchStart: Label, tryStart: Label, tryEnd: Label, tryGaps: List<Pair<Label, Label>>, type: String?) {
|
private fun genTryCatchCover(catchStart: Label, tryStart: Label, tryEnd: Label, tryGaps: List<Pair<Label, Label>>, type: String?) {
|
||||||
|
|||||||
+53
-19
@@ -12,10 +12,17 @@ fun foo() {
|
|||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val x = try {
|
||||||
|
mightThrow3()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var throw1 = false
|
var throw1 = false
|
||||||
var throw2 = false
|
var throw2 = false
|
||||||
|
var throw3 = false
|
||||||
|
|
||||||
fun mightThrow() {
|
fun mightThrow() {
|
||||||
if (throw1) throw Exception()
|
if (throw1) throw Exception()
|
||||||
@@ -25,7 +32,14 @@ fun mightThrow2() {
|
|||||||
if (throw2) throw Exception()
|
if (throw2) throw Exception()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun mightThrow3(): Int {
|
||||||
|
if (throw3) throw Exception()
|
||||||
|
return 42
|
||||||
|
}
|
||||||
|
|
||||||
fun box() {
|
fun box() {
|
||||||
|
foo()
|
||||||
|
throw3 = true
|
||||||
foo()
|
foo()
|
||||||
throw2 = true
|
throw2 = true
|
||||||
foo()
|
foo()
|
||||||
@@ -33,41 +47,61 @@ fun box() {
|
|||||||
foo()
|
foo()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// The JVM_IR backend will stop on line 13 even when mightThrow2
|
|
||||||
// does not throw!
|
|
||||||
|
|
||||||
// LINENUMBERS
|
// LINENUMBERS
|
||||||
// test.kt:29 box
|
// test.kt:41 box
|
||||||
// test.kt:4 foo
|
// test.kt:4 foo
|
||||||
// test.kt:5 foo
|
// test.kt:5 foo
|
||||||
// test.kt:21 mightThrow
|
// test.kt:28 mightThrow
|
||||||
// test.kt:22 mightThrow
|
// test.kt:29 mightThrow
|
||||||
// test.kt:5 foo
|
// test.kt:5 foo
|
||||||
// test.kt:10 foo
|
// test.kt:10 foo
|
||||||
// test.kt:11 foo
|
// test.kt:11 foo
|
||||||
// test.kt:25 mightThrow2
|
// test.kt:32 mightThrow2
|
||||||
// test.kt:26 mightThrow2
|
// test.kt:33 mightThrow2
|
||||||
// test.kt:11 foo
|
// test.kt:11 foo
|
||||||
// test.kt:10 foo
|
// test.kt:10 foo
|
||||||
// test.kt:15 foo
|
// test.kt:16 foo
|
||||||
// test.kt:30 box
|
// test.kt:17 foo
|
||||||
// test.kt:31 box
|
// test.kt:36 mightThrow3
|
||||||
|
// test.kt:37 mightThrow3
|
||||||
|
// test.kt:17 foo
|
||||||
|
// test.kt:16 foo
|
||||||
|
// test.kt:21 foo
|
||||||
|
// test.kt:42 box
|
||||||
|
// test.kt:43 box
|
||||||
// test.kt:4 foo
|
// test.kt:4 foo
|
||||||
// test.kt:5 foo
|
// test.kt:5 foo
|
||||||
// test.kt:21 mightThrow
|
// test.kt:28 mightThrow
|
||||||
// test.kt:22 mightThrow
|
// test.kt:29 mightThrow
|
||||||
// test.kt:5 foo
|
// test.kt:5 foo
|
||||||
// test.kt:10 foo
|
// test.kt:10 foo
|
||||||
// test.kt:11 foo
|
// test.kt:11 foo
|
||||||
// test.kt:25 mightThrow2
|
// test.kt:32 mightThrow2
|
||||||
|
// test.kt:33 mightThrow2
|
||||||
|
// test.kt:11 foo
|
||||||
|
// test.kt:10 foo
|
||||||
|
// test.kt:16 foo
|
||||||
|
// test.kt:17 foo
|
||||||
|
// test.kt:36 mightThrow3
|
||||||
|
// test.kt:18 foo
|
||||||
|
// test.kt:19 foo
|
||||||
|
// test.kt:44 box
|
||||||
|
// test.kt:45 box
|
||||||
|
// test.kt:4 foo
|
||||||
|
// test.kt:5 foo
|
||||||
|
// test.kt:28 mightThrow
|
||||||
|
// test.kt:29 mightThrow
|
||||||
|
// test.kt:5 foo
|
||||||
|
// test.kt:10 foo
|
||||||
|
// test.kt:11 foo
|
||||||
|
// test.kt:32 mightThrow2
|
||||||
// test.kt:12 foo
|
// test.kt:12 foo
|
||||||
// test.kt:13 foo
|
// test.kt:13 foo
|
||||||
// test.kt:32 box
|
// test.kt:46 box
|
||||||
// test.kt:33 box
|
// test.kt:47 box
|
||||||
// test.kt:4 foo
|
// test.kt:4 foo
|
||||||
// test.kt:5 foo
|
// test.kt:5 foo
|
||||||
// test.kt:21 mightThrow
|
// test.kt:28 mightThrow
|
||||||
// test.kt:6 foo
|
// test.kt:6 foo
|
||||||
// test.kt:7 foo
|
// test.kt:7 foo
|
||||||
// test.kt:34 box
|
// test.kt:48 box
|
||||||
@@ -37,10 +37,6 @@ fun box() {
|
|||||||
foo()
|
foo()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// The JVM_IR backend goes back to line 17 after line 18. It has the
|
|
||||||
// sequence 17, 18, 17 which doesn't make sense.
|
|
||||||
|
|
||||||
// LINENUMBERS
|
// LINENUMBERS
|
||||||
// test.kt:33 box
|
// test.kt:33 box
|
||||||
// test.kt:4 foo
|
// test.kt:4 foo
|
||||||
|
|||||||
+6
-3
@@ -34,9 +34,10 @@ fun box() {
|
|||||||
foo()
|
foo()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IGNORE_BACKEND: JVM_IR
|
// The JVM backend steps back to line 11 when leaving the
|
||||||
// The JVM_IR backend goes back to line 13 after line 14. It has the
|
// `mightThrow2` call. The JVM_IR backend does not. The
|
||||||
// sequence 13, 14, 13 which doesn't make sense.
|
// JVM_IR behavior is consistent with what happens for the
|
||||||
|
// try-finally where the value is discarded which seems good.
|
||||||
|
|
||||||
// LINENUMBERS
|
// LINENUMBERS
|
||||||
// test.kt:29 box
|
// test.kt:29 box
|
||||||
@@ -50,7 +51,9 @@ fun box() {
|
|||||||
// test.kt:11 foo
|
// test.kt:11 foo
|
||||||
// test.kt:25 mightThrow2
|
// test.kt:25 mightThrow2
|
||||||
// test.kt:26 mightThrow2
|
// test.kt:26 mightThrow2
|
||||||
|
// LINENUMBERS JVM
|
||||||
// test.kt:11 foo
|
// test.kt:11 foo
|
||||||
|
// LINENUMBERS
|
||||||
// test.kt:13 foo
|
// test.kt:13 foo
|
||||||
// test.kt:14 foo
|
// test.kt:14 foo
|
||||||
// test.kt:10 foo
|
// test.kt:10 foo
|
||||||
|
|||||||
Reference in New Issue
Block a user