Create a copy of incorrectly deserialized parent's writeSelf function

To avoid problems during code generation when INVOKEDYNAMIC
is used instead of static

#KT-47161 Fixed
This commit is contained in:
Leonid Startsev
2021-06-07 16:22:53 +03:00
committed by Space
parent 7c7905b55c
commit dd21326425
2 changed files with 17 additions and 5 deletions
@@ -299,11 +299,22 @@ class SerializableIrGenerator(
ignoreIndexTo = bindingContext.serializablePropertiesFor(superClass.descriptor).size
// call super.writeSelf
val superWriteSelfF = superClass.findWriteSelfMethod()
var superWriteSelfF = superClass.findWriteSelfMethod()
if (superWriteSelfF != null) {
// Workaround for incorrect DeserializedClassDescriptor on JVM (see MemberDeserializer#getDispatchReceiverParameter):
// Because Kotlin does not have static functions, descriptors from other modules are deserialized with dispatch receiver,
// even if they were created without it
if (superWriteSelfF.dispatchReceiverParameter != null) {
superWriteSelfF = compilerContext.copiedStaticWriteSelf.getOrPut(superWriteSelfF) {
superWriteSelfF!!.deepCopyWithSymbols(initialParent = superClass).also { it.dispatchReceiverParameter = null }
}
}
val args = mutableListOf<IrExpression>(irGet(objectToSerialize), irGet(localOutput), irGet(localSerialDesc))
val typeArgsForParent = serializableDescriptor.typeConstructor.supertypes.single { it.toClassDescriptor?.isInternalSerializable == true }.arguments
val typeArgsForParent =
serializableDescriptor.typeConstructor.supertypes.single { it.toClassDescriptor?.isInternalSerializable == true }.arguments
val parentWriteSelfSerializers = typeArgsForParent.map { arg ->
val genericIdx = serializableDescriptor.defaultType.arguments.indexOf(arg).let { if (it == -1) null else it }
val serial = findTypeSerializerOrContext(serializableDescriptor.module, arg.type)
@@ -10,9 +10,7 @@ import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -23,6 +21,7 @@ import org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializableCompa
import org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializableIrGenerator
import org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializerIrGenerator
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver
import java.util.concurrent.ConcurrentHashMap
/**
* Copy of [runOnFilePostfix], but this implementation first lowers declaration, then its children.
@@ -44,6 +43,8 @@ fun ClassLoweringPass.runOnFileInOrder(irFile: IrFile) {
class SerializationPluginContext(baseContext: IrPluginContext, val metadataPlugin: SerializationDescriptorSerializerPlugin?) :
IrPluginContext by baseContext {
lateinit var serialInfoImplJvmIrGenerator: SerialInfoImplJvmIrGenerator
internal val copiedStaticWriteSelf: MutableMap<IrSimpleFunction, IrSimpleFunction> = ConcurrentHashMap()
}
private class SerializerClassLowering(