From e6af3ff6a86cdc8853108698d1dbe0e48133b0b7 Mon Sep 17 00:00:00 2001 From: Ilya Goncharov Date: Mon, 2 Aug 2021 15:40:38 +0300 Subject: [PATCH] [JS IR] Rename and doc new intrinsics, add new intrinsic to call suspend fun as supertype ^KT-46204 fixed --- .../kotlin/ir/backend/js/JsIntrinsics.kt | 9 ++-- .../irToJs/JsIntrinsicTransformers.kt | 23 +++------ .../src/kotlin/coroutines_13/IntrinsicsJs.kt | 50 +++++++++++++------ 3 files changed, 48 insertions(+), 34 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt index 3c2e3919b8b..969b95279e3 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt @@ -163,9 +163,12 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC get() = context.ir.symbols.coroutineContextGetter val jsGetContinuation = getInternalFunction("getContinuation") - val jsInvokeSuspendFunction = getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendFunction") - val jsInvokeSuspendFunctionWithReceiver = getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendFunctionWithReceiver") - val jsInvokeSuspendFunctionWithReceiverAndParam = getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendFunctionWithReceiverAndParam") + val jsInvokeSuspendSuperType = + getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendSuperType") + val jsInvokeSuspendSuperTypeWithReceiver = + getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendSuperTypeWithReceiver") + val jsInvokeSuspendSuperTypeWithReceiverAndParam = + getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendSuperTypeWithReceiverAndParam") val jsGetKClass = getInternalWithoutPackage("getKClass") val jsGetKClassFromExpression = getInternalWithoutPackage("getKClassFromExpression") 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 1e3017e5136..c0d43a72d80 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 @@ -13,15 +13,15 @@ import org.jetbrains.kotlin.ir.backend.js.utils.getClassRef import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction -import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.expressions.IrFunctionReference -import org.jetbrains.kotlin.ir.expressions.IrGetField +import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.classifierOrFail +import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.util.getInlineClassBackingField import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.js.backend.ast.* +import java.lang.IllegalArgumentException typealias IrCallTransformer = (IrCall, context: JsGenerationContext) -> JsExpression @@ -233,16 +233,9 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) { // Because it is intrinsic, we know everything about this function // There is callable reference as extension receiver val invokeFun = (call.extensionReceiver as IrCall) - // Single parameter is field - .getValueArgument(0) - .let { it as IrGetField } - .symbol - .owner - // It should be SuspendFunctionN + .getValueArgument(0)!! .type - .classifierOrFail - .owner - .let { it as IrClass } + .getClass()!! .declarations .filterIsInstance() .single { it.name.asString() == "invoke" } @@ -280,9 +273,9 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) { JsInvocation(jsExtensionReceiver, args) } - add(intrinsics.jsInvokeSuspendFunction, suspendInvokeTransform) - add(intrinsics.jsInvokeSuspendFunctionWithReceiver, suspendInvokeTransform) - add(intrinsics.jsInvokeSuspendFunctionWithReceiverAndParam, suspendInvokeTransform) + add(intrinsics.jsInvokeSuspendSuperType, suspendInvokeTransform) + add(intrinsics.jsInvokeSuspendSuperTypeWithReceiver, suspendInvokeTransform) + add(intrinsics.jsInvokeSuspendSuperTypeWithReceiverAndParam, suspendInvokeTransform) } } diff --git a/libraries/stdlib/js-ir/src/kotlin/coroutines_13/IntrinsicsJs.kt b/libraries/stdlib/js-ir/src/kotlin/coroutines_13/IntrinsicsJs.kt index fe41aa79d52..0fcef920ef0 100644 --- a/libraries/stdlib/js-ir/src/kotlin/coroutines_13/IntrinsicsJs.kt +++ b/libraries/stdlib/js-ir/src/kotlin/coroutines_13/IntrinsicsJs.kt @@ -10,23 +10,41 @@ package kotlin.coroutines.intrinsics import kotlin.coroutines.* import kotlin.internal.InlineOnly -@SinceKotlin("1.3") -public fun (suspend () -> T).invokeSuspendFunction( +/** + * Invoke 'invoke' method of suspend super type + * Because callable references translated with local classes, + * necessary to call it in special way, not in synamic way + */ +@Suppress("UNUSED_PARAMETER", "unused") +@SinceKotlin("1.5") +public fun (suspend () -> T).invokeSuspendSuperType( completion: Continuation ): Any? { throw NotImplementedError("It is intrinsic method") } -@SinceKotlin("1.3") -public fun (suspend R.() -> T).invokeSuspendFunctionWithReceiver( +/** + * Invoke 'invoke' method of suspend super type with receiver + * Because callable references translated with local classes, + * necessary to call it in special way, not in synamic way + */ +@Suppress("UNUSED_PARAMETER", "unused") +@SinceKotlin("1.5") +public fun (suspend R.() -> T).invokeSuspendSuperTypeWithReceiver( receiver: R, completion: Continuation ): Any? { throw NotImplementedError("It is intrinsic method") } -@SinceKotlin("1.3") -public fun (suspend R.(P) -> T).invokeSuspendFunctionWithReceiverAndParam( +/** + * Invoke 'invoke' method of suspend super type with receiver and param + * Because callable references translated with local classes, + * necessary to call it in special way, not in synamic way + */ +@Suppress("UNUSED_PARAMETER", "unused") +@SinceKotlin("1.5") +public fun (suspend R.(P) -> T).invokeSuspendSuperTypeWithReceiverAndParam( receiver: R, param: P, completion: Continuation @@ -46,14 +64,14 @@ public fun (suspend R.(P) -> T).invokeSuspendFunctionWithReceiverAndPa * This function is designed to be used from inside of [suspendCoroutineUninterceptedOrReturn] to resume the execution of a suspended * coroutine using a reference to the suspending function. */ -@SinceKotlin("1.3") +@SinceKotlin("1.5") @InlineOnly public actual inline fun (suspend () -> T).startCoroutineUninterceptedOrReturn( completion: Continuation ): Any? { val a = this.asDynamic() return if (jsTypeOf(a) == "function") a(completion) - else ::invoke.invokeSuspendFunction(completion) + else ::invoke.invokeSuspendSuperType(completion) } /** @@ -68,7 +86,7 @@ public actual inline fun (suspend () -> T).startCoroutineUninterceptedOrRetu * This function is designed to be used from inside of [suspendCoroutineUninterceptedOrReturn] to resume the execution of a suspended * coroutine using a reference to the suspending function. */ -@SinceKotlin("1.3") +@SinceKotlin("1.5") @InlineOnly public actual inline fun (suspend R.() -> T).startCoroutineUninterceptedOrReturn( receiver: R, @@ -76,7 +94,7 @@ public actual inline fun (suspend R.() -> T).startCoroutineUninterceptedO ): Any? { val a = this.asDynamic() return if (jsTypeOf(a) == "function") a(receiver, completion) - else ::invoke.invokeSuspendFunctionWithReceiver(receiver, completion) + else ::invoke.invokeSuspendSuperTypeWithReceiver(receiver, completion) } @InlineOnly @@ -87,7 +105,7 @@ internal actual inline fun (suspend R.(P) -> T).startCoroutineUninterc ): Any? { val a = this.asDynamic() return if (jsTypeOf(a) == "function") a(receiver, param, completion) - else ::invoke.invokeSuspendFunctionWithReceiverAndParam(receiver, param, completion) + else ::invoke.invokeSuspendSuperTypeWithReceiverAndParam(receiver, param, completion) } /** @@ -106,14 +124,14 @@ internal actual inline fun (suspend R.(P) -> T).startCoroutineUninterc * Repeated invocation of any resume function on the resulting continuation corrupts the * state machine of the coroutine and may result in arbitrary behaviour or exception. */ -@SinceKotlin("1.3") +@SinceKotlin("1.5") public actual fun (suspend () -> T).createCoroutineUnintercepted( completion: Continuation ): Continuation = createCoroutineFromSuspendFunction(completion) { val a = this.asDynamic() if (jsTypeOf(a) == "function") a(completion) - else ::invoke.invokeSuspendFunction(completion) + else ::invoke.invokeSuspendSuperType(completion) } /** @@ -132,7 +150,7 @@ public actual fun (suspend () -> T).createCoroutineUnintercepted( * Repeated invocation of any resume function on the resulting continuation corrupts the * state machine of the coroutine and may result in arbitrary behaviour or exception. */ -@SinceKotlin("1.3") +@SinceKotlin("1.5") public actual fun (suspend R.() -> T).createCoroutineUnintercepted( receiver: R, completion: Continuation @@ -140,13 +158,13 @@ public actual fun (suspend R.() -> T).createCoroutineUnintercepted( createCoroutineFromSuspendFunction(completion) { val a = this.asDynamic() if (jsTypeOf(a) == "function") a(receiver, completion) - else ::invoke.invokeSuspendFunctionWithReceiver(receiver, completion) + else ::invoke.invokeSuspendSuperTypeWithReceiver(receiver, completion) } /** * Intercepts this continuation with [ContinuationInterceptor]. */ -@SinceKotlin("1.3") +@SinceKotlin("1.5") public actual fun Continuation.intercepted(): Continuation = (this as? CoroutineImpl)?.intercepted() ?: this