[Native] Move KonanPartialModuleDeserializer to a separate file
This commit is contained in:
+2
-2
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.backend.konan.NativeGenerationState
|
|||||||
import org.jetbrains.kotlin.backend.konan.KonanFqNames
|
import org.jetbrains.kotlin.backend.konan.KonanFqNames
|
||||||
import org.jetbrains.kotlin.backend.konan.isExternalObjCClass
|
import org.jetbrains.kotlin.backend.konan.isExternalObjCClass
|
||||||
import org.jetbrains.kotlin.backend.konan.isFunctionInterfaceFile
|
import org.jetbrains.kotlin.backend.konan.isFunctionInterfaceFile
|
||||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrLinker
|
|
||||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr
|
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr
|
||||||
|
import org.jetbrains.kotlin.backend.konan.serialization.KonanPartialModuleDeserializer
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.library.impl.javaFile
|
|||||||
|
|
||||||
internal class CacheInfoBuilder(
|
internal class CacheInfoBuilder(
|
||||||
private val generationState: NativeGenerationState,
|
private val generationState: NativeGenerationState,
|
||||||
private val moduleDeserializer: KonanIrLinker.KonanPartialModuleDeserializer,
|
private val moduleDeserializer: KonanPartialModuleDeserializer,
|
||||||
private val irModule: IrModuleFragment
|
private val irModule: IrModuleFragment
|
||||||
) {
|
) {
|
||||||
fun build() {
|
fun build() {
|
||||||
|
|||||||
-486
@@ -17,9 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.serialization
|
package org.jetbrains.kotlin.backend.konan.serialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.linkage.issues.UserVisibleIrModulesSupport
|
import org.jetbrains.kotlin.backend.common.linkage.issues.UserVisibleIrModulesSupport
|
||||||
import org.jetbrains.kotlin.backend.common.linkage.issues.checkNoUnboundSymbols
|
|
||||||
import org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinker
|
import org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinker
|
||||||
import org.jetbrains.kotlin.backend.common.lower.parents
|
|
||||||
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder
|
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideClassFilter
|
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideClassFilter
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.*
|
import org.jetbrains.kotlin.backend.common.serialization.*
|
||||||
@@ -27,7 +25,6 @@ import org.jetbrains.kotlin.backend.common.serialization.encodings.BinaryNameAnd
|
|||||||
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.encodings.FunctionFlags
|
import org.jetbrains.kotlin.backend.common.serialization.encodings.FunctionFlags
|
||||||
import org.jetbrains.kotlin.backend.konan.*
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.ClassLayoutBuilder
|
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.findPackage
|
import org.jetbrains.kotlin.backend.konan.descriptors.findPackage
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
|
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary
|
import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary
|
||||||
@@ -44,10 +41,8 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
|
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase
|
import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
@@ -60,7 +55,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
|||||||
import sun.misc.Unsafe
|
import sun.misc.Unsafe
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrClass as ProtoClass
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrClass as ProtoClass
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclaration as ProtoDeclaration
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclaration as ProtoDeclaration
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrField as ProtoField
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrFunction as ProtoFunction
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrFunction as ProtoFunction
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrProperty as ProtoProperty
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrProperty as ProtoProperty
|
||||||
|
|
||||||
@@ -553,486 +547,6 @@ internal class KonanIrLinker(
|
|||||||
else -> error("Unknown package fragment kind ${packageFragment::class.java}")
|
else -> error("Unknown package fragment kind ${packageFragment::class.java}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
|
||||||
class KonanPartialModuleDeserializer(
|
|
||||||
konanIrLinker: KonanIrLinker,
|
|
||||||
moduleDescriptor: ModuleDescriptor,
|
|
||||||
override val klib: KotlinLibrary,
|
|
||||||
private val stubGenerator: DeclarationStubGenerator,
|
|
||||||
private val cachedLibraries: CachedLibraries,
|
|
||||||
private val inlineFunctionFiles: MutableMap<IrExternalPackageFragment, IrFile>,
|
|
||||||
strategyResolver: (String) -> DeserializationStrategy,
|
|
||||||
private val cacheDeserializationStrategy: CacheDeserializationStrategy,
|
|
||||||
containsErrorCode: Boolean = false
|
|
||||||
) : BasicIrModuleDeserializer(konanIrLinker, moduleDescriptor, klib,
|
|
||||||
{ fileName ->
|
|
||||||
if (cacheDeserializationStrategy.contains(fileName))
|
|
||||||
strategyResolver(fileName)
|
|
||||||
else DeserializationStrategy.ON_DEMAND
|
|
||||||
}, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, containsErrorCode
|
|
||||||
) {
|
|
||||||
private val descriptorSignatures = mutableMapOf<DeclarationDescriptor, IdSignature>()
|
|
||||||
|
|
||||||
val files by lazy { fileDeserializationStates.map { it.file } }
|
|
||||||
|
|
||||||
private val idSignatureToFile by lazy {
|
|
||||||
buildMap {
|
|
||||||
fileDeserializationStates.forEach { fileDeserializationState ->
|
|
||||||
fileDeserializationState.fileDeserializer.reversedSignatureIndex.keys.forEach { idSig ->
|
|
||||||
put(idSig, fileDeserializationState.file)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val fileReferenceToFileDeserializationState by lazy {
|
|
||||||
fileDeserializationStates.associateBy { SerializedFileReference(it.file.packageFqName.asString(), it.file.path) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private val SerializedFileReference.deserializationState
|
|
||||||
get() = fileReferenceToFileDeserializationState[this] ?: error("Unknown file $this")
|
|
||||||
|
|
||||||
private tailrec fun IdSignature.fileSignature(): IdSignature.FileSignature? = when (this) {
|
|
||||||
is IdSignature.FileSignature -> this
|
|
||||||
is IdSignature.CompositeSignature -> this.container.fileSignature()
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
private val IrClass.firstNonClassParent: IrDeclarationParent
|
|
||||||
get() {
|
|
||||||
var parent = parent
|
|
||||||
while (parent is IrClass) parent = parent.parent
|
|
||||||
return parent
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getFileNameOf(declaration: IrDeclaration): String {
|
|
||||||
fun IrDeclaration.getSignature() = symbol.signature ?: descriptorSignatures[descriptor]
|
|
||||||
|
|
||||||
val idSig = declaration.getSignature()
|
|
||||||
?: (declaration.parent as? IrDeclaration)?.getSignature()
|
|
||||||
?: ((declaration as? IrAttributeContainer)?.attributeOwnerId as? IrDeclaration)?.getSignature()
|
|
||||||
?: error("Can't find signature of ${declaration.render()}")
|
|
||||||
val topLevelIdSig = idSig.topLevelSignature()
|
|
||||||
return topLevelIdSig.fileSignature()?.fileName
|
|
||||||
?: idSignatureToFile[topLevelIdSig]?.path
|
|
||||||
?: error("No file for $idSig")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getKlibFileIndexOf(irFile: IrFile) = fileDeserializationStates.first { it.file == irFile }.fileIndex
|
|
||||||
|
|
||||||
fun buildInlineFunctionReference(irFunction: IrFunction): SerializedInlineFunctionReference {
|
|
||||||
val signature = irFunction.symbol.signature
|
|
||||||
?: error("No signature for ${irFunction.render()}")
|
|
||||||
val topLevelSignature = signature.topLevelSignature()
|
|
||||||
val fileDeserializationState = moduleReversedFileIndex[topLevelSignature]
|
|
||||||
?: error("No file deserializer for ${topLevelSignature.render()}")
|
|
||||||
val declarationIndex = fileDeserializationState.fileDeserializer.reversedSignatureIndex[topLevelSignature]
|
|
||||||
?: error("No declaration for ${topLevelSignature.render()}")
|
|
||||||
val fileReader = fileDeserializationState.fileReader
|
|
||||||
val symbolDeserializer = fileDeserializationState.fileDeserializer.symbolDeserializer
|
|
||||||
val protoDeclaration = fileReader.declaration(declarationIndex)
|
|
||||||
|
|
||||||
val outerClasses = (irFunction.parent as? IrClass)?.getOuterClasses(takeOnlyInner = false) ?: emptyList()
|
|
||||||
require((outerClasses.getOrNull(0)?.parent ?: irFunction.parent) is IrFile) {
|
|
||||||
"Local inline functions are not supported: ${irFunction.render()}"
|
|
||||||
}
|
|
||||||
|
|
||||||
val typeParameterSigs = mutableListOf<Int>()
|
|
||||||
val outerReceiverSigs = mutableListOf<Int>()
|
|
||||||
val protoFunction = if (outerClasses.isEmpty()) {
|
|
||||||
val irProperty = (irFunction as? IrSimpleFunction)?.correspondingPropertySymbol?.owner
|
|
||||||
if (irProperty == null)
|
|
||||||
protoDeclaration.irFunction
|
|
||||||
else protoDeclaration.irProperty.findAccessor(irProperty, irFunction)
|
|
||||||
} else {
|
|
||||||
val firstNotInnerClassIndex = outerClasses.indexOfLast { !it.isInner }
|
|
||||||
var protoClass = protoDeclaration.irClass
|
|
||||||
outerClasses.indices.forEach { classIndex ->
|
|
||||||
if (classIndex >= firstNotInnerClassIndex /* owner's type parameters are always accessible */) {
|
|
||||||
(0 until protoClass.typeParameterCount).mapTo(typeParameterSigs) {
|
|
||||||
BinarySymbolData.decode(protoClass.getTypeParameter(it).base.symbol).signatureId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (classIndex < outerClasses.size - 1) {
|
|
||||||
if (classIndex >= firstNotInnerClassIndex)
|
|
||||||
outerReceiverSigs.add(BinarySymbolData.decode(protoClass.thisReceiver.base.symbol).signatureId)
|
|
||||||
protoClass = protoClass.findClass(outerClasses[classIndex + 1], fileReader, symbolDeserializer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
protoClass.findInlineFunction(irFunction, fileReader, symbolDeserializer)
|
|
||||||
}
|
|
||||||
|
|
||||||
val functionSignature = BinarySymbolData.decode(protoFunction.base.base.symbol).signatureId
|
|
||||||
(0 until protoFunction.base.typeParameterCount).mapTo(typeParameterSigs) {
|
|
||||||
BinarySymbolData.decode(protoFunction.base.getTypeParameter(it).base.symbol).signatureId
|
|
||||||
}
|
|
||||||
val defaultValues = mutableListOf<Int>()
|
|
||||||
val valueParameterSigs = (0 until protoFunction.base.valueParameterCount).map {
|
|
||||||
val valueParameter = protoFunction.base.getValueParameter(it)
|
|
||||||
defaultValues.add(if (valueParameter.hasDefaultValue()) valueParameter.defaultValue else INVALID_INDEX)
|
|
||||||
BinarySymbolData.decode(valueParameter.base.symbol).signatureId
|
|
||||||
}
|
|
||||||
val extensionReceiverSig = irFunction.extensionReceiverParameter?.let {
|
|
||||||
BinarySymbolData.decode(protoFunction.base.extensionReceiver.base.symbol).signatureId
|
|
||||||
} ?: INVALID_INDEX
|
|
||||||
val dispatchReceiverSig = irFunction.dispatchReceiverParameter?.let {
|
|
||||||
BinarySymbolData.decode(protoFunction.base.dispatchReceiver.base.symbol).signatureId
|
|
||||||
} ?: INVALID_INDEX
|
|
||||||
|
|
||||||
return SerializedInlineFunctionReference(SerializedFileReference(fileDeserializationState.file),
|
|
||||||
functionSignature, protoFunction.base.body, irFunction.startOffset, irFunction.endOffset,
|
|
||||||
extensionReceiverSig, dispatchReceiverSig, outerReceiverSigs.toIntArray(),
|
|
||||||
valueParameterSigs.toIntArray(), typeParameterSigs.toIntArray(), defaultValues.toIntArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun buildClassFields(irClass: IrClass, fields: List<ClassLayoutBuilder.FieldInfo>): SerializedClassFields {
|
|
||||||
val signature = irClass.symbol.signature
|
|
||||||
?: error("No signature for ${irClass.render()}")
|
|
||||||
val topLevelSignature = signature.topLevelSignature()
|
|
||||||
val fileDeserializationState = moduleReversedFileIndex[topLevelSignature]
|
|
||||||
?: error("No file deserializer for ${topLevelSignature.render()}")
|
|
||||||
val fileDeserializer = fileDeserializationState.fileDeserializer
|
|
||||||
val declarationIndex = fileDeserializer.reversedSignatureIndex[topLevelSignature]
|
|
||||||
?: error("No declaration for ${topLevelSignature.render()}")
|
|
||||||
val fileReader = fileDeserializationState.fileReader
|
|
||||||
val symbolDeserializer = fileDeserializer.symbolDeserializer
|
|
||||||
val protoDeclaration = fileReader.declaration(declarationIndex)
|
|
||||||
|
|
||||||
val outerClasses = irClass.getOuterClasses(takeOnlyInner = false)
|
|
||||||
require(outerClasses.first().parent is IrFile) { "Local classes are not supported: ${irClass.render()}" }
|
|
||||||
|
|
||||||
val typeParameterSigs = mutableListOf<Int>()
|
|
||||||
var protoClass = protoDeclaration.irClass
|
|
||||||
val protoClasses = mutableListOf(protoClass)
|
|
||||||
val firstNotInnerClassIndex = outerClasses.indexOfLast { !it.isInner }
|
|
||||||
for (classIndex in outerClasses.indices) {
|
|
||||||
if (classIndex >= firstNotInnerClassIndex /* owner's type parameters are always accessible */) {
|
|
||||||
(0 until protoClass.typeParameterCount).mapTo(typeParameterSigs) {
|
|
||||||
BinarySymbolData.decode(protoClass.getTypeParameter(it).base.symbol).signatureId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (classIndex < outerClasses.size - 1) {
|
|
||||||
protoClass = protoClass.findClass(outerClasses[classIndex + 1], fileReader, symbolDeserializer)
|
|
||||||
protoClasses += protoClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val protoFields = mutableListOf<ProtoField>()
|
|
||||||
for (i in 0 until protoClass.declarationCount) {
|
|
||||||
val declaration = protoClass.getDeclaration(i)
|
|
||||||
if (declaration.declaratorCase == ProtoDeclaration.DeclaratorCase.IR_FIELD)
|
|
||||||
protoFields.add(declaration.irField)
|
|
||||||
else if (declaration.declaratorCase == ProtoDeclaration.DeclaratorCase.IR_PROPERTY) {
|
|
||||||
val protoProperty = declaration.irProperty
|
|
||||||
if (protoProperty.hasBackingField())
|
|
||||||
protoFields.add(protoProperty.backingField)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val protoFieldsMap = mutableMapOf<String, ProtoField>()
|
|
||||||
protoFields.forEach {
|
|
||||||
val nameAndType = BinaryNameAndType.decode(it.nameType)
|
|
||||||
val name = fileReader.string(nameAndType.nameIndex)
|
|
||||||
val prev = protoFieldsMap[name]
|
|
||||||
if (prev != null)
|
|
||||||
error("Class ${irClass.render()} has two fields with same name '$name'")
|
|
||||||
protoFieldsMap[name] = it
|
|
||||||
}
|
|
||||||
|
|
||||||
val outerThisIndex = fields.indexOfFirst { it.irField?.origin == IrDeclarationOrigin.FIELD_FOR_OUTER_THIS }
|
|
||||||
val compatibleMode = CompatibilityMode(libraryAbiVersion).oldSignatures
|
|
||||||
return SerializedClassFields(
|
|
||||||
SerializedFileReference(fileDeserializationState.file),
|
|
||||||
BinarySymbolData.decode(protoClass.base.symbol).signatureId,
|
|
||||||
typeParameterSigs.toIntArray(),
|
|
||||||
outerThisIndex,
|
|
||||||
Array(fields.size) {
|
|
||||||
val field = fields[it]
|
|
||||||
val irField = field.irField ?: error("No IR for field ${field.name} of ${irClass.render()}")
|
|
||||||
if (it == outerThisIndex) {
|
|
||||||
require(irClass.isInner) { "Expected an inner class: ${irClass.render()}" }
|
|
||||||
require(protoClasses.size > 1) { "An inner class must have at least one outer class" }
|
|
||||||
val outerProtoClass = protoClasses[protoClasses.size - 2]
|
|
||||||
val nameAndType = BinaryNameAndType.decode(outerProtoClass.thisReceiver.nameType)
|
|
||||||
|
|
||||||
SerializedClassFieldInfo(name = INVALID_INDEX, binaryType = INVALID_INDEX, nameAndType.typeIndex, flags = 0, field.alignment)
|
|
||||||
} else {
|
|
||||||
val protoField = protoFieldsMap[field.name] ?: error("No proto for ${irField.render()}")
|
|
||||||
val nameAndType = BinaryNameAndType.decode(protoField.nameType)
|
|
||||||
var flags = 0
|
|
||||||
if (field.isConst)
|
|
||||||
flags = flags or SerializedClassFieldInfo.FLAG_IS_CONST
|
|
||||||
val classifier = irField.type.classifierOrNull
|
|
||||||
?: error("Fields of type ${irField.type.render()} are not supported")
|
|
||||||
val primitiveBinaryType = irField.type.computePrimitiveBinaryTypeOrNull()
|
|
||||||
|
|
||||||
SerializedClassFieldInfo(
|
|
||||||
nameAndType.nameIndex,
|
|
||||||
primitiveBinaryType?.ordinal ?: INVALID_INDEX,
|
|
||||||
if (with(KonanManglerIr) { (classifier as? IrClassSymbol)?.owner?.isExported(compatibleMode) } == false)
|
|
||||||
INVALID_INDEX
|
|
||||||
else nameAndType.typeIndex,
|
|
||||||
flags,
|
|
||||||
field.alignment
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun buildEagerInitializedFile(irFile: IrFile) =
|
|
||||||
SerializedEagerInitializedFile(SerializedFileReference(irFile))
|
|
||||||
|
|
||||||
private val descriptorByIdSignatureFinder = DescriptorByIdSignatureFinderImpl(
|
|
||||||
moduleDescriptor, KonanManglerDesc,
|
|
||||||
DescriptorByIdSignatureFinderImpl.LookupMode.MODULE_ONLY
|
|
||||||
)
|
|
||||||
|
|
||||||
private val deserializedSymbols = mutableMapOf<IdSignature, IrSymbol>()
|
|
||||||
|
|
||||||
// Need to notify the deserializing machinery that some symbols have already been created by stub generator
|
|
||||||
// (like type parameters and receiver parameters) and there's no need to create new symbols for them.
|
|
||||||
private fun referenceIrSymbol(symbolDeserializer: IrSymbolDeserializer, sigIndex: Int, symbol: IrSymbol) {
|
|
||||||
val idSig = symbolDeserializer.deserializeIdSignature(sigIndex)
|
|
||||||
symbolDeserializer.referenceLocalIrSymbol(symbol, idSig)
|
|
||||||
if (idSig.isPubliclyVisible) {
|
|
||||||
deserializedSymbols[idSig]?.let {
|
|
||||||
require(it == symbol) { "Two different symbols for the same signature ${idSig.render()}" }
|
|
||||||
}
|
|
||||||
// Sometimes the linker would want to create a new symbol, so save actual symbol here
|
|
||||||
// and use it in [contains] and [tryDeserializeSymbol].
|
|
||||||
deserializedSymbols[idSig] = symbol
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun contains(idSig: IdSignature): Boolean =
|
|
||||||
super.contains(idSig) || deserializedSymbols.containsKey(idSig) ||
|
|
||||||
cacheDeserializationStrategy != CacheDeserializationStrategy.WholeModule
|
|
||||||
&& idSig.isPubliclyVisible && descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) != null
|
|
||||||
|
|
||||||
override fun tryDeserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol? {
|
|
||||||
super.tryDeserializeIrSymbol(idSig, symbolKind)?.let { return it }
|
|
||||||
|
|
||||||
deserializedSymbols[idSig]?.let { return it }
|
|
||||||
|
|
||||||
val descriptor = descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) ?: return null
|
|
||||||
|
|
||||||
descriptorSignatures[descriptor] = idSig
|
|
||||||
|
|
||||||
return (stubGenerator.generateMemberStub(descriptor) as IrSymbolOwner).symbol
|
|
||||||
}
|
|
||||||
|
|
||||||
private val inlineFunctionReferences by lazy {
|
|
||||||
val cache = cachedLibraries.getLibraryCache(klib)!! // ?: error("No cache for ${klib.libraryName}") // KT-54668
|
|
||||||
cache.serializedInlineFunctionBodies.associateBy {
|
|
||||||
it.file.deserializationState.declarationDeserializer.symbolDeserializer.deserializeIdSignature(it.functionSignature)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val deserializedInlineFunctions = mutableMapOf<IrFunction, InlineFunctionOriginInfo>()
|
|
||||||
|
|
||||||
fun deserializeInlineFunction(function: IrFunction): DeserializedInlineFunction {
|
|
||||||
deserializedInlineFunctions[function]?.let { return DeserializedInlineFunction(firstAccess = false, it) }
|
|
||||||
val result = deserializeInlineFunctionInternal(function)
|
|
||||||
deserializedInlineFunctions[function] = result
|
|
||||||
return DeserializedInlineFunction(firstAccess = true, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun deserializeInlineFunctionInternal(function: IrFunction): InlineFunctionOriginInfo {
|
|
||||||
val packageFragment = function.getPackageFragment()
|
|
||||||
if (function.parents.any { (it as? IrFunction)?.isInline == true }) {
|
|
||||||
// Already deserialized by the top-most inline function.
|
|
||||||
return InlineFunctionOriginInfo(
|
|
||||||
function,
|
|
||||||
packageFragment as? IrFile
|
|
||||||
?: inlineFunctionFiles[packageFragment as IrExternalPackageFragment]
|
|
||||||
?: error("${function.render()} should've been deserialized along with its parent"),
|
|
||||||
function.startOffset, function.endOffset
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val signature = function.symbol.signature
|
|
||||||
?: descriptorSignatures[function.descriptor]
|
|
||||||
?: error("No signature for ${function.render()}")
|
|
||||||
val inlineFunctionReference = inlineFunctionReferences[signature]
|
|
||||||
?: error("No inline function reference for ${function.render()}, sig = ${signature.render()}")
|
|
||||||
val fileDeserializationState = inlineFunctionReference.file.deserializationState
|
|
||||||
val declarationDeserializer = fileDeserializationState.declarationDeserializer
|
|
||||||
|
|
||||||
if (packageFragment is IrExternalPackageFragment) {
|
|
||||||
val symbolDeserializer = declarationDeserializer.symbolDeserializer
|
|
||||||
|
|
||||||
inlineFunctionFiles[packageFragment]?.let {
|
|
||||||
require(it == fileDeserializationState.file) {
|
|
||||||
"Different files ${it.fileEntry.name} and ${fileDeserializationState.file.fileEntry.name} have the same $packageFragment"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inlineFunctionFiles[packageFragment] = fileDeserializationState.file
|
|
||||||
|
|
||||||
val outerClasses = (function.parent as? IrClass)?.getOuterClasses(takeOnlyInner = true) ?: emptyList()
|
|
||||||
require((outerClasses.getOrNull(0)?.firstNonClassParent ?: function.parent) is IrPackageFragment) {
|
|
||||||
"Local inline functions are not supported: ${function.render()}"
|
|
||||||
}
|
|
||||||
|
|
||||||
var endToEndTypeParameterIndex = 0
|
|
||||||
outerClasses.forEach { outerClass ->
|
|
||||||
outerClass.typeParameters.forEach { parameter ->
|
|
||||||
val sigIndex = inlineFunctionReference.typeParameterSigs[endToEndTypeParameterIndex++]
|
|
||||||
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function.typeParameters.forEach { parameter ->
|
|
||||||
val sigIndex = inlineFunctionReference.typeParameterSigs[endToEndTypeParameterIndex++]
|
|
||||||
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
|
||||||
}
|
|
||||||
function.valueParameters.forEachIndexed { index, parameter ->
|
|
||||||
val sigIndex = inlineFunctionReference.valueParameterSigs[index]
|
|
||||||
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
|
||||||
}
|
|
||||||
function.extensionReceiverParameter?.let { parameter ->
|
|
||||||
val sigIndex = inlineFunctionReference.extensionReceiverSig
|
|
||||||
require(sigIndex != INVALID_INDEX) { "Expected a valid sig reference to the extension receiver for ${function.render()}" }
|
|
||||||
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
|
||||||
}
|
|
||||||
function.dispatchReceiverParameter?.let { parameter ->
|
|
||||||
val sigIndex = inlineFunctionReference.dispatchReceiverSig
|
|
||||||
require(sigIndex != INVALID_INDEX) { "Expected a valid sig reference to the dispatch receiver for ${function.render()}" }
|
|
||||||
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
|
||||||
}
|
|
||||||
for (index in 0 until outerClasses.size - 1) {
|
|
||||||
val sigIndex = inlineFunctionReference.outerReceiverSigs[index]
|
|
||||||
referenceIrSymbol(symbolDeserializer, sigIndex, outerClasses[index].thisReceiver!!.symbol)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
with(declarationDeserializer) {
|
|
||||||
function.withDeserializeBodies {
|
|
||||||
body = (deserializeStatementBody(inlineFunctionReference.body) as IrBody)
|
|
||||||
valueParameters.forEachIndexed { index, parameter ->
|
|
||||||
val defaultValueIndex = inlineFunctionReference.defaultValues[index]
|
|
||||||
if (defaultValueIndex != INVALID_INDEX)
|
|
||||||
parameter.defaultValue = deserializeExpressionBody(defaultValueIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (packageFragment is IrFile)
|
|
||||||
linker.deserializeAllReachableTopLevels()
|
|
||||||
|
|
||||||
linker.partialLinkageSupport.exploreClassifiers(linker.fakeOverrideBuilder)
|
|
||||||
linker.partialLinkageSupport.exploreClassifiersInInlineLazyIrFunction(function)
|
|
||||||
|
|
||||||
linker.fakeOverrideBuilder.provideFakeOverrides()
|
|
||||||
|
|
||||||
linker.partialLinkageSupport.generateStubsAndPatchUsages(linker.symbolTable, function)
|
|
||||||
|
|
||||||
linker.checkNoUnboundSymbols(
|
|
||||||
linker.symbolTable,
|
|
||||||
"after deserializing lazy-IR function ${function.name.asString()} in inline functions lowering"
|
|
||||||
)
|
|
||||||
|
|
||||||
return InlineFunctionOriginInfo(function, fileDeserializationState.file, inlineFunctionReference.startOffset, inlineFunctionReference.endOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val classesFields by lazy {
|
|
||||||
val cache = cachedLibraries.getLibraryCache(klib)!! // ?: error("No cache for ${klib.libraryName}") // KT-54668
|
|
||||||
cache.serializedClassFields.associateBy {
|
|
||||||
it.file.deserializationState.declarationDeserializer.symbolDeserializer.deserializeIdSignature(it.classSignature)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val lock = Any()
|
|
||||||
|
|
||||||
fun deserializeClassFields(irClass: IrClass, outerThisFieldInfo: ClassLayoutBuilder.FieldInfo?): List<ClassLayoutBuilder.FieldInfo> = synchronized(lock) {
|
|
||||||
val signature = irClass.symbol.signature
|
|
||||||
?: error("No signature for ${irClass.render()}")
|
|
||||||
val serializedClassFields = classesFields[signature]
|
|
||||||
?: error("No class fields for ${irClass.render()}, sig = ${signature.render()}")
|
|
||||||
val fileDeserializationState = serializedClassFields.file.deserializationState
|
|
||||||
val declarationDeserializer = fileDeserializationState.declarationDeserializer
|
|
||||||
val symbolDeserializer = declarationDeserializer.symbolDeserializer
|
|
||||||
|
|
||||||
if (irClass.getPackageFragment() is IrExternalPackageFragment) {
|
|
||||||
val outerClasses = irClass.getOuterClasses(takeOnlyInner = true)
|
|
||||||
require(outerClasses.first().firstNonClassParent is IrExternalPackageFragment) {
|
|
||||||
"Local classes are not supported: ${irClass.render()}"
|
|
||||||
}
|
|
||||||
|
|
||||||
var endToEndTypeParameterIndex = 0
|
|
||||||
outerClasses.forEach { outerClass ->
|
|
||||||
outerClass.typeParameters.forEach { parameter ->
|
|
||||||
val sigIndex = serializedClassFields.typeParameterSigs[endToEndTypeParameterIndex++]
|
|
||||||
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
require(endToEndTypeParameterIndex == serializedClassFields.typeParameterSigs.size) {
|
|
||||||
"Not all type parameters have been referenced"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getByClassId(classId: ClassId): IrClassSymbol {
|
|
||||||
val classIdSig = getPublicSignature(classId.packageFqName, classId.relativeClassName.asString())
|
|
||||||
return symbolDeserializer.deserializePublicSymbol(classIdSig, BinarySymbolData.SymbolKind.CLASS_SYMBOL) as IrClassSymbol
|
|
||||||
}
|
|
||||||
|
|
||||||
return serializedClassFields.fields.mapIndexed { index, field ->
|
|
||||||
val builtIns = linker.builtIns
|
|
||||||
if (index == serializedClassFields.outerThisIndex) {
|
|
||||||
require(irClass.isInner) { "Expected an inner class: ${irClass.render()}" }
|
|
||||||
require(outerThisFieldInfo != null) { "For an inner class ${irClass.render()} there should be <outer this> field" }
|
|
||||||
outerThisFieldInfo.also {
|
|
||||||
require(it.alignment == field.alignment) { "Mismatched align information for outer this"}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val name = fileDeserializationState.fileReader.string(field.name)
|
|
||||||
val type = when {
|
|
||||||
field.type != INVALID_INDEX -> declarationDeserializer.deserializeIrType(field.type)
|
|
||||||
field.binaryType == INVALID_INDEX -> builtIns.anyNType
|
|
||||||
else -> when (PrimitiveBinaryType.values().getOrNull(field.binaryType)) {
|
|
||||||
PrimitiveBinaryType.BOOLEAN -> builtIns.booleanType
|
|
||||||
PrimitiveBinaryType.BYTE -> builtIns.byteType
|
|
||||||
PrimitiveBinaryType.SHORT -> builtIns.shortType
|
|
||||||
PrimitiveBinaryType.INT -> builtIns.intType
|
|
||||||
PrimitiveBinaryType.LONG -> builtIns.longType
|
|
||||||
PrimitiveBinaryType.FLOAT -> builtIns.floatType
|
|
||||||
PrimitiveBinaryType.DOUBLE -> builtIns.doubleType
|
|
||||||
PrimitiveBinaryType.POINTER -> getByClassId(KonanPrimitiveType.NON_NULL_NATIVE_PTR.classId).defaultType
|
|
||||||
PrimitiveBinaryType.VECTOR128 -> getByClassId(KonanPrimitiveType.VECTOR128.classId).defaultType
|
|
||||||
else -> error("Bad binary type of field $name of ${irClass.render()}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ClassLayoutBuilder.FieldInfo(
|
|
||||||
name, type,
|
|
||||||
isConst = (field.flags and SerializedClassFieldInfo.FLAG_IS_CONST) != 0,
|
|
||||||
irFieldSymbol = IrFieldSymbolImpl(),
|
|
||||||
alignment = field.alignment,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun IrClass.getOuterClasses(takeOnlyInner: Boolean): List<IrClass> {
|
|
||||||
var outerClass = this
|
|
||||||
val outerClasses = mutableListOf(outerClass)
|
|
||||||
while (outerClass.isInner || !takeOnlyInner) {
|
|
||||||
outerClass = outerClass.parent as? IrClass ?: break
|
|
||||||
outerClasses.add(outerClass)
|
|
||||||
}
|
|
||||||
outerClasses.reverse()
|
|
||||||
return outerClasses
|
|
||||||
}
|
|
||||||
|
|
||||||
val eagerInitializedFiles by lazy {
|
|
||||||
val cache = cachedLibraries.getLibraryCache(klib)!! // ?: error("No cache for ${klib.libraryName}") // KT-54668
|
|
||||||
cache.serializedEagerInitializedFiles
|
|
||||||
.map { it.file.deserializationState.file }
|
|
||||||
.distinct()
|
|
||||||
}
|
|
||||||
|
|
||||||
val sortedFileIds by lazy {
|
|
||||||
fileDeserializationStates
|
|
||||||
.sortedBy { it.file.fileEntry.name }
|
|
||||||
.map { CacheSupport.cacheFileId(it.file.packageFqName.asString(), it.file.fileEntry.name) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class KonanInteropModuleDeserializer(
|
private inner class KonanInteropModuleDeserializer(
|
||||||
moduleDescriptor: ModuleDescriptor,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
override val klib: KotlinLibrary,
|
override val klib: KotlinLibrary,
|
||||||
|
|||||||
+528
@@ -0,0 +1,528 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.konan.serialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.linkage.issues.checkNoUnboundSymbols
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.parents
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.*
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinaryNameAndType
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
|
||||||
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
|
import org.jetbrains.kotlin.backend.konan.InlineFunctionOriginInfo
|
||||||
|
import org.jetbrains.kotlin.backend.konan.descriptors.ClassLayoutBuilder
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||||
|
import org.jetbrains.kotlin.ir.types.defaultType
|
||||||
|
import org.jetbrains.kotlin.ir.types.getPublicSignature
|
||||||
|
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||||
|
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||||
|
import org.jetbrains.kotlin.ir.util.getPackageFragment
|
||||||
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
|
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclaration as ProtoDeclaration
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrField as ProtoField
|
||||||
|
|
||||||
|
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||||
|
internal class KonanPartialModuleDeserializer(
|
||||||
|
konanIrLinker: KonanIrLinker,
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
override val klib: KotlinLibrary,
|
||||||
|
private val stubGenerator: DeclarationStubGenerator,
|
||||||
|
private val cachedLibraries: CachedLibraries,
|
||||||
|
private val inlineFunctionFiles: MutableMap<IrExternalPackageFragment, IrFile>,
|
||||||
|
strategyResolver: (String) -> DeserializationStrategy,
|
||||||
|
private val cacheDeserializationStrategy: CacheDeserializationStrategy,
|
||||||
|
containsErrorCode: Boolean = false
|
||||||
|
) : BasicIrModuleDeserializer(konanIrLinker, moduleDescriptor, klib,
|
||||||
|
{ fileName ->
|
||||||
|
if (cacheDeserializationStrategy.contains(fileName))
|
||||||
|
strategyResolver(fileName)
|
||||||
|
else DeserializationStrategy.ON_DEMAND
|
||||||
|
}, klib.versions.abiVersion ?: KotlinAbiVersion.CURRENT, containsErrorCode
|
||||||
|
) {
|
||||||
|
private val descriptorSignatures = mutableMapOf<DeclarationDescriptor, IdSignature>()
|
||||||
|
|
||||||
|
val files by lazy { fileDeserializationStates.map { it.file } }
|
||||||
|
|
||||||
|
private val idSignatureToFile by lazy {
|
||||||
|
buildMap {
|
||||||
|
fileDeserializationStates.forEach { fileDeserializationState ->
|
||||||
|
fileDeserializationState.fileDeserializer.reversedSignatureIndex.keys.forEach { idSig ->
|
||||||
|
put(idSig, fileDeserializationState.file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val fileReferenceToFileDeserializationState by lazy {
|
||||||
|
fileDeserializationStates.associateBy { SerializedFileReference(it.file.packageFqName.asString(), it.file.path) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val SerializedFileReference.deserializationState
|
||||||
|
get() = fileReferenceToFileDeserializationState[this] ?: error("Unknown file $this")
|
||||||
|
|
||||||
|
private tailrec fun IdSignature.fileSignature(): IdSignature.FileSignature? = when (this) {
|
||||||
|
is IdSignature.FileSignature -> this
|
||||||
|
is IdSignature.CompositeSignature -> this.container.fileSignature()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
private val IrClass.firstNonClassParent: IrDeclarationParent
|
||||||
|
get() {
|
||||||
|
var parent = parent
|
||||||
|
while (parent is IrClass) parent = parent.parent
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getFileNameOf(declaration: IrDeclaration): String {
|
||||||
|
fun IrDeclaration.getSignature() = symbol.signature ?: descriptorSignatures[descriptor]
|
||||||
|
|
||||||
|
val idSig = declaration.getSignature()
|
||||||
|
?: (declaration.parent as? IrDeclaration)?.getSignature()
|
||||||
|
?: ((declaration as? IrAttributeContainer)?.attributeOwnerId as? IrDeclaration)?.getSignature()
|
||||||
|
?: error("Can't find signature of ${declaration.render()}")
|
||||||
|
val topLevelIdSig = idSig.topLevelSignature()
|
||||||
|
return topLevelIdSig.fileSignature()?.fileName
|
||||||
|
?: idSignatureToFile[topLevelIdSig]?.path
|
||||||
|
?: error("No file for $idSig")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getKlibFileIndexOf(irFile: IrFile) = fileDeserializationStates.first { it.file == irFile }.fileIndex
|
||||||
|
|
||||||
|
fun buildInlineFunctionReference(irFunction: IrFunction): SerializedInlineFunctionReference {
|
||||||
|
val signature = irFunction.symbol.signature
|
||||||
|
?: error("No signature for ${irFunction.render()}")
|
||||||
|
val topLevelSignature = signature.topLevelSignature()
|
||||||
|
val fileDeserializationState = moduleReversedFileIndex[topLevelSignature]
|
||||||
|
?: error("No file deserializer for ${topLevelSignature.render()}")
|
||||||
|
val declarationIndex = fileDeserializationState.fileDeserializer.reversedSignatureIndex[topLevelSignature]
|
||||||
|
?: error("No declaration for ${topLevelSignature.render()}")
|
||||||
|
val fileReader = fileDeserializationState.fileReader
|
||||||
|
val symbolDeserializer = fileDeserializationState.fileDeserializer.symbolDeserializer
|
||||||
|
val protoDeclaration = fileReader.declaration(declarationIndex)
|
||||||
|
|
||||||
|
val outerClasses = (irFunction.parent as? IrClass)?.getOuterClasses(takeOnlyInner = false) ?: emptyList()
|
||||||
|
require((outerClasses.getOrNull(0)?.parent ?: irFunction.parent) is IrFile) {
|
||||||
|
"Local inline functions are not supported: ${irFunction.render()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
val typeParameterSigs = mutableListOf<Int>()
|
||||||
|
val outerReceiverSigs = mutableListOf<Int>()
|
||||||
|
val protoFunction = if (outerClasses.isEmpty()) {
|
||||||
|
val irProperty = (irFunction as? IrSimpleFunction)?.correspondingPropertySymbol?.owner
|
||||||
|
if (irProperty == null)
|
||||||
|
protoDeclaration.irFunction
|
||||||
|
else protoDeclaration.irProperty.findAccessor(irProperty, irFunction)
|
||||||
|
} else {
|
||||||
|
val firstNotInnerClassIndex = outerClasses.indexOfLast { !it.isInner }
|
||||||
|
var protoClass = protoDeclaration.irClass
|
||||||
|
outerClasses.indices.forEach { classIndex ->
|
||||||
|
if (classIndex >= firstNotInnerClassIndex /* owner's type parameters are always accessible */) {
|
||||||
|
(0 until protoClass.typeParameterCount).mapTo(typeParameterSigs) {
|
||||||
|
BinarySymbolData.decode(protoClass.getTypeParameter(it).base.symbol).signatureId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (classIndex < outerClasses.size - 1) {
|
||||||
|
if (classIndex >= firstNotInnerClassIndex)
|
||||||
|
outerReceiverSigs.add(BinarySymbolData.decode(protoClass.thisReceiver.base.symbol).signatureId)
|
||||||
|
protoClass = protoClass.findClass(outerClasses[classIndex + 1], fileReader, symbolDeserializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protoClass.findInlineFunction(irFunction, fileReader, symbolDeserializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
val functionSignature = BinarySymbolData.decode(protoFunction.base.base.symbol).signatureId
|
||||||
|
(0 until protoFunction.base.typeParameterCount).mapTo(typeParameterSigs) {
|
||||||
|
BinarySymbolData.decode(protoFunction.base.getTypeParameter(it).base.symbol).signatureId
|
||||||
|
}
|
||||||
|
val defaultValues = mutableListOf<Int>()
|
||||||
|
val valueParameterSigs = (0 until protoFunction.base.valueParameterCount).map {
|
||||||
|
val valueParameter = protoFunction.base.getValueParameter(it)
|
||||||
|
defaultValues.add(if (valueParameter.hasDefaultValue()) valueParameter.defaultValue else KonanIrLinker.INVALID_INDEX)
|
||||||
|
BinarySymbolData.decode(valueParameter.base.symbol).signatureId
|
||||||
|
}
|
||||||
|
val extensionReceiverSig = irFunction.extensionReceiverParameter?.let {
|
||||||
|
BinarySymbolData.decode(protoFunction.base.extensionReceiver.base.symbol).signatureId
|
||||||
|
} ?: KonanIrLinker.INVALID_INDEX
|
||||||
|
val dispatchReceiverSig = irFunction.dispatchReceiverParameter?.let {
|
||||||
|
BinarySymbolData.decode(protoFunction.base.dispatchReceiver.base.symbol).signatureId
|
||||||
|
} ?: KonanIrLinker.INVALID_INDEX
|
||||||
|
|
||||||
|
return SerializedInlineFunctionReference(
|
||||||
|
SerializedFileReference(fileDeserializationState.file),
|
||||||
|
functionSignature, protoFunction.base.body, irFunction.startOffset, irFunction.endOffset,
|
||||||
|
extensionReceiverSig, dispatchReceiverSig, outerReceiverSigs.toIntArray(),
|
||||||
|
valueParameterSigs.toIntArray(), typeParameterSigs.toIntArray(), defaultValues.toIntArray()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun buildClassFields(irClass: IrClass, fields: List<ClassLayoutBuilder.FieldInfo>): SerializedClassFields {
|
||||||
|
val signature = irClass.symbol.signature
|
||||||
|
?: error("No signature for ${irClass.render()}")
|
||||||
|
val topLevelSignature = signature.topLevelSignature()
|
||||||
|
val fileDeserializationState = moduleReversedFileIndex[topLevelSignature]
|
||||||
|
?: error("No file deserializer for ${topLevelSignature.render()}")
|
||||||
|
val fileDeserializer = fileDeserializationState.fileDeserializer
|
||||||
|
val declarationIndex = fileDeserializer.reversedSignatureIndex[topLevelSignature]
|
||||||
|
?: error("No declaration for ${topLevelSignature.render()}")
|
||||||
|
val fileReader = fileDeserializationState.fileReader
|
||||||
|
val symbolDeserializer = fileDeserializer.symbolDeserializer
|
||||||
|
val protoDeclaration = fileReader.declaration(declarationIndex)
|
||||||
|
|
||||||
|
val outerClasses = irClass.getOuterClasses(takeOnlyInner = false)
|
||||||
|
require(outerClasses.first().parent is IrFile) { "Local classes are not supported: ${irClass.render()}" }
|
||||||
|
|
||||||
|
val typeParameterSigs = mutableListOf<Int>()
|
||||||
|
var protoClass = protoDeclaration.irClass
|
||||||
|
val protoClasses = mutableListOf(protoClass)
|
||||||
|
val firstNotInnerClassIndex = outerClasses.indexOfLast { !it.isInner }
|
||||||
|
for (classIndex in outerClasses.indices) {
|
||||||
|
if (classIndex >= firstNotInnerClassIndex /* owner's type parameters are always accessible */) {
|
||||||
|
(0 until protoClass.typeParameterCount).mapTo(typeParameterSigs) {
|
||||||
|
BinarySymbolData.decode(protoClass.getTypeParameter(it).base.symbol).signatureId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (classIndex < outerClasses.size - 1) {
|
||||||
|
protoClass = protoClass.findClass(outerClasses[classIndex + 1], fileReader, symbolDeserializer)
|
||||||
|
protoClasses += protoClass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val protoFields = mutableListOf<ProtoField>()
|
||||||
|
for (i in 0 until protoClass.declarationCount) {
|
||||||
|
val declaration = protoClass.getDeclaration(i)
|
||||||
|
if (declaration.declaratorCase == ProtoDeclaration.DeclaratorCase.IR_FIELD)
|
||||||
|
protoFields.add(declaration.irField)
|
||||||
|
else if (declaration.declaratorCase == ProtoDeclaration.DeclaratorCase.IR_PROPERTY) {
|
||||||
|
val protoProperty = declaration.irProperty
|
||||||
|
if (protoProperty.hasBackingField())
|
||||||
|
protoFields.add(protoProperty.backingField)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val protoFieldsMap = mutableMapOf<String, ProtoField>()
|
||||||
|
protoFields.forEach {
|
||||||
|
val nameAndType = BinaryNameAndType.decode(it.nameType)
|
||||||
|
val name = fileReader.string(nameAndType.nameIndex)
|
||||||
|
val prev = protoFieldsMap[name]
|
||||||
|
if (prev != null)
|
||||||
|
error("Class ${irClass.render()} has two fields with same name '$name'")
|
||||||
|
protoFieldsMap[name] = it
|
||||||
|
}
|
||||||
|
|
||||||
|
val outerThisIndex = fields.indexOfFirst { it.irField?.origin == IrDeclarationOrigin.FIELD_FOR_OUTER_THIS }
|
||||||
|
val compatibleMode = CompatibilityMode(libraryAbiVersion).oldSignatures
|
||||||
|
return SerializedClassFields(
|
||||||
|
SerializedFileReference(fileDeserializationState.file),
|
||||||
|
BinarySymbolData.decode(protoClass.base.symbol).signatureId,
|
||||||
|
typeParameterSigs.toIntArray(),
|
||||||
|
outerThisIndex,
|
||||||
|
Array(fields.size) {
|
||||||
|
val field = fields[it]
|
||||||
|
val irField = field.irField ?: error("No IR for field ${field.name} of ${irClass.render()}")
|
||||||
|
if (it == outerThisIndex) {
|
||||||
|
require(irClass.isInner) { "Expected an inner class: ${irClass.render()}" }
|
||||||
|
require(protoClasses.size > 1) { "An inner class must have at least one outer class" }
|
||||||
|
val outerProtoClass = protoClasses[protoClasses.size - 2]
|
||||||
|
val nameAndType = BinaryNameAndType.decode(outerProtoClass.thisReceiver.nameType)
|
||||||
|
|
||||||
|
SerializedClassFieldInfo(
|
||||||
|
name = KonanIrLinker.INVALID_INDEX,
|
||||||
|
binaryType = KonanIrLinker.INVALID_INDEX,
|
||||||
|
nameAndType.typeIndex,
|
||||||
|
flags = 0,
|
||||||
|
field.alignment
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
val protoField = protoFieldsMap[field.name] ?: error("No proto for ${irField.render()}")
|
||||||
|
val nameAndType = BinaryNameAndType.decode(protoField.nameType)
|
||||||
|
var flags = 0
|
||||||
|
if (field.isConst)
|
||||||
|
flags = flags or SerializedClassFieldInfo.FLAG_IS_CONST
|
||||||
|
val classifier = irField.type.classifierOrNull
|
||||||
|
?: error("Fields of type ${irField.type.render()} are not supported")
|
||||||
|
val primitiveBinaryType = irField.type.computePrimitiveBinaryTypeOrNull()
|
||||||
|
|
||||||
|
SerializedClassFieldInfo(
|
||||||
|
nameAndType.nameIndex,
|
||||||
|
primitiveBinaryType?.ordinal ?: KonanIrLinker.INVALID_INDEX,
|
||||||
|
if (with(KonanManglerIr) { (classifier as? IrClassSymbol)?.owner?.isExported(compatibleMode) } == false)
|
||||||
|
KonanIrLinker.INVALID_INDEX
|
||||||
|
else nameAndType.typeIndex,
|
||||||
|
flags,
|
||||||
|
field.alignment
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun buildEagerInitializedFile(irFile: IrFile) =
|
||||||
|
SerializedEagerInitializedFile(SerializedFileReference(irFile))
|
||||||
|
|
||||||
|
private val descriptorByIdSignatureFinder = DescriptorByIdSignatureFinderImpl(
|
||||||
|
moduleDescriptor, KonanManglerDesc,
|
||||||
|
DescriptorByIdSignatureFinderImpl.LookupMode.MODULE_ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
private val deserializedSymbols = mutableMapOf<IdSignature, IrSymbol>()
|
||||||
|
|
||||||
|
// Need to notify the deserializing machinery that some symbols have already been created by stub generator
|
||||||
|
// (like type parameters and receiver parameters) and there's no need to create new symbols for them.
|
||||||
|
private fun referenceIrSymbol(symbolDeserializer: IrSymbolDeserializer, sigIndex: Int, symbol: IrSymbol) {
|
||||||
|
val idSig = symbolDeserializer.deserializeIdSignature(sigIndex)
|
||||||
|
symbolDeserializer.referenceLocalIrSymbol(symbol, idSig)
|
||||||
|
if (idSig.isPubliclyVisible) {
|
||||||
|
deserializedSymbols[idSig]?.let {
|
||||||
|
require(it == symbol) { "Two different symbols for the same signature ${idSig.render()}" }
|
||||||
|
}
|
||||||
|
// Sometimes the linker would want to create a new symbol, so save actual symbol here
|
||||||
|
// and use it in [contains] and [tryDeserializeSymbol].
|
||||||
|
deserializedSymbols[idSig] = symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun contains(idSig: IdSignature): Boolean =
|
||||||
|
super.contains(idSig) || deserializedSymbols.containsKey(idSig) ||
|
||||||
|
cacheDeserializationStrategy != CacheDeserializationStrategy.WholeModule
|
||||||
|
&& idSig.isPubliclyVisible && descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) != null
|
||||||
|
|
||||||
|
override fun tryDeserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol? {
|
||||||
|
super.tryDeserializeIrSymbol(idSig, symbolKind)?.let { return it }
|
||||||
|
|
||||||
|
deserializedSymbols[idSig]?.let { return it }
|
||||||
|
|
||||||
|
val descriptor = descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) ?: return null
|
||||||
|
|
||||||
|
descriptorSignatures[descriptor] = idSig
|
||||||
|
|
||||||
|
return (stubGenerator.generateMemberStub(descriptor) as IrSymbolOwner).symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
private val inlineFunctionReferences by lazy {
|
||||||
|
val cache = cachedLibraries.getLibraryCache(klib)!! // ?: error("No cache for ${klib.libraryName}") // KT-54668
|
||||||
|
cache.serializedInlineFunctionBodies.associateBy {
|
||||||
|
it.file.deserializationState.declarationDeserializer.symbolDeserializer.deserializeIdSignature(it.functionSignature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val deserializedInlineFunctions = mutableMapOf<IrFunction, InlineFunctionOriginInfo>()
|
||||||
|
|
||||||
|
fun deserializeInlineFunction(function: IrFunction): DeserializedInlineFunction {
|
||||||
|
deserializedInlineFunctions[function]?.let { return DeserializedInlineFunction(firstAccess = false, it) }
|
||||||
|
val result = deserializeInlineFunctionInternal(function)
|
||||||
|
deserializedInlineFunctions[function] = result
|
||||||
|
return DeserializedInlineFunction(firstAccess = true, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deserializeInlineFunctionInternal(function: IrFunction): InlineFunctionOriginInfo {
|
||||||
|
val packageFragment = function.getPackageFragment()
|
||||||
|
if (function.parents.any { (it as? IrFunction)?.isInline == true }) {
|
||||||
|
// Already deserialized by the top-most inline function.
|
||||||
|
return InlineFunctionOriginInfo(
|
||||||
|
function,
|
||||||
|
packageFragment as? IrFile
|
||||||
|
?: inlineFunctionFiles[packageFragment as IrExternalPackageFragment]
|
||||||
|
?: error("${function.render()} should've been deserialized along with its parent"),
|
||||||
|
function.startOffset, function.endOffset
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val signature = function.symbol.signature
|
||||||
|
?: descriptorSignatures[function.descriptor]
|
||||||
|
?: error("No signature for ${function.render()}")
|
||||||
|
val inlineFunctionReference = inlineFunctionReferences[signature]
|
||||||
|
?: error("No inline function reference for ${function.render()}, sig = ${signature.render()}")
|
||||||
|
val fileDeserializationState = inlineFunctionReference.file.deserializationState
|
||||||
|
val declarationDeserializer = fileDeserializationState.declarationDeserializer
|
||||||
|
|
||||||
|
if (packageFragment is IrExternalPackageFragment) {
|
||||||
|
val symbolDeserializer = declarationDeserializer.symbolDeserializer
|
||||||
|
|
||||||
|
inlineFunctionFiles[packageFragment]?.let {
|
||||||
|
require(it == fileDeserializationState.file) {
|
||||||
|
"Different files ${it.fileEntry.name} and ${fileDeserializationState.file.fileEntry.name} have the same $packageFragment"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inlineFunctionFiles[packageFragment] = fileDeserializationState.file
|
||||||
|
|
||||||
|
val outerClasses = (function.parent as? IrClass)?.getOuterClasses(takeOnlyInner = true) ?: emptyList()
|
||||||
|
require((outerClasses.getOrNull(0)?.firstNonClassParent ?: function.parent) is IrPackageFragment) {
|
||||||
|
"Local inline functions are not supported: ${function.render()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
var endToEndTypeParameterIndex = 0
|
||||||
|
outerClasses.forEach { outerClass ->
|
||||||
|
outerClass.typeParameters.forEach { parameter ->
|
||||||
|
val sigIndex = inlineFunctionReference.typeParameterSigs[endToEndTypeParameterIndex++]
|
||||||
|
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function.typeParameters.forEach { parameter ->
|
||||||
|
val sigIndex = inlineFunctionReference.typeParameterSigs[endToEndTypeParameterIndex++]
|
||||||
|
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
||||||
|
}
|
||||||
|
function.valueParameters.forEachIndexed { index, parameter ->
|
||||||
|
val sigIndex = inlineFunctionReference.valueParameterSigs[index]
|
||||||
|
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
||||||
|
}
|
||||||
|
function.extensionReceiverParameter?.let { parameter ->
|
||||||
|
val sigIndex = inlineFunctionReference.extensionReceiverSig
|
||||||
|
require(sigIndex != KonanIrLinker.INVALID_INDEX) { "Expected a valid sig reference to the extension receiver for ${function.render()}" }
|
||||||
|
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
||||||
|
}
|
||||||
|
function.dispatchReceiverParameter?.let { parameter ->
|
||||||
|
val sigIndex = inlineFunctionReference.dispatchReceiverSig
|
||||||
|
require(sigIndex != KonanIrLinker.INVALID_INDEX) { "Expected a valid sig reference to the dispatch receiver for ${function.render()}" }
|
||||||
|
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
||||||
|
}
|
||||||
|
for (index in 0 until outerClasses.size - 1) {
|
||||||
|
val sigIndex = inlineFunctionReference.outerReceiverSigs[index]
|
||||||
|
referenceIrSymbol(symbolDeserializer, sigIndex, outerClasses[index].thisReceiver!!.symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
with(declarationDeserializer) {
|
||||||
|
function.withDeserializeBodies {
|
||||||
|
body = (deserializeStatementBody(inlineFunctionReference.body) as IrBody)
|
||||||
|
valueParameters.forEachIndexed { index, parameter ->
|
||||||
|
val defaultValueIndex = inlineFunctionReference.defaultValues[index]
|
||||||
|
if (defaultValueIndex != KonanIrLinker.INVALID_INDEX)
|
||||||
|
parameter.defaultValue = deserializeExpressionBody(defaultValueIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (packageFragment is IrFile)
|
||||||
|
linker.deserializeAllReachableTopLevels()
|
||||||
|
|
||||||
|
linker.partialLinkageSupport.exploreClassifiers(linker.fakeOverrideBuilder)
|
||||||
|
linker.partialLinkageSupport.exploreClassifiersInInlineLazyIrFunction(function)
|
||||||
|
|
||||||
|
linker.fakeOverrideBuilder.provideFakeOverrides()
|
||||||
|
|
||||||
|
linker.partialLinkageSupport.generateStubsAndPatchUsages(linker.symbolTable, function)
|
||||||
|
|
||||||
|
linker.checkNoUnboundSymbols(
|
||||||
|
linker.symbolTable,
|
||||||
|
"after deserializing lazy-IR function ${function.name.asString()} in inline functions lowering"
|
||||||
|
)
|
||||||
|
|
||||||
|
return InlineFunctionOriginInfo(
|
||||||
|
function,
|
||||||
|
fileDeserializationState.file,
|
||||||
|
inlineFunctionReference.startOffset,
|
||||||
|
inlineFunctionReference.endOffset
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val classesFields by lazy {
|
||||||
|
val cache = cachedLibraries.getLibraryCache(klib)!! // ?: error("No cache for ${klib.libraryName}") // KT-54668
|
||||||
|
cache.serializedClassFields.associateBy {
|
||||||
|
it.file.deserializationState.declarationDeserializer.symbolDeserializer.deserializeIdSignature(it.classSignature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val lock = Any()
|
||||||
|
|
||||||
|
fun deserializeClassFields(irClass: IrClass, outerThisFieldInfo: ClassLayoutBuilder.FieldInfo?): List<ClassLayoutBuilder.FieldInfo> = synchronized(lock) {
|
||||||
|
val signature = irClass.symbol.signature
|
||||||
|
?: error("No signature for ${irClass.render()}")
|
||||||
|
val serializedClassFields = classesFields[signature]
|
||||||
|
?: error("No class fields for ${irClass.render()}, sig = ${signature.render()}")
|
||||||
|
val fileDeserializationState = serializedClassFields.file.deserializationState
|
||||||
|
val declarationDeserializer = fileDeserializationState.declarationDeserializer
|
||||||
|
val symbolDeserializer = declarationDeserializer.symbolDeserializer
|
||||||
|
|
||||||
|
if (irClass.getPackageFragment() is IrExternalPackageFragment) {
|
||||||
|
val outerClasses = irClass.getOuterClasses(takeOnlyInner = true)
|
||||||
|
require(outerClasses.first().firstNonClassParent is IrExternalPackageFragment) {
|
||||||
|
"Local classes are not supported: ${irClass.render()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
var endToEndTypeParameterIndex = 0
|
||||||
|
outerClasses.forEach { outerClass ->
|
||||||
|
outerClass.typeParameters.forEach { parameter ->
|
||||||
|
val sigIndex = serializedClassFields.typeParameterSigs[endToEndTypeParameterIndex++]
|
||||||
|
referenceIrSymbol(symbolDeserializer, sigIndex, parameter.symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require(endToEndTypeParameterIndex == serializedClassFields.typeParameterSigs.size) {
|
||||||
|
"Not all type parameters have been referenced"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getByClassId(classId: ClassId): IrClassSymbol {
|
||||||
|
val classIdSig = getPublicSignature(classId.packageFqName, classId.relativeClassName.asString())
|
||||||
|
return symbolDeserializer.deserializePublicSymbol(classIdSig, BinarySymbolData.SymbolKind.CLASS_SYMBOL) as IrClassSymbol
|
||||||
|
}
|
||||||
|
|
||||||
|
return serializedClassFields.fields.mapIndexed { index, field ->
|
||||||
|
val builtIns = linker.builtIns
|
||||||
|
if (index == serializedClassFields.outerThisIndex) {
|
||||||
|
require(irClass.isInner) { "Expected an inner class: ${irClass.render()}" }
|
||||||
|
require(outerThisFieldInfo != null) { "For an inner class ${irClass.render()} there should be <outer this> field" }
|
||||||
|
outerThisFieldInfo.also {
|
||||||
|
require(it.alignment == field.alignment) { "Mismatched align information for outer this"}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val name = fileDeserializationState.fileReader.string(field.name)
|
||||||
|
val type = when {
|
||||||
|
field.type != KonanIrLinker.INVALID_INDEX -> declarationDeserializer.deserializeIrType(field.type)
|
||||||
|
field.binaryType == KonanIrLinker.INVALID_INDEX -> builtIns.anyNType
|
||||||
|
else -> when (PrimitiveBinaryType.values().getOrNull(field.binaryType)) {
|
||||||
|
PrimitiveBinaryType.BOOLEAN -> builtIns.booleanType
|
||||||
|
PrimitiveBinaryType.BYTE -> builtIns.byteType
|
||||||
|
PrimitiveBinaryType.SHORT -> builtIns.shortType
|
||||||
|
PrimitiveBinaryType.INT -> builtIns.intType
|
||||||
|
PrimitiveBinaryType.LONG -> builtIns.longType
|
||||||
|
PrimitiveBinaryType.FLOAT -> builtIns.floatType
|
||||||
|
PrimitiveBinaryType.DOUBLE -> builtIns.doubleType
|
||||||
|
PrimitiveBinaryType.POINTER -> getByClassId(KonanPrimitiveType.NON_NULL_NATIVE_PTR.classId).defaultType
|
||||||
|
PrimitiveBinaryType.VECTOR128 -> getByClassId(KonanPrimitiveType.VECTOR128.classId).defaultType
|
||||||
|
else -> error("Bad binary type of field $name of ${irClass.render()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClassLayoutBuilder.FieldInfo(
|
||||||
|
name, type,
|
||||||
|
isConst = (field.flags and SerializedClassFieldInfo.FLAG_IS_CONST) != 0,
|
||||||
|
irFieldSymbol = IrFieldSymbolImpl(),
|
||||||
|
alignment = field.alignment,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrClass.getOuterClasses(takeOnlyInner: Boolean): List<IrClass> {
|
||||||
|
var outerClass = this
|
||||||
|
val outerClasses = mutableListOf(outerClass)
|
||||||
|
while (outerClass.isInner || !takeOnlyInner) {
|
||||||
|
outerClass = outerClass.parent as? IrClass ?: break
|
||||||
|
outerClasses.add(outerClass)
|
||||||
|
}
|
||||||
|
outerClasses.reverse()
|
||||||
|
return outerClasses
|
||||||
|
}
|
||||||
|
|
||||||
|
val eagerInitializedFiles by lazy {
|
||||||
|
val cache = cachedLibraries.getLibraryCache(klib)!! // ?: error("No cache for ${klib.libraryName}") // KT-54668
|
||||||
|
cache.serializedEagerInitializedFiles
|
||||||
|
.map { it.file.deserializationState.file }
|
||||||
|
.distinct()
|
||||||
|
}
|
||||||
|
|
||||||
|
val sortedFileIds by lazy {
|
||||||
|
fileDeserializationStates
|
||||||
|
.sortedBy { it.file.fileEntry.name }
|
||||||
|
.map { CacheSupport.cacheFileId(it.file.packageFqName.asString(), it.file.fileEntry.name) }
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user