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.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
|
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.IrExpressionLambda
|
||||||
import org.jetbrains.kotlin.codegen.JvmKotlinType
|
import org.jetbrains.kotlin.codegen.JvmKotlinType
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
@@ -197,7 +198,7 @@ fun isInlineIrExpression(argumentExpression: IrExpression) =
|
|||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrBlock.isInlineIrBlock(): Boolean = origin == IrStatementOrigin.LAMBDA || origin == IrStatementOrigin.ANONYMOUS_FUNCTION
|
fun IrBlock.isInlineIrBlock(): Boolean = origin.isLambda
|
||||||
|
|
||||||
fun IrFunction.isInlineFunctionCall(context: JvmBackendContext) =
|
fun IrFunction.isInlineFunctionCall(context: JvmBackendContext) =
|
||||||
(!context.state.isInlineDisabled || typeParameters.any { it.isReified }) && isInline
|
(!context.state.isInlineDisabled || typeParameters.any { it.isReified }) && isInline
|
||||||
@@ -99,7 +99,7 @@ fun IrType.getArrayElementType(irBuiltIns: IrBuiltIns): IrType =
|
|||||||
else
|
else
|
||||||
irBuiltIns.primitiveArrayElementTypes.getValue(this.classOrNull!!)
|
irBuiltIns.primitiveArrayElementTypes.getValue(this.classOrNull!!)
|
||||||
|
|
||||||
val IrStatementOrigin?.isLambda
|
val IrStatementOrigin?.isLambda: Boolean
|
||||||
get() = this == IrStatementOrigin.LAMBDA || this == IrStatementOrigin.ANONYMOUS_FUNCTION
|
get() = this == IrStatementOrigin.LAMBDA || this == IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||||
|
|
||||||
val IrConstructor.shouldBeHidden: Boolean
|
val IrConstructor.shouldBeHidden: Boolean
|
||||||
|
|||||||
+1
-8
@@ -48,9 +48,6 @@ internal val callableReferencePhase = makeIrFilePhase(
|
|||||||
description = "Handle callable references"
|
description = "Handle callable references"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val IrStatementOrigin?.isLambda
|
|
||||||
get() = this == IrStatementOrigin.LAMBDA || this == IrStatementOrigin.ANONYMOUS_FUNCTION
|
|
||||||
|
|
||||||
internal class InlineReferenceLocator(private val context: JvmBackendContext) : IrElementVisitorVoidWithContext() {
|
internal class InlineReferenceLocator(private val context: JvmBackendContext) : IrElementVisitorVoidWithContext() {
|
||||||
val inlineReferences = mutableSetOf<IrFunctionReference>()
|
val inlineReferences = mutableSetOf<IrFunctionReference>()
|
||||||
|
|
||||||
@@ -379,11 +376,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
|
|||||||
private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction = buildOverride(superFunction).apply {
|
private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction = buildOverride(superFunction).apply {
|
||||||
body = context.createJvmIrBuilder(symbol, startOffset, endOffset).run {
|
body = context.createJvmIrBuilder(symbol, startOffset, endOffset).run {
|
||||||
irExprBody(irCall(backendContext.ir.symbols.signatureStringIntrinsic).apply {
|
irExprBody(irCall(backendContext.ir.symbols.signatureStringIntrinsic).apply {
|
||||||
putValueArgument(0, with(irFunctionReference) {
|
putValueArgument(0, irFunctionReference.deepCopyWithSymbols(symbol.owner))
|
||||||
IrFunctionReferenceImpl(
|
|
||||||
startOffset, endOffset, type, symbol, descriptor, typeArgumentsCount, valueArgumentsCount, origin
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+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.isSubtypeOfClass
|
||||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
@@ -48,64 +47,6 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
|||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
inlineLambdaToCallSite.putAll(InlineReferenceLocator.scan(context, irFile).lambdaToCallSite)
|
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)
|
irFile.transformChildrenVoid(this)
|
||||||
pendingTransformations.forEach { it() }
|
pendingTransformations.forEach { it() }
|
||||||
}
|
}
|
||||||
@@ -147,6 +88,57 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
|||||||
handleAccess(expression, expression.symbol, setterMap, ::makeSetterAccessorSymbol, ::modifySetterExpression)
|
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(
|
private inline fun <ExprT : IrDeclarationReference, reified FromSyT : IrSymbol, ToSyT : IrSymbol> handleAccess(
|
||||||
expression: ExprT,
|
expression: ExprT,
|
||||||
symbol: FromSyT,
|
symbol: FromSyT,
|
||||||
|
|||||||
Reference in New Issue
Block a user