Supported IrConstructorCall
(cherry picked from commit 315362b0fc3ddec049955b67f1df876d5569aa22)
This commit is contained in:
committed by
Vasily Levchenko
parent
6708e4df80
commit
2138b37dc9
+1
-1
@@ -99,7 +99,7 @@ private fun KotlinToCCallBuilder.addArgument(
|
||||
if (!variadic) cFunctionBuilder.addParameter(cArgument.type)
|
||||
}
|
||||
|
||||
private fun KotlinToCCallBuilder.buildKotlinBridgeCall(transformCall: (IrCall) -> IrExpression = { it }): IrExpression =
|
||||
private fun KotlinToCCallBuilder.buildKotlinBridgeCall(transformCall: (IrMemberAccessExpression) -> IrExpression = { it }): IrExpression =
|
||||
bridgeCallBuilder.build(
|
||||
bridgeBuilder.buildKotlinBridge().also {
|
||||
this.stubs.addKotlin(it)
|
||||
|
||||
+5
-2
@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTryImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
@@ -128,8 +130,9 @@ private fun createKotlinBridge(
|
||||
)
|
||||
bridgeDescriptor.bind(bridge)
|
||||
if (isExternal) {
|
||||
val constructor = symbols.filterExceptions.owner.constructors.single()
|
||||
bridge.annotations +=
|
||||
irCall(startOffset, endOffset, symbols.filterExceptions.owner.constructors.single(), emptyList())
|
||||
IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, constructor.returnType, constructor.symbol)
|
||||
}
|
||||
return bridge
|
||||
}
|
||||
@@ -185,7 +188,7 @@ internal class KotlinCallBuilder(private val irBuilder: IrBuilderWithScope, priv
|
||||
|
||||
fun build(
|
||||
function: IrFunction,
|
||||
transformCall: (IrCall) -> IrExpression = { it }
|
||||
transformCall: (IrMemberAccessExpression) -> IrExpression = { it }
|
||||
): IrExpression {
|
||||
val arguments = this.arguments.toMutableList()
|
||||
|
||||
|
||||
+3
-12
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.konan.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.SharedVariablesManager
|
||||
import org.jetbrains.kotlin.backend.konan.KonanBackendContext
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
@@ -21,9 +20,9 @@ import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.types.typeWith
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.types.*
|
||||
@@ -36,14 +35,6 @@ internal class KonanSharedVariablesManager(val context: KonanBackendContext) : S
|
||||
|
||||
private val elementProperty = refClass.owner.declarations.filterIsInstance<IrProperty>().single()
|
||||
|
||||
private fun refConstructor(elementType: KotlinType): ClassConstructorDescriptor {
|
||||
val typeParameter = refClassConstructor.descriptor.typeParameters[0]
|
||||
|
||||
return refClassConstructor.descriptor.substitute(TypeSubstitutor.create(
|
||||
mapOf(typeParameter.typeConstructor to TypeProjectionImpl(Variance.INVARIANT, elementType))
|
||||
))!!
|
||||
}
|
||||
|
||||
private fun refType(elementType: KotlinType): KotlinType {
|
||||
return refClass.descriptor.defaultType.replace(listOf(TypeProjectionImpl(elementType)))
|
||||
}
|
||||
@@ -66,10 +57,10 @@ internal class KonanSharedVariablesManager(val context: KonanBackendContext) : S
|
||||
|
||||
val valueType = originalDeclaration.type
|
||||
|
||||
val refConstructorCall = IrCallImpl(
|
||||
val refConstructorCall = IrConstructorCallImpl.fromSymbolOwner(
|
||||
originalDeclaration.startOffset, originalDeclaration.endOffset,
|
||||
refClass.typeWith(valueType),
|
||||
refClassConstructor, refConstructor(valueType.toKotlinType()), 1
|
||||
refClassConstructor
|
||||
).apply {
|
||||
putTypeArgument(0, valueType)
|
||||
}
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ class IrFileImpl(entry: SourceManager.FileEntry) : IrFile {
|
||||
|
||||
override val metadata: MetadataSource.File?
|
||||
get() = TODO("not implemented")
|
||||
override val annotations: MutableList<IrCall>
|
||||
override val annotations: MutableList<IrConstructorCall>
|
||||
get() = TODO("not implemented")
|
||||
override val fqName: FqName
|
||||
get() = TODO("not implemented")
|
||||
|
||||
-7
@@ -92,13 +92,6 @@ val IrClass.isFinalClass: Boolean
|
||||
|
||||
fun IrClass.isSpecialClassWithNoSupertypes() = this.isAny() || this.isNothing()
|
||||
|
||||
private val IrCall.annotationClass
|
||||
get() = (this.symbol.owner as IrConstructor).constructedClass
|
||||
|
||||
fun List<IrCall>.findAnnotation(fqName: FqName): IrCall? = this.firstOrNull {
|
||||
it.annotationClass.fqNameSafe == fqName
|
||||
}
|
||||
|
||||
fun <T> IrDeclaration.getAnnotationArgumentValue(fqName: FqName, argumentName: String): T? {
|
||||
val annotation = this.annotations.findAnnotation(fqName)
|
||||
if (annotation == null) {
|
||||
|
||||
+3
-4
@@ -8,7 +8,6 @@ import org.jetbrains.kotlin.backend.konan.llvm.objc.genObjCSelector
|
||||
import org.jetbrains.kotlin.backend.konan.reportCompilationError
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.types.getClass
|
||||
@@ -147,8 +146,8 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
||||
}
|
||||
IntrinsicType.OBJC_INIT_BY -> {
|
||||
val receiver = environment.evaluateExpression(callSite.extensionReceiver!!)
|
||||
val irConstructorCall = callSite.getValueArgument(0) as IrCall
|
||||
val constructorDescriptor = irConstructorCall.symbol.owner as IrConstructor
|
||||
val irConstructorCall = callSite.getValueArgument(0) as IrConstructorCall
|
||||
val constructorDescriptor = irConstructorCall.symbol.owner
|
||||
val constructorArgs = environment.evaluateExplicitArgs(irConstructorCall)
|
||||
val args = listOf(receiver) + constructorArgs
|
||||
environment.evaluateCall(constructorDescriptor, args, Lifetime.IRRELEVANT)
|
||||
@@ -159,7 +158,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
||||
environment.functionGenerationContext.genObjCSelector(selector)
|
||||
}
|
||||
IntrinsicType.INIT_INSTANCE -> {
|
||||
val initializer = callSite.getValueArgument(1) as IrCall
|
||||
val initializer = callSite.getValueArgument(1) as IrConstructorCall
|
||||
val thiz = environment.evaluateExpression(callSite.getValueArgument(0)!!)
|
||||
environment.evaluateCall(
|
||||
initializer.symbol.owner,
|
||||
|
||||
+34
-28
@@ -760,6 +760,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
is IrCall -> return evaluateCall (value)
|
||||
is IrDelegatingConstructorCall ->
|
||||
return evaluateCall (value)
|
||||
is IrConstructorCall -> return evaluateCall (value)
|
||||
is IrInstanceInitializerCall ->
|
||||
return evaluateInstanceInitializerCall(value)
|
||||
is IrGetValue -> return evaluateGetValue (value)
|
||||
@@ -1751,6 +1752,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
updateBuilderDebugLocation(value)
|
||||
return when (value) {
|
||||
is IrDelegatingConstructorCall -> delegatingConstructorCall(value.symbol.owner, args)
|
||||
is IrConstructorCall -> evaluateConstructorCall(value, args)
|
||||
else -> evaluateFunctionCall(value as IrCall, args, resultLifetime(value))
|
||||
}
|
||||
}
|
||||
@@ -2016,7 +2018,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
return when {
|
||||
function.isTypedIntrinsic -> intrinsicGenerator.evaluateCall(callee, args)
|
||||
function.symbol in context.irBuiltIns.irBuiltInsSymbols -> evaluateOperatorCall(callee, argsWithContinuationIfNeeded)
|
||||
function is IrConstructor -> evaluateConstructorCall(callee, argsWithContinuationIfNeeded)
|
||||
else -> evaluateSimpleFunctionCall(function, argsWithContinuationIfNeeded, resultLifetime, callee.superQualifierSymbol?.owner)
|
||||
}
|
||||
}
|
||||
@@ -2045,34 +2046,40 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
return lifetimes.getOrElse(callee) { /* TODO: make IRRELEVANT */ Lifetime.GLOBAL }
|
||||
}
|
||||
|
||||
private fun evaluateConstructorCall(callee: IrCall, args: List<LLVMValueRef>): LLVMValueRef {
|
||||
private fun evaluateConstructorCall(callee: IrConstructorCall, args: List<LLVMValueRef>): LLVMValueRef {
|
||||
context.log{"evaluateConstructorCall : ${ir2string(callee)}"}
|
||||
return memScoped {
|
||||
val constructedClass = (callee.symbol as IrConstructorSymbol).owner.constructedClass
|
||||
val thisValue = if (constructedClass.isArray) {
|
||||
assert(args.isNotEmpty() && args[0].type == int32Type)
|
||||
functionGenerationContext.allocArray(codegen.typeInfoValue(constructedClass), args[0],
|
||||
resultLifetime(callee), currentCodeContext.exceptionHandler)
|
||||
} else if (constructedClass == context.ir.symbols.string.owner) {
|
||||
// TODO: consider returning the empty string literal instead.
|
||||
assert(args.isEmpty())
|
||||
functionGenerationContext.allocArray(codegen.typeInfoValue(constructedClass), count = kImmZero,
|
||||
lifetime = resultLifetime(callee), exceptionHandler = currentCodeContext.exceptionHandler)
|
||||
} else if (constructedClass.isObjCClass()) {
|
||||
assert(constructedClass.isKotlinObjCClass()) // Calls to other ObjC class constructors must be lowered.
|
||||
val symbols = context.ir.symbols
|
||||
val rawPtr = callDirect(
|
||||
symbols.interopAllocObjCObject.owner,
|
||||
listOf(genGetObjCClass(constructedClass)),
|
||||
Lifetime.IRRELEVANT
|
||||
)
|
||||
|
||||
callDirect(symbols.interopInterpretObjCPointer.owner, listOf(rawPtr), resultLifetime(callee)).also {
|
||||
// Balance pointer retained by alloc:
|
||||
callDirect(symbols.interopObjCRelease.owner, listOf(rawPtr), Lifetime.IRRELEVANT)
|
||||
val constructedClass = callee.symbol.owner.constructedClass
|
||||
val thisValue = when {
|
||||
constructedClass.isArray -> {
|
||||
assert(args.isNotEmpty() && args[0].type == int32Type)
|
||||
functionGenerationContext.allocArray(codegen.typeInfoValue(constructedClass), args[0],
|
||||
resultLifetime(callee), currentCodeContext.exceptionHandler)
|
||||
}
|
||||
} else {
|
||||
functionGenerationContext.allocInstance(constructedClass, resultLifetime(callee))
|
||||
|
||||
constructedClass == context.ir.symbols.string.owner -> {
|
||||
// TODO: consider returning the empty string literal instead.
|
||||
assert(args.isEmpty())
|
||||
functionGenerationContext.allocArray(codegen.typeInfoValue(constructedClass), count = kImmZero,
|
||||
lifetime = resultLifetime(callee), exceptionHandler = currentCodeContext.exceptionHandler)
|
||||
}
|
||||
|
||||
constructedClass.isObjCClass() -> {
|
||||
assert(constructedClass.isKotlinObjCClass()) // Calls to other ObjC class constructors must be lowered.
|
||||
val symbols = context.ir.symbols
|
||||
val rawPtr = callDirect(
|
||||
symbols.interopAllocObjCObject.owner,
|
||||
listOf(genGetObjCClass(constructedClass)),
|
||||
Lifetime.IRRELEVANT
|
||||
)
|
||||
|
||||
callDirect(symbols.interopInterpretObjCPointer.owner, listOf(rawPtr), resultLifetime(callee)).also {
|
||||
// Balance pointer retained by alloc:
|
||||
callDirect(symbols.interopObjCRelease.owner, listOf(rawPtr), Lifetime.IRRELEVANT)
|
||||
}
|
||||
}
|
||||
|
||||
else -> functionGenerationContext.allocInstance(constructedClass, resultLifetime(callee))
|
||||
}
|
||||
evaluateSimpleFunctionCall(callee.symbol.owner,
|
||||
listOf(thisValue) + args, Lifetime.IRRELEVANT /* constructor doesn't return anything */)
|
||||
@@ -2223,8 +2230,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun delegatingConstructorCall(
|
||||
constructor: IrConstructor, args: List<LLVMValueRef>): LLVMValueRef {
|
||||
private fun delegatingConstructorCall(constructor: IrConstructor, args: List<LLVMValueRef>): LLVMValueRef {
|
||||
|
||||
val constructedClass = functionGenerationContext.constructedClass!!
|
||||
val thisPtr = currentCodeContext.genGetValue(constructedClass.thisReceiver!!)
|
||||
|
||||
+8
-7
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.backend.konan.descriptors.target
|
||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -32,8 +33,7 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
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.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
@@ -131,6 +131,7 @@ private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTr
|
||||
private val IrFunctionAccessExpression.target: IrFunction get() = when (this) {
|
||||
is IrCall -> this.callTarget
|
||||
is IrDelegatingConstructorCall -> this.symbol.owner
|
||||
is IrConstructorCall -> this.symbol.owner
|
||||
else -> TODO(this.render())
|
||||
}
|
||||
|
||||
@@ -266,12 +267,12 @@ private class InlineClassTransformer(private val context: Context) : IrBuildingT
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
super.visitCall(expression)
|
||||
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||
super.visitConstructorCall(expression)
|
||||
|
||||
val function = expression.symbol.owner
|
||||
return if (function is IrConstructor && function.constructedClass.isInlined()) {
|
||||
builder.lowerConstructorCallToValue(expression, function)
|
||||
val constructor = expression.symbol.owner
|
||||
return if (constructor.constructedClass.isInlined()) {
|
||||
builder.lowerConstructorCallToValue(expression, constructor)
|
||||
} else {
|
||||
expression
|
||||
}
|
||||
|
||||
+2
-1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
@@ -171,7 +172,7 @@ internal class DeepCopyIrTreeWithSymbolsForInliner(val context: Context,
|
||||
classifier = symbolRemapper.getReferencedClassifier(type.classifier),
|
||||
hasQuestionMark = type.hasQuestionMark,
|
||||
arguments = remapTypeArguments(type.arguments),
|
||||
annotations = type.annotations.map { it.transform(copier, null) as IrCall }
|
||||
annotations = type.annotations.map { it.transform(copier, null) as IrConstructorCall }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -220,14 +220,14 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
.map {
|
||||
val initializer = it.initializerExpression
|
||||
val entryConstructorCall = when {
|
||||
initializer is IrCall -> initializer
|
||||
initializer is IrConstructorCall -> initializer
|
||||
|
||||
initializer is IrBlock && initializer.origin == ARGUMENTS_REORDERING_FOR_CALL ->
|
||||
initializer.statements.last() as IrCall
|
||||
initializer.statements.last() as IrConstructorCall
|
||||
|
||||
else -> error("Unexpected initializer: $initializer")
|
||||
}
|
||||
val entryClass = (entryConstructorCall.symbol.owner as IrConstructor).constructedClass
|
||||
val entryClass = entryConstructorCall.symbol.owner.constructedClass
|
||||
|
||||
irCall(startOffset, endOffset,
|
||||
createUninitializedInstance,
|
||||
@@ -265,7 +265,7 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
val startOffset = irClass.startOffset
|
||||
val endOffset = irClass.endOffset
|
||||
|
||||
fun IrBlockBuilder.initInstanceCall(instance: IrCall, constructor: IrCall): IrCall =
|
||||
fun IrBlockBuilder.initInstanceCall(instance: IrCall, constructor: IrConstructorCall): IrCall =
|
||||
irCall(initInstanceSymbol).apply {
|
||||
putValueArgument(0, instance)
|
||||
putValueArgument(1, constructor)
|
||||
@@ -288,11 +288,11 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
val initializer = it.value.initializerExpression!!
|
||||
initializer.patchDeclarationParents(constructor)
|
||||
when {
|
||||
initializer is IrCall -> +initInstanceCall(instance, initializer)
|
||||
initializer is IrConstructorCall -> +initInstanceCall(instance, initializer)
|
||||
|
||||
initializer is IrBlock && initializer.origin == ARGUMENTS_REORDERING_FOR_CALL -> {
|
||||
val statements = initializer.statements
|
||||
val constructorCall = statements.last() as IrCall
|
||||
val constructorCall = statements.last() as IrConstructorCall
|
||||
statements[statements.lastIndex] = initInstanceCall(instance, constructorCall)
|
||||
+initializer
|
||||
}
|
||||
|
||||
+3
-11
@@ -270,21 +270,13 @@ internal class EnumConstructorsLowering(val context: Context) : ClassLoweringPas
|
||||
}
|
||||
|
||||
private inner class InEnumEntryClassConstructor(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) {
|
||||
override fun createConstructorCall(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
loweredConstructor: IrConstructorSymbol
|
||||
) = IrDelegatingConstructorCallImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
context.irBuiltIns.unitType,
|
||||
loweredConstructor
|
||||
)
|
||||
override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: IrConstructorSymbol) =
|
||||
IrDelegatingConstructorCallImpl(startOffset, endOffset, context.irBuiltIns.unitType, loweredConstructor)
|
||||
}
|
||||
|
||||
private inner class InEnumEntryInitializer(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) {
|
||||
override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: IrConstructorSymbol) =
|
||||
IrCallImpl(startOffset, endOffset, loweredConstructor.owner.returnType, loweredConstructor)
|
||||
IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, loweredConstructor.owner.returnType, loweredConstructor)
|
||||
}
|
||||
|
||||
private inner class EnumClassBodyTransformer : IrElementTransformerVoid() {
|
||||
|
||||
+1
-7
@@ -32,13 +32,7 @@ import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
||||
internal class ExpectDeclarationsRemoving(val context: Context) : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
// All declarations with `isExpect == true` are nested into a top-level declaration with `isExpect == true`.
|
||||
irFile.declarations.removeAll {
|
||||
if (it.descriptor.isExpectMember) {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
irFile.declarations.removeAll { it.descriptor.isExpectMember }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+28
-21
@@ -36,19 +36,24 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
||||
|
||||
fun inline(irModule: IrModuleFragment) = irModule.accept(this, data = null)
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
val callSite = super.visitCall(expression) as IrCall
|
||||
if (!callSite.symbol.owner.needsInlining)
|
||||
return callSite
|
||||
if (Symbols.isLateinitIsInitializedPropertyGetter(callSite.symbol))
|
||||
return callSite
|
||||
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
val callee = when (expression) {
|
||||
is IrCall -> expression.symbol.owner
|
||||
is IrConstructorCall -> expression.symbol.owner
|
||||
else -> return expression
|
||||
}
|
||||
if (!callee.needsInlining)
|
||||
return expression
|
||||
if (Symbols.isLateinitIsInitializedPropertyGetter(callee.symbol))
|
||||
return expression
|
||||
|
||||
val callee = getFunctionDeclaration(callSite.symbol)
|
||||
val actualCallee = getFunctionDeclaration(callee.symbol)
|
||||
|
||||
callee.transformChildrenVoid(this) // Process recursive inline.
|
||||
actualCallee.transformChildrenVoid(this) // Process recursive inline.
|
||||
|
||||
val parent = allScopes.map { it.irElement }.filterIsInstance<IrDeclarationParent>().lastOrNull()
|
||||
val inliner = Inliner(callSite, callee, currentScope!!, parent, context)
|
||||
val inliner = Inliner(expression, actualCallee, currentScope!!, parent, context)
|
||||
return inliner.inline()
|
||||
}
|
||||
|
||||
@@ -76,7 +81,7 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
||||
|
||||
private val IrFunction.needsInlining get() = isInlineConstructor || (this.isInline && !this.isExternal)
|
||||
|
||||
private inner class Inliner(val callSite: IrCall,
|
||||
private inner class Inliner(val callSite: IrFunctionAccessExpression,
|
||||
val callee: IrFunction,
|
||||
val currentScope: ScopeWithIr,
|
||||
val parent: IrDeclarationParent?,
|
||||
@@ -109,7 +114,7 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
||||
}
|
||||
}
|
||||
|
||||
private fun inlineFunction(callSite: IrCall, callee: IrFunction): IrReturnableBlock {
|
||||
private fun inlineFunction(callSite: IrFunctionAccessExpression, callee: IrFunction): IrReturnableBlock {
|
||||
val copiedCallee = copyIrElement.copy(callee) as IrFunction
|
||||
|
||||
val evaluationStatements = evaluateArguments(callSite, copiedCallee)
|
||||
@@ -126,12 +131,13 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
||||
val constructedClass = callee.parentAsClass
|
||||
copiedCallee.parent = constructedClass
|
||||
val delegatingConstructorCall = statements[0] as IrDelegatingConstructorCall
|
||||
// TODO: Try use type parameters from callee.
|
||||
irBuilder.run {
|
||||
val constructorCall = IrCallImpl(
|
||||
val constructorCall = IrConstructorCallImpl(
|
||||
startOffset, endOffset,
|
||||
callSite.type,
|
||||
delegatingConstructorCall.symbol, delegatingConstructorCall.descriptor,
|
||||
constructedClass.typeParameters.size,
|
||||
constructedClass.typeParameters.size, 0,
|
||||
delegatingConstructorCall.symbol.owner.valueParameters.size
|
||||
).apply {
|
||||
delegatingConstructorCall.symbol.owner.valueParameters.forEach {
|
||||
@@ -216,11 +222,12 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
||||
val unboundArgsSet = unboundFunctionParameters.toSet()
|
||||
val valueParameters = expression.getArguments().drop(1) // Skip dispatch receiver.
|
||||
|
||||
val immediateCall = IrCallImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type,
|
||||
functionArgument.symbol, functionArgument.descriptor
|
||||
).apply {
|
||||
val immediateCall = with(expression) {
|
||||
if (function is IrConstructor)
|
||||
IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, type, function.symbol)
|
||||
else
|
||||
IrCallImpl(startOffset, endOffset, type, functionArgument.symbol)
|
||||
}.apply {
|
||||
functionParameters.forEach {
|
||||
val argument =
|
||||
if (!unboundArgsSet.contains(it))
|
||||
@@ -237,7 +244,7 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
||||
for (index in 0 until functionArgument.typeArgumentsCount)
|
||||
putTypeArgument(index, functionArgument.getTypeArgument(index))
|
||||
}
|
||||
return this@FunctionInlining.visitCall(super.visitCall(immediateCall) as IrCall)
|
||||
return this@FunctionInlining.visitExpression(super.visitExpression(immediateCall))
|
||||
}
|
||||
if (functionArgument !is IrBlock)
|
||||
return super.visitCall(expression)
|
||||
@@ -292,7 +299,7 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun buildParameterToArgument(callSite: IrCall, callee: IrFunction): List<ParameterToArgument> {
|
||||
private fun buildParameterToArgument(callSite: IrFunctionAccessExpression, callee: IrFunction): List<ParameterToArgument> {
|
||||
|
||||
val parameterToArgument = mutableListOf<ParameterToArgument>()
|
||||
|
||||
@@ -367,7 +374,7 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun evaluateArguments(callSite: IrCall, callee: IrFunction): List<IrStatement> {
|
||||
private fun evaluateArguments(callSite: IrFunctionAccessExpression, callee: IrFunction): List<IrStatement> {
|
||||
|
||||
val parameterToArgumentOld = buildParameterToArgument(callSite, callee)
|
||||
val evaluationStatements = mutableListOf<IrStatement>()
|
||||
|
||||
+31
-25
@@ -649,28 +649,31 @@ internal class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfo
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||
expression.transformChildrenVoid()
|
||||
|
||||
val descriptor = expression.descriptor.original
|
||||
val callee = expression.symbol.owner
|
||||
val initMethod = callee.getObjCInitMethod() ?: return expression
|
||||
|
||||
val arguments = descriptor.valueParameters.map { expression.getValueArgument(it) }
|
||||
assert(expression.extensionReceiver == null)
|
||||
assert(expression.dispatchReceiver == null)
|
||||
|
||||
val constructedClass = callee.constructedClass
|
||||
val initMethodInfo = initMethod.getExternalObjCMethodInfo()!!
|
||||
return builder.at(expression).run {
|
||||
val classPtr = getObjCClass(constructedClass.symbol)
|
||||
irForceNotNull(callAllocAndInit(classPtr, initMethodInfo, arguments, expression, initMethod))
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
expression.transformChildrenVoid()
|
||||
|
||||
val descriptor = expression.descriptor.original
|
||||
|
||||
val callee = expression.symbol.owner
|
||||
if (callee is IrConstructor) {
|
||||
val initMethod = callee.getObjCInitMethod()
|
||||
|
||||
if (initMethod != null) {
|
||||
val arguments = descriptor.valueParameters.map { expression.getValueArgument(it) }
|
||||
assert(expression.extensionReceiver == null)
|
||||
assert(expression.dispatchReceiver == null)
|
||||
|
||||
val constructedClass = callee.constructedClass
|
||||
val initMethodInfo = initMethod.getExternalObjCMethodInfo()!!
|
||||
return builder.at(expression).run {
|
||||
val classPtr = getObjCClass(constructedClass.symbol)
|
||||
irForceNotNull(callAllocAndInit(classPtr, initMethodInfo, arguments, expression, initMethod))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
descriptor.getObjCFactoryInitMethodInfo()?.let { initMethodInfo ->
|
||||
val arguments = (0 until expression.valueArgumentsCount)
|
||||
@@ -858,6 +861,17 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi
|
||||
private fun generateCFunctionPointer(function: IrSimpleFunction, expression: IrExpression): IrExpression =
|
||||
generateWithStubs { generateCFunctionPointer(function, function, expression) }
|
||||
|
||||
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val function = expression.symbol.owner
|
||||
val inlinedClass = function.returnType.getInlinedClassNative()
|
||||
if (inlinedClass?.descriptor == interop.cPointer || inlinedClass?.descriptor == interop.nativePointed) {
|
||||
throw Error("Native interop types constructors must not be called directly")
|
||||
}
|
||||
return expression
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
@@ -865,13 +879,6 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi
|
||||
val descriptor = expression.descriptor.original
|
||||
val function = expression.symbol.owner
|
||||
|
||||
if (function is IrConstructor) {
|
||||
val inlinedClass = function.returnType.getInlinedClassNative()
|
||||
if (inlinedClass?.descriptor == interop.cPointer || inlinedClass?.descriptor == interop.nativePointed) {
|
||||
throw Error("Native interop types constructors must not be called directly")
|
||||
}
|
||||
}
|
||||
|
||||
if (descriptor == interop.nativePointedRawPtrGetter ||
|
||||
OverridingUtil.overrides(descriptor, interop.nativePointedRawPtrGetter)) {
|
||||
|
||||
@@ -1029,8 +1036,7 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi
|
||||
val intrinsic = interop.objCObjectInitBy.name
|
||||
|
||||
val argument = expression.getValueArgument(0)!!
|
||||
val constructedClass =
|
||||
((argument as? IrCall)?.descriptor as? ClassConstructorDescriptor)?.constructedClass
|
||||
val constructedClass = (argument as? IrConstructorCall)?.symbol?.owner?.constructedClass?.descriptor
|
||||
|
||||
if (constructedClass == null) {
|
||||
context.reportCompilationError("Argument of '$intrinsic' must be a constructor call",
|
||||
|
||||
+1
-1
@@ -1068,7 +1068,7 @@ internal class SuspendFunctionsLowering(val context: Context): FileLoweringPass
|
||||
}
|
||||
}
|
||||
|
||||
fun IrBlockBodyBuilder.irSuccess(value: IrExpression): IrCall {
|
||||
fun IrBlockBodyBuilder.irSuccess(value: IrExpression): IrMemberAccessExpression {
|
||||
val createResult = symbols.kotlinResult.owner.constructors.single { it.isPrimary }
|
||||
return irCall(createResult).apply {
|
||||
putValueArgument(0, value)
|
||||
|
||||
+1
-6
@@ -87,12 +87,7 @@ internal class VarargInjectionLowering constructor(val context: KonanBackendCont
|
||||
expression.transformChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
replaceEmptyParameterWithEmptyArray(expression)
|
||||
return expression
|
||||
}
|
||||
|
||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
||||
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression {
|
||||
replaceEmptyParameterWithEmptyArray(expression)
|
||||
return expression
|
||||
}
|
||||
|
||||
+14
-8
@@ -557,6 +557,17 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
||||
else symbolTable.mapFunction(value.symbol.owner.constructors.single())
|
||||
)
|
||||
|
||||
is IrConstructorCall -> {
|
||||
val callee = value.symbol.owner
|
||||
val arguments = value.getArguments().map { expressionToEdge(it.second) }
|
||||
DataFlowIR.Node.NewObject(
|
||||
symbolTable.mapFunction(callee),
|
||||
arguments,
|
||||
symbolTable.mapClassReferenceType(callee.constructedClass, false),
|
||||
value
|
||||
)
|
||||
}
|
||||
|
||||
is IrCall -> when (value.symbol) {
|
||||
getContinuationSymbol -> getContinuation()
|
||||
|
||||
@@ -573,9 +584,9 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
||||
|
||||
initInstanceSymbol -> {
|
||||
val thiz = expressionToEdge(value.getValueArgument(0)!!)
|
||||
val initializer = value.getValueArgument(1) as IrCall
|
||||
val initializer = value.getValueArgument(1) as IrConstructorCall
|
||||
val arguments = listOf(thiz) + initializer.getArguments().map { expressionToEdge(it.second) }
|
||||
val callee = initializer.symbol.owner as IrConstructor
|
||||
val callee = initializer.symbol.owner
|
||||
DataFlowIR.Node.StaticCall(
|
||||
symbolTable.mapFunction(callee),
|
||||
arguments,
|
||||
@@ -595,12 +606,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
||||
it
|
||||
}
|
||||
if (callee is IrConstructor) {
|
||||
DataFlowIR.Node.NewObject(
|
||||
symbolTable.mapFunction(callee),
|
||||
arguments,
|
||||
symbolTable.mapClassReferenceType(callee.constructedClass, false),
|
||||
value
|
||||
)
|
||||
error("Constructor call should be done with IrConstructorCall")
|
||||
} else {
|
||||
callee as IrSimpleFunction
|
||||
if (callee.isOverridable && value.superQualifier == null) {
|
||||
|
||||
+3
-1
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetField
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
@@ -233,7 +234,8 @@ internal object DataFlowIR {
|
||||
: Call(callee, arguments, irCallSite)
|
||||
|
||||
// TODO: It can be replaced with a pair(AllocInstance, constructor Call), remove.
|
||||
class NewObject(constructor: FunctionSymbol, arguments: List<Edge>, val constructedType: Type, override val irCallSite: IrCall?)
|
||||
class NewObject(constructor: FunctionSymbol, arguments: List<Edge>, val constructedType: Type,
|
||||
override val irCallSite: IrConstructorCall?)
|
||||
: Call(constructor, arguments, irCallSite)
|
||||
|
||||
open class VirtualCall(callee: FunctionSymbol, arguments: List<Edge>,
|
||||
|
||||
+4
-6
@@ -491,12 +491,10 @@ private fun IrFunction.substitutedReturnType(typeArguments: List<IrType>): IrTyp
|
||||
|
||||
// TODO: this function must be avoided since it takes symbol's owner implicitly.
|
||||
fun IrBuilderWithScope.irCall(symbol: IrFunctionSymbol, typeArguments: List<IrType> = emptyList()) =
|
||||
irCall(symbol.owner, typeArguments)
|
||||
this.irCall(symbol, symbol.owner.substitutedReturnType(typeArguments), typeArguments)
|
||||
|
||||
fun IrBuilderWithScope.irCall(
|
||||
irFunction: IrFunction,
|
||||
typeArguments: List<IrType> = emptyList()
|
||||
): IrCall = irCall(this.startOffset, this.endOffset, irFunction, typeArguments)
|
||||
fun IrBuilderWithScope.irCall(irFunction: IrFunction, typeArguments: List<IrType> = emptyList()) =
|
||||
irCall(irFunction.symbol, typeArguments)
|
||||
|
||||
internal fun irCall(startOffset: Int, endOffset: Int, irFunction: IrFunction, typeArguments: List<IrType>): IrCall =
|
||||
IrCallImpl(
|
||||
@@ -512,7 +510,7 @@ fun IrBuilderWithScope.irCallOp(
|
||||
callee: IrFunction,
|
||||
dispatchReceiver: IrExpression,
|
||||
argument: IrExpression
|
||||
): IrCall =
|
||||
) =
|
||||
irCall(callee).apply {
|
||||
this.dispatchReceiver = dispatchReceiver
|
||||
putValueArgument(0, argument)
|
||||
|
||||
Reference in New Issue
Block a user