[JS BE] Set enclosing exception state in finally block

[Fix KT-28207]
This commit is contained in:
Roman Artemev
2018-11-15 15:20:30 +03:00
committed by romanart
parent 353b469f4a
commit d5acc8ff5b
9 changed files with 186 additions and 1 deletions
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
@@ -0,0 +1,43 @@
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
import helpers.*
import COROUTINES_PACKAGE.*
import COROUTINES_PACKAGE.intrinsics.*
// Note: This test for issue KT-28207 about infinite loop after throwing exception from finally block
suspend fun throwHere(): Nothing = throw RuntimeException("Do not catch me")
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
var result = ""
var count = 0
try {
builder {
try {
throwHere()
count = 1
} finally {
if (count == 0) {
count = 2
result = "O"
throw Exception("K")
} else if (count == 2) {
result = "FAIL: execution gets into infinite loop"
} else {
result = "FAIL: exception has not been thrown"
}
}
}
} catch (x: Exception) {
result += x.message
}
return result
}
@@ -0,0 +1,52 @@
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
import helpers.*
import COROUTINES_PACKAGE.*
import COROUTINES_PACKAGE.intrinsics.*
// Note: This test for issue KT-28207 about infinite loop after throwing exception from finally block
var resume: () -> Unit = {}
suspend fun suspendHere(): String = suspendCoroutineUninterceptedOrReturn { cont ->
resume = {
cont.resumeWithException(RuntimeException("Do not catch me"))
}
COROUTINE_SUSPENDED
}
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box(): String {
var result = ""
var count = 0
try {
builder {
try {
suspendHere()
count = 1
} finally {
if (count == 0) {
count = 2
result = "O"
throw Exception("K")
} else if (count == 2) {
result = "FAIL: execution gets into infinite loop"
} else {
result = "FAIL: exception has not been thrown"
}
}
}
resume()
} catch (x: Exception) {
result += x.message
}
return result
}