Disable tail call optimization, if the call is inside try block
#KT-21165: Fixed
This commit is contained in:
+8
@@ -692,6 +692,14 @@ private fun allSuspensionPointsAreTailCalls(
|
|||||||
val beginIndex = instructions.indexOf(suspensionPoint.suspensionCallBegin)
|
val beginIndex = instructions.indexOf(suspensionPoint.suspensionCallBegin)
|
||||||
val endIndex = instructions.indexOf(suspensionPoint.suspensionCallEnd)
|
val endIndex = instructions.indexOf(suspensionPoint.suspensionCallEnd)
|
||||||
|
|
||||||
|
val insideTryBlock = methodNode.tryCatchBlocks.any { block ->
|
||||||
|
val tryBlockStartIndex = instructions.indexOf(block.start)
|
||||||
|
val tryBlockEndIndex = instructions.indexOf(block.end)
|
||||||
|
|
||||||
|
beginIndex in tryBlockStartIndex..tryBlockEndIndex
|
||||||
|
}
|
||||||
|
if (insideTryBlock) return@all false
|
||||||
|
|
||||||
safelyReachableReturns[endIndex + 1]?.all { returnIndex ->
|
safelyReachableReturns[endIndex + 1]?.all { returnIndex ->
|
||||||
val sourceInsn =
|
val sourceInsn =
|
||||||
sourceFrames[returnIndex].top().sure {
|
sourceFrames[returnIndex].top().sure {
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_COROUTINES
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
val postponedActions = ArrayList<() -> Unit>()
|
||||||
|
|
||||||
|
suspend fun suspendWithException(): String = suspendCoroutine { x ->
|
||||||
|
postponedActions.add {
|
||||||
|
x.resumeWithException(Exception("OK"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun catchException(): String {
|
||||||
|
try {
|
||||||
|
return suspendWithException()
|
||||||
|
}
|
||||||
|
catch(e: Exception) {
|
||||||
|
return e.message!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun run(c: suspend () -> String): String {
|
||||||
|
var res: String = "FAIL 0"
|
||||||
|
c.startCoroutine(handleResultContinuation {
|
||||||
|
res = it
|
||||||
|
})
|
||||||
|
postponedActions[0]()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return run {
|
||||||
|
catchException()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
suspend fun catchException(): String {
|
||||||
|
try {
|
||||||
|
return suspendWithException()
|
||||||
|
}
|
||||||
|
catch(e: Exception) {
|
||||||
|
return e.message!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun suspendWithException(): String = TODO()
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
@kotlin.Metadata
|
||||||
|
final class TryCatchTailCallKt$catchException$1 {
|
||||||
|
synthetic field data: java.lang.Object
|
||||||
|
synthetic field exception: java.lang.Throwable
|
||||||
|
inner class TryCatchTailCallKt$catchException$1
|
||||||
|
method <init>(p0: kotlin.coroutines.experimental.Continuation): void
|
||||||
|
public final @org.jetbrains.annotations.Nullable method doResume(@org.jetbrains.annotations.Nullable p0: java.lang.Object, @org.jetbrains.annotations.Nullable p1: java.lang.Throwable): java.lang.Object
|
||||||
|
synthetic final method getLabel(): int
|
||||||
|
synthetic final method setLabel(p0: int): void
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class TryCatchTailCallKt {
|
||||||
|
inner class TryCatchTailCallKt$catchException$1
|
||||||
|
public final static @org.jetbrains.annotations.Nullable method catchException(@org.jetbrains.annotations.Nullable p0: java.lang.Object): java.lang.Object
|
||||||
|
public final static @org.jetbrains.annotations.Nullable method suspendWithException(@org.jetbrains.annotations.Nullable p0: java.lang.Object): java.lang.Object
|
||||||
|
}
|
||||||
Generated
+6
@@ -6388,6 +6388,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("tryCatch.kt")
|
||||||
|
public void testTryCatch() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
|
||||||
|
|||||||
+6
@@ -6388,6 +6388,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("tryCatch.kt")
|
||||||
|
public void testTryCatch() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
|
||||||
|
|||||||
+6
@@ -157,6 +157,12 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("tryCatchTailCall.kt")
|
||||||
|
public void testTryCatchTailCall() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/tryCatchTailCall.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/bytecodeListing/annotations")
|
@TestMetadata("compiler/testData/codegen/bytecodeListing/annotations")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+6
@@ -6388,6 +6388,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("tryCatch.kt")
|
||||||
|
public void testTryCatch() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
|
||||||
|
|||||||
+6
@@ -6946,6 +6946,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("tryCatch.kt")
|
||||||
|
public void testTryCatch() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
|
@TestMetadata("compiler/testData/codegen/box/coroutines/tailOperations")
|
||||||
|
|||||||
Reference in New Issue
Block a user