JVM IR: Don't compute signatures in CallableReferenceLowering
This commit is contained in:
committed by
Alexander Udalov
parent
417c570243
commit
3db3f5bf7f
@@ -427,6 +427,16 @@ class JvmSymbols(
|
||||
}
|
||||
|
||||
val systemArraycopy: IrSimpleFunctionSymbol = systemClass.functionByName("arraycopy")
|
||||
|
||||
val signatureStringIntrinsic: IrSimpleFunctionSymbol =
|
||||
buildFun {
|
||||
name = Name.special("<signature-string>")
|
||||
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
|
||||
}.apply {
|
||||
parent = kotlinJvmInternalPackage
|
||||
addValueParameter("v", irBuiltIns.anyNType)
|
||||
returnType = irBuiltIns.stringType
|
||||
}.symbol
|
||||
}
|
||||
|
||||
private fun IrClassSymbol.functionByName(name: String): IrSimpleFunctionSymbol =
|
||||
|
||||
+4
-8
@@ -30,8 +30,11 @@ import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.load.java.*
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.load.java.getJvmMethodNameIfSpecial
|
||||
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinReflectingJvmDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.load.kotlin.forceSingleValueParameterBoxing
|
||||
import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor
|
||||
@@ -216,13 +219,6 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
||||
writeParameter(sw, JvmMethodParameterKind.RECEIVER, receiverParameter.type, function)
|
||||
}
|
||||
|
||||
// This is needed because mapSignature is currently invoked in CallableReferenceLowering before InnerClassesLowering where
|
||||
// this parameter is transformed to a normal value parameter.
|
||||
// TODO: do not call mapSignature in CallableReferenceLowering
|
||||
if (function is IrConstructor && function.dispatchReceiverParameter != null) {
|
||||
writeParameter(sw, JvmMethodParameterKind.VALUE, function.dispatchReceiverParameter!!.type, function)
|
||||
}
|
||||
|
||||
for (parameter in function.valueParameters) {
|
||||
val kind = when (parameter.origin) {
|
||||
JvmLoweredDeclarationOrigin.FIELD_FOR_OUTER_THIS -> JvmMethodParameterKind.OUTER
|
||||
|
||||
+2
-1
@@ -96,7 +96,8 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
|
||||
irBuiltIns.checkNotNullSymbol.toKey()!! to IrCheckNotNull,
|
||||
irBuiltIns.andandSymbol.toKey()!! to AndAnd,
|
||||
irBuiltIns.ororSymbol.toKey()!! to OrOr,
|
||||
symbols.unsafeCoerceIntrinsic.toKey()!! to UnsafeCoerce
|
||||
symbols.unsafeCoerceIntrinsic.toKey()!! to UnsafeCoerce,
|
||||
symbols.signatureStringIntrinsic.toKey()!! to SignatureString
|
||||
) +
|
||||
numberConversionMethods() +
|
||||
unaryFunForPrimitives("plus", UnaryPlus) +
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.PromisedValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
|
||||
/**
|
||||
* Computes the JVM signature of a given IrFunction. The function is passed as an IrFunctionReference
|
||||
* to the single argument of the intrinsic.
|
||||
*/
|
||||
object SignatureString : IntrinsicMethod() {
|
||||
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
|
||||
val function = (expression.getValueArgument(0) as IrFunctionReference).symbol.owner
|
||||
|
||||
// TODO do not use descriptors
|
||||
val declaration = codegen.context.referenceFunction(
|
||||
DescriptorUtils.unwrapFakeOverride(function.descriptor).original
|
||||
).owner
|
||||
|
||||
val method = codegen.context.methodSignatureMapper.mapAsmMethod(declaration)
|
||||
val descriptor = method.name + method.descriptor
|
||||
|
||||
return object : PromisedValue(codegen, AsmTypes.JAVA_STRING_TYPE, codegen.context.irBuiltIns.stringType) {
|
||||
override fun materialize() {
|
||||
codegen.mv.aconst(descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
@@ -99,6 +99,9 @@ fun IrType.getArrayElementType(irBuiltIns: IrBuiltIns): IrType =
|
||||
else
|
||||
irBuiltIns.primitiveArrayElementTypes.getValue(this.classOrNull!!)
|
||||
|
||||
val IrStatementOrigin?.isLambda
|
||||
get() = this == IrStatementOrigin.LAMBDA || this == IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||
|
||||
val IrConstructor.shouldBeHidden: Boolean
|
||||
get() = !Visibilities.isPrivate(visibility) && !constructedClass.isInline && hasMangledParameters
|
||||
|
||||
|
||||
+10
-21
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.irArray
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.shouldBeHidden
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isLambda
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildClass
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
@@ -40,8 +41,6 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
internal val callableReferencePhase = makeIrFilePhase(
|
||||
::CallableReferenceLowering,
|
||||
@@ -378,24 +377,14 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
|
||||
get() = (metadata as? MetadataSource.Function)?.descriptor?.name ?: name
|
||||
|
||||
private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction = buildOverride(superFunction).apply {
|
||||
val codegenContext = context
|
||||
body = context.createIrBuilder(symbol, startOffset, endOffset).run {
|
||||
// TODO do not use descriptors
|
||||
val declaration = codegenContext.referenceFunction(
|
||||
DescriptorUtils.unwrapFakeOverride(irFunctionReference.symbol.descriptor).original
|
||||
).owner
|
||||
val method = codegenContext.methodSignatureMapper.mapAsmMethod(declaration)
|
||||
// HACK: When referencing a constructor taking inline class parameters, we will actually
|
||||
// end up calling a public bridge method with an additional argument.
|
||||
// TODO: Don't compute signatures in CallableReferenceLowering
|
||||
val descriptor = if (declaration is IrConstructor && declaration.shouldBeHidden) {
|
||||
val marker =
|
||||
codegenContext.typeMapper.mapType(codegenContext.ir.symbols.defaultConstructorMarker.owner.defaultType)
|
||||
Type.getMethodDescriptor(method.returnType, *method.argumentTypes, marker)
|
||||
} else {
|
||||
method.descriptor
|
||||
}
|
||||
irExprBody(irString(method.name + descriptor))
|
||||
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
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isLambda
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
|
||||
internal val removeDeclarationsThatWouldBeInlined = makeIrFilePhase(
|
||||
@@ -36,8 +36,10 @@ private class RemoveDeclarationsThatWouldBeInlinedLowering(val context: JvmBacke
|
||||
override fun visitElement(element: IrElement) = element.acceptChildrenVoid(this)
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference) {
|
||||
assert(expression.origin == IrStatementOrigin.LAMBDA || expression.origin == IrStatementOrigin.ANONYMOUS_FUNCTION)
|
||||
loweredLambdasToDelete.add(expression.symbol.owner)
|
||||
if (expression.origin.isLambda) {
|
||||
loweredLambdasToDelete.add(expression.symbol.owner)
|
||||
}
|
||||
|
||||
expression.acceptChildrenVoid(this)
|
||||
}
|
||||
})
|
||||
|
||||
+35
-14
@@ -14,11 +14,13 @@ import org.jetbrains.kotlin.backend.common.ir.remapTypeParameters
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.intrinsics.receiverAndArgs
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.isLambda
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.shouldBeHidden
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||
@@ -33,8 +35,7 @@ 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.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
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
|
||||
@@ -49,16 +50,19 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
inlineLambdaToCallSite.putAll(InlineReferenceLocator.scan(context, irFile).lambdaToCallSite)
|
||||
|
||||
// Unconditionally add bridges for hidden constructors
|
||||
irFile.acceptChildrenVoid(object: IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) = element.acceptChildrenVoid(this)
|
||||
irFile.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||
private val hiddenDeclarations = mutableSetOf<IrConstructor>()
|
||||
|
||||
private fun handleConstructor(declaration: IrConstructor) {
|
||||
if (!declaration.shouldBeHidden)
|
||||
return
|
||||
private fun handleConstructor(declaration: IrConstructor): IrConstructorSymbol? {
|
||||
if (declaration.shouldBeHidden) {
|
||||
declaration.visibility = Visibilities.PRIVATE
|
||||
hiddenDeclarations += declaration
|
||||
}
|
||||
|
||||
declaration.visibility = Visibilities.PRIVATE
|
||||
if (declaration !in hiddenDeclarations)
|
||||
return null
|
||||
|
||||
functionMap.computeIfAbsent(declaration.symbol) {
|
||||
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
|
||||
@@ -71,17 +75,34 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
declaration.annotations.clear()
|
||||
declaration.valueParameters.forEach { it.annotations.clear() }
|
||||
}.symbol
|
||||
}
|
||||
} as IrConstructorSymbol
|
||||
}
|
||||
|
||||
override fun visitConstructor(declaration: IrConstructor) {
|
||||
override fun visitConstructor(declaration: IrConstructor): IrStatement {
|
||||
handleConstructor(declaration)
|
||||
super.visitConstructor(declaration)
|
||||
return super.visitConstructor(declaration)
|
||||
}
|
||||
|
||||
override fun visitConstructorCall(expression: IrConstructorCall) {
|
||||
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||
handleConstructor(expression.symbol.owner)
|
||||
super.visitConstructorCall(expression)
|
||||
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)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user