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 typeSystem: TypeSystemCommonBackendContext
) : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
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
}
@@ -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
@@ -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
}
@@ -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.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()
@@ -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,
@@ -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,
)
}
}
}