diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt index 7432ffc2b51..2d4da384146 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt @@ -20,10 +20,21 @@ class DescriptorTable { fun get(descriptor: DeclarationDescriptor) = descriptors[descriptor] } -// TODO: We don't manage id clashes anyhow now. -abstract class GlobalDeclarationTable(private val mangler: KotlinMangler) { +interface UniqIdClashTracker { + fun commit(declaration: IrDeclaration, uniqId: UniqId) + + companion object { + val DEFAULT_TRACKER = object : UniqIdClashTracker { + override fun commit(declaration: IrDeclaration, uniqId: UniqId) {} + } + } +} + +abstract class GlobalDeclarationTable(private val mangler: KotlinMangler, private val clashTracker: UniqIdClashTracker) { private val table = mutableMapOf() + constructor(mangler: KotlinMangler) : this(mangler, UniqIdClashTracker.DEFAULT_TRACKER) + protected open fun loadKnownBuiltins(builtIns: IrBuiltIns, startIndex: Long): Long { var index = startIndex builtIns.knownBuiltins.forEach { @@ -34,7 +45,7 @@ abstract class GlobalDeclarationTable(private val mangler: KotlinMangler) { open fun computeUniqIdByDeclaration(declaration: IrDeclaration): UniqId { return table.getOrPut(declaration) { - UniqId(mangler.hashedMangleImpl(declaration), false) + UniqId(mangler.hashedMangleImpl(declaration), false).also { clashTracker.commit(declaration, it) } } } 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 ec2673d578b..324d9dd4ae7 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 @@ -8,13 +8,30 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns +import org.jetbrains.kotlin.ir.util.render -class JsDeclarationTable(builtIns: IrBuiltIns, descriptorTable: DescriptorTable) : DeclarationTable(builtIns, descriptorTable, JsMangler) { +class JsUniqIdClashTracker: UniqIdClashTracker { + private val commitedUniqIds = mutableMapOf() - override var currentIndex = PUBLIC_LOCAL_UNIQ_ID_EDGE + override fun commit(declaration: IrDeclaration, uniqId: UniqId) { + if (uniqId.isLocal) return // don't track local ids - init { - loadKnownBuiltins() - currentIndex = 0 + if (uniqId in commitedUniqIds) { + val clashedDeclaration = commitedUniqIds[uniqId]!! + // TODO: handle clashes properly + error("UniqId clash: $uniqId; Existed declaration ${clashedDeclaration.render()} clashed with new ${declaration.render()}") + } + + commitedUniqIds[uniqId] = declaration + } +} + +class JsGlobalDeclarationTable(builtIns: IrBuiltIns) : GlobalDeclarationTable(JsMangler, JsUniqIdClashTracker()) { + private val FUNCTION_INDEX_START: Long = loadKnownBuiltins(builtIns, PUBLIC_LOCAL_UNIQ_ID_EDGE) + + override fun computeUniqIdByDeclaration(declaration: IrDeclaration): UniqId { + return if (isBuiltInFunction(declaration)) { + UniqId(FUNCTION_INDEX_START + builtInFunctionId(declaration), false) + } else super.computeUniqIdByDeclaration(declaration) } } \ No newline at end of file