[IrSerializer] Removed hacks with functional interfaces

This commit is contained in:
Igor Chevdar
2019-08-05 13:49:09 +03:00
parent 00dc335559
commit 226013353d
5 changed files with 27 additions and 103 deletions
@@ -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)
}
@@ -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")
}
@@ -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<UniqIdKey, UniqIdKey>()),
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
@@ -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) }
}
}
}