JVM_IR: Support inline suspend lambdas
This commit is contained in:
@@ -13,8 +13,10 @@ import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.*
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure
|
||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor
|
||||
import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
@@ -190,12 +192,14 @@ abstract class ExpressionLambda(isCrossInline: Boolean) : LambdaInfo(isCrossInli
|
||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner<*>) {
|
||||
node = sourceCompiler.generateLambdaBody(this)
|
||||
}
|
||||
|
||||
abstract fun getInlineSuspendLambdaViewDescriptor(): FunctionDescriptor
|
||||
}
|
||||
|
||||
class PsiExpressionLambda(
|
||||
expression: KtExpression,
|
||||
typeMapper: KotlinTypeMapper,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
private val typeMapper: KotlinTypeMapper,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
isCrossInline: Boolean,
|
||||
override val isBoundCallableReference: Boolean
|
||||
) : ExpressionLambda(isCrossInline) {
|
||||
@@ -292,4 +296,12 @@ class PsiExpressionLambda(
|
||||
|
||||
val isPropertyReference: Boolean
|
||||
get() = propertyReferenceInfo != null
|
||||
|
||||
override fun getInlineSuspendLambdaViewDescriptor(): FunctionDescriptor {
|
||||
return getOrCreateJvmSuspendFunctionView(
|
||||
invokeMethodDescriptor,
|
||||
languageVersionSettings.isReleaseCoroutines(),
|
||||
typeMapper.bindingContext
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -236,13 +236,16 @@ class MethodInliner(
|
||||
var coroutineDesc = desc
|
||||
val actualInvokeDescriptor: FunctionDescriptor
|
||||
if (info.invokeMethodDescriptor.isSuspend) {
|
||||
actualInvokeDescriptor = getOrCreateJvmSuspendFunctionView(info.invokeMethodDescriptor, inliningContext.state)
|
||||
actualInvokeDescriptor = (info as ExpressionLambda).getInlineSuspendLambdaViewDescriptor()
|
||||
val parametersSize = actualInvokeDescriptor.valueParameters.size +
|
||||
(if (actualInvokeDescriptor.extensionReceiverParameter != null) 1 else 0)
|
||||
// And here we expect invoke(...Ljava/lang/Object;) be replaced with invoke(...Lkotlin/coroutines/Continuation;)
|
||||
// if this does not happen, insert fake continuation, since we could not have one yet.
|
||||
val argumentTypes = Type.getArgumentTypes(desc)
|
||||
if (argumentTypes.size != parametersSize) {
|
||||
if (argumentTypes.size != parametersSize &&
|
||||
// TODO: Workaround IR-related problem. In IR we already have lowered lambda, while in Old BE we don't.
|
||||
!(inliningContext.root.state.isIrBackend && desc.endsWith("Lkotlin/coroutines/Continuation;)Ljava/lang/Object;"))
|
||||
) {
|
||||
addFakeContinuationMarker(this)
|
||||
coroutineDesc = Type.getMethodDescriptor(Type.getReturnType(desc), *argumentTypes, AsmTypes.OBJECT_TYPE)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -196,7 +196,7 @@ class GenerationState private constructor(
|
||||
)
|
||||
val bindingContext: BindingContext = bindingTrace.bindingContext
|
||||
val mainFunctionDetector = MainFunctionDetector(bindingContext, languageVersionSettings)
|
||||
private val isIrBackend = configuration.get(JVMConfigurationKeys.IR) ?: false
|
||||
val isIrBackend = configuration.get(JVMConfigurationKeys.IR) ?: false
|
||||
val typeMapper: KotlinTypeMapper = KotlinTypeMapper(
|
||||
this.bindingContext,
|
||||
classBuilderMode,
|
||||
|
||||
Reference in New Issue
Block a user