From 0cd80d8b0e4c695370d3691421dfa69a04c0c6ca Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 19 Apr 2017 11:21:03 +0300 Subject: [PATCH] Get rid of class builder factory for coroutines Initially it was a sort of hack: introducing another interception class builder factory that will process all functions. To differentiate suspend functions from the common ones the fake annotation class has been used. The problem is that now we should inject the different class builder into the CoroutineTransformerMethodVisitor: we need class builder for anonymous class representing state for named function while currently it will be the one for the class where the named function is defined --- .../kotlin/codegen/FunctionCodegen.java | 18 ++++++++----- .../codegen/FunctionGenerationStrategy.java | 5 +++- .../codegen/coroutines/CoroutineCodegen.kt | 6 ++++- ...t => CoroutineTransformerMethodVisitor.kt} | 26 +++---------------- .../coroutines/coroutineCodegenUtil.kt | 2 -- .../kotlin/codegen/state/GenerationState.kt | 2 -- 6 files changed, 25 insertions(+), 34 deletions(-) rename compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/{CoroutineTransformationClassBuilder.kt => CoroutineTransformerMethodVisitor.kt} (94%) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 23a19d55e12..0f172467b6a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -200,12 +200,18 @@ public class FunctionCodegen { // Native methods are only defined in facades and do not need package part implementations return; } - MethodVisitor mv = v.newMethod(origin, - flags, - asmMethod.getName(), - asmMethod.getDescriptor(), - jvmSignature.getGenericsSignature(), - getThrownExceptions(functionDescriptor, typeMapper)); + MethodVisitor mv = + strategy.wrapMethodVisitor( + v.newMethod(origin, + flags, + asmMethod.getName(), + asmMethod.getDescriptor(), + jvmSignature.getGenericsSignature(), + getThrownExceptions(functionDescriptor, typeMapper) + ), + flags, asmMethod.getName(), + asmMethod.getDescriptor() + ); if (CodegenContextUtil.isImplClassOwner(owner)) { v.getSerializationBindings().put(METHOD_FOR_FUNCTION, CodegenUtilKt.unwrapFrontendVersion(functionDescriptor), asmMethod); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionGenerationStrategy.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionGenerationStrategy.java index a5410c95993..70e647d1220 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionGenerationStrategy.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionGenerationStrategy.java @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.codegen.context.MethodContext; import org.jetbrains.kotlin.codegen.state.GenerationState; -import org.jetbrains.kotlin.descriptors.CallableDescriptor; import org.jetbrains.kotlin.psi.KtDeclarationWithBody; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; import org.jetbrains.org.objectweb.asm.MethodVisitor; @@ -33,6 +32,10 @@ public abstract class FunctionGenerationStrategy { @NotNull MemberCodegen parentCodegen ); + public MethodVisitor wrapMethodVisitor(@NotNull MethodVisitor mv, int access, @NotNull String name, @NotNull String desc) { + return mv; + } + public static class FunctionDefault extends CodegenBased { private final KtDeclarationWithBody declaration; 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 1dfb9525cf8..160d14e0370 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineCodegen.kt @@ -306,8 +306,12 @@ class CoroutineCodegen private constructor( OtherOrigin(element), doResumeDescriptor, object : FunctionGenerationStrategy.FunctionDefault(state, element as KtDeclarationWithBody) { + + override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor { + return CoroutineTransformerMethodVisitor(mv, access, name, desc, null, null, v) + } + override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) { - codegen.v.visitAnnotation(CONTINUATION_METHOD_ANNOTATION_DESC, true).visitEnd() codegen.initializeCoroutineParameters() super.doGenerateBody(codegen, signature) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformationClassBuilder.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt similarity index 94% rename from compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformationClassBuilder.kt rename to compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt index 630ce80c707..9ccd4767b9b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformationClassBuilder.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -17,7 +17,10 @@ package org.jetbrains.kotlin.codegen.coroutines import com.intellij.util.containers.Stack -import org.jetbrains.kotlin.codegen.* +import org.jetbrains.kotlin.codegen.AsmUtil +import org.jetbrains.kotlin.codegen.ClassBuilder +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.codegen.TransformationMethodVisitor import org.jetbrains.kotlin.codegen.optimization.DeadCodeEliminationMethodTransformer import org.jetbrains.kotlin.codegen.optimization.FixStackWithLabelNormalizationMethodTransformer import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue @@ -34,24 +37,6 @@ import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.tree.* -class CoroutineTransformationClassBuilder(private val delegate: ClassBuilder) : DelegatingClassBuilder() { - override fun getDelegate() = delegate - - override fun newMethod( - origin: JvmDeclarationOrigin, - access: Int, name: String, - desc: String, signature: - String?, - exceptions: Array? - ) = CoroutineTransformerMethodVisitor( - delegate.newMethod(origin, access, name, desc, signature, exceptions), - access, name, desc, signature, exceptions, this) -} - -class CoroutineTransformerClassBuilderFactory(delegate: ClassBuilderFactory) : DelegatingClassBuilderFactory(delegate) { - override fun newClassBuilder(origin: JvmDeclarationOrigin) = CoroutineTransformationClassBuilder(delegate.newClassBuilder(origin)) -} - class CoroutineTransformerMethodVisitor( delegate: MethodVisitor, access: Int, @@ -62,9 +47,6 @@ class CoroutineTransformerMethodVisitor( private val classBuilder: ClassBuilder ) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) { override fun performTransformations(methodNode: MethodNode) { - if (methodNode.visibleAnnotations?.none { it.desc == CONTINUATION_METHOD_ANNOTATION_DESC } != false) return - methodNode.visibleAnnotations.removeAll { it.desc == CONTINUATION_METHOD_ANNOTATION_DESC } - val customCoroutineStartMarker = methodNode.instructions.toArray().filterIsInstance().firstOrNull { it.owner == COROUTINE_MARKER_OWNER && it.name == ACTUAL_COROUTINE_START_MARKER_NAME } 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 c4b7c5c59a4..37c43e63a89 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutineCodegenUtil.kt @@ -53,8 +53,6 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.tree.MethodNode // These classes do not actually exist at runtime -val CONTINUATION_METHOD_ANNOTATION_DESC = "Lkotlin/ContinuationMethod;" - const val COROUTINE_MARKER_OWNER = "kotlin/coroutines/Markers" const val BEFORE_SUSPENSION_POINT_MARKER_NAME = "beforeSuspensionPoint" const val AFTER_SUSPENSION_POINT_MARKER_NAME = "afterSuspensionPoint" diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index 94369b0bf1f..414aba2dec0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.codegen.`when`.MappingsClassesForWhenByEnum import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.context.CodegenContext import org.jetbrains.kotlin.codegen.context.RootContext -import org.jetbrains.kotlin.codegen.coroutines.CoroutineTransformerClassBuilderFactory import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension import org.jetbrains.kotlin.codegen.inline.InlineCache import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods @@ -177,7 +176,6 @@ class GenerationState @JvmOverloads constructor( this.interceptedBuilderFactory = builderFactory .wrapWith( { OptimizationClassBuilderFactory(it, configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false)) }, - ::CoroutineTransformerClassBuilderFactory, { BuilderFactoryForDuplicateSignatureDiagnostics( it, this.bindingContext, diagnostics, fileClassesProvider, this.moduleName,