Introduce support for plugin-defined intrinsics in JVM IR backend:

Add intrinsic for kotlinx.serialization.serializer<T>() function.

Plugin intrinsic for old backend is removed because it is too hard
and unjustifiable to unify them.
This commit is contained in:
Leonid Startsev
2022-02-07 18:08:23 +03:00
committed by Space
parent f9edbd825a
commit a59f5f407b
20 changed files with 989 additions and 580 deletions
@@ -72,7 +72,7 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: KotlinType,
type: KT,
asmType: Type
): Int = -1
}
@@ -206,7 +206,7 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
val applyResult = intrinsicsSupport.applyPluginDefinedReifiedOperationMarker(
insn,
instructions,
intrinsicsSupport.toKotlinType(type),
type,
asmType
)
if (applyResult == -1) return false
@@ -10,6 +10,7 @@ dependencies {
api(project(":compiler:ir.tree"))
api(project(":compiler:ir.interpreter"))
compileOnly(intellijCore())
compileOnly(commonDependency("org.jetbrains.intellij.deps:asm-all"))
}
sourceSets {
@@ -5,9 +5,15 @@
package org.jetbrains.kotlin.backend.common.extensions
import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
interface IrGenerationExtension : IrDeserializer.IrLinkerExtension {
companion object :
@@ -16,4 +22,15 @@ interface IrGenerationExtension : IrDeserializer.IrLinkerExtension {
)
fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext)
// TODO: normal dependency & typing
fun retrieveIntrinsic(symbol: IrFunctionSymbol): Any? = null
fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: IrType,
jvmBackendContext: BackendContext,
): Int = -1
}
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.intrinsics.SignatureString
import org.jetbrains.kotlin.backend.jvm.ir.getCallableReferenceOwnerKClassType
import org.jetbrains.kotlin.backend.jvm.ir.getCallableReferenceTopLevelFlag
@@ -12,12 +14,14 @@ import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.util.allParametersCount
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
@@ -31,6 +35,8 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.Type.INT_TYPE
import org.jetbrains.org.objectweb.asm.Type.VOID_TYPE
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
class IrInlineIntrinsicsSupport(
private val classCodegen: ClassCodegen,
@@ -120,4 +126,22 @@ class IrInlineIntrinsicsSupport(
classCodegen.context.ktDiagnosticReporter.at(reportErrorsOn, containingFile)
.report(JvmBackendErrors.TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND, typeParameterName.asString())
}
override fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: IrType,
asmType: Type
): Int {
return IrGenerationExtension.getInstances(classCodegen.context.state.project)
.map {
it.applyPluginDefinedReifiedOperationMarker(
insn,
instructions,
type,
classCodegen.context
)
}
.maxOrNull() ?: -1
}
}
@@ -286,8 +286,10 @@ open class JvmIrCodegenFactory(
if (evaluatorFragmentInfoForPsi2Ir != null) {
context.localDeclarationsLoweringData = mutableMapOf()
}
// todo: pass it here
val generationExtensions = IrGenerationExtension.getInstances(state.project)
val intrinsics by lazy { IrIntrinsicMethods(irModuleFragment.irBuiltins, context.ir.symbols) }
context.getIntrinsic = { symbol: IrFunctionSymbol -> intrinsics.getIntrinsic(symbol) }
context.getIntrinsic = { symbol: IrFunctionSymbol -> intrinsics.getIntrinsic(symbol) ?: generationExtensions.firstNotNullOfOrNull { it.retrieveIntrinsic(symbol) as? IntrinsicMarker } }
/* JvmBackendContext creates new unbound symbols, have to resolve them. */
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
@@ -157,7 +157,7 @@ class JvmBackendContext(
}
}
internal fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol =
fun referenceClass(descriptor: ClassDescriptor): IrClassSymbol =
symbolTable.lazyWrapper.referenceClass(descriptor)
internal fun referenceTypeParameter(descriptor: TypeParameterDescriptor): IrTypeParameterSymbol =
@@ -9,6 +9,7 @@ dependencies {
compileOnly(project(":compiler:backend"))
compileOnly(project(":compiler:ir.backend.common"))
compileOnly(project(":compiler:backend.jvm"))
compileOnly(project(":compiler:backend.jvm.codegen"))
compileOnly(project(":compiler:ir.tree"))
compileOnly(project(":js:js.frontend"))
compileOnly(project(":js:js.translator"))
@@ -63,7 +63,7 @@ internal fun IrClass.findPluginGeneratedMethod(name: String): IrSimpleFunction?
}
}
internal fun IrClass.isEnumWithLegacyGeneratedSerializer(context: SerializationPluginContext): Boolean = isInternallySerializableEnum() && !context.runtimeHasEnumSerializerFactoryFunctions
internal fun IrClass.isEnumWithLegacyGeneratedSerializer(context: SerializationBaseContext): Boolean = isInternallySerializableEnum() && !context.runtimeHasEnumSerializerFactoryFunctions
internal val IrClass.isSealedSerializableInterface: Boolean
get() = kind == ClassKind.INTERFACE && modality == Modality.SEALED && hasSerializableOrMetaAnnotation()
@@ -102,7 +102,7 @@ internal val IrClass.isSerialInfoAnnotation: Boolean
internal val IrClass.isInheritableSerialInfoAnnotation: Boolean
get() = annotations.hasAnnotation(SerializationAnnotations.inheritableSerialInfoFqName)
internal fun IrClass.shouldHaveGeneratedSerializer(context: SerializationPluginContext): Boolean
internal fun IrClass.shouldHaveGeneratedSerializer(context: SerializationBaseContext): Boolean
= (isInternalSerializable && (modality == Modality.FINAL || modality == Modality.OPEN))
|| isEnumWithLegacyGeneratedSerializer(context)
@@ -30,7 +30,7 @@ class IrSerializableProperty(
override val originalDescriptorName: Name = ir.name
val type = ir.getter!!.returnType as IrSimpleType
val genericIndex = type.genericIndex
fun serializableWith(ctx: SerializationPluginContext) = ir.annotations.serializableWith() ?: analyzeSpecialSerializers(ctx, ir.annotations)
fun serializableWith(ctx: SerializationBaseContext) = ir.annotations.serializableWith() ?: analyzeSpecialSerializers(ctx, ir.annotations)
override val optional = !ir.annotations.hasAnnotation(SerializationAnnotations.requiredAnnotationFqName) && declaresDefaultValue
override val transient = ir.annotations.hasAnnotation(SerializationAnnotations.serialTransientFqName) || !hasBackingField
}
@@ -33,30 +33,15 @@ class SerializableCompanionIrGenerator(
compilerContext: SerializationPluginContext,
) : BaseIrGenerator(irClass, compilerContext) {
private fun getSerializerGetterFunction(): IrSimpleFunction {
return irClass.findDeclaration<IrSimpleFunction> {
(it.valueParameters.size == serializableIrClass.typeParameters.size
&& it.valueParameters.all { p -> p.type.isKSerializer() }) && it.returnType.isKSerializer()
} ?: throw IllegalStateException(
"Can't find synthesized 'Companion.serializer()' function to generate, " +
"probably clash with user-defined function has occurred"
)
}
fun generate() {
val serializerGetterFunction = getSerializerGetterFunction()
if (serializableIrClass.isSerializableObject
|| serializableIrClass.isAbstractOrSealedSerializableClass
|| serializableIrClass.isSerializableEnum()
) {
generateLazySerializerGetter(serializerGetterFunction)
} else {
generateSerializerGetter(serializerGetterFunction)
}
}
companion object {
fun getSerializerGetterFunction(serializableIrClass: IrClass): IrSimpleFunction? {
val irClass = if (serializableIrClass.isSerializableObject) serializableIrClass else serializableIrClass.companionObject() ?: return null
return irClass.findDeclaration<IrSimpleFunction> {
(it.valueParameters.size == serializableIrClass.typeParameters.size
&& it.valueParameters.all { p -> p.type.isKSerializer() }) && it.returnType.isKSerializer()
}
}
fun generate(
irClass: IrClass,
context: SerializationPluginContext,
@@ -71,6 +56,22 @@ class SerializableCompanionIrGenerator(
}
}
fun generate() {
val serializerGetterFunction = getSerializerGetterFunction(serializableIrClass) ?: throw IllegalStateException(
"Can't find synthesized 'Companion.serializer()' function to generate, " +
"probably clash with user-defined function has occurred"
)
if (serializableIrClass.isSerializableObject
|| serializableIrClass.isAbstractOrSealedSerializableClass
|| serializableIrClass.isSerializableEnum()
) {
generateLazySerializerGetter(serializerGetterFunction)
} else {
generateSerializerGetter(serializerGetterFunction)
}
}
private fun IrBuilderWithScope.patchSerializableClassWithMarkerAnnotation(serializer: IrClass) {
if (serializer.kind != ClassKind.OBJECT) {
return
@@ -198,6 +199,5 @@ class SerializableCompanionIrGenerator(
patchSerializableClassWithMarkerAnnotation(irClass)
}
}
}
@@ -0,0 +1,391 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlinx.serialization.compiler.backend.ir
import org.jetbrains.kotlin.backend.common.extensions.FirIncompatiblePluginAPI
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
import org.jetbrains.kotlin.backend.jvm.codegen.MaterialValue
import org.jetbrains.kotlin.backend.jvm.codegen.PromisedValue
import org.jetbrains.kotlin.backend.jvm.intrinsics.IntrinsicMethod
import org.jetbrains.kotlin.backend.jvm.ir.representativeUpperBound
import org.jetbrains.kotlin.backend.jvm.mapping.mapClass
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.inline.newMethodNodeWithCorrectStackSize
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.*
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.annotationArrayType
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.doubleAnnotationArrayType
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.enumFactoriesType
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.kSerializerArrayType
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.kSerializerType
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.stringArrayType
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.stringType
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.ENUM_SERIALIZER_FACTORY_FUNC_NAME
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.MARKED_ENUM_SERIALIZER_FACTORY_FUNC_NAME
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializersClassIds.contextSerializerId
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializersClassIds.enumSerializerId
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializersClassIds.objectSerializerId
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializersClassIds.polymorphicSerializerId
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializersClassIds.referenceArraySerializerId
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializersClassIds.sealedSerializerId
import org.jetbrains.kotlinx.serialization.compiler.resolve.SpecialBuiltins
import org.jetbrains.kotlinx.serialization.compiler.resolve.getClassFromSerializationPackage
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
class SerializationJvmIrIntrinsicSupport(val jvmBackendContext: JvmBackendContext) : SerializationBaseContext {
companion object {
fun isSerializerReifiedFunction(targetFunction: IrFunction): Boolean =
targetFunction.fqNameWhenAvailable?.asString() == "kotlinx.serialization.SerializersKt.serializer"
&& targetFunction.valueParameters.isEmpty()
&& targetFunction.typeParameters.size == 1
&& targetFunction.dispatchReceiverParameter == null
&& targetFunction.extensionReceiverParameter == null
}
object ReifiedSerializerMethod : IntrinsicMethod() {
override fun invoke(
expression: IrFunctionAccessExpression,
codegen: ExpressionCodegen,
data: BlockInfo
): PromisedValue {
with(codegen) {
val argument = expression.getTypeArgument(0)!!
SerializationJvmIrIntrinsicSupport(codegen.context).generateSerializerForType(
argument,
mv
)
return MaterialValue(codegen, kSerializerType, expression.type)
}
}
}
private val emptyGenerator: BaseIrGenerator? = null
private val module = jvmBackendContext.state.module
private val typeSystemContext = jvmBackendContext.typeSystem
private val typeMapper = jvmBackendContext.defaultTypeMapper
/**
* This likely won't work in FIR because module is empty there and can't reference dependencies
* Proper referencing can be done via FirPluginContext, but it's not available in the intrinsics.
*/
@FirIncompatiblePluginAPI
override fun referenceClassId(classId: ClassId): IrClassSymbol? {
return module.findClassAcrossModuleDependencies(classId)?.let { jvmBackendContext.referenceClass(it) }
}
override val runtimeHasEnumSerializerFactoryFunctions: Boolean
get() = false // TODO
private fun findTypeSerializerOrContext(argType: IrType): IrClassSymbol? =
emptyGenerator.findTypeSerializerOrContextUnchecked(this, argType)
private fun instantiateObject(iv: InstructionAdapter, objectSymbol: IrClassSymbol) {
val originalIrClass = objectSymbol.owner
require(originalIrClass.isObject)
val targetField = jvmBackendContext.cachedDeclarations.getFieldForObjectInstance(originalIrClass)
val ownerType = typeMapper.mapClass(targetField.parentAsClass)
val fieldType = typeMapper.mapType(targetField.type)
iv.visitFieldInsn(Opcodes.GETSTATIC, ownerType.internalName, targetField.name.asString(), fieldType.descriptor)
}
fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: IrType,
): Int {
val newMethodNode = newMethodNodeWithCorrectStackSize {
generateSerializerForType(type, it)
}
instructions.remove(insn.next)
instructions.insert(insn, newMethodNode.instructions)
return newMethodNode.maxStack
}
private fun InstructionAdapter.putReifyMarkerIfNeeded(type: KotlinTypeMarker): Boolean =
with(typeSystemContext) {
val typeDescriptor = type.typeConstructor().getTypeParameterClassifier()
if (typeDescriptor != null) { // need further reification
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(
typeDescriptor,
false,
ReifiedTypeInliner.OperationKind.PLUGIN_DEFINED,
this@putReifyMarkerIfNeeded,
typeSystemContext
)
invokestatic("kotlinx/serialization/SerializersKt", "serializer", "()Lkotlinx/serialization/KSerializer;", false)
return true
}
return false
}
fun generateSerializerForType(
type: IrType,
adapter: InstructionAdapter
) {
with(typeSystemContext) {
if (adapter.putReifyMarkerIfNeeded(type)) return
val typeDescriptor: IrClass = type.classOrNull!!.owner
val support = this@SerializationJvmIrIntrinsicSupport
val serializerMethod = SerializableCompanionIrGenerator.getSerializerGetterFunction(typeDescriptor)
if (serializerMethod != null) {
// fast path
val companionType = if (typeDescriptor.isSerializableObject) typeDescriptor else typeDescriptor.companionObject()!!
support.instantiateObject(adapter, companionType.symbol)
val args = type.getArguments().map { it.getType() }
args.forEach { generateSerializerForType(it, adapter) }
val signature = kSerializerType.descriptor.repeat(args.size)
adapter.invokevirtual(
typeMapper.mapClass(companionType).internalName,
"serializer",
"(${signature})${kSerializerType.descriptor}",
false
)
} else {
// More general path, including special ol built-in serializers for e.g. List
val serializer = support.findTypeSerializerOrContext(type)
support.stackValueSerializerInstance(
type,
serializer,
adapter
) { genericArg ->
assert(putReifyMarkerIfNeeded(genericArg))
}
if (type.isMarkedNullable()) adapter.wrapStackValueIntoNullableSerializer()
}
}
}
private fun stackValueSerializerInstance(
kType: IrType, maybeSerializer: IrClassSymbol?,
iv: InstructionAdapter?,
genericIndex: Int? = null,
genericSerializerFieldGetter: (InstructionAdapter.(IrType) -> Unit)? = null,
): Boolean = with(typeSystemContext) {
if (maybeSerializer == null && genericIndex != null) {
// get field from serializer object
iv?.run { genericSerializerFieldGetter?.invoke(this, kType) }
return true
}
val serializer = maybeSerializer ?: run {
iv?.apply {
aconst(kType.classFqName!!.asString())
invokestatic(
"kotlinx/serialization/SerializersKt",
"noCompiledSerializer",
"(Ljava/lang/String;)Lkotlinx/serialization/KSerializer;",
false
)
}
return false
}
if (serializer.owner.isObject) {
// singleton serializer -- just get it
iv?.let { instantiateObject(it, serializer) }
return true
}
// serializer is not singleton object and shall be instantiated
val argSerializers = (kType as IrSimpleType).arguments.map { projection ->
// check if any type argument is not serializable
val argType = projection.typeOrNull!!
val argSerializer =
if (argType.isTypeParameter()) null else findTypeSerializerOrContext(argType)
// check if it can be properly serialized with its args recursively
Pair(argType, argSerializer)
}
// new serializer if needed
iv?.apply {
val serializerType = typeMapper.mapClass(serializer.owner)
if (serializer.owner.classId == enumSerializerId && runtimeHasEnumSerializerFactoryFunctions) {
val enumIrClass = kType.classOrNull!!.owner
// runtime contains enum serializer factory functions
val javaEnumArray = Type.getType("[Ljava/lang/Enum;")
val enumJavaType = typeMapper.mapType(kType, TypeMappingMode.GENERIC_ARGUMENT)
val serialName = enumIrClass.serialName()
if (enumIrClass.isEnumWithSerialInfoAnnotation()) {
aconst(serialName)
invokestatic(enumJavaType.internalName, "values", "()[${enumJavaType.descriptor}", false)
checkcast(javaEnumArray)
val entries = enumIrClass.enumEntries()
fillArray(stringType, entries) { _, entry ->
entry.annotations.serialNameValue.let {
if (it == null) {
aconst(null)
} else {
aconst(it)
}
}
}
checkcast(stringArrayType)
fillArray(annotationArrayType, entries) { _, _ ->
// FIXME: no org.jetbrains.kotlin.codegen.ExpressionCodegen available here to generate instances from descriptors
// val annotations = entry.descriptor.annotationsWithArguments()
aconst(null)
}
checkcast(doubleAnnotationArrayType)
invokestatic(
enumFactoriesType.internalName,
MARKED_ENUM_SERIALIZER_FACTORY_FUNC_NAME.asString(),
"(${stringType.descriptor}${javaEnumArray.descriptor}${stringArrayType.descriptor}${doubleAnnotationArrayType.descriptor})${kSerializerType.descriptor}",
false
)
} else {
aconst(serialName)
invokestatic(enumJavaType.internalName, "values", "()[${enumJavaType.descriptor}", false)
checkcast(javaEnumArray)
invokestatic(
enumFactoriesType.internalName,
ENUM_SERIALIZER_FACTORY_FUNC_NAME.asString(),
"(${stringType.descriptor}${javaEnumArray.descriptor})${kSerializerType.descriptor}",
false
)
}
return true
}
anew(serializerType)
dup()
// instantiate all arg serializers on stack
val signature = StringBuilder("(")
fun instantiate(typeArgument: Pair<IrType, IrClassSymbol?>, writeSignature: Boolean = true) {
val (argType, argSerializer) = typeArgument
stackValueSerializerInstance(
argType,
argSerializer,
this,
argType.genericIndex,
genericSerializerFieldGetter
)
// wrap into nullable serializer if argType is nullable
if (argType.isMarkedNullable()) wrapStackValueIntoNullableSerializer()
if (writeSignature) signature.append(kSerializerType.descriptor)
}
val serialName = kType.serialName()
when (serializer.owner.classId) {
enumSerializerId -> {
// support legacy serializer instantiation by constructor for old runtimes
aconst(serialName)
signature.append("Ljava/lang/String;")
val enumJavaType = typeMapper.mapTypeCommon(kType, TypeMappingMode.GENERIC_ARGUMENT)
val javaEnumArray = Type.getType("[Ljava/lang/Enum;")
invokestatic(enumJavaType.internalName, "values", "()[${enumJavaType.descriptor}", false)
checkcast(javaEnumArray)
signature.append(javaEnumArray.descriptor)
}
contextSerializerId, polymorphicSerializerId -> {
// a special way to instantiate enum -- need a enum KClass reference
// GENERIC_ARGUMENT forces boxing in order to obtain KClass
aconst(typeMapper.mapTypeCommon(kType, TypeMappingMode.GENERIC_ARGUMENT))
AsmUtil.wrapJavaClassIntoKClass(this)
signature.append(AsmTypes.K_CLASS_TYPE.descriptor)
if (serializer.owner.classId == contextSerializerId && serializer.constructors.any { it.owner.valueParameters.size == 3 }) { // TODO: this isn't working with LAZY IR CLASS
// append new additional arguments
val fallbackDefaultSerializer = findTypeSerializer(this@SerializationJvmIrIntrinsicSupport, kType)
if (fallbackDefaultSerializer != null && fallbackDefaultSerializer != serializer) {
instantiate(kType to fallbackDefaultSerializer, writeSignature = false)
} else {
aconst(null)
}
signature.append(kSerializerType.descriptor)
fillArray(kSerializerType, argSerializers) { _, serializer ->
instantiate(serializer, writeSignature = false)
}
signature.append(kSerializerArrayType.descriptor)
}
}
referenceArraySerializerId -> {
// a special way to instantiate reference array serializer -- need an element KClass reference
aconst(typeMapper.mapTypeCommon(kType.getArguments().first().getType(), TypeMappingMode.GENERIC_ARGUMENT))
AsmUtil.wrapJavaClassIntoKClass(this)
signature.append(AsmTypes.K_CLASS_TYPE.descriptor)
// Reference array serializer still needs serializer for its argument type
instantiate(argSerializers[0])
}
sealedSerializerId -> {
aconst(serialName)
signature.append("Ljava/lang/String;")
aconst(typeMapper.mapTypeCommon(kType, TypeMappingMode.GENERIC_ARGUMENT))
AsmUtil.wrapJavaClassIntoKClass(this)
signature.append(AsmTypes.K_CLASS_TYPE.descriptor)
val (subClasses, subSerializers) = emptyGenerator.allSealedSerializableSubclassesFor(
kType.classOrUpperBound()?.owner!!,
this@SerializationJvmIrIntrinsicSupport
)
// KClasses vararg
fillArray(AsmTypes.K_CLASS_TYPE, subClasses) { _, type ->
aconst(typeMapper.mapTypeCommon(type, TypeMappingMode.GENERIC_ARGUMENT))
AsmUtil.wrapJavaClassIntoKClass(this)
}
signature.append(AsmTypes.K_CLASS_ARRAY_TYPE.descriptor)
// Serializers vararg
fillArray(kSerializerType, subSerializers) { i, serializer ->
val (argType, argSerializer) = subClasses[i] to serializer
assert(
stackValueSerializerInstance(
argType,
argSerializer,
this,
argType.genericIndex
) { genericType ->
// if we encountered generic type parameter in one of subclasses of sealed class, use polymorphism from upper bound
assert(
stackValueSerializerInstance(
(genericType.classifierOrNull as IrTypeParameterSymbol).owner.representativeUpperBound,
jvmBackendContext.referenceClass(module.getClassFromSerializationPackage(SpecialBuiltins.polymorphicSerializer)),
this
)
)
}
)
if (argType.isMarkedNullable()) wrapStackValueIntoNullableSerializer()
}
signature.append(kSerializerArrayType.descriptor)
}
objectSerializerId -> {
aconst(serialName)
signature.append("Ljava/lang/String;")
instantiateObject(iv, kType.classOrNull!!)
signature.append("Ljava/lang/Object;")
}
// all serializers get arguments with serializers of their generic types
else -> argSerializers.forEach { instantiate(it) }
}
signature.append(")V")
// invoke constructor
invokespecial(serializerType.internalName, "<init>", signature.toString(), false)
}
return true
}
}
@@ -16,7 +16,10 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages
import org.jetbrains.kotlinx.serialization.compiler.resolve.SpecialBuiltins
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializersClassIds.contextSerializerId
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializersClassIds.enumSerializerId
@@ -30,7 +33,13 @@ class IrSerialTypeInfo(
val serializer: IrClassSymbol? = null
)
fun BaseIrGenerator.getIrSerialTypeInfo(property: IrSerializableProperty, ctx: SerializationPluginContext): IrSerialTypeInfo {
interface SerializationBaseContext {
fun referenceClassId(classId: ClassId): IrClassSymbol?
val runtimeHasEnumSerializerFactoryFunctions: Boolean
}
fun BaseIrGenerator.getIrSerialTypeInfo(property: IrSerializableProperty, ctx: SerializationBaseContext): IrSerialTypeInfo {
fun SerializableInfo(serializer: IrClassSymbol?) =
IrSerialTypeInfo(property, if (property.type.isNullable()) "Nullable" else "", serializer)
@@ -57,7 +66,7 @@ fun BaseIrGenerator.getIrSerialTypeInfo(property: IrSerializableProperty, ctx: S
}
}
fun BaseIrGenerator.findAddOnSerializer(propertyType: IrType, ctx: SerializationPluginContext): IrClassSymbol? {
fun BaseIrGenerator.findAddOnSerializer(propertyType: IrType, ctx: SerializationBaseContext): IrClassSymbol? {
val classSymbol = propertyType.classOrNull ?: return null
additionalSerializersInScopeOfCurrentFile[classSymbol to propertyType.isNullable()]?.let { return it }
if (classSymbol in contextualKClassListInCurrentFile)
@@ -68,61 +77,62 @@ fun BaseIrGenerator.findAddOnSerializer(propertyType: IrType, ctx: Serialization
return null
}
fun BaseIrGenerator.findTypeSerializerOrContext(
context: SerializationPluginContext, kType: IrType
fun BaseIrGenerator?.findTypeSerializerOrContext(
context: SerializationBaseContext, kType: IrType
): IrClassSymbol? {
if (kType.isTypeParameter()) return null
return findTypeSerializerOrContextUnchecked(context, kType) ?: error("Serializer for element of type ${kType.render()} has not been found")
}
fun BaseIrGenerator.findTypeSerializerOrContextUnchecked(
context: SerializationPluginContext, kType: IrType
fun BaseIrGenerator?.findTypeSerializerOrContextUnchecked(
context: SerializationBaseContext, kType: IrType
): IrClassSymbol? {
val annotations = kType.annotations
if (kType.isTypeParameter()) return null
annotations.serializableWith()?.let { return it }
additionalSerializersInScopeOfCurrentFile[kType.classOrNull!! to kType.isNullable()]?.let {
this?.additionalSerializersInScopeOfCurrentFile?.get(kType.classOrNull!! to kType.isNullable())?.let {
return it
}
if (kType.isMarkedNullable()) return findTypeSerializerOrContextUnchecked(context, kType.makeNotNull())
if (kType.classOrNull in contextualKClassListInCurrentFile) return context.referenceClass(contextSerializerId)
if (this?.contextualKClassListInCurrentFile?.contains(kType.classOrNull) == true) return context.referenceClassId(contextSerializerId)
return analyzeSpecialSerializers(context, annotations) ?: findTypeSerializer(context, kType)
}
fun analyzeSpecialSerializers(
context: SerializationPluginContext,
context: SerializationBaseContext,
annotations: List<IrConstructorCall>
): IrClassSymbol? = when {
annotations.hasAnnotation(SerializationAnnotations.contextualFqName) || annotations.hasAnnotation(SerializationAnnotations.contextualOnPropertyFqName) ->
context.referenceClass(contextSerializerId)
context.referenceClassId(contextSerializerId)
// can be annotation on type usage, e.g. List<@Polymorphic Any>
annotations.hasAnnotation(SerializationAnnotations.polymorphicFqName) ->
context.referenceClass(polymorphicSerializerId)
context.referenceClassId(polymorphicSerializerId)
else -> null
}
fun findTypeSerializer(context: SerializationPluginContext, type: IrType): IrClassSymbol? {
fun findTypeSerializer(context: SerializationBaseContext, type: IrType): IrClassSymbol? {
type.overridenSerializer?.let { return it }
if (type.isTypeParameter()) return null
if (type.isArray()) return context.referenceClass(referenceArraySerializerId)
if (type.isGeneratedSerializableObject()) return context.referenceClass(objectSerializerId)
if (type.isArray()) return context.referenceClassId(referenceArraySerializerId)
if (type.isGeneratedSerializableObject()) return context.referenceClassId(objectSerializerId)
val stdSer = findStandardKotlinTypeSerializer(context, type) // see if there is a standard serializer
?: findEnumTypeSerializer(context, type)
if (stdSer != null) return stdSer
if (type.isInterface() && type.classOrNull?.owner?.isSealedSerializableInterface == false) return context.referenceClass(
if (type.isInterface() && type.classOrNull?.owner?.isSealedSerializableInterface == false) return context.referenceClassId(
polymorphicSerializerId
)
return type.classOrNull?.owner.classSerializer(context) // check for serializer defined on the type
}
fun findEnumTypeSerializer(context: SerializationPluginContext, type: IrType): IrClassSymbol? {
fun findEnumTypeSerializer(context: SerializationBaseContext, type: IrType): IrClassSymbol? {
val classSymbol = type.classOrNull?.owner ?: return null
return if (classSymbol.kind == ClassKind.ENUM_CLASS && !classSymbol.isEnumWithLegacyGeneratedSerializer(context))
context.referenceClass(enumSerializerId)
context.referenceClassId(enumSerializerId)
else null
}
internal fun IrClass?.classSerializer(context: SerializationPluginContext): IrClassSymbol? = this?.let {
internal fun IrClass?.classSerializer(context: SerializationBaseContext): IrClassSymbol? = this?.let {
// serializer annotation on class?
serializableWith?.let { return it }
// companion object serializer?
@@ -139,7 +149,7 @@ internal fun IrClass?.classSerializer(context: SerializationPluginContext): IrCl
return null
}
internal fun IrClass.polymorphicSerializerIfApplicableAutomatically(context: SerializationPluginContext): IrClassSymbol? {
internal fun IrClass.polymorphicSerializerIfApplicableAutomatically(context: SerializationBaseContext): IrClassSymbol? {
val serializer = when {
kind == ClassKind.INTERFACE && modality == Modality.SEALED -> SpecialBuiltins.sealedSerializer
kind == ClassKind.INTERFACE -> SpecialBuiltins.polymorphicSerializer
@@ -170,7 +180,7 @@ internal val IrClass.serializerForClass: IrClassSymbol?
get() = (annotations.findAnnotation(SerializationAnnotations.serializerAnnotationFqName)
?.getValueArgument(0) as? IrClassReference)?.symbol as? IrClassSymbol
fun findStandardKotlinTypeSerializer(context: SerializationPluginContext, type: IrType): IrClassSymbol? {
fun findStandardKotlinTypeSerializer(context: SerializationBaseContext, type: IrType): IrClassSymbol? {
val typeName = type.classFqName?.toString()
val name = when (typeName) {
"Z" -> if (type.isBoolean()) "BooleanSerializer" else null
@@ -202,9 +212,9 @@ internal fun getSerializableClassByCompanion(companionClass: IrClass): IrClass?
return classDescriptor
}
fun BaseIrGenerator.allSealedSerializableSubclassesFor(
fun BaseIrGenerator?.allSealedSerializableSubclassesFor(
irClass: IrClass,
context: SerializationPluginContext
context: SerializationBaseContext
): Pair<List<IrSimpleType>, List<IrClassSymbol>> {
assert(irClass.modality == Modality.SEALED)
fun recursiveSealed(klass: IrClass): Collection<IrClass> {
@@ -217,7 +227,7 @@ fun BaseIrGenerator.allSealedSerializableSubclassesFor(
}.unzip()
}
internal fun SerializationPluginContext.getSerializableClassDescriptorBySerializer(serializer: IrClass): IrClass? {
internal fun SerializationBaseContext.getSerializableClassDescriptorBySerializer(serializer: IrClass): IrClass? {
val serializerForClass = serializer.serializerForClass
if (serializerForClass != null) return serializerForClass.owner
if (serializer.name !in setOf(
@@ -230,22 +240,22 @@ internal fun SerializationPluginContext.getSerializableClassDescriptorBySerializ
return classDescriptor
}
fun SerializationPluginContext.getClassFromRuntimeOrNull(className: String, vararg packages: FqName): IrClassSymbol? {
fun SerializationBaseContext.getClassFromRuntimeOrNull(className: String, vararg packages: FqName): IrClassSymbol? {
val listToSearch = if (packages.isEmpty()) SerializationPackages.allPublicPackages else packages.toList()
for (pkg in listToSearch) {
referenceClass(ClassId(pkg, Name.identifier(className)))?.let { return it }
referenceClassId(ClassId(pkg, Name.identifier(className)))?.let { return it }
}
return null
}
fun SerializationPluginContext.getClassFromRuntime(className: String, vararg packages: FqName): IrClassSymbol {
fun SerializationBaseContext.getClassFromRuntime(className: String, vararg packages: FqName): IrClassSymbol {
return getClassFromRuntimeOrNull(className, *packages) ?: error(
"Class $className wasn't found in ${packages.toList().ifEmpty { SerializationPackages.allPublicPackages }}. " +
"Check that you have correct version of serialization runtime in classpath."
)
}
fun SerializationPluginContext.getClassFromInternalSerializationPackage(className: String): IrClassSymbol =
fun SerializationBaseContext.getClassFromInternalSerializationPackage(className: String): IrClassSymbol =
getClassFromRuntimeOrNull(className, SerializationPackages.internalPackageFqName)
?: error("Class $className wasn't found in ${SerializationPackages.internalPackageFqName}. Check that you have correct version of serialization runtime in classpath.")
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.context.ClassContext
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapperBase
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -34,6 +35,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
import org.jetbrains.kotlinx.serialization.compiler.backend.common.*
@@ -95,11 +97,11 @@ internal val serializationExceptionName = "kotlinx/serialization/$SERIAL_EXC"
internal val serializationExceptionMissingFieldName = "kotlinx/serialization/$MISSING_FIELD_EXC"
internal val serializationExceptionUnknownIndexName = "kotlinx/serialization/$UNKNOWN_FIELD_EXC"
private val annotationType = Type.getObjectType("java/lang/annotation/Annotation")
private val annotationArrayType = Type.getObjectType("[${annotationType.descriptor}")
private val doubleAnnotationArrayType = Type.getObjectType("[${annotationArrayType.descriptor}")
private val stringType = AsmTypes.JAVA_STRING_TYPE
private val stringArrayType = Type.getObjectType("[${stringType.descriptor}")
internal val annotationType = Type.getObjectType("java/lang/annotation/Annotation")
internal val annotationArrayType = Type.getObjectType("[${annotationType.descriptor}")
internal val doubleAnnotationArrayType = Type.getObjectType("[${annotationArrayType.descriptor}")
internal val stringType = AsmTypes.JAVA_STRING_TYPE
internal val stringArrayType = Type.getObjectType("[${stringType.descriptor}")
internal val descriptorGetterName = JvmAbi.getterName(SERIAL_DESC_FIELD)
internal val getLazyValueName = JvmAbi.getterName("value")
@@ -256,7 +258,8 @@ internal fun AbstractSerialGenerator?.stackValueSerializerInstance(
genericSerializerFieldGetter: (InstructionAdapter.(Int, KotlinType) -> Unit)? = null
): Boolean {
return stackValueSerializerInstance(
expressionCodegen,codegen.typeMapper,
expressionCodegen,
codegen.typeMapper,
module,
kType,
maybeSerializer,
@@ -357,7 +360,7 @@ internal fun AbstractSerialGenerator?.stackValueSerializerInstance(
} else {
fillArray(annotationType, annotations) { _, annotation ->
val (annotationClass, args, consParams) = annotation
expressionCodegen?.generateSyntheticAnnotationOnStack(annotationClass, args, consParams)
expressionCodegen?.generateSyntheticAnnotationOnStack(annotationClass, args, consParams) ?: nop()
}
}
}
@@ -1,124 +0,0 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlinx.serialization.compiler.backend.jvm
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.inline.newMethodNodeWithCorrectStackSize
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.typeParametersCount
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlinx.serialization.compiler.backend.common.AbstractSerialGenerator
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
import org.jetbrains.kotlinx.serialization.compiler.backend.common.findTypeSerializerOrContextUnchecked
import org.jetbrains.kotlinx.serialization.compiler.resolve.isSerializableObject
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
object JvmSerializerIntrinsic {
fun applyFunction(resolvedCall: ResolvedCall<*>, c: ExpressionCodegenExtension.Context): StackValue? {
val targetFunction = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return null
val isSerializerReifiedFunction =
targetFunction.fqNameSafe.asString() == "kotlinx.serialization.serializer"
&& targetFunction.valueParameters.isEmpty()
&& targetFunction.typeParametersCount == 1
&& targetFunction.dispatchReceiverParameter == null
&& targetFunction.extensionReceiverParameter == null
if (!isSerializerReifiedFunction) return null
val typeArgument =
resolvedCall.typeArguments.entries.singleOrNull()?.value ?: error("serializer() function has exactly one type parameter")
return StackValue.functionCall(kSerializerType, targetFunction.returnType) { iv ->
generateSerializerForType(typeArgument, iv, c.typeMapper, c.codegen.typeSystem, module = c.codegen.state.module)
}
}
fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: KotlinType,
typeMapper: KotlinTypeMapper,
typeSystem: TypeSystemCommonBackendContext,
module: ModuleDescriptor
): Int {
val newMethodNode = newMethodNodeWithCorrectStackSize {
generateSerializerForType(type, it, typeMapper, typeSystem, module)
}
instructions.remove(insn.next)
instructions.insert(insn, newMethodNode.instructions)
return newMethodNode.maxStack
}
private fun InstructionAdapter.putReifyMarkerIfNeeded(type: KotlinType, typeSystem: TypeSystemCommonBackendContext): Boolean {
val typeDescriptor = (type as SimpleType).constructor.declarationDescriptor!!
if (typeDescriptor is TypeParameterDescriptor) { // need further reification
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(
typeDescriptor,
false,
ReifiedTypeInliner.OperationKind.PLUGIN_DEFINED,
this,
typeSystem
)
invokestatic("kotlinx/serialization/SerializersKt", "serializer", "()Lkotlinx/serialization/KSerializer;", false)
return true
}
return false
}
private fun generateSerializerForType(
type: KotlinType,
adapter: InstructionAdapter,
typeMapper: KotlinTypeMapper,
typeSystem: TypeSystemCommonBackendContext,
module: ModuleDescriptor
): Unit = with(adapter) {
if (putReifyMarkerIfNeeded(type, typeSystem)) return
val typeDescriptor = (type as SimpleType).constructor.declarationDescriptor!! as ClassDescriptor
val serializerMethod = SerializableCompanionCodegen.findSerializerGetterOnCompanion(typeDescriptor)
if (serializerMethod != null) {
// fast path
val companionType = if (typeDescriptor.isSerializableObject) typeDescriptor else typeDescriptor.companionObjectDescriptor!!
StackValue.singleton(companionType, typeMapper).put(this)
val args = type.arguments.map { it.type }
args.forEach { generateSerializerForType(it, this, typeMapper, typeSystem, module) }
val signature = kSerializerType.descriptor.repeat(args.size)
invokevirtual(
typeMapper.mapType(companionType).internalName,
"serializer",
"(${signature})${kSerializerType.descriptor}",
false
)
} else {
// More general path, including special ol built-in serializers for e.g. List
val emptyGenerator: AbstractSerialGenerator? = null // stub indicating we do not look into @UseSerializers to avoid confusion
val serializer = emptyGenerator.findTypeSerializerOrContextUnchecked(module, type)
emptyGenerator.stackValueSerializerInstance(
null,
typeMapper,
module,
type,
serializer,
this,
insertExceptionOnNoSerializer = true
) { _, genericArg ->
assert(putReifyMarkerIfNeeded(genericArg, typeSystem))
}
if (type.isMarkedNullable) wrapStackValueIntoNullableSerializer()
}
}
}
@@ -8,11 +8,11 @@ package org.jetbrains.kotlinx.serialization.compiler.extensions
import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapperBase
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.*
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.InsnList
@@ -26,22 +26,6 @@ open class SerializationCodegenExtension @JvmOverloads constructor(val metadataP
SerializableCompanionCodegenImpl.generateSerializableExtensions(codegen)
}
override fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: ExpressionCodegenExtension.Context): StackValue? {
return JvmSerializerIntrinsic.applyFunction(resolvedCall, c)
}
override fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: KotlinType,
asmType: Type,
typeMapper: KotlinTypeMapper,
typeSystem: TypeSystemCommonBackendContext,
module: ModuleDescriptor
): Int {
return JvmSerializerIntrinsic.applyPluginDefinedReifiedOperationMarker(insn, instructions, type, typeMapper, typeSystem, module)
}
override val shouldGenerateClassSyntheticPartsInLightClassesMode: Boolean
get() = false
}
@@ -5,25 +5,34 @@
package org.jetbrains.kotlinx.serialization.compiler.extensions
import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CompilationException
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.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.ir.fileParent
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.platform.jvm.isJvm
import org.jetbrains.kotlinx.serialization.compiler.backend.ir.*
import org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializationJvmIrIntrinsicSupport
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages
import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
import java.util.concurrent.ConcurrentHashMap
/**
@@ -44,7 +53,7 @@ fun ClassLoweringPass.runOnFileInOrder(irFile: IrFile) {
class SerializationPluginContext(baseContext: IrPluginContext, val metadataPlugin: SerializationDescriptorSerializerPlugin?) :
IrPluginContext by baseContext {
IrPluginContext by baseContext, SerializationBaseContext {
lateinit var serialInfoImplJvmIrGenerator: SerialInfoImplJvmIrGenerator
internal val copiedStaticWriteSelf: MutableMap<IrSimpleFunction, IrSimpleFunction> = ConcurrentHashMap()
@@ -63,7 +72,9 @@ class SerializationPluginContext(baseContext: IrPluginContext, val metadataPlugi
)
).singleOrNull()
val runtimeHasEnumSerializerFactoryFunctions = enumSerializerFactoryFunc != null && markedEnumSerializerFactoryFunc != null
override val runtimeHasEnumSerializerFactoryFunctions = enumSerializerFactoryFunc != null && markedEnumSerializerFactoryFunc != null
override fun referenceClassId(classId: ClassId): IrClassSymbol? = referenceClass(classId)
}
private inline fun IrClass.runPluginSafe(block: () -> Unit) {
@@ -126,4 +137,25 @@ open class SerializationLoweringExtension @JvmOverloads constructor(
moduleFragment.files.forEach(pass1::runOnFileInOrder)
moduleFragment.files.forEach(pass2::runOnFileInOrder)
}
override fun retrieveIntrinsic(symbol: IrFunctionSymbol): Any? {
if (!SerializationJvmIrIntrinsicSupport.isSerializerReifiedFunction(symbol.owner)) return null
return SerializationJvmIrIntrinsicSupport.ReifiedSerializerMethod
}
override fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: IrType,
jvmBackendContext: BackendContext,
): Int {
val ctx = jvmBackendContext as? JvmBackendContext ?: return -1
return SerializationJvmIrIntrinsicSupport(ctx).applyPluginDefinedReifiedOperationMarker(
insn,
instructions,
type,
)
}
}
@@ -0,0 +1,62 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM_IR
// WITH_STDLIB
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.internal.*
import kotlinx.serialization.descriptors.*
@Serializable
class Simple(val firstName: String, val lastName: String)
@Serializable
data class Box<out T>(val boxed: T)
@Serializable
object SerializableObject {}
inline fun <reified T : Any> getSer(): KSerializer<T> {
return serializer<T>()
}
inline fun <reified T : Any> getBoxSer(): KSerializer<Box<T>> {
return serializer<Box<T>>()
}
inline fun <reified T : Any> listSer(): KSerializer<List<T>> {
return serializer<List<T>>()
}
fun SerialDescriptor.recursiveToString(): String {
return (0 until elementsCount).joinToString(", ", "$serialName(", ")") { i ->
getElementName(i) + ": " + getElementDescriptor(i).recursiveToString()
}
}
fun assertHasSerializers(kSerializer: KSerializer<*>, list: List<String>) {
var str = kSerializer.descriptor.recursiveToString()
for (name in list) {
if (name !in str) error("Not found $name in $str")
str = str.replaceBefore(name, "")
str = str.removePrefix(name)
}
}
fun box(): String {
assertHasSerializers(serializer<Simple>(), listOf("Simple"))
assertHasSerializers(getSer<Simple>(), listOf("Simple"))
assertHasSerializers(getSer<Box<Simple>>(), listOf("Box", "Simple"))
assertHasSerializers(getBoxSer<Simple>(), listOf("Box", "Simple"))
assertHasSerializers(listSer<Simple>(), listOf("ArrayList", "Simple"))
assertHasSerializers(serializer<Box<List<Simple>>>(), listOf("Box", "ArrayList", "Simple"))
assertHasSerializers(listSer<Box<List<Simple>>>(), listOf("ArrayList", "Box", "ArrayList", "Simple"))
assertHasSerializers(serializer<Int>(), listOf("Int"))
assertHasSerializers(serializer<SerializableObject>(), listOf("SerializableObject"))
assertHasSerializers(listSer<List<Box<Int>>>(), listOf("ArrayList", "ArrayList", "Box", "Int"))
return "OK"
}
@@ -74,313 +74,116 @@ public final class IntrinsicsKt : java/lang/Object {
public final static kotlinx.serialization.KSerializer listSer()
public final static void test() {
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
POP
LABEL (L0)
LINENUMBER (28)
ICONST_0
ISTORE (0)
LABEL (L1)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
LABEL (L2)
LINENUMBER (50)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (1)
LABEL (L3)
ICONST_0
ISTORE (2)
LABEL (L4)
LINENUMBER (51)
ALOAD (1)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L5)
LINENUMBER (50)
NOP
LABEL (L6)
LINENUMBER (29)
ICONST_0
ISTORE (0)
LABEL (L7)
LINENUMBER (52)
ICONST_0
ISTORE (1)
LABEL (L8)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
LABEL (L9)
LINENUMBER (53)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L10)
ICONST_0
ISTORE (3)
LABEL (L11)
LINENUMBER (54)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L12)
LINENUMBER (53)
LABEL (L1)
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
LABEL (L2)
LINENUMBER (44)
NOP
LABEL (L13)
LINENUMBER (52)
NOP
LABEL (L14)
LABEL (L3)
POP
LABEL (L4)
LINENUMBER (30)
ICONST_0
ISTORE (0)
LABEL (L15)
LINENUMBER (55)
ICONST_0
ISTORE (1)
LABEL (L16)
LDC (LBox;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L17)
LINENUMBER (56)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L18)
ICONST_0
ISTORE (3)
LABEL (L19)
LINENUMBER (57)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L20)
LINENUMBER (56)
LABEL (L5)
GETSTATIC (Box, Companion, LBox$Companion;)
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
LABEL (L6)
LINENUMBER (45)
NOP
LABEL (L21)
LINENUMBER (55)
NOP
LABEL (L22)
LABEL (L7)
POP
LABEL (L8)
LINENUMBER (31)
ICONST_0
ISTORE (0)
LABEL (L23)
LINENUMBER (58)
ICONST_0
ISTORE (1)
LABEL (L24)
LDC (LBox;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L25)
LINENUMBER (59)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L26)
ICONST_0
ISTORE (3)
LABEL (L27)
LINENUMBER (60)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L28)
LINENUMBER (59)
LABEL (L9)
GETSTATIC (Box, Companion, LBox$Companion;)
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
LABEL (L10)
LINENUMBER (46)
NOP
LABEL (L29)
LINENUMBER (58)
NOP
LABEL (L30)
LABEL (L11)
POP
LABEL (L12)
LINENUMBER (32)
ICONST_0
ISTORE (0)
LABEL (L31)
LINENUMBER (61)
ICONST_0
ISTORE (1)
LABEL (L32)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L33)
LINENUMBER (62)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L34)
ICONST_0
ISTORE (3)
LABEL (L35)
LINENUMBER (63)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L36)
LINENUMBER (62)
LABEL (L13)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
LABEL (L14)
LINENUMBER (47)
NOP
LABEL (L37)
LINENUMBER (61)
NOP
LABEL (L38)
LINENUMBER (34)
ICONST_0
ISTORE (0)
LABEL (L39)
LDC (LBox;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L40)
LINENUMBER (64)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (1)
LABEL (L41)
ICONST_0
ISTORE (2)
LABEL (L42)
LINENUMBER (65)
ALOAD (1)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L43)
LINENUMBER (64)
NOP
LABEL (L44)
LABEL (L15)
POP
GETSTATIC (Box, Companion, LBox$Companion;)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
GETSTATIC (Simple$$serializer, INSTANCE, LSimple$$serializer;)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
POP
LABEL (L16)
LINENUMBER (36)
ICONST_0
ISTORE (0)
LABEL (L45)
LINENUMBER (66)
ICONST_0
ISTORE (1)
LABEL (L46)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LBox;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L47)
LINENUMBER (67)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L48)
ICONST_0
ISTORE (3)
LABEL (L49)
LINENUMBER (68)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L50)
LINENUMBER (67)
LABEL (L17)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
GETSTATIC (Box, Companion, LBox$Companion;)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
GETSTATIC (Simple$$serializer, INSTANCE, LSimple$$serializer;)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
LABEL (L18)
LINENUMBER (48)
NOP
LABEL (L51)
LINENUMBER (66)
NOP
LABEL (L52)
LINENUMBER (38)
ICONST_0
ISTORE (0)
LABEL (L53)
GETSTATIC (java/lang/Integer, TYPE, Ljava/lang/Class;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
LABEL (L54)
LINENUMBER (69)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (1)
LABEL (L55)
ICONST_0
ISTORE (2)
LABEL (L56)
LINENUMBER (70)
ALOAD (1)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L57)
LINENUMBER (69)
NOP
LABEL (L58)
LINENUMBER (40)
ICONST_0
ISTORE (0)
LABEL (L59)
LDC (LSerializableObject;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
LABEL (L60)
LINENUMBER (71)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (1)
LABEL (L61)
ICONST_0
ISTORE (2)
LABEL (L62)
LINENUMBER (72)
ALOAD (1)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L63)
LINENUMBER (71)
NOP
LABEL (L64)
LABEL (L19)
POP
GETSTATIC (kotlinx/serialization/internal/IntSerializer, INSTANCE, Lkotlinx/serialization/internal/IntSerializer;)
POP
GETSTATIC (SerializableObject, INSTANCE, LSerializableObject;)
INVOKEVIRTUAL (SerializableObject, serializer, ()Lkotlinx/serialization/KSerializer;)
POP
LABEL (L20)
LINENUMBER (42)
ICONST_0
ISTORE (0)
LABEL (L65)
LINENUMBER (73)
ICONST_0
ISTORE (1)
LABEL (L66)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LBox;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
GETSTATIC (java/lang/Integer, TYPE, Ljava/lang/Class;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L67)
LINENUMBER (74)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L68)
ICONST_0
ISTORE (3)
LABEL (L69)
LINENUMBER (75)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L70)
LINENUMBER (74)
LABEL (L21)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
NEW (Box$$serializer)
DUP
GETSTATIC (kotlinx/serialization/internal/IntSerializer, INSTANCE, Lkotlinx/serialization/internal/IntSerializer;)
INVOKESPECIAL (Box$$serializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
LABEL (L22)
LINENUMBER (49)
NOP
LABEL (L71)
LINENUMBER (73)
NOP
LABEL (L72)
LABEL (L23)
POP
LABEL (L24)
LINENUMBER (43)
RETURN
}
@@ -462,4 +265,4 @@ public final class Simple : java/lang/Object {
public final java.lang.String getLastName()
public final static void write$Self(Simple self, kotlinx.serialization.encoding.CompositeEncoder output, kotlinx.serialization.descriptors.SerialDescriptor serialDesc)
}
}
+284 -87
View File
@@ -70,114 +70,311 @@ public final class IntrinsicsKt : java/lang/Object {
public final static void test() {
LABEL (L0)
LINENUMBER (28)
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
POP
ICONST_0
ISTORE (0)
LABEL (L1)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
LABEL (L2)
LINENUMBER (50)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (1)
LABEL (L3)
ICONST_0
ISTORE (2)
LABEL (L4)
LINENUMBER (51)
ALOAD (1)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L5)
LINENUMBER (50)
NOP
LABEL (L6)
LINENUMBER (29)
ICONST_0
ISTORE (0)
LABEL (L2)
LINENUMBER (44)
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
LABEL (L3)
POP
LABEL (L4)
LABEL (L7)
LINENUMBER (52)
ICONST_0
ISTORE (1)
LABEL (L8)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
LABEL (L9)
LINENUMBER (53)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L10)
ICONST_0
ISTORE (3)
LABEL (L11)
LINENUMBER (54)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L12)
LINENUMBER (53)
NOP
LABEL (L13)
LINENUMBER (52)
NOP
LABEL (L14)
LINENUMBER (30)
ICONST_0
ISTORE (0)
LABEL (L5)
LINENUMBER (45)
GETSTATIC (Box, Companion, LBox$Companion;)
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
LABEL (L6)
POP
LABEL (L7)
LABEL (L15)
LINENUMBER (55)
ICONST_0
ISTORE (1)
LABEL (L16)
LDC (LBox;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L17)
LINENUMBER (56)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L18)
ICONST_0
ISTORE (3)
LABEL (L19)
LINENUMBER (57)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L20)
LINENUMBER (56)
NOP
LABEL (L21)
LINENUMBER (55)
NOP
LABEL (L22)
LINENUMBER (31)
ICONST_0
ISTORE (0)
LABEL (L8)
LINENUMBER (46)
GETSTATIC (Box, Companion, LBox$Companion;)
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
LABEL (L9)
POP
LABEL (L10)
LABEL (L23)
LINENUMBER (58)
ICONST_0
ISTORE (1)
LABEL (L24)
LDC (LBox;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L25)
LINENUMBER (59)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L26)
ICONST_0
ISTORE (3)
LABEL (L27)
LINENUMBER (60)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L28)
LINENUMBER (59)
NOP
LABEL (L29)
LINENUMBER (58)
NOP
LABEL (L30)
LINENUMBER (32)
ICONST_0
ISTORE (0)
LABEL (L11)
LINENUMBER (47)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
LABEL (L12)
POP
LABEL (L13)
LABEL (L31)
LINENUMBER (61)
ICONST_0
ISTORE (1)
LABEL (L32)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L33)
LINENUMBER (62)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L34)
ICONST_0
ISTORE (3)
LABEL (L35)
LINENUMBER (63)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L36)
LINENUMBER (62)
NOP
LABEL (L37)
LINENUMBER (61)
NOP
LABEL (L38)
LINENUMBER (34)
GETSTATIC (Box, Companion, LBox$Companion;)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
GETSTATIC (Simple$$serializer, INSTANCE, LSimple$$serializer;)
CHECKCAST (kotlinx/serialization/KSerializer)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
POP
LABEL (L14)
ICONST_0
ISTORE (0)
LABEL (L39)
LDC (LBox;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L40)
LINENUMBER (64)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (1)
LABEL (L41)
ICONST_0
ISTORE (2)
LABEL (L42)
LINENUMBER (65)
ALOAD (1)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L43)
LINENUMBER (64)
NOP
LABEL (L44)
LINENUMBER (36)
ICONST_0
ISTORE (0)
LABEL (L15)
LINENUMBER (48)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
GETSTATIC (Box, Companion, LBox$Companion;)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
GETSTATIC (Simple$$serializer, INSTANCE, LSimple$$serializer;)
CHECKCAST (kotlinx/serialization/KSerializer)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
LABEL (L16)
POP
LABEL (L17)
LABEL (L45)
LINENUMBER (66)
ICONST_0
ISTORE (1)
LABEL (L46)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LBox;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LSimple;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L47)
LINENUMBER (67)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L48)
ICONST_0
ISTORE (3)
LABEL (L49)
LINENUMBER (68)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L50)
LINENUMBER (67)
NOP
LABEL (L51)
LINENUMBER (66)
NOP
LABEL (L52)
LINENUMBER (38)
GETSTATIC (kotlinx/serialization/internal/IntSerializer, INSTANCE, Lkotlinx/serialization/internal/IntSerializer;)
CHECKCAST (kotlinx/serialization/KSerializer)
POP
LABEL (L18)
ICONST_0
ISTORE (0)
LABEL (L53)
GETSTATIC (java/lang/Integer, TYPE, Ljava/lang/Class;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
LABEL (L54)
LINENUMBER (69)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (1)
LABEL (L55)
ICONST_0
ISTORE (2)
LABEL (L56)
LINENUMBER (70)
ALOAD (1)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L57)
LINENUMBER (69)
NOP
LABEL (L58)
LINENUMBER (40)
GETSTATIC (SerializableObject, INSTANCE, LSerializableObject;)
INVOKEVIRTUAL (SerializableObject, serializer, ()Lkotlinx/serialization/KSerializer;)
POP
LABEL (L19)
ICONST_0
ISTORE (0)
LABEL (L59)
LDC (LSerializableObject;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
LABEL (L60)
LINENUMBER (71)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (1)
LABEL (L61)
ICONST_0
ISTORE (2)
LABEL (L62)
LINENUMBER (72)
ALOAD (1)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L63)
LINENUMBER (71)
NOP
LABEL (L64)
LINENUMBER (42)
ICONST_0
ISTORE (0)
LABEL (L20)
LINENUMBER (49)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
NEW (Box$$serializer)
DUP
GETSTATIC (kotlinx/serialization/internal/IntSerializer, INSTANCE, Lkotlinx/serialization/internal/IntSerializer;)
CHECKCAST (kotlinx/serialization/KSerializer)
INVOKESPECIAL (Box$$serializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
LABEL (L21)
POP
LABEL (L22)
LABEL (L65)
LINENUMBER (73)
ICONST_0
ISTORE (1)
LABEL (L66)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (Ljava/util/List;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
LDC (LBox;)
GETSTATIC (kotlin/reflect/KTypeProjection, Companion, Lkotlin/reflect/KTypeProjection$Companion;)
GETSTATIC (java/lang/Integer, TYPE, Ljava/lang/Class;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
INVOKEVIRTUAL (kotlin/reflect/KTypeProjection$Companion, invariant, (Lkotlin/reflect/KType;)Lkotlin/reflect/KTypeProjection;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, typeOf, (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;)
LABEL (L67)
LINENUMBER (74)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ASTORE (2)
LABEL (L68)
ICONST_0
ISTORE (3)
LABEL (L69)
LINENUMBER (75)
ALOAD (2)
LDC (null cannot be cast to non-null type kotlinx.serialization.KSerializer<T of kotlinx.serialization.internal.Platform_commonKt.cast>)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNull, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L70)
LINENUMBER (74)
NOP
LABEL (L71)
LINENUMBER (73)
NOP
LABEL (L72)
LINENUMBER (43)
RETURN
}
@@ -257,4 +454,4 @@ public final class Simple : java/lang/Object {
public final java.lang.String getLastName()
public final static void write$Self(Simple self, kotlinx.serialization.encoding.CompositeEncoder output, kotlinx.serialization.descriptors.SerialDescriptor serialDesc)
}
}
@@ -55,6 +55,12 @@ public class SerializationIrBoxTestGenerated extends AbstractSerializationIrBoxT
runTest("plugins/kotlinx-serialization/testData/boxIr/inlineClasses.kt");
}
@Test
@TestMetadata("intrinsicsBox.kt")
public void testIntrinsicsBox() throws Exception {
runTest("plugins/kotlinx-serialization/testData/boxIr/intrinsicsBox.kt");
}
@Test
@TestMetadata("metaSerializable.kt")
public void testMetaSerializable() throws Exception {