JVM: Fix usage of ClassBuilder API in AnonymousObjectTransformer
This commit is contained in:
committed by
Alexander Udalov
parent
c156613141
commit
1b5214a2dc
+13
-8
@@ -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)
|
||||
}
|
||||
|
||||
+22
-5
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user