[K/N][IR] Refactored bridges building
This commit is contained in:
+5
-62
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanIr
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager
|
||||
import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_BRIDGE_METHOD
|
||||
import org.jetbrains.kotlin.backend.konan.lower.BridgesSupport
|
||||
import org.jetbrains.kotlin.backend.konan.lower.InnerClassesSupport
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
|
||||
import org.jetbrains.kotlin.backend.konan.optimizations.DevirtualizationAnalysis
|
||||
@@ -28,12 +28,10 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
|
||||
import org.jetbrains.kotlin.ir.deepCopyWithVariables
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
@@ -54,7 +52,10 @@ import kotlin.LazyThreadSafetyMode.PUBLICATION
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
internal class NativeMapping : DefaultMapping() {
|
||||
data class BridgeKey(val target: IrSimpleFunction, val bridgeDirections: BridgeDirections)
|
||||
|
||||
val outerThisFields = DefaultDelegateFactory.newDeclarationToDeclarationMapping<IrClass, IrField>()
|
||||
val bridges = mutableMapOf<BridgeKey, IrSimpleFunction>()
|
||||
}
|
||||
|
||||
internal class InlineFunctionOriginInfo(val irFunction: IrFunction, val irFile: IrFile, val startOffset: Int, val endOffset: Int)
|
||||
@@ -68,10 +69,6 @@ internal class SpecialDeclarationsFactory(val context: Context) {
|
||||
private val internalLoweredEnums = mutableMapOf<IrClass, InternalLoweredEnum>()
|
||||
private val externalLoweredEnums = mutableMapOf<IrClass, ExternalLoweredEnum>()
|
||||
|
||||
private data class BridgeKey(val target: IrSimpleFunction, val bridgeDirections: BridgeDirections)
|
||||
|
||||
private val bridges = mutableMapOf<BridgeKey, IrSimpleFunction>()
|
||||
|
||||
private val notLoweredInlineFunctions = mutableMapOf<IrFunctionSymbol, IrFunction>()
|
||||
val loweredInlineFunctions = mutableMapOf<IrFunction, InlineFunctionOriginInfo>()
|
||||
fun getNonLoweredInlineFunction(function: IrFunction): IrFunction {
|
||||
@@ -112,61 +109,6 @@ internal class SpecialDeclarationsFactory(val context: Context) {
|
||||
|
||||
fun getEnumEntryOrdinal(enumEntry: IrEnumEntry) =
|
||||
enumEntry.parentAsClass.declarations.filterIsInstance<IrEnumEntry>().indexOf(enumEntry)
|
||||
|
||||
fun getBridge(overriddenFunction: OverriddenFunctionInfo): IrSimpleFunction {
|
||||
val irFunction = overriddenFunction.function
|
||||
assert(overriddenFunction.needBridge) {
|
||||
"Function ${irFunction.descriptor} is not needed in a bridge to call overridden function ${overriddenFunction.overriddenFunction.descriptor}"
|
||||
}
|
||||
val key = BridgeKey(irFunction, overriddenFunction.bridgeDirections)
|
||||
return bridges.getOrPut(key) { createBridge(key) }
|
||||
}
|
||||
|
||||
private fun createBridge(key: BridgeKey): IrSimpleFunction {
|
||||
val (function, bridgeDirections) = key
|
||||
val startOffset = function.startOffset
|
||||
val endOffset = function.endOffset
|
||||
|
||||
fun BridgeDirection.type() =
|
||||
if (this.kind == BridgeDirectionKind.NONE)
|
||||
null
|
||||
else this.irClass?.defaultType ?: context.irBuiltIns.anyNType
|
||||
|
||||
return IrFunctionImpl(
|
||||
startOffset, endOffset,
|
||||
DECLARATION_ORIGIN_BRIDGE_METHOD(function),
|
||||
IrSimpleFunctionSymbolImpl(),
|
||||
"<bridge-$bridgeDirections>${function.computeFunctionName()}".synthesizedName,
|
||||
function.visibility,
|
||||
function.modality,
|
||||
isInline = false,
|
||||
isExternal = false,
|
||||
isTailrec = false,
|
||||
isSuspend = function.isSuspend,
|
||||
returnType = bridgeDirections.returnDirection.type() ?: function.returnType,
|
||||
isExpect = false,
|
||||
isFakeOverride = false,
|
||||
isOperator = false,
|
||||
isInfix = false
|
||||
).apply {
|
||||
val bridge = this
|
||||
parent = function.parent
|
||||
|
||||
dispatchReceiverParameter = function.dispatchReceiverParameter?.let {
|
||||
it.copyTo(bridge, type = bridgeDirections.dispatchReceiverDirection.type() ?: it.type)
|
||||
}
|
||||
extensionReceiverParameter = function.extensionReceiverParameter?.let {
|
||||
it.copyTo(bridge, type = bridgeDirections.extensionReceiverDirection.type() ?: it.type)
|
||||
}
|
||||
valueParameters += function.valueParameters.map {
|
||||
it.copyTo(bridge, type = bridgeDirections.parameterDirectionAt(it.index).type() ?: it.type)
|
||||
}
|
||||
|
||||
typeParameters += function.typeParameters.map { parameter ->
|
||||
parameter.copyToWithoutSuperTypes(bridge).also { it.superTypes += parameter.superTypes }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
@@ -205,6 +147,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
|
||||
val specialDeclarationsFactory = SpecialDeclarationsFactory(this)
|
||||
val innerClassesSupport by lazy { InnerClassesSupport(mapping, irFactory) }
|
||||
val bridgesSupport by lazy { BridgesSupport(mapping, irBuiltIns, irFactory) }
|
||||
|
||||
open class LazyMember<T>(val initializer: Context.() -> T) {
|
||||
operator fun getValue(thisRef: Context, property: KProperty<*>): T = thisRef.getValue(this)
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ internal class OverriddenFunctionInfo(
|
||||
} else {
|
||||
function
|
||||
}
|
||||
context.specialDeclarationsFactory.getBridge(OverriddenFunctionInfo(bridgeOwner, overriddenFunction))
|
||||
context.bridgesSupport.getBridge(OverriddenFunctionInfo(bridgeOwner, overriddenFunction))
|
||||
}
|
||||
return if (implementation.modality == Modality.ABSTRACT) null else implementation
|
||||
}
|
||||
|
||||
+55
-3
@@ -11,10 +11,14 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||
import org.jetbrains.kotlin.backend.common.lower.irIfThen
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.NativeMapping
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.computeFunctionName
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
@@ -26,13 +30,61 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||
import org.jetbrains.kotlin.ir.util.simpleFunctions
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
|
||||
import org.jetbrains.kotlin.load.java.SpecialGenericSignatures
|
||||
|
||||
internal class BridgesSupport(mapping: NativeMapping, val irBuiltIns: IrBuiltIns, val irFactory: IrFactory) {
|
||||
private val bridges = mapping.bridges
|
||||
|
||||
fun getBridge(overriddenFunction: OverriddenFunctionInfo): IrSimpleFunction {
|
||||
val irFunction = overriddenFunction.function
|
||||
assert(overriddenFunction.needBridge) {
|
||||
"Function ${irFunction.render()} doesn't need a bridge to call overridden function ${overriddenFunction.overriddenFunction.render()}"
|
||||
}
|
||||
val key = NativeMapping.BridgeKey(irFunction, overriddenFunction.bridgeDirections)
|
||||
return bridges.getOrPut(key) { createBridge(key) }
|
||||
}
|
||||
|
||||
private fun BridgeDirection.type() =
|
||||
if (this.kind == BridgeDirectionKind.NONE)
|
||||
null
|
||||
else this.irClass?.defaultType ?: irBuiltIns.anyNType
|
||||
|
||||
private fun createBridge(key: NativeMapping.BridgeKey): IrSimpleFunction {
|
||||
val (function, bridgeDirections) = key
|
||||
|
||||
return irFactory.buildFun {
|
||||
startOffset = function.startOffset
|
||||
endOffset = function.endOffset
|
||||
origin = DECLARATION_ORIGIN_BRIDGE_METHOD(function)
|
||||
name = "<bridge-$bridgeDirections>${function.computeFunctionName()}".synthesizedName
|
||||
visibility = function.visibility
|
||||
modality = function.modality
|
||||
returnType = bridgeDirections.returnDirection.type() ?: function.returnType
|
||||
isSuspend = function.isSuspend
|
||||
}.apply {
|
||||
parent = function.parent
|
||||
val bridge = this
|
||||
|
||||
dispatchReceiverParameter = function.dispatchReceiverParameter?.let {
|
||||
it.copyTo(bridge, type = bridgeDirections.dispatchReceiverDirection.type() ?: it.type)
|
||||
}
|
||||
extensionReceiverParameter = function.extensionReceiverParameter?.let {
|
||||
it.copyTo(bridge, type = bridgeDirections.extensionReceiverDirection.type() ?: it.type)
|
||||
}
|
||||
valueParameters = function.valueParameters.map {
|
||||
it.copyTo(bridge, type = bridgeDirections.parameterDirectionAt(it.index).type() ?: it.type)
|
||||
}
|
||||
|
||||
typeParameters = function.typeParameters.map { parameter ->
|
||||
parameter.copyToWithoutSuperTypes(bridge).also { it.superTypes += parameter.superTypes }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
internal class WorkersBridgesBuilding(val context: Context) : DeclarationContainerLoweringPass, IrElementTransformerVoid() {
|
||||
|
||||
val symbols = context.ir.symbols
|
||||
@@ -230,7 +282,7 @@ private fun Context.buildBridge(startOffset: Int, endOffset: Int,
|
||||
overriddenFunction: OverriddenFunctionInfo, targetSymbol: IrSimpleFunctionSymbol,
|
||||
superQualifierSymbol: IrClassSymbol? = null): IrFunction {
|
||||
|
||||
val bridge = specialDeclarationsFactory.getBridge(overriddenFunction)
|
||||
val bridge = bridgesSupport.getBridge(overriddenFunction)
|
||||
|
||||
if (bridge.modality == Modality.ABSTRACT) {
|
||||
return bridge
|
||||
|
||||
Reference in New Issue
Block a user