diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt index 604531ac1e4..d86a580829f 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt @@ -50,4 +50,5 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin { object FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE : IrDeclarationOriginImpl("FOR_INLINE_TEMPLATE_CROSSINLINE") object CONTINUATION_CLASS_RESULT_FIELD: IrDeclarationOriginImpl("CONTINUATION_CLASS_RESULT_FIELD", isSynthetic = true) object COMPANION_PROPERTY_BACKING_FIELD : IrDeclarationOriginImpl("COMPANION_MOVED_PROPERTY_BACKING_FIELD") + object FIELD_FOR_STATIC_LAMBDA_INSTANCE : IrDeclarationOriginImpl("FIELD_FOR_STATIC_LAMBDA_INSTANCE") } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index 5ed2d23d429..c23133c0062 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -235,21 +235,25 @@ abstract class ClassCodegen protected constructor( if (field.origin == IrDeclarationOrigin.PROPERTY_DELEGATE) null else context.methodSignatureMapper.mapFieldSignature(field) val fieldName = field.name.asString() + val flags = field.flags val fv = visitor.newField( - field.OtherOrigin, field.flags, fieldName, fieldType.descriptor, + field.OtherOrigin, flags, fieldName, fieldType.descriptor, fieldSignature, (field.initializer?.expression as? IrConst<*>)?.value ) jvmSignatureClashDetector.trackField(field, RawSignature(fieldName, fieldType.descriptor, MemberKind.FIELD)) if (field.origin != JvmLoweredDeclarationOrigin.CONTINUATION_CLASS_RESULT_FIELD) { - object : AnnotationCodegen(this@ClassCodegen, context) { + val skipNullabilityAnnotations = + flags and Opcodes.ACC_SYNTHETIC != 0 || flags and Opcodes.ACC_PRIVATE != 0 || + field.origin == JvmLoweredDeclarationOrigin.FIELD_FOR_STATIC_LAMBDA_INSTANCE + object : AnnotationCodegen(this@ClassCodegen, context, skipNullabilityAnnotations) { override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor { return fv.visitAnnotation(descr, visible) } override fun visitTypeAnnotation(descr: String?, path: TypePath?, visible: Boolean): AnnotationVisitor { - return fv.visitTypeAnnotation(TypeReference.newTypeReference(TypeReference.FIELD).value,path, descr, visible) + return fv.visitTypeAnnotation(TypeReference.newTypeReference(TypeReference.FIELD).value, path, descr, visible) } }.genAnnotations(field, fieldType, field.type) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticLambdaLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticLambdaLowering.kt index c6488593843..1f4366f25c9 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticLambdaLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticLambdaLowering.kt @@ -10,24 +10,30 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin +import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.builders.declarations.buildField import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irExprBody import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.util.constructedClass +import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.primaryConstructor import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid +import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import java.util.* internal val staticLambdaPhase = makeIrFilePhase( ::StaticLambdaLowering, @@ -36,12 +42,14 @@ internal val staticLambdaPhase = makeIrFilePhase( ) class StaticLambdaLowering(val backendContext: JvmBackendContext) : FileLoweringPass, IrElementTransformerVoid() { + private val staticLambdaFields = HashMap() + override fun lower(irFile: IrFile) = irFile.transformChildrenVoid() override fun visitClass(declaration: IrClass): IrStatement { declaration.transformChildrenVoid() if (declaration.isSyntheticSingleton) { - declaration.declarations += backendContext.declarationFactory.getFieldForObjectInstance(declaration).also { field -> + declaration.declarations += getFieldForStaticLambdaInstance(declaration).also { field -> field.initializer = backendContext.createIrBuilder(field.symbol).run { irExprBody(irCall(declaration.primaryConstructor!!)) } @@ -50,12 +58,26 @@ class StaticLambdaLowering(val backendContext: JvmBackendContext) : FileLowering return declaration } + private fun getFieldForStaticLambdaInstance(lambdaClass: IrClass): IrField = + staticLambdaFields.getOrPut(lambdaClass) { + buildField { + name = Name.identifier(JvmAbi.INSTANCE_FIELD) + type = lambdaClass.defaultType + origin = JvmLoweredDeclarationOrigin.FIELD_FOR_STATIC_LAMBDA_INSTANCE + isFinal = true + isStatic = true + visibility = Visibilities.PUBLIC + }.apply { + parent = lambdaClass + } + } + override fun visitConstructorCall(expression: IrConstructorCall): IrExpression { val constructor = expression.symbol.owner if (!constructor.constructedClass.isSyntheticSingleton) return super.visitConstructorCall(expression) - val instanceField = backendContext.declarationFactory.getFieldForObjectInstance(constructor.constructedClass) + val instanceField = getFieldForStaticLambdaInstance(constructor.constructedClass) return IrGetFieldImpl(expression.startOffset, expression.endOffset, instanceField.symbol, expression.type) } diff --git a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt index 11d37fc5ca8..d5f4a906680 100644 --- a/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt +++ b/compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override5_ir.txt @@ -37,7 +37,7 @@ public final class Override5Kt$inlineMe$1$generic$1 { @kotlin.Metadata public final class Override5Kt$inlineMe$1$generic$2 { - public final static @org.jetbrains.annotations.NotNull field INSTANCE: Override5Kt$inlineMe$1$generic$2 + public final static field INSTANCE: Override5Kt$inlineMe$1$generic$2 inner (anonymous) class Override5Kt$inlineMe$1 inner (anonymous) class Override5Kt$inlineMe$1$generic$2 static method (): void diff --git a/compiler/testData/codegen/bytecodeListing/annotations/kt9320.kt b/compiler/testData/codegen/bytecodeListing/annotations/kt9320.kt index 9671debbfb9..146922068b2 100644 --- a/compiler/testData/codegen/bytecodeListing/annotations/kt9320.kt +++ b/compiler/testData/codegen/bytecodeListing/annotations/kt9320.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR annotation class Ann @Ann open class My