diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt index 7987ee78c92..56376ff8c19 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.test.TargetBackend import java.io.File -private val runtimeSourcesCommon = listOfKtFilesFrom( +private val runtimeSources = listOfKtFilesFrom( "core/builtins/src/kotlin", "libraries/stdlib/common/src", "libraries/stdlib/src/kotlin/", @@ -72,32 +72,20 @@ private val runtimeSourcesCommon = listOfKtFilesFrom( // Mostly array-specific stuff "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 "libraries/stdlib/js/src/kotlin/jsTypeOf.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 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( pathToTestDir: String, testGroupOutputDirPrefix: String, diff --git a/libraries/stdlib/js/irRuntime/coroutines_12/coroutineAliases.kt b/libraries/stdlib/js/irRuntime/coroutines_12/coroutineAliases.kt deleted file mode 100644 index 030d3b703e8..00000000000 --- a/libraries/stdlib/js/irRuntime/coroutines_12/coroutineAliases.kt +++ /dev/null @@ -1,9 +0,0 @@ - -package kotlin.js.coroutineAliases - -import kotlin.coroutines.experimental.* - - -typealias ContinuationAlias = Continuation -typealias CoroutineContextAlias = CoroutineContext -typealias ContinuationInterceptorAlias = ContinuationInterceptor \ No newline at end of file diff --git a/libraries/stdlib/js/irRuntime/coroutines_12/coroutineIntrinsics.kt b/libraries/stdlib/js/irRuntime/coroutines_12/coroutineIntrinsics.kt deleted file mode 100644 index 712dcab9a55..00000000000 --- a/libraries/stdlib/js/irRuntime/coroutines_12/coroutineIntrinsics.kt +++ /dev/null @@ -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 normalizeContinuation(continuation: Continuation): Continuation = - (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 suspendCoroutineOrReturn(crossinline block: (Continuation) -> Any?): T = - suspendCoroutineUninterceptedOrReturn { cont -> block(cont.intercepted()) } - -@SinceKotlin("1.2") -public suspend fun suspendCoroutineUninterceptedOrReturn(block: (Continuation) -> Any?): T = - throw NotImplementedError("Implementation of suspendCoroutineUninterceptedOrReturn is intrinsic") - -/** - * Intercept continuation with [ContinuationInterceptor]. - */ -@SinceKotlin("1.2") -@kotlin.internal.InlineOnly -public inline fun Continuation.intercepted() = normalizeContinuation(this) - -@SinceKotlin("1.1") -public val COROUTINE_SUSPENDED: Any = Any() - -@SinceKotlin("1.1") -@Suppress("UNCHECKED_CAST") -@kotlin.internal.InlineOnly -public actual inline fun (suspend () -> T).startCoroutineUninterceptedOrReturn( - completion: Continuation -): 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, Any?>).invoke(completion) -} - -@SinceKotlin("1.1") -@Suppress("UNCHECKED_CAST") -@kotlin.internal.InlineOnly -public actual inline fun (suspend R.() -> T).startCoroutineUninterceptedOrReturn( - receiver: R, - completion: Continuation -): 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, Any?>).invoke(receiver, completion) -} - -@SinceKotlin("1.1") -public actual fun (suspend R.() -> T).createCoroutineUnchecked( - receiver: R, - completion: Continuation -): Continuation { - return if (this !is CoroutineImpl) { - buildContinuationByInvokeCall(completion) { - @Suppress("UNCHECKED_CAST") (this as Function2, Any?>).invoke(receiver, completion) - } - } else { - (create(receiver, completion) as CoroutineImpl).facade - } -} - -@SinceKotlin("1.1") -public actual fun (suspend () -> T).createCoroutineUnchecked( - completion: Continuation -): Continuation { - return if (this !is CoroutineImpl) { - buildContinuationByInvokeCall(completion) { - @Suppress("UNCHECKED_CAST") (this as Function1, Any?>).invoke(completion) - } - } else { - (create(completion) as CoroutineImpl).facade - } -} - -private inline fun buildContinuationByInvokeCall( - completion: Continuation, - crossinline block: () -> Any? -): Continuation { - val continuation = - object : Continuation { - 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) -} \ No newline at end of file diff --git a/libraries/stdlib/js/irRuntime/coroutines_12/coroutines.kt b/libraries/stdlib/js/irRuntime/coroutines_12/coroutines.kt deleted file mode 100644 index d57a46ed869..00000000000 --- a/libraries/stdlib/js/irRuntime/coroutines_12/coroutines.kt +++ /dev/null @@ -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 (suspend R.() -> T).startCoroutine( - receiver: R, - completion: Continuation -) { - 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 (suspend () -> T).startCoroutine( - completion: Continuation -) { - 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 (suspend R.() -> T).createCoroutine( - receiver: R, - completion: Continuation -): Continuation = 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 (suspend () -> T).createCoroutine( - completion: Continuation -): Continuation = 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 get(key: Key): 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 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 get(key: Key): E? = - if (this.key === key) this as E else null - - public override fun 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 -} - -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 - - /** - * 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 interceptContinuation(continuation: Continuation): Continuation -} - - -internal class CombinedContext(val left: CoroutineContext, val element: CoroutineContext.Element) : CoroutineContext { - override fun get(key: CoroutineContext.Key): 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 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 get(key: CoroutineContext.Key): E? = null - public override fun 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 -internal actual constructor( - private val delegate: Continuation, - initialResult: Any? -) : Continuation { - - @PublishedApi - internal actual constructor(delegate: Continuation) : 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 suspendCoroutine(crossinline block: (Continuation) -> Unit): T = - suspendCoroutineOrReturn { c: Continuation -> - 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).resume(result) - } - } catch (t: Throwable) { - completion.resumeWithException(t) - } -} \ No newline at end of file diff --git a/libraries/stdlib/js/irRuntime/coroutines_12/coroutinesInternal.kt b/libraries/stdlib/js/irRuntime/coroutines_12/coroutinesInternal.kt deleted file mode 100644 index 71ffe2e0463..00000000000 --- a/libraries/stdlib/js/irRuntime/coroutines_12/coroutinesInternal.kt +++ /dev/null @@ -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) : Continuation { - 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 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 { - throw IllegalStateException("create(Continuation) has not been overridden") - } - - open fun create(value: Any?, completion: Continuation<*>): Continuation { - throw IllegalStateException("create(Any?;Continuation) has not been overridden") - } -} \ No newline at end of file