Rewrote coroutines lowering to use symbols
This commit is contained in:
+43
-33
@@ -24,28 +24,28 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
|
||||||
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.declarations.impl.IrFunctionImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
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.util.createParameterDeclarations
|
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
abstract class DescriptorWithIrBuilder<out D: DeclarationDescriptor, out B: IrDeclaration> {
|
abstract class SymbolWithIrBuilder<out S: IrSymbol, out D: IrDeclaration> {
|
||||||
|
|
||||||
protected abstract fun buildDescriptor(): D
|
protected abstract fun buildSymbol(): S
|
||||||
|
|
||||||
protected open fun doInitialize() { }
|
protected open fun doInitialize() { }
|
||||||
|
|
||||||
protected abstract fun buildIr(): B
|
protected abstract fun buildIr(): D
|
||||||
|
|
||||||
val descriptor by lazy { buildDescriptor() }
|
val symbol by lazy { buildSymbol() }
|
||||||
|
|
||||||
private val builtIr by lazy { buildIr() }
|
private val builtIr by lazy { buildIr() }
|
||||||
private var initialized: Boolean = false
|
private var initialized: Boolean = false
|
||||||
@@ -55,7 +55,7 @@ abstract class DescriptorWithIrBuilder<out D: DeclarationDescriptor, out B: IrDe
|
|||||||
initialized = true
|
initialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val ir: B
|
val ir: D
|
||||||
get() {
|
get() {
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
throw Error("Access to IR before initialization")
|
throw Error("Access to IR before initialization")
|
||||||
@@ -64,11 +64,12 @@ abstract class DescriptorWithIrBuilder<out D: DeclarationDescriptor, out B: IrDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun BackendContext.createPropertyGetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
fun BackendContext.createPropertyGetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
||||||
symbol: IrFieldSymbol, type: KotlinType)
|
fieldSymbol: IrFieldSymbol, type: KotlinType)
|
||||||
= object: DescriptorWithIrBuilder<PropertyGetterDescriptorImpl, IrFunction>() {
|
= object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
||||||
|
|
||||||
override fun buildDescriptor() = PropertyGetterDescriptorImpl(
|
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
||||||
/* correspondingProperty = */ symbol.descriptor,
|
PropertyGetterDescriptorImpl(
|
||||||
|
/* correspondingProperty = */ fieldSymbol.descriptor,
|
||||||
/* annotations = */ Annotations.EMPTY,
|
/* annotations = */ Annotations.EMPTY,
|
||||||
/* modality = */ Modality.FINAL,
|
/* modality = */ Modality.FINAL,
|
||||||
/* visibility = */ Visibilities.PRIVATE,
|
/* visibility = */ Visibilities.PRIVATE,
|
||||||
@@ -79,8 +80,10 @@ fun BackendContext.createPropertyGetterBuilder(startOffset: Int, endOffset: Int,
|
|||||||
/* original = */ null,
|
/* original = */ null,
|
||||||
/* source = */ SourceElement.NO_SOURCE
|
/* source = */ SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
override fun doInitialize() {
|
override fun doInitialize() {
|
||||||
|
val descriptor = symbol.descriptor as PropertyGetterDescriptorImpl
|
||||||
descriptor.apply {
|
descriptor.apply {
|
||||||
initialize(type)
|
initialize(type)
|
||||||
}
|
}
|
||||||
@@ -90,22 +93,23 @@ fun BackendContext.createPropertyGetterBuilder(startOffset: Int, endOffset: Int,
|
|||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset,
|
endOffset = endOffset,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
descriptor = descriptor).apply {
|
symbol = symbol).apply {
|
||||||
|
|
||||||
createParameterDeclarations()
|
createParameterDeclarations()
|
||||||
|
|
||||||
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
|
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
|
||||||
+irReturn(irGetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), symbol))
|
+irReturn(irGetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), fieldSymbol))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun BackendContext.createPropertySetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
private fun BackendContext.createPropertySetterBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
||||||
symbol: IrFieldSymbol, type: KotlinType)
|
fieldSymbol: IrFieldSymbol, type: KotlinType)
|
||||||
= object: DescriptorWithIrBuilder<PropertySetterDescriptorImpl, IrFunction>() {
|
= object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
||||||
|
|
||||||
override fun buildDescriptor() = PropertySetterDescriptorImpl(
|
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
||||||
/* correspondingProperty = */ symbol.descriptor,
|
PropertySetterDescriptorImpl(
|
||||||
|
/* correspondingProperty = */ fieldSymbol.descriptor,
|
||||||
/* annotations = */ Annotations.EMPTY,
|
/* annotations = */ Annotations.EMPTY,
|
||||||
/* modality = */ Modality.FINAL,
|
/* modality = */ Modality.FINAL,
|
||||||
/* visibility = */ Visibilities.PRIVATE,
|
/* visibility = */ Visibilities.PRIVATE,
|
||||||
@@ -116,10 +120,12 @@ private fun BackendContext.createPropertySetterBuilder(startOffset: Int, endOffs
|
|||||||
/* original = */ null,
|
/* original = */ null,
|
||||||
/* source = */ SourceElement.NO_SOURCE
|
/* source = */ SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
lateinit var valueParameterDescriptor: ValueParameterDescriptor
|
lateinit var valueParameterDescriptor: ValueParameterDescriptor
|
||||||
|
|
||||||
override fun doInitialize() {
|
override fun doInitialize() {
|
||||||
|
val descriptor = symbol.descriptor as PropertySetterDescriptorImpl
|
||||||
descriptor.apply {
|
descriptor.apply {
|
||||||
valueParameterDescriptor = ValueParameterDescriptorImpl(
|
valueParameterDescriptor = ValueParameterDescriptorImpl(
|
||||||
containingDeclaration = this,
|
containingDeclaration = this,
|
||||||
@@ -143,25 +149,25 @@ private fun BackendContext.createPropertySetterBuilder(startOffset: Int, endOffs
|
|||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset,
|
endOffset = endOffset,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
descriptor = descriptor).apply {
|
symbol = symbol).apply {
|
||||||
|
|
||||||
createParameterDeclarations()
|
createParameterDeclarations()
|
||||||
|
|
||||||
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
|
body = createIrBuilder(this.symbol, startOffset, endOffset).irBlockBody {
|
||||||
+irSetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), symbol, irGet(this@apply.valueParameters.single().symbol))
|
+irSetField(irGet(this@apply.dispatchReceiverParameter!!.symbol), fieldSymbol, irGet(this@apply.valueParameters.single().symbol))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun BackendContext.createPropertyWithBackingFieldBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
fun BackendContext.createPropertyWithBackingFieldBuilder(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
|
||||||
owner: ClassDescriptor, name: Name, type: KotlinType, isMutable: Boolean)
|
owner: ClassDescriptor, name: Name, type: KotlinType, isMutable: Boolean)
|
||||||
= object: DescriptorWithIrBuilder<PropertyDescriptorImpl, IrProperty>() {
|
= object: SymbolWithIrBuilder<IrFieldSymbol, IrProperty>() {
|
||||||
|
|
||||||
private lateinit var getterBuilder: DescriptorWithIrBuilder<PropertyGetterDescriptorImpl, IrFunction>
|
private lateinit var getterBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>
|
||||||
private var setterBuilder: DescriptorWithIrBuilder<PropertySetterDescriptorImpl, IrFunction>? = null
|
private var setterBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>? = null
|
||||||
private lateinit var fieldSymbol: IrFieldSymbol
|
|
||||||
|
|
||||||
override fun buildDescriptor() = PropertyDescriptorImpl.create(
|
override fun buildSymbol() = IrFieldSymbolImpl(
|
||||||
|
PropertyDescriptorImpl.create(
|
||||||
/* containingDeclaration = */ owner,
|
/* containingDeclaration = */ owner,
|
||||||
/* annotations = */ Annotations.EMPTY,
|
/* annotations = */ Annotations.EMPTY,
|
||||||
/* modality = */ Modality.FINAL,
|
/* modality = */ Modality.FINAL,
|
||||||
@@ -175,14 +181,18 @@ fun BackendContext.createPropertyWithBackingFieldBuilder(startOffset: Int, endOf
|
|||||||
/* isHeader = */ false,
|
/* isHeader = */ false,
|
||||||
/* isImpl = */ false,
|
/* isImpl = */ false,
|
||||||
/* isExternal = */ false,
|
/* isExternal = */ false,
|
||||||
/* isDelegated = */ false)
|
/* isDelegated = */ false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
override fun doInitialize() {
|
override fun doInitialize() {
|
||||||
fieldSymbol = IrFieldSymbolImpl(descriptor)
|
val descriptor = symbol.descriptor as PropertyDescriptorImpl
|
||||||
getterBuilder = createPropertyGetterBuilder(startOffset, endOffset, origin, fieldSymbol, type).apply { initialize() }
|
getterBuilder = createPropertyGetterBuilder(startOffset, endOffset, origin, symbol, type).apply { initialize() }
|
||||||
if (isMutable)
|
if (isMutable)
|
||||||
setterBuilder = createPropertySetterBuilder(startOffset, endOffset, origin, fieldSymbol, type).apply { initialize() }
|
setterBuilder = createPropertySetterBuilder(startOffset, endOffset, origin, symbol, type).apply { initialize() }
|
||||||
descriptor.initialize(getterBuilder.descriptor, setterBuilder?.descriptor)
|
descriptor.initialize(
|
||||||
|
/* getter = */ getterBuilder.symbol.descriptor as PropertyGetterDescriptorImpl,
|
||||||
|
/* setter = */ setterBuilder?.symbol?.descriptor as? PropertySetterDescriptorImpl)
|
||||||
val receiverType: KotlinType? = null
|
val receiverType: KotlinType? = null
|
||||||
descriptor.setType(type, emptyList(), owner.thisAsReceiverParameter, receiverType)
|
descriptor.setType(type, emptyList(), owner.thisAsReceiverParameter, receiverType)
|
||||||
}
|
}
|
||||||
@@ -192,13 +202,13 @@ fun BackendContext.createPropertyWithBackingFieldBuilder(startOffset: Int, endOf
|
|||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset,
|
endOffset = endOffset,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
symbol = fieldSymbol)
|
symbol = symbol)
|
||||||
return IrPropertyImpl(
|
return IrPropertyImpl(
|
||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset,
|
endOffset = endOffset,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
isDelegated = false,
|
isDelegated = false,
|
||||||
descriptor = descriptor,
|
descriptor = symbol.descriptor,
|
||||||
backingField = backingField,
|
backingField = backingField,
|
||||||
getter = getterBuilder.ir,
|
getter = getterBuilder.ir,
|
||||||
setter = setterBuilder?.ir)
|
setter = setterBuilder?.ir)
|
||||||
|
|||||||
+25
-17
@@ -38,8 +38,12 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||||
import org.jetbrains.kotlin.ir.util.getArguments
|
import org.jetbrains.kotlin.ir.util.getArguments
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
@@ -171,9 +175,10 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
|
|||||||
.map { it.createFakeOverrideDescriptor(functionReferenceClassDescriptor) }
|
.map { it.createFakeOverrideDescriptor(functionReferenceClassDescriptor) }
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
val contributedDescriptors = (
|
val contributedDescriptors = (
|
||||||
inheritedKFunctionImpl + invokeMethodBuilder.descriptor
|
inheritedKFunctionImpl + invokeMethodBuilder.symbol.descriptor
|
||||||
).toList()
|
).toList()
|
||||||
functionReferenceClassDescriptor.initialize(SimpleMemberScope(contributedDescriptors), setOf(constructorBuilder.descriptor), null)
|
functionReferenceClassDescriptor.initialize(
|
||||||
|
SimpleMemberScope(contributedDescriptors), setOf(constructorBuilder.symbol.descriptor), null)
|
||||||
|
|
||||||
constructorBuilder.initialize()
|
constructorBuilder.initialize()
|
||||||
functionReferenceClass.declarations.add(constructorBuilder.ir)
|
functionReferenceClass.declarations.add(constructorBuilder.ir)
|
||||||
@@ -185,20 +190,21 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createConstructorBuilder()
|
private fun createConstructorBuilder()
|
||||||
= object : DescriptorWithIrBuilder<ClassConstructorDescriptorImpl, IrConstructor>() {
|
= object : SymbolWithIrBuilder<IrConstructorSymbol, IrConstructor>() {
|
||||||
|
|
||||||
private val kFunctionImplConstructorDescriptor = kFunctionImplClassDescriptor.constructors.single()
|
private val kFunctionImplConstructorDescriptor = kFunctionImplClassDescriptor.constructors.single()
|
||||||
|
|
||||||
override fun buildDescriptor(): ClassConstructorDescriptorImpl {
|
override fun buildSymbol() = IrConstructorSymbolImpl(
|
||||||
return ClassConstructorDescriptorImpl.create(
|
ClassConstructorDescriptorImpl.create(
|
||||||
/* containingDeclaration = */ functionReferenceClassDescriptor,
|
/* containingDeclaration = */ functionReferenceClassDescriptor,
|
||||||
/* annotations = */ Annotations.EMPTY,
|
/* annotations = */ Annotations.EMPTY,
|
||||||
/* isPrimary = */ false,
|
/* isPrimary = */ false,
|
||||||
/* source = */ SourceElement.NO_SOURCE
|
/* source = */ SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
|
|
||||||
override fun doInitialize() {
|
override fun doInitialize() {
|
||||||
|
val descriptor = symbol.descriptor as ClassConstructorDescriptorImpl
|
||||||
val constructorParameters = boundFunctionParameters.mapIndexed { index, parameter ->
|
val constructorParameters = boundFunctionParameters.mapIndexed { index, parameter ->
|
||||||
parameter.copyAsValueParameter(descriptor, index)
|
parameter.copyAsValueParameter(descriptor, index)
|
||||||
}
|
}
|
||||||
@@ -217,7 +223,7 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
|
|||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset,
|
endOffset = endOffset,
|
||||||
origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
|
origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
|
||||||
descriptor = descriptor).apply {
|
symbol = symbol).apply {
|
||||||
|
|
||||||
val irBuilder = context.createIrBuilder(this.symbol, startOffset, endOffset)
|
val irBuilder = context.createIrBuilder(this.symbol, startOffset, endOffset)
|
||||||
|
|
||||||
@@ -261,20 +267,24 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createInvokeMethodBuilder(functionInvokeFunctionDescriptor: FunctionDescriptor)
|
private fun createInvokeMethodBuilder(functionInvokeFunctionDescriptor: FunctionDescriptor)
|
||||||
= object : DescriptorWithIrBuilder<SimpleFunctionDescriptorImpl, IrFunction>() {
|
= object : SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
||||||
|
|
||||||
override fun buildDescriptor() = SimpleFunctionDescriptorImpl.create(
|
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
||||||
|
SimpleFunctionDescriptorImpl.create(
|
||||||
/* containingDeclaration = */ functionReferenceClassDescriptor,
|
/* containingDeclaration = */ functionReferenceClassDescriptor,
|
||||||
/* annotations = */ Annotations.EMPTY,
|
/* annotations = */ Annotations.EMPTY,
|
||||||
/* name = */ Name.identifier("invoke"),
|
/* name = */ Name.identifier("invoke"),
|
||||||
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
||||||
/* source = */ SourceElement.NO_SOURCE)
|
/* source = */ SourceElement.NO_SOURCE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
override fun doInitialize() {
|
override fun doInitialize() {
|
||||||
|
val descriptor = symbol.descriptor as SimpleFunctionDescriptorImpl
|
||||||
val valueParameters = functionInvokeFunctionDescriptor.valueParameters
|
val valueParameters = functionInvokeFunctionDescriptor.valueParameters
|
||||||
.map { it.copyAsValueParameter(this.descriptor, it.index) }
|
.map { it.copyAsValueParameter(descriptor, it.index) }
|
||||||
|
|
||||||
this.descriptor.initialize(
|
descriptor.initialize(
|
||||||
/* receiverParameterType = */ null,
|
/* receiverParameterType = */ null,
|
||||||
/* dispatchReceiverParameter = */ functionReferenceClassDescriptor.thisAsReceiverParameter,
|
/* dispatchReceiverParameter = */ functionReferenceClassDescriptor.thisAsReceiverParameter,
|
||||||
/* typeParameters = */ emptyList(),
|
/* typeParameters = */ emptyList(),
|
||||||
@@ -286,15 +296,14 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun buildIr(): IrFunction {
|
override fun buildIr(): IrSimpleFunction {
|
||||||
val startOffset = functionReference.startOffset
|
val startOffset = functionReference.startOffset
|
||||||
val endOffset = functionReference.endOffset
|
val endOffset = functionReference.endOffset
|
||||||
val ourDescriptor = this.descriptor
|
|
||||||
return IrFunctionImpl(
|
return IrFunctionImpl(
|
||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset,
|
endOffset = endOffset,
|
||||||
origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
|
origin = DECLARATION_ORIGIN_FUNCTION_REFERENCE_IMPL,
|
||||||
descriptor = this.descriptor).apply {
|
symbol = symbol).apply {
|
||||||
|
|
||||||
val function = this
|
val function = this
|
||||||
val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
|
val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
|
||||||
@@ -317,8 +326,7 @@ internal class CallableReferenceLowering(val context: Context): DeclarationConta
|
|||||||
else -> putValueArgument((it as ValueParameterDescriptor).index, argument)
|
else -> putValueArgument((it as ValueParameterDescriptor).index, argument)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(unboundIndex == ourDescriptor.valueParameters.size,
|
assert(unboundIndex == valueParameters.size, { "Not all arguments of <invoke> are used" })
|
||||||
{ "Not all arguments of <invoke> are used" })
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+209
-175
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.backend.konan.lower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.explicitParameters
|
import org.jetbrains.kotlin.backend.common.descriptors.explicitParameters
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.isSuspend
|
|
||||||
import org.jetbrains.kotlin.backend.common.lower.*
|
import org.jetbrains.kotlin.backend.common.lower.*
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
import org.jetbrains.kotlin.backend.common.*
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
@@ -40,6 +39,10 @@ import org.jetbrains.kotlin.ir.declarations.impl.*
|
|||||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
||||||
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.impl.IrConstructorSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||||
import org.jetbrains.kotlin.ir.util.getArguments
|
import org.jetbrains.kotlin.ir.util.getArguments
|
||||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||||
@@ -56,7 +59,7 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
|||||||
internal class SuspendFunctionsLowering(val context: Context): DeclarationContainerLoweringPass {
|
internal class SuspendFunctionsLowering(val context: Context): DeclarationContainerLoweringPass {
|
||||||
|
|
||||||
private val builtCoroutines = mutableMapOf<FunctionDescriptor, BuiltCoroutine>()
|
private val builtCoroutines = mutableMapOf<FunctionDescriptor, BuiltCoroutine>()
|
||||||
private val suspendLambdas = mutableMapOf<FunctionDescriptor, IrCallableReference>()
|
private val suspendLambdas = mutableMapOf<FunctionDescriptor, IrFunctionReference>()
|
||||||
|
|
||||||
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
|
||||||
markSuspendLambdas(irDeclarationContainer)
|
markSuspendLambdas(irDeclarationContainer)
|
||||||
@@ -76,12 +79,12 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
element.acceptChildrenVoid(this)
|
element.acceptChildrenVoid(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCallableReference(expression: IrCallableReference) {
|
override fun visitFunctionReference(expression: IrFunctionReference) {
|
||||||
expression.acceptChildrenVoid(this)
|
expression.acceptChildrenVoid(this)
|
||||||
|
|
||||||
val descriptor = expression.descriptor
|
val descriptor = expression.descriptor
|
||||||
if (descriptor.isSuspend)
|
if (descriptor.isSuspend)
|
||||||
suspendLambdas.put(descriptor as FunctionDescriptor, expression)
|
suspendLambdas.put(descriptor, expression)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -91,20 +94,21 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
irDeclarationContainer.declarations.forEach {
|
irDeclarationContainer.declarations.forEach {
|
||||||
it.transformChildrenVoid(object: IrElementTransformerVoid() {
|
it.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||||
|
|
||||||
override fun visitCallableReference(expression: IrCallableReference): IrExpression {
|
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
val descriptor = expression.descriptor
|
val descriptor = expression.descriptor
|
||||||
if (!descriptor.isSuspend) return expression
|
if (!descriptor.isSuspend)
|
||||||
|
return expression
|
||||||
val coroutine = builtCoroutines[descriptor]
|
val coroutine = builtCoroutines[descriptor]
|
||||||
?: throw Error("Non-local callable reference to suspend lambda: $descriptor")
|
?: throw Error("Non-local callable reference to suspend lambda: $descriptor")
|
||||||
val constructorParameters = coroutine.coroutineConstructorDescriptor.valueParameters
|
val constructorParameters = coroutine.coroutineConstructor.valueParameters
|
||||||
val expressionArguments = expression.getArguments().map { it.second }
|
val expressionArguments = expression.getArguments().map { it.second }
|
||||||
assert (constructorParameters.size == expressionArguments.size,
|
assert (constructorParameters.size == expressionArguments.size,
|
||||||
{ "Inconsistency between callable reference to suspend lambda and the corresponding coroutine" })
|
{ "Inconsistency between callable reference to suspend lambda and the corresponding coroutine" })
|
||||||
val irBuilder = context.createIrBuilder(descriptor, expression.startOffset, expression.endOffset)
|
val irBuilder = context.createIrBuilder(expression.symbol, expression.startOffset, expression.endOffset)
|
||||||
irBuilder.run {
|
irBuilder.run {
|
||||||
return irCall(coroutine.coroutineConstructorDescriptor).apply {
|
return irCall(coroutine.coroutineConstructor.symbol).apply {
|
||||||
expressionArguments.forEachIndexed { index, argument ->
|
expressionArguments.forEachIndexed { index, argument ->
|
||||||
putValueArgument(index, argument) }
|
putValueArgument(index, argument) }
|
||||||
}
|
}
|
||||||
@@ -150,7 +154,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
NEEDS_STATE_MACHINE
|
NEEDS_STATE_MACHINE
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun transformSuspendFunction(irFunction: IrFunction, callableReference: IrCallableReference?): List<IrDeclaration>? {
|
private fun transformSuspendFunction(irFunction: IrFunction, functionReference: IrFunctionReference?): List<IrDeclaration>? {
|
||||||
val suspendFunctionKind = getSuspendFunctionKind(irFunction)
|
val suspendFunctionKind = getSuspendFunctionKind(irFunction)
|
||||||
return when (suspendFunctionKind) {
|
return when (suspendFunctionKind) {
|
||||||
SuspendFunctionKind.NO_SUSPEND_CALLS -> {
|
SuspendFunctionKind.NO_SUSPEND_CALLS -> {
|
||||||
@@ -164,7 +168,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
}
|
}
|
||||||
|
|
||||||
SuspendFunctionKind.NEEDS_STATE_MACHINE -> {
|
SuspendFunctionKind.NEEDS_STATE_MACHINE -> {
|
||||||
val coroutine = buildCoroutine(irFunction, callableReference) // Coroutine implementation.
|
val coroutine = buildCoroutine(irFunction, functionReference) // Coroutine implementation.
|
||||||
if (suspendLambdas.contains(irFunction.descriptor)) // Suspend lambdas are called through factory method <create>,
|
if (suspendLambdas.contains(irFunction.descriptor)) // Suspend lambdas are called through factory method <create>,
|
||||||
listOf(coroutine) // thus we can eliminate original body.
|
listOf(coroutine) // thus we can eliminate original body.
|
||||||
else
|
else
|
||||||
@@ -255,18 +259,18 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildCoroutine(irFunction: IrFunction, callableReference: IrCallableReference?): IrClass {
|
private fun buildCoroutine(irFunction: IrFunction, functionReference: IrFunctionReference?): IrClass {
|
||||||
val descriptor = irFunction.descriptor
|
val descriptor = irFunction.descriptor
|
||||||
val coroutine = CoroutineBuilder(irFunction, callableReference).build()
|
val coroutine = CoroutineBuilder(irFunction, functionReference).build()
|
||||||
builtCoroutines.put(descriptor, coroutine)
|
builtCoroutines.put(descriptor, coroutine)
|
||||||
|
|
||||||
if (callableReference == null) {
|
if (functionReference == null) {
|
||||||
// It is not a lambda - replace original function with a call to constructor of the built coroutine.
|
// It is not a lambda - replace original function with a call to constructor of the built coroutine.
|
||||||
val irBuilder = context.createIrBuilder(descriptor, irFunction.startOffset, irFunction.endOffset)
|
val irBuilder = context.createIrBuilder(irFunction.symbol, irFunction.startOffset, irFunction.endOffset)
|
||||||
irFunction.body = irBuilder.irBlockBody(irFunction) {
|
irFunction.body = irBuilder.irBlockBody(irFunction) {
|
||||||
+irReturn(
|
+irReturn(
|
||||||
irCall(coroutine.doResumeFunctionDescriptor).apply {
|
irCall(coroutine.doResumeFunction.symbol).apply {
|
||||||
dispatchReceiver = irCall(coroutine.coroutineConstructorDescriptor).apply {
|
dispatchReceiver = irCall(coroutine.coroutineConstructor.symbol).apply {
|
||||||
val functionParameters = irFunction.descriptor.explicitParameters
|
val functionParameters = irFunction.descriptor.explicitParameters
|
||||||
functionParameters.forEachIndexed { index, argument ->
|
functionParameters.forEachIndexed { index, argument ->
|
||||||
putValueArgument(index, irGet(argument))
|
putValueArgument(index, irGet(argument))
|
||||||
@@ -284,8 +288,8 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class BuiltCoroutine(val coroutineClass: IrClass,
|
private class BuiltCoroutine(val coroutineClass: IrClass,
|
||||||
val coroutineConstructorDescriptor: ClassConstructorDescriptor,
|
val coroutineConstructor: IrConstructor,
|
||||||
val doResumeFunctionDescriptor: FunctionDescriptor)
|
val doResumeFunction: IrFunction)
|
||||||
|
|
||||||
private var coroutineId = 0
|
private var coroutineId = 0
|
||||||
|
|
||||||
@@ -302,20 +306,21 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
private val COROUTINE_SUSPENDED = coroutinesIntrinsicsScope
|
private val COROUTINE_SUSPENDED = coroutinesIntrinsicsScope
|
||||||
.getContributedVariables(Name.identifier("COROUTINE_SUSPENDED"), NoLookupLocation.FROM_BACKEND).first()
|
.getContributedVariables(Name.identifier("COROUTINE_SUSPENDED"), NoLookupLocation.FROM_BACKEND).first()
|
||||||
|
|
||||||
private inner class CoroutineBuilder(val irFunction: IrFunction, val callableReference: IrCallableReference?) {
|
private inner class CoroutineBuilder(val irFunction: IrFunction, val functionReference: IrFunctionReference?) {
|
||||||
|
|
||||||
private val functionParameters = irFunction.descriptor.explicitParameters
|
private val functionParameters = irFunction.descriptor.explicitParameters
|
||||||
private val boundFunctionParameters = callableReference?.getArguments()?.map { it.first }
|
private val boundFunctionParameters = functionReference?.getArguments()?.map { it.first }
|
||||||
private val unboundFunctionParameters = boundFunctionParameters?.let { functionParameters - it }
|
private val unboundFunctionParameters = boundFunctionParameters?.let { functionParameters - it }
|
||||||
|
|
||||||
private var tempIndex = 0
|
private var tempIndex = 0
|
||||||
private var suspensionPointIdIndex = 0
|
private var suspensionPointIdIndex = 0
|
||||||
private lateinit var suspendResult: VariableDescriptor
|
private lateinit var suspendResult: IrVariableSymbol
|
||||||
private lateinit var dataArgument: ValueParameterDescriptor
|
private lateinit var dataArgument: IrValueParameterSymbol
|
||||||
private lateinit var exceptionArgument: ValueParameterDescriptor
|
private lateinit var exceptionArgument: IrValueParameterSymbol
|
||||||
private lateinit var coroutineClassDescriptor: ClassDescriptorImpl
|
private lateinit var coroutineClassDescriptor: ClassDescriptorImpl
|
||||||
private lateinit var argumentToPropertiesMap: Map<ParameterDescriptor, PropertyDescriptor>
|
private lateinit var coroutineClass: IrClassImpl
|
||||||
private val coroutineMembers = mutableListOf<IrDeclaration>()
|
private lateinit var coroutineClassThis: IrValueParameterSymbol
|
||||||
|
private lateinit var argumentToPropertiesMap: Map<ParameterDescriptor, IrFieldSymbol>
|
||||||
|
|
||||||
private val coroutineImplClassDescriptor = context.builtIns.getKonanInternalClass("CoroutineImpl")
|
private val coroutineImplClassDescriptor = context.builtIns.getKonanInternalClass("CoroutineImpl")
|
||||||
private val create1FunctionDescriptor = coroutineImplClassDescriptor.unsubstitutedMemberScope
|
private val create1FunctionDescriptor = coroutineImplClassDescriptor.unsubstitutedMemberScope
|
||||||
@@ -353,23 +358,34 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
/* source = */ SourceElement.NO_SOURCE,
|
/* source = */ SourceElement.NO_SOURCE,
|
||||||
/* isExternal = */ false
|
/* isExternal = */ false
|
||||||
)
|
)
|
||||||
|
coroutineClass = IrClassImpl(
|
||||||
|
startOffset = irFunction.startOffset,
|
||||||
|
endOffset = irFunction.endOffset,
|
||||||
|
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
||||||
|
descriptor = coroutineClassDescriptor
|
||||||
|
)
|
||||||
|
|
||||||
|
coroutineClass.createParameterDeclarations()
|
||||||
|
|
||||||
|
coroutineClassThis = coroutineClass.thisReceiver!!.symbol
|
||||||
|
|
||||||
val overriddenMap = mutableMapOf<CallableMemberDescriptor, CallableMemberDescriptor>()
|
val overriddenMap = mutableMapOf<CallableMemberDescriptor, CallableMemberDescriptor>()
|
||||||
val constructors = mutableSetOf<ClassConstructorDescriptor>()
|
val constructors = mutableSetOf<ClassConstructorDescriptor>()
|
||||||
val coroutineConstructorBuilder = createConstructorBuilder()
|
val coroutineConstructorBuilder = createConstructorBuilder()
|
||||||
constructors.add(coroutineConstructorBuilder.descriptor)
|
constructors.add(coroutineConstructorBuilder.symbol.descriptor)
|
||||||
|
|
||||||
val doResumeFunctionDescriptor = coroutineImplClassDescriptor.unsubstitutedMemberScope
|
val doResumeFunctionDescriptor = coroutineImplClassDescriptor.unsubstitutedMemberScope
|
||||||
.getContributedFunctions(Name.identifier("doResume"), NoLookupLocation.FROM_BACKEND).single()
|
.getContributedFunctions(Name.identifier("doResume"), NoLookupLocation.FROM_BACKEND).single()
|
||||||
val doResumeMethodBuilder = createDoResumeMethodBuilder(doResumeFunctionDescriptor)
|
val doResumeMethodBuilder = createDoResumeMethodBuilder(doResumeFunctionDescriptor)
|
||||||
overriddenMap += doResumeFunctionDescriptor to doResumeMethodBuilder.descriptor
|
overriddenMap += doResumeFunctionDescriptor to doResumeMethodBuilder.symbol.descriptor
|
||||||
|
|
||||||
var coroutineFactoryConstructorBuilder: DescriptorWithIrBuilder<ClassConstructorDescriptor, IrConstructor>? = null
|
var coroutineFactoryConstructorBuilder: SymbolWithIrBuilder<IrConstructorSymbol, IrConstructor>? = null
|
||||||
var createMethodBuilder: DescriptorWithIrBuilder<FunctionDescriptor, IrFunction>? = null
|
var createMethodBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>? = null
|
||||||
var invokeMethodBuilder: DescriptorWithIrBuilder<FunctionDescriptor, IrFunction>? = null
|
var invokeMethodBuilder: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>? = null
|
||||||
if (callableReference != null) {
|
if (functionReference != null) {
|
||||||
// Suspend lambda - create factory methods.
|
// Suspend lambda - create factory methods.
|
||||||
coroutineFactoryConstructorBuilder = createFactoryConstructorBuilder(boundFunctionParameters!!)
|
coroutineFactoryConstructorBuilder = createFactoryConstructorBuilder(boundFunctionParameters!!)
|
||||||
constructors.add(coroutineFactoryConstructorBuilder.descriptor)
|
constructors.add(coroutineFactoryConstructorBuilder.symbol.descriptor)
|
||||||
|
|
||||||
val createFunctionDescriptor = coroutineImplClassDescriptor.unsubstitutedMemberScope
|
val createFunctionDescriptor = coroutineImplClassDescriptor.unsubstitutedMemberScope
|
||||||
.getContributedFunctions(Name.identifier("create"), NoLookupLocation.FROM_BACKEND)
|
.getContributedFunctions(Name.identifier("create"), NoLookupLocation.FROM_BACKEND)
|
||||||
@@ -377,9 +393,9 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
createMethodBuilder = createCreateMethodBuilder(
|
createMethodBuilder = createCreateMethodBuilder(
|
||||||
unboundArgs = unboundFunctionParameters!!,
|
unboundArgs = unboundFunctionParameters!!,
|
||||||
superFunctionDescriptor = createFunctionDescriptor,
|
superFunctionDescriptor = createFunctionDescriptor,
|
||||||
coroutineConstructorDescriptor = coroutineConstructorBuilder.descriptor)
|
coroutineConstructorSymbol = coroutineConstructorBuilder.symbol)
|
||||||
if (createFunctionDescriptor != null)
|
if (createFunctionDescriptor != null)
|
||||||
overriddenMap += createFunctionDescriptor to createMethodBuilder.descriptor
|
overriddenMap += createFunctionDescriptor to createMethodBuilder.symbol.descriptor
|
||||||
|
|
||||||
val invokeFunctionDescriptor = functionClassDescriptor!!.unsubstitutedMemberScope
|
val invokeFunctionDescriptor = functionClassDescriptor!!.unsubstitutedMemberScope
|
||||||
.getContributedFunctions(Name.identifier("invoke"), NoLookupLocation.FROM_BACKEND).single()
|
.getContributedFunctions(Name.identifier("invoke"), NoLookupLocation.FROM_BACKEND).single()
|
||||||
@@ -388,73 +404,63 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
invokeMethodBuilder = createInvokeMethodBuilder(
|
invokeMethodBuilder = createInvokeMethodBuilder(
|
||||||
suspendFunctionInvokeFunctionDescriptor = suspendInvokeFunctionDescriptor,
|
suspendFunctionInvokeFunctionDescriptor = suspendInvokeFunctionDescriptor,
|
||||||
functionInvokeFunctionDescriptor = invokeFunctionDescriptor,
|
functionInvokeFunctionDescriptor = invokeFunctionDescriptor,
|
||||||
createFunctionDescriptor = createMethodBuilder.descriptor,
|
createFunctionSymbol = createMethodBuilder.symbol,
|
||||||
doResumeFunctionDescriptor = doResumeMethodBuilder.descriptor)
|
doResumeFunctionSymbol = doResumeMethodBuilder.symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
val inheritedFromCoroutineImpl = coroutineImplClassDescriptor.unsubstitutedMemberScope
|
val inheritedFromCoroutineImpl = coroutineImplClassDescriptor.unsubstitutedMemberScope
|
||||||
.getContributedDescriptors()
|
.getContributedDescriptors()
|
||||||
.map { overriddenMap[it] ?: it.createFakeOverrideDescriptor(coroutineClassDescriptor) }
|
.map { overriddenMap[it] ?: it.createFakeOverrideDescriptor(coroutineClassDescriptor) }
|
||||||
val contributedDescriptors = (
|
val contributedDescriptors = (
|
||||||
inheritedFromCoroutineImpl + invokeMethodBuilder?.descriptor
|
inheritedFromCoroutineImpl + invokeMethodBuilder?.symbol?.descriptor
|
||||||
).filterNotNull().toList()
|
).filterNotNull().toList()
|
||||||
coroutineClassDescriptor.initialize(SimpleMemberScope(contributedDescriptors), constructors, null)
|
coroutineClassDescriptor.initialize(SimpleMemberScope(contributedDescriptors), constructors, null)
|
||||||
|
|
||||||
coroutineConstructorBuilder.initialize()
|
coroutineConstructorBuilder.initialize()
|
||||||
coroutineMembers.add(coroutineConstructorBuilder.ir)
|
coroutineClass.declarations.add(coroutineConstructorBuilder.ir)
|
||||||
|
|
||||||
coroutineFactoryConstructorBuilder?.let {
|
coroutineFactoryConstructorBuilder?.let {
|
||||||
it.initialize()
|
it.initialize()
|
||||||
coroutineMembers.add(it.ir)
|
coroutineClass.declarations.add(it.ir)
|
||||||
}
|
}
|
||||||
|
|
||||||
createMethodBuilder?.let {
|
createMethodBuilder?.let {
|
||||||
it.initialize()
|
it.initialize()
|
||||||
coroutineMembers.add(it.ir)
|
coroutineClass.declarations.add(it.ir)
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeMethodBuilder?.let {
|
invokeMethodBuilder?.let {
|
||||||
it.initialize()
|
it.initialize()
|
||||||
coroutineMembers.add(it.ir)
|
coroutineClass.declarations.add(it.ir)
|
||||||
}
|
}
|
||||||
|
|
||||||
doResumeMethodBuilder.initialize()
|
doResumeMethodBuilder.initialize()
|
||||||
coroutineMembers.add(doResumeMethodBuilder.ir)
|
coroutineClass.declarations.add(doResumeMethodBuilder.ir)
|
||||||
|
|
||||||
val coroutineClass = IrClassImpl(
|
|
||||||
startOffset = irFunction.startOffset,
|
|
||||||
endOffset = irFunction.endOffset,
|
|
||||||
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
|
||||||
descriptor = coroutineClassDescriptor,
|
|
||||||
members = coroutineMembers
|
|
||||||
)
|
|
||||||
|
|
||||||
coroutineClass.createParameterDeclarations()
|
|
||||||
|
|
||||||
return BuiltCoroutine(
|
return BuiltCoroutine(
|
||||||
coroutineClass = coroutineClass,
|
coroutineClass = coroutineClass,
|
||||||
coroutineConstructorDescriptor = coroutineFactoryConstructorBuilder?.descriptor
|
coroutineConstructor = coroutineFactoryConstructorBuilder?.ir
|
||||||
?: coroutineConstructorBuilder.descriptor,
|
?: coroutineConstructorBuilder.ir,
|
||||||
doResumeFunctionDescriptor = doResumeMethodBuilder.descriptor)
|
doResumeFunction = doResumeMethodBuilder.ir)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createConstructorBuilder()
|
private fun createConstructorBuilder()
|
||||||
= object : DescriptorWithIrBuilder<ClassConstructorDescriptorImpl, IrConstructor>() {
|
= object : SymbolWithIrBuilder<IrConstructorSymbol, IrConstructor>() {
|
||||||
|
|
||||||
private val coroutineImplConstructorDescriptor = coroutineImplClassDescriptor.constructors.single()
|
private val coroutineImplConstructorDescriptor = coroutineImplClassDescriptor.constructors.single()
|
||||||
private lateinit var constructorParameters: List<ValueParameterDescriptor>
|
|
||||||
|
|
||||||
override fun buildDescriptor(): ClassConstructorDescriptorImpl {
|
override fun buildSymbol() = IrConstructorSymbolImpl(
|
||||||
return ClassConstructorDescriptorImpl.create(
|
ClassConstructorDescriptorImpl.create(
|
||||||
/* containingDeclaration = */ coroutineClassDescriptor,
|
/* containingDeclaration = */ coroutineClassDescriptor,
|
||||||
/* annotations = */ Annotations.EMPTY,
|
/* annotations = */ Annotations.EMPTY,
|
||||||
/* isPrimary = */ false,
|
/* isPrimary = */ false,
|
||||||
/* source = */ SourceElement.NO_SOURCE
|
/* source = */ SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
|
|
||||||
override fun doInitialize() {
|
override fun doInitialize() {
|
||||||
constructorParameters = (
|
val descriptor = symbol.descriptor as ClassConstructorDescriptorImpl
|
||||||
|
val constructorParameters = (
|
||||||
functionParameters
|
functionParameters
|
||||||
+ coroutineImplConstructorDescriptor.valueParameters[0] // completion.
|
+ coroutineImplConstructorDescriptor.valueParameters[0] // completion.
|
||||||
).mapIndexed { index, parameter -> parameter.copyAsValueParameter(descriptor, index) }
|
).mapIndexed { index, parameter -> parameter.copyAsValueParameter(descriptor, index) }
|
||||||
@@ -471,23 +477,23 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
|
|
||||||
val startOffset = irFunction.startOffset
|
val startOffset = irFunction.startOffset
|
||||||
val endOffset = irFunction.endOffset
|
val endOffset = irFunction.endOffset
|
||||||
val irBuilder = context.createIrBuilder(descriptor, startOffset, endOffset)
|
|
||||||
return IrConstructorImpl(
|
return IrConstructorImpl(
|
||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset,
|
endOffset = endOffset,
|
||||||
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
||||||
descriptor = descriptor).apply {
|
symbol = symbol).apply {
|
||||||
|
|
||||||
createParameterDeclarations()
|
createParameterDeclarations()
|
||||||
|
|
||||||
|
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
|
||||||
body = irBuilder.irBlockBody {
|
body = irBuilder.irBlockBody {
|
||||||
val completionParameter = descriptor.valueParameters.last()
|
val completionParameter = valueParameters.last()
|
||||||
+IrDelegatingConstructorCallImpl(startOffset, endOffset, coroutineImplConstructorDescriptor).apply {
|
+IrDelegatingConstructorCallImpl(startOffset, endOffset, coroutineImplConstructorDescriptor).apply {
|
||||||
putValueArgument(0, irGet(completionParameter))
|
putValueArgument(0, irGet(completionParameter.symbol))
|
||||||
}
|
}
|
||||||
+IrInstanceInitializerCallImpl(startOffset, endOffset, coroutineClassDescriptor)
|
+IrInstanceInitializerCallImpl(startOffset, endOffset, coroutineClass.symbol)
|
||||||
functionParameters.forEachIndexed { index, parameter ->
|
functionParameters.forEachIndexed { index, parameter ->
|
||||||
+irSetField(irThis(), argumentToPropertiesMap[parameter]!!, irGet(constructorParameters[index]))
|
+irSetField(irGet(coroutineClassThis), argumentToPropertiesMap[parameter]!!, irGet(valueParameters[index].symbol))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -495,22 +501,22 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createFactoryConstructorBuilder(boundParams: List<ParameterDescriptor>)
|
private fun createFactoryConstructorBuilder(boundParams: List<ParameterDescriptor>)
|
||||||
= object : DescriptorWithIrBuilder<ClassConstructorDescriptorImpl, IrConstructor>() {
|
= object : SymbolWithIrBuilder<IrConstructorSymbol, IrConstructor>() {
|
||||||
|
|
||||||
private val coroutineImplConstructorDescriptor = coroutineImplClassDescriptor.constructors.single()
|
private val coroutineImplConstructorDescriptor = coroutineImplClassDescriptor.constructors.single()
|
||||||
private lateinit var constructorParameters: List<ValueParameterDescriptor>
|
|
||||||
|
|
||||||
override fun buildDescriptor(): ClassConstructorDescriptorImpl {
|
override fun buildSymbol() = IrConstructorSymbolImpl(
|
||||||
return ClassConstructorDescriptorImpl.create(
|
ClassConstructorDescriptorImpl.create(
|
||||||
/* containingDeclaration = */ coroutineClassDescriptor,
|
/* containingDeclaration = */ coroutineClassDescriptor,
|
||||||
/* annotations = */ Annotations.EMPTY,
|
/* annotations = */ Annotations.EMPTY,
|
||||||
/* isPrimary = */ false,
|
/* isPrimary = */ false,
|
||||||
/* source = */ SourceElement.NO_SOURCE
|
/* source = */ SourceElement.NO_SOURCE
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
|
|
||||||
override fun doInitialize() {
|
override fun doInitialize() {
|
||||||
constructorParameters = boundParams.mapIndexed { index, parameter ->
|
val descriptor = symbol.descriptor as ClassConstructorDescriptorImpl
|
||||||
|
val constructorParameters = boundParams.mapIndexed { index, parameter ->
|
||||||
parameter.copyAsValueParameter(descriptor, index)
|
parameter.copyAsValueParameter(descriptor, index)
|
||||||
}
|
}
|
||||||
descriptor.initialize(constructorParameters, Visibilities.PUBLIC)
|
descriptor.initialize(constructorParameters, Visibilities.PUBLIC)
|
||||||
@@ -520,23 +526,23 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
override fun buildIr(): IrConstructor {
|
override fun buildIr(): IrConstructor {
|
||||||
val startOffset = irFunction.startOffset
|
val startOffset = irFunction.startOffset
|
||||||
val endOffset = irFunction.endOffset
|
val endOffset = irFunction.endOffset
|
||||||
val irBuilder = context.createIrBuilder(descriptor, startOffset, endOffset)
|
|
||||||
return IrConstructorImpl(
|
return IrConstructorImpl(
|
||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset,
|
endOffset = endOffset,
|
||||||
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
||||||
descriptor = descriptor).apply {
|
symbol = symbol).apply {
|
||||||
|
|
||||||
createParameterDeclarations()
|
createParameterDeclarations()
|
||||||
|
|
||||||
|
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
|
||||||
body = irBuilder.irBlockBody {
|
body = irBuilder.irBlockBody {
|
||||||
+IrDelegatingConstructorCallImpl(startOffset, endOffset, coroutineImplConstructorDescriptor).apply {
|
+IrDelegatingConstructorCallImpl(startOffset, endOffset, coroutineImplConstructorDescriptor).apply {
|
||||||
putValueArgument(0, irNull()) // Completion.
|
putValueArgument(0, irNull()) // Completion.
|
||||||
}
|
}
|
||||||
+IrInstanceInitializerCallImpl(startOffset, endOffset, coroutineClassDescriptor)
|
+IrInstanceInitializerCallImpl(startOffset, endOffset, coroutineClass.symbol)
|
||||||
// Save all arguments to fields.
|
// Save all arguments to fields.
|
||||||
boundParams.forEachIndexed { index, parameter ->
|
boundParams.forEachIndexed { index, parameter ->
|
||||||
+irSetField(irThis(), argumentToPropertiesMap[parameter]!!, irGet(constructorParameters[index]))
|
+irSetField(irGet(coroutineClassThis), argumentToPropertiesMap[parameter]!!, irGet(valueParameters[index].symbol))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -545,17 +551,21 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
|
|
||||||
private fun createCreateMethodBuilder(unboundArgs: List<ParameterDescriptor>,
|
private fun createCreateMethodBuilder(unboundArgs: List<ParameterDescriptor>,
|
||||||
superFunctionDescriptor: FunctionDescriptor?,
|
superFunctionDescriptor: FunctionDescriptor?,
|
||||||
coroutineConstructorDescriptor: ClassConstructorDescriptor)
|
coroutineConstructorSymbol: IrConstructorSymbol)
|
||||||
= object: DescriptorWithIrBuilder<SimpleFunctionDescriptorImpl, IrFunction>() {
|
= object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
||||||
|
|
||||||
override fun buildDescriptor() = SimpleFunctionDescriptorImpl.create(
|
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
||||||
|
SimpleFunctionDescriptorImpl.create(
|
||||||
/* containingDeclaration = */ coroutineClassDescriptor,
|
/* containingDeclaration = */ coroutineClassDescriptor,
|
||||||
/* annotations = */ Annotations.EMPTY,
|
/* annotations = */ Annotations.EMPTY,
|
||||||
/* name = */ Name.identifier("create"),
|
/* name = */ Name.identifier("create"),
|
||||||
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
||||||
/* source = */ SourceElement.NO_SOURCE)
|
/* source = */ SourceElement.NO_SOURCE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
override fun doInitialize() {
|
override fun doInitialize() {
|
||||||
|
val descriptor = symbol.descriptor as SimpleFunctionDescriptorImpl
|
||||||
val valueParameters = (
|
val valueParameters = (
|
||||||
unboundArgs + create1CompletionParameter
|
unboundArgs + create1CompletionParameter
|
||||||
).mapIndexed { index, parameter ->
|
).mapIndexed { index, parameter ->
|
||||||
@@ -577,34 +587,33 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun buildIr(): IrFunction {
|
override fun buildIr(): IrSimpleFunction {
|
||||||
val startOffset = irFunction.startOffset
|
val startOffset = irFunction.startOffset
|
||||||
val endOffset = irFunction.endOffset
|
val endOffset = irFunction.endOffset
|
||||||
val ourDescriptor = descriptor
|
|
||||||
val irBuilder = context.createIrBuilder(descriptor, startOffset, endOffset)
|
|
||||||
return IrFunctionImpl(
|
return IrFunctionImpl(
|
||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset,
|
endOffset = endOffset,
|
||||||
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
||||||
descriptor = descriptor).apply {
|
symbol = symbol).apply {
|
||||||
|
|
||||||
createParameterDeclarations()
|
createParameterDeclarations()
|
||||||
|
|
||||||
|
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
|
||||||
body = irBuilder.irBlockBody(startOffset, endOffset) {
|
body = irBuilder.irBlockBody(startOffset, endOffset) {
|
||||||
+irReturn(
|
+irReturn(
|
||||||
irCall(coroutineConstructorDescriptor).apply {
|
irCall(coroutineConstructorSymbol).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(ourDescriptor.valueParameters[unboundIndex++])
|
irGet(valueParameters[unboundIndex++].symbol)
|
||||||
else
|
else
|
||||||
irGet(irThis(), argumentToPropertiesMap[it]!!)
|
irGetField(irGet(coroutineClassThis), argumentToPropertiesMap[it]!!)
|
||||||
}.forEachIndexed { index, argument ->
|
}.forEachIndexed { index, argument ->
|
||||||
putValueArgument(index, argument)
|
putValueArgument(index, argument)
|
||||||
}
|
}
|
||||||
putValueArgument(functionParameters.size, irGet(ourDescriptor.valueParameters[unboundIndex]))
|
putValueArgument(functionParameters.size, irGet(valueParameters[unboundIndex].symbol))
|
||||||
assert(unboundIndex == ourDescriptor.valueParameters.size - 1,
|
assert(unboundIndex == valueParameters.size - 1,
|
||||||
{ "Not all arguments of <create> are used" })
|
{ "Not all arguments of <create> are used" })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -614,24 +623,28 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
|
|
||||||
private fun createInvokeMethodBuilder(suspendFunctionInvokeFunctionDescriptor: FunctionDescriptor,
|
private fun createInvokeMethodBuilder(suspendFunctionInvokeFunctionDescriptor: FunctionDescriptor,
|
||||||
functionInvokeFunctionDescriptor: FunctionDescriptor,
|
functionInvokeFunctionDescriptor: FunctionDescriptor,
|
||||||
createFunctionDescriptor: FunctionDescriptor,
|
createFunctionSymbol: IrFunctionSymbol,
|
||||||
doResumeFunctionDescriptor: FunctionDescriptor)
|
doResumeFunctionSymbol: IrFunctionSymbol)
|
||||||
= object: DescriptorWithIrBuilder<SimpleFunctionDescriptorImpl, IrFunction>() {
|
= object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
||||||
|
|
||||||
override fun buildDescriptor() = SimpleFunctionDescriptorImpl.create(
|
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
||||||
|
SimpleFunctionDescriptorImpl.create(
|
||||||
/* containingDeclaration = */ coroutineClassDescriptor,
|
/* containingDeclaration = */ coroutineClassDescriptor,
|
||||||
/* annotations = */ Annotations.EMPTY,
|
/* annotations = */ Annotations.EMPTY,
|
||||||
/* name = */ Name.identifier("invoke"),
|
/* name = */ Name.identifier("invoke"),
|
||||||
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
||||||
/* source = */ SourceElement.NO_SOURCE)
|
/* source = */ SourceElement.NO_SOURCE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
override fun doInitialize() {
|
override fun doInitialize() {
|
||||||
val valueParameters = createFunctionDescriptor.valueParameters
|
val descriptor = symbol.descriptor as SimpleFunctionDescriptorImpl
|
||||||
|
val valueParameters = createFunctionSymbol.descriptor.valueParameters
|
||||||
// Skip completion - invoke() already has it implicitly as a suspend function.
|
// Skip completion - invoke() already has it implicitly as a suspend function.
|
||||||
.take(createFunctionDescriptor.valueParameters.size - 1)
|
.take(createFunctionSymbol.descriptor.valueParameters.size - 1)
|
||||||
.map { it.copyAsValueParameter(this.descriptor, it.index) }
|
.map { it.copyAsValueParameter(descriptor, it.index) }
|
||||||
|
|
||||||
this.descriptor.initialize(
|
descriptor.initialize(
|
||||||
/* receiverParameterType = */ null,
|
/* receiverParameterType = */ null,
|
||||||
/* dispatchReceiverParameter = */ coroutineClassDescriptor.thisAsReceiverParameter,
|
/* dispatchReceiverParameter = */ coroutineClassDescriptor.thisAsReceiverParameter,
|
||||||
/* typeParameters = */ emptyList(),
|
/* typeParameters = */ emptyList(),
|
||||||
@@ -645,29 +658,28 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun buildIr(): IrFunction {
|
override fun buildIr(): IrSimpleFunction {
|
||||||
val startOffset = irFunction.startOffset
|
val startOffset = irFunction.startOffset
|
||||||
val endOffset = irFunction.endOffset
|
val endOffset = irFunction.endOffset
|
||||||
val ourDescriptor = this.descriptor
|
|
||||||
val irBuilder = context.createIrBuilder(this.descriptor, startOffset, endOffset)
|
|
||||||
return IrFunctionImpl(
|
return IrFunctionImpl(
|
||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset,
|
endOffset = endOffset,
|
||||||
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
||||||
descriptor = this.descriptor).apply {
|
symbol = symbol).apply {
|
||||||
|
|
||||||
createParameterDeclarations()
|
createParameterDeclarations()
|
||||||
|
|
||||||
|
val irBuilder = context.createIrBuilder(symbol, startOffset, endOffset)
|
||||||
body = irBuilder.irBlockBody(startOffset, endOffset) {
|
body = irBuilder.irBlockBody(startOffset, endOffset) {
|
||||||
+irReturn(
|
+irReturn(
|
||||||
irCall(doResumeFunctionDescriptor).apply {
|
irCall(doResumeFunctionSymbol).apply {
|
||||||
dispatchReceiver = irCall(createFunctionDescriptor).apply {
|
dispatchReceiver = irCall(createFunctionSymbol).apply {
|
||||||
dispatchReceiver = irThis()
|
dispatchReceiver = irGet(coroutineClassThis)
|
||||||
ourDescriptor.valueParameters.forEach {
|
valueParameters.forEachIndexed { index, parameter ->
|
||||||
putValueArgument(it.index, irGet(it))
|
putValueArgument(index, irGet(parameter.symbol))
|
||||||
}
|
}
|
||||||
putValueArgument(ourDescriptor.valueParameters.size,
|
putValueArgument(valueParameters.size,
|
||||||
irCall(getContinuationDescriptor.substitute(ourDescriptor.returnType!!)))
|
irCall(getContinuationDescriptor.substitute(symbol.descriptor.returnType!!)))
|
||||||
}
|
}
|
||||||
putValueArgument(0, irUnit()) // value
|
putValueArgument(0, irUnit()) // value
|
||||||
putValueArgument(1, irNull()) // exception
|
putValueArgument(1, irNull()) // exception
|
||||||
@@ -678,7 +690,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildPropertyWithBackingField(name: Name, type: KotlinType, isMutable: Boolean): PropertyDescriptor {
|
private fun buildPropertyWithBackingField(name: Name, type: KotlinType, isMutable: Boolean): IrFieldSymbol {
|
||||||
val propertyBuilder = context.createPropertyWithBackingFieldBuilder(
|
val propertyBuilder = context.createPropertyWithBackingFieldBuilder(
|
||||||
startOffset = irFunction.startOffset,
|
startOffset = irFunction.startOffset,
|
||||||
endOffset = irFunction.endOffset,
|
endOffset = irFunction.endOffset,
|
||||||
@@ -690,65 +702,74 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
initialize()
|
initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
coroutineMembers.add(propertyBuilder.ir)
|
coroutineClass.declarations.add(propertyBuilder.ir)
|
||||||
return propertyBuilder.descriptor
|
return propertyBuilder.symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDoResumeMethodBuilder(doResumeFunctionDescriptor: FunctionDescriptor)
|
private fun createDoResumeMethodBuilder(doResumeFunctionDescriptor: FunctionDescriptor)
|
||||||
= object: DescriptorWithIrBuilder<FunctionDescriptor, IrFunction>() {
|
= object: SymbolWithIrBuilder<IrSimpleFunctionSymbol, IrSimpleFunction>() {
|
||||||
|
|
||||||
override fun buildDescriptor() = doResumeFunctionDescriptor.createOverriddenDescriptor(coroutineClassDescriptor)
|
override fun buildSymbol() = IrSimpleFunctionSymbolImpl(
|
||||||
|
doResumeFunctionDescriptor.createOverriddenDescriptor(coroutineClassDescriptor)
|
||||||
|
)
|
||||||
|
|
||||||
override fun doInitialize() { }
|
override fun doInitialize() { }
|
||||||
|
|
||||||
override fun buildIr(): IrFunction {
|
override fun buildIr(): IrSimpleFunction {
|
||||||
dataArgument = descriptor.valueParameters[0]
|
val originalBody = irFunction.body!!
|
||||||
exceptionArgument = descriptor.valueParameters[1]
|
val startOffset = irFunction.startOffset
|
||||||
suspendResult = IrTemporaryVariableDescriptorImpl(
|
val endOffset = irFunction.endOffset
|
||||||
|
val function = IrFunctionImpl(
|
||||||
|
startOffset = startOffset,
|
||||||
|
endOffset = endOffset,
|
||||||
|
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
||||||
|
symbol = symbol).apply {
|
||||||
|
|
||||||
|
createParameterDeclarations()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
dataArgument = function.valueParameters[0].symbol
|
||||||
|
exceptionArgument = function.valueParameters[1].symbol
|
||||||
|
suspendResult = IrVariableSymbolImpl(
|
||||||
|
IrTemporaryVariableDescriptorImpl(
|
||||||
containingDeclaration = irFunction.descriptor,
|
containingDeclaration = irFunction.descriptor,
|
||||||
name = "suspendResult".synthesizedName,
|
name = "suspendResult".synthesizedName,
|
||||||
outType = context.builtIns.nullableAnyType,
|
outType = context.builtIns.nullableAnyType,
|
||||||
isMutable = true)
|
isMutable = true)
|
||||||
|
)
|
||||||
val label = coroutineClassDescriptor.unsubstitutedMemberScope
|
val label = coroutineClassDescriptor.unsubstitutedMemberScope
|
||||||
.getContributedVariables(Name.identifier("label"), NoLookupLocation.FROM_BACKEND).single()
|
.getContributedVariables(Name.identifier("label"), NoLookupLocation.FROM_BACKEND).single()
|
||||||
|
|
||||||
val originalBody = irFunction.body!!
|
val irBuilder = context.createIrBuilder(function.symbol, startOffset, endOffset)
|
||||||
val startOffset = irFunction.startOffset
|
function.body = irBuilder.irBlockBody(startOffset, endOffset) {
|
||||||
val endOffset = irFunction.endOffset
|
|
||||||
val irBuilder = context.createIrBuilder(descriptor, startOffset, endOffset)
|
|
||||||
return IrFunctionImpl(
|
|
||||||
startOffset = startOffset,
|
|
||||||
endOffset = endOffset,
|
|
||||||
origin = DECLARATION_ORIGIN_COROUTINE_IMPL,
|
|
||||||
descriptor = descriptor).apply {
|
|
||||||
|
|
||||||
createParameterDeclarations()
|
|
||||||
|
|
||||||
body = irBuilder.irBlockBody(startOffset, endOffset) {
|
|
||||||
|
|
||||||
// Extract all suspend calls to temporaries in order to make correct jumps to them.
|
// Extract all suspend calls to temporaries in order to make correct jumps to them.
|
||||||
originalBody.transformChildrenVoid(ExpressionSlicer(label.type))
|
originalBody.transformChildrenVoid(ExpressionSlicer(label.type))
|
||||||
|
|
||||||
val liveLocals = computeLivenessAtSuspensionPoints(originalBody)
|
val liveLocals = computeLivenessAtSuspensionPoints(originalBody)
|
||||||
|
|
||||||
val immutableLiveLocals = liveLocals.values.flatten().filterNot { it.isVar }.toSet()
|
val immutableLiveLocals = liveLocals.values.flatten().filterNot { it.descriptor.isVar }.toSet()
|
||||||
val localsMap = immutableLiveLocals.associate {
|
val localsMap = immutableLiveLocals.associate {
|
||||||
it to IrTemporaryVariableDescriptorImpl(
|
// TODO: Remove .descriptor as soon as all symbols are bound.
|
||||||
|
it.descriptor to IrVariableSymbolImpl(
|
||||||
|
IrTemporaryVariableDescriptorImpl(
|
||||||
containingDeclaration = irFunction.descriptor,
|
containingDeclaration = irFunction.descriptor,
|
||||||
name = it.name,
|
name = it.descriptor.name,
|
||||||
outType = it.type,
|
outType = it.descriptor.type,
|
||||||
isMutable = true)
|
isMutable = true)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localsMap.isNotEmpty())
|
if (localsMap.isNotEmpty())
|
||||||
transformVariables(originalBody, localsMap) // Make variables mutable in order to save/restore them.
|
transformVariables(originalBody, localsMap) // Make variables mutable in order to save/restore them.
|
||||||
|
|
||||||
val localToPropertyMap = mutableMapOf<VariableDescriptor, PropertyDescriptor>()
|
val localToPropertyMap = mutableMapOf<IrVariableSymbol, IrFieldSymbol>()
|
||||||
// TODO: optimize by using the same property for different locals.
|
// TODO: optimize by using the same property for different locals.
|
||||||
liveLocals.values.forEach { scope ->
|
liveLocals.values.forEach { scope ->
|
||||||
scope.forEach {
|
scope.forEach {
|
||||||
localToPropertyMap.getOrPut(it) {
|
localToPropertyMap.getOrPut(it) {
|
||||||
buildPropertyWithBackingField(it.name, it.type, true)
|
buildPropertyWithBackingField(it.descriptor.name, it.descriptor.type, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -771,7 +792,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
|
|
||||||
val capturedValue = argumentToPropertiesMap[expression.descriptor]
|
val capturedValue = argumentToPropertiesMap[expression.descriptor]
|
||||||
?: return expression
|
?: return expression
|
||||||
return irGet(irThis(), capturedValue)
|
return irGetField(irGet(coroutineClassThis), capturedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save/restore state at suspension points.
|
// Save/restore state at suspension points.
|
||||||
@@ -785,22 +806,21 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
val descriptor = expression.descriptor
|
when (expression.symbol) {
|
||||||
when (descriptor) {
|
saveStateSymbol -> {
|
||||||
saveStateDescriptor -> {
|
|
||||||
val scope = liveLocals[suspensionPoint]!!
|
val scope = liveLocals[suspensionPoint]!!
|
||||||
return irBlock(expression) {
|
return irBlock(expression) {
|
||||||
scope.forEach {
|
scope.forEach {
|
||||||
+irSet(irThis(), localToPropertyMap[it]!!, irGet(localsMap[it] ?: it))
|
+irSetField(irGet(coroutineClassThis), localToPropertyMap[it]!!, irGet(localsMap[it.descriptor] ?: it))
|
||||||
}
|
}
|
||||||
+irSet(irThis(), label, irGet(suspensionPoint.suspensionPointIdParameter.descriptor))
|
+irSet(irGet(coroutineClassThis), label, irGet(suspensionPoint.suspensionPointIdParameter.symbol))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
restoreStateDescriptor -> {
|
restoreStateSymbol -> {
|
||||||
val scope = liveLocals[suspensionPoint]!!
|
val scope = liveLocals[suspensionPoint]!!
|
||||||
return irBlock(expression) {
|
return irBlock(expression) {
|
||||||
scope.forEach {
|
scope.forEach {
|
||||||
+irSetVar(localsMap[it] ?: it, irGet(irThis(), localToPropertyMap[it]!!))
|
+irSetVar(localsMap[it.descriptor] ?: it, irGetField(irGet(coroutineClassThis), localToPropertyMap[it]!!))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -818,7 +838,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
startOffset = startOffset,
|
startOffset = startOffset,
|
||||||
endOffset = endOffset,
|
endOffset = endOffset,
|
||||||
type = context.builtIns.unitType,
|
type = context.builtIns.unitType,
|
||||||
suspensionPointId = irGet(irThis(), label),
|
suspensionPointId = irGet(irGet(coroutineClassThis), label),
|
||||||
result = irBlock(startOffset, endOffset) {
|
result = irBlock(startOffset, endOffset) {
|
||||||
+irThrowIfNotNull(exceptionArgument) // Coroutine might start with an exception.
|
+irThrowIfNotNull(exceptionArgument) // Coroutine might start with an exception.
|
||||||
statements.forEach { +it }
|
statements.forEach { +it }
|
||||||
@@ -826,36 +846,36 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
if (irFunction.descriptor.returnType!!.isUnit())
|
if (irFunction.descriptor.returnType!!.isUnit())
|
||||||
+irReturn(irUnit()) // Insert explicit return for Unit functions.
|
+irReturn(irUnit()) // Insert explicit return for Unit functions.
|
||||||
}
|
}
|
||||||
}
|
return function
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun transformVariables(element: IrElement, variablesMap: Map<VariableDescriptor, VariableDescriptor>) {
|
private fun transformVariables(element: IrElement, variablesMap: Map<VariableDescriptor, IrVariableSymbol>) {
|
||||||
element.transformChildrenVoid(object: IrElementTransformerVoid() {
|
element.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
val newVariable = variablesMap[expression.descriptor]
|
val newVariable = variablesMap[expression.symbol.descriptor]
|
||||||
?: return expression
|
?: return expression
|
||||||
|
|
||||||
return IrGetValueImpl(
|
return IrGetValueImpl(
|
||||||
startOffset = expression.startOffset,
|
startOffset = expression.startOffset,
|
||||||
endOffset = expression.endOffset,
|
endOffset = expression.endOffset,
|
||||||
descriptor = newVariable,
|
symbol = newVariable,
|
||||||
origin = expression.origin)
|
origin = expression.origin)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSetVariable(expression: IrSetVariable): IrExpression {
|
override fun visitSetVariable(expression: IrSetVariable): IrExpression {
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
val newVariable = variablesMap[expression.descriptor]
|
val newVariable = variablesMap[expression.symbol.descriptor]
|
||||||
?: return expression
|
?: return expression
|
||||||
|
|
||||||
return IrSetVariableImpl(
|
return IrSetVariableImpl(
|
||||||
startOffset = expression.startOffset,
|
startOffset = expression.startOffset,
|
||||||
endOffset = expression.endOffset,
|
endOffset = expression.endOffset,
|
||||||
descriptor = newVariable,
|
symbol = newVariable,
|
||||||
value = expression.value,
|
value = expression.value,
|
||||||
origin = expression.origin)
|
origin = expression.origin)
|
||||||
}
|
}
|
||||||
@@ -863,23 +883,24 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
override fun visitVariable(declaration: IrVariable): IrStatement {
|
override fun visitVariable(declaration: IrVariable): IrStatement {
|
||||||
declaration.transformChildrenVoid(this)
|
declaration.transformChildrenVoid(this)
|
||||||
|
|
||||||
val newVariable = variablesMap[declaration.descriptor]
|
val newVariable = variablesMap[declaration.symbol.descriptor]
|
||||||
?: return declaration
|
?: return declaration
|
||||||
|
|
||||||
return IrVariableImpl(
|
return IrVariableImpl(
|
||||||
startOffset = declaration.startOffset,
|
startOffset = declaration.startOffset,
|
||||||
endOffset = declaration.endOffset,
|
endOffset = declaration.endOffset,
|
||||||
origin = declaration.origin,
|
origin = declaration.origin,
|
||||||
descriptor = newVariable,
|
symbol = newVariable).apply {
|
||||||
initializer = declaration.initializer)
|
initializer = declaration.initializer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun computeLivenessAtSuspensionPoints(body: IrBody): Map<IrSuspensionPoint, List<VariableDescriptor>> {
|
private fun computeLivenessAtSuspensionPoints(body: IrBody): Map<IrSuspensionPoint, List<IrVariableSymbol>> {
|
||||||
// TODO: data flow analysis.
|
// TODO: data flow analysis.
|
||||||
// Just save all visible for now.
|
// Just save all visible for now.
|
||||||
val result = mutableMapOf<IrSuspensionPoint, List<VariableDescriptor>>()
|
val result = mutableMapOf<IrSuspensionPoint, List<IrVariableSymbol>>()
|
||||||
body.acceptChildrenVoid(object: VariablesScopeTracker() {
|
body.acceptChildrenVoid(object: VariablesScopeTracker() {
|
||||||
|
|
||||||
override fun visitExpression(expression: IrExpression) {
|
override fun visitExpression(expression: IrExpression) {
|
||||||
@@ -892,7 +913,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
suspensionPoint.result.acceptChildrenVoid(this)
|
suspensionPoint.result.acceptChildrenVoid(this)
|
||||||
suspensionPoint.resumeResult.acceptChildrenVoid(this)
|
suspensionPoint.resumeResult.acceptChildrenVoid(this)
|
||||||
|
|
||||||
val visibleVariables = mutableListOf<VariableDescriptor>()
|
val visibleVariables = mutableListOf<IrVariableSymbol>()
|
||||||
scopeStack.forEach { visibleVariables += it }
|
scopeStack.forEach { visibleVariables += it }
|
||||||
result.put(suspensionPoint, visibleVariables)
|
result.put(suspensionPoint, visibleVariables)
|
||||||
}
|
}
|
||||||
@@ -902,7 +923,8 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
}
|
}
|
||||||
|
|
||||||
// These are marker descriptors to split up the lowering on two parts.
|
// These are marker descriptors to split up the lowering on two parts.
|
||||||
private val saveStateDescriptor = SimpleFunctionDescriptorImpl.create(
|
private val saveStateSymbol = IrSimpleFunctionSymbolImpl(
|
||||||
|
SimpleFunctionDescriptorImpl.create(
|
||||||
irFunction.descriptor,
|
irFunction.descriptor,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
"saveState".synthesizedName,
|
"saveState".synthesizedName,
|
||||||
@@ -910,8 +932,10 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
SourceElement.NO_SOURCE).apply {
|
SourceElement.NO_SOURCE).apply {
|
||||||
initialize(null, null, emptyList(), emptyList(), context.builtIns.unitType, Modality.ABSTRACT, Visibilities.PRIVATE)
|
initialize(null, null, emptyList(), emptyList(), context.builtIns.unitType, Modality.ABSTRACT, Visibilities.PRIVATE)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
private val restoreStateDescriptor = SimpleFunctionDescriptorImpl.create(
|
private val restoreStateSymbol = IrSimpleFunctionSymbolImpl(
|
||||||
|
SimpleFunctionDescriptorImpl.create(
|
||||||
irFunction.descriptor,
|
irFunction.descriptor,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
"restoreState".synthesizedName,
|
"restoreState".synthesizedName,
|
||||||
@@ -919,6 +943,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
SourceElement.NO_SOURCE).apply {
|
SourceElement.NO_SOURCE).apply {
|
||||||
initialize(null, null, emptyList(), emptyList(), context.builtIns.unitType, Modality.ABSTRACT, Visibilities.PRIVATE)
|
initialize(null, null, emptyList(), emptyList(), context.builtIns.unitType, Modality.ABSTRACT, Visibilities.PRIVATE)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
private inner class ExpressionSlicer(val suspensionPointIdType: KotlinType): IrElementTransformerVoid() {
|
private inner class ExpressionSlicer(val suspensionPointIdType: KotlinType): IrElementTransformerVoid() {
|
||||||
// TODO: optimize - it has square complexity.
|
// TODO: optimize - it has square complexity.
|
||||||
@@ -936,7 +961,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun sliceExpression(expression: IrExpression): IrExpression {
|
private fun sliceExpression(expression: IrExpression): IrExpression {
|
||||||
val irBuilder = context.createIrBuilder(irFunction.descriptor, expression.startOffset, expression.endOffset)
|
val irBuilder = context.createIrBuilder(irFunction.symbol, expression.startOffset, expression.endOffset)
|
||||||
irBuilder.run {
|
irBuilder.run {
|
||||||
val children = when (expression) {
|
val children = when (expression) {
|
||||||
is IrSetField -> listOf(expression.receiver, expression.value)
|
is IrSetField -> listOf(expression.receiver, expression.value)
|
||||||
@@ -977,10 +1002,12 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
newChildren[index] = transformedChild
|
newChildren[index] = transformedChild
|
||||||
else {
|
else {
|
||||||
// Save to temporary in order to save execution order.
|
// Save to temporary in order to save execution order.
|
||||||
val tmp = IrTemporaryVariableDescriptorImpl(
|
val tmp = IrVariableSymbolImpl(
|
||||||
|
IrTemporaryVariableDescriptorImpl(
|
||||||
containingDeclaration = irFunction.descriptor,
|
containingDeclaration = irFunction.descriptor,
|
||||||
name = "tmp${tempIndex++}".synthesizedName,
|
name = "tmp${tempIndex++}".synthesizedName,
|
||||||
outType = transformedChild.type)
|
outType = transformedChild.type)
|
||||||
|
)
|
||||||
tempStatements += irVar(tmp, transformedChild)
|
tempStatements += irVar(tmp, transformedChild)
|
||||||
newChildren[index] = irGet(tmp)
|
newChildren[index] = irGet(tmp)
|
||||||
}
|
}
|
||||||
@@ -995,15 +1022,17 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
newChildren[numberOfChildren - 1] =
|
newChildren[numberOfChildren - 1] =
|
||||||
irBlock(lastChild) {
|
irBlock(lastChild) {
|
||||||
if (lastChild.isPure()) {
|
if (lastChild.isPure()) {
|
||||||
+irCall(saveStateDescriptor)
|
+irCall(saveStateSymbol)
|
||||||
+lastChild
|
+lastChild
|
||||||
} else {
|
} else {
|
||||||
val tmp = IrTemporaryVariableDescriptorImpl(
|
val tmp = IrVariableSymbolImpl(
|
||||||
|
IrTemporaryVariableDescriptorImpl(
|
||||||
containingDeclaration = irFunction.descriptor,
|
containingDeclaration = irFunction.descriptor,
|
||||||
name = "tmp${tempIndex++}".synthesizedName,
|
name = "tmp${tempIndex++}".synthesizedName,
|
||||||
outType = lastChild.type)
|
outType = lastChild.type)
|
||||||
|
)
|
||||||
+irVar(tmp, lastChild)
|
+irVar(tmp, lastChild)
|
||||||
+irCall(saveStateDescriptor)
|
+irCall(saveStateSymbol)
|
||||||
+irGet(tmp)
|
+irGet(tmp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1041,13 +1070,13 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
suspensionPointIdParameter = irVar(suspensionPointIdParameter, null),
|
suspensionPointIdParameter = irVar(suspensionPointIdParameter, null),
|
||||||
result = irBlock(startOffset, endOffset) {
|
result = irBlock(startOffset, endOffset) {
|
||||||
if (!calledSaveState)
|
if (!calledSaveState)
|
||||||
+irCall(saveStateDescriptor)
|
+irCall(saveStateSymbol)
|
||||||
+irSetVar(suspendResult, suspendCall)
|
+irSetVar(suspendResult, suspendCall)
|
||||||
+irReturnIfSuspended(suspendResult)
|
+irReturnIfSuspended(suspendResult)
|
||||||
+irGet(suspendResult)
|
+irGet(suspendResult)
|
||||||
},
|
},
|
||||||
resumeResult = irBlock(startOffset, endOffset) {
|
resumeResult = irBlock(startOffset, endOffset) {
|
||||||
+irCall(restoreStateDescriptor)
|
+irCall(restoreStateSymbol)
|
||||||
+irThrowIfNotNull(exceptionArgument)
|
+irThrowIfNotNull(exceptionArgument)
|
||||||
+irGet(dataArgument)
|
+irGet(dataArgument)
|
||||||
})
|
})
|
||||||
@@ -1116,18 +1145,23 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
private fun IrBuilderWithScope.irVar(descriptor: VariableDescriptor, initializer: IrExpression?) =
|
private fun IrBuilderWithScope.irVar(descriptor: VariableDescriptor, initializer: IrExpression?) =
|
||||||
IrVariableImpl(startOffset, endOffset, DECLARATION_ORIGIN_COROUTINE_IMPL, descriptor, initializer)
|
IrVariableImpl(startOffset, endOffset, DECLARATION_ORIGIN_COROUTINE_IMPL, descriptor, initializer)
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irReturnIfSuspended(value: ValueDescriptor) =
|
private fun IrBuilderWithScope.irVar(symbol: IrVariableSymbol, initializer: IrExpression?) =
|
||||||
|
IrVariableImpl(startOffset, endOffset, DECLARATION_ORIGIN_COROUTINE_IMPL, symbol).apply {
|
||||||
|
this.initializer = initializer
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrBuilderWithScope.irReturnIfSuspended(value: IrValueSymbol) =
|
||||||
irIfThen(irEqeqeq(irGet(value), irGet(COROUTINE_SUSPENDED)),
|
irIfThen(irEqeqeq(irGet(value), irGet(COROUTINE_SUSPENDED)),
|
||||||
irReturn(irGet(value)))
|
irReturn(irGet(value)))
|
||||||
|
|
||||||
private fun IrBuilderWithScope.irThrowIfNotNull(exception: ValueDescriptor) =
|
private fun IrBuilderWithScope.irThrowIfNotNull(exception: IrValueSymbol) =
|
||||||
irIfThen(irNot(irEqeqeq(irGet(exception), irNull())),
|
irIfThen(irNot(irEqeqeq(irGet(exception), irNull())),
|
||||||
irThrow(irImplicitCast(irGet(exception), exception.type.makeNotNullable())))
|
irThrow(irImplicitCast(irGet(exception), exception.descriptor.type.makeNotNullable())))
|
||||||
}
|
}
|
||||||
|
|
||||||
private open class VariablesScopeTracker: IrElementVisitorVoid {
|
private open class VariablesScopeTracker: IrElementVisitorVoid {
|
||||||
|
|
||||||
protected val scopeStack = mutableListOf<MutableSet<VariableDescriptor>>(mutableSetOf())
|
protected val scopeStack = mutableListOf<MutableSet<IrVariableSymbol>>(mutableSetOf())
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
override fun visitElement(element: IrElement) {
|
||||||
element.acceptChildrenVoid(this)
|
element.acceptChildrenVoid(this)
|
||||||
@@ -1142,14 +1176,14 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCatch(aCatch: IrCatch) {
|
override fun visitCatch(aCatch: IrCatch) {
|
||||||
scopeStack.push(mutableSetOf(aCatch.parameter))
|
scopeStack.push(mutableSetOf())
|
||||||
super.visitCatch(aCatch)
|
super.visitCatch(aCatch)
|
||||||
scopeStack.pop()
|
scopeStack.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitVariable(declaration: IrVariable) {
|
override fun visitVariable(declaration: IrVariable) {
|
||||||
super.visitVariable(declaration)
|
super.visitVariable(declaration)
|
||||||
scopeStack.peek()!!.add(declaration.descriptor)
|
scopeStack.peek()!!.add(declaration.symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user