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
This commit is contained in:
Denis Zharkov
2017-04-19 11:21:03 +03:00
parent 7271ca0b72
commit 0cd80d8b0e
6 changed files with 25 additions and 34 deletions
@@ -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);
@@ -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;
@@ -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)
}
@@ -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<out String>?
) = 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<MethodInsnNode>().firstOrNull {
it.owner == COROUTINE_MARKER_OWNER && it.name == ACTUAL_COROUTINE_START_MARKER_NAME
}
@@ -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"
@@ -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,