From 13a2879b78a2a6735536fa755c8e4bbc64ed9f65 Mon Sep 17 00:00:00 2001 From: pyos Date: Tue, 3 Dec 2019 11:16:22 +0100 Subject: [PATCH] JVM_IR: generate more correct parameter metadata --- .../kotlin/backend/common/ir/IrUtils.kt | 6 +- .../kotlin/backend/jvm/DeclarationOrigins.kt | 2 + .../backend/jvm/codegen/irCodegenUtils.kt | 104 ++++++------------ .../jvm/descriptors/JvmDeclarationFactory.kt | 3 +- ...AnonymousObjectSuperConstructorLowering.kt | 5 +- .../backend/jvm/lower/EnumClassLowering.kt | 9 +- .../ir/declarations/IrDeclarationOrigin.kt | 3 +- .../box/parametersMetadata/defaultImpls.kt | 1 - .../codegen/box/parametersMetadata/enum.kt | 1 - .../box/parametersMetadata/superParams.kt | 1 - 10 files changed, 50 insertions(+), 85 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt index ef50e6cdd78..baeede6ff4a 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt @@ -544,12 +544,14 @@ fun createStaticFunctionWithReceivers( this, name = Name.identifier("this"), index = offset++, - type = dispatchReceiverType!! + type = dispatchReceiverType!!, + origin = IrDeclarationOrigin.MOVED_RECEIVER_PARAMETER ) val extensionReceiver = oldFunction.extensionReceiverParameter?.copyTo( this, name = Name.identifier("receiver"), - index = offset++ + index = offset++, + origin = IrDeclarationOrigin.MOVED_RECEIVER_PARAMETER ) valueParameters.addAll(listOfNotNull(dispatchReceiver, extensionReceiver) + oldFunction.valueParameters.map { it.copyTo(this, index = it.index + offset) } 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 7036e63be7f..8c7d470d1f6 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 @@ -49,4 +49,6 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin { object SUSPEND_IMPL_STATIC_FUNCTION : IrDeclarationOriginImpl("SUSPEND_IMPL_STATIC_FUNCTION", isSynthetic = true) object INTERFACE_COMPANION_PRIVATE_INSTANCE : IrDeclarationOriginImpl("INTERFACE_COMPANION_PRIVATE_INSTANCE", isSynthetic = true) object POLYMORPHIC_SIGNATURE_INSTANTIATION : IrDeclarationOriginImpl("POLYMORPHIC_SIGNATURE_INSTANTIATION", isSynthetic = true) + object ENUM_CONSTRUCTOR_SYNTHETIC_PARAMETER : IrDeclarationOriginImpl("ENUM_CONSTRUCTOR_SYNTHETIC_PARAMETER", isSynthetic = true) + object OBJECT_SUPER_CONSTRUCTOR_PARAMETER : IrDeclarationOriginImpl("OBJECT_SUPER_CONSTURCTOR_PARAMETER", isSynthetic = true) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt index fbe42c7a02e..d5032636dc8 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt @@ -7,14 +7,15 @@ package org.jetbrains.kotlin.backend.jvm.codegen import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.ir.ir2string +import org.jetbrains.kotlin.backend.common.lower.BOUND_RECEIVER_PARAMETER +import org.jetbrains.kotlin.backend.common.lower.BOUND_VALUE_PARAMETER import org.jetbrains.kotlin.backend.common.lower.allOverridden import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.codegen.* -import org.jetbrains.kotlin.codegen.AsmUtil.LABELED_THIS_PARAMETER -import org.jetbrains.kotlin.codegen.AsmUtil.RECEIVER_PARAMETER_NAME import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter import org.jetbrains.kotlin.codegen.state.GenerationState @@ -413,78 +414,42 @@ fun IrClass.isOptionalAnnotationClass(): Boolean = /* From generateJava8ParameterNames.kt */ -fun generateParameterNames( - irFunction: IrFunction, - mv: MethodVisitor, - jvmSignature: JvmMethodSignature, - state: GenerationState -) { +fun generateParameterNames(irFunction: IrFunction, mv: MethodVisitor, jvmSignature: JvmMethodSignature, state: GenerationState) { val iterator = irFunction.valueParameters.iterator() val kotlinParameterTypes = jvmSignature.valueParameters - var isEnumName = true kotlinParameterTypes.forEachIndexed { index, parameterSignature -> - val kind = parameterSignature.kind - - val name = when (kind) { - JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL -> { - isEnumName = !isEnumName - if (!isEnumName) "\$enum\$name" else "\$enum\$ordinal" - } - JvmMethodParameterKind.RECEIVER -> { - getNameForReceiverParameter(irFunction, state.languageVersionSettings) - } - JvmMethodParameterKind.OUTER -> AsmUtil.CAPTURED_THIS_FIELD - JvmMethodParameterKind.VALUE -> iterator.next().name.asString() - - JvmMethodParameterKind.CONSTRUCTOR_MARKER, - JvmMethodParameterKind.SUPER_CALL_PARAM, - JvmMethodParameterKind.CAPTURED_LOCAL_VARIABLE, - JvmMethodParameterKind.THIS -> { - //we can't generate null name cause of jdk problem #9045294 - "arg" + index - } + val irParameter = when (parameterSignature.kind) { + JvmMethodParameterKind.RECEIVER -> irFunction.extensionReceiverParameter!! + else -> iterator.next() } - - //A construct emitted by a Java compiler must be marked as synthetic if it does not correspond to a construct declared explicitly or - // implicitly in source code, unless the emitted construct is a class initialization method (JVMS §2.9). - //A construct emitted by a Java compiler must be marked as mandated if it corresponds to a formal parameter + val name = when { + irParameter == irFunction.extensionReceiverParameter -> getNameForReceiverParameter(irFunction, state.languageVersionSettings) + irParameter.origin == JvmLoweredDeclarationOrigin.FIELD_FOR_OUTER_THIS -> AsmUtil.CAPTURED_THIS_FIELD + else -> irParameter.name.asString() + } + // A construct emitted by a Java compiler must be marked as synthetic if it does not correspond to a construct declared + // explicitly or implicitly in source code, unless the emitted construct is a class initialization method (JVMS §2.9). + // A construct emitted by a Java compiler must be marked as mandated if it corresponds to a formal parameter // declared implicitly in source code (§8.8.1, §8.8.9, §8.9.3, §15.9.5.1). - val access = when (kind) { - JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL -> Opcodes.ACC_SYNTHETIC - JvmMethodParameterKind.RECEIVER -> Opcodes.ACC_MANDATED - JvmMethodParameterKind.OUTER -> Opcodes.ACC_MANDATED - JvmMethodParameterKind.VALUE -> 0 - - JvmMethodParameterKind.CONSTRUCTOR_MARKER, - JvmMethodParameterKind.SUPER_CALL_PARAM, - JvmMethodParameterKind.CAPTURED_LOCAL_VARIABLE, - JvmMethodParameterKind.THIS -> Opcodes.ACC_SYNTHETIC + val access = when { + irParameter == irFunction.extensionReceiverParameter -> Opcodes.ACC_MANDATED + irParameter.origin == JvmLoweredDeclarationOrigin.FIELD_FOR_OUTER_THIS -> Opcodes.ACC_MANDATED + // TODO mark these backend-common origins as synthetic? (note: ExpressionCodegen is still expected + // to generate LVT entries for them) + irParameter.origin == IrDeclarationOrigin.MOVED_RECEIVER_PARAMETER -> Opcodes.ACC_SYNTHETIC + irParameter.origin == BOUND_VALUE_PARAMETER -> Opcodes.ACC_SYNTHETIC + irParameter.origin == BOUND_RECEIVER_PARAMETER -> Opcodes.ACC_SYNTHETIC + irParameter.origin.isSynthetic -> Opcodes.ACC_SYNTHETIC + else -> 0 } - mv.visitParameter(name, access) } } -/* From AsmUtil.java */ - -fun getNameForReceiverParameter( - irFunction: IrFunction, - languageVersionSettings: LanguageVersionSettings -): String { - return getLabeledThisNameForReceiver( - irFunction, languageVersionSettings, LABELED_THIS_PARAMETER, RECEIVER_PARAMETER_NAME - ) -} - -private fun getLabeledThisNameForReceiver( - irFunction: IrFunction, - languageVersionSettings: LanguageVersionSettings, - prefix: String, - defaultName: String -): String { +private fun getNameForReceiverParameter(irFunction: IrFunction, languageVersionSettings: LanguageVersionSettings): String { if (!languageVersionSettings.supportsFeature(LanguageFeature.NewCapturedReceiverFieldNamingConvention)) { - return defaultName + return AsmUtil.RECEIVER_PARAMETER_NAME } // Current codegen never touches CALL_LABEL_FOR_LAMBDA_ARGUMENT @@ -497,17 +462,10 @@ private fun getLabeledThisNameForReceiver( // val callableName = irFunction.descriptor.safeAs()?.correspondingVariable?.name ?: irFunction.descriptor.name val callableName = irFunction.safeAs()?.correspondingPropertySymbol?.owner?.name ?: irFunction.name - - return if (callableName.isSpecial) { - defaultName - } else getLabeledThisName(callableName.asString(), prefix, defaultName) - -} - -fun getLabeledThisName(callableName: String, prefix: String, defaultName: String): String { - return if (!Name.isValidIdentifier(callableName)) { - defaultName - } else prefix + mangleNameIfNeeded(callableName) + return if (callableName.isSpecial || !Name.isValidIdentifier(callableName.asString())) + AsmUtil.RECEIVER_PARAMETER_NAME + else + AsmUtil.LABELED_THIS_PARAMETER + mangleNameIfNeeded(callableName.asString()) } val IrAnnotationContainer.deprecationFlags: Int diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt index d235708a5a0..f44cd88ecd1 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.jvm.codegen.MethodSignatureMapper import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject +import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities @@ -107,7 +108,7 @@ class JvmDeclarationFactory( val outerThisValueParameter = IrValueParameterImpl( UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_OUTER_THIS, IrValueParameterSymbolImpl(outerThisDescriptor), - Name.identifier("\$outer"), + Name.identifier(AsmUtil.CAPTURED_THIS_FIELD), 0, type = outerThisType, varargElementType = null, diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AnonymousObjectSuperConstructorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AnonymousObjectSuperConstructorLowering.kt index b29aa7f4ec5..9ae4ebbcede 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AnonymousObjectSuperConstructorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AnonymousObjectSuperConstructorLowering.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlock 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.ir.builders.declarations.addValueParameter import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.builders.irTemporary @@ -72,7 +73,9 @@ private class AnonymousObjectSuperConstructorLowering(val context: JvmBackendCon val newArguments = mutableListOf() fun addArgument(value: IrExpression): IrValueParameter { newArguments.add(value) - return objectConstructor.addValueParameter("\$super_call_param\$${newArguments.size}", value.type) + return objectConstructor.addValueParameter( + "\$super_call_param\$${newArguments.size}", value.type, JvmLoweredDeclarationOrigin.OBJECT_SUPER_CONSTRUCTOR_PARAMETER + ) } fun IrDelegatingConstructorCall.transform(lift: List) = apply { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt index 3a833ae9b9d..fbae32c7fe0 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ir.copyTo 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.backend.jvm.ir.createJvmIrBuilder import org.jetbrains.kotlin.backend.jvm.ir.irArray import org.jetbrains.kotlin.descriptors.ClassKind @@ -169,9 +170,9 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP val descriptor = WrappedValueParameterDescriptor() return IrValueParameterImpl( UNDEFINED_OFFSET, UNDEFINED_OFFSET, - IrDeclarationOrigin.DEFINED, + JvmLoweredDeclarationOrigin.ENUM_CONSTRUCTOR_SYNTHETIC_PARAMETER, IrValueParameterSymbolImpl(descriptor), - Name.identifier("name"), + Name.identifier("\$enum\$name"), index = 0, type = context.irBuiltIns.stringType, varargElementType = null, @@ -187,9 +188,9 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP val descriptor = WrappedValueParameterDescriptor() return IrValueParameterImpl( UNDEFINED_OFFSET, UNDEFINED_OFFSET, - IrDeclarationOrigin.DEFINED, + JvmLoweredDeclarationOrigin.ENUM_CONSTRUCTOR_SYNTHETIC_PARAMETER, IrValueParameterSymbolImpl(descriptor), - Name.identifier("ordinal"), + Name.identifier("\$enum\$ordinal"), index = 1, type = context.irBuiltIns.intType, varargElementType = null, diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt index 9986b0bbcdf..2c8bb15ac8d 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt @@ -31,7 +31,8 @@ interface IrDeclarationOrigin { object FUNCTION_FOR_DEFAULT_PARAMETER : IrDeclarationOriginImpl("FUNCTION_FOR_DEFAULT_PARAMETER", isSynthetic = true) object MASK_FOR_DEFAULT_FUNCTION : IrDeclarationOriginImpl("MASK_FOR_DEFAULT_FUNCTION", isSynthetic = true) object DEFAULT_CONSTRUCTOR_MARKER : IrDeclarationOriginImpl("DEFAULT_CONSTRUCTOR_MARKER", isSynthetic = true) - object METHOD_HANDLER_IN_DEFAULT_FUNCTION : IrDeclarationOriginImpl("METHOD_HANDLER_IN_DEFAULT_FUNCTION", isSynthetic = true) + object METHOD_HANDLER_IN_DEFAULT_FUNCTION : IrDeclarationOriginImpl("METHOD_HANDLER_IN_DEFAULT_FUNCTION", isSynthetic = true) + object MOVED_RECEIVER_PARAMETER : IrDeclarationOriginImpl("MOVED_RECEIVER_PARAMETER") object FILE_CLASS : IrDeclarationOriginImpl("FILE_CLASS") object GENERATED_DATA_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_DATA_CLASS_MEMBER") diff --git a/compiler/testData/codegen/box/parametersMetadata/defaultImpls.kt b/compiler/testData/codegen/box/parametersMetadata/defaultImpls.kt index f0cacedb775..bf002b2cf8c 100644 --- a/compiler/testData/codegen/box/parametersMetadata/defaultImpls.kt +++ b/compiler/testData/codegen/box/parametersMetadata/defaultImpls.kt @@ -1,6 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR // SKIP_JDK6 -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK diff --git a/compiler/testData/codegen/box/parametersMetadata/enum.kt b/compiler/testData/codegen/box/parametersMetadata/enum.kt index db711540040..5406e349b16 100644 --- a/compiler/testData/codegen/box/parametersMetadata/enum.kt +++ b/compiler/testData/codegen/box/parametersMetadata/enum.kt @@ -1,6 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR // SKIP_JDK6 -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK diff --git a/compiler/testData/codegen/box/parametersMetadata/superParams.kt b/compiler/testData/codegen/box/parametersMetadata/superParams.kt index 1fc02a56846..09e074db9b0 100644 --- a/compiler/testData/codegen/box/parametersMetadata/superParams.kt +++ b/compiler/testData/codegen/box/parametersMetadata/superParams.kt @@ -1,6 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR // SKIP_JDK6 -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK