[JS IR] Fix state machine builder to fit into switch optimizer requirements
This commit is contained in:
+14
-12
@@ -16,10 +16,7 @@ import org.jetbrains.kotlin.ir.builders.*
|
|||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.util.explicitParameters
|
import org.jetbrains.kotlin.ir.util.explicitParameters
|
||||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||||
@@ -83,7 +80,12 @@ class JsSuspendFunctionsLowering(ctx: JsIrBackendContext) : AbstractSuspendFunct
|
|||||||
val unit = context.irBuiltIns.unitType
|
val unit = context.irBuiltIns.unitType
|
||||||
|
|
||||||
val switch = IrWhenImpl(body.startOffset, body.endOffset, unit, COROUTINE_SWITCH)
|
val switch = IrWhenImpl(body.startOffset, body.endOffset, unit, COROUTINE_SWITCH)
|
||||||
val rootTry = IrTryImpl(body.startOffset, body.endOffset, unit).apply { tryResult = switch }
|
val stateVar = JsIrBuilder.buildVar(context.irBuiltIns.intType, stateMachineFunction)
|
||||||
|
val switchBlock = IrBlockImpl(switch.startOffset, switch.endOffset, switch.type).apply {
|
||||||
|
statements += stateVar
|
||||||
|
statements += switch
|
||||||
|
}
|
||||||
|
val rootTry = IrTryImpl(body.startOffset, body.endOffset, unit).apply { tryResult = switchBlock }
|
||||||
val rootLoop = IrDoWhileLoopImpl(
|
val rootLoop = IrDoWhileLoopImpl(
|
||||||
body.startOffset,
|
body.startOffset,
|
||||||
body.endOffset,
|
body.endOffset,
|
||||||
@@ -97,6 +99,9 @@ class JsSuspendFunctionsLowering(ctx: JsIrBackendContext) : AbstractSuspendFunct
|
|||||||
|
|
||||||
val suspendableNodes = collectSuspendableNodes(body)
|
val suspendableNodes = collectSuspendableNodes(body)
|
||||||
val thisReceiver = (stateMachineFunction.dispatchReceiverParameter as IrValueParameter).symbol
|
val thisReceiver = (stateMachineFunction.dispatchReceiverParameter as IrValueParameter).symbol
|
||||||
|
stateVar.initializer = JsIrBuilder.buildCall(coroutineImplLabelPropertyGetter.symbol).apply {
|
||||||
|
dispatchReceiver = JsIrBuilder.buildGetValue(thisReceiver)
|
||||||
|
}
|
||||||
|
|
||||||
val stateMachineBuilder = StateMachineBuilder(
|
val stateMachineBuilder = StateMachineBuilder(
|
||||||
suspendableNodes,
|
suspendableNodes,
|
||||||
@@ -118,7 +123,7 @@ class JsSuspendFunctionsLowering(ctx: JsIrBackendContext) : AbstractSuspendFunct
|
|||||||
|
|
||||||
rootTry.catches += stateMachineBuilder.globalCatch
|
rootTry.catches += stateMachineBuilder.globalCatch
|
||||||
|
|
||||||
assignStateIds(stateMachineBuilder.entryState, thisReceiver, switch, rootLoop)
|
assignStateIds(stateMachineBuilder.entryState, stateVar.symbol, switch, rootLoop)
|
||||||
|
|
||||||
exceptionTrapId = stateMachineBuilder.rootExceptionTrap.id
|
exceptionTrapId = stateMachineBuilder.rootExceptionTrap.id
|
||||||
|
|
||||||
@@ -147,7 +152,7 @@ class JsSuspendFunctionsLowering(ctx: JsIrBackendContext) : AbstractSuspendFunct
|
|||||||
var localCounter = 0
|
var localCounter = 0
|
||||||
// TODO: optimize by using the same property for different locals.
|
// TODO: optimize by using the same property for different locals.
|
||||||
liveLocals.forEach {
|
liveLocals.forEach {
|
||||||
if (it != suspendState && it != suspendResult) {
|
if (it !== suspendState && it !== suspendResult && it !== stateVar) {
|
||||||
localToPropertyMap.getOrPut(it.symbol) {
|
localToPropertyMap.getOrPut(it.symbol) {
|
||||||
coroutineClass.addField(Name.identifier("${it.name}${localCounter++}"), it.type, (it as? IrVariable)?.isVar ?: false)
|
coroutineClass.addField(Name.identifier("${it.name}${localCounter++}"), it.type, (it as? IrVariable)?.isVar ?: false)
|
||||||
.symbol
|
.symbol
|
||||||
@@ -163,7 +168,7 @@ class JsSuspendFunctionsLowering(ctx: JsIrBackendContext) : AbstractSuspendFunct
|
|||||||
stateMachineFunction.transform(LiveLocalsTransformer(localToPropertyMap, { JsIrBuilder.buildGetValue(thisReceiver) }, unit), null)
|
stateMachineFunction.transform(LiveLocalsTransformer(localToPropertyMap, { JsIrBuilder.buildGetValue(thisReceiver) }, unit), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignStateIds(entryState: SuspendState, thisReceiver: IrValueParameterSymbol, switch: IrWhen, rootLoop: IrLoop) {
|
private fun assignStateIds(entryState: SuspendState, subject: IrVariableSymbol, switch: IrWhen, rootLoop: IrLoop) {
|
||||||
val visited = mutableSetOf<SuspendState>()
|
val visited = mutableSetOf<SuspendState>()
|
||||||
|
|
||||||
val sortedStates = DFS.topologicalOrder(listOf(entryState), { it.successors }, { visited.add(it) })
|
val sortedStates = DFS.topologicalOrder(listOf(entryState), { it.successors }, { visited.add(it) })
|
||||||
@@ -173,9 +178,7 @@ class JsSuspendFunctionsLowering(ctx: JsIrBackendContext) : AbstractSuspendFunct
|
|||||||
|
|
||||||
for (state in sortedStates) {
|
for (state in sortedStates) {
|
||||||
val condition = JsIrBuilder.buildCall(eqeqeqInt).apply {
|
val condition = JsIrBuilder.buildCall(eqeqeqInt).apply {
|
||||||
putValueArgument(0, JsIrBuilder.buildCall(coroutineImplLabelPropertyGetter.symbol).also {
|
putValueArgument(0, JsIrBuilder.buildGetValue(subject))
|
||||||
it.dispatchReceiver = JsIrBuilder.buildGetValue(thisReceiver)
|
|
||||||
})
|
|
||||||
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.intType, state.id))
|
putValueArgument(1, JsIrBuilder.buildInt(context.irBuiltIns.intType, state.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +211,6 @@ class JsSuspendFunctionsLowering(ctx: JsIrBackendContext) : AbstractSuspendFunct
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun initializeStateMachine(coroutineConstructors: List<IrConstructor>, coroutineClassThis: IrValueDeclaration) {
|
override fun initializeStateMachine(coroutineConstructors: List<IrConstructor>, coroutineClassThis: IrValueDeclaration) {
|
||||||
for (it in coroutineConstructors) {
|
for (it in coroutineConstructors) {
|
||||||
(it.body as? IrBlockBody)?.run {
|
(it.body as? IrBlockBody)?.run {
|
||||||
|
|||||||
Reference in New Issue
Block a user