Move release coroutines sources into the corresponding stdlib sourcesets

This commit is contained in:
Ilya Gorbunov
2018-11-17 06:34:05 +03:00
parent 7d61a2de73
commit 5c94ef229b
25 changed files with 2 additions and 9 deletions
@@ -0,0 +1,74 @@
/*
* 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
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater
import kotlin.coroutines.intrinsics.CoroutineSingletons.*
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
import kotlin.coroutines.jvm.internal.CoroutineStackFrame
@PublishedApi
@SinceKotlin("1.3")
internal actual class SafeContinuation<in T>
internal actual constructor(
private val delegate: Continuation<T>,
initialResult: Any?
) : Continuation<T>, CoroutineStackFrame {
@PublishedApi
internal actual constructor(delegate: Continuation<T>) : this(delegate, UNDECIDED)
public actual override val context: CoroutineContext
get() = delegate.context
@Volatile
private var result: Any? = initialResult
private companion object {
@Suppress("UNCHECKED_CAST")
@JvmStatic
private val RESULT = AtomicReferenceFieldUpdater.newUpdater<SafeContinuation<*>, Any?>(
SafeContinuation::class.java, Any::class.java as Class<Any?>, "result"
)
}
public actual override fun resumeWith(result: Result<T>) {
while (true) { // lock-free loop
val cur = this.result // atomic read
when {
cur === UNDECIDED -> if (RESULT.compareAndSet(this, UNDECIDED, result.value)) return
cur === COROUTINE_SUSPENDED -> if (RESULT.compareAndSet(this, COROUTINE_SUSPENDED, RESUMED)) {
delegate.resumeWith(result)
return
}
else -> throw IllegalStateException("Already resumed")
}
}
}
@PublishedApi
internal actual fun getOrThrow(): Any? {
var result = this.result // atomic read
if (result === UNDECIDED) {
if (RESULT.compareAndSet(this, UNDECIDED, COROUTINE_SUSPENDED)) return COROUTINE_SUSPENDED
result = this.result // reread volatile var
}
return when {
result === RESUMED -> COROUTINE_SUSPENDED // already called continuation, indicate COROUTINE_SUSPENDED upstream
result is Result.Failure -> throw result.exception
else -> result // either COROUTINE_SUSPENDED or data
}
}
// --- CoroutineStackFrame implementation
public override val callerFrame: CoroutineStackFrame?
get() = delegate as? CoroutineStackFrame
override fun getStackTraceElement(): StackTraceElement? =
null
override fun toString(): String =
"SafeContinuation for $delegate"
}
@@ -0,0 +1,197 @@
/*
* 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.
*/
@file:kotlin.jvm.JvmName("IntrinsicsKt")
@file:kotlin.jvm.JvmMultifileClass
@file:Suppress("UNCHECKED_CAST")
package kotlin.coroutines.intrinsics
import kotlin.coroutines.*
import kotlin.coroutines.jvm.internal.*
import kotlin.internal.InlineOnly
/**
* Starts unintercepted coroutine without receiver and with result type [T] and executes it until its first suspension.
* Returns the result of the coroutine or throws its exception if it does not suspend or [COROUTINE_SUSPENDED] if it suspends.
* In the later case, the [completion] continuation is invoked when coroutine completes with result or exception.
*
* The coroutine is started directly in the invoker's thread without going through the [ContinuationInterceptor] that might
* be present in the completion's [CoroutineContext]. It is invoker's responsibility to ensure that the proper invocation
* context is established.
*
* This function is designed to be used from inside of [suspendCoroutineUninterceptedOrReturn] to resume the execution of suspended
* coroutine using a reference to the suspending function.
*/
@SinceKotlin("1.3")
@InlineOnly
public actual inline fun <T> (suspend () -> T).startCoroutineUninterceptedOrReturn(
completion: Continuation<T>
): Any? = (this as Function1<Continuation<T>, Any?>).invoke(completion)
/**
* Starts unintercepted coroutine with receiver type [R] and result type [T] and executes it until its first suspension.
* Returns the result of the coroutine or throws its exception if it does not suspend or [COROUTINE_SUSPENDED] if it suspends.
* In the later case, the [completion] continuation is invoked when coroutine completes with result or exception.
*
* The coroutine is started directly in the invoker's thread without going through the [ContinuationInterceptor] that might
* be present in the completion's [CoroutineContext]. It is invoker's responsibility to ensure that the proper invocation
* context is established.
*
* This function is designed to be used from inside of [suspendCoroutineUninterceptedOrReturn] to resume the execution of suspended
* coroutine using a reference to the suspending function.
*/
@SinceKotlin("1.3")
@InlineOnly
public actual inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedOrReturn(
receiver: R,
completion: Continuation<T>
): Any? = (this as Function2<R, Continuation<T>, Any?>).invoke(receiver, completion)
// JVM declarations
/**
* Creates unintercepted 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.
*
* This function returns unintercepted continuation.
* Invocation of `resume(Unit)` starts coroutine immediately in the invoker's call stack without going through the
* [ContinuationInterceptor] that might be present in the completion's [CoroutineContext].
* It is invoker's responsibility to ensure that the proper invocation context is established.
* Note that [completion] of this function may get invoked in an arbitrary context.
*
* [Continuation.intercepted] can be used to acquire the intercepted continuation.
* Invocation of `resume(Unit)` on intercepted continuation guarantees that execution of
* both the coroutine and [completion] happens in the invocation context established by
* [ContinuationInterceptor].
*
* Repeated invocation of any resume function on the resulting continuation corrupts the
* state machine of the coroutine and may result in arbitrary behaviour or exception.
*/
@SinceKotlin("1.3")
public actual fun <T> (suspend () -> T).createCoroutineUnintercepted(
completion: Continuation<T>
): Continuation<Unit> {
val probeCompletion = probeCoroutineCreated(completion)
return if (this is BaseContinuationImpl)
create(probeCompletion)
else
createCoroutineFromSuspendFunction(probeCompletion) {
(this as Function1<Continuation<T>, Any?>).invoke(it)
}
}
/**
* Creates unintercepted 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.
*
* This function returns unintercepted continuation.
* Invocation of `resume(Unit)` starts coroutine immediately in the invoker's call stack without going through the
* [ContinuationInterceptor] that might be present in the completion's [CoroutineContext].
* It is invoker's responsibility to ensure that the proper invocation context is established.
* Note that [completion] of this function may get invoked in an arbitrary context.
*
* [Continuation.intercepted] can be used to acquire the intercepted continuation.
* Invocation of `resume(Unit)` on intercepted continuation guarantees that execution of
* both the coroutine and [completion] happens in the invocation context established by
* [ContinuationInterceptor].
*
* Repeated invocation of any resume function on the resulting continuation corrupts the
* state machine of the coroutine and may result in arbitrary behaviour or exception.
*/
@SinceKotlin("1.3")
public actual fun <R, T> (suspend R.() -> T).createCoroutineUnintercepted(
receiver: R,
completion: Continuation<T>
): Continuation<Unit> {
val probeCompletion = probeCoroutineCreated(completion)
return if (this is BaseContinuationImpl)
create(receiver, probeCompletion)
else {
createCoroutineFromSuspendFunction(probeCompletion) {
(this as Function2<R, Continuation<T>, Any?>).invoke(receiver, it)
}
}
}
/**
* Intercepts this continuation with [ContinuationInterceptor].
*
* This function shall be used on the immediate result of [createCoroutineUnintercepted] or [suspendCoroutineUninterceptedOrReturn],
* in which case it checks for [ContinuationInterceptor] in the continuation's [context][Continuation.context],
* invokes [ContinuationInterceptor.interceptContinuation], caches and returns result.
*
* If this function is invoked on other [Continuation] instances it returns `this` continuation unchanged.
*/
@SinceKotlin("1.3")
public actual fun <T> Continuation<T>.intercepted(): Continuation<T> =
(this as? ContinuationImpl)?.intercepted() ?: this
// INTERNAL DEFINITIONS
/**
* This function is used when [createCoroutineUnintercepted] encounters suspending lambda that does not extend BaseContinuationImpl.
*
* It happens in two cases:
* 1. Callable reference to suspending function,
* 2. Suspending function reference implemented by Java code.
*
* We must wrap it into an instance that extends [BaseContinuationImpl], because that is an expectation of all coroutines machinery.
* As an optimization we use lighter-weight [RestrictedContinuationImpl] base class (it has less fields) if the context is
* [EmptyCoroutineContext], and a full-blown [ContinuationImpl] class otherwise.
*
* The instance of [BaseContinuationImpl] is passed to the [block] so that it can be passed to the corresponding invocation.
*/
@SinceKotlin("1.3")
private inline fun <T> createCoroutineFromSuspendFunction(
completion: Continuation<T>,
crossinline block: (Continuation<T>) -> Any?
): Continuation<Unit> {
val context = completion.context
// label == 0 when coroutine is not started yet (initially) or label == 1 when it was
return if (context === EmptyCoroutineContext)
object : RestrictedContinuationImpl(completion as Continuation<Any?>) {
private var label = 0
override fun invokeSuspend(result: Result<Any?>): Any? =
when (label) {
0 -> {
label = 1
result.getOrThrow() // Rethrow exception if trying to start with exception (will be caught by BaseContinuationImpl.resumeWith
block(this) // run the block, may return or suspend
}
1 -> {
label = 2
result.getOrThrow() // this is the result if the block had suspended
}
else -> error("This coroutine had already completed")
}
}
else
object : ContinuationImpl(completion as Continuation<Any?>, context) {
private var label = 0
override fun invokeSuspend(result: Result<Any?>): Any? =
when (label) {
0 -> {
label = 1
result.getOrThrow() // Rethrow exception if trying to start with exception (will be caught by BaseContinuationImpl.resumeWith
block(this) // run the block, may return or suspend
}
1 -> {
label = 2
result.getOrThrow() // this is the result if the block had suspended
}
else -> error("This coroutine had already completed")
}
}
}
@@ -0,0 +1,166 @@
/*
* 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.jvm.internal
import java.io.Serializable
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
import kotlin.jvm.internal.FunctionBase
import kotlin.jvm.internal.Reflection
@SinceKotlin("1.3")
internal abstract class BaseContinuationImpl(
// This is `public val` so that it is private on JVM and cannot be modified by untrusted code, yet
// it has a public getter (since even untrusted code is allowed to inspect its call stack).
public val completion: Continuation<Any?>?
) : Continuation<Any?>, CoroutineStackFrame, Serializable {
// This implementation is final. This fact is used to unroll resumeWith recursion.
public final override fun resumeWith(result: Result<Any?>) {
// Invoke "resume" debug probe only once, even if previous frames are "resumed" in the loop below, too
probeCoroutineResumed(this)
// This loop unrolls recursion in current.resumeWith(param) to make saner and shorter stack traces on resume
var current = this
var param = result
while (true) {
with(current) {
val completion = completion!! // fail fast when trying to resume continuation without completion
val outcome: Result<Any?> =
try {
val outcome = invokeSuspend(param)
if (outcome === COROUTINE_SUSPENDED) return
Result.success(outcome)
} catch (exception: Throwable) {
Result.failure(exception)
}
releaseIntercepted() // this state machine instance is terminating
if (completion is BaseContinuationImpl) {
// unrolling recursion via loop
current = completion
param = outcome
} else {
// top-level completion reached -- invoke and return
completion.resumeWith(outcome)
return
}
}
}
}
protected abstract fun invokeSuspend(result: Result<Any?>): Any?
protected open fun releaseIntercepted() {
// does nothing here, overridden in ContinuationImpl
}
public open fun create(completion: Continuation<*>): Continuation<Unit> {
throw UnsupportedOperationException("create(Continuation) has not been overridden")
}
public open fun create(value: Any?, completion: Continuation<*>): Continuation<Unit> {
throw UnsupportedOperationException("create(Any?;Continuation) has not been overridden")
}
public override fun toString(): String =
"Continuation at ${getStackTraceElement() ?: this::class.java.name}"
// --- CoroutineStackFrame implementation
public override val callerFrame: CoroutineStackFrame?
get() = completion as? CoroutineStackFrame
public override fun getStackTraceElement(): StackTraceElement? =
getStackTraceElementImpl()
}
@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")
// State machines for named suspend functions extend from this class
internal abstract class ContinuationImpl(
completion: Continuation<Any?>?,
private val _context: CoroutineContext?
) : BaseContinuationImpl(completion) {
constructor(completion: Continuation<Any?>?) : this(completion, completion?.context)
public override val context: CoroutineContext
get() = _context!!
@Transient
private var intercepted: Continuation<Any?>? = null
public fun intercepted(): Continuation<Any?> =
intercepted
?: (context[ContinuationInterceptor]?.interceptContinuation(this) ?: this)
.also { intercepted = it }
protected override fun releaseIntercepted() {
val intercepted = intercepted
if (intercepted != null && intercepted !== this) {
context[ContinuationInterceptor]!!.releaseInterceptedContinuation(intercepted)
}
this.intercepted = CompletedContinuation // just in case
}
}
internal object CompletedContinuation : Continuation<Any?> {
override val context: CoroutineContext
get() = error("This continuation is already complete")
override fun resumeWith(result: Result<Any?>) {
error("This continuation is already complete")
}
override fun toString(): String = "This continuation is already complete"
}
@SinceKotlin("1.3")
// To distinguish suspend function types from ordinary function types all suspend function types shall implement this interface
internal interface SuspendFunction
@SinceKotlin("1.3")
// Restricted suspension lambdas inherit from this class
internal abstract class RestrictedSuspendLambda(
public override val arity: Int,
completion: Continuation<Any?>?
) : RestrictedContinuationImpl(completion), FunctionBase<Any?>, SuspendFunction {
constructor(arity: Int) : this(arity, null)
public override fun toString(): String =
if (completion == null)
Reflection.renderLambdaToString(this) // this is lambda
else
super.toString() // this is continuation
}
@SinceKotlin("1.3")
// Suspension lambdas inherit from this class
internal abstract class SuspendLambda(
public override val arity: Int,
completion: Continuation<Any?>?
) : ContinuationImpl(completion), FunctionBase<Any?>, SuspendFunction {
constructor(arity: Int) : this(arity, null)
public override fun toString(): String =
if (completion == null)
Reflection.renderLambdaToString(this) // this is lambda
else
super.toString() // this is continuation
}
@@ -0,0 +1,31 @@
/*
* 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.jvm.internal
import kotlin.coroutines.*
/**
* Represents one frame in the coroutine call stack for debugger.
* This interface is implemented by compiler-generated implementations of
* [Continuation] interface.
*/
@SinceKotlin("1.3")
public interface CoroutineStackFrame {
/**
* Returns a reference to the stack frame of the caller of this frame,
* that is a frame before this frame in coroutine call stack.
* The result is `null` for the first frame of coroutine.
*/
public val callerFrame: CoroutineStackFrame?
/**
* Returns stack trace element that correspond to this stack frame.
* The result is `null` if the stack trace element is not available for this frame.
* In this case, the debugger represents this stack frame using the
* result of [toString] function.
*/
public fun getStackTraceElement(): StackTraceElement?
}
@@ -0,0 +1,92 @@
/*
* 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.jvm.internal
@Target(AnnotationTarget.CLASS)
@SinceKotlin("1.3")
internal annotation class DebugMetadata(
@get:JvmName("v")
val version: Int = 1,
@get:JvmName("f")
val sourceFile: String = "",
@get:JvmName("l")
val lineNumbers: IntArray = [],
@get:JvmName("n")
val localNames: Array<String> = [],
@get:JvmName("s")
val spilled: Array<String> = [],
@get:JvmName("i")
val indexToLabel: IntArray = [],
@get:JvmName("m")
val methodName: String = "",
@get:JvmName("c")
val className: String = ""
)
/**
* Returns [StackTraceElement] containing file name and line number of current coroutine's suspension point.
* The coroutine can be either running coroutine, that calls the function on its continuation and obtaining
* the information about current file and line number, or, more likely, the function is called to produce accurate stack traces of
* suspended coroutine.
*
* The result is `null` when debug metadata is not available.
*/
@SinceKotlin("1.3")
@JvmName("getStackTraceElement")
internal fun BaseContinuationImpl.getStackTraceElementImpl(): StackTraceElement? {
val debugMetadata = getDebugMetadataAnnotation() ?: return null
checkDebugMetadataVersion(COROUTINES_DEBUG_METADATA_VERSION, debugMetadata.version)
val label = getLabel()
val lineNumber = if (label < 0) -1 else debugMetadata.lineNumbers[label]
return StackTraceElement(debugMetadata.className, debugMetadata.methodName, debugMetadata.sourceFile, lineNumber)
}
private fun BaseContinuationImpl.getDebugMetadataAnnotation(): DebugMetadata? =
javaClass.getAnnotation(DebugMetadata::class.java)
private fun BaseContinuationImpl.getLabel(): Int =
try {
val field = javaClass.getDeclaredField("label")
field.isAccessible = true
(field.get(this) as? Int ?: 0) - 1
} catch (e: Exception) { // NoSuchFieldException, SecurityException, or IllegalAccessException
-1
}
private fun checkDebugMetadataVersion(expected: Int, actual: Int) {
if (actual > expected) {
error("Debug metadata version mismatch. Expected: $expected, got $actual. Please update the Kotlin standard library.")
}
}
/**
* Returns an array of spilled variable names and continuation's field names where the variable has been spilled.
* The structure is the following:
* - field names take 2*k'th indices
* - corresponding variable names take (2*k + 1)'th indices.
*
* The function is for debugger to use, thus it returns simplest data type possible.
* This function should only be called on suspended coroutines to get accurate mapping.
*
* The result is `null` when debug metadata is not available.
*/
@SinceKotlin("1.3")
@JvmName("getSpilledVariableFieldMapping")
internal fun BaseContinuationImpl.getSpilledVariableFieldMapping(): Array<String>? {
val debugMetadata = getDebugMetadataAnnotation() ?: return null
checkDebugMetadataVersion(COROUTINES_DEBUG_METADATA_VERSION, debugMetadata.version)
val res = arrayListOf<String>()
val label = getLabel()
for ((i, labelOfIndex) in debugMetadata.indexToLabel.withIndex()) {
if (labelOfIndex == label) {
res.add(debugMetadata.spilled[i])
res.add(debugMetadata.localNames[i])
}
}
return res.toTypedArray()
}
private const val COROUTINES_DEBUG_METADATA_VERSION = 1
@@ -0,0 +1,77 @@
/*
* 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.jvm.internal
import kotlin.coroutines.Continuation
import kotlin.coroutines.intrinsics.*
/**
* This probe is invoked when coroutine is being created and it can replace completion
* with its own wrapped object to intercept completion of this coroutine.
*
* This probe is invoked from stdlib implementation of [createCoroutineUnintercepted] function.
*
* Once created, coroutine is repeatedly [resumed][probeCoroutineResumed] and [suspended][probeCoroutineSuspended],
* until it is complete. On completion, the object that was returned by this probe is invoked.
*
* ```
* +-------+ probeCoroutineCreated +-----------+
* | START | ---------------------->| SUSPENDED |
* +-------+ +-----------+
* probeCoroutineResumed | ^ probeCoroutineSuspended
* V |
* +------------+ completion invoked +-----------+
* | RUNNING | ------------------->| COMPLETED |
* +------------+ +-----------+
* ```
*
* While the coroutine is resumed and suspended, it is represented by the pointer to its `frame`
* which always extends [BaseContinuationImpl] and represents a pointer to the topmost frame of the
* coroutine. Each [BaseContinuationImpl] object has [completion][BaseContinuationImpl.completion] reference
* that points either to another frame (extending [BaseContinuationImpl]) or to the completion object
* that was returned by this `probeCoroutineCreated` function.
*
* When coroutine is [suspended][probeCoroutineSuspended], then it is later [resumed][probeCoroutineResumed]
* with a reference to the same frame. However, while coroutine is running it can unwind its frames and
* invoke other suspending functions, so its next suspension can happen with a different frame pointer.
*/
@SinceKotlin("1.3")
internal fun <T> probeCoroutineCreated(completion: Continuation<T>): Continuation<T> {
/** implementation of this function is replaced by debugger */
return completion
}
/**
* This probe is invoked when coroutine is resumed using [Continuation.resumeWith].
*
* This probe is invoked from stdlib implementation of [BaseContinuationImpl.resumeWith] function.
*
* Coroutines machinery implementation guarantees that the actual [frame] instance extends
* [BaseContinuationImpl] class, despite the fact that the declared type of [frame]
* parameter in this function is `Continuation<*>`. See [probeCoroutineCreated] for details.
*/
@SinceKotlin("1.3")
@Suppress("UNUSED_PARAMETER")
internal fun probeCoroutineResumed(frame: Continuation<*>) {
/** implementation of this function is replaced by debugger */
}
/**
* This probe is invoked when coroutine is suspended using [suspendCoroutineUninterceptedOrReturn], that is
* when the corresponding `block` returns [COROUTINE_SUSPENDED].
*
* This probe is invoked from compiler-generated intrinsic for [suspendCoroutineUninterceptedOrReturn] function.
*
* Coroutines machinery implementation guarantees that the actual [frame] instance extends
* [BaseContinuationImpl] class, despite the fact that the declared type of [frame]
* parameter in this function is `Continuation<*>`. See [probeCoroutineCreated] for details.
*/
@SinceKotlin("1.3")
@Suppress("UNUSED_PARAMETER")
internal fun probeCoroutineSuspended(frame: Continuation<*>) {
/** implementation of this function is replaced by debugger */
}
@@ -0,0 +1,45 @@
/*
* 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.jvm.internal
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.startCoroutine
/**
* Wrapper for `suspend fun main` and `@Test suspend fun testXXX` functions.
*/
@SinceKotlin("1.3")
internal fun runSuspend(block: suspend () -> Unit) {
val run = RunSuspend()
block.startCoroutine(run)
run.await()
}
private class RunSuspend : Continuation<Unit> {
override val context: CoroutineContext
get() = EmptyCoroutineContext
var result: Result<Unit>? = null
override fun resumeWith(result: Result<Unit>) = synchronized(this) {
this.result = result
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).notifyAll()
}
fun await() = synchronized(this) {
while (true) {
when (val result = this.result) {
null -> @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).wait()
else -> {
result.getOrThrow() // throw up failure
return
}
}
}
}
}
@@ -0,0 +1,48 @@
/*
* 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.
*/
@file:JvmName("Boxing")
@file:Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
package kotlin.coroutines.jvm.internal
/*
* Box primitive to Java wrapper class by allocating the wrapper object.
*
* This allows HotSpot JIT to eliminate allocations completely in coroutines code with primitives.
*/
@SinceKotlin("1.3")
@PublishedApi
internal fun boxBoolean(primitive: Boolean): java.lang.Boolean = java.lang.Boolean.valueOf(primitive) as java.lang.Boolean
@SinceKotlin("1.3")
@PublishedApi
internal fun boxByte(primitive: Byte): java.lang.Byte = java.lang.Byte.valueOf(primitive) as java.lang.Byte
@SinceKotlin("1.3")
@PublishedApi
internal fun boxShort(primitive: Short): java.lang.Short = java.lang.Short(primitive)
@SinceKotlin("1.3")
@PublishedApi
internal fun boxInt(primitive: Int): java.lang.Integer = java.lang.Integer(primitive)
@SinceKotlin("1.3")
@PublishedApi
internal fun boxLong(primitive: Long): java.lang.Long = java.lang.Long(primitive)
@SinceKotlin("1.3")
@PublishedApi
internal fun boxFloat(primitive: Float): java.lang.Float = java.lang.Float(primitive)
@SinceKotlin("1.3")
@PublishedApi
internal fun boxDouble(primitive: Double): java.lang.Double = java.lang.Double(primitive)
@SinceKotlin("1.3")
@PublishedApi
internal fun boxChar(primitive: Char): java.lang.Character = java.lang.Character(primitive)