From 0927dfd0702bc5d5bbfbd16a56394e12e051da53 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Fri, 8 Jun 2018 12:22:13 +0300 Subject: [PATCH] Fixed coroutines --- .../jetbrains/kotlin/backend/konan/ir/Ir.kt | 18 +++++++++-- .../backend/konan/lower/FunctionInlining.kt | 30 ++++++++++++------- .../main/kotlin/konan/internal/Coroutines.kt | 10 +++++++ 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt index 7e088238a73..18538d27238 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt @@ -16,6 +16,9 @@ package org.jetbrains.kotlin.backend.konan.ir +import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME +import org.jetbrains.kotlin.backend.common.INTERCEPTED_NAME +import org.jetbrains.kotlin.backend.common.SUSPEND_COROUTINE_UNINTERCEPTED_OR_RETURN_NAME import org.jetbrains.kotlin.backend.common.atMostOne import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Symbols @@ -27,6 +30,8 @@ import org.jetbrains.kotlin.backend.konan.llvm.findMainEntryPoint 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.languageVersionSettings import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.declarations.* @@ -277,11 +282,20 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable): Sym val getContinuation = symbolTable.referenceSimpleFunction( context.getInternalFunctions("getContinuation").single()) + val intercepted = symbolTable.referenceSimpleFunction( + context.getInternalFunctions("intercepted").single()) + + val suspendCoroutineUninterceptedOrReturn = symbolTable.referenceSimpleFunction( + context.getInternalFunctions("suspendCoroutineUninterceptedOrReturn").single()) + + private val coroutinesPackage = context.builtIns.builtInsModule.getPackage( + context.config.configuration.languageVersionSettings.coroutinesIntrinsicsPackageFqName()).memberScope + override val coroutineImpl = symbolTable.referenceClass(context.getInternalClass("CoroutineImpl")) override val coroutineSuspendedGetter = symbolTable.referenceSimpleFunction( - builtInsPackage("kotlin", "coroutines", "experimental", "intrinsics") - .getContributedVariables(Name.identifier("COROUTINE_SUSPENDED"), NoLookupLocation.FROM_BACKEND) + coroutinesPackage + .getContributedVariables(COROUTINE_SUSPENDED_NAME, NoLookupLocation.FROM_BACKEND) .single().getter!! ) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt index 6663e0bec3d..4c1bbae493a 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt @@ -18,30 +18,35 @@ package org.jetbrains.kotlin.backend.konan.lower -import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext -import org.jetbrains.kotlin.backend.common.ScopeWithIr +import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.common.lower.createIrBuilder -import org.jetbrains.kotlin.backend.common.reportWarning import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining import org.jetbrains.kotlin.backend.konan.descriptors.propertyIfAccessor import org.jetbrains.kotlin.backend.konan.descriptors.resolveFakeOverride import org.jetbrains.kotlin.backend.konan.ir.DeserializerDriver +import org.jetbrains.kotlin.backend.konan.llvm.types +import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.builders.irCall -import org.jetbrains.kotlin.ir.builders.irGet -import org.jetbrains.kotlin.ir.builders.irReturn +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.builders.* +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.getDefault +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl +import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl +import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.createValueSymbol import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -60,6 +65,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW private val deserializer = DeserializerDriver(context) private val globalSubstituteMap = mutableMapOf() + private val languageVersionSettings = context.config.configuration.languageVersionSettings //-------------------------------------------------------------------------// @@ -77,7 +83,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW val functionDescriptor = irCall.descriptor if (!functionDescriptor.needsInlining) return irCall // This call does not need inlining. - val functionDeclaration = getFunctionDeclaration(irCall) // Get declaration of the function to be inlined. + val functionDeclaration = getFunctionDeclaration(functionDescriptor) // Get declaration of the function to be inlined. if (functionDeclaration == null) { // We failed to get the declaration. val message = "Inliner failed to obtain function declaration: " + functionDescriptor.fqNameSafe.toString() @@ -92,10 +98,12 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW //-------------------------------------------------------------------------// - private fun getFunctionDeclaration(irCall: IrCall): IrFunction? { - - val functionDescriptor = irCall.descriptor - val originalDescriptor = functionDescriptor.resolveFakeOverride().original + private fun getFunctionDeclaration(descriptor: FunctionDescriptor): IrFunction? { + val originalDescriptor = descriptor.resolveFakeOverride().original + if (originalDescriptor.isBuiltInIntercepted(languageVersionSettings)) + return getFunctionDeclaration(context.ir.symbols.intercepted.descriptor) + if (originalDescriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings)) + return getFunctionDeclaration(context.ir.symbols.suspendCoroutineUninterceptedOrReturn.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. diff --git a/runtime/src/main/kotlin/konan/internal/Coroutines.kt b/runtime/src/main/kotlin/konan/internal/Coroutines.kt index 6ffb8e664c1..4c66378844c 100644 --- a/runtime/src/main/kotlin/konan/internal/Coroutines.kt +++ b/runtime/src/main/kotlin/konan/internal/Coroutines.kt @@ -19,6 +19,16 @@ package konan.internal import kotlin.coroutines.experimental.* import kotlin.coroutines.experimental.intrinsics.* +@kotlin.internal.InlineOnly +@PublishedApi +internal inline suspend fun suspendCoroutineUninterceptedOrReturn(crossinline block: (Continuation) -> Any?): T = + returnIfSuspended(block(getContinuation())) + +@kotlin.internal.InlineOnly +@PublishedApi +internal inline fun Continuation.intercepted(): Continuation = + normalizeContinuation(this) + @Intrinsic @PublishedApi internal external fun getContinuation(): Continuation