Introduce createCoroutineUnchecked intrinsic

Also use it for buildSequence implenentation

 #KT-16155 Fixed
This commit is contained in:
Denis Zharkov
2017-02-03 14:03:30 +03:00
parent 9a71a20ad6
commit 4f6a77cf38
13 changed files with 107 additions and 97 deletions
@@ -19,6 +19,7 @@ package kotlin.coroutines.experimental
import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED
import kotlin.coroutines.experimental.intrinsics.suspendCoroutineOrReturn
import kotlin.coroutines.experimental.intrinsics.createCoroutineUnchecked
/**
* Starts coroutine with receiver type [R] and result type [T].
@@ -31,7 +32,7 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
receiver: R,
completion: Continuation<T>
) {
createCoroutineInternal(receiver, completion).resume(Unit)
createCoroutineUnchecked(receiver, completion).resume(Unit)
}
/**
@@ -44,7 +45,7 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
public fun <T> (suspend () -> T).startCoroutine(
completion: Continuation<T>
) {
createCoroutineInternal(completion).resume(Unit)
createCoroutineUnchecked(completion).resume(Unit)
}
/**
@@ -58,7 +59,7 @@ public fun <T> (suspend () -> T).startCoroutine(
public fun <R, T> (suspend R.() -> T).createCoroutine(
receiver: R,
completion: Continuation<T>
): Continuation<Unit> = SafeContinuation(createCoroutineInternal(receiver, completion), COROUTINE_SUSPENDED)
): Continuation<Unit> = SafeContinuation(createCoroutineUnchecked(receiver, completion), COROUTINE_SUSPENDED)
/**
* Creates coroutine without receiver and with result type [T].
@@ -70,7 +71,7 @@ public fun <R, T> (suspend R.() -> T).createCoroutine(
@Suppress("UNCHECKED_CAST")
public fun <T> (suspend () -> T).createCoroutine(
completion: Continuation<T>
): Continuation<Unit> = SafeContinuation(createCoroutineInternal(completion), COROUTINE_SUSPENDED)
): Continuation<Unit> = SafeContinuation(createCoroutineUnchecked(completion), COROUTINE_SUSPENDED)
/**
* Obtains the current continuation instance inside suspend functions and suspends
@@ -1,68 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:kotlin.jvm.JvmName("CoroutinesJvmKt")
@file:kotlin.jvm.JvmVersion
package kotlin.coroutines.experimental
import kotlin.coroutines.experimental.jvm.internal.CoroutineImpl
import kotlin.coroutines.experimental.jvm.internal.interceptContinuationIfNeeded
@SinceKotlin("1.1")
internal fun <T> (suspend () -> T).createCoroutineInternal(
completion: Continuation<T>
): Continuation<Unit> =
if (this !is CoroutineImpl)
buildContinuationByInvokeCall(completion) {
(this as Function1<Continuation<T>, Any?>).invoke(completion)
}
else
(this.create(completion) as CoroutineImpl).facade
@SinceKotlin("1.1")
internal fun <R, T> (suspend R.() -> T).createCoroutineInternal(
receiver: R,
completion: Continuation<T>
): Continuation<Unit> =
if (this !is CoroutineImpl)
buildContinuationByInvokeCall(completion) {
(this as Function2<R, Continuation<T>, Any?>).invoke(receiver, completion)
}
else
((this as CoroutineImpl).create(receiver, completion) as CoroutineImpl).facade
private inline fun <T> buildContinuationByInvokeCall(
completion: Continuation<T>,
crossinline block: () -> Any?
): Continuation<Unit> {
val continuation =
object : Continuation<Unit> {
override val context: CoroutineContext
get() = completion.context
override fun resume(value: Unit) {
processBareContinuationResume(completion, block)
}
override fun resumeWithException(exception: Throwable) {
completion.resumeWithException(exception)
}
}
return completion.context.interceptContinuationIfNeeded(continuation)
}
@@ -32,7 +32,7 @@ public fun <T> buildSequence(builderAction: suspend SequenceBuilder<T>.() -> Uni
@SinceKotlin("1.1")
public fun <T> buildIterator(builderAction: suspend SequenceBuilder<T>.() -> Unit): Iterator<T> {
val iterator = SequenceBuilderIterator<T>()
iterator.nextStep = builderAction.createCoroutine(receiver = iterator, completion = iterator)
iterator.nextStep = builderAction.createCoroutineUnchecked(receiver = iterator, completion = iterator)
return iterator
}
@@ -19,6 +19,8 @@
package kotlin.coroutines.experimental.intrinsics
import kotlin.coroutines.experimental.Continuation
import kotlin.coroutines.experimental.CoroutineContext
import kotlin.coroutines.experimental.processBareContinuationResume
/**
* Obtains the current continuation instance inside suspend functions and either suspend
@@ -48,3 +50,53 @@ public inline suspend fun <T> suspendCoroutineOrReturn(crossinline block: (Conti
@SinceKotlin("1.1")
public val COROUTINE_SUSPENDED: Any = Any()
// JVM declarations
@SinceKotlin("1.1")
@kotlin.jvm.JvmVersion
public fun <T> (suspend () -> T).createCoroutineUnchecked(
completion: Continuation<T>
): Continuation<Unit> =
if (this !is kotlin.coroutines.experimental.jvm.internal.CoroutineImpl)
buildContinuationByInvokeCall(completion) {
(this as Function1<Continuation<T>, Any?>).invoke(completion)
}
else
(this.create(completion) as kotlin.coroutines.experimental.jvm.internal.CoroutineImpl).facade
@SinceKotlin("1.1")
@kotlin.jvm.JvmVersion
public fun <R, T> (suspend R.() -> T).createCoroutineUnchecked(
receiver: R,
completion: Continuation<T>
): Continuation<Unit> =
if (this !is kotlin.coroutines.experimental.jvm.internal.CoroutineImpl)
buildContinuationByInvokeCall(completion) {
(this as Function2<R, Continuation<T>, Any?>).invoke(receiver, completion)
}
else
(this.create(receiver, completion) as kotlin.coroutines.experimental.jvm.internal.CoroutineImpl).facade
// INTERNAL DEFINITIONS
@kotlin.jvm.JvmVersion
private inline fun <T> buildContinuationByInvokeCall(
completion: Continuation<T>,
crossinline block: () -> Any?
): Continuation<Unit> {
val continuation =
object : Continuation<Unit> {
override val context: CoroutineContext
get() = completion.context
override fun resume(value: Unit) {
processBareContinuationResume(completion, block)
}
override fun resumeWithException(exception: Throwable) {
completion.resumeWithException(exception)
}
}
return kotlin.coroutines.experimental.jvm.internal.interceptContinuationIfNeeded(completion.context, continuation)
}
@@ -14,7 +14,6 @@
* limitations under the License.
*/
@file:kotlin.jvm.JvmName("IntrinsicsJvmKt")
@file:kotlin.jvm.JvmVersion
package kotlin.coroutines.experimental.intrinsics
import kotlin.coroutines.experimental.*
@@ -41,7 +41,7 @@ abstract class CoroutineImpl(
private var _facade: Continuation<Any?>? = null
val facade: Continuation<Any?> get() {
if (_facade == null) _facade = _context!!.interceptContinuationIfNeeded(this)
if (_facade == null) _facade = interceptContinuationIfNeeded(_context!!, this)
return _facade!!
}
@@ -26,6 +26,7 @@ import kotlin.coroutines.experimental.jvm.internal.CoroutineImpl
fun <T> normalizeContinuation(continuation: Continuation<T>): Continuation<T> =
(continuation as? CoroutineImpl)?.facade ?: continuation
internal fun <T> CoroutineContext.interceptContinuationIfNeeded(
internal fun <T> interceptContinuationIfNeeded(
context: CoroutineContext,
continuation: Continuation<T>
) = this[ContinuationInterceptor]?.interceptContinuation(continuation) ?: continuation
) = context[ContinuationInterceptor]?.interceptContinuation(continuation) ?: continuation