Skip to content

Commit

Permalink
Create a copy of incorrectly deserialized parent's writeSelf function
Browse files Browse the repository at this point in the history
To avoid problems during code generation when INVOKEDYNAMIC
is used instead of static

#KT-47161 Fixed
  • Loading branch information
sandwwraith authored and Space committed Jun 8, 2021
1 parent 7c7905b commit dd21326
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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(
Expand Down

0 comments on commit dd21326

Please sign in to comment.