From 3cdf4bae07e5265d340bda1b7b77cbfecf0b0dfa Mon Sep 17 00:00:00 2001 From: Vladimir Sukharev Date: Mon, 17 Apr 2023 10:35:55 +0000 Subject: [PATCH] [K2/N] Refactor KonanSymbols before re-enabling special backend checks ^KT-55598 Merge-request: KT-MR-9477 Merged-by: Vladimir Sukharev --- .../kotlin/fir/backend/IrBuiltInsOverFir.kt | 13 +- .../descriptors/IrBuiltInsOverDescriptors.kt | 6 + .../src/org/jetbrains/kotlin/ir/IrBuiltIns.kt | 2 + .../kotlin/backend/konan/DescriptorsLookup.kt | 17 - .../kotlin/backend/konan/InteropUtils.kt | 147 +++------ .../kotlin/backend/konan/KonanFqNames.kt | 2 +- .../jetbrains/kotlin/backend/konan/ir/Ir.kt | 307 +++++++++++++----- 7 files changed, 279 insertions(+), 215 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/IrBuiltInsOverFir.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/IrBuiltInsOverFir.kt index 0f6e08eed06..ef4a1d3934c 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/IrBuiltInsOverFir.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/IrBuiltInsOverFir.kt @@ -28,10 +28,7 @@ import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl -import org.jetbrains.kotlin.ir.symbols.IrClassSymbol -import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol -import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol -import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl @@ -623,6 +620,9 @@ class IrBuiltInsOverFir( override fun findFunctions(name: Name, packageFqName: FqName): Iterable = findFunctions(packageFqName, name) + override fun findProperties(name: Name, packageFqName: FqName): Iterable = + findProperties(packageFqName, name) + override fun findClass(name: Name, vararg packageNameSegments: String): IrClassSymbol? = referenceClassByFqname(FqName.fromSegments(packageNameSegments.asList()), name) @@ -1165,4 +1165,9 @@ class IrBuiltInsOverFir( components.session.symbolProvider.getTopLevelFunctionSymbols(packageName, name).mapNotNull { firOpSymbol -> components.declarationStorage.getIrFunctionSymbol(firOpSymbol) as? IrSimpleFunctionSymbol } + + private fun findProperties(packageName: FqName, name: Name): List = + components.session.symbolProvider.getTopLevelPropertySymbols(packageName, name).mapNotNull { firOpSymbol -> + components.declarationStorage.getIrPropertySymbol(firOpSymbol) as? IrPropertySymbol + } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt index a1f55f7bb3c..478a859d0e8 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/descriptors/IrBuiltInsOverDescriptors.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.ir.descriptors.* import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol +import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.* @@ -488,6 +489,11 @@ class IrBuiltInsOverDescriptors( symbolTable.referenceSimpleFunction(it) } + override fun findProperties(name: Name, packageFqName: FqName): Iterable = + builtIns.builtInsModule.getPackage(packageFqName).memberScope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND).map { + symbolTable.referenceProperty(it) + } + override fun findClass(name: Name, vararg packageNameSegments: String): IrClassSymbol? = (builtInsPackage(*packageNameSegments).getContributedClassifier( name, diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt index 7a8186c445d..2a144f3f0af 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment import org.jetbrains.kotlin.ir.declarations.IrFactory import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol +import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.name.FqName @@ -159,6 +160,7 @@ abstract class IrBuiltIns { // TODO: drop variants from segments, add helper from whole fqn abstract fun findFunctions(name: Name, vararg packageNameSegments: String = arrayOf("kotlin")): Iterable abstract fun findFunctions(name: Name, packageFqName: FqName): Iterable + abstract fun findProperties(name: Name, packageFqName: FqName): Iterable abstract fun findClass(name: Name, vararg packageNameSegments: String = arrayOf("kotlin")): IrClassSymbol? abstract fun findClass(name: Name, packageFqName: FqName): IrClassSymbol? diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/DescriptorsLookup.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/DescriptorsLookup.kt index 8ad5006bf05..3b32c5e98c3 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/DescriptorsLookup.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/DescriptorsLookup.kt @@ -6,27 +6,10 @@ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.incremental.components.NoLookupLocation -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.scopes.MemberScope internal class DescriptorsLookup(val builtIns: KonanBuiltIns) { - private val packageScope by lazy { builtIns.builtInsModule.getPackage(KonanFqNames.internalPackageName).memberScope } - - val nativePtr by lazy { packageScope.getContributedClassifier(NATIVE_PTR_NAME) as ClassDescriptor } - val getNativeNullPtr by lazy { packageScope.getContributedFunctions("getNativeNullPtr").single() } - val immutableBlobOf by lazy { - builtIns.builtInsModule.getPackage(KonanFqNames.packageName).memberScope.getContributedFunctions("immutableBlobOf").single() - } val interopBuiltIns by lazy { InteropBuiltIns(this.builtIns) } - - private fun MemberScope.getContributedClassifier(name: String) = - this.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) - - private fun MemberScope.getContributedFunctions(name: String) = - this.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) } \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/InteropUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/InteropUtils.kt index 15beed6957f..c8a1d99f401 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/InteropUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/InteropUtils.kt @@ -5,18 +5,12 @@ package org.jetbrains.kotlin.backend.konan -import org.jetbrains.kotlin.backend.konan.InteropFqNames.cValue -import org.jetbrains.kotlin.backend.konan.InteropFqNames.cValueName -import org.jetbrains.kotlin.backend.konan.InteropFqNames.managedTypeName import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.types.TypeUtils object InteropFqNames { @@ -29,16 +23,52 @@ object InteropFqNames { const val objCOutletName = "ObjCOutlet" const val objCMethodImpName = "ObjCMethodImp" const val exportObjCClassName = "ExportObjCClass" + const val nativeHeapName = "nativeHeap" const val cValueName = "CValue" const val cValuesName = "CValues" const val cValuesRefName = "CValuesRef" const val cEnumName = "CEnum" const val cStructVarName = "CStructVar" + const val cEnumVarName = "CEnumVar" + const val cPrimitiveVarName = "CPrimitiveVar" private const val cPointedName = "CPointed" const val interopStubsName = "InteropStubs" const val managedTypeName = "ManagedType" + const val memScopeName = "MemScope" + const val foreignObjCObjectName = "ForeignObjCObject" + const val cOpaqueName = "COpaque" + const val objCObjectName = "ObjCObject" + const val objCObjectBaseMetaName = "ObjCObjectBaseMeta" + const val objCClassName = "ObjCClass" + const val objCClassOfName = "ObjCClassOf" + const val objCProtocolName = "ObjCProtocol" + const val nativeMemUtilsName = "nativeMemUtils" + const val cPlusPlusClassName = "CPlusPlusClass" + const val skiaRefCntName = "SkiaRefCnt" + const val TypeName = "Type" + + const val cstrPropertyName = "cstr" + const val wcstrPropertyName = "wcstr" + const val nativePointedRawPtrPropertyName = "rawPtr" + const val cPointerRawValuePropertyName = "rawValue" + + const val getObjCClassFunName = "getObjCClass" + const val objCObjectSuperInitCheckFunName = "superInitCheck" + const val allocObjCObjectFunName = "allocObjCObject" + const val typeOfFunName = "typeOf" + const val objCObjectInitByFunName = "initBy" + const val objCObjectRawPtrFunName = "objcPtr" + const val interpretObjCPointerFunName = "interpretObjCPointer" + const val interpretObjCPointerOrNullFunName = "interpretObjCPointerOrNull" + const val interpretNullablePointedFunName = "interpretNullablePointed" + const val interpretCPointerFunName = "interpretCPointer" + const val nativePointedGetRawPointerFunName = "getRawPointer" + const val cPointerGetRawValueFunName = "getRawValue" + const val cValueWriteFunName = "write" + const val cValueReadFunName = "readValue" + const val allocTypeFunName = "alloc" val packageName = FqName("kotlinx.cinterop") @@ -69,112 +99,15 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns) { private val packageScope = builtIns.builtInsModule.getPackage(InteropFqNames.packageName).memberScope - val nativePointed = packageScope.getContributedClass(InteropFqNames.nativePointedName) - - val cValuesRef = this.packageScope.getContributedClass("CValuesRef") - val cValue = this.packageScope.getContributedClass(cValueName) - val cOpaque = this.packageScope.getContributedClass("COpaque") - val cValueWrite = this.packageScope.getContributedFunctions("write") - .single { it.extensionReceiverParameter?.type?.constructor?.declarationDescriptor?.fqNameSafe == InteropFqNames.cValue } - val cValueRead = this.packageScope.getContributedFunctions("readValue") - .single { it.valueParameters.size == 1 } - - val cEnumVar = this.packageScope.getContributedClass("CEnumVar") - val cStructVar = this.packageScope.getContributedClass("CStructVar") - val cStructVarType = cStructVar.defaultType.memberScope.getContributedClass("Type") - private val cPrimitiveVar = this.packageScope.getContributedClass("CPrimitiveVar") - val cPrimitiveVarType = cPrimitiveVar.defaultType.memberScope.getContributedClass("Type") - - val nativeMemUtils = this.packageScope.getContributedClass("nativeMemUtils") - - val allocType = this.packageScope.getContributedFunctions("alloc") - .single { it.extensionReceiverParameter != null - && it.valueParameters.singleOrNull()?.name?.toString() == "type" } - - val cPointer = this.packageScope.getContributedClass(InteropFqNames.cPointerName) - - val cPointerRawValue = cPointer.unsubstitutedMemberScope.getContributedVariables("rawValue").single() - - val cPointerGetRawValue = packageScope.getContributedFunctions("getRawValue").single { - val extensionReceiverParameter = it.extensionReceiverParameter - extensionReceiverParameter != null && - TypeUtils.getClassDescriptor(extensionReceiverParameter.type)?.fqNameUnsafe == InteropFqNames.cPointer - } - - val cstr = packageScope.getContributedVariables("cstr").single() - val wcstr = packageScope.getContributedVariables("wcstr").single() - val memScope = packageScope.getContributedClass("MemScope") - - val nativePointedRawPtrGetter = - nativePointed.unsubstitutedMemberScope.getContributedVariables("rawPtr").single().getter!! - - val nativePointedGetRawPointer = packageScope.getContributedFunctions("getRawPointer").single { - val extensionReceiverParameter = it.extensionReceiverParameter - extensionReceiverParameter != null && - TypeUtils.getClassDescriptor(extensionReceiverParameter.type) == nativePointed - } - - val typeOf = packageScope.getContributedFunctions("typeOf").single() - - val objCObject = packageScope.getContributedClass("ObjCObject") - - val objCObjectBase = packageScope.getContributedClass("ObjCObjectBase") - - val objCObjectBaseMeta = packageScope.getContributedClass("ObjCObjectBaseMeta") - - val objCClass = packageScope.getContributedClass("ObjCClass") - - val objCClassOf = packageScope.getContributedClass("ObjCClassOf") - - val objCProtocol = packageScope.getContributedClass("ObjCProtocol") - - val allocObjCObject = packageScope.getContributedFunctions("allocObjCObject").single() - - val getObjCClass = packageScope.getContributedFunctions("getObjCClass").single() - - val objCObjectRawPtr = packageScope.getContributedFunctions("objcPtr").single() - - val interpretObjCPointerOrNull = packageScope.getContributedFunctions("interpretObjCPointerOrNull").single() - val interpretObjCPointer = packageScope.getContributedFunctions("interpretObjCPointer").single() - val interpretNullablePointed = packageScope.getContributedFunctions("interpretNullablePointed").single() - val interpretCPointer = packageScope.getContributedFunctions("interpretCPointer").single() - - val objCObjectSuperInitCheck = packageScope.getContributedFunctions("superInitCheck").single() - val objCObjectInitBy = packageScope.getContributedFunctions("initBy").single() - - val objCMethodImp = packageScope.getContributedClass(InteropFqNames.objCMethodImpName) - val nativeHeap = packageScope.getContributedClass("nativeHeap") - val managedType = packageScope.getContributedClass(managedTypeName) // used in CStructVarClassGenerator.kt - val cPlusPlusClass = packageScope.getContributedClass("CPlusPlusClass") - val skiaRefCnt = packageScope.getContributedClass("SkiaRefCnt") - - val interopGetPtr = packageScope.getContributedVariables("ptr").single { - val singleTypeParameter = it.typeParameters.singleOrNull() - val singleTypeParameterUpperBound = singleTypeParameter?.upperBounds?.singleOrNull() - val extensionReceiverParameter = it.extensionReceiverParameter - - singleTypeParameterUpperBound != null && - extensionReceiverParameter != null && - TypeUtils.getClassDescriptor(singleTypeParameterUpperBound)?.fqNameSafe == InteropFqNames.cPointed && - extensionReceiverParameter.type == singleTypeParameter.defaultType - }.getter!! - - val interopManagedGetPtr = packageScope.getContributedVariables("ptr").single { - val singleTypeParameter = it.typeParameters.singleOrNull() - val singleTypeParameterUpperBound = singleTypeParameter?.upperBounds?.singleOrNull() - val extensionReceiverParameter = it.extensionReceiverParameter - - singleTypeParameterUpperBound != null && - extensionReceiverParameter != null && - TypeUtils.getClassDescriptor(singleTypeParameterUpperBound)?.fqNameSafe == InteropFqNames.cStructVar && - TypeUtils.getClassDescriptor(extensionReceiverParameter.type)?.fqNameSafe == InteropFqNames.managedType - }.getter!! + internal fun getContributedVariables(name: String) = packageScope.getContributedVariables(name) + internal fun getContributedFunctions(name: String) = packageScope.getContributedFunctions(name) + internal fun getContributedClass(name: String) = packageScope.getContributedClass(name) } private fun MemberScope.getContributedVariables(name: String) = this.getContributedVariables(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) -private fun MemberScope.getContributedClass(name: String): ClassDescriptor = +internal fun MemberScope.getContributedClass(name: String): ClassDescriptor = this.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) as ClassDescriptor private fun MemberScope.getContributedFunctions(name: String) = diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanFqNames.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanFqNames.kt index 5db525e2ce2..b3b79b525cc 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanFqNames.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanFqNames.kt @@ -6,12 +6,12 @@ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.Name internal const val NATIVE_PTR_NAME = "NativePtr" internal const val NON_NULL_NATIVE_PTR_NAME = "NonNullNativePtr" internal const val VECTOR128 = "Vector128" +internal const val IMMUTABLE_BLOB_OF = "immutableBlobOf" object KonanFqNames { val function = FqName("kotlin.Function") diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt index 2ed1b7729da..c9e7d0d30c4 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/Ir.kt @@ -14,22 +14,29 @@ import org.jetbrains.kotlin.backend.konan.llvm.findMainEntryPoint import org.jetbrains.kotlin.backend.konan.lower.TestProcessor import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty +import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef +import org.jetbrains.kotlin.fir.types.constructClassLikeType import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.IrBuiltIns -import org.jetbrains.kotlin.ir.declarations.IrEnumEntry -import org.jetbrains.kotlin.ir.declarations.IrProperty -import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol +import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.defaultType -import org.jetbrains.kotlin.ir.types.typeWith +import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.findDeclaration +import org.jetbrains.kotlin.js.descriptorUtils.getKotlinTypeFqName +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe +import org.jetbrains.kotlin.types.TypeUtils object KonanNameConventions { val setWithoutBoundCheck = Name.special("") @@ -41,13 +48,19 @@ internal class KonanIr(context: Context, override val symbols: KonanSymbols): Ir internal abstract class KonanSymbols( context: PhaseContext, - descriptorsLookup: DescriptorsLookup, + val descriptorsLookup: DescriptorsLookup, // Please don't add usages of `descriptorsLookup` and `descriptorsLookup.builtIns` to this class anymore. irBuiltIns: IrBuiltIns, - internal val symbolTable: SymbolTable, + internal val symbolTable: SymbolTable, // Please don't add usages of `symbolTable` to this class anymore. lazySymbolTable: ReferenceSymbolTable ): Symbols(irBuiltIns, symbolTable) { - internal abstract fun IrClassSymbol.findMemberSimpleFunction(name: Name): IrSimpleFunctionSymbol? - internal abstract fun IrClassSymbol.findMemberPropertyGetter(name: Name): IrSimpleFunctionSymbol? + protected abstract fun IrClassSymbol.findMemberSimpleFunction(name: Name): IrSimpleFunctionSymbol? + protected abstract fun IrClassSymbol.findMemberProperty(name: Name): IrPropertySymbol? + protected abstract fun IrClassSymbol.findMemberPropertyGetter(name: Name): IrSimpleFunctionSymbol? + protected abstract fun findDefaultConstructor(className: String): IrConstructorSymbol + protected abstract fun findDefaultConstructor(className: String, nestedClassName: String): IrConstructorSymbol + protected abstract fun findTopLevelExtensionPropertyGetter(packageName: FqName, name: Name, extensionParameterClassID: ClassId): IrSimpleFunctionSymbol? + private fun findInteropExtensionPropertyGetter(name: Name, extensionClassID: ClassId): IrSimpleFunctionSymbol? = + findTopLevelExtensionPropertyGetter(InteropFqNames.packageName, name, extensionClassID) val entryPoint = findMainEntryPoint(context, descriptorsLookup.builtIns)?.let { symbolTable.referenceSimpleFunction(it) } @@ -56,11 +69,11 @@ internal abstract class KonanSymbols( val nothing get() = irBuiltIns.nothingClass val throwable get() = irBuiltIns.throwableClass val enum get() = irBuiltIns.enumClass - val nativePtr = symbolTable.referenceClass(descriptorsLookup.nativePtr) - val nativePointed = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.nativePointed) + private val nativePtr = internalClass(NATIVE_PTR_NAME) + val nativePointed = interopClass(InteropFqNames.nativePointedName) val nativePtrType = nativePtr.typeWith(arguments = emptyList()) - val immutableBlobOf = symbolTable.referenceSimpleFunction(descriptorsLookup.immutableBlobOf) + val immutableBlobOf = nativeFunction(IMMUTABLE_BLOB_OF) val signedIntegerClasses = setOf(byte, short, int, long) val unsignedIntegerClasses = setOf(uByte!!, uShort!!, uInt!!, uLong!!) @@ -95,41 +108,40 @@ internal abstract class KonanSymbols( val exportForCppRuntime = topLevelClass(RuntimeNames.exportForCppRuntime) val typedIntrinsic = topLevelClass(RuntimeNames.typedIntrinsicAnnotation) - val objCMethodImp = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.objCMethodImp) + val objCMethodImp = interopClass(InteropFqNames.objCMethodImpName) val processUnhandledException = irBuiltIns.findFunctions(Name.identifier("processUnhandledException"), "kotlin", "native").single() val terminateWithUnhandledException = irBuiltIns.findFunctions(Name.identifier("terminateWithUnhandledException"), "kotlin", "native").single() - val interopNativePointedGetRawPointer = - symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.nativePointedGetRawPointer) + abstract val interopNativePointedGetRawPointer: IrSimpleFunctionSymbol - val interopCPointer = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.cPointer) - val interopCstr = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.cstr.getter!!) - val interopWcstr = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.wcstr.getter!!) - val interopMemScope = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.memScope) - val interopCValue = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.cValue) - val interopCValuesRef = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.cValuesRef) - val interopCValueWrite = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.cValueWrite) - val interopCValueRead = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.cValueRead) - val interopAllocType = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.allocType) + val interopCPointer = interopClass(InteropFqNames.cPointerName) + val interopCstr = findInteropExtensionPropertyGetter(Name.identifier(InteropFqNames.cstrPropertyName), StandardClassIds.String)!! + val interopWcstr = findInteropExtensionPropertyGetter(Name.identifier(InteropFqNames.wcstrPropertyName), StandardClassIds.String)!! + val interopMemScope = interopClass(InteropFqNames.memScopeName) + val interopCValue = interopClass(InteropFqNames.cValueName) + val interopCValuesRef = interopClass(InteropFqNames.cValuesRefName) + abstract val interopCValueWrite: IrSimpleFunctionSymbol + abstract val interopCValueRead: IrSimpleFunctionSymbol + abstract val interopAllocType: IrSimpleFunctionSymbol - val interopTypeOf = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.typeOf) + val interopTypeOf = interopFunction(InteropFqNames.typeOfFunName) - val interopCPointerGetRawValue = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.cPointerGetRawValue) + abstract val interopCPointerGetRawValue: IrSimpleFunctionSymbol - val interopAllocObjCObject = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.allocObjCObject) + val interopAllocObjCObject = interopFunction(InteropFqNames.allocObjCObjectFunName) - val interopForeignObjCObject = interopClass("ForeignObjCObject") + val interopForeignObjCObject = interopClass(InteropFqNames.foreignObjCObjectName) // These are possible supertypes of forward declarations - we need to reference them explicitly to force their deserialization. // TODO: Do it lazily. - val interopCOpaque = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.cOpaque) - val interopObjCObject = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.objCObject) - val interopObjCObjectBase = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.objCObjectBase) - val interopObjCObjectBaseMeta = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.objCObjectBaseMeta) - val interopObjCClass = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.objCClass) - val interopObjCClassOf = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.objCClassOf) - val interopObjCProtocol = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.objCProtocol) + val interopCOpaque = interopClass(InteropFqNames.cOpaqueName) + val interopObjCObject = interopClass(InteropFqNames.objCObjectName) + val interopObjCObjectBase = interopClass(InteropFqNames.objCObjectBaseName) + val interopObjCObjectBaseMeta = interopClass(InteropFqNames.objCObjectBaseMetaName) + val interopObjCClass = interopClass(InteropFqNames.objCClassName) + val interopObjCClassOf = interopClass(InteropFqNames.objCClassOfName) + val interopObjCProtocol = interopClass(InteropFqNames.objCProtocolName) val interopObjCRelease = interopFunction("objc_release") @@ -147,49 +159,35 @@ internal abstract class KonanSymbols( val interopGetMessenger = interopFunction("getMessenger") val interopGetMessengerStret = interopFunction("getMessengerStret") - val interopGetObjCClass = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.getObjCClass) + val interopGetObjCClass = interopFunction(InteropFqNames.getObjCClassFunName) + val interopObjCObjectSuperInitCheck = interopFunction(InteropFqNames.objCObjectSuperInitCheckFunName) + val interopObjCObjectInitBy = interopFunction(InteropFqNames.objCObjectInitByFunName) + val interopObjCObjectRawValueGetter = interopFunction(InteropFqNames.objCObjectRawPtrFunName) - val interopObjCObjectSuperInitCheck = - symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.objCObjectSuperInitCheck) + val interopNativePointedRawPtrGetter = interopClass(InteropFqNames.nativePointedName) + .findMemberPropertyGetter(Name.identifier(InteropFqNames.nativePointedRawPtrPropertyName))!! - val interopObjCObjectInitBy = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.objCObjectInitBy) + val interopCPointerRawValue: IrPropertySymbol = interopClass(InteropFqNames.cPointerName) + .findMemberProperty(Name.identifier(InteropFqNames.cPointerRawValuePropertyName))!! - val interopObjCObjectRawValueGetter = - symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.objCObjectRawPtr) - - val interopNativePointedRawPtrGetter = - symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.nativePointedRawPtrGetter) - - val interopCPointerRawValue = - symbolTable.referenceProperty(descriptorsLookup.interopBuiltIns.cPointerRawValue) - - val interopInterpretObjCPointer = - symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.interpretObjCPointer) - - val interopInterpretObjCPointerOrNull = - symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.interpretObjCPointerOrNull) - - val interopInterpretNullablePointed = - symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.interpretNullablePointed) - - val interopInterpretCPointer = - symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.interpretCPointer) + val interopInterpretObjCPointer = interopFunction(InteropFqNames.interpretObjCPointerFunName) + val interopInterpretObjCPointerOrNull = interopFunction(InteropFqNames.interpretObjCPointerOrNullFunName) + val interopInterpretNullablePointed = interopFunction(InteropFqNames.interpretNullablePointedFunName) + val interopInterpretCPointer = interopFunction(InteropFqNames.interpretCPointerFunName) val createForeignException = interopFunction("CreateForeignException") val interopCEnumVar = interopClass("CEnumVar") - val nativeMemUtils = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.nativeMemUtils) + val nativeMemUtils = interopClass(InteropFqNames.nativeMemUtilsName) + val nativeHeap = interopClass(InteropFqNames.nativeHeapName) - val nativeHeap = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.nativeHeap) + abstract val interopGetPtr: IrSimpleFunctionSymbol + abstract val interopManagedGetPtr: IrSimpleFunctionSymbol - val interopGetPtr = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.interopGetPtr) - - val interopManagedGetPtr = symbolTable.referenceSimpleFunction(descriptorsLookup.interopBuiltIns.interopManagedGetPtr) - - val interopManagedType = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.managedType) - val interopCPlusPlusClass = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.cPlusPlusClass) - val interopSkiaRefCnt = symbolTable.referenceClass(descriptorsLookup.interopBuiltIns.skiaRefCnt) + val interopManagedType = interopClass(InteropFqNames.managedTypeName) + val interopCPlusPlusClass = interopClass(InteropFqNames.cPlusPlusClassName) + val interopSkiaRefCnt = interopClass(InteropFqNames.skiaRefCntName) val readBits = interopFunction("readBits") val writeBits = interopFunction("writeBits") @@ -200,7 +198,7 @@ internal abstract class KonanSymbols( val objCExportGetCoroutineSuspended = internalFunction("getCoroutineSuspended") val objCExportInterceptedContinuation = internalFunction("interceptedContinuation") - val getNativeNullPtr = symbolTable.referenceSimpleFunction(descriptorsLookup.getNativeNullPtr) + val getNativeNullPtr = internalFunction("getNativeNullPtr") val boxCachePredicates = BoxCache.values().associateWith { internalFunction("in${it.name.lowercase().replaceFirstChar(Char::uppercaseChar)}BoxCache") @@ -395,26 +393,19 @@ internal abstract class KonanSymbols( val sharedImmutable = topLevelClass(KonanFqNames.sharedImmutable) - val volatile = topLevelClass(KonanFqNames.volatile) - val eagerInitialization = topLevelClass(KonanFqNames.eagerInitialization) - val cStructVarConstructorSymbol = symbolTable.referenceConstructor( - descriptorsLookup.interopBuiltIns.cStructVar.unsubstitutedPrimaryConstructor!! - ) - val managedTypeConstructor = symbolTable.referenceConstructor( - descriptorsLookup.interopBuiltIns.managedType.unsubstitutedPrimaryConstructor!! - ) - val enumVarConstructorSymbol = symbolTable.referenceConstructor( - descriptorsLookup.interopBuiltIns.cEnumVar.unsubstitutedPrimaryConstructor!! - ) - val primitiveVarPrimaryConstructor = symbolTable.referenceConstructor( - descriptorsLookup.interopBuiltIns.cPrimitiveVarType.unsubstitutedPrimaryConstructor!!) - val structVarPrimaryConstructor = symbolTable.referenceConstructor( - descriptorsLookup.interopBuiltIns.cStructVarType.unsubstitutedPrimaryConstructor!!) + val cStructVarConstructorSymbol = findDefaultConstructor(InteropFqNames.cStructVarName) + val managedTypeConstructor = findDefaultConstructor(InteropFqNames.managedTypeName) + val enumVarConstructorSymbol = findDefaultConstructor(InteropFqNames.cEnumVarName) + val primitiveVarPrimaryConstructor = findDefaultConstructor(InteropFqNames.cPrimitiveVarName, InteropFqNames.TypeName) + val structVarPrimaryConstructor = findDefaultConstructor(InteropFqNames.cStructVarName, InteropFqNames.TypeName) private fun topLevelClass(fqName: FqName): IrClassSymbol = irBuiltIns.findClass(fqName.shortName(), fqName.parent())!! + private fun nativeFunction(name: String) = + irBuiltIns.findFunctions(Name.identifier(name), KonanFqNames.packageName).single() + private fun internalFunction(name: String) = irBuiltIns.findFunctions(Name.identifier(name), RuntimeNames.kotlinNativeInternalPackageName).single() @@ -433,7 +424,7 @@ internal abstract class KonanSymbols( private fun interopFunction(name: String) = irBuiltIns.findFunctions(Name.identifier(name), InteropFqNames.packageName).single() - private fun interopClass(name: String) = + protected fun interopClass(name: String) = irBuiltIns.findClass(Name.identifier(name), InteropFqNames.packageName)!! fun kFunctionN(n: Int) = irBuiltIns.kFunctionN(n).symbol @@ -466,6 +457,8 @@ internal abstract class KonanSymbols( fun getTestFunctionKind(kind: TestProcessor.FunctionKind) = testFunctionKindCache[kind]!! } +// WARNING: override protected functions are called from base class(`KonanSymbols`) constructor, +// so its functionality must be independent of the derived object(`KonanSymbolsOverDescriptors`)'s state, which is uninitialized at the invocation moment internal class KonanSymbolsOverDescriptors( context: PhaseContext, descriptorsLookup: DescriptorsLookup, @@ -479,13 +472,88 @@ internal class KonanSymbolsOverDescriptors( .singleOrNull() ?.let { symbolTable.referenceSimpleFunction(it) } + override fun IrClassSymbol.findMemberProperty(name: Name): IrPropertySymbol? = + descriptor.unsubstitutedMemberScope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND) + .singleOrNull() + ?.let { symbolTable.referenceProperty(it) } + override fun IrClassSymbol.findMemberPropertyGetter(name: Name): IrSimpleFunctionSymbol? = descriptor.unsubstitutedMemberScope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND) .singleOrNull() ?.getter ?.let { symbolTable.referenceSimpleFunction(it) } + + override fun findTopLevelExtensionPropertyGetter(packageName: FqName, name: Name, extensionParameterClassID: ClassId): IrSimpleFunctionSymbol? { + val extensionParameterFqNameString = extensionParameterClassID.asFqNameString() + return descriptorsLookup.builtIns.builtInsModule.getPackage(InteropFqNames.packageName).memberScope + .getContributedVariables(name, NoLookupLocation.FROM_BACKEND) + .singleOrNull { + it.extensionReceiverParameter?.type?.getKotlinTypeFqName(true) == extensionParameterFqNameString + }?.getter + ?.let { symbolTable.referenceSimpleFunction(it) } + } + + override val interopNativePointedGetRawPointer = symbolTable.referenceSimpleFunction( + descriptorsLookup.interopBuiltIns.getContributedFunctions(InteropFqNames.nativePointedGetRawPointerFunName).single { + val extensionReceiverParameter = it.extensionReceiverParameter + extensionReceiverParameter != null && + TypeUtils.getClassDescriptor(extensionReceiverParameter.type)?.fqNameUnsafe == InteropFqNames.nativePointed + }) + override val interopCValueWrite = symbolTable.referenceSimpleFunction( + descriptorsLookup.interopBuiltIns.getContributedFunctions(InteropFqNames.cValueWriteFunName).single { + it.extensionReceiverParameter?.type?.constructor?.declarationDescriptor?.fqNameSafe == InteropFqNames.cValue + }) + override val interopCValueRead = symbolTable.referenceSimpleFunction( + descriptorsLookup.interopBuiltIns.getContributedFunctions(InteropFqNames.cValueReadFunName).single { + it.valueParameters.size == 1 + }) + override val interopAllocType = symbolTable.referenceSimpleFunction( + descriptorsLookup.interopBuiltIns.getContributedFunctions(InteropFqNames.allocTypeFunName).single { + it.extensionReceiverParameter != null && it.valueParameters.singleOrNull()?.name?.toString() == "type" + }) + override val interopCPointerGetRawValue = symbolTable.referenceSimpleFunction( + descriptorsLookup.interopBuiltIns.getContributedFunctions(InteropFqNames.cPointerGetRawValueFunName).single { + val extensionReceiverParameter = it.extensionReceiverParameter + extensionReceiverParameter != null && + TypeUtils.getClassDescriptor(extensionReceiverParameter.type)?.fqNameUnsafe == InteropFqNames.cPointer + }) + + override fun findDefaultConstructor(className: String): IrConstructorSymbol = symbolTable.referenceConstructor( + descriptorsLookup.interopBuiltIns.getContributedClass(className) + .unsubstitutedPrimaryConstructor!! + ) + + override fun findDefaultConstructor(className: String, nestedClassName: String): IrConstructorSymbol = symbolTable.referenceConstructor( + descriptorsLookup.interopBuiltIns.getContributedClass(className) + .defaultType.memberScope.getContributedClass(nestedClassName) + .unsubstitutedPrimaryConstructor!! + ) + + override val interopGetPtr = descriptorsLookup.interopBuiltIns.getContributedVariables("ptr").single { + val singleTypeParameter = it.typeParameters.singleOrNull() + val singleTypeParameterUpperBound = singleTypeParameter?.upperBounds?.singleOrNull() + val extensionReceiverParameter = it.extensionReceiverParameter + + singleTypeParameterUpperBound != null && + extensionReceiverParameter != null && + TypeUtils.getClassDescriptor(singleTypeParameterUpperBound)?.fqNameSafe == InteropFqNames.cPointed && + extensionReceiverParameter.type == singleTypeParameter.defaultType + }.getter!!.let { symbolTable.referenceSimpleFunction(it) } + + override val interopManagedGetPtr = descriptorsLookup.interopBuiltIns.getContributedVariables("ptr").single { + val singleTypeParameter = it.typeParameters.singleOrNull() + val singleTypeParameterUpperBound = singleTypeParameter?.upperBounds?.singleOrNull() + val extensionReceiverParameter = it.extensionReceiverParameter + + singleTypeParameterUpperBound != null && + extensionReceiverParameter != null && + TypeUtils.getClassDescriptor(singleTypeParameterUpperBound)?.fqNameSafe == InteropFqNames.cStructVar && + TypeUtils.getClassDescriptor(extensionReceiverParameter.type)?.fqNameSafe == InteropFqNames.managedType + }.getter!!.let { symbolTable.referenceSimpleFunction(it) } } +// WARNING: override protected functions are called from base class(`KonanSymbols`) constructor, +// so its functionality must be independent of the derived object(`KonanSymbolsOverFir`)'s state, which is uninitialized at the invocation moment internal class KonanSymbolsOverFir( context: PhaseContext, descriptorsLookup: DescriptorsLookup, @@ -496,6 +564,73 @@ internal class KonanSymbolsOverFir( override fun IrClassSymbol.findMemberSimpleFunction(name: Name): IrSimpleFunctionSymbol? = owner.findDeclaration { it.name == name }?.symbol + override fun IrClassSymbol.findMemberProperty(name: Name): IrPropertySymbol? = + owner.findDeclaration { it.name == name }?.symbol + override fun IrClassSymbol.findMemberPropertyGetter(name: Name): IrSimpleFunctionSymbol? = owner.findDeclaration { it.name == name }?.getter?.symbol + + override fun findTopLevelExtensionPropertyGetter(packageName: FqName, name: Name, extensionParameterClassID: ClassId): IrSimpleFunctionSymbol? { + val extensionParameterConeKotlinType = extensionParameterClassID.constructClassLikeType(arrayOf(), false).type + return irBuiltIns.findProperties(name, packageName).singleOrNull { + ((it.owner as Fir2IrLazyProperty).fir.receiverParameter?.typeRef as FirResolvedTypeRef).type == extensionParameterConeKotlinType + }?.owner?.getter?.symbol + } + + override val interopNativePointedGetRawPointer = findSingleInteropFunction(InteropFqNames.nativePointedGetRawPointerFunName) { + val extensionReceiverParameter = it.owner.extensionReceiverParameter + extensionReceiverParameter != null && + extensionReceiverParameter.type.classFqName?.toUnsafe() == InteropFqNames.nativePointed + } + override val interopCValueWrite = findSingleInteropFunction(InteropFqNames.cValueWriteFunName) { + it.owner.extensionReceiverParameter?.type?.classFqName == InteropFqNames.cValue + } + override val interopCValueRead = findSingleInteropFunction(InteropFqNames.cValueReadFunName) { + it.owner.valueParameters.size == 1 + } + override val interopAllocType = findSingleInteropFunction(InteropFqNames.allocTypeFunName) { + it.owner.extensionReceiverParameter != null && it.owner.valueParameters.singleOrNull()?.name?.toString() == "type" + } + override val interopCPointerGetRawValue = findSingleInteropFunction(InteropFqNames.cPointerGetRawValueFunName) { + it.owner.extensionReceiverParameter?.type?.classFqName?.toUnsafe() == InteropFqNames.cPointer + } + + override val interopGetPtr = irBuiltIns.findProperties(Name.identifier("ptr"), InteropFqNames.packageName).single { + val singleTypeParameter = it.owner.getter?.typeParameters?.singleOrNull() + val singleTypeParameterUpperBound = singleTypeParameter?.symbol?.superTypes()?.singleOrNull() + val extensionReceiverParameter = it.owner.getter?.extensionReceiverParameter + + singleTypeParameterUpperBound != null && + extensionReceiverParameter != null && + singleTypeParameterUpperBound.classFqName == InteropFqNames.cPointed && + extensionReceiverParameter.type.classFqName == singleTypeParameter.defaultType.classFqName + }.owner.getter!!.symbol + + override val interopManagedGetPtr = irBuiltIns.findProperties(Name.identifier("ptr"), InteropFqNames.packageName).single { + val singleTypeParameter = it.owner.getter?.typeParameters?.singleOrNull() + val singleTypeParameterUpperBound = singleTypeParameter?.symbol?.superTypes()?.singleOrNull() + val extensionReceiverParameter = it.owner.getter?.extensionReceiverParameter + + singleTypeParameterUpperBound != null && + extensionReceiverParameter != null && + singleTypeParameterUpperBound.classFqName == InteropFqNames.cStructVar && + extensionReceiverParameter.type.classFqName == InteropFqNames.managedType + }.owner.getter!!.symbol + + private fun findSingleInteropFunction(name: String, predicate: (IrSimpleFunctionSymbol) -> Boolean) = + irBuiltIns.findFunctions(Name.identifier(name), InteropFqNames.packageName).single(predicate) + + override fun findDefaultConstructor(className: String): IrConstructorSymbol = + interopClass(className).owner.declarations.single { + it is IrConstructor && it.isPrimary + }.symbol as IrConstructorSymbol + + override fun findDefaultConstructor(className: String, nestedClassName: String): IrConstructorSymbol { + val nested = interopClass(className).owner.declarations.single { + it is IrClass && it.name == Name.identifier(nestedClassName) + }.symbol as IrClassSymbol + return nested.owner.declarations.single { + it is IrConstructor && it.isPrimary + }.symbol as IrConstructorSymbol + } }