JVM: Fix usage of ClassBuilder API in AnonymousObjectTransformer

This commit is contained in:
Steven Schäfer
2021-03-23 15:22:21 +01:00
committed by Alexander Udalov
parent c156613141
commit 1b5214a2dc
10 changed files with 72 additions and 14 deletions
@@ -81,7 +81,7 @@ class AnonymousObjectTransformer(
debugMetadataAnnotation = AnnotationNode(desc)
return debugMetadataAnnotation
}
return super.visitAnnotation(desc, visible)
return classBuilder.newAnnotation(desc, visible)
}
override fun visitMethod(
@@ -197,9 +197,8 @@ class AnonymousObjectTransformer(
classBuilder.visitSource(sourceInfo!!, debugInfo)
}
val visitor = classBuilder.visitor
innerClassNodes.forEach { node ->
visitor.visitInnerClass(node.name, node.outerName, node.innerName, node.access)
classBuilder.visitInnerClass(node.name, node.outerName, node.innerName, node.access)
}
if (header != null) {
@@ -208,12 +207,12 @@ class AnonymousObjectTransformer(
// debugMetadataAnnotation can be null in LV < 1.3
if (putDebugMetadata && debugMetadataAnnotation != null) {
visitor.visitAnnotation(debugMetadataAnnotation!!.desc, true).also {
classBuilder.newAnnotation(debugMetadataAnnotation!!.desc, true).also {
debugMetadataAnnotation!!.accept(it)
}
}
writeOuterInfo(visitor)
writeOuterInfo(classBuilder)
if (inliningContext.generateAssertField && fieldNames.none { it.key == ASSERTIONS_DISABLED_FIELD_NAME }) {
val clInitBuilder = classBuilder.newMethod(NO_ORIGIN, Opcodes.ACC_STATIC, "<clinit>", "()V", null, null)
@@ -234,7 +233,13 @@ class AnonymousObjectTransformer(
private fun writeTransformedMetadata(header: KotlinClassHeader, classBuilder: ClassBuilder) {
// The transformed anonymous object becomes part of the public ABI if it is inside of a public inline function.
val publicAbi = inliningContext.callSiteInfo.isInPublicInlineScope
writeKotlinMetadata(classBuilder, state, header.kind, publicAbi, header.extraInt and JvmAnnotationNames.METADATA_PUBLIC_ABI_FLAG.inv()) action@{ av ->
writeKotlinMetadata(
classBuilder,
state,
header.kind,
publicAbi,
header.extraInt and JvmAnnotationNames.METADATA_PUBLIC_ABI_FLAG.inv()
) action@{ av ->
val (newProto, newStringTable) = transformMetadata(header) ?: run {
val data = header.data
val strings = header.strings
@@ -277,12 +282,12 @@ class AnonymousObjectTransformer(
}
}
private fun writeOuterInfo(visitor: ClassVisitor) {
private fun writeOuterInfo(classBuilder: ClassBuilder) {
val info = inliningContext.callSiteInfo
// Since $$forInline functions are not generated if retransformation is the last one (i.e. call site is not inline)
// link to the function in OUTERCLASS field becomes invalid. However, since $$forInline function always has no-inline
// companion without the suffix, use it.
visitor.visitOuterClass(info.ownerClassName, info.method.name.removeSuffix(FOR_INLINE_SUFFIX), info.method.descriptor)
classBuilder.visitOuterClass(info.ownerClassName, info.method.name.removeSuffix(FOR_INLINE_SUFFIX), info.method.descriptor)
}
private fun inlineMethodAndUpdateGlobalResult(
@@ -93,7 +93,7 @@ open class InliningContext(
newTypeMappings: MutableMap<String, String?>,
callSiteInfo: InlineCallSiteInfo,
transformationInfo: TransformationInfo
): InliningContext = RegeneratedClassContext(
): RegeneratedClassContext = RegeneratedClassContext(
this, state, generator, TypeRemapper.createFrom(typeRemapper, newTypeMappings),
lambdaInfo, callSiteInfo, transformationInfo
)
@@ -193,6 +193,10 @@ class MethodInliner(
ReifiedTypeInliner.putNeedClassReificationMarker(mv)
result.reifiedTypeParametersUsages.mergeAll(transformResult.reifiedTypeParametersUsages)
}
for (classBuilder in childInliningContext.continuationBuilders.values) {
classBuilder.done()
}
} else {
result.addNotChangedClass(oldClassName)
}
@@ -11,10 +11,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.ClassBuilder;
import org.jetbrains.kotlin.codegen.DelegatingClassBuilder;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import org.jetbrains.org.objectweb.asm.ClassVisitor;
import org.jetbrains.org.objectweb.asm.FieldVisitor;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.commons.*;
import org.jetbrains.org.objectweb.asm.commons.FieldRemapper;
@@ -25,6 +22,7 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
private final ClassBuilder builder;
private final Remapper remapper;
private final Map<String, FieldVisitor> spilledCoroutineVariables = new HashMap<>();
private ClassVisitor visitor = null;
public RemappingClassBuilder(@NotNull ClassBuilder builder, @NotNull Remapper remapper) {
this.builder = builder;
@@ -125,9 +123,28 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
return new AnnotationRemapper(builder.newAnnotation(remapper.mapDesc(desc), visible), remapper);
}
@Override
public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
getVisitor().visitInnerClass(name, outerName, innerName, access);
}
@Override
public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
getVisitor().visitOuterClass(owner, name, desc);
}
@NotNull
@Override
public RecordComponentVisitor newRecordComponent(@NotNull String name, @NotNull String desc, @Nullable String signature) {
return getVisitor().visitRecordComponent(name, desc, signature);
}
@Override
@NotNull
public ClassVisitor getVisitor() {
return new ClassRemapper(builder.getVisitor(), remapper);
if (visitor == null) {
visitor = new ClassRemapper(builder.getVisitor(), remapper);
}
return visitor;
}
}
@@ -1,6 +1,7 @@
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class CrossinlineKt$box$1$filter$$inlined$source$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$box$1$filter$$inlined$source$1.consume(LSink;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field L$1: java.lang.Object
@@ -15,6 +16,7 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1$1 {
@kotlin.Metadata
public final class CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$box$1$filter$$inlined$source$1$lambda$1.send(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -55,6 +57,7 @@ public final class CrossinlineKt$box$1$filter$$inlined$source$1 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class CrossinlineKt$box$1$fold$$inlined$consumeEach$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$box$1$fold$$inlined$consumeEach$1.send(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field label: int
@@ -83,6 +86,7 @@ public final class CrossinlineKt$box$1$fold$$inlined$consumeEach$1 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1.consume(LSink;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field L$1: java.lang.Object
@@ -174,6 +178,7 @@ public final class CrossinlineKt$consumeEach$2 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class CrossinlineKt$filter$$inlined$source$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$filter$$inlined$source$1.consume(LSink;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field L$1: java.lang.Object
@@ -188,6 +193,7 @@ public final class CrossinlineKt$filter$$inlined$source$1$1 {
@kotlin.Metadata
public final class CrossinlineKt$filter$$inlined$source$1$lambda$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$filter$$inlined$source$1$lambda$1.send(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -228,6 +234,7 @@ public final class CrossinlineKt$filter$$inlined$source$1 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class CrossinlineKt$fold$$inlined$consumeEach$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$fold$$inlined$consumeEach$1.send(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field label: int
@@ -269,6 +276,7 @@ public final class CrossinlineKt$fold$1 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class CrossinlineKt$range$$inlined$source$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$range$$inlined$source$1.consume(LSink;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field I$0: int
field I$1: int
@@ -1,6 +1,7 @@
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$box$1$invokeSuspend$$inlined$filter$1.consume(LSink;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field label: int
@@ -91,6 +92,7 @@ public final class CrossinlineKt$consumeEach$2 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class CrossinlineKt$filter$$inlined$source$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$filter$$inlined$source$1.consume(LSink;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field label: int
@@ -117,6 +119,7 @@ public final class CrossinlineKt$filter$$inlined$source$1 {
@kotlin.Metadata
public final class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1.send(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -144,6 +147,7 @@ public final class CrossinlineKt$filter$lambda-3$$inlined$consumeEach$1 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class CrossinlineKt$fold$$inlined$consumeEach$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$fold$$inlined$consumeEach$1.send(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field label: int
@@ -185,6 +189,7 @@ final class CrossinlineKt$fold$1 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class CrossinlineKt$range$$inlined$source$1$1 {
// source: 'crossinline.kt'
enclosing method CrossinlineKt$range$$inlined$source$1.consume(LSink;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field I$0: int
field I$1: int
@@ -115,6 +115,7 @@ public final class flow/InnerObjectRetransformationKt$flow$1 {
@kotlin.Metadata
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1 {
// source: 'innerObjectRetransformation.kt'
enclosing method flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1.collect(Lflow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -140,6 +141,7 @@ public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1 {
@kotlin.Metadata
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2$1 {
// source: 'innerObjectRetransformation.kt'
enclosing method flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$2.collect(Lflow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -116,6 +116,7 @@ public final class flow/InnerObjectRetransformationKt$flow$1 {
@kotlin.Metadata
public final class flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1$1 {
// source: 'innerObjectRetransformation.kt'
enclosing method flow/InnerObjectRetransformationKt$flowWith$$inlined$flow$1.collect(Lflow/FlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -81,6 +81,7 @@ public final class TcoContinuationKt$foo$$inlined$flow$1 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class TcoContinuationKt$foo$$inlined$map$1$2$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$foo$$inlined$map$1$2.emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field label: int
@@ -116,6 +117,7 @@ public final class TcoContinuationKt$foo$$inlined$map$1 {
@kotlin.Metadata
public final class TcoContinuationKt$map$$inlined$transform$1$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$map$$inlined$transform$1.collect(LFlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -129,6 +131,7 @@ public final class TcoContinuationKt$map$$inlined$transform$1$1 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class TcoContinuationKt$map$$inlined$transform$1$2$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$map$$inlined$transform$1$2.emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field label: int
@@ -168,6 +171,7 @@ public final class TcoContinuationKt$map$$inlined$transform$1 {
@kotlin.Metadata
public final class TcoContinuationKt$map$$inlined$transform$2$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$map$$inlined$transform$2.collect(LFlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -181,6 +185,7 @@ public final class TcoContinuationKt$map$$inlined$transform$2$1 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class TcoContinuationKt$map$$inlined$transform$2$2$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$map$$inlined$transform$2$2.emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field label: int
@@ -220,6 +225,7 @@ public final class TcoContinuationKt$map$$inlined$transform$2 {
@kotlin.Metadata
public final class TcoContinuationKt$transform$$inlined$flow$1$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$transform$$inlined$flow$1.collect(LFlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -232,6 +238,7 @@ public final class TcoContinuationKt$transform$$inlined$flow$1$1 {
@kotlin.Metadata
public final class TcoContinuationKt$transform$$inlined$flow$1$lambda$1$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$transform$$inlined$flow$1$lambda$1.emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -270,6 +277,7 @@ public final class TcoContinuationKt$transform$$inlined$flow$1 {
@kotlin.Metadata
public final class TcoContinuationKt$transform$$inlined$flow$2$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$transform$$inlined$flow$2.collect(LFlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -282,6 +290,7 @@ public final class TcoContinuationKt$transform$$inlined$flow$2$1 {
@kotlin.Metadata
public final class TcoContinuationKt$transform$$inlined$flow$2$lambda$1$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$transform$$inlined$flow$2$lambda$1.emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -320,6 +329,7 @@ public final class TcoContinuationKt$transform$$inlined$flow$2 {
@kotlin.Metadata
public final class TcoContinuationKt$transform$$inlined$flow$3$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$transform$$inlined$flow$3.collect(LFlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -332,6 +342,7 @@ public final class TcoContinuationKt$transform$$inlined$flow$3$1 {
@kotlin.Metadata
public final class TcoContinuationKt$transform$$inlined$flow$3$lambda$1$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$transform$$inlined$flow$3$lambda$1.emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -81,6 +81,7 @@ public final class TcoContinuationKt$foo$$inlined$flow$1 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class TcoContinuationKt$foo$$inlined$map$1$2$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$foo$$inlined$map$1$2.emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field label: int
@@ -115,6 +116,7 @@ public final class TcoContinuationKt$foo$$inlined$map$1 {
@kotlin.Metadata
public final class TcoContinuationKt$map$$inlined$transform$1$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$map$$inlined$transform$1.collect(LFlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -128,6 +130,7 @@ public final class TcoContinuationKt$map$$inlined$transform$1$1 {
@kotlin.Metadata
@kotlin.coroutines.jvm.internal.DebugMetadata
public final class TcoContinuationKt$map$$inlined$transform$1$2$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$map$$inlined$transform$1$2.emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field L$0: java.lang.Object
field label: int
@@ -167,6 +170,7 @@ public final class TcoContinuationKt$map$$inlined$transform$1 {
@kotlin.Metadata
public final class TcoContinuationKt$transform$$inlined$flow$1$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$transform$$inlined$flow$1.collect(LFlowCollector;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
@@ -192,6 +196,7 @@ public final class TcoContinuationKt$transform$$inlined$flow$1 {
@kotlin.Metadata
public final class TcoContinuationKt$transform$lambda-1$$inlined$collect$1$1 {
// source: 'tcoContinuation.kt'
enclosing method TcoContinuationKt$transform$lambda-1$$inlined$collect$1.emit(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object