Substitute real rootFunction type parametrs instead of deserialized ones.

More direct acquisition of type serializer from the descriptor serializer.
This commit is contained in:
Alexander Gorshenev
2017-04-13 14:40:09 +03:00
committed by alexander-gorshenev
parent 3139ae279c
commit 2ad0be6182
4 changed files with 60 additions and 13 deletions
@@ -286,7 +286,11 @@ class KonanDescriptorSerializer private constructor(
builder.sinceKotlinInfo = writeSinceKotlinInfo(LanguageFeature.Coroutines) 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 return builder
} }
@@ -98,7 +98,9 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
super.serializeClass(descriptor, proto) 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( proto.setFunctionIndex(
inlineDescriptorTable.indexByValue(descriptor)) inlineDescriptorTable.indexByValue(descriptor))
@@ -107,7 +109,7 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
if (descriptor.needsInlining) { if (descriptor.needsInlining) {
val encodedIR: String = IrSerializer( context, val encodedIR: String = IrSerializer( context,
inlineDescriptorTable, stringTable, util, descriptor) inlineDescriptorTable, stringTable, util, typeSerializer!!, descriptor)
.serializeInlineBody() .serializeInlineBody()
val inlineIrBody = KonanLinkData.InlineIrBody val inlineIrBody = KonanLinkData.InlineIrBody
@@ -49,10 +49,10 @@ class LocalDeclarationDeserializer(val rootFunction: FunctionDescriptor, val mod
val context = components.createContext( val context = components.createContext(
pkg, nameResolver, typeTable, SinceKotlinInfoTable.EMPTY, null) pkg, nameResolver, typeTable, SinceKotlinInfoTable.EMPTY, null)
val typeParameters = (rootFunction as DeserializedSimpleFunctionDescriptor).proto.typeParameterList val typeParameterProtos = (rootFunction as DeserializedSimpleFunctionDescriptor).proto.typeParameterList
val childContext = context.childContext(rootFunction, typeParameterProtos, nameResolver, typeTable)
val childContext = context.childContext(rootFunction, typeParameters, nameResolver, typeTable)
val typeDeserializer = childContext.typeDeserializer val typeDeserializer = childContext.typeDeserializer
val memberDeserializer = MemberDeserializer(childContext) val memberDeserializer = MemberDeserializer(childContext)
fun deserializeInlineType(type: ProtoBuf.Type): KotlinType { fun deserializeInlineType(type: ProtoBuf.Type): KotlinType {
@@ -97,7 +97,6 @@ class LocalDeclarationDeserializer(val rootFunction: FunctionDescriptor, val mod
memberDeserializerByParentFqNameIndex(containingFqName) memberDeserializerByParentFqNameIndex(containingFqName)
val function = memberDeserializer.loadFunction(proto) val function = memberDeserializer.loadFunction(proto)
return function return function
} }
@@ -16,20 +16,25 @@
package org.jetbrains.kotlin.backend.konan.serialization 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.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.ir2string
import org.jetbrains.kotlin.backend.konan.ir.ir2stringWhole 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.base64Decode
import org.jetbrains.kotlin.backend.konan.llvm.base64Encode import org.jetbrains.kotlin.backend.konan.llvm.base64Encode
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement 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.*
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin.DEFINED 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.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.serialization.KonanIr 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.KonanLinkData
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.TypeSubstitutor
internal class IrSerializer(val context: Context, internal class IrSerializer(val context: Context,
val descriptorTable: DescriptorTable, val descriptorTable: DescriptorTable,
val stringTable: KonanStringTable, val stringTable: KonanStringTable,
val util: KonanSerializationUtil, val util: KonanSerializationUtil,
val typeSerializer: ((KotlinType)->Int),
var rootFunction: FunctionDescriptor) { var rootFunction: FunctionDescriptor) {
val loopIndex = mutableMapOf<IrLoop, Int>() val loopIndex = mutableMapOf<IrLoop, Int>()
var currentLoopIndex = 0 var currentLoopIndex = 0
val irDescriptorSerializer = IrDescriptorSerializer(context, val irDescriptorSerializer = IrDescriptorSerializer(context,
descriptorTable, stringTable, util.typeSerializer, rootFunction) descriptorTable, stringTable, typeSerializer, rootFunction)
fun serializeInlineBody(): String { fun serializeInlineBody(): String {
val declaration = context.ir.originalModuleIndex.functions[rootFunction]!! val declaration = context.ir.originalModuleIndex.functions[rootFunction]!!
@@ -1033,6 +1042,35 @@ internal class IrDeserializer(val context: Context,
return declaration 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 { fun decodeDeclaration(): IrDeclaration {
val proto = (rootFunction as DeserializedSimpleFunctionDescriptor).proto val proto = (rootFunction as DeserializedSimpleFunctionDescriptor).proto
@@ -1044,7 +1082,11 @@ internal class IrDeserializer(val context: Context,
val base64 = inlineProto.encodedIr val base64 = inlineProto.encodedIr
val byteArray = base64Decode(base64) val byteArray = base64Decode(base64)
val irProto = KonanIr.IrDeclaration.parseFrom(byteArray, KonanSerializerProtocol.extensionRegistry) val irProto = KonanIr.IrDeclaration.parseFrom(byteArray, KonanSerializerProtocol.extensionRegistry)
return deserializeDeclaration(irProto) val declaration = deserializeDeclaration(irProto)
val copyFunctionDeclaration = adaptDeserializedTypeParameters(declaration)
return copyFunctionDeclaration
} }
} }