JVM IR: Refactor SyntheticAccessorLowering to use a single traversal
This commit is contained in:
committed by
Alexander Udalov
parent
3098723406
commit
18940ab0cb
+2
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.codegen
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isLambda
|
||||
import org.jetbrains.kotlin.codegen.IrExpressionLambda
|
||||
import org.jetbrains.kotlin.codegen.JvmKotlinType
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
@@ -197,7 +198,7 @@ fun isInlineIrExpression(argumentExpression: IrExpression) =
|
||||
else -> false
|
||||
}
|
||||
|
||||
fun IrBlock.isInlineIrBlock(): Boolean = origin == IrStatementOrigin.LAMBDA || origin == IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||
fun IrBlock.isInlineIrBlock(): Boolean = origin.isLambda
|
||||
|
||||
fun IrFunction.isInlineFunctionCall(context: JvmBackendContext) =
|
||||
(!context.state.isInlineDisabled || typeParameters.any { it.isReified }) && isInline
|
||||
@@ -99,7 +99,7 @@ fun IrType.getArrayElementType(irBuiltIns: IrBuiltIns): IrType =
|
||||
else
|
||||
irBuiltIns.primitiveArrayElementTypes.getValue(this.classOrNull!!)
|
||||
|
||||
val IrStatementOrigin?.isLambda
|
||||
val IrStatementOrigin?.isLambda: Boolean
|
||||
get() = this == IrStatementOrigin.LAMBDA || this == IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||
|
||||
val IrConstructor.shouldBeHidden: Boolean
|
||||
|
||||
+1
-8
@@ -48,9 +48,6 @@ internal val callableReferencePhase = makeIrFilePhase(
|
||||
description = "Handle callable references"
|
||||
)
|
||||
|
||||
private val IrStatementOrigin?.isLambda
|
||||
get() = this == IrStatementOrigin.LAMBDA || this == IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||
|
||||
internal class InlineReferenceLocator(private val context: JvmBackendContext) : IrElementVisitorVoidWithContext() {
|
||||
val inlineReferences = mutableSetOf<IrFunctionReference>()
|
||||
|
||||
@@ -379,11 +376,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
|
||||
private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction = buildOverride(superFunction).apply {
|
||||
body = context.createJvmIrBuilder(symbol, startOffset, endOffset).run {
|
||||
irExprBody(irCall(backendContext.ir.symbols.signatureStringIntrinsic).apply {
|
||||
putValueArgument(0, with(irFunctionReference) {
|
||||
IrFunctionReferenceImpl(
|
||||
startOffset, endOffset, type, symbol, descriptor, typeArgumentsCount, valueArgumentsCount, origin
|
||||
)
|
||||
})
|
||||
putValueArgument(0, irFunctionReference.deepCopyWithSymbols(symbol.owner))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+51
-59
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.types.isSubtypeOfClass
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
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.JavaVisibilities
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
@@ -48,64 +47,6 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
inlineLambdaToCallSite.putAll(InlineReferenceLocator.scan(context, irFile).lambdaToCallSite)
|
||||
|
||||
// Unconditionally add bridges for hidden constructors
|
||||
irFile.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||
private val hiddenDeclarations = mutableSetOf<IrConstructor>()
|
||||
|
||||
private fun handleConstructor(declaration: IrConstructor): IrConstructorSymbol? {
|
||||
if (declaration.shouldBeHidden) {
|
||||
declaration.visibility = Visibilities.PRIVATE
|
||||
hiddenDeclarations += declaration
|
||||
}
|
||||
|
||||
if (declaration !in hiddenDeclarations)
|
||||
return null
|
||||
|
||||
return functionMap.getOrPut(declaration.symbol) {
|
||||
declaration.makeConstructorAccessor().also { accessor ->
|
||||
// There's a special case in the JVM backend for serializing the metadata of hidden
|
||||
// constructors - we serialize the descriptor of the original constructor, but the
|
||||
// signature of the bridge. We implement this special case in the JVM IR backend by
|
||||
// attaching the metadata directly to the bridge. We also have to move all annotations
|
||||
// to the bridge method. Parameter annotations are already moved by the copyTo method.
|
||||
accessor.metadata = declaration.metadata
|
||||
declaration.safeAs<IrConstructorImpl>()?.metadata = null
|
||||
accessor.annotations += declaration.annotations
|
||||
declaration.annotations.clear()
|
||||
declaration.valueParameters.forEach { it.annotations.clear() }
|
||||
}.symbol
|
||||
} as IrConstructorSymbol
|
||||
}
|
||||
|
||||
override fun visitConstructor(declaration: IrConstructor): IrStatement {
|
||||
handleConstructor(declaration)
|
||||
return super.visitConstructor(declaration)
|
||||
}
|
||||
|
||||
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||
handleConstructor(expression.symbol.owner)
|
||||
return super.visitConstructorCall(expression)
|
||||
}
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||
val function = expression.symbol.owner
|
||||
|
||||
if (!expression.origin.isLambda && function is IrConstructor) {
|
||||
handleConstructor(function)?.let { accessor ->
|
||||
expression.transformChildrenVoid()
|
||||
return IrFunctionReferenceImpl(
|
||||
expression.startOffset, expression.endOffset, expression.type,
|
||||
accessor, accessor.descriptor, accessor.owner.typeParameters.size,
|
||||
accessor.owner.valueParameters.size, expression.origin
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return super.visitFunctionReference(expression)
|
||||
}
|
||||
})
|
||||
|
||||
irFile.transformChildrenVoid(this)
|
||||
pendingTransformations.forEach { it() }
|
||||
}
|
||||
@@ -147,6 +88,57 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
handleAccess(expression, expression.symbol, setterMap, ::makeSetterAccessorSymbol, ::modifySetterExpression)
|
||||
)
|
||||
|
||||
override fun visitConstructor(declaration: IrConstructor): IrStatement {
|
||||
handleHiddenConstructor(declaration)
|
||||
return super.visitConstructor(declaration)
|
||||
}
|
||||
|
||||
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||
handleHiddenConstructor(expression.symbol.owner)
|
||||
return super.visitConstructorCall(expression)
|
||||
}
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||
val function = expression.symbol.owner
|
||||
|
||||
if (!expression.origin.isLambda && function is IrConstructor) {
|
||||
handleHiddenConstructor(function)?.let { accessor ->
|
||||
expression.transformChildrenVoid()
|
||||
return IrFunctionReferenceImpl(
|
||||
expression.startOffset, expression.endOffset, expression.type,
|
||||
accessor, accessor.descriptor, accessor.owner.typeParameters.size,
|
||||
accessor.owner.valueParameters.size, expression.origin
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return super.visitFunctionReference(expression)
|
||||
}
|
||||
|
||||
private fun handleHiddenConstructor(declaration: IrConstructor): IrConstructorSymbol? {
|
||||
functionMap[declaration.symbol]?.let { return it as IrConstructorSymbol }
|
||||
|
||||
if (!declaration.shouldBeHidden)
|
||||
return null
|
||||
|
||||
declaration.visibility = Visibilities.PRIVATE
|
||||
|
||||
return declaration.makeConstructorAccessor().also { accessor ->
|
||||
functionMap[declaration.symbol] = accessor.symbol
|
||||
|
||||
// There's a special case in the JVM backend for serializing the metadata of hidden
|
||||
// constructors - we serialize the descriptor of the original constructor, but the
|
||||
// signature of the bridge. We implement this special case in the JVM IR backend by
|
||||
// attaching the metadata directly to the bridge. We also have to move all annotations
|
||||
// to the bridge method. Parameter annotations are already moved by the copyTo method.
|
||||
accessor.metadata = declaration.metadata
|
||||
declaration.safeAs<IrConstructorImpl>()?.metadata = null
|
||||
accessor.annotations += declaration.annotations
|
||||
declaration.annotations.clear()
|
||||
declaration.valueParameters.forEach { it.annotations.clear() }
|
||||
}.symbol
|
||||
}
|
||||
|
||||
private inline fun <ExprT : IrDeclarationReference, reified FromSyT : IrSymbol, ToSyT : IrSymbol> handleAccess(
|
||||
expression: ExprT,
|
||||
symbol: FromSyT,
|
||||
|
||||
Reference in New Issue
Block a user