Leave only 1.3 JS IR runtime sources
Update exclusions after merging coroutines sources into stdlib.
This commit is contained in:
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
private val runtimeSourcesCommon = listOfKtFilesFrom(
|
private val runtimeSources = listOfKtFilesFrom(
|
||||||
"core/builtins/src/kotlin",
|
"core/builtins/src/kotlin",
|
||||||
"libraries/stdlib/common/src",
|
"libraries/stdlib/common/src",
|
||||||
"libraries/stdlib/src/kotlin/",
|
"libraries/stdlib/src/kotlin/",
|
||||||
@@ -72,32 +72,20 @@ private val runtimeSourcesCommon = listOfKtFilesFrom(
|
|||||||
// Mostly array-specific stuff
|
// Mostly array-specific stuff
|
||||||
"libraries/stdlib/js/src/kotlin/builtins.kt",
|
"libraries/stdlib/js/src/kotlin/builtins.kt",
|
||||||
|
|
||||||
|
// coroutines
|
||||||
|
// TODO: merge coroutines_13 with JS BE coroutines
|
||||||
|
"libraries/stdlib/js/src/kotlin/coroutines/intrinsics/IntrinsicsJs.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/coroutines/CoroutineImpl.kt",
|
||||||
|
|
||||||
// Inlining of js fun doesn't update the variables inside
|
// Inlining of js fun doesn't update the variables inside
|
||||||
"libraries/stdlib/js/src/kotlin/jsTypeOf.kt",
|
"libraries/stdlib/js/src/kotlin/jsTypeOf.kt",
|
||||||
"libraries/stdlib/js/src/kotlin/collections/utils.kt"
|
"libraries/stdlib/js/src/kotlin/collections/utils.kt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
private val coroutine12Files = listOfKtFilesFrom(
|
|
||||||
"libraries/stdlib/js/irRuntime/coroutines_12"
|
|
||||||
)
|
|
||||||
|
|
||||||
private val coroutine13Files = listOfKtFilesFrom(
|
|
||||||
"libraries/stdlib/coroutines/common",
|
|
||||||
"libraries/stdlib/coroutines/js/src/kotlin/coroutines/SafeContinuationJs.kt",
|
|
||||||
"libraries/stdlib/coroutines/src",
|
|
||||||
// TODO: merge coroutines_13 with JS BE coroutines
|
|
||||||
"libraries/stdlib/js/irRuntime/coroutines_13"
|
|
||||||
)
|
|
||||||
|
|
||||||
private var runtimeResult: Result? = null
|
private var runtimeResult: Result? = null
|
||||||
private val runtimeFile = File("js/js.translator/testData/out/irBox/testRuntime.js")
|
private val runtimeFile = File("js/js.translator/testData/out/irBox/testRuntime.js")
|
||||||
|
|
||||||
private val runtimeSources_12 = (runtimeSourcesCommon - coroutine13Files + coroutine12Files).distinct()
|
|
||||||
private val runtimeSources_13 = (runtimeSourcesCommon - coroutine12Files + coroutine13Files).distinct()
|
|
||||||
|
|
||||||
private val runtimeSources = runtimeSources_13
|
|
||||||
|
|
||||||
abstract class BasicIrBoxTest(
|
abstract class BasicIrBoxTest(
|
||||||
pathToTestDir: String,
|
pathToTestDir: String,
|
||||||
testGroupOutputDirPrefix: String,
|
testGroupOutputDirPrefix: String,
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
package kotlin.js.coroutineAliases
|
|
||||||
|
|
||||||
import kotlin.coroutines.experimental.*
|
|
||||||
|
|
||||||
|
|
||||||
typealias ContinuationAlias<T> = Continuation<T>
|
|
||||||
typealias CoroutineContextAlias = CoroutineContext
|
|
||||||
typealias ContinuationInterceptorAlias = ContinuationInterceptor
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package kotlin.coroutines.experimental.intrinsics
|
|
||||||
|
|
||||||
import kotlin.coroutines.experimental.*
|
|
||||||
|
|
||||||
@PublishedApi
|
|
||||||
internal fun <T> normalizeContinuation(continuation: Continuation<T>): Continuation<T> =
|
|
||||||
(continuation as? CoroutineImpl)?.facade ?: continuation
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtains the current continuation instance inside suspend functions and either suspends
|
|
||||||
* currently running coroutine or returns result immediately without suspension.
|
|
||||||
*
|
|
||||||
* Unlike [suspendCoroutineOrReturn] it does not intercept continuation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@SinceKotlin("1.1")
|
|
||||||
@kotlin.internal.InlineOnly
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
public suspend inline fun <T> suspendCoroutineOrReturn(crossinline block: (Continuation<T>) -> Any?): T =
|
|
||||||
suspendCoroutineUninterceptedOrReturn { cont -> block(cont.intercepted()) }
|
|
||||||
|
|
||||||
@SinceKotlin("1.2")
|
|
||||||
public suspend fun <T> suspendCoroutineUninterceptedOrReturn(block: (Continuation<T>) -> Any?): T =
|
|
||||||
throw NotImplementedError("Implementation of suspendCoroutineUninterceptedOrReturn is intrinsic")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Intercept continuation with [ContinuationInterceptor].
|
|
||||||
*/
|
|
||||||
@SinceKotlin("1.2")
|
|
||||||
@kotlin.internal.InlineOnly
|
|
||||||
public inline fun <T> Continuation<T>.intercepted() = normalizeContinuation<T>(this)
|
|
||||||
|
|
||||||
@SinceKotlin("1.1")
|
|
||||||
public val COROUTINE_SUSPENDED: Any = Any()
|
|
||||||
|
|
||||||
@SinceKotlin("1.1")
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
@kotlin.internal.InlineOnly
|
|
||||||
public actual inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn(
|
|
||||||
completion: Continuation<T>
|
|
||||||
): Any? {
|
|
||||||
val self_0 = this
|
|
||||||
val cmpt_0 = completion
|
|
||||||
return js("self_0.invoke(cmpt_0)")
|
|
||||||
// TODO: use clean version once function references is fixed
|
|
||||||
// return (this as Function1<Continuation<T>, Any?>).invoke(completion)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SinceKotlin("1.1")
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
@kotlin.internal.InlineOnly
|
|
||||||
public actual inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedOrReturn(
|
|
||||||
receiver: R,
|
|
||||||
completion: Continuation<T>
|
|
||||||
): Any? {
|
|
||||||
val self_0 = this
|
|
||||||
val rec_0 = receiver
|
|
||||||
val cmpt_0 = completion
|
|
||||||
return js("self_0.invoke(rec_0, cmpt_0)")
|
|
||||||
// TODO: use clean version once function references is fixed
|
|
||||||
// return (this as Function2<R, Continuation<T>, Any?>).invoke(receiver, completion)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SinceKotlin("1.1")
|
|
||||||
public actual fun <R, T> (suspend R.() -> T).createCoroutineUnchecked(
|
|
||||||
receiver: R,
|
|
||||||
completion: Continuation<T>
|
|
||||||
): Continuation<Unit> {
|
|
||||||
return if (this !is CoroutineImpl) {
|
|
||||||
buildContinuationByInvokeCall(completion) {
|
|
||||||
@Suppress("UNCHECKED_CAST") (this as Function2<R, Continuation<T>, Any?>).invoke(receiver, completion)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
(create(receiver, completion) as CoroutineImpl).facade
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SinceKotlin("1.1")
|
|
||||||
public actual fun <T> (suspend () -> T).createCoroutineUnchecked(
|
|
||||||
completion: Continuation<T>
|
|
||||||
): Continuation<Unit> {
|
|
||||||
return if (this !is CoroutineImpl) {
|
|
||||||
buildContinuationByInvokeCall(completion) {
|
|
||||||
@Suppress("UNCHECKED_CAST") (this as Function1<Continuation<T>, Any?>).invoke(completion)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
(create(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 interceptContinuationIfNeeded(completion.context, continuation)
|
|
||||||
}
|
|
||||||
@@ -1,313 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package kotlin.coroutines.experimental
|
|
||||||
|
|
||||||
import kotlin.coroutines.experimental.intrinsics.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts coroutine with receiver type [R] and result type [T].
|
|
||||||
* This function creates and start a new, fresh instance of suspendable computation every time it is invoked.
|
|
||||||
* The [completion] continuation is invoked when coroutine completes with result or exception.
|
|
||||||
*/
|
|
||||||
@SinceKotlin("1.1")
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
public fun <R, T> (suspend R.() -> T).startCoroutine(
|
|
||||||
receiver: R,
|
|
||||||
completion: Continuation<T>
|
|
||||||
) {
|
|
||||||
createCoroutineUnchecked(receiver, completion).resume(Unit)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts coroutine without receiver and with result type [T].
|
|
||||||
* This function creates and start a new, fresh instance of suspendable computation every time it is invoked.
|
|
||||||
* The [completion] continuation is invoked when coroutine completes with result or exception.
|
|
||||||
*/
|
|
||||||
@SinceKotlin("1.1")
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
public fun <T> (suspend () -> T).startCoroutine(
|
|
||||||
completion: Continuation<T>
|
|
||||||
) {
|
|
||||||
createCoroutineUnchecked(completion).resume(Unit)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a coroutine with receiver type [R] and result type [T].
|
|
||||||
* This function creates a new, fresh instance of suspendable computation every time it is invoked.
|
|
||||||
*
|
|
||||||
* To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance.
|
|
||||||
* The [completion] continuation is invoked when coroutine completes with result or exception.
|
|
||||||
* Repeated invocation of any resume function on the resulting continuation produces [IllegalStateException].
|
|
||||||
*/
|
|
||||||
@SinceKotlin("1.1")
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
public fun <R, T> (suspend R.() -> T).createCoroutine(
|
|
||||||
receiver: R,
|
|
||||||
completion: Continuation<T>
|
|
||||||
): Continuation<Unit> = SafeContinuation(createCoroutineUnchecked(receiver, completion), COROUTINE_SUSPENDED)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a coroutine without receiver and with result type [T].
|
|
||||||
* This function creates a new, fresh instance of suspendable computation every time it is invoked.
|
|
||||||
*
|
|
||||||
* To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance.
|
|
||||||
* The [completion] continuation is invoked when coroutine completes with result or exception.
|
|
||||||
* Repeated invocation of any resume function on the resulting continuation produces [IllegalStateException].
|
|
||||||
*/
|
|
||||||
@SinceKotlin("1.1")
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
public fun <T> (suspend () -> T).createCoroutine(
|
|
||||||
completion: Continuation<T>
|
|
||||||
): Continuation<Unit> = SafeContinuation(createCoroutineUnchecked(completion), COROUTINE_SUSPENDED)
|
|
||||||
|
|
||||||
public interface CoroutineContext {
|
|
||||||
/**
|
|
||||||
* Returns the element with the given [key] from this context or `null`.
|
|
||||||
* Keys are compared _by reference_, that is to get an element from the context the reference to its actual key
|
|
||||||
* object must be presented to this function.
|
|
||||||
*/
|
|
||||||
public operator fun <E : Element> get(key: Key<E>): E?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accumulates entries of this context starting with [initial] value and applying [operation]
|
|
||||||
* from left to right to current accumulator value and each element of this context.
|
|
||||||
*/
|
|
||||||
public fun <R> fold(initial: R, operation: (R, Element) -> R): R
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a context containing elements from this context and elements from other [context].
|
|
||||||
* The elements from this context with the same key as in the other one are dropped.
|
|
||||||
*/
|
|
||||||
public operator fun plus(context: CoroutineContext): CoroutineContext =
|
|
||||||
if (context === EmptyCoroutineContext) this else // fast path -- avoid lambda creation
|
|
||||||
context.fold(this) { acc, element ->
|
|
||||||
val removed = acc.minusKey(element.key)
|
|
||||||
if (removed === EmptyCoroutineContext) element else {
|
|
||||||
// make sure interceptor is always last in the context (and thus is fast to get when present)
|
|
||||||
val interceptor = removed[ContinuationInterceptor]
|
|
||||||
if (interceptor == null) CombinedContext(removed, element) else {
|
|
||||||
val left = removed.minusKey(ContinuationInterceptor)
|
|
||||||
if (left === EmptyCoroutineContext) CombinedContext(element, interceptor) else
|
|
||||||
CombinedContext(CombinedContext(left, element), interceptor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a context containing elements from this context, but without an element with
|
|
||||||
* the specified [key]. Keys are compared _by reference_, that is to remove an element from the context
|
|
||||||
* the reference to its actual key object must be presented to this function.
|
|
||||||
*/
|
|
||||||
public fun minusKey(key: Key<*>): CoroutineContext
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An element of the [CoroutineContext]. An element of the coroutine context is a singleton context by itself.
|
|
||||||
*/
|
|
||||||
public interface Element : CoroutineContext {
|
|
||||||
/**
|
|
||||||
* A key of this coroutine context element.
|
|
||||||
*/
|
|
||||||
public val key: Key<*>
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
public override operator fun <E : Element> get(key: Key<E>): E? =
|
|
||||||
if (this.key === key) this as E else null
|
|
||||||
|
|
||||||
public override fun <R> fold(initial: R, operation: (R, Element) -> R): R =
|
|
||||||
operation(initial, this)
|
|
||||||
|
|
||||||
public override fun minusKey(key: Key<*>): CoroutineContext =
|
|
||||||
if (this.key === key) EmptyCoroutineContext else this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Key for the elements of [CoroutineContext]. [E] is a type of element with this key.
|
|
||||||
* Keys in the context are compared _by reference_.
|
|
||||||
*/
|
|
||||||
public interface Key<E : Element>
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class AbstractCoroutineContextElement(public override val key: CoroutineContext.Key<*>) : CoroutineContext.Element
|
|
||||||
|
|
||||||
public interface ContinuationInterceptor : CoroutineContext.Element {
|
|
||||||
/**
|
|
||||||
* The key that defines *the* context interceptor.
|
|
||||||
*/
|
|
||||||
companion object Key : CoroutineContext.Key<ContinuationInterceptor>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns continuation that wraps the original [continuation], thus intercepting all resumptions.
|
|
||||||
* This function is invoked by coroutines framework when needed and the resulting continuations are
|
|
||||||
* cached internally per each instance of the original [continuation].
|
|
||||||
*
|
|
||||||
* By convention, implementations that install themselves as *the* interceptor in the context with
|
|
||||||
* the [Key] shall also scan the context for other element that implement [ContinuationInterceptor] interface
|
|
||||||
* and use their [interceptContinuation] functions, too.
|
|
||||||
*/
|
|
||||||
public fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal class CombinedContext(val left: CoroutineContext, val element: CoroutineContext.Element) : CoroutineContext {
|
|
||||||
override fun <E : CoroutineContext.Element> get(key: CoroutineContext.Key<E>): E? {
|
|
||||||
var cur = this
|
|
||||||
while (true) {
|
|
||||||
cur.element[key]?.let { return it }
|
|
||||||
val next = cur.left
|
|
||||||
if (next is CombinedContext) {
|
|
||||||
cur = next
|
|
||||||
} else {
|
|
||||||
return next[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun <R> fold(initial: R, operation: (R, CoroutineContext.Element) -> R): R =
|
|
||||||
operation(left.fold(initial, operation), element)
|
|
||||||
|
|
||||||
public override fun minusKey(key: CoroutineContext.Key<*>): CoroutineContext {
|
|
||||||
element[key]?.let { return left }
|
|
||||||
val newLeft = left.minusKey(key)
|
|
||||||
return when {
|
|
||||||
newLeft === left -> this
|
|
||||||
newLeft === EmptyCoroutineContext -> element
|
|
||||||
else -> CombinedContext(newLeft, element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun size(): Int =
|
|
||||||
if (left is CombinedContext) left.size() + 1 else 2
|
|
||||||
|
|
||||||
private fun contains(element: CoroutineContext.Element): Boolean =
|
|
||||||
get(element.key) == element
|
|
||||||
|
|
||||||
private fun containsAll(context: CombinedContext): Boolean {
|
|
||||||
var cur = context
|
|
||||||
while (true) {
|
|
||||||
if (!contains(cur.element)) return false
|
|
||||||
val next = cur.left
|
|
||||||
if (next is CombinedContext) {
|
|
||||||
cur = next
|
|
||||||
} else {
|
|
||||||
return contains(next as CoroutineContext.Element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean =
|
|
||||||
this === other || other is CombinedContext && other.size() == size() && other.containsAll(this)
|
|
||||||
|
|
||||||
override fun hashCode(): Int = left.hashCode() + element.hashCode()
|
|
||||||
|
|
||||||
override fun toString(): String = "CC"
|
|
||||||
}
|
|
||||||
|
|
||||||
public object EmptyCoroutineContext : CoroutineContext {
|
|
||||||
public override fun <E : CoroutineContext.Element> get(key: CoroutineContext.Key<E>): E? = null
|
|
||||||
public override fun <R> fold(initial: R, operation: (R, CoroutineContext.Element) -> R): R = initial
|
|
||||||
public override fun plus(context: CoroutineContext): CoroutineContext = context
|
|
||||||
public override fun minusKey(key: CoroutineContext.Key<*>): CoroutineContext = this
|
|
||||||
public override fun hashCode(): Int = 0
|
|
||||||
public override fun toString(): String = "EmptyCoroutineContext"
|
|
||||||
}
|
|
||||||
|
|
||||||
@PublishedApi
|
|
||||||
internal actual class SafeContinuation<in T>
|
|
||||||
internal actual constructor(
|
|
||||||
private val delegate: Continuation<T>,
|
|
||||||
initialResult: Any?
|
|
||||||
) : Continuation<T> {
|
|
||||||
|
|
||||||
@PublishedApi
|
|
||||||
internal actual constructor(delegate: Continuation<T>) : this(delegate, UNDECIDED)
|
|
||||||
|
|
||||||
public actual override val context: CoroutineContext
|
|
||||||
get() = delegate.context
|
|
||||||
|
|
||||||
private var result: Any? = initialResult
|
|
||||||
|
|
||||||
actual override fun resume(value: T) {
|
|
||||||
when {
|
|
||||||
result === UNDECIDED -> {
|
|
||||||
result = value
|
|
||||||
}
|
|
||||||
result === COROUTINE_SUSPENDED -> {
|
|
||||||
result = RESUMED
|
|
||||||
delegate.resume(value)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
throw IllegalStateException("Already resumed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actual override fun resumeWithException(exception: Throwable) {
|
|
||||||
when {
|
|
||||||
result === UNDECIDED -> {
|
|
||||||
result = Fail(exception)
|
|
||||||
}
|
|
||||||
result === COROUTINE_SUSPENDED -> {
|
|
||||||
result = RESUMED
|
|
||||||
delegate.resumeWithException(exception)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
throw IllegalStateException("Already resumed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PublishedApi
|
|
||||||
internal actual fun getResult(): Any? {
|
|
||||||
if (result === UNDECIDED) {
|
|
||||||
result = COROUTINE_SUSPENDED
|
|
||||||
}
|
|
||||||
val result = this.result
|
|
||||||
return when {
|
|
||||||
result === RESUMED -> {
|
|
||||||
COROUTINE_SUSPENDED // already called continuation, indicate SUSPENDED upstream
|
|
||||||
}
|
|
||||||
result is Fail -> {
|
|
||||||
throw result.exception
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
result // either SUSPENDED or data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<T>) -> Unit): T =
|
|
||||||
suspendCoroutineOrReturn { c: Continuation<T> ->
|
|
||||||
val safe = SafeContinuation(c)
|
|
||||||
block(safe)
|
|
||||||
safe.getResult()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val UNDECIDED: Any? = Any()
|
|
||||||
private val RESUMED: Any? = Any()
|
|
||||||
|
|
||||||
private class Fail(val exception: Throwable)
|
|
||||||
|
|
||||||
@SinceKotlin("1.2")
|
|
||||||
@Suppress("WRONG_MODIFIER_TARGET")
|
|
||||||
@kotlin.internal.InlineOnly
|
|
||||||
public suspend inline val coroutineContext: CoroutineContext
|
|
||||||
get() {
|
|
||||||
throw NotImplementedError("Implemented as intrinsic")
|
|
||||||
}
|
|
||||||
|
|
||||||
@kotlin.internal.InlineOnly
|
|
||||||
internal inline fun processBareContinuationResume(completion: Continuation<*>, block: () -> Any?) {
|
|
||||||
try {
|
|
||||||
val result = block()
|
|
||||||
if (result !== COROUTINE_SUSPENDED) {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
(completion as Continuation<Any?>).resume(result)
|
|
||||||
}
|
|
||||||
} catch (t: Throwable) {
|
|
||||||
completion.resumeWithException(t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package kotlin.coroutines.experimental
|
|
||||||
|
|
||||||
internal abstract class CoroutineImpl(private val completion: Continuation<Any?>) : Continuation<Any?> {
|
|
||||||
protected var exceptionState = 0
|
|
||||||
protected var state: Int = 0
|
|
||||||
|
|
||||||
protected var exception: dynamic = null
|
|
||||||
protected var result: dynamic = null
|
|
||||||
|
|
||||||
public override val context: CoroutineContext get() = completion?.context
|
|
||||||
|
|
||||||
val facade: Continuation<Any?> get() {
|
|
||||||
return if (context != null) interceptContinuationIfNeeded(context, this)
|
|
||||||
else this
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun resume(value: Any?) {
|
|
||||||
this.result = value
|
|
||||||
doResumeWrapper()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun resumeWithException(exception: Throwable) {
|
|
||||||
// TODO: once we have arrays working refact it with exception table
|
|
||||||
this.state = exceptionState
|
|
||||||
this.exception = exception
|
|
||||||
doResumeWrapper()
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun doResumeWrapper() {
|
|
||||||
processBareContinuationResume(completion) { doResume() }
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun doResume(): Any?
|
|
||||||
|
|
||||||
open fun create(completion: Continuation<*>): Continuation<Unit> {
|
|
||||||
throw IllegalStateException("create(Continuation) has not been overridden")
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun create(value: Any?, completion: Continuation<*>): Continuation<Unit> {
|
|
||||||
throw IllegalStateException("create(Any?;Continuation) has not been overridden")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user