Extracted BaseContinuationImpl

This commit is contained in:
Roman Elizarov
2018-07-03 17:23:52 +03:00
committed by Denis Zharkov
parent 38c17249b9
commit 33f4a3fcbf
2 changed files with 38 additions and 41 deletions
@@ -10,8 +10,7 @@
package kotlin.coroutines.intrinsics package kotlin.coroutines.intrinsics
import kotlin.coroutines.* import kotlin.coroutines.*
import kotlin.coroutines.jvm.internal.ContinuationImpl import kotlin.coroutines.jvm.internal.*
import kotlin.coroutines.jvm.internal.RestrictedContinuationImpl
import kotlin.internal.InlineOnly import kotlin.internal.InlineOnly
/** /**
@@ -79,7 +78,7 @@ public actual inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedO
public actual fun <T> (suspend () -> T).createCoroutineUnintercepted( public actual fun <T> (suspend () -> T).createCoroutineUnintercepted(
completion: Continuation<T> completion: Continuation<T>
): Continuation<Unit> = ): Continuation<Unit> =
if (this is RestrictedContinuationImpl) if (this is BaseContinuationImpl)
create(completion) create(completion)
else else
createCoroutineFromSuspendFunction(completion) { createCoroutineFromSuspendFunction(completion) {
@@ -112,7 +111,7 @@ public actual fun <R, T> (suspend R.() -> T).createCoroutineUnintercepted(
receiver: R, receiver: R,
completion: Continuation<T> completion: Continuation<T>
): Continuation<Unit> = ): Continuation<Unit> =
if (this is RestrictedContinuationImpl) if (this is BaseContinuationImpl)
create(receiver, completion) create(receiver, completion)
else { else {
createCoroutineFromSuspendFunction(completion) { createCoroutineFromSuspendFunction(completion) {
@@ -144,14 +143,14 @@ private inline fun <T> createCoroutineFromSuspendFunction(
return if (context === EmptyCoroutineContext) return if (context === EmptyCoroutineContext)
object : RestrictedContinuationImpl(completion as Continuation<Any?>) { object : RestrictedContinuationImpl(completion as Continuation<Any?>) {
override fun invokeSuspend(result: SuccessOrFailure<Any?>): Any? { override fun invokeSuspend(result: SuccessOrFailure<Any?>): 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 return block() // run the block
} }
} }
else else
object : ContinuationImpl(completion as Continuation<Any?>, context) { object : ContinuationImpl(completion as Continuation<Any?>, context) {
override fun invokeSuspend(result: SuccessOrFailure<Any?>): Any? { override fun invokeSuspend(result: SuccessOrFailure<Any?>): 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 return block() // run the block
} }
} }
@@ -12,26 +12,11 @@ import kotlin.jvm.internal.FunctionBase
import kotlin.jvm.internal.Reflection import kotlin.jvm.internal.Reflection
@SinceKotlin("1.3") @SinceKotlin("1.3")
// State machines for named restricted suspend functions extend from this class internal abstract class BaseContinuationImpl(
internal abstract class RestrictedContinuationImpl protected constructor(
@JvmField @JvmField
protected val completion: Continuation<Any?>? protected val completion: Continuation<Any?>?
) : Continuation<Any?>, Serializable { ) : Continuation<Any?>, Serializable {
init { // This implementation is final. This fact is used to unroll resumeWith recursion.
@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
public final override fun resumeWith(result: SuccessOrFailure<Any?>) { public final override fun resumeWith(result: SuccessOrFailure<Any?>) {
var current = this var current = this
var param = result var param = result
@@ -48,7 +33,7 @@ internal abstract class RestrictedContinuationImpl protected constructor(
SuccessOrFailure.failure(exception) SuccessOrFailure.failure(exception)
} }
releaseIntercepted() // this state machine instance is terminating releaseIntercepted() // this state machine instance is terminating
if (completion is RestrictedContinuationImpl) { if (completion is BaseContinuationImpl) {
// unrolling recursion via loop // unrolling recursion via loop
current = completion current = completion
param = outcome param = outcome
@@ -74,22 +59,40 @@ internal abstract class RestrictedContinuationImpl protected constructor(
public open fun create(value: Any?, completion: Continuation<*>): Continuation<Unit> { public open fun create(value: Any?, completion: Continuation<*>): Continuation<Unit> {
throw UnsupportedOperationException("create(Any?;Continuation) has not been overridden") 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<Any?>?
) : 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") @SinceKotlin("1.3")
// State machines for named suspend functions extend from this class // State machines for named suspend functions extend from this class
internal abstract class ContinuationImpl protected constructor( internal abstract class ContinuationImpl(
completion: Continuation<Any?>?, completion: Continuation<Any?>?,
private val _context: CoroutineContext? private val _context: CoroutineContext?
) : RestrictedContinuationImpl(completion) { ) : BaseContinuationImpl(completion) {
protected constructor(completion: Continuation<Any?>?) : this(completion, completion?.context) constructor(completion: Continuation<Any?>?) : this(completion, completion?.context)
protected override fun validateContext() {
// nothing to do here -- supports any context
}
public override val context: CoroutineContext public override val context: CoroutineContext
get() = _context!! get() = _context!!
@Transient @Transient
private var intercepted: Continuation<Any?>? = null private var intercepted: Continuation<Any?>? = null
@@ -106,11 +109,6 @@ internal abstract class ContinuationImpl protected constructor(
} }
this.intercepted = CompletedContinuation // just in case 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<Any?> { internal object CompletedContinuation : Continuation<Any?> {
@@ -126,11 +124,11 @@ internal object CompletedContinuation : Continuation<Any?> {
@SinceKotlin("1.3") @SinceKotlin("1.3")
// Restricted suspension lambdas inherit from this class // Restricted suspension lambdas inherit from this class
internal abstract class RestrictedSuspendLambda protected constructor( internal abstract class RestrictedSuspendLambda(
private val arity: Int, private val arity: Int,
completion: Continuation<Any?>? completion: Continuation<Any?>?
) : RestrictedContinuationImpl(completion), FunctionBase { ) : RestrictedContinuationImpl(completion), FunctionBase {
protected constructor(arity: Int) : this(arity, null) constructor(arity: Int) : this(arity, null)
public override fun getArity(): Int = arity public override fun getArity(): Int = arity
@@ -143,11 +141,11 @@ internal abstract class RestrictedSuspendLambda protected constructor(
@SinceKotlin("1.3") @SinceKotlin("1.3")
// Suspension lambdas inherit from this class // Suspension lambdas inherit from this class
internal abstract class SuspendLambda protected constructor( internal abstract class SuspendLambda(
private val arity: Int, private val arity: Int,
completion: Continuation<Any?>? completion: Continuation<Any?>?
) : ContinuationImpl(completion), FunctionBase { ) : ContinuationImpl(completion), FunctionBase {
protected constructor(arity: Int) : this(arity, null) constructor(arity: Int) : this(arity, null)
public override fun getArity(): Int = arity public override fun getArity(): Int = arity