From 17ef26b4f80914ab9a67857b2b951a123a819537 Mon Sep 17 00:00:00 2001 From: Alexander Gorshenev Date: Sun, 17 May 2020 02:16:16 +0300 Subject: [PATCH] K/N counterparts for: Construct fake overrides after IR deserialization Signature based fake override validation (cherry picked from commit c2b1b976d79d7bbe9e80b8f7f2f382420c2d3805) --- .../kotlin/backend/konan/ToplevelPhases.kt | 23 ++++++++------ .../ir/interop/IrProviderForInteropStubs.kt | 31 ------------------- .../kotlin/backend/konan/llvm/ContextUtils.kt | 3 +- .../backend/konan/optimizations/DataFlowIR.kt | 4 ++- .../serialization/KonanIrFileSerializer.kt | 2 ++ .../konan/serialization/KonanIrlinker.kt | 10 ++++++ 6 files changed, 30 insertions(+), 43 deletions(-) delete mode 100644 backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForInteropStubs.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt index 48ce60555bb..8bd64b13a73 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt @@ -3,6 +3,7 @@ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension +import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker import org.jetbrains.kotlin.backend.common.phaser.* import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter @@ -19,18 +20,17 @@ import org.jetbrains.kotlin.backend.konan.serialization.* import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.languageVersionSettings -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib -import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.konan.target.CompilerOutputKind -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator import org.jetbrains.kotlin.utils.DFS @@ -168,7 +168,8 @@ internal val psiToIrPhase = konanUnitPhase( val irProviderForCEnumsAndCStructs = IrProviderForCEnumAndCStructStubs(generatorContext, interopBuiltIns, symbols) - val deserializer = KonanIrLinker( + val linker = + KonanIrLinker( moduleDescriptor, functionIrClassFactory, this as LoggingContext, @@ -188,7 +189,7 @@ internal val psiToIrPhase = konanUnitPhase( generatorContext.symbolTable, generatorContext.typeTranslator, generatorContext.irBuiltIns, - linker = deserializer + linker = linker ) pluginExtensions.forEach { extension -> extension.generate(module, pluginContext) @@ -212,7 +213,7 @@ internal val psiToIrPhase = konanUnitPhase( val kotlinLibrary = dependency.getCapability(KlibModuleOrigin.CAPABILITY)?.let { (it as? DeserializedKlibModuleOrigin)?.library } - deserializer.deserializeIrModuleHeader(dependency, kotlinLibrary) + linker.deserializeIrModuleHeader(dependency, kotlinLibrary) } if (dependencies.size == dependenciesCount) break dependenciesCount = dependencies.size @@ -224,7 +225,7 @@ internal val psiToIrPhase = konanUnitPhase( .filter(ModuleDescriptor::isFromInteropLibrary) .forEach(irProviderForCEnumsAndCStructs::referenceAllEnumsAndStructsFrom) - val irProviders = listOf(deserializer) + val irProviders = listOf(linker) stubGenerator.setIrProviders(irProviders) expectDescriptorToSymbol = mutableMapOf() @@ -239,7 +240,7 @@ internal val psiToIrPhase = konanUnitPhase( if (expectActualLinker) expectDescriptorToSymbol else null ) - deserializer.postProcess() + linker.postProcess() if (this.stdlibModule in modulesWithoutDCE) { functionIrClassFactory.buildAllClasses() @@ -249,13 +250,15 @@ internal val psiToIrPhase = konanUnitPhase( stubGenerator.unboundSymbolGeneration = true module.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc))) + val fakeOverrideChecker = FakeOverrideChecker(KonanManglerIr, KonanManglerDesc) + linker.modules.values.forEach{ fakeOverrideChecker.check(it) } irModule = module - irModules = deserializer.modules.filterValues { llvmModuleSpecification.containsModule(it) } + irModules = linker.modules.filterValues { llvmModuleSpecification.containsModule(it) } ir.symbols = symbols functionIrClassFactory.module = - (listOf(irModule!!) + deserializer.modules.values) + (listOf(irModule!!) + linker.modules.values) .single { it.descriptor.isNativeStdlib() } }, name = "Psi2Ir", diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForInteropStubs.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForInteropStubs.kt deleted file mode 100644 index 55158fea077..00000000000 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForInteropStubs.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license - * that can be found in the LICENSE file. - */ -package org.jetbrains.kotlin.backend.konan.ir.interop - -import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator -import org.jetbrains.kotlin.ir.util.IdSignature -import org.jetbrains.kotlin.ir.util.IrProvider - -/** - * Generates external IR declarations for descriptors from interop libraries. - * [isSpecialInteropCase] allows to delegate providing of interop symbols to other providers. - * For example, for CEnums we need to generate non-lazy IR. - */ -class IrProviderForInteropStubs( - private val declarationStubGenerator: DeclarationStubGenerator, - private val isSpecialInteropCase: (IrSymbol) -> Boolean -) : IrProvider { - override fun getDeclaration(symbol: IrSymbol): IrDeclaration? = - when { - symbol.isBound -> symbol.owner as IrDeclaration - isSpecialInteropCase(symbol) -> null - symbol.isPublicApi && symbol.signature.run { IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY.test() } -> - declarationStubGenerator.generateMemberStub(symbol.descriptor) - else -> null - } - -} \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index 386bc1a5ed6..f0bdd4d3a19 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -15,9 +15,11 @@ import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization import org.jetbrains.kotlin.ir.util.isReal +import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.KotlinLibrary @@ -164,7 +166,6 @@ internal interface ContextUtils : RuntimeAware { val IrFunction.llvmFunctionOrNull: LLVMValueRef? get() { assert(this.isReal) - return if (isExternal(this)) { runtime.addedLLVMExternalFunctions.getOrPut(this) { context.llvm.externalFunction(this.symbolName, getLlvmFunctionType(this), origin = this.llvmSymbolOrigin) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt index 0e71ff9f5cb..5c4ae6e40b5 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt @@ -527,7 +527,9 @@ internal object DataFlowIR { type.superTypes += irClass.superTypes.map { mapClassReferenceType(it.getClass()!!) } if (!isAbstract) { val layoutBuilder = context.getLayoutBuilder(irClass) - type.vtable += layoutBuilder.vtableEntries.map { mapFunction(it.getImplementation(context)!!) } + type.vtable += layoutBuilder.vtableEntries.map { + mapFunction(it.getImplementation(context)!!) + } layoutBuilder.methodTableEntries.forEach { type.itable[it.overriddenFunction.functionName.localHash.value] = mapFunction(it.getImplementation(context)!!) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrFileSerializer.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrFileSerializer.kt index a182caf5c5c..2a34d1f745c 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrFileSerializer.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrFileSerializer.kt @@ -23,4 +23,6 @@ class KonanIrFileSerializer( override fun backendSpecificExplicitRoot(declaration: IrClass) = declaration.annotations.hasAnnotation(RuntimeNames.exportTypeInfoAnnotation) + + override fun backendSpecificSerializeAllMembers(irClass: IrClass) = !KonanFakeOverrideClassFilter.constructFakeOverrides(irClass) } \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt index cc165e6c9a0..50d92027fa6 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt @@ -17,11 +17,15 @@ package org.jetbrains.kotlin.backend.konan.serialization import org.jetbrains.kotlin.backend.common.LoggingContext +import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilderImpl +import org.jetbrains.kotlin.backend.common.overrides.PlatformFakeOverrideClassFilter import org.jetbrains.kotlin.backend.common.serialization.* import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData +import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs +import org.jetbrains.kotlin.backend.konan.isObjCClass import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary @@ -41,6 +45,10 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.module +object KonanFakeOverrideClassFilter : PlatformFakeOverrideClassFilter { + override fun constructFakeOverrides(clazz: IrClass): Boolean = !clazz.isObjCClass() +} + internal class KonanIrLinker( private val currentModule: ModuleDescriptor, override val functionalInteraceFactory: IrAbstractFunctionFactory, @@ -64,6 +72,8 @@ internal class KonanIrLinker( override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor.isNativeStdlib() + override val fakeOverrideBuilderImpl = FakeOverrideBuilderImpl(symbolTable, IdSignatureSerializer(KonanManglerIr), builtIns, KonanFakeOverrideClassFilter) + private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserialier(it) } override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer {