diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt index c7765210dbc..028fbe07cae 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.backend.common.serialization -import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor -import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor +import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor +import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation -import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor +import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -17,16 +17,30 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor import org.jetbrains.kotlin.resolve.scopes.MemberScope +// This is all information needed to find a descriptor in the +// tree of deserialized descriptors. Think of it as base + offset. +// packageFqName + classFqName + index allow to localize some deserialized descriptor. +// Then the rest of the fields allow to find the needed descriptor relative to the one with index. abstract class DescriptorReferenceDeserializer( val currentModule: ModuleDescriptor, val mangler: KotlinMangler, + val builtIns: IrBuiltIns, val resolvedForwardDeclarations: MutableMap ) : DescriptorUniqIdAware { + protected open fun resolveSpecialDescriptor(fqn: FqName) = builtIns.builtIns.getBuiltInClassByFqName(fqn) - protected abstract fun resolveSpecialDescriptor(fqn: FqName): DeclarationDescriptor - protected abstract fun checkIfSpecialDescriptorId(id: Long): Boolean - protected abstract fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor): Long? + protected open fun checkIfSpecialDescriptorId(id: Long) = with(mangler) { id.isSpecial } + + protected open fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor) = + if (isBuiltInFunction(descriptor)) { + val uniqName = when (descriptor) { + is FunctionClassDescriptor -> KotlinMangler.functionClassSymbolName(descriptor.name) + is FunctionInvokeDescriptor -> KotlinMangler.functionInvokeSymbolName(descriptor.containingDeclaration.name) + else -> error("Unexpected descriptor type: $descriptor") + } + with(mangler) { uniqName.hashMangle } + } else null protected fun getContributedDescriptors(packageFqNameString: String, name: String): Collection { val packageFqName = packageFqNameString.let { diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt index 999fb5a6a5c..1bfa4ab40a6 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt @@ -5,24 +5,15 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir -import org.jetbrains.kotlin.backend.common.serialization.UniqId import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable -import org.jetbrains.kotlin.backend.common.serialization.isBuiltInFunction -import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns class JsDeclarationTable(builtIns: IrBuiltIns, descriptorTable: DescriptorTable) : DeclarationTable(builtIns, descriptorTable, JsMangler) { override var currentIndex = PUBLIC_LOCAL_UNIQ_ID_EDGE - private val FUNCTION_INDEX_START: Long = loadKnownBuiltins() init { - currentIndex += BUILT_IN_UNIQ_ID_GAP + loadKnownBuiltins() } - - override fun computeUniqIdByDeclaration(value: IrDeclaration) = - if (isBuiltInFunction(value)) { - UniqId(FUNCTION_INDEX_START + builtInFunctionId(value), false) - } else super.computeUniqIdByDeclaration(value) } diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTableUtils.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTableUtils.kt index 916f52de1f4..07e74fa7f65 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTableUtils.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTableUtils.kt @@ -5,58 +5,4 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir -import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction -import org.jetbrains.kotlin.ir.util.nameForIrSerialization -import org.jetbrains.kotlin.ir.util.parentAsClass -import org.jetbrains.kotlin.psi2ir.findFirstFunction - internal const val PUBLIC_LOCAL_UNIQ_ID_EDGE = 0x7FFF_FFFF_FFFF_FFFFL + 1L -internal const val BUILT_IN_FUNCTION_CLASS_COUNT = 4 -internal const val BUILT_IN_FUNCTION_ARITY_COUNT = 256 -internal const val BUILT_IN_UNIQ_ID_GAP = 2 * BUILT_IN_FUNCTION_ARITY_COUNT * BUILT_IN_FUNCTION_CLASS_COUNT -internal const val BUILT_IN_UNIQ_ID_CLASS_OFFSET = BUILT_IN_FUNCTION_CLASS_COUNT * BUILT_IN_FUNCTION_ARITY_COUNT - -private fun builtInOffset(function: IrSimpleFunction): Long { - val isK = function.parentAsClass.name.asString().startsWith("K") - return when { - isK && function.isSuspend -> 3 - isK -> 2 - function.isSuspend -> 1 - else -> 0 - } -} - -internal fun builtInFunctionId(value: IrDeclaration): Long = when (value) { - is IrSimpleFunction -> { - value.run { valueParameters.size + builtInOffset(value) * BUILT_IN_FUNCTION_ARITY_COUNT }.toLong() - } - is IrClass -> { - BUILT_IN_UNIQ_ID_CLASS_OFFSET + builtInFunctionId(value.declarations.first { it.nameForIrSerialization.asString() == "invoke" }) - } - else -> error("Only class or function is expected") -} - -private fun builtInOffset(function: FunctionInvokeDescriptor): Long { - val isK = function.containingDeclaration.name.asString().startsWith("K") - return when { - isK && function.isSuspend -> 3 - isK -> 2 - function.isSuspend -> 1 - else -> 0 - } -} - -internal fun builtInFunctionId(value: DeclarationDescriptor): Long = when (value) { - is FunctionInvokeDescriptor -> { - value.run { valueParameters.size + builtInOffset(value) * BUILT_IN_FUNCTION_ARITY_COUNT }.toLong() - } - is ClassDescriptor -> { - BUILT_IN_UNIQ_ID_CLASS_OFFSET + builtInFunctionId(value.findFirstFunction("invoke") { true }) - } - else -> error("Only class or function is expected") -} diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDescriptorReferenceDeserializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDescriptorReferenceDeserializer.kt index 66975716bd6..c554bae5059 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDescriptorReferenceDeserializer.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDescriptorReferenceDeserializer.kt @@ -6,28 +6,16 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir import org.jetbrains.kotlin.backend.common.serialization.* +import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor +import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.name.FqName - class JsDescriptorReferenceDeserializer( currentModule: ModuleDescriptor, mangler: KotlinMangler, - val builtIns: IrBuiltIns, - val FUNCTION_INDEX_START: Long) : - DescriptorReferenceDeserializer(currentModule, mangler, mutableMapOf()), - DescriptorUniqIdAware by JsDescriptorUniqIdAware { - - override fun resolveSpecialDescriptor(fqn: FqName) = builtIns.builtIns.getBuiltInClassByFqName(fqn) - - override fun checkIfSpecialDescriptorId(id: Long) = - (FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_CLASS_OFFSET) <= id && id < (FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_GAP) - - override fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor) = - if (isBuiltInFunction(descriptor)) - FUNCTION_INDEX_START + builtInFunctionId(descriptor) - else null - -} + builtIns: IrBuiltIns +) : DescriptorReferenceDeserializer(currentModule, mangler, builtIns, mutableMapOf()), + DescriptorUniqIdAware by JsDescriptorUniqIdAware diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt index 8571db1c0d1..43f8b838655 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt @@ -23,13 +23,11 @@ class JsIrLinker( ) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, PUBLIC_LOCAL_UNIQ_ID_EDGE), DescriptorUniqIdAware by JsDescriptorUniqIdAware { - private val FUNCTION_INDEX_START: Long = indexAfterKnownBuiltins - override fun getPrimitiveTypeOrNull(symbol: IrClassifierSymbol, hasQuestionMark: Boolean) = builtIns.getPrimitiveTypeOrNullByDescriptor(symbol.descriptor, hasQuestionMark) override val descriptorReferenceDeserializer = - JsDescriptorReferenceDeserializer(currentModule, mangler, builtIns, FUNCTION_INDEX_START) + JsDescriptorReferenceDeserializer(currentModule, mangler, builtIns) override fun reader(moduleDescriptor: ModuleDescriptor, uniqId: UniqId): ByteArray { return moduleDescriptor.kotlinLibrary.irDeclaration(uniqId.index, uniqId.isLocal) @@ -56,17 +54,4 @@ class JsIrLinker( } private val ModuleDescriptor.userName get() = kotlinLibrary.libraryFile.absolutePath - - override fun declareForwardDeclarations() { - // since for `knownBuiltIns` such as FunctionN it is possible to have unbound symbols after deserialization - // reference them through out lazy symbol table - with(symbolTable) { - ArrayList(unboundClasses).forEach { lazyWrapper.referenceClass(it.descriptor) } - ArrayList(unboundConstructors).forEach { lazyWrapper.referenceConstructor(it.descriptor) } - ArrayList(unboundEnumEntries).forEach { lazyWrapper.referenceEnumEntry(it.descriptor) } - ArrayList(unboundFields).forEach { lazyWrapper.referenceField(it.descriptor) } - ArrayList(unboundSimpleFunctions).forEach { lazyWrapper.referenceSimpleFunction(it.descriptor) } - ArrayList(unboundTypeParameters).forEach { lazyWrapper.referenceTypeParameter(it.descriptor) } - } - } } \ No newline at end of file