diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineBodyTransformer.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineBodyTransformer.kt index 5594c953c84..8b66e4a7de8 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineBodyTransformer.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineBodyTransformer.kt @@ -52,12 +52,11 @@ class CoroutineBodyTransformer( fun preProcess(node: JsNode) { breakContinueTargetStatements += node.collectBreakContinueTargets() nodesToSplit = node.collectNodesToSplit() - currentStatements += exceptionState(currentCatchBlock) } fun postProcess(): List { currentBlock.statements += JsReturn() - val graph = entryBlock.buildGraph() + val graph = entryBlock.buildGraph(globalCatchBlock) val orderedBlocks = DFS.topologicalOrder(listOf(entryBlock)) { graph[it].orEmpty() } orderedBlocks.replaceCoroutineFlowStatements(context, program) return orderedBlocks diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineFunctionTransformer.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineFunctionTransformer.kt index c1966986505..3b36bec5ee8 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineFunctionTransformer.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineFunctionTransformer.kt @@ -53,13 +53,14 @@ class CoroutineFunctionTransformer( bodyTransformer.preProcess(body) body.statements.forEach { it.accept(bodyTransformer) } val coroutineBlocks = bodyTransformer.postProcess() + val globalCatchBlockIndex = coroutineBlocks.indexOf(context.globalCatchBlock) coroutineBlocks.forEach { it.jsBlock.collectAdditionalLocalVariables() } coroutineBlocks.forEach { it.jsBlock.replaceLocalVariables(function.scope, context, localVariables) } val additionalStatements = mutableListOf() val resumeName = generateDoResume(coroutineBlocks, context, additionalStatements, throwName) - generateContinuationConstructor(context, additionalStatements, bodyTransformer.hasFinallyBlocks) + generateContinuationConstructor(context, additionalStatements, bodyTransformer.hasFinallyBlocks, globalCatchBlockIndex) generateContinuationMethods(resumeName, additionalStatements) generateCoroutineInstantiation() @@ -70,7 +71,8 @@ class CoroutineFunctionTransformer( private fun generateContinuationConstructor( context: CoroutineTransformationContext, statements: MutableList, - hasFinallyBlocks: Boolean + hasFinallyBlocks: Boolean, + globalCatchBlockIndex: Int ) { val constructor = JsFunction(function.scope.parent, JsBlock(), "Continuation") constructor.name = className @@ -86,7 +88,7 @@ class CoroutineFunctionTransformer( constructor.body.statements.run { assign(context.stateFieldName, program.getNumberLiteral(0)) - assign(context.exceptionStateName, program.getNumberLiteral(0)) + assign(context.exceptionStateName, program.getNumberLiteral(globalCatchBlockIndex)) if (hasFinallyBlocks) { assign(context.finallyPathFieldName, JsLiteral.NULL) } diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutinePasses.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutinePasses.kt index 92cf32a2b64..14d198a9247 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutinePasses.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutinePasses.kt @@ -118,7 +118,7 @@ fun List.replaceCoroutineFlowStatements(context: CoroutineTransf return forEach { blockReplacementVisitor.accept(it.jsBlock) } } -fun CoroutineBlock.buildGraph(): Map> { +fun CoroutineBlock.buildGraph(globalCatchBlock: CoroutineBlock?): Map> { // That's a little more than DFS due to need of tracking finally paths val visitedBlocks = mutableSetOf() @@ -139,6 +139,9 @@ fun CoroutineBlock.buildGraph(): Map> { val successors = graph.getOrPut(block) { mutableSetOf() } successors += block.collectTargetBlocks() + if (block == this && globalCatchBlock != null) { + successors += globalCatchBlock + } successors.forEach(::visitBlock) }