diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt index a037b099a5f..a578e31c662 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt @@ -64,24 +64,23 @@ abstract class AbstractCoroutineCodegen( protected val classDescriptor = closureContext.contextDescriptor protected val languageVersionSettings = outerExpressionCodegen.state.languageVersionSettings - protected val methodToImplement = - createImplMethod( - INVOKE_SUSPEND_METHOD_NAME, - SUSPEND_CALL_RESULT_NAME to classDescriptor.module.getResult(classDescriptor.builtIns.anyType) - ) - - private fun createImplMethod(name: String, vararg parameters: Pair) = + protected val methodToImplement: FunctionDescriptor = SimpleFunctionDescriptorImpl.create( - classDescriptor, Annotations.EMPTY, Name.identifier(name), CallableMemberDescriptor.Kind.DECLARATION, + classDescriptor, Annotations.EMPTY, Name.identifier(INVOKE_SUSPEND_METHOD_NAME), CallableMemberDescriptor.Kind.DECLARATION, funDescriptor.source ).apply { initialize( null, classDescriptor.thisAsReceiverParameter, emptyList(), - parameters.withIndex().map { (index, nameAndType) -> - createValueParameterForDoResume(Name.identifier(nameAndType.first), nameAndType.second, index) - }, + listOf( + ValueParameterDescriptorImpl( + this, null, 0, Annotations.EMPTY, Name.identifier(SUSPEND_CALL_RESULT_NAME), + classDescriptor.module.getResult(classDescriptor.builtIns.anyType), + declaresDefaultValue = false, isCrossinline = false, isNoinline = false, varargElementType = null, + SourceElement.NO_SOURCE + ) + ), builtIns.nullableAnyType, Modality.FINAL, DescriptorVisibilities.PUBLIC, @@ -89,15 +88,6 @@ abstract class AbstractCoroutineCodegen( ) } - private fun FunctionDescriptor.createValueParameterForDoResume(name: Name, type: KotlinType, index: Int) = - ValueParameterDescriptorImpl( - this, null, index, Annotations.EMPTY, name, - type, - declaresDefaultValue = false, isCrossinline = false, - isNoinline = false, - varargElementType = null, source = SourceElement.NO_SOURCE - ) - override fun generateConstructor(): Method { val args = calculateConstructorParameters(typeMapper, languageVersionSettings, closure, asmType) val argTypes = args.map { it.fieldType }.plus(CONTINUATION_ASM_TYPE).toTypedArray() @@ -119,7 +109,7 @@ abstract class AbstractCoroutineCodegen( iv.iconst(funDescriptor.arity) } - iv.load(argTypes.map { it.size }.sum(), AsmTypes.OBJECT_TYPE) + iv.load(argTypes.sumOf { it.size }, AsmTypes.OBJECT_TYPE) val parameters = if (passArityToSuperClass) @@ -392,7 +382,7 @@ class CoroutineCodegenForLambda private constructor( if (generateErasedCreate) { load(allFunctionParameters().size + 1, AsmTypes.OBJECT_TYPE) } else { - load(allFunctionParameters().map { typeMapper.mapType(it.type).size }.sum() + 1, AsmTypes.OBJECT_TYPE) + load(allFunctionParameters().sumOf { typeMapper.mapType(it.type).size } + 1, AsmTypes.OBJECT_TYPE) } } @@ -482,7 +472,9 @@ class CoroutineCodegenForLambda private constructor( val name = if (parameter is ReceiverParameterDescriptor) - DescriptorAsmUtil.getNameForReceiverParameter(originalSuspendFunctionDescriptor, bindingContext, languageVersionSettings) + DescriptorAsmUtil.getNameForReceiverParameter( + originalSuspendFunctionDescriptor, bindingContext, languageVersionSettings + ) else (getNameForDestructuredParameterOrNull(parameter as ValueParameterDescriptor) ?: parameter.name.asString()) val label = Label() @@ -705,38 +697,6 @@ class CoroutineCodegenForNamedFunction private constructor( ) } - private fun generateGetLabelMethod() { - val mv = v.newMethod( - JvmDeclarationOrigin.NO_ORIGIN, - Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL or AsmUtil.NO_FLAG_PACKAGE_PRIVATE, - "getLabel", - Type.getMethodDescriptor(Type.INT_TYPE), - null, - null - ) - - mv.visitCode() - labelFieldStackValue.put(Type.INT_TYPE, InstructionAdapter(mv)) - mv.visitInsn(Opcodes.IRETURN) - mv.visitEnd() - } - - private fun generateSetLabelMethod() { - val mv = v.newMethod( - JvmDeclarationOrigin.NO_ORIGIN, - Opcodes.ACC_SYNTHETIC or Opcodes.ACC_FINAL or AsmUtil.NO_FLAG_PACKAGE_PRIVATE, - "setLabel", - Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE), - null, - null - ) - - mv.visitCode() - labelFieldStackValue.store(StackValue.local(1, Type.INT_TYPE), InstructionAdapter(mv)) - mv.visitInsn(Opcodes.RETURN) - mv.visitEnd() - } - override fun generateKotlinMetadataAnnotation() { val publicAbi = InlineUtil.isInPublicInlineScope(classDescriptor) writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, publicAbi, 0) { av -> diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt index 9aab6637fe4..5c7809aee17 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -1110,7 +1110,7 @@ inline fun withInstructionAdapter(block: InstructionAdapter.() -> Unit): InsnLis return tmpMethodNode.instructions } -fun Type.normalize() = +fun Type.normalize(): Type = when (sort) { Type.ARRAY, Type.OBJECT -> AsmTypes.OBJECT_TYPE else -> this @@ -1156,7 +1156,7 @@ internal operator fun List.contains(insn: AbstractInsnNode): Bo any { insn in it } internal fun getLastParameterIndex(desc: String, access: Int) = - Type.getArgumentTypes(desc).dropLast(1).map { it.size }.sum() + (if (!isStatic(access)) 1 else 0) + Type.getArgumentTypes(desc).dropLast(1).sumOf { it.size } + (if (!isStatic(access)) 1 else 0) private fun getParameterTypesForCoroutineConstructor(desc: String, hasDispatchReceiver: Boolean, thisName: String) = listOfNotNull(if (!hasDispatchReceiver) null else Type.getObjectType(thisName)).toTypedArray() + @@ -1192,6 +1192,7 @@ internal fun replaceFakeContinuationsWithRealOnes(methodNode: MethodNode, contin } } +@Suppress("unused") private fun MethodNode.nodeTextWithLiveness(liveness: List): String = liveness.zip(this.instructions.asSequence().toList()).joinToString("\n") { (a, b) -> "$a|${b.insnText}" } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt index bde418acfb0..99a01c893ab 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt @@ -12,8 +12,6 @@ import org.jetbrains.kotlin.codegen.inline.addFakeContinuationConstructorCallMar import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.codegen.inline.preprocessSuspendMarkers import org.jetbrains.kotlin.codegen.state.GenerationState -import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.psi.KtFunction @@ -37,9 +35,7 @@ class SuspendFunctionGenerationStrategy( private val containingClassInternalName: String, private val functionCodegen: FunctionCodegen ) : FunctionGenerationStrategy.CodegenBased(state) { - private lateinit var codegen: ExpressionCodegen - private val languageVersionSettings: LanguageVersionSettings = state.configuration.languageVersionSettings private val classBuilderForCoroutineState by lazy { state.factory.newVisitor( @@ -61,7 +57,9 @@ class SuspendFunctionGenerationStrategy( } val stateMachineBuilder = createStateMachineBuilder(mv, access, name, desc) if (originalSuspendDescriptor.isInline) { - return SuspendForInlineCopyingMethodVisitor(stateMachineBuilder, access, name, desc, functionCodegen::newMethod, keepAccess = false) + return SuspendForInlineCopyingMethodVisitor( + stateMachineBuilder, access, name, desc, functionCodegen::newMethod, keepAccess = false + ) } if (state.bindingContext[CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA, originalSuspendDescriptor] == true) { return AddConstructorCallForCoroutineRegeneration( @@ -70,7 +68,6 @@ class SuspendFunctionGenerationStrategy( containingClassInternalName, originalSuspendDescriptor.dispatchReceiverParameter != null, containingClassInternalNameOrNull(), - languageVersionSettings ) } return stateMachineBuilder @@ -136,7 +133,6 @@ class SuspendFunctionGenerationStrategy( private val containingClassInternalName: String, private val needDispatchReceiver: Boolean, private val internalNameForDispatchReceiver: String?, - private val languageVersionSettings: LanguageVersionSettings ) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) { private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState) override fun performTransformations(methodNode: MethodNode) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt index 4ec1597bcb9..5e5699b965a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt @@ -17,7 +17,6 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.inline.addFakeContinuationMarker import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper -import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.coroutines.isSuspendLambda import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations @@ -146,9 +145,9 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor( ExpressionValueArgument(arguments) ) - val newTypeArguments = newCandidateDescriptor.typeParameters.map { - Pair(it, typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection()) - }.toMap() + val newTypeArguments = newCandidateDescriptor.typeParameters.associateWith { + typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection() + } newCall.setSubstitutor( TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor() @@ -440,7 +439,9 @@ fun FunctionDescriptor.isSuspendLambdaOrLocalFunction() = this.isSuspend && when else -> false } -fun FunctionDescriptor.isLocalSuspendFunctionNotSuspendLambda() = isSuspendLambdaOrLocalFunction() && this !is AnonymousFunctionDescriptor +fun FunctionDescriptor.isLocalSuspendFunctionNotSuspendLambda(): Boolean = + isSuspendLambdaOrLocalFunction() && this !is AnonymousFunctionDescriptor + @JvmField val CONTINUATION_ASM_TYPE = StandardNames.CONTINUATION_INTERFACE_FQ_NAME.topLevelClassAsmType() @@ -451,4 +452,4 @@ fun FunctionDescriptor.isInvokeSuspendOfLambda(): Boolean { name.asString() != INVOKE_SUSPEND_METHOD_NAME ) return false return containingDeclaration is SyntheticClassDescriptorForLambda -} \ No newline at end of file +} diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt index 46394d8e651..e35af3b31b7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/coroutines/CoroutineTransformer.kt @@ -30,6 +30,7 @@ class CoroutineTransformer( private val superClassName: String ) { private val state = inliningContext.state + // If we inline into inline function, we should generate both method with state-machine for Java interop and method without // state-machine for further transformation/inlining. private val generateForInline = inliningContext.callSiteInfo.isInlineOrInsideInline @@ -152,7 +153,7 @@ class CoroutineTransformer( context.continuationBuilders[continuationClassName] = classBuilder } - fun unregisterClassBuilder(continuationClassName: String) = + private fun unregisterClassBuilder(continuationClassName: String): ClassBuilder? = (inliningContext as RegeneratedClassContext).continuationBuilders.remove(continuationClassName) // If tail-call optimization took place, we do not need continuation class anymore, unless it is used by $$forInline method