From 2ad0be618200259a8a85fa344655059a340469b8 Mon Sep 17 00:00:00 2001 From: Alexander Gorshenev Date: Thu, 13 Apr 2017 14:40:09 +0300 Subject: [PATCH] Substitute real rootFunction type parametrs instead of deserialized ones. More direct acquisition of type serializer from the descriptor serializer. --- .../KonanDescriptorSerializer.kt | 6 ++- .../serialization/KonanSerializerExtension.kt | 6 ++- .../LocalDeclarationDeserializer.kt | 7 ++- .../konan/serialization/SerializeIr.kt | 54 ++++++++++++++++--- 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanDescriptorSerializer.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanDescriptorSerializer.kt index 1a4629c37c6..9064b75a481 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanDescriptorSerializer.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanDescriptorSerializer.kt @@ -286,7 +286,11 @@ class KonanDescriptorSerializer private constructor( builder.sinceKotlinInfo = writeSinceKotlinInfo(LanguageFeature.Coroutines) } - extension.serializeFunction(descriptor, builder) + if (extension is KonanSerializerExtension) { + extension.serializeFunctionWithIR(descriptor, builder, {it -> typeId(it)}) + } else { + extension.serializeFunction(descriptor, builder) + } return builder } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanSerializerExtension.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanSerializerExtension.kt index c0e15543a3a..c662bcebd5a 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanSerializerExtension.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanSerializerExtension.kt @@ -98,7 +98,9 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer super.serializeClass(descriptor, proto) } - override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) { + override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) = serializeFunctionWithIR(descriptor, proto, null) + + fun serializeFunctionWithIR(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder, typeSerializer: ((KotlinType)->Int)?) { proto.setFunctionIndex( inlineDescriptorTable.indexByValue(descriptor)) @@ -107,7 +109,7 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer if (descriptor.needsInlining) { val encodedIR: String = IrSerializer( context, - inlineDescriptorTable, stringTable, util, descriptor) + inlineDescriptorTable, stringTable, util, typeSerializer!!, descriptor) .serializeInlineBody() val inlineIrBody = KonanLinkData.InlineIrBody diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/LocalDeclarationDeserializer.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/LocalDeclarationDeserializer.kt index bee84882338..07592e997bb 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/LocalDeclarationDeserializer.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/LocalDeclarationDeserializer.kt @@ -49,10 +49,10 @@ class LocalDeclarationDeserializer(val rootFunction: FunctionDescriptor, val mod val context = components.createContext( pkg, nameResolver, typeTable, SinceKotlinInfoTable.EMPTY, null) - val typeParameters = (rootFunction as DeserializedSimpleFunctionDescriptor).proto.typeParameterList - - val childContext = context.childContext(rootFunction, typeParameters, nameResolver, typeTable) + val typeParameterProtos = (rootFunction as DeserializedSimpleFunctionDescriptor).proto.typeParameterList + val childContext = context.childContext(rootFunction, typeParameterProtos, nameResolver, typeTable) val typeDeserializer = childContext.typeDeserializer + val memberDeserializer = MemberDeserializer(childContext) fun deserializeInlineType(type: ProtoBuf.Type): KotlinType { @@ -97,7 +97,6 @@ class LocalDeclarationDeserializer(val rootFunction: FunctionDescriptor, val mod memberDeserializerByParentFqNameIndex(containingFqName) val function = memberDeserializer.loadFunction(proto) - return function } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeIr.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeIr.kt index b5af8523be9..ad39303697b 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeIr.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/SerializeIr.kt @@ -16,20 +16,25 @@ package org.jetbrains.kotlin.backend.konan.serialization + +import org.jetbrains.kotlin.backend.common.DeepCopyIrTreeWithDescriptors +import org.jetbrains.kotlin.backend.common.ScopeWithIr import org.jetbrains.kotlin.backend.konan.Context -import org.jetbrains.kotlin.backend.konan.descriptors.getMemberScope +import org.jetbrains.kotlin.backend.konan.KonanIrDeserializationException import org.jetbrains.kotlin.backend.konan.ir.ir2string import org.jetbrains.kotlin.backend.konan.ir.ir2stringWhole -import org.jetbrains.kotlin.backend.konan.KonanIrDeserializationException import org.jetbrains.kotlin.backend.konan.llvm.base64Decode import org.jetbrains.kotlin.backend.konan.llvm.base64Encode import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin.DEFINED -import org.jetbrains.kotlin.ir.declarations.impl.* +import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrEnumEntryImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl +import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.serialization.KonanIr @@ -37,17 +42,21 @@ import org.jetbrains.kotlin.serialization.KonanIr.IrConst.ValueCase.* import org.jetbrains.kotlin.serialization.KonanLinkData import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeProjectionImpl +import org.jetbrains.kotlin.types.TypeSubstitutor + internal class IrSerializer(val context: Context, val descriptorTable: DescriptorTable, val stringTable: KonanStringTable, val util: KonanSerializationUtil, + val typeSerializer: ((KotlinType)->Int), var rootFunction: FunctionDescriptor) { val loopIndex = mutableMapOf() var currentLoopIndex = 0 val irDescriptorSerializer = IrDescriptorSerializer(context, - descriptorTable, stringTable, util.typeSerializer, rootFunction) + descriptorTable, stringTable, typeSerializer, rootFunction) fun serializeInlineBody(): String { val declaration = context.ir.originalModuleIndex.functions[rootFunction]!! @@ -1033,6 +1042,35 @@ internal class IrDeserializer(val context: Context, return declaration } + // We run inline body deserializations after the public descriptor tree + // deserialization is long gone. So we don't have the needed chain of + // deserialization contexts available to take type parameters. + // So typeDeserializer introduces a brand new set of DeserializadTypeParameterDescriptor + // for the rootFunction. + // This function takes the type parameters from the rootFunction descriptor + // and substitutes them instead the deserialized ones. + // TODO: consider lazy inline body deserialization during the public descriptors deserialization. + // I tried to copy over TypeDeserializaer, MemberDeserializer, + // and the rest of what's needed, but it didn't work out. + fun adaptDeserializedTypeParameters(declaration: IrDeclaration): IrDeclaration { + val rootFunctionTypeParameters = + descriptorDeserializer.localDeserializer.childContext.typeDeserializer.ownTypeParameters + + val substitutionContext = rootFunctionTypeParameters.mapIndexed{ + index, param -> + Pair(param.typeConstructor, TypeProjectionImpl(rootFunction.typeParameters[index].defaultType)) + }.associate{ + (key,value) -> + key to value} + + val copyFunctionDeclaration = DeepCopyIrTreeWithDescriptors(rootFunction.containingDeclaration, context).copy( + irElement = declaration, + typeSubstitutor = TypeSubstitutor.create(substitutionContext) + ) as IrFunction + + return copyFunctionDeclaration + } + fun decodeDeclaration(): IrDeclaration { val proto = (rootFunction as DeserializedSimpleFunctionDescriptor).proto @@ -1044,7 +1082,11 @@ internal class IrDeserializer(val context: Context, val base64 = inlineProto.encodedIr val byteArray = base64Decode(base64) val irProto = KonanIr.IrDeclaration.parseFrom(byteArray, KonanSerializerProtocol.extensionRegistry) - return deserializeDeclaration(irProto) + val declaration = deserializeDeclaration(irProto) + + val copyFunctionDeclaration = adaptDeserializedTypeParameters(declaration) + + return copyFunctionDeclaration } }