Coroutines lowering: minor refactoring
This commit is contained in:
+34
@@ -28,6 +28,8 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
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.IrTypeOperator
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
@@ -72,6 +74,38 @@ inline fun IrGeneratorWithScope.irBlock(expression: IrExpression, origin: IrStat
|
|||||||
inline fun IrGeneratorWithScope.irBlockBody(irElement: IrElement, body: IrBlockBodyBuilder.() -> Unit) =
|
inline fun IrGeneratorWithScope.irBlockBody(irElement: IrElement, body: IrBlockBodyBuilder.() -> Unit) =
|
||||||
this.irBlockBody(irElement.startOffset, irElement.endOffset, body)
|
this.irBlockBody(irElement.startOffset, irElement.endOffset, body)
|
||||||
|
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irUnit() =
|
||||||
|
IrGetObjectValueImpl(startOffset, endOffset, context.builtIns.unitType, context.builtIns.unit)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irIfThen(condition: IrExpression, thenPart: IrExpression) =
|
||||||
|
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, thenPart, null)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irGet(descriptor: PropertyDescriptor) =
|
||||||
|
IrGetterCallImpl(startOffset, endOffset, descriptor.getter!!, null)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irSet(receiver: IrExpression, descriptor: PropertyDescriptor, arg: IrExpression) =
|
||||||
|
IrSetterCallImpl(startOffset, endOffset, descriptor.setter!!, null, receiver, null, arg)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irNot(arg: IrExpression) =
|
||||||
|
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNot, IrStatementOrigin.EXCL, arg)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irThrow(arg: IrExpression) =
|
||||||
|
IrThrowImpl(startOffset, endOffset, context.builtIns.nothingType, arg)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irCast(arg: IrExpression, type: KotlinType, typeOperand: KotlinType) =
|
||||||
|
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, typeOperand, arg)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irImplicitCoercionToUnit(arg: IrExpression) =
|
||||||
|
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.unitType,
|
||||||
|
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.builtIns.unitType, arg)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irGetField(receiver: IrExpression, descriptor: PropertyDescriptor) =
|
||||||
|
IrGetFieldImpl(startOffset, endOffset, descriptor, receiver)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irSetField(receiver: IrExpression, descriptor: PropertyDescriptor, value: IrExpression) =
|
||||||
|
IrSetFieldImpl(startOffset, endOffset, descriptor, receiver, value)
|
||||||
|
|
||||||
open class IrBuildingTransformer(private val context: BackendContext) : IrElementTransformerVoid() {
|
open class IrBuildingTransformer(private val context: BackendContext) : IrElementTransformerVoid() {
|
||||||
private var currentBuilder: IrBuilderWithScope? = null
|
private var currentBuilder: IrBuilderWithScope? = null
|
||||||
|
|
||||||
|
|||||||
+20
-46
@@ -21,7 +21,10 @@ import org.jetbrains.kotlin.backend.common.descriptors.explicitParameters
|
|||||||
import org.jetbrains.kotlin.backend.common.descriptors.isSuspend
|
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.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
import org.jetbrains.kotlin.backend.konan.descriptors.getKonanInternalClass
|
||||||
|
import org.jetbrains.kotlin.backend.konan.descriptors.getKonanInternalFunctions
|
||||||
|
import org.jetbrains.kotlin.backend.konan.descriptors.isSuspendFunctionInvoke
|
||||||
|
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||||
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.*
|
||||||
@@ -1131,7 +1134,9 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
first = false
|
first = false
|
||||||
if (!transformedChild.isPure() && hasSuspendCallInTail[index]) {
|
if (transformedChild.isPure() || !hasSuspendCallInTail[index])
|
||||||
|
newChildren[index] = transformedChild
|
||||||
|
else {
|
||||||
// Save to temporary in order to save execution order.
|
// Save to temporary in order to save execution order.
|
||||||
val tmp = IrTemporaryVariableDescriptorImpl(
|
val tmp = IrTemporaryVariableDescriptorImpl(
|
||||||
containingDeclaration = irFunction.descriptor,
|
containingDeclaration = irFunction.descriptor,
|
||||||
@@ -1140,27 +1145,24 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
tempStatements += irVar(tmp, transformedChild)
|
tempStatements += irVar(tmp, transformedChild)
|
||||||
newChildren[index] = irGet(tmp)
|
newChildren[index] = irGet(tmp)
|
||||||
}
|
}
|
||||||
else newChildren[index] = transformedChild
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var calledSaveState = false
|
var calledSaveState = false
|
||||||
if (expression.isSuspendCall) {
|
if (expression.isSuspendCall) {
|
||||||
val lastChild = newChildren.last()
|
val lastChild = newChildren.last()
|
||||||
if (lastChild != null) {
|
if (lastChild != null) {
|
||||||
// Save state at late as possible.
|
// Save state as late as possible.
|
||||||
calledSaveState = true
|
calledSaveState = true
|
||||||
newChildren[numberOfChildren - 1] =
|
newChildren[numberOfChildren - 1] =
|
||||||
if (lastChild.isPure())
|
irBlock(lastChild) {
|
||||||
irBlock(lastChild) {
|
if (lastChild.isPure()) {
|
||||||
+irCall(saveStateDescriptor)
|
+irCall(saveStateDescriptor)
|
||||||
+lastChild
|
+lastChild
|
||||||
}
|
} else {
|
||||||
else {
|
val tmp = IrTemporaryVariableDescriptorImpl(
|
||||||
val tmp = IrTemporaryVariableDescriptorImpl(
|
containingDeclaration = irFunction.descriptor,
|
||||||
containingDeclaration = irFunction.descriptor,
|
name = "tmp${tempIndex++}".synthesizedName,
|
||||||
name = "tmp${tempIndex++}".synthesizedName,
|
outType = lastChild.type)
|
||||||
outType = lastChild.type)
|
|
||||||
irBlock(lastChild) {
|
|
||||||
+irVar(tmp, lastChild)
|
+irVar(tmp, lastChild)
|
||||||
+irCall(saveStateDescriptor)
|
+irCall(saveStateDescriptor)
|
||||||
+irGet(tmp)
|
+irGet(tmp)
|
||||||
@@ -1233,9 +1235,11 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
private val IrExpression.isSuspendCall: Boolean
|
private val IrExpression.isSuspendCall: Boolean
|
||||||
get() = this is IrCall && this.descriptor.isSuspend
|
get() = this is IrCall && this.descriptor.isSuspend
|
||||||
|
|
||||||
private object STATEMENT_ORIGIN_COROUTINE_IMPL: IrStatementOriginImpl("COROUTINE_IMPL")
|
private object STATEMENT_ORIGIN_COROUTINE_IMPL :
|
||||||
|
IrStatementOriginImpl("COROUTINE_IMPL")
|
||||||
|
|
||||||
private fun IrElement.isSpecialBlock() = this is IrBlock && this.origin == STATEMENT_ORIGIN_COROUTINE_IMPL
|
private fun IrElement.isSpecialBlock()
|
||||||
|
= this is IrBlock && this.origin == STATEMENT_ORIGIN_COROUTINE_IMPL
|
||||||
|
|
||||||
private fun IrElement.hasSuspendCalls(): Boolean {
|
private fun IrElement.hasSuspendCalls(): Boolean {
|
||||||
var hasSuspendCalls = false
|
var hasSuspendCalls = false
|
||||||
@@ -1257,7 +1261,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
return when (this) {
|
return when (this) {
|
||||||
is IrConst<*> -> true
|
is IrConst<*> -> true
|
||||||
is IrCall -> false // TODO: skip builtin operators.
|
is IrCall -> false // TODO: skip builtin operators.
|
||||||
is IrTypeOperatorCall -> this.argument.isPure()
|
is IrTypeOperatorCall -> this.argument.isPure() && this.operator != IrTypeOperator.CAST
|
||||||
is IrGetValue -> !this.descriptor.let { it is VariableDescriptor && it.isVar }
|
is IrGetValue -> !this.descriptor.let { it is VariableDescriptor && it.isVar }
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
@@ -1315,34 +1319,4 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
|
|||||||
scopeStack.peek()!!.add(declaration.descriptor)
|
scopeStack.peek()!!.add(declaration.descriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrBuilderWithScope.irUnit() =
|
|
||||||
IrGetObjectValueImpl(startOffset, endOffset, context.builtIns.unitType, context.builtIns.unit)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIfThen(condition: IrExpression, thenPart: IrExpression) =
|
|
||||||
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, thenPart, null)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irGet(descriptor: PropertyDescriptor) =
|
|
||||||
IrGetterCallImpl(startOffset, endOffset, descriptor.getter!!, null)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irSet(receiver: IrExpression, descriptor: PropertyDescriptor, arg: IrExpression) =
|
|
||||||
IrSetterCallImpl(startOffset, endOffset, descriptor.setter!!, null, receiver, null, arg)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irNot(arg: IrExpression) =
|
|
||||||
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNot, IrStatementOrigin.EXCL, arg)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irThrow(arg: IrExpression) =
|
|
||||||
IrThrowImpl(startOffset, endOffset, arg.type, arg)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irCast(arg: IrExpression, type: KotlinType, typeOperand: KotlinType) =
|
|
||||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, typeOperand, arg)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irImplicitCoercionToUnit(arg: IrExpression) =
|
|
||||||
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.unitType, IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.builtIns.unitType, arg)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irGetField(receiver: IrExpression, descriptor: PropertyDescriptor) =
|
|
||||||
IrGetFieldImpl(startOffset, endOffset, descriptor, receiver)
|
|
||||||
|
|
||||||
fun IrBuilderWithScope.irSetField(receiver: IrExpression, descriptor: PropertyDescriptor, value: IrExpression) =
|
|
||||||
IrSetFieldImpl(startOffset, endOffset, descriptor, receiver, value)
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user