diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DeserializeDescriptorReference.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DeserializeDescriptorReference.kt index 1ddfa5f1389..93ff0c34422 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DeserializeDescriptorReference.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DeserializeDescriptorReference.kt @@ -2,31 +2,46 @@ package org.jetbrains.kotlin.backend.konan.serialization import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation -import org.jetbrains.kotlin.metadata.KonanIr import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor +// 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. class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val resolvedForwardDeclarations: MutableMap) { + fun deserializeDescriptorReference( + packageFqNameString: String, + classFqNameString: String, + name: String, + index: Long?, + isEnumEntry: Boolean = false, + isEnumSpecial: Boolean = false, + isDefaultConstructor: Boolean = false, + isFakeOverride: Boolean = false, + isGetter: Boolean = false, + isSetter: Boolean = false + ): DeclarationDescriptor { + val packageFqName = packageFqNameString.let { + if (it == "") FqName.ROOT else FqName(it) + }// TODO: whould we store an empty string in the protobuf? - fun deserializeDescriptorReference(proto: KonanIr.DescriptorReference): DeclarationDescriptor { - val packageFqName = - if (proto.packageFqName == "") FqName.ROOT else FqName(proto.packageFqName) // TODO: whould we store an empty string in the protobuf? - val classFqName = FqName(proto.classFqName) - val protoIndex = if (proto.hasUniqId()) proto.uniqId.index else null + val classFqName = FqName(classFqNameString) + val protoIndex = index - val (clazz, members) = if (proto.classFqName == "") { + val (clazz, members) = if (classFqNameString == "") { Pair(null, currentModule.getPackage(packageFqName).memberScope.getContributedDescriptors()) } else { val clazz = currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, classFqName, false))!! Pair(clazz, clazz.unsubstitutedMemberScope.getContributedDescriptors() + clazz.getConstructors()) } - if (proto.packageFqName.startsWith("cnames.") || proto.packageFqName.startsWith("objcnames.")) { + if (packageFqNameString.startsWith("cnames.") || packageFqNameString.startsWith("objcnames.")) { val descriptor = - currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, FqName(proto.name), false))!! + currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, FqName(name), false))!! if (!descriptor.fqNameUnsafe.asString().startsWith("cnames") && !descriptor.fqNameUnsafe.asString().startsWith( "objcnames" ) @@ -44,23 +59,21 @@ class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val r return descriptor } - if (proto.isEnumEntry) { - val name = proto.name + if (isEnumEntry) { val memberScope = (clazz as DeserializedClassDescriptor).getUnsubstitutedMemberScope() return memberScope.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BACKEND)!! } - if (proto.isEnumSpecial) { - val name = proto.name + if (isEnumSpecial) { return clazz!!.getStaticScope() .getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).single() } members.forEach { member -> - if (proto.isDefaultConstructor && member is ClassConstructorDescriptor) return member + if (isDefaultConstructor && member is ClassConstructorDescriptor) return member val realMembers = - if (proto.isFakeOverride && member is CallableMemberDescriptor && member.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) + if (isFakeOverride && member is CallableMemberDescriptor && member.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) member.resolveFakeOverrideMaybeAbstract() else setOf(member) @@ -69,12 +82,12 @@ class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val r if (memberIndices.contains(protoIndex)) { return when { - member is PropertyDescriptor && proto.isSetter -> member.setter!! - member is PropertyDescriptor && proto.isGetter -> member.getter!! + member is PropertyDescriptor && isSetter -> member.setter!! + member is PropertyDescriptor && isGetter -> member.getter!! else -> member } } } - error("Could not find serialized descriptor for index: ${proto.uniqId.index} ${proto.packageFqName},${proto.classFqName},${proto.name}") + error("Could not find serialized descriptor for index: ${index} ${packageFqName},${classFqName},${name}") } } \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/IrModuleDeserializer.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/IrModuleDeserializer.kt index 62a679a7528..18028e2fd79 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/IrModuleDeserializer.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/IrModuleDeserializer.kt @@ -62,6 +62,7 @@ abstract class IrModuleDeserializer( abstract fun deserializeIrSymbol(proto: KonanIr.IrSymbol): IrSymbol abstract fun deserializeIrType(proto: KonanIr.IrTypeIndex): IrType abstract fun deserializeDescriptorReference(proto: KonanIr.DescriptorReference): DeclarationDescriptor + abstract fun deserializeString(proto: KonanIr.String): String private fun deserializeTypeArguments(proto: KonanIr.TypeArguments): List { logger.log { "### deserializeTypeArguments" } @@ -540,7 +541,7 @@ abstract class IrModuleDeserializer( val loopId = proto.loopId loopIndex.getOrPut(loopId) { loop } - val label = if (proto.hasLabel()) proto.label else null + val label = if (proto.hasLabel()) deserializeString(proto.label) else null val body = if (proto.hasBody()) deserializeExpression(proto.body) else null val condition = deserializeExpression(proto.condition) @@ -568,7 +569,7 @@ abstract class IrModuleDeserializer( } private fun deserializeBreak(proto: KonanIr.IrBreak, start: Int, end: Int, type: IrType): IrBreak { - val label = if (proto.hasLabel()) proto.label else null + val label = if (proto.hasLabel()) deserializeString(proto.label) else null val loopId = proto.loopId val loop = loopIndex[loopId]!! val irBreak = IrBreakImpl(start, end, type, loop) @@ -578,7 +579,7 @@ abstract class IrModuleDeserializer( } private fun deserializeContinue(proto: KonanIr.IrContinue, start: Int, end: Int, type: IrType): IrContinue { - val label = if (proto.hasLabel()) proto.label else null + val label = if (proto.hasLabel()) deserializeString(proto.label) else null val loopId = proto.loopId val loop = loopIndex[loopId]!! val irContinue = IrContinueImpl(start, end, type, loop) @@ -604,7 +605,7 @@ abstract class IrModuleDeserializer( LONG -> IrConstImpl.long(start, end, type, proto.long) STRING - -> IrConstImpl.string(start, end, type, proto.string) + -> IrConstImpl.string(start, end, type, deserializeString(proto.string)) FLOAT -> IrConstImpl.float(start, end, type, proto.float) DOUBLE @@ -693,7 +694,7 @@ abstract class IrModuleDeserializer( origin: IrDeclarationOrigin ): IrTypeParameter { val symbol = deserializeIrSymbol(proto.symbol) as IrTypeParameterSymbol - val name = Name.identifier(proto.name) + val name = Name.identifier(deserializeString(proto.name)) val variance = deserializeIrTypeVariance(proto.variance) val parameter = symbolTable.declareGlobalTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin, @@ -741,7 +742,7 @@ abstract class IrModuleDeserializer( IrValueParameterImpl( start, end, origin, deserializeIrSymbol(proto.symbol) as IrValueParameterSymbol, - Name.identifier(proto.name), + Name.identifier(deserializeString(proto.name)), proto.index, deserializeIrType(proto.type), varargElementType, @@ -763,11 +764,11 @@ abstract class IrModuleDeserializer( val modality = deserializeModality(proto.modality) val clazz = symbolTable.declareClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin, - symbol.descriptor, modality) { symbol -> + symbol.descriptor, modality) { IrClassImpl( start, end, origin, - symbol, - Name.identifier(proto.name), + it, + Name.identifier(deserializeString(proto.name)), deserializeClassKind(proto.kind), deserializeVisibility(proto.visibility), modality, @@ -825,14 +826,14 @@ abstract class IrModuleDeserializer( start: Int, end: Int, origin: IrDeclarationOrigin, correspondingProperty: IrProperty? = null ): IrSimpleFunction { - logger.log { "### deserializing IrFunction ${proto.base.name}" } + logger.log { "### deserializing IrFunction ${deserializeString(proto.base.name)}" } val symbol = deserializeIrSymbol(proto.symbol) as IrSimpleFunctionSymbol val function = symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin, symbol.descriptor, { IrFunctionImpl( start, end, origin, it, - Name.identifier(proto.base.name), + Name.identifier(deserializeString(proto.base.name)), deserializeVisibility(proto.base.visibility), deserializeModality(proto.modality), deserializeIrType(proto.base.returnType), @@ -869,7 +870,7 @@ abstract class IrModuleDeserializer( end, origin, symbol, - Name.identifier(proto.name), + Name.identifier(deserializeString(proto.name)), type, proto.isVar, proto.isConst, @@ -891,7 +892,7 @@ abstract class IrModuleDeserializer( irrelevantOrigin, symbol.descriptor ) { - IrEnumEntryImpl(start, end, origin, it, Name.identifier(proto.name)) + IrEnumEntryImpl(start, end, origin, it, Name.identifier(deserializeString(proto.name))) } if (proto.hasCorrespondingClass()) { @@ -916,8 +917,8 @@ abstract class IrModuleDeserializer( return initializer } - private fun deserializeVisibility(value: String): Visibility { // TODO: switch to enum - return when (value) { + private fun deserializeVisibility(value: KonanIr.Visibility): Visibility { // TODO: switch to enum + return when (deserializeString(value.name)) { "public" -> Visibilities.PUBLIC "private" -> Visibilities.PRIVATE "private_to_this" -> Visibilities.PRIVATE_TO_THIS @@ -942,7 +943,7 @@ abstract class IrModuleDeserializer( IrConstructorImpl( start, end, origin, it, - Name.identifier(proto.base.name), + Name.identifier(deserializeString(proto.base.name)), deserializeVisibility(proto.base.visibility), deserializeIrType(proto.base.returnType), proto.base.isInline, @@ -968,7 +969,7 @@ abstract class IrModuleDeserializer( { IrFieldImpl( start, end, origin, it, - Name.identifier(proto.name), + Name.identifier(deserializeString(proto.name)), type, deserializeVisibility(proto.visibility), proto.isFinal, @@ -1009,7 +1010,7 @@ abstract class IrModuleDeserializer( val property = IrPropertyImpl( start, end, origin, descriptor, - Name.identifier(proto.name), + Name.identifier(deserializeString(proto.name)), deserializeVisibility(proto.visibility), deserializeModality(proto.modality), proto.isVar, @@ -1068,12 +1069,13 @@ abstract class IrModuleDeserializer( IrDeclarationOrigin::class.nestedClasses.toList() + DeclarationFactory.FIELD_FOR_OUTER_THIS::class val originIndex = allKnownOrigins.map { it.objectInstance as IrDeclarationOriginImpl }.associateBy { it.name } val irrelevantOrigin = object : IrDeclarationOriginImpl("irrelevant") {} + fun deserializeIrDeclarationOrigin(proto: KonanIr.IrDeclarationOrigin) = originIndex[deserializeString(proto.custom)]!! protected fun deserializeDeclaration(proto: KonanIr.IrDeclaration, parent: IrDeclarationParent?): IrDeclaration { val start = proto.coordinates.startOffset val end = proto.coordinates.endOffset - val origin = originIndex[proto.origin.name]!! + val origin = deserializeIrDeclarationOrigin(proto.origin) val declarator = proto.declarator diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/IrModuleSerializer.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/IrModuleSerializer.kt index 14a560cd4dd..f1ade2f5fef 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/IrModuleSerializer.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/IrModuleSerializer.kt @@ -51,7 +51,7 @@ internal class IrModuleSerializer( private val loopIndex = mutableMapOf() private var currentLoopIndex = 0 - val descriptorReferenceSerializer = DescriptorReferenceSerializer(declarationTable) + val descriptorReferenceSerializer = DescriptorReferenceSerializer(declarationTable, { string -> serializeString(string) }) // The same symbol can be used multiple times in a module // so use this index to store symbol data only once. @@ -63,6 +63,44 @@ internal class IrModuleSerializer( val protoTypeMap = mutableMapOf() val protoTypeArray = arrayListOf() + val protoStringMap = mutableMapOf() + val protoStringArray = arrayListOf() + + /* ------- Common fields ---------------------------------------------------- */ + + private fun serializeIrDeclarationOrigin(origin: IrDeclarationOrigin) = + KonanIr.IrDeclarationOrigin.newBuilder() + .setCustom(serializeString((origin as IrDeclarationOriginImpl).name)) + .build() + + private fun serializeIrStatementOrigin(origin: IrStatementOrigin) = + KonanIr.IrStatementOrigin.newBuilder() + .setName(serializeString((origin as IrStatementOriginImpl).debugName)) + .build() + + private fun serializeVisibility(visibility: Visibility) = + KonanIr.Visibility.newBuilder() + .setName(serializeString(visibility.name)) + .build() + + private fun serializeCoordinates(start: Int, end: Int): KonanIr.Coordinates { + return KonanIr.Coordinates.newBuilder() + .setStartOffset(start) + .setEndOffset(end) + .build() + } + + /* ------- Strings ---------------------------------------------------------- */ + + fun serializeString(value: String): KonanIr.String { + val proto = KonanIr.String.newBuilder() + proto.index = protoStringMap.getOrPut(value) { + protoStringArray.add(value) + protoStringArray.size - 1 + } + return proto.build() + } + /* ------- IrSymbols -------------------------------------------------------- */ fun protoSymbolKind(symbol: IrSymbol): KonanIr.IrSymbolKind = when (symbol) { @@ -377,7 +415,7 @@ internal class IrModuleSerializer( val proto = KonanIr.IrFunctionReference.newBuilder() .setSymbol(serializeIrSymbol(callable.symbol)) .setMemberAccess(serializeMemberAccessCommon(callable)) - callable.origin?.let { proto.origin = (it as IrStatementOriginImpl).debugName } + callable.origin?.let { proto.origin = serializeIrStatementOrigin(it) } return proto.build() } @@ -388,7 +426,7 @@ internal class IrModuleSerializer( callable.field?.let { proto.field = serializeIrSymbol(it) } callable.getter?.let { proto.getter = serializeIrSymbol(it) } callable.setter?.let { proto.setter = serializeIrSymbol(it) } - callable.origin?.let { proto.origin = (it as IrStatementOriginImpl).debugName } + callable.origin?.let { proto.origin = serializeIrStatementOrigin(it) } return proto.build() } @@ -409,7 +447,7 @@ internal class IrModuleSerializer( IrConstKind.Short -> proto.short = (value.value as Short).toInt() IrConstKind.Int -> proto.int = value.value as Int IrConstKind.Long -> proto.long = value.value as Long - IrConstKind.String -> proto.string = value.value as String + IrConstKind.String -> proto.string = serializeString(value.value as String) IrConstKind.Float -> proto.float = value.value as Float IrConstKind.Double -> proto.double = value.value as Double } @@ -606,7 +644,7 @@ internal class IrModuleSerializer( private fun serializeLoop(expression: IrLoop): KonanIr.Loop { val proto = KonanIr.Loop.newBuilder() .setCondition(serializeExpression(expression.condition)) - val label = expression.label + val label = expression.label?.let { serializeString(it) } if (label != null) { proto.label = label } @@ -631,7 +669,7 @@ internal class IrModuleSerializer( private fun serializeBreak(expression: IrBreak): KonanIr.IrBreak { val proto = KonanIr.IrBreak.newBuilder() - val label = expression.label + val label = expression.label?.let { serializeString(it) } if (label != null) { proto.label = label } @@ -643,7 +681,7 @@ internal class IrModuleSerializer( private fun serializeContinue(expression: IrContinue): KonanIr.IrContinue { val proto = KonanIr.IrContinue.newBuilder() - val label = expression.label + val label = expression.label?.let { serializeString(it) } if (label != null) { proto.label = label } @@ -653,13 +691,6 @@ internal class IrModuleSerializer( return proto.build() } - private fun serializeCoordinates(start: Int, end: Int): KonanIr.Coordinates { - return KonanIr.Coordinates.newBuilder() - .setStartOffset(start) - .setEndOffset(end) - .build() - } - private fun serializeExpression(expression: IrExpression): KonanIr.IrExpression { logger.log { "### serializing Expression: ${ir2string(expression)}" } @@ -758,7 +789,7 @@ internal class IrModuleSerializer( private fun serializeIrValueParameter(parameter: IrValueParameter): KonanIr.IrValueParameter { val proto = KonanIr.IrValueParameter.newBuilder() .setSymbol(serializeIrSymbol(parameter.symbol)) - .setName(parameter.name.toString()) + .setName(serializeString(parameter.name.toString())) .setIndex(parameter.index) .setType(serializeIrType(parameter.type)) .setIsCrossinline(parameter.isCrossinline) @@ -773,7 +804,7 @@ internal class IrModuleSerializer( private fun serializeIrTypeParameter(parameter: IrTypeParameter): KonanIr.IrTypeParameter { val proto = KonanIr.IrTypeParameter.newBuilder() .setSymbol(serializeIrSymbol(parameter.symbol)) - .setName(parameter.name.toString()) + .setName(serializeString(parameter.name.toString())) .setIndex(parameter.index) .setVariance(serializeIrTypeVariance(parameter.variance)) .setIsReified(parameter.isReified) @@ -793,7 +824,7 @@ internal class IrModuleSerializer( private fun serializeIrFunctionBase(function: IrFunctionBase): KonanIr.IrFunctionBase { val proto = KonanIr.IrFunctionBase.newBuilder() - .setName(function.name.toString()) + .setName(serializeString(function.name.toString())) .setVisibility(serializeVisibility(function.visibility)) .setIsInline(function.isInline) .setIsExternal(function.isExternal) @@ -854,16 +885,12 @@ internal class IrModuleSerializer( .setBody(serializeStatement(declaration.body)) .build() - private fun serializeVisibility(visibility: Visibility): String { - return visibility.name - } - private fun serializeIrProperty(property: IrProperty): KonanIr.IrProperty { val index = declarationTable.uniqIdByDeclaration(property) val proto = KonanIr.IrProperty.newBuilder() .setIsDelegated(property.isDelegated) - .setName(property.name.toString()) + .setName(serializeString(property.name.toString())) .setVisibility(serializeVisibility(property.visibility)) .setModality(serializeModality(property.modality)) .setIsVar(property.isVar) @@ -890,7 +917,7 @@ internal class IrModuleSerializer( private fun serializeIrField(field: IrField): KonanIr.IrField { val proto = KonanIr.IrField.newBuilder() .setSymbol(serializeIrSymbol(field.symbol)) - .setName(field.name.toString()) + .setName(serializeString(field.name.toString())) .setVisibility(serializeVisibility(field.visibility)) .setIsFinal(field.isFinal) .setIsExternal(field.isExternal) @@ -906,7 +933,7 @@ internal class IrModuleSerializer( private fun serializeIrVariable(variable: IrVariable): KonanIr.IrVariable { val proto = KonanIr.IrVariable.newBuilder() .setSymbol(serializeIrSymbol(variable.symbol)) - .setName(variable.name.toString()) + .setName(serializeString(variable.name.toString())) .setType(serializeIrType(variable.type)) .setIsConst(variable.isConst) .setIsVar(variable.isVar) @@ -935,7 +962,7 @@ internal class IrModuleSerializer( private fun serializeIrClass(clazz: IrClass): KonanIr.IrClass { val proto = KonanIr.IrClass.newBuilder() - .setName(clazz.name.toString()) + .setName(serializeString(clazz.name.toString())) .setSymbol(serializeIrSymbol(clazz.symbol)) .setKind(serializeClassKind(clazz.kind)) .setVisibility(serializeVisibility(clazz.visibility)) @@ -957,7 +984,7 @@ internal class IrModuleSerializer( private fun serializeIrEnumEntry(enumEntry: IrEnumEntry): KonanIr.IrEnumEntry { val proto = KonanIr.IrEnumEntry.newBuilder() - .setName(enumEntry.name.toString()) + .setName(serializeString(enumEntry.name.toString())) .setSymbol(serializeIrSymbol(enumEntry.symbol)) enumEntry.initializerExpression?.let { @@ -969,10 +996,6 @@ internal class IrModuleSerializer( return proto.build() } - private fun serializeIrDeclarationOrigin(origin: IrDeclarationOrigin) = - KonanIr.IrDeclarationOrigin.newBuilder() - .setName((origin as IrDeclarationOriginImpl).name) - private fun serializeDeclaration(declaration: IrDeclaration): KonanIr.IrDeclaration { logger.log { "### serializing Declaration: ${ir2string(declaration)}" } @@ -1020,7 +1043,7 @@ internal class IrModuleSerializer( //val fileName = context.ir.originalModuleIndex.declarationToFile[declaration.descriptor] //proto.fileName = fileName - proto.fileName = "some file name" + proto.fileName = serializeString("some file name") return proto.build() } @@ -1028,7 +1051,7 @@ internal class IrModuleSerializer( // ---------- Top level ------------------------------------------------------ fun serializeFileEntry(entry: SourceManager.FileEntry) = KonanIr.FileEntry.newBuilder() - .setName(entry.name) + .setName(serializeString(entry.name)) .build() val topLevelDeclarations = mutableMapOf() @@ -1054,7 +1077,7 @@ internal class IrModuleSerializer( fun serializeModule(module: IrModuleFragment): KonanIr.IrModule { val proto = KonanIr.IrModule.newBuilder() - .setName(module.name.toString()) + .setName(serializeString(module.name.toString())) module.files.forEach { proto.addFile(serializeIrFile(it)) } @@ -1066,6 +1089,10 @@ internal class IrModuleSerializer( .addAllTypes(protoTypeArray) .build() + proto.stringTable = KonanIr.StringTable.newBuilder() + .addAllStrings(protoStringArray) + .build() + return proto.build() } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIr.proto b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIr.proto index d95b41908f8..692e9fb4f30 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIr.proto +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIr.proto @@ -28,6 +28,52 @@ message Coordinates { required int32 end_offset = 2; } +message Visibility { + required String name = 1; +} + +message IrStatementOrigin { + required String name = 1; +} + +enum KnownOrigin { + CUSTOM = 1; + DEFINED = 2; + FAKE_OVERRIDE = 3; + FOR_LOOP_ITERATOR = 4; + FOR_LOOP_VARIABLE = 5; + FOR_LOOP_IMPLICIT_VARIABLE = 6; + PROPERTY_BACKING_FIELD = 7; + DEFAULT_PROPERTY_ACCESSOR = 8; + DELEGATE = 9; + DELEGATED_PROPERTY_ACCESSOR = 10; + DELEGATED_MEMBER = 11; + ENUM_CLASS_SPECIAL_MEMBER = 12; + FUNCTION_FOR_DEFAULT_PARAMETER = 13; + FILE_CLASS = 14; + GENERATED_DATA_CLASS_MEMBER = 15; + GENERATED_INLINE_CLASS_MEMBER = 16; + LOCAL_FUNCTION_FOR_LAMBDA = 17; + CATCH_PARAMETER = 19; + INSTANCE_RECEIVER = 20; + PRIMARY_CONSTRUCTOR_PARAMETER = 21; + IR_TEMPORARY_VARIABLE = 22; + IR_EXTERNAL_DECLARATION_STUB = 23; + IR_EXTERNAL_JAVA_DECLARATION_STUB = 24; + IR_BUILTINS_STUB = 25; + BRIDGE = 26; + FIELD_FOR_ENUM_ENTRY = 27; + FIELD_FOR_ENUM_VALUES = 28; + FIELD_FOR_OBJECT_INSTANCE = 29; +} + +message IrDeclarationOrigin { + oneof either { + KnownOrigin origin = 1; + String custom = 2; + } +} + /* ------ Top Level---------------------------------------KonanIrModuleDeserializer.kt------- */ message IrDeclarationContainer { @@ -35,7 +81,7 @@ message IrDeclarationContainer { } message FileEntry { // TODO: extend me. - required string name = 1; + required String name = 1; } message IrFile { @@ -46,10 +92,11 @@ message IrFile { } message IrModule { - required string name = 1; + required String name = 1; repeated IrFile file = 2; required IrSymbolTable symbol_table = 3; required IrTypeTable type_table = 4; + required StringTable string_table = 5; } /* ------ String Table ------------------------------------------ */ @@ -59,7 +106,7 @@ message String { } message StringTable { - repeated string value = 1; + repeated string strings = 1; } /* ------ IrSymbols --------------------------------------------- */ @@ -193,7 +240,7 @@ message IrCall { message IrFunctionReference { required IrSymbol symbol = 1; - optional Origin origin = 2; + optional IrStatementOrigin origin = 2; required MemberAccessCommon member_access = 3; } @@ -202,7 +249,7 @@ message IrPropertyReference { optional IrSymbol field = 1; optional IrSymbol getter = 2; optional IrSymbol setter = 3; - optional Origin origin = 4; + optional IrStatementOrigin origin = 4; required MemberAccessCommon member_access = 5; } @@ -421,8 +468,8 @@ message IrFunction { } message IrFunctionBase { - required string name = 1; - required string visibility = 2; + required String name = 1; + required Visibility visibility = 2; required bool is_inline = 3; required bool is_external = 4; required IrTypeParameterContainer type_parameters = 5; @@ -443,8 +490,8 @@ message IrConstructor { message IrField { required IrSymbol symbol = 1; optional IrExpression initializer = 2; - required string name = 3; - required string visibility = 4; + required String name = 3; + required Visibility visibility = 4; required bool is_final = 5; required bool is_external = 6; required bool is_static = 7; @@ -453,8 +500,8 @@ message IrField { message IrProperty { optional DescriptorReference descriptor = 1; // IrProperty doesn't have a symbol at all. Preserve this rudiment for now. - required string name = 2; - required string visibility = 3; + required String name = 2; + required Visibility visibility = 3; required ModalityKind modality = 4; required bool is_var = 5; required bool is_const = 6; @@ -467,7 +514,7 @@ message IrProperty { } message IrVariable { - required string name = 1; + required String name = 1; required IrSymbol symbol = 2; required IrTypeIndex type = 3; required bool is_var = 4; @@ -494,7 +541,7 @@ enum ModalityKind { // It is ModalityKind to not clash with Modality in descript message IrValueParameter { required IrSymbol symbol = 1; - required string name = 2; + required String name = 2; required int32 index = 3; required IrTypeIndex type = 4; optional IrTypeIndex vararg_element_type = 5; @@ -505,7 +552,7 @@ message IrValueParameter { message IrTypeParameter { required IrSymbol symbol = 1; - required string name = 2; + required String name = 2; required int32 index = 3; required IrTypeVariance variance = 4; repeated IrTypeIndex super_type = 5; @@ -518,9 +565,9 @@ message IrTypeParameterContainer { message IrClass { required IrSymbol symbol = 1; - required string name = 2; + required String name = 2; required ClassKind kind = 3; - required string visibility = 4; + required Visibility visibility = 4; required ModalityKind modality = 5; // TODO: consider using flags for the booleans. required bool is_companion = 6; @@ -538,7 +585,7 @@ message IrEnumEntry { required IrSymbol symbol = 1; optional IrExpression initializer = 2; optional IrDeclaration corresponding_class = 3; - required string name = 4; + required String name = 4; } message IrAnonymousInit { @@ -564,17 +611,12 @@ message IrDeclarator { } } -message IrDeclarationOrigin { - required string name = 1; -} - message IrDeclaration { required IrDeclarationOrigin origin = 1; required Coordinates coordinates = 2; required Annotations annotations = 3; required IrDeclarator declarator = 4; - //repeated IrDeclaration nested = 5; - required string file_name = 5; // TODO: files should be communicated some other way, I suppose. + required String file_name = 5; // TODO: files should be communicated some other way, I suppose. } /* ------- IrStatements --------------------------------------------- */ diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleDeserializer.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleDeserializer.kt index bd4d65e837c..d7dde8a6da7 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleDeserializer.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrModuleDeserializer.kt @@ -56,6 +56,7 @@ class KonanIrModuleDeserializer( var deserializedModuleDescriptor: ModuleDescriptor? = null var deserializedModuleProtoSymbolTables = mutableMapOf() + var deserializedModuleProtoStringTables = mutableMapOf() var deserializedModuleProtoTypeTables = mutableMapOf() val resolvedForwardDeclarations = mutableMapOf() @@ -139,6 +140,9 @@ class KonanIrModuleDeserializer( return deserializeIrTypeData(typeData) } + override fun deserializeString(proto: KonanIr.String) = + deserializedModuleProtoStringTables[deserializedModuleDescriptor]!!.getStrings(proto.index) + fun deserializeIrSymbolData(proto: KonanIr.IrSymbolData): IrSymbol { val key = proto.uniqId.uniqIdKey(deserializedModuleDescriptor!!) val topLevelKey = proto.topLevelUniqId.uniqIdKey(deserializedModuleDescriptor!!) @@ -169,8 +173,19 @@ class KonanIrModuleDeserializer( return symbol } - override fun deserializeDescriptorReference(proto: KonanIr.DescriptorReference) - = descriptorReferenceDeserializer.deserializeDescriptorReference(proto) + override fun deserializeDescriptorReference(proto: KonanIr.DescriptorReference): DeclarationDescriptor = + descriptorReferenceDeserializer.deserializeDescriptorReference( + deserializeString(proto.packageFqName), + deserializeString(proto.classFqName), + deserializeString(proto.name), + if (proto.hasUniqId()) proto.uniqId.index else null, + isEnumEntry = proto.isEnumEntry, + isEnumSpecial = proto.isEnumSpecial, + isDefaultConstructor = proto.isDefaultConstructor, + isFakeOverride = proto.isFakeOverride, + isGetter = proto.isGetter, + isSetter = proto.isSetter + ) private val ByteArray.codedInputStream: org.jetbrains.kotlin.protobuf.CodedInputStream get() { @@ -295,7 +310,7 @@ class KonanIrModuleDeserializer( } fun deserializeIrFile(fileProto: KonanIr.IrFile, moduleDescriptor: ModuleDescriptor, deserializeAllDeclarations: Boolean): IrFile { - val fileEntry = NaiveSourceBasedFileEntryImpl(fileProto.fileEntry.name) + val fileEntry = NaiveSourceBasedFileEntryImpl(deserializeString(fileProto.fileEntry.name)) // TODO: we need to store "" in protobuf, I suppose. Or better yet, reuse fqname storage from metadata. val fqName = if (fileProto.fqName == "") FqName.ROOT else FqName(fileProto.fqName) @@ -321,6 +336,7 @@ class KonanIrModuleDeserializer( deserializedModuleDescriptor = moduleDescriptor deserializedModuleProtoSymbolTables.put(moduleDescriptor, proto.symbolTable) + deserializedModuleProtoStringTables.put(moduleDescriptor, proto.stringTable) deserializedModuleProtoTypeTables.put(moduleDescriptor, proto.typeTable) val files = proto.fileList.map { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeDescriptorReference.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeDescriptorReference.kt index 581e67ec358..044648a48bc 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeDescriptorReference.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeDescriptorReference.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.metadata.KonanIr import org.jetbrains.kotlin.resolve.descriptorUtil.classId -class DescriptorReferenceSerializer(val declarationTable: DeclarationTable) { +class DescriptorReferenceSerializer(val declarationTable: DeclarationTable, val serializeString: (String) -> KonanIr.String) { // Not all exported descriptors are deserialized, some a synthesized anew during metadata deserialization. // Those created descriptors can't carry the uniqIdIndex, since it is available only for deserialized descriptors. @@ -73,9 +73,9 @@ class DescriptorReferenceSerializer(val declarationTable: DeclarationTable) { uniqId?.let { declarationTable.descriptors.put(discoverableDescriptorsDeclaration.descriptor, it) } val proto = KonanIr.DescriptorReference.newBuilder() - .setPackageFqName(packageFqName) - .setClassFqName(classFqName) - .setName(descriptor.name.toString()) + .setPackageFqName(serializeString(packageFqName)) + .setClassFqName(serializeString(classFqName)) + .setName(serializeString(descriptor.name.toString())) if (uniqId != null) proto.setUniqId(protoUniqId(uniqId))