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)
|
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(
|
bridgeCallBuilder.build(
|
||||||
bridgeBuilder.buildKotlinBridge().also {
|
bridgeBuilder.buildKotlinBridge().also {
|
||||||
this.stubs.addKotlin(it)
|
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.declarations.impl.IrValueParameterImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
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.expressions.impl.IrTryImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||||
@@ -128,8 +130,9 @@ private fun createKotlinBridge(
|
|||||||
)
|
)
|
||||||
bridgeDescriptor.bind(bridge)
|
bridgeDescriptor.bind(bridge)
|
||||||
if (isExternal) {
|
if (isExternal) {
|
||||||
|
val constructor = symbols.filterExceptions.owner.constructors.single()
|
||||||
bridge.annotations +=
|
bridge.annotations +=
|
||||||
irCall(startOffset, endOffset, symbols.filterExceptions.owner.constructors.single(), emptyList())
|
IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, constructor.returnType, constructor.symbol)
|
||||||
}
|
}
|
||||||
return bridge
|
return bridge
|
||||||
}
|
}
|
||||||
@@ -185,7 +188,7 @@ internal class KotlinCallBuilder(private val irBuilder: IrBuilderWithScope, priv
|
|||||||
|
|
||||||
fun build(
|
fun build(
|
||||||
function: IrFunction,
|
function: IrFunction,
|
||||||
transformCall: (IrCall) -> IrExpression = { it }
|
transformCall: (IrMemberAccessExpression) -> IrExpression = { it }
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
val arguments = this.arguments.toMutableList()
|
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.common.ir.SharedVariablesManager
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanBackendContext
|
import org.jetbrains.kotlin.backend.konan.KonanBackendContext
|
||||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
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.IrSetVariable
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
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.expressions.impl.IrGetValueImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
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.types.typeWith
|
||||||
import org.jetbrains.kotlin.ir.util.constructors
|
import org.jetbrains.kotlin.ir.util.constructors
|
||||||
import org.jetbrains.kotlin.types.*
|
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 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 {
|
private fun refType(elementType: KotlinType): KotlinType {
|
||||||
return refClass.descriptor.defaultType.replace(listOf(TypeProjectionImpl(elementType)))
|
return refClass.descriptor.defaultType.replace(listOf(TypeProjectionImpl(elementType)))
|
||||||
}
|
}
|
||||||
@@ -66,10 +57,10 @@ internal class KonanSharedVariablesManager(val context: KonanBackendContext) : S
|
|||||||
|
|
||||||
val valueType = originalDeclaration.type
|
val valueType = originalDeclaration.type
|
||||||
|
|
||||||
val refConstructorCall = IrCallImpl(
|
val refConstructorCall = IrConstructorCallImpl.fromSymbolOwner(
|
||||||
originalDeclaration.startOffset, originalDeclaration.endOffset,
|
originalDeclaration.startOffset, originalDeclaration.endOffset,
|
||||||
refClass.typeWith(valueType),
|
refClass.typeWith(valueType),
|
||||||
refClassConstructor, refConstructor(valueType.toKotlinType()), 1
|
refClassConstructor
|
||||||
).apply {
|
).apply {
|
||||||
putTypeArgument(0, valueType)
|
putTypeArgument(0, valueType)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -97,7 +97,7 @@ class IrFileImpl(entry: SourceManager.FileEntry) : IrFile {
|
|||||||
|
|
||||||
override val metadata: MetadataSource.File?
|
override val metadata: MetadataSource.File?
|
||||||
get() = TODO("not implemented")
|
get() = TODO("not implemented")
|
||||||
override val annotations: MutableList<IrCall>
|
override val annotations: MutableList<IrConstructorCall>
|
||||||
get() = TODO("not implemented")
|
get() = TODO("not implemented")
|
||||||
override val fqName: FqName
|
override val fqName: FqName
|
||||||
get() = TODO("not implemented")
|
get() = TODO("not implemented")
|
||||||
|
|||||||
-7
@@ -92,13 +92,6 @@ val IrClass.isFinalClass: Boolean
|
|||||||
|
|
||||||
fun IrClass.isSpecialClassWithNoSupertypes() = this.isAny() || this.isNothing()
|
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? {
|
fun <T> IrDeclaration.getAnnotationArgumentValue(fqName: FqName, argumentName: String): T? {
|
||||||
val annotation = this.annotations.findAnnotation(fqName)
|
val annotation = this.annotations.findAnnotation(fqName)
|
||||||
if (annotation == null) {
|
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.backend.konan.reportCompilationError
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
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.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.types.getClass
|
import org.jetbrains.kotlin.ir.types.getClass
|
||||||
@@ -147,8 +146,8 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
}
|
}
|
||||||
IntrinsicType.OBJC_INIT_BY -> {
|
IntrinsicType.OBJC_INIT_BY -> {
|
||||||
val receiver = environment.evaluateExpression(callSite.extensionReceiver!!)
|
val receiver = environment.evaluateExpression(callSite.extensionReceiver!!)
|
||||||
val irConstructorCall = callSite.getValueArgument(0) as IrCall
|
val irConstructorCall = callSite.getValueArgument(0) as IrConstructorCall
|
||||||
val constructorDescriptor = irConstructorCall.symbol.owner as IrConstructor
|
val constructorDescriptor = irConstructorCall.symbol.owner
|
||||||
val constructorArgs = environment.evaluateExplicitArgs(irConstructorCall)
|
val constructorArgs = environment.evaluateExplicitArgs(irConstructorCall)
|
||||||
val args = listOf(receiver) + constructorArgs
|
val args = listOf(receiver) + constructorArgs
|
||||||
environment.evaluateCall(constructorDescriptor, args, Lifetime.IRRELEVANT)
|
environment.evaluateCall(constructorDescriptor, args, Lifetime.IRRELEVANT)
|
||||||
@@ -159,7 +158,7 @@ internal class IntrinsicGenerator(private val environment: IntrinsicGeneratorEnv
|
|||||||
environment.functionGenerationContext.genObjCSelector(selector)
|
environment.functionGenerationContext.genObjCSelector(selector)
|
||||||
}
|
}
|
||||||
IntrinsicType.INIT_INSTANCE -> {
|
IntrinsicType.INIT_INSTANCE -> {
|
||||||
val initializer = callSite.getValueArgument(1) as IrCall
|
val initializer = callSite.getValueArgument(1) as IrConstructorCall
|
||||||
val thiz = environment.evaluateExpression(callSite.getValueArgument(0)!!)
|
val thiz = environment.evaluateExpression(callSite.getValueArgument(0)!!)
|
||||||
environment.evaluateCall(
|
environment.evaluateCall(
|
||||||
initializer.symbol.owner,
|
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 IrCall -> return evaluateCall (value)
|
||||||
is IrDelegatingConstructorCall ->
|
is IrDelegatingConstructorCall ->
|
||||||
return evaluateCall (value)
|
return evaluateCall (value)
|
||||||
|
is IrConstructorCall -> return evaluateCall (value)
|
||||||
is IrInstanceInitializerCall ->
|
is IrInstanceInitializerCall ->
|
||||||
return evaluateInstanceInitializerCall(value)
|
return evaluateInstanceInitializerCall(value)
|
||||||
is IrGetValue -> return evaluateGetValue (value)
|
is IrGetValue -> return evaluateGetValue (value)
|
||||||
@@ -1751,6 +1752,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
updateBuilderDebugLocation(value)
|
updateBuilderDebugLocation(value)
|
||||||
return when (value) {
|
return when (value) {
|
||||||
is IrDelegatingConstructorCall -> delegatingConstructorCall(value.symbol.owner, args)
|
is IrDelegatingConstructorCall -> delegatingConstructorCall(value.symbol.owner, args)
|
||||||
|
is IrConstructorCall -> evaluateConstructorCall(value, args)
|
||||||
else -> evaluateFunctionCall(value as IrCall, args, resultLifetime(value))
|
else -> evaluateFunctionCall(value as IrCall, args, resultLifetime(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2016,7 +2018,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
return when {
|
return when {
|
||||||
function.isTypedIntrinsic -> intrinsicGenerator.evaluateCall(callee, args)
|
function.isTypedIntrinsic -> intrinsicGenerator.evaluateCall(callee, args)
|
||||||
function.symbol in context.irBuiltIns.irBuiltInsSymbols -> evaluateOperatorCall(callee, argsWithContinuationIfNeeded)
|
function.symbol in context.irBuiltIns.irBuiltInsSymbols -> evaluateOperatorCall(callee, argsWithContinuationIfNeeded)
|
||||||
function is IrConstructor -> evaluateConstructorCall(callee, argsWithContinuationIfNeeded)
|
|
||||||
else -> evaluateSimpleFunctionCall(function, argsWithContinuationIfNeeded, resultLifetime, callee.superQualifierSymbol?.owner)
|
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 }
|
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)}"}
|
context.log{"evaluateConstructorCall : ${ir2string(callee)}"}
|
||||||
return memScoped {
|
return memScoped {
|
||||||
val constructedClass = (callee.symbol as IrConstructorSymbol).owner.constructedClass
|
val constructedClass = callee.symbol.owner.constructedClass
|
||||||
val thisValue = if (constructedClass.isArray) {
|
val thisValue = when {
|
||||||
assert(args.isNotEmpty() && args[0].type == int32Type)
|
constructedClass.isArray -> {
|
||||||
functionGenerationContext.allocArray(codegen.typeInfoValue(constructedClass), args[0],
|
assert(args.isNotEmpty() && args[0].type == int32Type)
|
||||||
resultLifetime(callee), currentCodeContext.exceptionHandler)
|
functionGenerationContext.allocArray(codegen.typeInfoValue(constructedClass), args[0],
|
||||||
} else if (constructedClass == context.ir.symbols.string.owner) {
|
resultLifetime(callee), currentCodeContext.exceptionHandler)
|
||||||
// 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)
|
|
||||||
}
|
}
|
||||||
} 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,
|
evaluateSimpleFunctionCall(callee.symbol.owner,
|
||||||
listOf(thisValue) + args, Lifetime.IRRELEVANT /* constructor doesn't return anything */)
|
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(
|
private fun delegatingConstructorCall(constructor: IrConstructor, args: List<LLVMValueRef>): LLVMValueRef {
|
||||||
constructor: IrConstructor, args: List<LLVMValueRef>): LLVMValueRef {
|
|
||||||
|
|
||||||
val constructedClass = functionGenerationContext.constructedClass!!
|
val constructedClass = functionGenerationContext.constructedClass!!
|
||||||
val thisPtr = currentCodeContext.genGetValue(constructedClass.thisReceiver!!)
|
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.backend.konan.ir.*
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
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.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
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.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
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) {
|
private val IrFunctionAccessExpression.target: IrFunction get() = when (this) {
|
||||||
is IrCall -> this.callTarget
|
is IrCall -> this.callTarget
|
||||||
is IrDelegatingConstructorCall -> this.symbol.owner
|
is IrDelegatingConstructorCall -> this.symbol.owner
|
||||||
|
is IrConstructorCall -> this.symbol.owner
|
||||||
else -> TODO(this.render())
|
else -> TODO(this.render())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,12 +267,12 @@ private class InlineClassTransformer(private val context: Context) : IrBuildingT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||||
super.visitCall(expression)
|
super.visitConstructorCall(expression)
|
||||||
|
|
||||||
val function = expression.symbol.owner
|
val constructor = expression.symbol.owner
|
||||||
return if (function is IrConstructor && function.constructedClass.isInlined()) {
|
return if (constructor.constructedClass.isInlined()) {
|
||||||
builder.lowerConstructorCallToValue(expression, function)
|
builder.lowerConstructorCallToValue(expression, constructor)
|
||||||
} else {
|
} else {
|
||||||
expression
|
expression
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
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.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
@@ -171,7 +172,7 @@ internal class DeepCopyIrTreeWithSymbolsForInliner(val context: Context,
|
|||||||
classifier = symbolRemapper.getReferencedClassifier(type.classifier),
|
classifier = symbolRemapper.getReferencedClassifier(type.classifier),
|
||||||
hasQuestionMark = type.hasQuestionMark,
|
hasQuestionMark = type.hasQuestionMark,
|
||||||
arguments = remapTypeArguments(type.arguments),
|
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 {
|
.map {
|
||||||
val initializer = it.initializerExpression
|
val initializer = it.initializerExpression
|
||||||
val entryConstructorCall = when {
|
val entryConstructorCall = when {
|
||||||
initializer is IrCall -> initializer
|
initializer is IrConstructorCall -> initializer
|
||||||
|
|
||||||
initializer is IrBlock && initializer.origin == ARGUMENTS_REORDERING_FOR_CALL ->
|
initializer is IrBlock && initializer.origin == ARGUMENTS_REORDERING_FOR_CALL ->
|
||||||
initializer.statements.last() as IrCall
|
initializer.statements.last() as IrConstructorCall
|
||||||
|
|
||||||
else -> error("Unexpected initializer: $initializer")
|
else -> error("Unexpected initializer: $initializer")
|
||||||
}
|
}
|
||||||
val entryClass = (entryConstructorCall.symbol.owner as IrConstructor).constructedClass
|
val entryClass = entryConstructorCall.symbol.owner.constructedClass
|
||||||
|
|
||||||
irCall(startOffset, endOffset,
|
irCall(startOffset, endOffset,
|
||||||
createUninitializedInstance,
|
createUninitializedInstance,
|
||||||
@@ -265,7 +265,7 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
|||||||
val startOffset = irClass.startOffset
|
val startOffset = irClass.startOffset
|
||||||
val endOffset = irClass.endOffset
|
val endOffset = irClass.endOffset
|
||||||
|
|
||||||
fun IrBlockBuilder.initInstanceCall(instance: IrCall, constructor: IrCall): IrCall =
|
fun IrBlockBuilder.initInstanceCall(instance: IrCall, constructor: IrConstructorCall): IrCall =
|
||||||
irCall(initInstanceSymbol).apply {
|
irCall(initInstanceSymbol).apply {
|
||||||
putValueArgument(0, instance)
|
putValueArgument(0, instance)
|
||||||
putValueArgument(1, constructor)
|
putValueArgument(1, constructor)
|
||||||
@@ -288,11 +288,11 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
|||||||
val initializer = it.value.initializerExpression!!
|
val initializer = it.value.initializerExpression!!
|
||||||
initializer.patchDeclarationParents(constructor)
|
initializer.patchDeclarationParents(constructor)
|
||||||
when {
|
when {
|
||||||
initializer is IrCall -> +initInstanceCall(instance, initializer)
|
initializer is IrConstructorCall -> +initInstanceCall(instance, initializer)
|
||||||
|
|
||||||
initializer is IrBlock && initializer.origin == ARGUMENTS_REORDERING_FOR_CALL -> {
|
initializer is IrBlock && initializer.origin == ARGUMENTS_REORDERING_FOR_CALL -> {
|
||||||
val statements = initializer.statements
|
val statements = initializer.statements
|
||||||
val constructorCall = statements.last() as IrCall
|
val constructorCall = statements.last() as IrConstructorCall
|
||||||
statements[statements.lastIndex] = initInstanceCall(instance, constructorCall)
|
statements[statements.lastIndex] = initInstanceCall(instance, constructorCall)
|
||||||
+initializer
|
+initializer
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-11
@@ -270,21 +270,13 @@ internal class EnumConstructorsLowering(val context: Context) : ClassLoweringPas
|
|||||||
}
|
}
|
||||||
|
|
||||||
private inner class InEnumEntryClassConstructor(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) {
|
private inner class InEnumEntryClassConstructor(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) {
|
||||||
override fun createConstructorCall(
|
override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: IrConstructorSymbol) =
|
||||||
startOffset: Int,
|
IrDelegatingConstructorCallImpl(startOffset, endOffset, context.irBuiltIns.unitType, loweredConstructor)
|
||||||
endOffset: Int,
|
|
||||||
loweredConstructor: IrConstructorSymbol
|
|
||||||
) = IrDelegatingConstructorCallImpl(
|
|
||||||
startOffset,
|
|
||||||
endOffset,
|
|
||||||
context.irBuiltIns.unitType,
|
|
||||||
loweredConstructor
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class InEnumEntryInitializer(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) {
|
private inner class InEnumEntryInitializer(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) {
|
||||||
override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: IrConstructorSymbol) =
|
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() {
|
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 {
|
internal class ExpectDeclarationsRemoving(val context: Context) : FileLoweringPass {
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
// All declarations with `isExpect == true` are nested into a top-level declaration with `isExpect == true`.
|
// All declarations with `isExpect == true` are nested into a top-level declaration with `isExpect == true`.
|
||||||
irFile.declarations.removeAll {
|
irFile.declarations.removeAll { it.descriptor.isExpectMember }
|
||||||
if (it.descriptor.isExpectMember) {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+28
-21
@@ -36,19 +36,24 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
|||||||
|
|
||||||
fun inline(irModule: IrModuleFragment) = irModule.accept(this, data = null)
|
fun inline(irModule: IrModuleFragment) = irModule.accept(this, data = null)
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression {
|
||||||
val callSite = super.visitCall(expression) as IrCall
|
expression.transformChildrenVoid(this)
|
||||||
if (!callSite.symbol.owner.needsInlining)
|
val callee = when (expression) {
|
||||||
return callSite
|
is IrCall -> expression.symbol.owner
|
||||||
if (Symbols.isLateinitIsInitializedPropertyGetter(callSite.symbol))
|
is IrConstructorCall -> expression.symbol.owner
|
||||||
return callSite
|
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 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()
|
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 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 callee: IrFunction,
|
||||||
val currentScope: ScopeWithIr,
|
val currentScope: ScopeWithIr,
|
||||||
val parent: IrDeclarationParent?,
|
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 copiedCallee = copyIrElement.copy(callee) as IrFunction
|
||||||
|
|
||||||
val evaluationStatements = evaluateArguments(callSite, copiedCallee)
|
val evaluationStatements = evaluateArguments(callSite, copiedCallee)
|
||||||
@@ -126,12 +131,13 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
|||||||
val constructedClass = callee.parentAsClass
|
val constructedClass = callee.parentAsClass
|
||||||
copiedCallee.parent = constructedClass
|
copiedCallee.parent = constructedClass
|
||||||
val delegatingConstructorCall = statements[0] as IrDelegatingConstructorCall
|
val delegatingConstructorCall = statements[0] as IrDelegatingConstructorCall
|
||||||
|
// TODO: Try use type parameters from callee.
|
||||||
irBuilder.run {
|
irBuilder.run {
|
||||||
val constructorCall = IrCallImpl(
|
val constructorCall = IrConstructorCallImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
callSite.type,
|
callSite.type,
|
||||||
delegatingConstructorCall.symbol, delegatingConstructorCall.descriptor,
|
delegatingConstructorCall.symbol, delegatingConstructorCall.descriptor,
|
||||||
constructedClass.typeParameters.size,
|
constructedClass.typeParameters.size, 0,
|
||||||
delegatingConstructorCall.symbol.owner.valueParameters.size
|
delegatingConstructorCall.symbol.owner.valueParameters.size
|
||||||
).apply {
|
).apply {
|
||||||
delegatingConstructorCall.symbol.owner.valueParameters.forEach {
|
delegatingConstructorCall.symbol.owner.valueParameters.forEach {
|
||||||
@@ -216,11 +222,12 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
|||||||
val unboundArgsSet = unboundFunctionParameters.toSet()
|
val unboundArgsSet = unboundFunctionParameters.toSet()
|
||||||
val valueParameters = expression.getArguments().drop(1) // Skip dispatch receiver.
|
val valueParameters = expression.getArguments().drop(1) // Skip dispatch receiver.
|
||||||
|
|
||||||
val immediateCall = IrCallImpl(
|
val immediateCall = with(expression) {
|
||||||
expression.startOffset, expression.endOffset,
|
if (function is IrConstructor)
|
||||||
expression.type,
|
IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, type, function.symbol)
|
||||||
functionArgument.symbol, functionArgument.descriptor
|
else
|
||||||
).apply {
|
IrCallImpl(startOffset, endOffset, type, functionArgument.symbol)
|
||||||
|
}.apply {
|
||||||
functionParameters.forEach {
|
functionParameters.forEach {
|
||||||
val argument =
|
val argument =
|
||||||
if (!unboundArgsSet.contains(it))
|
if (!unboundArgsSet.contains(it))
|
||||||
@@ -237,7 +244,7 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
|
|||||||
for (index in 0 until functionArgument.typeArgumentsCount)
|
for (index in 0 until functionArgument.typeArgumentsCount)
|
||||||
putTypeArgument(index, functionArgument.getTypeArgument(index))
|
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)
|
if (functionArgument !is IrBlock)
|
||||||
return super.visitCall(expression)
|
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>()
|
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 parameterToArgumentOld = buildParameterToArgument(callSite, callee)
|
||||||
val evaluationStatements = mutableListOf<IrStatement>()
|
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 {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
expression.transformChildrenVoid()
|
expression.transformChildrenVoid()
|
||||||
|
|
||||||
val descriptor = expression.descriptor.original
|
val descriptor = expression.descriptor.original
|
||||||
|
|
||||||
val callee = expression.symbol.owner
|
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 ->
|
descriptor.getObjCFactoryInitMethodInfo()?.let { initMethodInfo ->
|
||||||
val arguments = (0 until expression.valueArgumentsCount)
|
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 =
|
private fun generateCFunctionPointer(function: IrSimpleFunction, expression: IrExpression): IrExpression =
|
||||||
generateWithStubs { generateCFunctionPointer(function, function, expression) }
|
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 {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
@@ -865,13 +879,6 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi
|
|||||||
val descriptor = expression.descriptor.original
|
val descriptor = expression.descriptor.original
|
||||||
val function = expression.symbol.owner
|
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 ||
|
if (descriptor == interop.nativePointedRawPtrGetter ||
|
||||||
OverridingUtil.overrides(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 intrinsic = interop.objCObjectInitBy.name
|
||||||
|
|
||||||
val argument = expression.getValueArgument(0)!!
|
val argument = expression.getValueArgument(0)!!
|
||||||
val constructedClass =
|
val constructedClass = (argument as? IrConstructorCall)?.symbol?.owner?.constructedClass?.descriptor
|
||||||
((argument as? IrCall)?.descriptor as? ClassConstructorDescriptor)?.constructedClass
|
|
||||||
|
|
||||||
if (constructedClass == null) {
|
if (constructedClass == null) {
|
||||||
context.reportCompilationError("Argument of '$intrinsic' must be a constructor call",
|
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 }
|
val createResult = symbols.kotlinResult.owner.constructors.single { it.isPrimary }
|
||||||
return irCall(createResult).apply {
|
return irCall(createResult).apply {
|
||||||
putValueArgument(0, value)
|
putValueArgument(0, value)
|
||||||
|
|||||||
+1
-6
@@ -87,12 +87,7 @@ internal class VarargInjectionLowering constructor(val context: KonanBackendCont
|
|||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression {
|
||||||
replaceEmptyParameterWithEmptyArray(expression)
|
|
||||||
return expression
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
|
||||||
replaceEmptyParameterWithEmptyArray(expression)
|
replaceEmptyParameterWithEmptyArray(expression)
|
||||||
return 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())
|
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) {
|
is IrCall -> when (value.symbol) {
|
||||||
getContinuationSymbol -> getContinuation()
|
getContinuationSymbol -> getContinuation()
|
||||||
|
|
||||||
@@ -573,9 +584,9 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
|
|
||||||
initInstanceSymbol -> {
|
initInstanceSymbol -> {
|
||||||
val thiz = expressionToEdge(value.getValueArgument(0)!!)
|
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 arguments = listOf(thiz) + initializer.getArguments().map { expressionToEdge(it.second) }
|
||||||
val callee = initializer.symbol.owner as IrConstructor
|
val callee = initializer.symbol.owner
|
||||||
DataFlowIR.Node.StaticCall(
|
DataFlowIR.Node.StaticCall(
|
||||||
symbolTable.mapFunction(callee),
|
symbolTable.mapFunction(callee),
|
||||||
arguments,
|
arguments,
|
||||||
@@ -595,12 +606,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
it
|
it
|
||||||
}
|
}
|
||||||
if (callee is IrConstructor) {
|
if (callee is IrConstructor) {
|
||||||
DataFlowIR.Node.NewObject(
|
error("Constructor call should be done with IrConstructorCall")
|
||||||
symbolTable.mapFunction(callee),
|
|
||||||
arguments,
|
|
||||||
symbolTable.mapClassReferenceType(callee.constructedClass, false),
|
|
||||||
value
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
callee as IrSimpleFunction
|
callee as IrSimpleFunction
|
||||||
if (callee.isOverridable && value.superQualifier == null) {
|
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.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
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.IrFunctionAccessExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrGetField
|
import org.jetbrains.kotlin.ir.expressions.IrGetField
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
@@ -233,7 +234,8 @@ internal object DataFlowIR {
|
|||||||
: Call(callee, arguments, irCallSite)
|
: Call(callee, arguments, irCallSite)
|
||||||
|
|
||||||
// TODO: It can be replaced with a pair(AllocInstance, constructor Call), remove.
|
// 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)
|
: Call(constructor, arguments, irCallSite)
|
||||||
|
|
||||||
open class VirtualCall(callee: FunctionSymbol, arguments: List<Edge>,
|
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.
|
// TODO: this function must be avoided since it takes symbol's owner implicitly.
|
||||||
fun IrBuilderWithScope.irCall(symbol: IrFunctionSymbol, typeArguments: List<IrType> = emptyList()) =
|
fun IrBuilderWithScope.irCall(symbol: IrFunctionSymbol, typeArguments: List<IrType> = emptyList()) =
|
||||||
irCall(symbol.owner, typeArguments)
|
this.irCall(symbol, symbol.owner.substitutedReturnType(typeArguments), typeArguments)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irCall(
|
fun IrBuilderWithScope.irCall(irFunction: IrFunction, typeArguments: List<IrType> = emptyList()) =
|
||||||
irFunction: IrFunction,
|
irCall(irFunction.symbol, typeArguments)
|
||||||
typeArguments: List<IrType> = emptyList()
|
|
||||||
): IrCall = irCall(this.startOffset, this.endOffset, irFunction, typeArguments)
|
|
||||||
|
|
||||||
internal fun irCall(startOffset: Int, endOffset: Int, irFunction: IrFunction, typeArguments: List<IrType>): IrCall =
|
internal fun irCall(startOffset: Int, endOffset: Int, irFunction: IrFunction, typeArguments: List<IrType>): IrCall =
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
@@ -512,7 +510,7 @@ fun IrBuilderWithScope.irCallOp(
|
|||||||
callee: IrFunction,
|
callee: IrFunction,
|
||||||
dispatchReceiver: IrExpression,
|
dispatchReceiver: IrExpression,
|
||||||
argument: IrExpression
|
argument: IrExpression
|
||||||
): IrCall =
|
) =
|
||||||
irCall(callee).apply {
|
irCall(callee).apply {
|
||||||
this.dispatchReceiver = dispatchReceiver
|
this.dispatchReceiver = dispatchReceiver
|
||||||
putValueArgument(0, argument)
|
putValueArgument(0, argument)
|
||||||
|
|||||||
Reference in New Issue
Block a user