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)
}
extension.serializeFunction(descriptor, builder)
if (extension is KonanSerializerExtension) {
extension.serializeFunctionWithIR(descriptor, builder, {it -> typeId(it)})
} else {
extension.serializeFunction(descriptor, builder)
}
return builder
}
@@ -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
@@ -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
}
@@ -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<IrLoop, Int>()
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
}
}