Coroutines lowering
This commit is contained in:
+1
@@ -200,6 +200,7 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: DeclarationDe
|
|||||||
/* visibility = */ oldDescriptor.visibility
|
/* visibility = */ oldDescriptor.visibility
|
||||||
)
|
)
|
||||||
isTailrec = oldDescriptor.isTailrec
|
isTailrec = oldDescriptor.isTailrec
|
||||||
|
isSuspend = oldDescriptor.isSuspend
|
||||||
overriddenDescriptors += oldDescriptor.overriddenDescriptors
|
overriddenDescriptors += oldDescriptor.overriddenDescriptors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -16,10 +16,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.descriptors
|
package org.jetbrains.kotlin.backend.common.descriptors
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.coroutines.isSuspendLambda
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
internal val CallableDescriptor.isSuspend: Boolean
|
||||||
|
get() = this is FunctionDescriptor && isSuspend
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return naturally-ordered list of all parameters available inside the function body.
|
* @return naturally-ordered list of all parameters available inside the function body.
|
||||||
|
|||||||
+2
-4
@@ -21,10 +21,7 @@ import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
|||||||
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
|
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -456,6 +453,7 @@ class LocalDeclarationsLowering(val context: BackendContext) : DeclarationContai
|
|||||||
oldDescriptor.source
|
oldDescriptor.source
|
||||||
).apply {
|
).apply {
|
||||||
isTailrec = oldDescriptor.isTailrec
|
isTailrec = oldDescriptor.isTailrec
|
||||||
|
isSuspend = oldDescriptor.isSuspend
|
||||||
// TODO: copy other properties or consider using `FunctionDescriptor.CopyBuilder`.
|
// TODO: copy other properties or consider using `FunctionDescriptor.CopyBuilder`.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-3
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.common.lower
|
package org.jetbrains.kotlin.backend.common.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.konan.util.atMostOne
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
@@ -138,11 +139,17 @@ fun computeOverrides(current: ClassDescriptor, functionsFromCurrent: List<Callab
|
|||||||
|
|
||||||
class SimpleMemberScope(val members: List<DeclarationDescriptor>) : MemberScopeImpl() {
|
class SimpleMemberScope(val members: List<DeclarationDescriptor>) : MemberScopeImpl() {
|
||||||
|
|
||||||
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = TODO()
|
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? =
|
||||||
|
members.filterIsInstance<ClassifierDescriptor>()
|
||||||
|
.atMostOne { it.name == name }
|
||||||
|
|
||||||
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> = TODO()
|
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> =
|
||||||
|
members.filterIsInstance<PropertyDescriptor>()
|
||||||
|
.filter { it.name == name }
|
||||||
|
|
||||||
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> = TODO()
|
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> =
|
||||||
|
members.filterIsInstance<SimpleFunctionDescriptor>()
|
||||||
|
.filter { it.name == name }
|
||||||
|
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter,
|
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter,
|
||||||
nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> =
|
nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> =
|
||||||
|
|||||||
+32
-29
@@ -88,11 +88,11 @@ internal class SpecialDescriptorsFactory(val context: Context) {
|
|||||||
val bridgeDirections = overriddenFunctionDescriptor.bridgeDirections
|
val bridgeDirections = overriddenFunctionDescriptor.bridgeDirections
|
||||||
return bridgesDescriptors.getOrPut(descriptor to bridgeDirections) {
|
return bridgesDescriptors.getOrPut(descriptor to bridgeDirections) {
|
||||||
SimpleFunctionDescriptorImpl.create(
|
SimpleFunctionDescriptorImpl.create(
|
||||||
descriptor.containingDeclaration,
|
/* containingDeclaration = */ descriptor.containingDeclaration,
|
||||||
Annotations.EMPTY,
|
/* annotations = */ Annotations.EMPTY,
|
||||||
("<bridge-" + bridgeDirections.toString() + ">" + descriptor.functionName).synthesizedName,
|
/* name = */ "<bridge-$bridgeDirections>${descriptor.functionName}".synthesizedName,
|
||||||
CallableMemberDescriptor.Kind.DECLARATION,
|
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
|
||||||
SourceElement.NO_SOURCE).apply {
|
/* source = */ SourceElement.NO_SOURCE).apply {
|
||||||
initializeBridgeDescriptor(this, descriptor, bridgeDirections.array)
|
initializeBridgeDescriptor(this, descriptor, bridgeDirections.array)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,31 +120,34 @@ internal class SpecialDescriptorsFactory(val context: Context) {
|
|||||||
BridgeDirection.FROM_VALUE_TYPE -> context.builtIns.anyType
|
BridgeDirection.FROM_VALUE_TYPE -> context.builtIns.anyType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val valueParameters = descriptor.valueParameters.mapIndexed { index, valueParameterDescriptor ->
|
||||||
|
when (bridgeDirections[index + 2]) {
|
||||||
|
BridgeDirection.TO_VALUE_TYPE -> valueParameterDescriptor
|
||||||
|
BridgeDirection.NOT_NEEDED -> valueParameterDescriptor
|
||||||
|
BridgeDirection.FROM_VALUE_TYPE -> ValueParameterDescriptorImpl(
|
||||||
|
containingDeclaration = valueParameterDescriptor.containingDeclaration,
|
||||||
|
original = null,
|
||||||
|
index = index,
|
||||||
|
annotations = Annotations.EMPTY,
|
||||||
|
name = valueParameterDescriptor.name,
|
||||||
|
outType = context.builtIns.anyType,
|
||||||
|
declaresDefaultValue = valueParameterDescriptor.declaresDefaultValue(),
|
||||||
|
isCrossinline = valueParameterDescriptor.isCrossinline,
|
||||||
|
isNoinline = valueParameterDescriptor.isNoinline,
|
||||||
|
varargElementType = valueParameterDescriptor.varargElementType,
|
||||||
|
source = SourceElement.NO_SOURCE)
|
||||||
|
}
|
||||||
|
}
|
||||||
bridgeDescriptor.initialize(
|
bridgeDescriptor.initialize(
|
||||||
extensionReceiverType,
|
/* receiverParameterType = */ extensionReceiverType,
|
||||||
descriptor.dispatchReceiverParameter,
|
/* dispatchReceiverParameter = */ descriptor.dispatchReceiverParameter,
|
||||||
descriptor.typeParameters,
|
/* typeParameters = */ descriptor.typeParameters,
|
||||||
descriptor.valueParameters.mapIndexed { index, valueParameterDescriptor ->
|
/* unsubstitutedValueParameters = */ valueParameters,
|
||||||
when (bridgeDirections[index + 2]) {
|
/* unsubstitutedReturnType = */ returnType,
|
||||||
BridgeDirection.TO_VALUE_TYPE -> valueParameterDescriptor
|
/* modality = */ descriptor.modality,
|
||||||
BridgeDirection.NOT_NEEDED -> valueParameterDescriptor
|
/* visibility = */ descriptor.visibility).apply {
|
||||||
BridgeDirection.FROM_VALUE_TYPE -> ValueParameterDescriptorImpl(
|
isSuspend = descriptor.isSuspend
|
||||||
valueParameterDescriptor.containingDeclaration,
|
}
|
||||||
null,
|
|
||||||
index,
|
|
||||||
Annotations.EMPTY,
|
|
||||||
valueParameterDescriptor.name,
|
|
||||||
context.builtIns.anyType,
|
|
||||||
valueParameterDescriptor.declaresDefaultValue(),
|
|
||||||
valueParameterDescriptor.isCrossinline,
|
|
||||||
valueParameterDescriptor.isNoinline,
|
|
||||||
valueParameterDescriptor.varargElementType,
|
|
||||||
SourceElement.NO_SOURCE)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
returnType,
|
|
||||||
descriptor.modality,
|
|
||||||
descriptor.visibility)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -62,9 +62,6 @@ internal class KonanLower(val context: Context) {
|
|||||||
phaser.phase(KonanPhase.LOWER_DELEGATION) {
|
phaser.phase(KonanPhase.LOWER_DELEGATION) {
|
||||||
PropertyDelegationLowering(context).lower(irFile)
|
PropertyDelegationLowering(context).lower(irFile)
|
||||||
}
|
}
|
||||||
phaser.phase(KonanPhase.LOWER_TYPE_OPERATORS) {
|
|
||||||
TypeOperatorLowering(context).runOnFilePostfix(irFile)
|
|
||||||
}
|
|
||||||
phaser.phase(KonanPhase.LOWER_LOCAL_FUNCTIONS) {
|
phaser.phase(KonanPhase.LOWER_LOCAL_FUNCTIONS) {
|
||||||
LocalDeclarationsLowering(context).runOnFilePostfix(irFile)
|
LocalDeclarationsLowering(context).runOnFilePostfix(irFile)
|
||||||
}
|
}
|
||||||
@@ -93,6 +90,12 @@ internal class KonanLower(val context: Context) {
|
|||||||
phaser.phase(KonanPhase.LOWER_VARARG) {
|
phaser.phase(KonanPhase.LOWER_VARARG) {
|
||||||
VarargInjectionLowering(context).runOnFilePostfix(irFile)
|
VarargInjectionLowering(context).runOnFilePostfix(irFile)
|
||||||
}
|
}
|
||||||
|
phaser.phase(KonanPhase.LOWER_COROUTINES) {
|
||||||
|
SuspendFunctionsLowering(context).runOnFilePostfix(irFile)
|
||||||
|
}
|
||||||
|
phaser.phase(KonanPhase.LOWER_TYPE_OPERATORS) {
|
||||||
|
TypeOperatorLowering(context).runOnFilePostfix(irFile)
|
||||||
|
}
|
||||||
phaser.phase(KonanPhase.BRIDGES_BUILDING) {
|
phaser.phase(KonanPhase.BRIDGES_BUILDING) {
|
||||||
BridgesBuilding(context).runOnFilePostfix(irFile)
|
BridgesBuilding(context).runOnFilePostfix(irFile)
|
||||||
DirectBridgesCallsLowering(context).runOnFilePostfix(irFile)
|
DirectBridgesCallsLowering(context).runOnFilePostfix(irFile)
|
||||||
|
|||||||
+4
-3
@@ -44,10 +44,11 @@ enum class KonanPhase(val description: String,
|
|||||||
/* ... ... */ LOWER_INNER_CLASSES("Inner classes lowering", LOWER_DEFAULT_PARAMETER_EXTENT),
|
/* ... ... */ LOWER_INNER_CLASSES("Inner classes lowering", LOWER_DEFAULT_PARAMETER_EXTENT),
|
||||||
/* ... ... */ LOWER_LATEINIT("Lateinit properties lowering"),
|
/* ... ... */ LOWER_LATEINIT("Lateinit properties lowering"),
|
||||||
/* ... ... */ LOWER_BUILTIN_OPERATORS("BuiltIn Operators Lowering", LOWER_DEFAULT_PARAMETER_EXTENT, LOWER_LATEINIT),
|
/* ... ... */ LOWER_BUILTIN_OPERATORS("BuiltIn Operators Lowering", LOWER_DEFAULT_PARAMETER_EXTENT, LOWER_LATEINIT),
|
||||||
/* ... ... */ LOWER_TYPE_OPERATORS("Type operators lowering"),
|
/* ... ... */ LOWER_COROUTINES("Coroutines lowering", LOWER_LOCAL_FUNCTIONS),
|
||||||
/* ... ... */ BRIDGES_BUILDING("Bridges building"),
|
/* ... ... */ LOWER_TYPE_OPERATORS("Type operators lowering", LOWER_COROUTINES),
|
||||||
|
/* ... ... */ BRIDGES_BUILDING("Bridges building", LOWER_COROUTINES),
|
||||||
/* ... ... */ LOWER_STRING_CONCAT("String concatenation lowering"),
|
/* ... ... */ LOWER_STRING_CONCAT("String concatenation lowering"),
|
||||||
/* ... ... */ AUTOBOX("Autoboxing of primitive types", BRIDGES_BUILDING),
|
/* ... ... */ AUTOBOX("Autoboxing of primitive types", BRIDGES_BUILDING, LOWER_COROUTINES),
|
||||||
/* ... */ BITCODE("LLVM BitCode Generation"),
|
/* ... */ BITCODE("LLVM BitCode Generation"),
|
||||||
/* ... ... */ RTTI("RTTI Generation"),
|
/* ... ... */ RTTI("RTTI Generation"),
|
||||||
/* ... ... */ CODEGEN("Code Generation"),
|
/* ... ... */ CODEGEN("Code Generation"),
|
||||||
|
|||||||
+2
-2
@@ -202,7 +202,7 @@ fun ClassDescriptor.isAbstract() = this.modality == Modality.SEALED || this.moda
|
|||||||
|
|
||||||
internal fun FunctionDescriptor.hasValueTypeAt(index: Int): Boolean {
|
internal fun FunctionDescriptor.hasValueTypeAt(index: Int): Boolean {
|
||||||
when (index) {
|
when (index) {
|
||||||
0 -> return returnType.let { it != null && it.isValueType() }
|
0 -> return !isSuspend && returnType.let { it != null && it.isValueType() }
|
||||||
1 -> return extensionReceiverParameter.let { it != null && it.type.isValueType() }
|
1 -> return extensionReceiverParameter.let { it != null && it.type.isValueType() }
|
||||||
else -> return this.valueParameters[index - 2].type.isValueType()
|
else -> return this.valueParameters[index - 2].type.isValueType()
|
||||||
}
|
}
|
||||||
@@ -210,7 +210,7 @@ internal fun FunctionDescriptor.hasValueTypeAt(index: Int): Boolean {
|
|||||||
|
|
||||||
internal fun FunctionDescriptor.hasReferenceAt(index: Int): Boolean {
|
internal fun FunctionDescriptor.hasReferenceAt(index: Int): Boolean {
|
||||||
when (index) {
|
when (index) {
|
||||||
0 -> return returnType.let { it != null && !it.isValueType() }
|
0 -> return isSuspend || returnType.let { it != null && !it.isValueType() }
|
||||||
1 -> return extensionReceiverParameter.let { it != null && !it.type.isValueType() }
|
1 -> return extensionReceiverParameter.let { it != null && !it.type.isValueType() }
|
||||||
else -> return !this.valueParameters[index - 2].type.isValueType()
|
else -> return !this.valueParameters[index - 2].type.isValueType()
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-9
@@ -51,15 +51,7 @@ fun ir2stringWhole(ir: IrElement?, withDescriptors: Boolean = false): String {
|
|||||||
internal fun DeclarationDescriptor.createFakeOverrideDescriptor(owner: ClassDescriptor): DeclarationDescriptor? {
|
internal fun DeclarationDescriptor.createFakeOverrideDescriptor(owner: ClassDescriptor): DeclarationDescriptor? {
|
||||||
// We need to copy descriptors for vtable building, thus take only functions and properties.
|
// We need to copy descriptors for vtable building, thus take only functions and properties.
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is FunctionDescriptor ->
|
is CallableMemberDescriptor ->
|
||||||
newCopyBuilder()
|
|
||||||
.setOwner(owner)
|
|
||||||
.setKind(CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
|
|
||||||
.setCopyOverrides(true)
|
|
||||||
.build()!!.apply {
|
|
||||||
overriddenDescriptors += this@createFakeOverrideDescriptor
|
|
||||||
}
|
|
||||||
is PropertyDescriptor ->
|
|
||||||
copy(
|
copy(
|
||||||
/* newOwner = */ owner,
|
/* newOwner = */ owner,
|
||||||
/* modality = */ modality,
|
/* modality = */ modality,
|
||||||
@@ -72,6 +64,17 @@ internal fun DeclarationDescriptor.createFakeOverrideDescriptor(owner: ClassDesc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun FunctionDescriptor.createOverriddenDescriptor(owner: ClassDescriptor, final: Boolean = true): FunctionDescriptor {
|
||||||
|
return this.newCopyBuilder()
|
||||||
|
.setOwner(owner)
|
||||||
|
.setCopyOverrides(true)
|
||||||
|
.setModality(if (final) Modality.FINAL else Modality.OPEN)
|
||||||
|
.setDispatchReceiverParameter(owner.thisAsReceiverParameter)
|
||||||
|
.build()!!.apply {
|
||||||
|
overriddenDescriptors += this@createOverriddenDescriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superConstructorDescriptor: ClassConstructorDescriptor, isPrimary: Boolean = false)
|
internal fun ClassDescriptor.createSimpleDelegatingConstructorDescriptor(superConstructorDescriptor: ClassConstructorDescriptor, isPrimary: Boolean = false)
|
||||||
: ClassConstructorDescriptor {
|
: ClassConstructorDescriptor {
|
||||||
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
val constructorDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
||||||
|
|||||||
+53
@@ -18,9 +18,12 @@ package org.jetbrains.kotlin.backend.konan.ir
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBlock
|
import org.jetbrains.kotlin.ir.expressions.IrBlock
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase
|
import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -50,3 +53,53 @@ class IrInlineFunctionBody(startOffset: Int, endOffset: Int, type: KotlinType, v
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------//
|
//-----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
interface IrSuspensionPoint : IrExpression {
|
||||||
|
var suspensionPointIdParameter: IrVariable
|
||||||
|
var result: IrExpression
|
||||||
|
var resumeResult: IrExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IrSuspendableExpression : IrExpression {
|
||||||
|
var suspensionPointId: IrExpression
|
||||||
|
var result: IrExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
class IrSuspensionPointImpl(startOffset: Int, endOffset: Int, type: KotlinType,
|
||||||
|
override var suspensionPointIdParameter: IrVariable,
|
||||||
|
override var result: IrExpression,
|
||||||
|
override var resumeResult: IrExpression)
|
||||||
|
: IrExpressionBase(startOffset, endOffset, type), IrSuspensionPoint {
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
|
visitor.visitExpression(this, data)
|
||||||
|
|
||||||
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
|
suspensionPointIdParameter.accept(visitor, data)
|
||||||
|
result.accept(visitor, data)
|
||||||
|
resumeResult.accept(visitor, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||||
|
suspensionPointIdParameter = suspensionPointIdParameter.transform(transformer, data) as IrVariable
|
||||||
|
result = result.transform(transformer, data)
|
||||||
|
resumeResult = resumeResult.transform(transformer, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IrSuspendableExpressionImpl(startOffset: Int, endOffset: Int, type: KotlinType,
|
||||||
|
override var suspensionPointId: IrExpression, override var result: IrExpression)
|
||||||
|
: IrExpressionBase(startOffset, endOffset, type), IrSuspendableExpression {
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
|
visitor.visitExpression(this, data)
|
||||||
|
|
||||||
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
|
suspensionPointId.accept(visitor, data)
|
||||||
|
result.accept(visitor, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||||
|
suspensionPointId = suspensionPointId.transform(transformer, data)
|
||||||
|
result = result.transform(transformer, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
-1
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.konan.lower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.AbstractValueUsageTransformer
|
import org.jetbrains.kotlin.backend.common.AbstractValueUsageTransformer
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.descriptors.isSuspend
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.ValueType
|
import org.jetbrains.kotlin.backend.konan.ValueType
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||||
@@ -25,7 +26,9 @@ import org.jetbrains.kotlin.backend.konan.notNullableIsRepresentedAs
|
|||||||
import org.jetbrains.kotlin.backend.konan.isRepresentedAs
|
import org.jetbrains.kotlin.backend.konan.isRepresentedAs
|
||||||
import org.jetbrains.kotlin.backend.konan.util.atMostOne
|
import org.jetbrains.kotlin.backend.konan.util.atMostOne
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
||||||
@@ -123,6 +126,23 @@ private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var currentFunctionDescriptor: FunctionDescriptor? = null
|
||||||
|
|
||||||
|
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||||
|
currentFunctionDescriptor = declaration.descriptor
|
||||||
|
val result = super.visitFunction(declaration)
|
||||||
|
currentFunctionDescriptor = null
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun IrExpression.useAsReturnValue(returnTarget: CallableDescriptor): IrExpression {
|
||||||
|
if (returnTarget.isSuspend && returnTarget == currentFunctionDescriptor)
|
||||||
|
return this.useAs(context.builtIns.nullableAnyType)
|
||||||
|
val returnType = returnTarget.returnType
|
||||||
|
?: return this
|
||||||
|
return this.useAs(returnType)
|
||||||
|
}
|
||||||
|
|
||||||
override fun IrExpression.useAs(type: KotlinType): IrExpression {
|
override fun IrExpression.useAs(type: KotlinType): IrExpression {
|
||||||
val interop = context.interopBuiltIns
|
val interop = context.interopBuiltIns
|
||||||
if (this.isNullConst() && interop.nullableInteropValueTypes.any { type.isRepresentedAs(it) }) {
|
if (this.isNullConst() && interop.nullableInteropValueTypes.any { type.isRepresentedAs(it) }) {
|
||||||
@@ -130,7 +150,10 @@ private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTr
|
|||||||
}
|
}
|
||||||
|
|
||||||
val actualType = when (this) {
|
val actualType = when (this) {
|
||||||
is IrCall -> this.descriptor.original.returnType ?: this.type
|
is IrCall -> {
|
||||||
|
if (this.descriptor.isSuspend) context.builtIns.nullableAnyType
|
||||||
|
else this.descriptor.original.returnType ?: this.type
|
||||||
|
}
|
||||||
is IrGetField -> this.descriptor.original.type
|
is IrGetField -> this.descriptor.original.type
|
||||||
|
|
||||||
is IrTypeOperatorCall -> when (this.operator) {
|
is IrTypeOperatorCall -> when (this.operator) {
|
||||||
|
|||||||
+1
@@ -410,6 +410,7 @@ private fun FunctionDescriptor.generateDefaultsDescription(context: Context): Fu
|
|||||||
/* unsubstitutedReturnType = */ returnType,
|
/* unsubstitutedReturnType = */ returnType,
|
||||||
/* modality = */ Modality.FINAL,
|
/* modality = */ Modality.FINAL,
|
||||||
/* visibility = */ this.visibility)
|
/* visibility = */ this.visibility)
|
||||||
|
descriptor.isSuspend = this.isSuspend
|
||||||
context.log{"adds to cache[$this] = $descriptor"}
|
context.log{"adds to cache[$this] = $descriptor"}
|
||||||
descriptor
|
descriptor
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-6
@@ -27,17 +27,13 @@ import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke
|
|||||||
import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining
|
import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.DeserializerDriver
|
import org.jetbrains.kotlin.backend.konan.ir.DeserializerDriver
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody
|
import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrMemberAccessExpressionBase
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||||
|
|||||||
+1180
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,14 @@ package konan.internal
|
|||||||
import kotlin.coroutines.experimental.*
|
import kotlin.coroutines.experimental.*
|
||||||
import kotlin.coroutines.experimental.intrinsics.*
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
@Intrinsic
|
||||||
|
@PublishedApi
|
||||||
|
internal fun <T> getContinuation(): Continuation<T> = throw AssertionError("Call to getContinuation should've been lowered")
|
||||||
|
|
||||||
|
@Intrinsic
|
||||||
|
@PublishedApi
|
||||||
|
internal fun <T> returnIfSuspended(value: Any?): T = throw AssertionError("Call to returnIfSuspended should've been lowered")
|
||||||
|
|
||||||
// Single-threaded continuation.
|
// Single-threaded continuation.
|
||||||
class SafeContinuation<in T>
|
class SafeContinuation<in T>
|
||||||
constructor(
|
constructor(
|
||||||
@@ -67,6 +75,7 @@ internal fun <T> interceptContinuationIfNeeded(
|
|||||||
* @suppress
|
* @suppress
|
||||||
*/
|
*/
|
||||||
@ExportForCompiler
|
@ExportForCompiler
|
||||||
|
@PublishedApi
|
||||||
internal fun <T> normalizeContinuation(continuation: Continuation<T>): Continuation<T> =
|
internal fun <T> normalizeContinuation(continuation: Continuation<T>): Continuation<T> =
|
||||||
(continuation as? CoroutineImpl)?.facade ?: continuation
|
(continuation as? CoroutineImpl)?.facade ?: continuation
|
||||||
|
|
||||||
@@ -80,7 +89,8 @@ abstract internal class CoroutineImpl(
|
|||||||
|
|
||||||
// label == -1 when coroutine cannot be started (it is just a factory object) or has already finished execution
|
// label == -1 when coroutine cannot be started (it is just a factory object) or has already finished execution
|
||||||
// label == 0 in initial part of the coroutine
|
// label == 0 in initial part of the coroutine
|
||||||
protected var label: Int = if (completion != null) 0L else -1L
|
// TODO: use IntPtr.
|
||||||
|
protected var label: Long = if (completion != null) 0L else -1L
|
||||||
|
|
||||||
private val _context: CoroutineContext? = completion?.context
|
private val _context: CoroutineContext? = completion?.context
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ package kotlin.coroutines.experimental.intrinsics
|
|||||||
import kotlin.coroutines.experimental.Continuation
|
import kotlin.coroutines.experimental.Continuation
|
||||||
import kotlin.coroutines.experimental.CoroutineContext
|
import kotlin.coroutines.experimental.CoroutineContext
|
||||||
import kotlin.coroutines.experimental.processBareContinuationResume
|
import kotlin.coroutines.experimental.processBareContinuationResume
|
||||||
import konan.internal.interceptContinuationIfNeeded
|
import konan.internal.*
|
||||||
import konan.internal.CoroutineImpl
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the current continuation instance inside suspend functions and either suspend
|
* Obtains the current continuation instance inside suspend functions and either suspend
|
||||||
@@ -40,7 +39,8 @@ import konan.internal.CoroutineImpl
|
|||||||
* continuation instance.
|
* continuation instance.
|
||||||
*/
|
*/
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public inline suspend fun <T> suspendCoroutineOrReturn(crossinline block: (Continuation<T>) -> Any?): T = throw Error("Should've been intrinsified")
|
public inline suspend fun <T> suspendCoroutineOrReturn(crossinline block: (Continuation<T>) -> Any?): T =
|
||||||
|
returnIfSuspended<T>(block(normalizeContinuation<T>(getContinuation<T>())))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This value is used as a return value of [suspendCoroutineOrReturn] `block` argument to state that
|
* This value is used as a return value of [suspendCoroutineOrReturn] `block` argument to state that
|
||||||
|
|||||||
Reference in New Issue
Block a user