Remove OperationType.PLUGIN_DEFINED type:

instead, plugins should emit the code similar to the TYPE_OF one with
a special call to MagicApiIntrinsics.voidMagicApiCall directly afterwards.

This is required because old compiler need to correctly inline code
rewritten by plugin.
This commit is contained in:
Leonid Startsev
2022-08-31 19:36:06 +02:00
committed by Space
parent 763303fe97
commit ad2adadb36
9 changed files with 123 additions and 146 deletions
@@ -42,22 +42,6 @@ interface ExpressionCodegenExtension {
*/ */
fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null
/**
* Called when inliner encounters [ReifiedTypeInliner.OperationKind.PLUGIN_DEFINED] marker
* to perform extension-specific operation with reified type parameter.
*
* @return Required stack size for method after inlining is performed, 0 if the size is unknown, or -1 if extension ignores this marker
*/
fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: KotlinType,
asmType: Type,
typeMapper: KotlinTypeMapper,
typeSystem: TypeSystemCommonBackendContext,
module: ModuleDescriptor
): Int = -1
fun generateClassSyntheticParts(codegen: ImplementationBodyCodegen) {} fun generateClassSyntheticParts(codegen: ImplementationBodyCodegen) {}
val shouldGenerateClassSyntheticPartsInLightClassesMode: Boolean val shouldGenerateClassSyntheticPartsInLightClassesMode: Boolean
@@ -86,21 +86,4 @@ class PsiInlineIntrinsicsSupport(
override fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name) { override fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name) {
state.diagnostics.report(TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND.on(reportErrorsOn, typeParameterName.asString())) state.diagnostics.report(TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND.on(reportErrorsOn, typeParameterName.asString()))
} }
override fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: KotlinType,
asmType: Type
): Int = pluginExtensions.maxOfOrNull {
it.applyPluginDefinedReifiedOperationMarker(
insn,
instructions,
type,
asmType,
state.typeMapper,
typeSystem,
state.module
)
} ?: -1
} }
@@ -46,7 +46,7 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
private val unifiedNullChecks: Boolean, private val unifiedNullChecks: Boolean,
) { ) {
enum class OperationKind { enum class OperationKind {
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS, ENUM_REIFIED, TYPE_OF, PLUGIN_DEFINED; NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS, ENUM_REIFIED, TYPE_OF;
val id: Int get() = ordinal val id: Int get() = ordinal
} }
@@ -66,21 +66,18 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
fun reportSuspendTypeUnsupported() fun reportSuspendTypeUnsupported()
fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name) fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name)
/** fun rewritePluginDefinedOperationMarker(v: InstructionAdapter, next: AbstractInsnNode, instructions: InsnList, type: KT): Boolean =
* @return Required stack size for method after inlining is performed, 0 if the size is unknown, or -1 if plugin was not applied false
*/
fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: KT,
asmType: Type
): Int = -1
} }
companion object { companion object {
const val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker" const val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
const val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification" const val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
const val pluginIntrinsicsMarkerOwner = "kotlin/jvm/internal/MagicApiIntrinsics"
const val pluginIntrinsicsMarkerMethod = "voidMagicApiCall"
const val pluginIntrinsicsMarkerSignature = "(Ljava/lang/Object;)V"
fun isOperationReifiedMarker(insn: AbstractInsnNode) = fun isOperationReifiedMarker(insn: AbstractInsnNode) =
isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME } isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME }
@@ -180,8 +177,7 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType) OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType) OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, instructions, asmType) OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, instructions, asmType)
OperationKind.TYPE_OF -> processTypeOf(insn, instructions, type) OperationKind.TYPE_OF -> processTypeOfOrPlugin(insn, instructions, type)
OperationKind.PLUGIN_DEFINED -> processPluginDefined(insn, instructions, type, asmType)
} }
) { ) {
instructions.remove(insn.previous.previous!!) // PUSH operation ID instructions.remove(insn.previous.previous!!) // PUSH operation ID
@@ -197,23 +193,6 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
} }
} }
private fun processPluginDefined(
insn: MethodInsnNode,
instructions: InsnList,
type: KT,
asmType: Type
): Boolean {
val applyResult = intrinsicsSupport.applyPluginDefinedReifiedOperationMarker(
insn,
instructions,
type,
asmType
)
if (applyResult == -1) return false
maxStackSize = max(maxStackSize, applyResult)
return true
}
private fun reify(argument: ReificationArgument, replacementAsmType: Type, type: KT): Pair<Type, KT> = private fun reify(argument: ReificationArgument, replacementAsmType: Type, type: KT): Pair<Type, KT> =
with(typeSystem) { with(typeSystem) {
val arrayType = type.arrayOf(argument.arrayDepth) val arrayType = type.arrayOf(argument.arrayDepth)
@@ -282,13 +261,21 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
return true return true
} }
private fun processTypeOf( private fun processTypeOfOrPlugin(
insn: MethodInsnNode, insn: MethodInsnNode,
instructions: InsnList, instructions: InsnList,
type: KT type: KT
) = rewriteNextTypeInsn(insn, Opcodes.ACONST_NULL) { stubConstNull: AbstractInsnNode -> ) = rewriteNextTypeInsn(insn, Opcodes.ACONST_NULL) { stubConstNull: AbstractInsnNode ->
val newMethodNode = newMethodNodeWithCorrectStackSize { val newMethodNode = newMethodNodeWithCorrectStackSize {
typeSystem.generateTypeOf(it, type, intrinsicsSupport) if (!isPluginNext(stubConstNull) || !intrinsicsSupport.rewritePluginDefinedOperationMarker(
it,
stubConstNull,
instructions,
type,
)
) {
typeSystem.generateTypeOf(it, type, intrinsicsSupport)
}
} }
instructions.insert(insn, newMethodNode.instructions) instructions.insert(insn, newMethodNode.instructions)
@@ -298,6 +285,15 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
return true return true
} }
private fun isPluginNext(insn: AbstractInsnNode): Boolean {
val magicInsn = insn.next?.next ?: return false
return magicInsn is MethodInsnNode && magicInsn.opcode == Opcodes.INVOKESTATIC
&& magicInsn.owner == pluginIntrinsicsMarkerOwner
&& magicInsn.name == pluginIntrinsicsMarkerMethod
&& magicInsn.desc == pluginIntrinsicsMarkerSignature
&& insn.next is LdcInsnNode
}
private inline fun rewriteNextTypeInsn( private inline fun rewriteNextTypeInsn(
marker: MethodInsnNode, marker: MethodInsnNode,
expectedNextOpcode: Int, expectedNextOpcode: Int,
@@ -10,7 +10,6 @@ dependencies {
api(project(":compiler:ir.tree")) api(project(":compiler:ir.tree"))
api(project(":compiler:ir.interpreter")) api(project(":compiler:ir.interpreter"))
compileOnly(intellijCore()) compileOnly(intellijCore())
compileOnly(commonDependency("org.jetbrains.intellij.deps:asm-all"))
} }
sourceSets { sourceSets {
@@ -32,8 +32,8 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.Type.INT_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.Type.VOID_TYPE
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnList import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
class IrInlineIntrinsicsSupport( class IrInlineIntrinsicsSupport(
private val classCodegen: ClassCodegen, private val classCodegen: ClassCodegen,
@@ -127,17 +127,7 @@ class IrInlineIntrinsicsSupport(
.report(JvmBackendErrors.TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND, typeParameterName.asString()) .report(JvmBackendErrors.TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND, typeParameterName.asString())
} }
override fun applyPluginDefinedReifiedOperationMarker( override fun rewritePluginDefinedOperationMarker(v: InstructionAdapter, next: AbstractInsnNode, instructions: InsnList, type: IrType): Boolean {
insn: MethodInsnNode, return pluginExtensions.any { it.rewritePluginDefinedOperationMarker(v, next, instructions, type, classCodegen.context) }
instructions: InsnList, }
type: IrType,
asmType: Type
): Int = pluginExtensions.maxOfOrNull {
it.applyPluginDefinedReifiedOperationMarker(
insn,
instructions,
type,
classCodegen.context
)
} ?: -1
} }
@@ -10,16 +10,22 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.intrinsics.IntrinsicMethod import org.jetbrains.kotlin.backend.jvm.intrinsics.IntrinsicMethod
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnList import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
interface JvmIrIntrinsicExtension : IrIntrinsicExtension { interface JvmIrIntrinsicExtension : IrIntrinsicExtension {
fun getIntrinsic(symbol: IrFunctionSymbol): IntrinsicMethod? fun getIntrinsic(symbol: IrFunctionSymbol): IntrinsicMethod?
fun applyPluginDefinedReifiedOperationMarker( /**
insn: MethodInsnNode, * Should return `true` if marker was processed.
* If this method returns `false`, a regular `TYPE_OF` intrinsic would be inserted.
*/
fun rewritePluginDefinedOperationMarker(
v: InstructionAdapter,
next: AbstractInsnNode,
instructions: InsnList, instructions: InsnList,
type: IrType, type: IrType,
jvmBackendContext: JvmBackendContext, jvmBackendContext: JvmBackendContext
): Int = -1 ): Boolean
} }
@@ -13,7 +13,9 @@ import org.jetbrains.kotlin.backend.jvm.ir.representativeUpperBound
import org.jetbrains.kotlin.backend.jvm.mapping.mapClass import org.jetbrains.kotlin.backend.jvm.mapping.mapClass
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.inline.newMethodNodeWithCorrectStackSize import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.pluginIntrinsicsMarkerMethod
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.pluginIntrinsicsMarkerOwner
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.pluginIntrinsicsMarkerSignature
import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
@@ -51,7 +53,7 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnList import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode import org.jetbrains.org.objectweb.asm.tree.LdcInsnNode
import org.jetbrains.org.objectweb.asm.tree.VarInsnNode import org.jetbrains.org.objectweb.asm.tree.VarInsnNode
class SerializationJvmIrIntrinsicSupport(val jvmBackendContext: JvmBackendContext) : SerializationBaseContext { class SerializationJvmIrIntrinsicSupport(val jvmBackendContext: JvmBackendContext) : SerializationBaseContext {
@@ -60,6 +62,11 @@ class SerializationJvmIrIntrinsicSupport(val jvmBackendContext: JvmBackendContex
class WithModule(val storedIndex: Int) : class WithModule(val storedIndex: Int) :
IntrinsicType(stubCallDescriptorWithModule) IntrinsicType(stubCallDescriptorWithModule)
fun magicMarkerString(): String = magicMarkerStringPrefix + when(this) {
is Simple -> "simple"
is WithModule -> "withModule"
}
} }
companion object { companion object {
@@ -78,13 +85,16 @@ class SerializationJvmIrIntrinsicSupport(val jvmBackendContext: JvmBackendContex
} }
val serializersModuleType: Type = Type.getObjectType("kotlinx/serialization/modules/SerializersModule") val serializersModuleType: Type = Type.getObjectType("kotlinx/serialization/modules/SerializersModule")
val kTypeType: Type = AsmTypes.K_TYPE
val stubCallDescriptorWithModule = "(${serializersModuleType.descriptor})${kSerializerType.descriptor}" val stubCallDescriptorWithModule = "(${serializersModuleType.descriptor}${kTypeType.descriptor})${kSerializerType.descriptor}"
val stubCallDescriptor = "()${kSerializerType.descriptor}" val stubCallDescriptor = "(${kTypeType.descriptor})${kSerializerType.descriptor}"
const val serializersKtInternalName = "kotlinx/serialization/SerializersKt" const val serializersKtInternalName = "kotlinx/serialization/SerializersKt"
const val callMethodName = "serializer" const val callMethodName = "serializer"
const val noCompiledSerializerMethodName = "noCompiledSerializer" const val noCompiledSerializerMethodName = "noCompiledSerializer"
const val magicMarkerStringPrefix = "kotlinx.serialization.serializer."
} }
class ReifiedSerializerMethod(private val withModule: Boolean) : IntrinsicMethod() { class ReifiedSerializerMethod(private val withModule: Boolean) : IntrinsicMethod() {
@@ -154,54 +164,53 @@ class SerializationJvmIrIntrinsicSupport(val jvmBackendContext: JvmBackendContex
iv.visitFieldInsn(Opcodes.GETSTATIC, ownerType.internalName, targetField.name.asString(), fieldType.descriptor) iv.visitFieldInsn(Opcodes.GETSTATIC, ownerType.internalName, targetField.name.asString(), fieldType.descriptor)
} }
fun applyPluginDefinedReifiedOperationMarker( /**
insn: MethodInsnNode, * Instructions at the moment of call:
*
* -3: iconst(6) // TYPE_OF
* -2: aconst(typeParamName) // TYPE_OF
* -1: invokestatic(reifiedOperationMarker)
* < instructions from instructionAdapter will be inserted here by inliner >
* 0 (stubConstNull): aconst(null)
* 1: aconst(kotlinx.serialization.serializer.<operationType>)
* 2: invokestatic(voidMagicApiCall)
* 3: aload(moduleVar) // if withModule
* 4: swap // if withModule
* 5: invokestatic(kotlinx.serialization.serializer(module?, kType)
*
* We need to remove instructions from 1 to 5
* Instructions 0, -1 -2 and -3 would be removed by inliner.
*/
fun rewritePluginDefinedReifiedOperationMarker(
v: InstructionAdapter,
stubConstNull: AbstractInsnNode,
instructions: InsnList, instructions: InsnList,
type: IrType, type: IrType
): Int { ): Boolean {
val intrinsicType = getOperationTypeFromInsn(insn) ?: return -1 val operationTypeStr = (stubConstNull.next as LdcInsnNode).cst as String
val newMethodNode = newMethodNodeWithCorrectStackSize { if (!operationTypeStr.startsWith(magicMarkerStringPrefix)) return false
generateSerializerForType(type, it, intrinsicType) val operationType = if (operationTypeStr.endsWith("withModule")) {
} val aload = stubConstNull.next.next.next as VarInsnNode
val storedVar = aload.`var`
when (intrinsicType) { instructions.remove(aload.next)
is IntrinsicType.Simple -> instructions.remove(insn.next) instructions.remove(aload)
is IntrinsicType.WithModule -> { IntrinsicType.WithModule(storedVar)
instructions.remove(insn.next.next) } else IntrinsicType.Simple
instructions.remove(insn.next) // Remove other instructions
} instructions.remove(stubConstNull.next.next.next)
} instructions.remove(stubConstNull.next.next)
instructions.insert(insn, newMethodNode.instructions) instructions.remove(stubConstNull.next)
// generate serializer
return newMethodNode.maxStack generateSerializerForType(type, v, operationType)
} return true
private fun getOperationTypeFromInsn(insn: MethodInsnNode): IntrinsicType? {
// insn is reification marker
// insn.next is serializer() OR load(module)
// insn.next.next is serializer(module) if insn.next was load(module)
val mayBeSerializerModuleCall: AbstractInsnNode? = insn.next?.next
val next = insn.next ?: error("Reification marker cannot be the last instruction in method")
if (
mayBeSerializerModuleCall is MethodInsnNode
&& mayBeSerializerModuleCall.opcode == Opcodes.INVOKESTATIC
&& mayBeSerializerModuleCall.owner == serializersKtInternalName
&& mayBeSerializerModuleCall.name == callMethodName
&& mayBeSerializerModuleCall.desc == stubCallDescriptorWithModule
) {
val loadIns = next as? VarInsnNode ?: error("Expected load(SerializersModule) instruction")
// It's possible to also check opcode, but that doesn't seem necessary
return IntrinsicType.WithModule(loadIns.`var`)
} else if (next is MethodInsnNode
&& next.opcode == Opcodes.INVOKESTATIC
&& next.owner == serializersKtInternalName
&& next.name == callMethodName
&& next.desc == stubCallDescriptor
) {
return IntrinsicType.Simple
} else return null // May be reification marker from other plugin
} }
/**
* This function produces identical to TYPE_OF reification marker. This is needed for compatibility reasons:
* old compiler should be able to inline and run newer versions of kotlinx-serialization or other libraries.
*
* Operation detection in new compilers performed by voidMagicApiCall.
*/
private fun InstructionAdapter.putReifyMarkerIfNeeded(type: KotlinTypeMarker, intrinsicType: IntrinsicType): Boolean = private fun InstructionAdapter.putReifyMarkerIfNeeded(type: KotlinTypeMarker, intrinsicType: IntrinsicType): Boolean =
with(typeSystemContext) { with(typeSystemContext) {
val typeDescriptor = type.typeConstructor().getTypeParameterClassifier() val typeDescriptor = type.typeConstructor().getTypeParameterClassifier()
@@ -209,12 +218,17 @@ class SerializationJvmIrIntrinsicSupport(val jvmBackendContext: JvmBackendContex
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded( ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(
typeDescriptor, typeDescriptor,
false, false,
ReifiedTypeInliner.OperationKind.PLUGIN_DEFINED, ReifiedTypeInliner.OperationKind.TYPE_OF,
this@putReifyMarkerIfNeeded, this@putReifyMarkerIfNeeded,
typeSystemContext typeSystemContext
) )
aconst(null)
aconst(intrinsicType.magicMarkerString())
invokestatic(pluginIntrinsicsMarkerOwner, pluginIntrinsicsMarkerMethod, pluginIntrinsicsMarkerSignature, false)
if (intrinsicType is IntrinsicType.WithModule) { if (intrinsicType is IntrinsicType.WithModule) {
// Force emit load instruction so we can retrieve var index later
load(intrinsicType.storedIndex, serializersModuleType) load(intrinsicType.storedIndex, serializersModuleType)
swap()
} }
invokestatic(serializersKtInternalName, callMethodName, intrinsicType.methodDescriptor, false) invokestatic(serializersKtInternalName, callMethodName, intrinsicType.methodDescriptor, false)
return true return true
@@ -317,7 +331,7 @@ class SerializationJvmIrIntrinsicSupport(val jvmBackendContext: JvmBackendContex
signature?.append(kSerializerType.descriptor) signature?.append(kSerializerType.descriptor)
} }
val serializer = maybeSerializer ?: iv.run { val serializer = maybeSerializer ?: iv.run {// insert noCompilerSerializer(module, kClass, arguments)
require(intrinsicType is IntrinsicType.WithModule) // SIMPLE is covered in previous if require(intrinsicType is IntrinsicType.WithModule) // SIMPLE is covered in previous if
// SerializersModule // SerializersModule
load(intrinsicType.storedIndex, serializersModuleType) load(intrinsicType.storedIndex, serializersModuleType)
@@ -5,7 +5,6 @@
package org.jetbrains.kotlinx.serialization.compiler.extensions 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.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CompilationException import org.jetbrains.kotlin.backend.common.CompilationException
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
@@ -34,8 +33,9 @@ import org.jetbrains.kotlinx.serialization.compiler.backend.ir.SerializationJvmI
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnList import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
/** /**
@@ -146,16 +146,17 @@ open class SerializationLoweringExtension @JvmOverloads constructor(
override fun getIntrinsic(symbol: IrFunctionSymbol): IntrinsicMethod? = override fun getIntrinsic(symbol: IrFunctionSymbol): IntrinsicMethod? =
SerializationJvmIrIntrinsicSupport.intrinsicForMethod(symbol.owner) SerializationJvmIrIntrinsicSupport.intrinsicForMethod(symbol.owner)
override fun applyPluginDefinedReifiedOperationMarker( override fun rewritePluginDefinedOperationMarker(
insn: MethodInsnNode, v: InstructionAdapter,
next: AbstractInsnNode,
instructions: InsnList, instructions: InsnList,
type: IrType, type: IrType,
jvmBackendContext: JvmBackendContext jvmBackendContext: JvmBackendContext
): Int = SerializationJvmIrIntrinsicSupport(jvmBackendContext).applyPluginDefinedReifiedOperationMarker( ): Boolean {
insn, return SerializationJvmIrIntrinsicSupport(jvmBackendContext).rewritePluginDefinedReifiedOperationMarker(
instructions, v, next, instructions, type
type, )
) }
} }
} }
} }
@@ -16,11 +16,15 @@ public final class IntrinsicsAdvancedKt : java/lang/Object {
LINENUMBER (18) LINENUMBER (18)
ALOAD (0) ALOAD (0)
ASTORE (2) ASTORE (2)
BIPUSH (7) BIPUSH (6)
LDC (T) LDC (T)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, reifiedOperationMarker, (ILjava/lang/String;)V) INVOKESTATIC (kotlin/jvm/internal/Intrinsics, reifiedOperationMarker, (ILjava/lang/String;)V)
ACONST_NULL
LDC (kotlinx.serialization.serializer.withModule)
INVOKESTATIC (kotlin/jvm/internal/MagicApiIntrinsics, voidMagicApiCall, (Ljava/lang/Object;)V)
ALOAD (2) ALOAD (2)
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlinx/serialization/modules/SerializersModule;)Lkotlinx/serialization/KSerializer;) SWAP
INVOKESTATIC (kotlinx/serialization/SerializersKt, serializer, (Lkotlinx/serialization/modules/SerializersModule;Lkotlin/reflect/KType;)Lkotlinx/serialization/KSerializer;)
ARETURN ARETURN
LABEL (L2) LABEL (L2)
} }