JVM_IR: generate more correct parameter metadata

This commit is contained in:
pyos
2019-12-03 11:16:22 +01:00
committed by max-kammerer
parent cf86dc9a89
commit 13a2879b78
10 changed files with 50 additions and 85 deletions
@@ -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) }
@@ -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)
}
@@ -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<VariableAccessorDescriptor>()?.correspondingVariable?.name ?: irFunction.descriptor.name
val callableName = irFunction.safeAs<IrSimpleFunction>()?.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
@@ -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,
@@ -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<IrExpression>()
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<IrVariable>) = apply {
@@ -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,
@@ -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")
@@ -1,6 +1,5 @@
// IGNORE_BACKEND_FIR: JVM_IR
// SKIP_JDK6
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// FULL_JDK
@@ -1,6 +1,5 @@
// IGNORE_BACKEND_FIR: JVM_IR
// SKIP_JDK6
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// FULL_JDK
@@ -1,6 +1,5 @@
// IGNORE_BACKEND_FIR: JVM_IR
// SKIP_JDK6
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// FULL_JDK