[KLIB] Create an abstract class for module deserializer

- Introduce Ir-based Functional interface factory
 - Switch from LazyIr to pure
 - Use kotlin library to access raw bytes
 - Link dirty files against IC cache and dependencies instead of LazyIr
 - Move `DescriptorByIdSignatureFinder` from K/N to common
 - Support inline-bodies only MODE
This commit is contained in:
Roman Artemev
2020-03-16 17:19:51 +03:00
committed by romanart
parent 74132fbc03
commit a9788f9506
19 changed files with 1647 additions and 801 deletions
@@ -102,6 +102,7 @@ fun generateKLib(
val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER)
val icData: List<KotlinFileSerializedData>
val serializedIrFiles: List<SerializedIrFile>?
if (incrementalDataProvider != null) {
val nonCompiledSources = files.map { VfsUtilCore.virtualToIoFile(it.virtualFile) to it }.toMap()
@@ -124,8 +125,10 @@ fun generateKLib(
}
icData = storage
serializedIrFiles = storage.map { it.irData }
} else {
icData = emptyList()
serializedIrFiles = null
}
val depsDescriptors =
@@ -135,8 +138,13 @@ fun generateKLib(
val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files,
deserializer = null, expectDescriptorToSymbol = expectDescriptorToSymbol)
val irLinker = JsIrLinker(psi2IrContext.moduleDescriptor, emptyLoggingContext, psi2IrContext.irBuiltIns, psi2IrContext.symbolTable, serializedIrFiles)
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
irLinker.deserializeOnlyHeaderModule(depsDescriptors.getModuleDescriptor(it), it)
}
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files, irLinker, expectDescriptorToSymbol)
moduleFragment.acceptVoid(ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc)))
@@ -193,22 +201,20 @@ fun loadIr(
val irBuiltIns = psi2IrContext.irBuiltIns
val symbolTable = psi2IrContext.symbolTable
val deserializer = JsIrLinker(emptyLoggingContext, irBuiltIns, symbolTable)
val irLinker = JsIrLinker(psi2IrContext.moduleDescriptor, emptyLoggingContext, irBuiltIns, symbolTable, null)
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it))!!
irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it), it)
}
deserializer.initializeExpectActualLinker()
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, mainModule.files, deserializer)
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, mainModule.files, irLinker)
// TODO: not sure whether this check should be enabled by default. Add configuration key for it.
val mangleChecker = ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc))
moduleFragment.acceptVoid(mangleChecker)
irBuiltIns.knownBuiltins.forEach { it.acceptVoid(mangleChecker) }
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, deserializer)
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker)
}
is MainModule.Klib -> {
val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModule.lib)
@@ -224,7 +230,7 @@ fun loadIr(
typeTranslator.constantValueGenerator = constantValueGenerator
constantValueGenerator.typeTranslator = typeTranslator
val irBuiltIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable)
val deserializer = JsIrLinker(emptyLoggingContext, irBuiltIns, symbolTable)
val irLinker = JsIrLinker(null, emptyLoggingContext, irBuiltIns, symbolTable, null)
val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map {
val strategy =
@@ -233,16 +239,16 @@ fun loadIr(
else
DeserializationStrategy.EXPLICITLY_EXPORTED
deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it), strategy)
irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it), it, strategy)
}
deserializer.initializeExpectActualLinker()
val moduleFragment = deserializedModuleFragments.last()
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
ExternalDependenciesGenerator(symbolTable, irProviders, configuration.languageVersionSettings)
.generateUnboundSymbolsAsDependencies()
irLinker.init(null, emptyList())
ExternalDependenciesGenerator(symbolTable, listOf(irLinker), configuration.languageVersionSettings).generateUnboundSymbolsAsDependencies()
irLinker.postProcess()
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, deserializer)
return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, irLinker)
}
}
}
@@ -266,14 +272,15 @@ private fun runAnalysisAndPreparePsi2Ir(depsDescriptors: ModulesStructure): Gene
fun GeneratorContext.generateModuleFragmentWithPlugins(
project: Project,
files: List<KtFile>,
deserializer: IrDeserializer? = null,
irLinker: IrDeserializer,
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
): IrModuleFragment {
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
val signaturer = IdSignatureDescriptor(JsManglerDesc)
val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration, signaturer)
for (extension in IrGenerationExtension.getInstances(project)) {
val extensions = IrGenerationExtension.getInstances(project)
for (extension in extensions) {
psi2Ir.addPostprocessingStep { module ->
extension.generate(
module,
@@ -289,26 +296,9 @@ fun GeneratorContext.generateModuleFragmentWithPlugins(
}
}
val moduleFragment =
psi2Ir.generateModuleFragment(
this,
files,
irProviders,
expectDescriptorToSymbol
)
return moduleFragment
return psi2Ir.generateModuleFragment(this, files, listOf(irLinker), expectDescriptorToSymbol, extensions)
}
fun GeneratorContext.generateModuleFragment(files: List<KtFile>, deserializer: IrDeserializer? = null, expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null): IrModuleFragment {
val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer)
val mangler = JsManglerDesc
val signaturer = IdSignatureDescriptor(mangler)
return Psi2IrTranslator(
languageVersionSettings, configuration, signaturer
).generateModuleFragment(this, files, irProviders, expectDescriptorToSymbol)
}
private fun createBuiltIns(storageManager: StorageManager) = object : KotlinBuiltIns(storageManager) {}
internal val JsFactories = KlibMetadataFactories(::createBuiltIns, DynamicTypeDeserializer)
@@ -6,40 +6,45 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.LoggingContext
import org.jetbrains.kotlin.backend.common.serialization.CurrentModuleWithICDeserializer
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
import org.jetbrains.kotlin.backend.common.serialization.IrModuleDeserializer
import org.jetbrains.kotlin.backend.common.serialization.KotlinIrLinker
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.descriptors.IrFunctionFactory
import org.jetbrains.kotlin.ir.util.IrExtensionGenerator
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.library.IrLibrary
import org.jetbrains.kotlin.library.SerializedIrFile
class JsIrLinker(logger: LoggingContext, builtIns: IrBuiltIns, symbolTable: SymbolTable) :
KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null) {
class JsIrLinker(currentModule: ModuleDescriptor?, logger: LoggingContext, builtIns: IrBuiltIns, symbolTable: SymbolTable, private val icData: List<SerializedIrFile>? = null) :
KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList()) {
override fun reader(moduleDescriptor: ModuleDescriptor, fileIndex: Int, idSigIndex: Int) =
moduleDescriptor.kotlinLibrary.irDeclaration(idSigIndex, fileIndex)
override val functionalInteraceFactory: IrAbstractFunctionFactory = IrFunctionFactory(builtIns, symbolTable)
override fun readType(moduleDescriptor: ModuleDescriptor, fileIndex: Int, typeIndex: Int) =
moduleDescriptor.kotlinLibrary.type(typeIndex, fileIndex)
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean =
moduleDescriptor === moduleDescriptor.builtIns.builtInsModule
override fun readSignature(moduleDescriptor: ModuleDescriptor, fileIndex: Int, signatureIndex: Int) =
moduleDescriptor.kotlinLibrary.signature(signatureIndex, fileIndex)
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer =
JsModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy)
override fun readString(moduleDescriptor: ModuleDescriptor, fileIndex: Int, stringIndex: Int) =
moduleDescriptor.kotlinLibrary.string(stringIndex, fileIndex)
private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy) :
KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy)
override fun readBody(moduleDescriptor: ModuleDescriptor, fileIndex: Int, bodyIndex: Int) =
moduleDescriptor.kotlinLibrary.body(bodyIndex, fileIndex)
override fun readFile(moduleDescriptor: ModuleDescriptor, fileIndex: Int) =
moduleDescriptor.kotlinLibrary.file(fileIndex)
override fun readFileCount(moduleDescriptor: ModuleDescriptor) =
moduleDescriptor.kotlinLibrary.fileCount()
override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, strategy: DeserializationStrategy): IrModuleDeserializer =
JsModuleDeserializer(moduleDescriptor, strategy)
private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, strategy: DeserializationStrategy) :
KotlinIrLinker.IrModuleDeserializer(moduleDescriptor, strategy)
}
override fun createCurrentModuleDeserializer(
moduleFragment: IrModuleFragment,
dependencies: Collection<IrModuleDeserializer>,
extensions: Collection<IrExtensionGenerator>
): IrModuleDeserializer {
val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies, extensions)
icData?.let {
return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it) { lib ->
JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategy)
}
}
return currentModuleDeserializer
}
}