IR: use buildFun where possible

This commit is contained in:
Alexander Udalov
2020-07-08 15:03:16 +02:00
parent 39e38c7049
commit 6aa09f61d4
14 changed files with 308 additions and 437 deletions
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildReceiverParameter import org.jetbrains.kotlin.ir.builders.declarations.buildReceiverParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildTypeParameter import org.jetbrains.kotlin.ir.builders.declarations.buildTypeParameter
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
@@ -486,25 +487,20 @@ fun IrClass.addFakeOverridesViaIncorrectHeuristic(implementedMembers: List<IrSim
fun createFakeOverride(overriddenFunctions: List<IrSimpleFunction>) = fun createFakeOverride(overriddenFunctions: List<IrSimpleFunction>) =
overriddenFunctions.first().let { irFunction -> overriddenFunctions.first().let { irFunction ->
val descriptor = WrappedSimpleFunctionDescriptor() buildFun {
IrFunctionImpl( origin = IrDeclarationOrigin.FAKE_OVERRIDE
UNDEFINED_OFFSET, name = irFunction.name
UNDEFINED_OFFSET, visibility = Visibilities.PUBLIC
IrDeclarationOrigin.FAKE_OVERRIDE, modality = irFunction.modality
IrSimpleFunctionSymbolImpl(descriptor), returnType = irFunction.returnType
irFunction.name, isInline = irFunction.isInline
Visibilities.PUBLIC, isExternal = irFunction.isExternal
irFunction.modality, isTailrec = irFunction.isTailrec
irFunction.returnType, isSuspend = irFunction.isSuspend
isInline = irFunction.isInline,
isExternal = irFunction.isExternal,
isTailrec = irFunction.isTailrec,
isSuspend = irFunction.isSuspend,
isExpect = irFunction.isExpect,
isFakeOverride = true,
isOperator = irFunction.isOperator isOperator = irFunction.isOperator
).apply { isExpect = irFunction.isExpect
descriptor.bind(this) isFakeOverride = true
}.apply {
parent = this@addFakeOverridesViaIncorrectHeuristic parent = this@addFakeOverridesViaIncorrectHeuristic
overriddenSymbols = overriddenFunctions.map { it.symbol } overriddenSymbols = overriddenFunctions.map { it.symbol }
copyParameterDeclarationsFrom(irFunction) copyParameterDeclarationsFrom(irFunction)
@@ -10,18 +10,17 @@ import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
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.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedFieldDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedFieldDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
@@ -29,7 +28,6 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl 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.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.defaultType
@@ -472,65 +470,54 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
unboundArgs: List<IrValueParameter>, unboundArgs: List<IrValueParameter>,
superFunctionSymbol: IrSimpleFunctionSymbol?, superFunctionSymbol: IrSimpleFunctionSymbol?,
coroutineConstructor: IrConstructor coroutineConstructor: IrConstructor
) = WrappedSimpleFunctionDescriptor().let { d -> ): IrSimpleFunction = buildFun {
IrFunctionImpl( startOffset = irFunction.startOffset
startOffset, endOffset, endOffset = irFunction.endOffset
DECLARATION_ORIGIN_COROUTINE_IMPL, origin = DECLARATION_ORIGIN_COROUTINE_IMPL
IrSimpleFunctionSymbolImpl(d), name = Name.identifier("create")
Name.identifier("create"), visibility = Visibilities.PROTECTED
Visibilities.PROTECTED, returnType = coroutineClass.defaultType
Modality.FINAL, }.apply {
coroutineClass.defaultType, parent = coroutineClass
isInline = false, coroutineClass.declarations += this
isExternal = false,
isTailrec = false,
isSuspend = false,
isExpect = false,
isFakeOverride = false,
isOperator = false
).apply {
d.bind(this)
parent = coroutineClass
coroutineClass.declarations += this
typeParameters = irFunction.typeParameters.map { parameter -> typeParameters = irFunction.typeParameters.map { parameter ->
parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL) parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL)
.apply { superTypes += parameter.superTypes } .apply { superTypes += parameter.superTypes }
} }
valueParameters = (unboundArgs + create1CompletionParameter).mapIndexed { index, parameter -> valueParameters = (unboundArgs + create1CompletionParameter).mapIndexed { index, parameter ->
parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index) parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index)
} }
this.createDispatchReceiverParameter() this.createDispatchReceiverParameter()
superFunctionSymbol?.let { superFunctionSymbol?.let {
overriddenSymbols += it.owner.overriddenSymbols overriddenSymbols += it.owner.overriddenSymbols
overriddenSymbols += it overriddenSymbols += it
} }
val thisReceiver = this.dispatchReceiverParameter!! val thisReceiver = this.dispatchReceiverParameter!!
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset) val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
body = irBuilder.irBlockBody(startOffset, endOffset) { body = irBuilder.irBlockBody(startOffset, endOffset) {
+irReturn( +irReturn(
irCall(coroutineConstructor).apply { irCall(coroutineConstructor).apply {
var unboundIndex = 0 var unboundIndex = 0
val unboundArgsSet = unboundArgs.toSet() val unboundArgsSet = unboundArgs.toSet()
functionParameters.map { functionParameters.map {
if (unboundArgsSet.contains(it)) if (unboundArgsSet.contains(it))
irGet(valueParameters[unboundIndex++]) irGet(valueParameters[unboundIndex++])
else else
irGetField(irGet(thisReceiver), argumentToPropertiesMap.getValue(it)) irGetField(irGet(thisReceiver), argumentToPropertiesMap.getValue(it))
}.forEachIndexed { index, argument -> }.forEachIndexed { index, argument ->
putValueArgument(index, argument) putValueArgument(index, argument)
} }
putValueArgument(functionParameters.size, irGet(valueParameters[unboundIndex])) putValueArgument(functionParameters.size, irGet(valueParameters[unboundIndex]))
assert(unboundIndex == valueParameters.size - 1) { assert(unboundIndex == valueParameters.size - 1) {
"Not all arguments of <create> are used" "Not all arguments of <create> are used"
} }
}) })
}
} }
} }
@@ -539,59 +526,49 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
functionInvokeFunctionSymbol: IrSimpleFunctionSymbol, functionInvokeFunctionSymbol: IrSimpleFunctionSymbol,
createFunction: IrFunction, createFunction: IrFunction,
stateMachineFunction: IrFunction stateMachineFunction: IrFunction
) = WrappedSimpleFunctionDescriptor().let { d -> ): IrSimpleFunction = buildFun {
IrFunctionImpl( startOffset = irFunction.startOffset
startOffset, endOffset, endOffset = irFunction.endOffset
DECLARATION_ORIGIN_COROUTINE_IMPL, origin = DECLARATION_ORIGIN_COROUTINE_IMPL
IrSimpleFunctionSymbolImpl(d), name = Name.identifier("invoke")
Name.identifier("invoke"), visibility = Visibilities.PROTECTED
Visibilities.PROTECTED, returnType = context.irBuiltIns.anyNType
Modality.FINAL, isSuspend = true
context.irBuiltIns.anyNType, }.apply {
isInline = false, parent = coroutineClass
isExternal = false, coroutineClass.declarations += this
isTailrec = false,
isSuspend = true,
isExpect = false,
isFakeOverride = false,
isOperator = false
).apply {
d.bind(this)
parent = coroutineClass
coroutineClass.declarations += this
typeParameters = irFunction.typeParameters.map { parameter -> typeParameters = irFunction.typeParameters.map { parameter ->
parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL) parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL)
.apply { superTypes += parameter.superTypes } .apply { superTypes += parameter.superTypes }
}
valueParameters = createFunction.valueParameters
// Skip completion - invoke() already has it implicitly as a suspend function.
.take(createFunction.valueParameters.size - 1)
.mapIndexed { index, parameter ->
parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index)
} }
valueParameters = createFunction.valueParameters this.createDispatchReceiverParameter()
// Skip completion - invoke() already has it implicitly as a suspend function.
.take(createFunction.valueParameters.size - 1) overriddenSymbols += functionInvokeFunctionSymbol
.mapIndexed { index, parameter -> overriddenSymbols += suspendFunctionInvokeFunctionSymbol
parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index)
val thisReceiver = dispatchReceiverParameter!!
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
body = irBuilder.irBlockBody(startOffset, endOffset) {
generateCoroutineStart(stateMachineFunction, irCall(createFunction).apply {
dispatchReceiver = irGet(thisReceiver)
valueParameters.forEachIndexed { index, parameter ->
putValueArgument(index, irGet(parameter))
} }
putValueArgument(
this.createDispatchReceiverParameter() valueParameters.size,
irCall(getContinuationSymbol, getContinuationSymbol.owner.returnType, listOf(returnType))
overriddenSymbols += functionInvokeFunctionSymbol )
overriddenSymbols += suspendFunctionInvokeFunctionSymbol })
val thisReceiver = dispatchReceiverParameter!!
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
body = irBuilder.irBlockBody(startOffset, endOffset) {
generateCoroutineStart(stateMachineFunction, irCall(createFunction).apply {
dispatchReceiver = irGet(thisReceiver)
valueParameters.forEachIndexed { index, parameter ->
putValueArgument(index, irGet(parameter))
}
putValueArgument(
valueParameters.size,
irCall(getContinuationSymbol, getContinuationSymbol.owner.returnType, listOf(returnType))
)
})
}
} }
} }
@@ -599,40 +576,36 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
stateMachineFunction: IrSimpleFunction, stateMachineFunction: IrSimpleFunction,
coroutineClass: IrClass coroutineClass: IrClass
): IrSimpleFunction { ): IrSimpleFunction {
val function = WrappedSimpleFunctionDescriptor().let { d -> val function = buildFun {
IrFunctionImpl( startOffset = irFunction.startOffset
startOffset, endOffset, endOffset = irFunction.endOffset
DECLARATION_ORIGIN_COROUTINE_IMPL, origin = DECLARATION_ORIGIN_COROUTINE_IMPL
IrSimpleFunctionSymbolImpl(d), name = stateMachineFunction.name
stateMachineFunction.name, visibility = stateMachineFunction.visibility
stateMachineFunction.visibility, returnType = context.irBuiltIns.anyNType
Modality.FINAL, isInline = stateMachineFunction.isInline
context.irBuiltIns.anyNType, isExternal = stateMachineFunction.isExternal
isInline = stateMachineFunction.isInline, isTailrec = stateMachineFunction.isTailrec
isExternal = stateMachineFunction.isExternal, isSuspend = stateMachineFunction.isSuspend
isTailrec = stateMachineFunction.isTailrec, isOperator = false
isSuspend = stateMachineFunction.isSuspend, isExpect = stateMachineFunction.isExpect
isExpect = stateMachineFunction.isExpect, isFakeOverride = false
isFakeOverride = false, }.apply {
isOperator = false parent = coroutineClass
).apply { coroutineClass.declarations += this
d.bind(this)
parent = coroutineClass
coroutineClass.declarations += this
typeParameters = stateMachineFunction.typeParameters.map { parameter -> typeParameters = stateMachineFunction.typeParameters.map { parameter ->
parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL) parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL)
.apply { superTypes += parameter.superTypes } .apply { superTypes += parameter.superTypes }
}
valueParameters = stateMachineFunction.valueParameters.mapIndexed { index, parameter ->
parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index)
}
this.createDispatchReceiverParameter()
overriddenSymbols += stateMachineFunction.symbol
} }
valueParameters = stateMachineFunction.valueParameters.mapIndexed { index, parameter ->
parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index)
}
this.createDispatchReceiverParameter()
overriddenSymbols += stateMachineFunction.symbol
} }
buildStateMachine(function, irFunction, argumentToPropertiesMap) buildStateMachine(function, irFunction, argumentToPropertiesMap)
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
import org.jetbrains.kotlin.ir.builders.declarations.buildFunWithDescriptorForInlining import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
@@ -514,7 +514,7 @@ private fun IrFunction.generateDefaultsFunctionImpl(
visibility = newVisibility visibility = newVisibility
} }
is IrSimpleFunction -> is IrSimpleFunction ->
buildFunWithDescriptorForInlining(descriptor) { buildFun(descriptor) {
updateFrom(this@generateDefaultsFunctionImpl) updateFrom(this@generateDefaultsFunctionImpl)
name = Name.identifier("${this@generateDefaultsFunctionImpl.name}\$default") name = Name.identifier("${this@generateDefaultsFunctionImpl.name}\$default")
origin = newOrigin origin = newOrigin
@@ -17,14 +17,13 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedFieldDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedFieldDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
@@ -32,11 +31,9 @@ import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
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
import org.jetbrains.kotlin.ir.types.impl.IrTypeAbbreviationImpl import org.jetbrains.kotlin.ir.types.impl.IrTypeAbbreviationImpl
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.constructedClass import org.jetbrains.kotlin.ir.util.constructedClass
import org.jetbrains.kotlin.ir.util.file import org.jetbrains.kotlin.ir.util.file
@@ -587,38 +584,22 @@ class LocalDeclarationsLowering(
private fun createLiftedDeclaration(localFunctionContext: LocalFunctionContext) { private fun createLiftedDeclaration(localFunctionContext: LocalFunctionContext) {
val oldDeclaration = localFunctionContext.declaration val oldDeclaration = localFunctionContext.declaration
assert(oldDeclaration.dispatchReceiverParameter == null)
val memberOwner = localFunctionContext.ownerForLoweredDeclaration
val newDescriptor = WrappedSimpleFunctionDescriptor(oldDeclaration.descriptor)
val newSymbol = IrSimpleFunctionSymbolImpl(newDescriptor)
val newName = generateNameForLiftedDeclaration(oldDeclaration, memberOwner)
if (oldDeclaration.dispatchReceiverParameter != null) { if (oldDeclaration.dispatchReceiverParameter != null) {
throw AssertionError("local functions must not have dispatch receiver") throw AssertionError("local functions must not have dispatch receiver")
} }
val memberOwner = localFunctionContext.ownerForLoweredDeclaration
val newName = generateNameForLiftedDeclaration(oldDeclaration, memberOwner)
// TODO: consider using fields to access the closure of enclosing class. // TODO: consider using fields to access the closure of enclosing class.
val (capturedValues, capturedTypeParameters) = localFunctionContext.closure val (capturedValues, capturedTypeParameters) = localFunctionContext.closure
val newDeclaration = IrFunctionImpl( val newDeclaration = buildFun(oldDeclaration.descriptor) {
oldDeclaration.startOffset, updateFrom(oldDeclaration)
oldDeclaration.endOffset, name = newName
oldDeclaration.origin, visibility = Visibilities.PRIVATE
newSymbol, modality = Modality.FINAL
newName, }
Visibilities.PRIVATE,
Modality.FINAL,
returnType = IrUninitializedType,
isInline = oldDeclaration.isInline,
isExternal = oldDeclaration.isExternal,
isTailrec = oldDeclaration.isTailrec,
isSuspend = oldDeclaration.isSuspend,
isExpect = oldDeclaration.isExpect,
isFakeOverride = oldDeclaration.isFakeOverride,
isOperator = oldDeclaration.isOperator
)
newDescriptor.bind(newDeclaration)
localFunctionContext.transformedDeclaration = newDeclaration localFunctionContext.transformedDeclaration = newDeclaration
@@ -105,7 +105,7 @@ inline fun IrProperty.addGetter(builder: IrFunctionBuilder.() -> Unit = {}): IrS
IrFunctionBuilder().run { IrFunctionBuilder().run {
name = Name.special("<get-${this@addGetter.name}>") name = Name.special("<get-${this@addGetter.name}>")
builder() builder()
buildFun().also { getter -> buildFunction().also { getter ->
this@addGetter.getter = getter this@addGetter.getter = getter
getter.correspondingPropertySymbol = this@addGetter.symbol getter.correspondingPropertySymbol = this@addGetter.symbol
getter.parent = this@addGetter.parent getter.parent = this@addGetter.parent
@@ -116,13 +116,16 @@ inline fun IrProperty.addSetter(builder: IrFunctionBuilder.() -> Unit = {}): IrS
IrFunctionBuilder().run { IrFunctionBuilder().run {
name = Name.special("<set-${this@addSetter.name}>") name = Name.special("<set-${this@addSetter.name}>")
builder() builder()
buildFun().also { setter -> buildFunction().also { setter ->
this@addSetter.setter = setter this@addSetter.setter = setter
setter.parent = this@addSetter.parent setter.parent = this@addSetter.parent
} }
} }
fun IrFunctionBuilder.buildFun(originalDescriptor: FunctionDescriptor? = null): IrSimpleFunction { @PublishedApi
internal fun IrFunctionBuilder.buildFunction(originalDescriptor: FunctionDescriptor? = null): IrSimpleFunction {
// Inlining relies on descriptors for external declarations. When replacing a potentially external function (e.g. in an IrCall),
// we have to ensure that we keep information from the original descriptor so as not to break inlining.
val wrappedDescriptor = when (originalDescriptor) { val wrappedDescriptor = when (originalDescriptor) {
is DescriptorWithContainerSource -> WrappedFunctionDescriptorWithContainerSource(originalDescriptor.containerSource) is DescriptorWithContainerSource -> WrappedFunctionDescriptorWithContainerSource(originalDescriptor.containerSource)
is PropertyGetterDescriptor -> WrappedPropertyGetterDescriptor(originalDescriptor.annotations, originalDescriptor.source) is PropertyGetterDescriptor -> WrappedPropertyGetterDescriptor(originalDescriptor.annotations, originalDescriptor.source)
@@ -134,8 +137,7 @@ fun IrFunctionBuilder.buildFun(originalDescriptor: FunctionDescriptor? = null):
startOffset, endOffset, origin, startOffset, endOffset, origin,
IrSimpleFunctionSymbolImpl(wrappedDescriptor), IrSimpleFunctionSymbolImpl(wrappedDescriptor),
name, visibility, modality, returnType, name, visibility, modality, returnType,
isInline = isInline, isExternal = isExternal, isTailrec = isTailrec, isSuspend = isSuspend, isExpect = isExpect, isInline, isExternal, isTailrec, isSuspend, isOperator, isExpect, isFakeOverride
isFakeOverride = isFakeOverride, isOperator = isOperator
).also { ).also {
wrappedDescriptor.bind(it) wrappedDescriptor.bind(it)
} }
@@ -154,27 +156,14 @@ fun IrFunctionBuilder.buildConstructor(): IrConstructor {
} }
} }
/** inline fun buildFun(originalDescriptor: FunctionDescriptor? = null, builder: IrFunctionBuilder.() -> Unit): IrSimpleFunction =
* Inlining relies on descriptors for external declarations. When replacing a
* potentially external function (e.g. in an IrCall) we have to ensure that we keep
* information from the original descriptor so as not to break inlining.
*/
inline fun buildFunWithDescriptorForInlining(
originalDescriptor: FunctionDescriptor, builder: IrFunctionBuilder.() -> Unit
): IrSimpleFunction =
IrFunctionBuilder().run { IrFunctionBuilder().run {
builder() builder()
buildFun(originalDescriptor) buildFunction(originalDescriptor)
}
inline fun buildFun(builder: IrFunctionBuilder.() -> Unit): IrSimpleFunction =
IrFunctionBuilder().run {
builder()
buildFun()
} }
inline fun IrDeclarationContainer.addFunction(builder: IrFunctionBuilder.() -> Unit): IrSimpleFunction = inline fun IrDeclarationContainer.addFunction(builder: IrFunctionBuilder.() -> Unit): IrSimpleFunction =
buildFun(builder).also { function -> buildFun(null, builder).also { function ->
declarations.add(function) declarations.add(function)
function.parent = this@addFunction function.parent = this@addFunction
} }
@@ -10,18 +10,16 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildVariable import org.jetbrains.kotlin.ir.builders.declarations.buildVariable
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
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.name.Name import org.jetbrains.kotlin.name.Name
@@ -103,28 +101,21 @@ object JsIrBuilder {
isOperator: Boolean = false, isOperator: Boolean = false,
isFakeOverride: Boolean = false, isFakeOverride: Boolean = false,
origin: IrDeclarationOrigin = SYNTHESIZED_DECLARATION origin: IrDeclarationOrigin = SYNTHESIZED_DECLARATION
): IrSimpleFunction { ): IrSimpleFunction = buildFun {
val descriptor = WrappedSimpleFunctionDescriptor() this.origin = origin
return IrFunctionImpl( this.name = name
UNDEFINED_OFFSET, this.visibility = visibility
UNDEFINED_OFFSET, this.modality = modality
origin, this.returnType = returnType
IrSimpleFunctionSymbolImpl(descriptor), this.isInline = isInline
name, this.isExternal = isExternal
visibility, this.isTailrec = isTailrec
modality, this.isSuspend = isSuspend
returnType, this.isOperator = isOperator
isInline = isInline, this.isExpect = isExpect
isExternal = isExternal, this.isFakeOverride = isFakeOverride
isTailrec = isTailrec, }.also {
isSuspend = isSuspend, it.parent = parent
isExpect = isExpect,
isFakeOverride = isFakeOverride,
isOperator = isOperator
).also {
descriptor.bind(it)
it.parent = parent
}
} }
fun buildAnonymousInitializer() = fun buildAnonymousInitializer() =
@@ -7,13 +7,11 @@ package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
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.IrSetField import org.jetbrains.kotlin.ir.expressions.IrSetField
@@ -21,7 +19,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
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.transformFlat import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -88,22 +85,18 @@ class CreateScriptFunctionsPhase(val context: CommonBackendContext) : FileLoweri
return (irScript.statements.lastOrNull() as? IrExpression)?.type ?: context.irBuiltIns.unitType return (irScript.statements.lastOrNull() as? IrExpression)?.type ?: context.irBuiltIns.unitType
} }
private fun createFunction(irScript: IrScript, name: String, returnType: IrType): IrSimpleFunction { private fun createFunction(irScript: IrScript, name: String, returnType: IrType): IrSimpleFunction =
val (startOffset, endOffset) = getFunctionBodyOffsets(irScript) buildFun {
val descriptor = WrappedSimpleFunctionDescriptor() val (startOffset, endOffset) = getFunctionBodyOffsets(irScript)
this.startOffset = startOffset
return IrFunctionImpl( this.endOffset = endOffset
startOffset, endOffset, SCRIPT_FUNCTION, this.origin = SCRIPT_FUNCTION
IrSimpleFunctionSymbolImpl(descriptor), this.name = Name.identifier(name)
Name.identifier(name), this.visibility = Visibilities.PRIVATE
Visibilities.PRIVATE, Modality.FINAL, returnType, this.returnType = returnType
isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false, isFakeOverride = false, }.also {
isOperator = false
).also {
descriptor.bind(it)
it.parent = irScript it.parent = irScript
} }
}
private fun List<IrStatement>.prepareForEvaluateScriptFunction(evaluateScriptFunction: IrFunction): List<IrStatement> { private fun List<IrStatement>.prepareForEvaluateScriptFunction(evaluateScriptFunction: IrFunction): List<IrStatement> {
return if (isNotEmpty()) { return if (isNotEmpty()) {
@@ -10,13 +10,11 @@ import org.jetbrains.kotlin.backend.common.DeclarationTransformer
import org.jetbrains.kotlin.backend.common.ir.copyTo import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -48,21 +46,13 @@ class PrivateMembersLowering(val context: JsIrBackendContext) : DeclarationTrans
if (function.visibility != Visibilities.PRIVATE || function.dispatchReceiverParameter == null) return null if (function.visibility != Visibilities.PRIVATE || function.dispatchReceiverParameter == null) return null
val descriptor = WrappedSimpleFunctionDescriptor() val staticFunction = buildFun {
val symbol = IrSimpleFunctionSymbolImpl(descriptor) updateFrom(function)
val staticFunction = function.run { name = function.name
IrFunctionImpl( returnType = function.returnType
startOffset, endOffset, origin, }.also {
symbol, name, visibility, modality, it.parent = function.parent
returnType, it.correspondingPropertySymbol = function.correspondingPropertySymbol
isInline = isInline, isExternal = isExternal, isTailrec = isTailrec, isSuspend = isSuspend, isExpect = isExpect,
isFakeOverride = isFakeOverride,
isOperator = isOperator
).also {
descriptor.bind(it)
it.parent = parent
it.correspondingPropertySymbol = correspondingPropertySymbol
}
} }
staticFunction.typeParameters += function.typeParameters.map { it.deepCopyWithSymbols(staticFunction) } staticFunction.typeParameters += function.typeParameters.map { it.deepCopyWithSymbols(staticFunction) }
@@ -14,15 +14,14 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.backend.js.lower.CallableReferenceLowering import org.jetbrains.kotlin.ir.backend.js.lower.CallableReferenceLowering
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedFieldDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedFieldDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
@@ -30,14 +29,15 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl 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.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val context: C) : BodyLoweringPass { abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val context: C) : BodyLoweringPass {
@@ -302,128 +302,111 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
} }
private fun buildInvokeSuspendMethod(stateMachineFunction: IrSimpleFunction): IrSimpleFunction { private fun buildInvokeSuspendMethod(stateMachineFunction: IrSimpleFunction): IrSimpleFunction {
val smFunction = WrappedSimpleFunctionDescriptor().let { d -> val smFunction = buildFun {
IrFunctionImpl( startOffset = function.startOffset
startOffset, endOffset, endOffset = function.endOffset
DECLARATION_ORIGIN_COROUTINE_IMPL, origin = DECLARATION_ORIGIN_COROUTINE_IMPL
IrSimpleFunctionSymbolImpl(d), name = stateMachineFunction.name
stateMachineFunction.name, visibility = stateMachineFunction.visibility
stateMachineFunction.visibility, modality = Modality.FINAL
Modality.FINAL, returnType = context.irBuiltIns.anyNType
context.irBuiltIns.anyNType, isInline = stateMachineFunction.isInline
isInline = stateMachineFunction.isInline, isExternal = stateMachineFunction.isExternal
isExternal = stateMachineFunction.isExternal, isTailrec = stateMachineFunction.isTailrec
isTailrec = stateMachineFunction.isTailrec, isSuspend = stateMachineFunction.isSuspend
isSuspend = stateMachineFunction.isSuspend, isOperator = false
isExpect = stateMachineFunction.isExpect, isExpect = stateMachineFunction.isExpect
isFakeOverride = false, isFakeOverride = false
isOperator = false }.apply {
).apply { parent = coroutineClass
d.bind(this) coroutineClass.addChild(this)
parent = coroutineClass
coroutineClass.addChild(this)
typeParameters = stateMachineFunction.typeParameters.map { parameter -> typeParameters = stateMachineFunction.typeParameters.map { parameter ->
parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL) parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL)
.apply { superTypes += parameter.superTypes } .apply { superTypes += parameter.superTypes }
}
valueParameters = stateMachineFunction.valueParameters.mapIndexed { index, parameter ->
parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index)
}
this.createDispatchReceiverParameter()
overriddenSymbols = listOf(stateMachineFunction.symbol)
} }
valueParameters = stateMachineFunction.valueParameters.mapIndexed { index, parameter ->
parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index)
}
this.createDispatchReceiverParameter()
overriddenSymbols = listOf(stateMachineFunction.symbol)
} }
buildStateMachine(smFunction, function, argumentToPropertiesMap) buildStateMachine(smFunction, function, argumentToPropertiesMap)
return smFunction return smFunction
} }
private fun buildCreateMethod(superCreateFunction: IrSimpleFunction?, constructor: IrConstructor): IrSimpleFunction { // val i = $lambdaN(this.f1, this.f2, ..., this.fn, continuation) // bound
// val i = $lambdaN(this.f1, this.f2, ..., this.fn, continuation) // bound // i.s1 = p1 // unbound
// i.s1 = p1 // unbound // ...
// ... // i.sn = pn
// i.sn = pn // return i
// return i private fun buildCreateMethod(superCreateFunction: IrSimpleFunction?, constructor: IrConstructor): IrSimpleFunction =
val createFunction = WrappedSimpleFunctionDescriptor().let { d -> buildFun {
IrFunctionImpl( startOffset = function.startOffset
startOffset, endOffset, endOffset = function.endOffset
DECLARATION_ORIGIN_COROUTINE_IMPL, origin = DECLARATION_ORIGIN_COROUTINE_IMPL
IrSimpleFunctionSymbolImpl(d), name = Name.identifier("create")
Name.identifier("create"), visibility = Visibilities.PROTECTED
Visibilities.PROTECTED, returnType = coroutineClass.defaultType
Modality.FINAL, }.apply {
coroutineClass.defaultType, parent = coroutineClass
isInline = false, coroutineClass.addChild(this)
isExternal = false,
isTailrec = false,
isSuspend = false,
isExpect = false,
isFakeOverride = false,
isOperator = false
).apply {
d.bind(this)
parent = coroutineClass
coroutineClass.addChild(this)
typeParameters = function.typeParameters.map { parameter -> typeParameters = function.typeParameters.map { parameter ->
parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL) parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL)
.apply { superTypes += parameter.superTypes } .apply { superTypes += parameter.superTypes }
} }
val unboundArgs = function.valueParameters val unboundArgs = function.valueParameters
val createValueParameters = (unboundArgs + create1CompletionParameter).mapIndexed { index, parameter -> val createValueParameters = (unboundArgs + create1CompletionParameter).mapIndexed { index, parameter ->
parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index) parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index)
} }
valueParameters = createValueParameters valueParameters = createValueParameters
this.createDispatchReceiverParameter() this.createDispatchReceiverParameter()
superCreateFunction?.let { superCreateFunction?.let {
overriddenSymbols = ArrayList<IrSimpleFunctionSymbol>(it.overriddenSymbols.size + 1).apply { overriddenSymbols = ArrayList<IrSimpleFunctionSymbol>(it.overriddenSymbols.size + 1).apply {
addAll(it.overriddenSymbols) addAll(it.overriddenSymbols)
add(it.symbol) add(it.symbol)
}
}
val thisReceiver = this.dispatchReceiverParameter!!
val boundFields =
context.mapping.capturedFields[coroutineClass] ?: error("No captured values for class ${coroutineClass.render()}")
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
body = irBuilder.irBlockBody(startOffset, endOffset) {
val instanceCreate = irCall(constructor).apply {
var unboundIndex = 0
for (f in boundFields) {
putValueArgument(unboundIndex++, irGetField(irGet(thisReceiver), f))
}
putValueArgument(unboundIndex++, irGet(createValueParameters.last()))
assert(unboundIndex == constructor.valueParameters.size) {
"Not all arguments of <create> are used"
}
}
val instanceVal = scope.createTmpVariable(instanceCreate, "i")
+instanceVal
assert(createValueParameters.size - 1 == argumentToPropertiesMap.size)
for ((p, f) in createValueParameters.zip(argumentToPropertiesMap.values)) {
+irSetField(irGet(instanceVal), f, irGet(p))
}
+irReturn(irGet(instanceVal))
} }
} }
}
return createFunction val thisReceiver = this.dispatchReceiverParameter!!
}
val boundFields =
context.mapping.capturedFields[coroutineClass] ?: error("No captured values for class ${coroutineClass.render()}")
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
body = irBuilder.irBlockBody(startOffset, endOffset) {
val instanceCreate = irCall(constructor).apply {
var unboundIndex = 0
for (f in boundFields) {
putValueArgument(unboundIndex++, irGetField(irGet(thisReceiver), f))
}
putValueArgument(unboundIndex++, irGet(createValueParameters.last()))
assert(unboundIndex == constructor.valueParameters.size) {
"Not all arguments of <create> are used"
}
}
val instanceVal = scope.createTmpVariable(instanceCreate, "i")
+instanceVal
assert(createValueParameters.size - 1 == argumentToPropertiesMap.size)
for ((p, f) in createValueParameters.zip(argumentToPropertiesMap.values)) {
+irSetField(irGet(instanceVal), f, irGet(p))
}
+irReturn(irGet(instanceVal))
}
}
private fun transformInvokeMethod(createFunction: IrSimpleFunction, stateMachineFunction: IrSimpleFunction) { private fun transformInvokeMethod(createFunction: IrSimpleFunction, stateMachineFunction: IrSimpleFunction) {
val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset) val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.backend.jvm.descriptors package org.jetbrains.kotlin.backend.jvm.descriptors
import org.jetbrains.kotlin.backend.common.DescriptorsToIrRemapper
import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
@@ -21,21 +20,19 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
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.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.buildField import org.jetbrains.kotlin.ir.builders.declarations.buildField
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.builders.setSourceRange import org.jetbrains.kotlin.ir.builders.setSourceRange
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
@@ -282,30 +279,25 @@ class JvmDeclarationFactory(
defaultImplsRedirections.getOrPut(fakeOverride) { defaultImplsRedirections.getOrPut(fakeOverride) {
assert(fakeOverride.isFakeOverride) assert(fakeOverride.isFakeOverride)
val irClass = fakeOverride.parentAsClass val irClass = fakeOverride.parentAsClass
val descriptor = DescriptorsToIrRemapper.remapDeclaredSimpleFunction(fakeOverride.descriptor) buildFun(fakeOverride.descriptor) {
with(fakeOverride) { origin = JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE
IrFunctionImpl( name = fakeOverride.name
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE, visibility = fakeOverride.visibility
IrSimpleFunctionSymbolImpl(descriptor), modality = fakeOverride.modality
name, visibility, modality, returnType, returnType = fakeOverride.returnType
isInline = isInline, isInline = fakeOverride.isInline
isExternal = false, isExternal = false
isTailrec = false, isTailrec = false
isSuspend = isSuspend, isSuspend = fakeOverride.isSuspend
isExpect = false, isOperator = fakeOverride.isOperator
isFakeOverride = false, isExpect = false
isOperator = isOperator isFakeOverride = false
).apply { }.apply {
descriptor.bind(this) parent = irClass
parent = irClass overriddenSymbols = fakeOverride.overriddenSymbols
overriddenSymbols = fakeOverride.overriddenSymbols copyParameterDeclarationsFrom(fakeOverride)
copyParameterDeclarationsFrom(fakeOverride) annotations = fakeOverride.annotations
annotations = fakeOverride.annotations copyCorrespondingPropertyFrom(fakeOverride)
copyCorrespondingPropertyFrom(fakeOverride)
}
} }
} }
} }
@@ -583,7 +583,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
if (function.body == null || !function.hasContinuation()) return result if (function.body == null || !function.hasContinuation()) return result
if (flag.capturesCrossinline || function.isInline) { if (flag.capturesCrossinline || function.isInline) {
result += buildFunWithDescriptorForInlining(view.descriptor) { result += buildFun(view.descriptor) {
name = Name.identifier(view.name.asString() + FOR_INLINE_SUFFIX) name = Name.identifier(view.name.asString() + FOR_INLINE_SUFFIX)
returnType = view.returnType returnType = view.returnType
modality = view.modality modality = view.modality
@@ -651,7 +651,7 @@ internal fun IrFunction.suspendFunctionOriginal(): IrFunction =
private fun IrFunction.createSuspendFunctionStub(context: JvmBackendContext): IrFunction { private fun IrFunction.createSuspendFunctionStub(context: JvmBackendContext): IrFunction {
require(this.isSuspend && this is IrSimpleFunction) require(this.isSuspend && this is IrSimpleFunction)
return buildFunWithDescriptorForInlining(descriptor) { return buildFun(descriptor) {
updateFrom(this@createSuspendFunctionStub) updateFrom(this@createSuspendFunctionStub)
name = this@createSuspendFunctionStub.name name = this@createSuspendFunctionStub.name
origin = this@createSuspendFunctionStub.origin origin = this@createSuspendFunctionStub.origin
@@ -14,14 +14,12 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.util.allTypeParameters import org.jetbrains.kotlin.ir.util.allTypeParameters
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
@@ -137,29 +135,16 @@ private class JvmOverloadsAnnotationLowering(val context: JvmBackendContext) : C
descriptor.bind(this) descriptor.bind(this)
} }
} }
is IrSimpleFunction -> { is IrSimpleFunction -> buildFun(oldFunction.descriptor) {
val descriptor = WrappedSimpleFunctionDescriptor(oldFunction.descriptor.annotations) origin = JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER
val modality = name = oldFunction.name
visibility = oldFunction.visibility
modality =
if (context.state.languageVersionSettings.supportsFeature(LanguageFeature.GenerateJvmOverloadsAsFinal)) Modality.FINAL if (context.state.languageVersionSettings.supportsFeature(LanguageFeature.GenerateJvmOverloadsAsFinal)) Modality.FINAL
else oldFunction.modality else oldFunction.modality
IrFunctionImpl( returnType = oldFunction.returnType
UNDEFINED_OFFSET, UNDEFINED_OFFSET, isInline = oldFunction.isInline
JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER, isSuspend = oldFunction.isSuspend
IrSimpleFunctionSymbolImpl(descriptor),
oldFunction.name,
oldFunction.visibility,
modality,
returnType = oldFunction.returnType,
isInline = oldFunction.isInline,
isExternal = false,
isTailrec = false,
isSuspend = oldFunction.isSuspend,
isExpect = false,
isFakeOverride = false,
isOperator = false,
).apply {
descriptor.bind(this)
}
} }
else -> error("Unknown kind of IrFunction: $oldFunction") else -> error("Unknown kind of IrFunction: $oldFunction")
} }
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference
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.builders.declarations.addFunction import org.jetbrains.kotlin.ir.builders.declarations.addFunction
import org.jetbrains.kotlin.ir.builders.declarations.buildFunWithDescriptorForInlining import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.builders.irExprBody import org.jetbrains.kotlin.ir.builders.irExprBody
import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.builders.irGet
@@ -192,7 +192,7 @@ private class MakeCallsStatic(
} }
private fun IrSimpleFunction.copyRemovingDispatchReceiver(): IrSimpleFunction = private fun IrSimpleFunction.copyRemovingDispatchReceiver(): IrSimpleFunction =
buildFunWithDescriptorForInlining(descriptor) { buildFun(descriptor) {
updateFrom(this@copyRemovingDispatchReceiver) updateFrom(this@copyRemovingDispatchReceiver)
name = this@copyRemovingDispatchReceiver.name name = this@copyRemovingDispatchReceiver.name
returnType = this@copyRemovingDispatchReceiver.returnType returnType = this@copyRemovingDispatchReceiver.returnType
@@ -210,4 +210,3 @@ private fun isJvmStaticFunction(declaration: IrDeclaration): Boolean =
(declaration.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) || (declaration.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) ||
declaration.correspondingPropertySymbol?.owner?.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) == true) && declaration.correspondingPropertySymbol?.owner?.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) == true) &&
declaration.origin != JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS declaration.origin != JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildFunWithDescriptorForInlining
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
@@ -185,7 +184,7 @@ class MemoizedInlineClassReplacements(private val mangleReturnTypes: Boolean) {
replacementOrigin: IrDeclarationOrigin, replacementOrigin: IrDeclarationOrigin,
noFakeOverride: Boolean = false, noFakeOverride: Boolean = false,
body: IrFunction.() -> Unit body: IrFunction.() -> Unit
) = buildFunWithDescriptorForInlining(function.descriptor) { ): IrSimpleFunction = buildFun(function.descriptor) {
updateFrom(function) updateFrom(function)
if (function is IrConstructor) { if (function is IrConstructor) {
// The [updateFrom] call will set the modality to FINAL for constructors, while the JVM backend would use OPEN here. // The [updateFrom] call will set the modality to FINAL for constructors, while the JVM backend would use OPEN here.