diff --git a/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/intrinsics/IntrinsicsJvm.kt b/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/intrinsics/IntrinsicsJvm.kt index f07a17b2432..9e9a220d6dc 100644 --- a/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/intrinsics/IntrinsicsJvm.kt +++ b/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/intrinsics/IntrinsicsJvm.kt @@ -10,8 +10,7 @@ package kotlin.coroutines.intrinsics import kotlin.coroutines.* -import kotlin.coroutines.jvm.internal.ContinuationImpl -import kotlin.coroutines.jvm.internal.RestrictedContinuationImpl +import kotlin.coroutines.jvm.internal.* import kotlin.internal.InlineOnly /** @@ -79,7 +78,7 @@ public actual inline fun (suspend R.() -> T).startCoroutineUninterceptedO public actual fun (suspend () -> T).createCoroutineUnintercepted( completion: Continuation ): Continuation = - if (this is RestrictedContinuationImpl) + if (this is BaseContinuationImpl) create(completion) else createCoroutineFromSuspendFunction(completion) { @@ -112,7 +111,7 @@ public actual fun (suspend R.() -> T).createCoroutineUnintercepted( receiver: R, completion: Continuation ): Continuation = - if (this is RestrictedContinuationImpl) + if (this is BaseContinuationImpl) create(receiver, completion) else { createCoroutineFromSuspendFunction(completion) { @@ -144,14 +143,14 @@ private inline fun createCoroutineFromSuspendFunction( return if (context === EmptyCoroutineContext) object : RestrictedContinuationImpl(completion as Continuation) { override fun invokeSuspend(result: SuccessOrFailure): Any? { - result.getOrThrow() // Rethrow exception if trying to start with exception (will be caught by ContinuationImpl.resumeWith + result.getOrThrow() // Rethrow exception if trying to start with exception (will be caught by BaseContinuationImpl.resumeWith return block() // run the block } } else object : ContinuationImpl(completion as Continuation, context) { override fun invokeSuspend(result: SuccessOrFailure): Any? { - result.getOrThrow() // Rethrow exception if trying to start with exception (will be caught by ContinuationImpl.resumeWith + result.getOrThrow() // Rethrow exception if trying to start with exception (will be caught by BaseContinuationImpl.resumeWith return block() // run the block } } diff --git a/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/jvm/internal/ContinuationImpl.kt b/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/jvm/internal/ContinuationImpl.kt index faf2c09fe40..d6296875d3c 100644 --- a/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/jvm/internal/ContinuationImpl.kt +++ b/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/jvm/internal/ContinuationImpl.kt @@ -12,26 +12,11 @@ import kotlin.jvm.internal.FunctionBase import kotlin.jvm.internal.Reflection @SinceKotlin("1.3") -// State machines for named restricted suspend functions extend from this class -internal abstract class RestrictedContinuationImpl protected constructor( +internal abstract class BaseContinuationImpl( @JvmField protected val completion: Continuation? ) : Continuation, Serializable { - init { - @Suppress("LeakingThis") - validateContext() - } - - protected open fun validateContext() { - completion?.let { - require(it.context === EmptyCoroutineContext) { "Coroutines with restricted suspension must have EmptyCoroutineContext" } - } - } - - public override val context: CoroutineContext - get() = EmptyCoroutineContext - - // This implementation is final that it is fundamentally used to unroll resumeWith recursion + // This implementation is final. This fact is used to unroll resumeWith recursion. public final override fun resumeWith(result: SuccessOrFailure) { var current = this var param = result @@ -48,7 +33,7 @@ internal abstract class RestrictedContinuationImpl protected constructor( SuccessOrFailure.failure(exception) } releaseIntercepted() // this state machine instance is terminating - if (completion is RestrictedContinuationImpl) { + if (completion is BaseContinuationImpl) { // unrolling recursion via loop current = completion param = outcome @@ -74,22 +59,40 @@ internal abstract class RestrictedContinuationImpl protected constructor( public open fun create(value: Any?, completion: Continuation<*>): Continuation { throw UnsupportedOperationException("create(Any?;Continuation) has not been overridden") } + + public override fun toString(): String { + // todo: how continuation shall be rendered? + return "Continuation @ ${this::class.java.name}" + } +} + +@SinceKotlin("1.3") +// State machines for named restricted suspend functions extend from this class +internal abstract class RestrictedContinuationImpl( + completion: Continuation? +) : BaseContinuationImpl(completion) { + init { + completion?.let { + require(it.context === EmptyCoroutineContext) { + "Coroutines with restricted suspension must have EmptyCoroutineContext" + } + } + } + + public override val context: CoroutineContext + get() = EmptyCoroutineContext } @SinceKotlin("1.3") // State machines for named suspend functions extend from this class -internal abstract class ContinuationImpl protected constructor( +internal abstract class ContinuationImpl( completion: Continuation?, private val _context: CoroutineContext? -) : RestrictedContinuationImpl(completion) { - protected constructor(completion: Continuation?) : this(completion, completion?.context) - - protected override fun validateContext() { - // nothing to do here -- supports any context - } +) : BaseContinuationImpl(completion) { + constructor(completion: Continuation?) : this(completion, completion?.context) public override val context: CoroutineContext - get() = _context!! + get() = _context!! @Transient private var intercepted: Continuation? = null @@ -106,11 +109,6 @@ internal abstract class ContinuationImpl protected constructor( } this.intercepted = CompletedContinuation // just in case } - - public override fun toString(): String { - // todo: how continuation shall be rendered? - return "Continuation @ ${this::class.java.name}" - } } internal object CompletedContinuation : Continuation { @@ -126,11 +124,11 @@ internal object CompletedContinuation : Continuation { @SinceKotlin("1.3") // Restricted suspension lambdas inherit from this class -internal abstract class RestrictedSuspendLambda protected constructor( +internal abstract class RestrictedSuspendLambda( private val arity: Int, completion: Continuation? ) : RestrictedContinuationImpl(completion), FunctionBase { - protected constructor(arity: Int) : this(arity, null) + constructor(arity: Int) : this(arity, null) public override fun getArity(): Int = arity @@ -143,11 +141,11 @@ internal abstract class RestrictedSuspendLambda protected constructor( @SinceKotlin("1.3") // Suspension lambdas inherit from this class -internal abstract class SuspendLambda protected constructor( +internal abstract class SuspendLambda( private val arity: Int, completion: Continuation? ) : ContinuationImpl(completion), FunctionBase { - protected constructor(arity: Int) : this(arity, null) + constructor(arity: Int) : this(arity, null) public override fun getArity(): Int = arity