diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt index af3de1a838106..e9bedf1fcd467 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsIntrinsicTransformers.kt @@ -284,6 +284,16 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) { val backingField = context.getNameForField(intrinsics.void.owner.backingField!!) JsNameRef(backingField) } + + add(intrinsics.suspendOrReturnFunctionSymbol) { call, context -> + val (generatorCall, continuation) = translateCallArguments(call, context) + val jsInvokeFunName = context.getNameForStaticFunction(call.symbol.owner) + val VOID = context.getNameForField(intrinsics.void.owner.backingField!!) + val generatorBindCall = (generatorCall as JsInvocation).let { + JsInvocation(JsNameRef(Namer.BIND_FUNCTION, it.qualifier), listOf(JsNameRef(VOID)) + it.arguments.dropLast(1)) + } + JsInvocation(JsNameRef(jsInvokeFunName), generatorBindCall, continuation) + } } } diff --git a/libraries/stdlib/js/src/kotlin/coroutines/intrinsics/IntrinsicsJs.kt b/libraries/stdlib/js/src/kotlin/coroutines/intrinsics/IntrinsicsJs.kt index 130cb8901d5cc..61c3484b76328 100644 --- a/libraries/stdlib/js/src/kotlin/coroutines/intrinsics/IntrinsicsJs.kt +++ b/libraries/stdlib/js/src/kotlin/coroutines/intrinsics/IntrinsicsJs.kt @@ -281,16 +281,18 @@ internal fun (suspend R.(P) -> T).createCoroutineUninterceptedGenerato } -internal fun suspendOrReturn(value: Any?, continuation: Continuation): Any? { - if (!isGeneratorSuspendStep(value)) return value +internal fun suspendOrReturn(generator: (continuation: Continuation) -> dynamic, continuation: Continuation): Any? { + val generatorCoroutineImpl = if (continuation.asDynamic().constructor === GeneratorCoroutineImpl::class.js) { + continuation.unsafeCast() + } else { + GeneratorCoroutineImpl(continuation) + } - val iterator = value.unsafeCast>() + val value = generator(generatorCoroutineImpl) - if (continuation.asDynamic().constructor !== GeneratorCoroutineImpl::class.js) { - return iterator.next().value - } + if (!isGeneratorSuspendStep(value)) return value - val generatorCoroutineImpl = continuation.unsafeCast() + val iterator = value.unsafeCast>() generatorCoroutineImpl.addNewIterator(iterator) try {