Refactor extensions for plugin intrinsics entry points

so platform-specific parts won't have unsafe downcasts.
This commit is contained in:
Leonid Startsev
2022-08-29 18:45:49 +02:00
committed by Space
parent eae588abea
commit 763303fe97
7 changed files with 80 additions and 54 deletions
@@ -34,6 +34,8 @@ class PsiInlineIntrinsicsSupport(
private val reportErrorsOn: KtElement, private val reportErrorsOn: KtElement,
private val typeSystem: TypeSystemCommonBackendContext private val typeSystem: TypeSystemCommonBackendContext
) : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> { ) : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
private val pluginExtensions = ExpressionCodegenExtension.getInstances(state.project)
override fun putClassInstance(v: InstructionAdapter, type: KotlinType) { override fun putClassInstance(v: InstructionAdapter, type: KotlinType) {
DescriptorAsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper) DescriptorAsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper)
} }
@@ -90,9 +92,15 @@ class PsiInlineIntrinsicsSupport(
instructions: InsnList, instructions: InsnList,
type: KotlinType, type: KotlinType,
asmType: Type asmType: Type
): Int { ): Int = pluginExtensions.maxOfOrNull {
return ExpressionCodegenExtension.getInstances(state.project) it.applyPluginDefinedReifiedOperationMarker(
.map { it.applyPluginDefinedReifiedOperationMarker(insn, instructions, type, asmType, state.typeMapper, typeSystem, state.module) } insn,
.maxOrNull() ?: -1 instructions,
} type,
asmType,
state.typeMapper,
typeSystem,
state.module
)
} ?: -1
} }
@@ -5,15 +5,9 @@
package org.jetbrains.kotlin.backend.common.extensions 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.extensions.ProjectExtensionDescriptor
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.linkage.IrDeserializer 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 { interface IrGenerationExtension : IrDeserializer.IrLinkerExtension {
companion object : companion object :
@@ -23,14 +17,11 @@ interface IrGenerationExtension : IrDeserializer.IrLinkerExtension {
fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext)
// TODO: normal dependency & typing fun getPlatformIntrinsicExtension(): IrIntrinsicExtension? = null
fun retrieveIntrinsic(symbol: IrFunctionSymbol): Any? = null
fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode,
instructions: InsnList,
type: IrType,
jvmBackendContext: BackendContext,
): Int = -1
} }
/**
* 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
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.backend.jvm.codegen package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension 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.intrinsics.SignatureString
import org.jetbrains.kotlin.backend.jvm.ir.getCallableReferenceOwnerKClassType import org.jetbrains.kotlin.backend.jvm.ir.getCallableReferenceOwnerKClassType
import org.jetbrains.kotlin.backend.jvm.ir.getCallableReferenceTopLevelFlag 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.AsmUtil
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classOrNull 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.allParametersCount
import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
@@ -46,6 +43,9 @@ class IrInlineIntrinsicsSupport(
override val state: GenerationState override val state: GenerationState
get() = classCodegen.context.state 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) { override fun putClassInstance(v: InstructionAdapter, type: IrType) {
ExpressionCodegen.generateClassInstance(v, type, classCodegen.typeMapper, wrapPrimitives = false) ExpressionCodegen.generateClassInstance(v, type, classCodegen.typeMapper, wrapPrimitives = false)
} }
@@ -132,16 +132,12 @@ class IrInlineIntrinsicsSupport(
instructions: InsnList, instructions: InsnList,
type: IrType, type: IrType,
asmType: Type asmType: Type
): Int { ): Int = pluginExtensions.maxOfOrNull {
return IrGenerationExtension.getInstances(classCodegen.context.state.project) it.applyPluginDefinedReifiedOperationMarker(
.map { insn,
it.applyPluginDefinedReifiedOperationMarker( instructions,
insn, type,
instructions, classCodegen.context
type, )
classCodegen.context } ?: -1
)
}
.maxOrNull() ?: -1
}
} }
@@ -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
}
@@ -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.phaser.invokeToplevel
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols 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.intrinsics.IrIntrinsicMethods
import org.jetbrains.kotlin.backend.jvm.ir.getIoFile import org.jetbrains.kotlin.backend.jvm.ir.getIoFile
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
@@ -286,10 +287,12 @@ open class JvmIrCodegenFactory(
if (evaluatorFragmentInfoForPsi2Ir != null) { if (evaluatorFragmentInfoForPsi2Ir != null) {
context.localDeclarationsLoweringData = mutableMapOf() context.localDeclarationsLoweringData = mutableMapOf()
} }
// todo: pass it here
val generationExtensions = IrGenerationExtension.getInstances(state.project) val generationExtensions = IrGenerationExtension.getInstances(state.project)
.mapNotNull { it.getPlatformIntrinsicExtension() as? JvmIrIntrinsicExtension }
val intrinsics by lazy { IrIntrinsicMethods(irModuleFragment.irBuiltins, context.ir.symbols) } 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. */ /* JvmBackendContext creates new unbound symbols, have to resolve them. */
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies() ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
@@ -248,7 +248,7 @@ class SerializationJvmIrIntrinsicSupport(val jvmBackendContext: JvmBackendContex
false false
) )
} else { } 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) val serializer = support.findTypeSerializerOrContext(type)
support.stackValueSerializerInstance( support.stackValueSerializerInstance(
type, type,
@@ -9,9 +9,12 @@ 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
import org.jetbrains.kotlin.backend.common.extensions.IrIntrinsicExtension
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.runOnFilePostfix import org.jetbrains.kotlin.backend.common.runOnFilePostfix
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext 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.backend.jvm.ir.fileParent
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
@@ -138,22 +141,22 @@ open class SerializationLoweringExtension @JvmOverloads constructor(
moduleFragment.files.forEach(pass2::runOnFileInOrder) moduleFragment.files.forEach(pass2::runOnFileInOrder)
} }
override fun retrieveIntrinsic(symbol: IrFunctionSymbol): Any? { override fun getPlatformIntrinsicExtension(): IrIntrinsicExtension? {
return SerializationJvmIrIntrinsicSupport.intrinsicForMethod(symbol.owner) return object : JvmIrIntrinsicExtension {
} override fun getIntrinsic(symbol: IrFunctionSymbol): IntrinsicMethod? =
SerializationJvmIrIntrinsicSupport.intrinsicForMethod(symbol.owner)
override fun applyPluginDefinedReifiedOperationMarker( override fun applyPluginDefinedReifiedOperationMarker(
insn: MethodInsnNode, insn: MethodInsnNode,
instructions: InsnList, instructions: InsnList,
type: IrType, type: IrType,
jvmBackendContext: BackendContext, jvmBackendContext: JvmBackendContext
): Int { ): Int = SerializationJvmIrIntrinsicSupport(jvmBackendContext).applyPluginDefinedReifiedOperationMarker(
val ctx = jvmBackendContext as? JvmBackendContext ?: return -1 insn,
return SerializationJvmIrIntrinsicSupport(ctx).applyPluginDefinedReifiedOperationMarker( instructions,
insn, type,
instructions, )
type, }
)
} }
} }