JVM_IR: fix a couple of inline class reflection issues.
1. Postpone the computation of the signature for property reference getters for extension properties until codegen time. 2. Generate metadata for static replacement functions instead of the original functions.
This commit is contained in:
committed by
Alexander Udalov
parent
2ebb797e61
commit
e7835fecfc
+4
-9
@@ -8,9 +8,10 @@ package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.PromisedValue
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.ir.util.collectRealOverrides
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
|
||||
/**
|
||||
@@ -20,15 +21,9 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
object SignatureString : IntrinsicMethod() {
|
||||
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
|
||||
val function = (expression.getValueArgument(0) as IrFunctionReference).symbol.owner
|
||||
|
||||
// TODO do not use descriptors
|
||||
val declaration = codegen.context.referenceFunction(
|
||||
DescriptorUtils.unwrapFakeOverride(function.descriptor).original
|
||||
).owner
|
||||
|
||||
val method = codegen.context.methodSignatureMapper.mapAsmMethod(declaration)
|
||||
val resolved = if (function is IrSimpleFunction) function.collectRealOverrides().first() else function
|
||||
val method = codegen.context.methodSignatureMapper.mapAsmMethod(resolved)
|
||||
val descriptor = method.name + method.descriptor
|
||||
|
||||
return object : PromisedValue(codegen, AsmTypes.JAVA_STRING_TYPE, codegen.context.irBuiltIns.stringType) {
|
||||
override fun materialize() {
|
||||
codegen.mv.aconst(descriptor)
|
||||
|
||||
+23
-7
@@ -19,10 +19,12 @@ import org.jetbrains.kotlin.backend.jvm.ir.irArrayOf
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.createType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
@@ -64,14 +66,11 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
|
||||
private val IrField.signature: String
|
||||
get() = "${JvmAbi.getterName(name.asString())}()${context.methodSignatureMapper.mapReturnType(this)}"
|
||||
|
||||
private val IrMemberAccessExpression.signature: String
|
||||
get() = getter?.let { getter ->
|
||||
localPropertyIndices[getter]?.let { "<v#$it>" }
|
||||
} ?: getter?.owner?.signature ?: field!!.owner.signature
|
||||
|
||||
private val arrayItemGetter =
|
||||
context.ir.symbols.array.owner.functions.single { it.name.asString() == "get" }
|
||||
|
||||
private val signatureStringIntrinsic = context.ir.symbols.signatureStringIntrinsic
|
||||
|
||||
private val kPropertyStarType = IrSimpleTypeImpl(
|
||||
context.irBuiltIns.kPropertyClass,
|
||||
false,
|
||||
@@ -95,6 +94,23 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
|
||||
calculateOwner(expression.propertyContainer, this@PropertyReferenceLowering.context)
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.computeSignatureString(expression: IrCallableReference): IrExpression {
|
||||
return expression.getter?.let { getter ->
|
||||
localPropertyIndices[getter]?.let { irString("<v#$it>") }
|
||||
?: if (getter.owner.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) {
|
||||
// Default property accessor. Compute the signature now, so that we will not get into trouble
|
||||
// if the getter is transformed to a static method by inline classes lowering.
|
||||
irString(getter.owner.signature)
|
||||
} else {
|
||||
// Delay the computation of the signature until after inline classes lowering to make sure
|
||||
// we mangle the function names correctly for things like extension methods on inline classes.
|
||||
irCall(signatureStringIntrinsic).apply {
|
||||
putValueArgument(0, IrFunctionReferenceImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, expression.type, getter, 0, null))
|
||||
}
|
||||
}
|
||||
} ?: irString(expression.field!!.owner.signature)
|
||||
}
|
||||
|
||||
private fun IrClass.addOverride(method: IrSimpleFunction, buildBody: IrBuilderWithScope.(List<IrValueParameter>) -> IrExpression) =
|
||||
addFunction {
|
||||
setSourceRange(this@addOverride)
|
||||
@@ -204,7 +220,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
|
||||
putValueArgument(0, irCall(referenceKind.reflectedSymbol.constructors.single()).apply {
|
||||
putValueArgument(0, buildReflectedContainerReference(expression))
|
||||
putValueArgument(1, irString(expression.symbol.descriptor.name.asString()))
|
||||
putValueArgument(2, irString(expression.signature))
|
||||
putValueArgument(2, computeSignatureString(expression))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -266,7 +282,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
|
||||
referenceClass.addSimpleDelegatingConstructor(superConstructor, context.irBuiltIns, isPrimary = true)
|
||||
referenceClass.addOverride(getName) { irString(expression.symbol.descriptor.name.asString()) }
|
||||
referenceClass.addOverride(getOwner) { buildReflectedContainerReference(expression) }
|
||||
referenceClass.addOverride(getSignature) { irString(expression.signature) }
|
||||
referenceClass.addOverride(getSignature) { computeSignatureString(expression) }
|
||||
|
||||
val receiverField = referenceClass.addField {
|
||||
name = backingFieldFromSuper.name
|
||||
|
||||
+5
-1
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFunWithDescriptorForInlining
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionBase
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
@@ -169,8 +170,11 @@ class MemoizedInlineClassReplacements {
|
||||
private fun createStaticReplacement(function: IrFunction): IrReplacementFunction {
|
||||
val parameterMap = mutableMapOf<IrValueParameterSymbol, IrValueParameter>()
|
||||
val replacement = buildReplacement(function) {
|
||||
if (function !is IrSimpleFunction || function.overriddenSymbols.isEmpty())
|
||||
// Generate metadata for the replacement function instead of the original.
|
||||
if (function is IrFunctionBase) {
|
||||
metadata = function.metadata
|
||||
function.metadata = null
|
||||
}
|
||||
|
||||
for ((index, parameter) in function.explicitParameters.withIndex()) {
|
||||
val name = when (parameter) {
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE
|
||||
// WITH_REFLECT
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE
|
||||
// WITH_REFLECT
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE
|
||||
// WITH_REFLECT
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.reflect.KMutableProperty2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE, JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR, JS, NATIVE
|
||||
// WITH_REFLECT
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
||||
Reference in New Issue
Block a user