Implemented intrinsic <coroutineContext> + tests
This commit is contained in:
+16
-4
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.backend.konan.lower.TestProcessor
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||
import org.jetbrains.kotlin.config.coroutinesIntrinsicsPackageFqName
|
||||
import org.jetbrains.kotlin.config.coroutinesPackageFqName
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
@@ -326,21 +327,32 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable): Sym
|
||||
val konanSuspendCoroutineUninterceptedOrReturn = symbolTable.referenceSimpleFunction(
|
||||
context.getInternalFunctions("suspendCoroutineUninterceptedOrReturn").single())
|
||||
|
||||
private val coroutinesPackage = context.builtIns.builtInsModule.getPackage(
|
||||
val konanCoroutineContextGetter = symbolTable.referenceSimpleFunction(
|
||||
context.getInternalFunctions("getCoroutineContext").single())
|
||||
|
||||
private val coroutinesIntrinsicsPackage = context.builtIns.builtInsModule.getPackage(
|
||||
context.config.configuration.languageVersionSettings.coroutinesIntrinsicsPackageFqName()).memberScope
|
||||
|
||||
val intercepted = coroutinesPackage
|
||||
private val coroutinesPackage = context.builtIns.builtInsModule.getPackage(
|
||||
context.config.configuration.languageVersionSettings.coroutinesPackageFqName()).memberScope
|
||||
|
||||
val intercepted = coroutinesIntrinsicsPackage
|
||||
.getContributedFunctions(INTERCEPTED_NAME, NoLookupLocation.FROM_BACKEND)
|
||||
.single()
|
||||
|
||||
val suspendCoroutineUninterceptedOrReturn = coroutinesPackage
|
||||
val suspendCoroutineUninterceptedOrReturn = coroutinesIntrinsicsPackage
|
||||
.getContributedFunctions(SUSPEND_COROUTINE_UNINTERCEPTED_OR_RETURN_NAME, NoLookupLocation.FROM_BACKEND)
|
||||
.single()
|
||||
|
||||
val coroutineContextGetter = coroutinesPackage
|
||||
.getContributedVariables(Name.identifier("coroutineContext"), NoLookupLocation.FROM_BACKEND)
|
||||
.single()
|
||||
.getter!!
|
||||
|
||||
override val coroutineImpl = symbolTable.referenceClass(context.getInternalClass("CoroutineImpl"))
|
||||
|
||||
override val coroutineSuspendedGetter = symbolTable.referenceSimpleFunction(
|
||||
coroutinesPackage
|
||||
coroutinesIntrinsicsPackage
|
||||
.getContributedVariables(COROUTINE_SUSPENDED_NAME, NoLookupLocation.FROM_BACKEND)
|
||||
.single().getter!!
|
||||
)
|
||||
|
||||
+20
-12
@@ -94,18 +94,26 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun getFunctionDeclaration(descriptor: FunctionDescriptor): IrFunction? {
|
||||
val originalDescriptor = descriptor.resolveFakeOverride().original
|
||||
if (originalDescriptor == context.ir.symbols.intercepted)
|
||||
return getFunctionDeclaration(context.ir.symbols.konanIntercepted.descriptor)
|
||||
if (originalDescriptor == context.ir.symbols.suspendCoroutineUninterceptedOrReturn) {
|
||||
return getFunctionDeclaration(context.ir.symbols.konanSuspendCoroutineUninterceptedOrReturn.descriptor)
|
||||
}
|
||||
val functionDeclaration =
|
||||
context.ir.originalModuleIndex.functions[originalDescriptor] ?: // If function is declared in the current module.
|
||||
deserializer.deserializeInlineBody(originalDescriptor) // Function is declared in another module.
|
||||
return functionDeclaration as IrFunction?
|
||||
}
|
||||
private fun getFunctionDeclaration(descriptor: FunctionDescriptor): IrFunction? =
|
||||
descriptor.resolveFakeOverride().original.let {
|
||||
when (it) {
|
||||
context.ir.symbols.intercepted ->
|
||||
getFunctionDeclaration(context.ir.symbols.konanIntercepted.descriptor)
|
||||
|
||||
context.ir.symbols.suspendCoroutineUninterceptedOrReturn ->
|
||||
getFunctionDeclaration(context.ir.symbols.konanSuspendCoroutineUninterceptedOrReturn.descriptor)
|
||||
|
||||
context.ir.symbols.coroutineContextGetter ->
|
||||
getFunctionDeclaration(context.ir.symbols.konanCoroutineContextGetter.descriptor)
|
||||
|
||||
else -> {
|
||||
val functionDeclaration =
|
||||
context.ir.originalModuleIndex.functions[it] ?: // If function is declared in the current module.
|
||||
deserializer.deserializeInlineBody(it) // Function is declared in another module.
|
||||
functionDeclaration as IrFunction?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
|
||||
@@ -1309,6 +1309,16 @@ task coroutines_returnsUnit1(type: RunKonanTest) {
|
||||
source = "codegen/coroutines/returnsUnit1.kt"
|
||||
}
|
||||
|
||||
task coroutines_coroutineContext1(type: RunKonanTest) {
|
||||
goldValue = "EmptyCoroutineContext\n"
|
||||
source = "codegen/coroutines/coroutineContext1.kt"
|
||||
}
|
||||
|
||||
task coroutines_coroutineContext2(type: RunKonanTest) {
|
||||
goldValue = "EmptyCoroutineContext\n"
|
||||
source = "codegen/coroutines/coroutineContext2.kt"
|
||||
}
|
||||
|
||||
task AbstractMutableCollection(type: RunKonanTest) {
|
||||
expectedExitStatus = 0
|
||||
source = "runtime/collections/AbstractMutableCollection.kt"
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package codegen.coroutines.coroutineContext1
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation<Any?> {
|
||||
companion object : EmptyContinuation()
|
||||
override fun resume(value: Any?) {}
|
||||
override fun resumeWithException(exception: Throwable) { throw exception }
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
@Test fun runTest() {
|
||||
builder { println(coroutineContext) }
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package codegen.coroutines.coroutineContext2
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
open class EmptyContinuation(override val context: CoroutineContext = EmptyCoroutineContext) : Continuation<Any?> {
|
||||
companion object : EmptyContinuation()
|
||||
override fun resume(value: Any?) {}
|
||||
override fun resumeWithException(exception: Throwable) { throw exception }
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
suspend fun foo() = coroutineContext
|
||||
|
||||
@Test fun runTest() {
|
||||
builder { println(foo()) }
|
||||
}
|
||||
@@ -33,6 +33,11 @@ internal inline fun <T> Continuation<T>.intercepted(): Continuation<T> =
|
||||
@PublishedApi
|
||||
internal external fun <T> getContinuation(): Continuation<T>
|
||||
|
||||
@kotlin.internal.InlineOnly
|
||||
@PublishedApi
|
||||
internal inline suspend fun getCoroutineContext(): CoroutineContext =
|
||||
getContinuation<Any?>().context
|
||||
|
||||
@Intrinsic
|
||||
@PublishedApi
|
||||
internal external suspend fun <T> returnIfSuspended(@Suppress("UNUSED_PARAMETER") argument: Any?): T
|
||||
|
||||
Reference in New Issue
Block a user