K/N counterparts for:

Construct fake overrides after IR deserialization
Signature based fake override validation

(cherry picked from commit c2b1b976d79d7bbe9e80b8f7f2f382420c2d3805)
This commit is contained in:
Alexander Gorshenev
2020-05-17 02:16:16 +03:00
committed by Vasily Levchenko
parent 212393e419
commit 17ef26b4f8
6 changed files with 30 additions and 43 deletions
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension 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.phaser.*
import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker
import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter 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.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings 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.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib 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.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
@@ -168,7 +168,8 @@ internal val psiToIrPhase = konanUnitPhase(
val irProviderForCEnumsAndCStructs = val irProviderForCEnumsAndCStructs =
IrProviderForCEnumAndCStructStubs(generatorContext, interopBuiltIns, symbols) IrProviderForCEnumAndCStructStubs(generatorContext, interopBuiltIns, symbols)
val deserializer = KonanIrLinker( val linker =
KonanIrLinker(
moduleDescriptor, moduleDescriptor,
functionIrClassFactory, functionIrClassFactory,
this as LoggingContext, this as LoggingContext,
@@ -188,7 +189,7 @@ internal val psiToIrPhase = konanUnitPhase(
generatorContext.symbolTable, generatorContext.symbolTable,
generatorContext.typeTranslator, generatorContext.typeTranslator,
generatorContext.irBuiltIns, generatorContext.irBuiltIns,
linker = deserializer linker = linker
) )
pluginExtensions.forEach { extension -> pluginExtensions.forEach { extension ->
extension.generate(module, pluginContext) extension.generate(module, pluginContext)
@@ -212,7 +213,7 @@ internal val psiToIrPhase = konanUnitPhase(
val kotlinLibrary = dependency.getCapability(KlibModuleOrigin.CAPABILITY)?.let { val kotlinLibrary = dependency.getCapability(KlibModuleOrigin.CAPABILITY)?.let {
(it as? DeserializedKlibModuleOrigin)?.library (it as? DeserializedKlibModuleOrigin)?.library
} }
deserializer.deserializeIrModuleHeader(dependency, kotlinLibrary) linker.deserializeIrModuleHeader(dependency, kotlinLibrary)
} }
if (dependencies.size == dependenciesCount) break if (dependencies.size == dependenciesCount) break
dependenciesCount = dependencies.size dependenciesCount = dependencies.size
@@ -224,7 +225,7 @@ internal val psiToIrPhase = konanUnitPhase(
.filter(ModuleDescriptor::isFromInteropLibrary) .filter(ModuleDescriptor::isFromInteropLibrary)
.forEach(irProviderForCEnumsAndCStructs::referenceAllEnumsAndStructsFrom) .forEach(irProviderForCEnumsAndCStructs::referenceAllEnumsAndStructsFrom)
val irProviders = listOf(deserializer) val irProviders = listOf(linker)
stubGenerator.setIrProviders(irProviders) stubGenerator.setIrProviders(irProviders)
expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>() expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
@@ -239,7 +240,7 @@ internal val psiToIrPhase = konanUnitPhase(
if (expectActualLinker) expectDescriptorToSymbol else null if (expectActualLinker) expectDescriptorToSymbol else null
) )
deserializer.postProcess() linker.postProcess()
if (this.stdlibModule in modulesWithoutDCE) { if (this.stdlibModule in modulesWithoutDCE) {
functionIrClassFactory.buildAllClasses() functionIrClassFactory.buildAllClasses()
@@ -249,13 +250,15 @@ internal val psiToIrPhase = konanUnitPhase(
stubGenerator.unboundSymbolGeneration = true stubGenerator.unboundSymbolGeneration = true
module.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc))) module.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc)))
val fakeOverrideChecker = FakeOverrideChecker(KonanManglerIr, KonanManglerDesc)
linker.modules.values.forEach{ fakeOverrideChecker.check(it) }
irModule = module irModule = module
irModules = deserializer.modules.filterValues { llvmModuleSpecification.containsModule(it) } irModules = linker.modules.filterValues { llvmModuleSpecification.containsModule(it) }
ir.symbols = symbols ir.symbols = symbols
functionIrClassFactory.module = functionIrClassFactory.module =
(listOf(irModule!!) + deserializer.modules.values) (listOf(irModule!!) + linker.modules.values)
.single { it.descriptor.isNativeStdlib() } .single { it.descriptor.isNativeStdlib() }
}, },
name = "Psi2Ir", name = "Psi2Ir",
@@ -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
}
}
@@ -15,9 +15,11 @@ import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.ir.declarations.* 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.file
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.util.isReal 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.library.KonanLibrary
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.KotlinLibrary
@@ -164,7 +166,6 @@ internal interface ContextUtils : RuntimeAware {
val IrFunction.llvmFunctionOrNull: LLVMValueRef? val IrFunction.llvmFunctionOrNull: LLVMValueRef?
get() { get() {
assert(this.isReal) assert(this.isReal)
return if (isExternal(this)) { return if (isExternal(this)) {
runtime.addedLLVMExternalFunctions.getOrPut(this) { context.llvm.externalFunction(this.symbolName, getLlvmFunctionType(this), runtime.addedLLVMExternalFunctions.getOrPut(this) { context.llvm.externalFunction(this.symbolName, getLlvmFunctionType(this),
origin = this.llvmSymbolOrigin) } origin = this.llvmSymbolOrigin) }
@@ -527,7 +527,9 @@ internal object DataFlowIR {
type.superTypes += irClass.superTypes.map { mapClassReferenceType(it.getClass()!!) } type.superTypes += irClass.superTypes.map { mapClassReferenceType(it.getClass()!!) }
if (!isAbstract) { if (!isAbstract) {
val layoutBuilder = context.getLayoutBuilder(irClass) 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 { layoutBuilder.methodTableEntries.forEach {
type.itable[it.overriddenFunction.functionName.localHash.value] = mapFunction(it.getImplementation(context)!!) type.itable[it.overriddenFunction.functionName.localHash.value] = mapFunction(it.getImplementation(context)!!)
} }
@@ -23,4 +23,6 @@ class KonanIrFileSerializer(
override fun backendSpecificExplicitRoot(declaration: IrClass) = override fun backendSpecificExplicitRoot(declaration: IrClass) =
declaration.annotations.hasAnnotation(RuntimeNames.exportTypeInfoAnnotation) declaration.annotations.hasAnnotation(RuntimeNames.exportTypeInfoAnnotation)
override fun backendSpecificSerializeAllMembers(irClass: IrClass) = !KonanFakeOverrideClassFilter.constructFakeOverrides(irClass)
} }
@@ -17,11 +17,15 @@
package org.jetbrains.kotlin.backend.konan.serialization package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.backend.common.LoggingContext 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.*
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData 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.isInteropLibrary
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs 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.*
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary 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.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
object KonanFakeOverrideClassFilter : PlatformFakeOverrideClassFilter {
override fun constructFakeOverrides(clazz: IrClass): Boolean = !clazz.isObjCClass()
}
internal class KonanIrLinker( internal class KonanIrLinker(
private val currentModule: ModuleDescriptor, private val currentModule: ModuleDescriptor,
override val functionalInteraceFactory: IrAbstractFunctionFactory, override val functionalInteraceFactory: IrAbstractFunctionFactory,
@@ -64,6 +72,8 @@ internal class KonanIrLinker(
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor.isNativeStdlib() override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor.isNativeStdlib()
override val fakeOverrideBuilderImpl = FakeOverrideBuilderImpl(symbolTable, IdSignatureSerializer(KonanManglerIr), builtIns, KonanFakeOverrideClassFilter)
private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserialier(it) } private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserialier(it) }
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer { override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer {