diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt index 927fcec9d45..11494e5ac09 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt @@ -34,6 +34,8 @@ class PsiInlineIntrinsicsSupport( private val reportErrorsOn: KtElement, private val typeSystem: TypeSystemCommonBackendContext ) : ReifiedTypeInliner.IntrinsicsSupport { + private val pluginExtensions = ExpressionCodegenExtension.getInstances(state.project) + override fun putClassInstance(v: InstructionAdapter, type: KotlinType) { DescriptorAsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper) } @@ -90,9 +92,15 @@ class PsiInlineIntrinsicsSupport( instructions: InsnList, type: KotlinType, asmType: Type - ): Int { - return ExpressionCodegenExtension.getInstances(state.project) - .map { it.applyPluginDefinedReifiedOperationMarker(insn, instructions, type, asmType, state.typeMapper, typeSystem, state.module) } - .maxOrNull() ?: -1 - } + ): Int = pluginExtensions.maxOfOrNull { + it.applyPluginDefinedReifiedOperationMarker( + insn, + instructions, + type, + asmType, + state.typeMapper, + typeSystem, + state.module + ) + } ?: -1 } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrGenerationExtension.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrGenerationExtension.kt index 73b5605fddb..07914bd1c24 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrGenerationExtension.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrGenerationExtension.kt @@ -5,15 +5,9 @@ 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 : @@ -23,14 +17,11 @@ 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 + fun getPlatformIntrinsicExtension(): IrIntrinsicExtension? = null } + +/** + * This interface for common IR is empty because intrinsics are done in a platform-specific way (because of inliner). + * Currently, only JVM intrinsics are supported via JvmIrIntrinsicExtension interface. + */ +interface IrIntrinsicExtension \ No newline at end of file diff --git a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineIntrinsicsSupport.kt b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineIntrinsicsSupport.kt index 59d3a4b9472..a5edeae9169 100644 --- a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineIntrinsicsSupport.kt +++ b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineIntrinsicsSupport.kt @@ -6,7 +6,6 @@ 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 @@ -14,14 +13,12 @@ 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 @@ -46,6 +43,9 @@ class IrInlineIntrinsicsSupport( override val state: GenerationState get() = classCodegen.context.state + private val pluginExtensions = IrGenerationExtension.getInstances(classCodegen.context.state.project) + .mapNotNull { it.getPlatformIntrinsicExtension() as? JvmIrIntrinsicExtension } + override fun putClassInstance(v: InstructionAdapter, type: IrType) { ExpressionCodegen.generateClassInstance(v, type, classCodegen.typeMapper, wrapPrimitives = false) } @@ -132,16 +132,12 @@ class IrInlineIntrinsicsSupport( instructions: InsnList, type: IrType, asmType: Type - ): Int { - return IrGenerationExtension.getInstances(classCodegen.context.state.project) - .map { - it.applyPluginDefinedReifiedOperationMarker( - insn, - instructions, - type, - classCodegen.context - ) - } - .maxOrNull() ?: -1 - } + ): Int = pluginExtensions.maxOfOrNull { + it.applyPluginDefinedReifiedOperationMarker( + insn, + instructions, + type, + classCodegen.context + ) + } ?: -1 } diff --git a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/JvmIrIntrinsicExtension.kt b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/JvmIrIntrinsicExtension.kt new file mode 100644 index 00000000000..f3ecea56589 --- /dev/null +++ b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/JvmIrIntrinsicExtension.kt @@ -0,0 +1,25 @@ +/* + * 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.kotlin.backend.jvm.codegen + +import org.jetbrains.kotlin.backend.common.extensions.IrIntrinsicExtension +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.backend.jvm.intrinsics.IntrinsicMethod +import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.org.objectweb.asm.tree.InsnList +import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode + +interface JvmIrIntrinsicExtension : IrIntrinsicExtension { + fun getIntrinsic(symbol: IrFunctionSymbol): IntrinsicMethod? + + fun applyPluginDefinedReifiedOperationMarker( + insn: MethodInsnNode, + instructions: InsnList, + type: IrType, + jvmBackendContext: JvmBackendContext, + ): Int = -1 +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt index 7be155da8ad..b5b2bfb9d3e 100644 --- a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt +++ b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols +import org.jetbrains.kotlin.backend.jvm.codegen.JvmIrIntrinsicExtension import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods import org.jetbrains.kotlin.backend.jvm.ir.getIoFile import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -286,10 +287,12 @@ open class JvmIrCodegenFactory( if (evaluatorFragmentInfoForPsi2Ir != null) { context.localDeclarationsLoweringData = mutableMapOf() } - // todo: pass it here val generationExtensions = IrGenerationExtension.getInstances(state.project) + .mapNotNull { it.getPlatformIntrinsicExtension() as? JvmIrIntrinsicExtension } val intrinsics by lazy { IrIntrinsicMethods(irModuleFragment.irBuiltins, context.ir.symbols) } - context.getIntrinsic = { symbol: IrFunctionSymbol -> intrinsics.getIntrinsic(symbol) ?: generationExtensions.firstNotNullOfOrNull { it.retrieveIntrinsic(symbol) as? IntrinsicMarker } } + context.getIntrinsic = { symbol: IrFunctionSymbol -> + intrinsics.getIntrinsic(symbol) ?: generationExtensions.firstNotNullOfOrNull { it.getIntrinsic(symbol) } + } /* JvmBackendContext creates new unbound symbols, have to resolve them. */ ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies() diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializationJvmIrIntrinsicSupport.kt b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializationJvmIrIntrinsicSupport.kt index 2b8f25f2982..44c6e6ed8f9 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializationJvmIrIntrinsicSupport.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializationJvmIrIntrinsicSupport.kt @@ -248,7 +248,7 @@ class SerializationJvmIrIntrinsicSupport(val jvmBackendContext: JvmBackendContex false ) } else { - // More general path, including special ol built-in serializers for e.g. List + // More general path, including special or built-in serializers for e.g. List val serializer = support.findTypeSerializerOrContext(type) support.stackValueSerializerInstance( type, diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt index 09c7e2eee2d..368fb34e26c 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt @@ -9,9 +9,12 @@ 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.IrIntrinsicExtension 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.codegen.JvmIrIntrinsicExtension +import org.jetbrains.kotlin.backend.jvm.intrinsics.IntrinsicMethod import org.jetbrains.kotlin.backend.jvm.ir.fileParent import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI @@ -138,22 +141,22 @@ open class SerializationLoweringExtension @JvmOverloads constructor( moduleFragment.files.forEach(pass2::runOnFileInOrder) } - override fun retrieveIntrinsic(symbol: IrFunctionSymbol): Any? { - return SerializationJvmIrIntrinsicSupport.intrinsicForMethod(symbol.owner) - } + override fun getPlatformIntrinsicExtension(): IrIntrinsicExtension? { + return object : JvmIrIntrinsicExtension { + override fun getIntrinsic(symbol: IrFunctionSymbol): IntrinsicMethod? = + SerializationJvmIrIntrinsicSupport.intrinsicForMethod(symbol.owner) - 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, - ) + override fun applyPluginDefinedReifiedOperationMarker( + insn: MethodInsnNode, + instructions: InsnList, + type: IrType, + jvmBackendContext: JvmBackendContext + ): Int = SerializationJvmIrIntrinsicSupport(jvmBackendContext).applyPluginDefinedReifiedOperationMarker( + insn, + instructions, + type, + ) + } } }