From f03c897dc45020c647ddf55a61c72aae6ea79e7f Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Tue, 22 Jun 2021 19:25:29 +0300 Subject: [PATCH] [K/N] Move fields from KFunctionImpl to functions --- .../konan/lower/FunctionReferenceLowering.kt | 69 ++++++++++++++----- .../kotlin/native/internal/KFunctionImpl.kt | 19 +++-- .../native/internal/KSuspendFunctionImpl.kt | 5 +- 3 files changed, 66 insertions(+), 27 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt index ebdfaabd483..536d36327ac 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt @@ -14,13 +14,11 @@ import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.llvm.computeFullName -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor -import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* +import org.jetbrains.kotlin.ir.builders.declarations.addFunction import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl @@ -288,6 +286,53 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass } functionReferenceClass.superTypes += superTypes + if (!isLambda) { + fun addOverrideInner(name: String, value: IrBuilderWithScope.(IrFunction) -> IrExpression) { + val overridden = functionReferenceClass.superTypes.mapNotNull { superType -> + superType.getClass() + ?.declarations + ?.filterIsInstance() + ?.singleOrNull { it.name.asString() == name } + ?.symbol + } + require(overridden.isNotEmpty()) + val function = functionReferenceClass.addFunction { + startOffset = SYNTHETIC_OFFSET + endOffset = SYNTHETIC_OFFSET + this.name = Name.identifier(name) + modality = Modality.FINAL + returnType = overridden[0].owner.returnType + } + function.createDispatchReceiverParameter() + function.overriddenSymbols += overridden + function.body = context.createIrBuilder(function.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { + +irReturn( + value(function) + ) + } + } + + fun addOverride(name: String, value: IrBuilderWithScope.() -> IrExpression) { + addOverrideInner(name) { _ -> value() } + } + + val kTypeGenerator = KTypeGenerator(context, irFile, functionReference) + addOverride("computeReturnType") { with(kTypeGenerator) { irKType(referencedFunction.returnType) } } + addOverride("computeArity") { irInt(unboundFunctionParameters.size + if (functionReferenceTarget.isSuspend) 1 else 0) } + addOverride("computeFlags") { irInt(getFlags()) } + val name = ((functionReferenceTarget as? IrSimpleFunction)?.attributeOwnerId as? IrSimpleFunction)?.name + ?: functionReferenceTarget.name + addOverride("computeName") { irString(name.asString()) } + addOverride("computeFqName") { irString(functionReferenceTarget.computeFullName()) } + + + val receiver = boundFunctionParameters.singleOrNull() + if (receiver?.descriptor is ReceiverParameterDescriptor) { + addOverrideInner("computeReceiver") { f -> + irGetField(irGet(f.dispatchReceiverParameter!!), argumentToPropertiesMap[receiver]!!) + } + } + } functionReferenceClass.addFakeOverrides(context.typeSystem) @@ -315,27 +360,13 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass type = parameter.type.substitute(typeArgumentsMap)) } - val kTypeGenerator = KTypeGenerator(context, irFile, functionReference) body = context.createIrBuilder(symbol, startOffset, endOffset).irBlockBody { val superConstructor = when { isKSuspendFunction -> kSuspendFunctionImplConstructorSymbol.owner isLambda -> irBuiltIns.anyClass.owner.constructors.single() else -> kFunctionImplConstructorSymbol.owner } - +irDelegatingConstructorCall(superConstructor).apply applyIrDelegationConstructorCall@ { - if (isLambda) return@applyIrDelegationConstructorCall - val name = ((functionReferenceTarget as? IrSimpleFunction)?.attributeOwnerId as? IrSimpleFunction)?.name - ?: functionReferenceTarget.name - val needReceiver = boundFunctionParameters.singleOrNull()?.descriptor is ReceiverParameterDescriptor - val receiver = if (needReceiver) irGet(valueParameters.single()) else irNull() - val arity = unboundFunctionParameters.size + if (functionReferenceTarget.isSuspend) 1 else 0 - putValueArgument(0, irString(name.asString())) - putValueArgument(1, irString(functionReferenceTarget.computeFullName())) - putValueArgument(2, receiver) - putValueArgument(3, irInt(arity)) - putValueArgument(4, irInt(getFlags())) - putValueArgument(5, with(kTypeGenerator) { irKType(referencedFunction.returnType) }) - } + +irDelegatingConstructorCall(superConstructor) +IrInstanceInitializerCallImpl(startOffset, endOffset, functionReferenceClass.symbol, irBuiltIns.unitType) // Save all arguments to fields. boundFunctionParameters.forEachIndexed { index, parameter -> diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KFunctionImpl.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KFunctionImpl.kt index bae3a016151..b99de3b0fbf 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KFunctionImpl.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KFunctionImpl.kt @@ -9,10 +9,21 @@ import kotlin.reflect.KFunction import kotlin.reflect.KType @FixmeReflection -internal abstract class KFunctionImpl( - override val name: String, val fqName: String, val receiver: Any?, - val arity: Int, val flags: Int, override val returnType: KType -): KFunction { +internal abstract class KFunctionImpl: KFunction { + final override val returnType get() = computeReturnType() + val flags get() = computeFlags() + val arity get() = computeArity() + val fqName get() = computeFqName() + val receiver get() = computeReceiver() + final override val name get() = computeName() + + abstract fun computeReturnType() : KType + abstract fun computeFlags() : Int + abstract fun computeArity() : Int + abstract fun computeFqName() : String + abstract fun computeName() : String + open fun computeReceiver(): Any? = null + override fun equals(other: Any?): Boolean { if (other !is KFunctionImpl<*>) return false return fqName == other.fqName && receiver == other.receiver diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KSuspendFunctionImpl.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KSuspendFunctionImpl.kt index 011311e7f05..767fe951c9a 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KSuspendFunctionImpl.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KSuspendFunctionImpl.kt @@ -10,9 +10,6 @@ import kotlin.reflect.KFunction import kotlin.reflect.KClass @FixmeReflection -internal abstract class KSuspendFunctionImpl( - name: String, fqName: String, receiver: Any?, - arity: Int, flags: Int, returnType: KType -): KFunctionImpl(name, fqName, receiver, arity, flags, returnType) { +internal abstract class KSuspendFunctionImpl: KFunctionImpl() { override fun toString() = "suspend function $name" }