From 98122913647c58911a942b3fe33a84a536936561 Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Tue, 24 Dec 2019 23:03:13 +0300 Subject: [PATCH] BlockDecomposerLowering --- .../kotlin/ir/backend/js/JsLoweringPhases.kt | 7 +- .../js/lower/BlockDecomposerLowering.kt | 97 ++++++++----------- 2 files changed, 45 insertions(+), 59 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt index 10afbca21ac..5a05c0f54c8 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -383,11 +383,8 @@ private val autoboxingTransformerPhase = makeJsModulePhase( description = "Insert box/unbox intrinsics" ) -private val blockDecomposerLoweringPhase = makeCustomJsModulePhase( - { context, module -> - JsBlockDecomposerLowering(context).lower(module) - module.patchDeclarationParents() - }, +private val blockDecomposerLoweringPhase = makeJsModulePhase( + ::JsBlockDecomposerLowering, name = "BlockDecomposerLowering", description = "Transform statement-like-expression nodes into pure-statement to make it easily transform into JS", prerequisite = setOf(typeOperatorLoweringPhase, suspendFunctionsLoweringPhase) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt index d60ddc98086..7a6960f72d3 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt @@ -5,8 +5,10 @@ package org.jetbrains.kotlin.ir.backend.js.lower +import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass +import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.ir.isElseBranch import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.IrElement @@ -30,31 +32,54 @@ class JsBlockDecomposerLowering(val context: JsIrBackendContext) : AbstractBlock JsIrBuilder.buildCall(context.intrinsics.unreachable.symbol, context.irBuiltIns.nothingType) } -abstract class AbstractBlockDecomposerLowering(context: CommonBackendContext) : DeclarationContainerLoweringPass { +abstract class AbstractBlockDecomposerLowering( + context: CommonBackendContext +) : BodyLoweringPass { + + private val nothingType = context.irBuiltIns.nothingType // Expression with Nothing type to be inserted in places of unreachable expression abstract fun unreachableExpression(): IrExpression private val decomposerTransformer = BlockDecomposerTransformer(context, ::unreachableExpression) - private val nothingType = context.irBuiltIns.nothingType - override fun lower(irDeclarationContainer: IrDeclarationContainer) { - irDeclarationContainer.transformDeclarationsFlat { declaration -> - when (declaration) { - is IrScript -> { - lower(declaration) - listOf(declaration) + override fun lower(irBody: IrBody, container: IrDeclaration) { + when (container) { + is IrFunction -> { + container.accept(decomposerTransformer, null) + irBody.patchDeclarationParents(container) + } + is IrField -> { + container.initializer?.apply { + + val initFunction = JsIrBuilder.buildFunction( + container.name.asString() + "\$init\$", + container.type, + container.parent, + Visibilities.PRIVATE + ) + + val newBody = toBlockBody(initFunction) + newBody.patchDeclarationParents(initFunction) + initFunction.body = newBody + + initFunction.accept(decomposerTransformer, null) + + val lastStatement = newBody.statements.last() + val actualParent = if (newBody.statements.size > 1 || lastStatement !is IrReturn || lastStatement.value != expression) { + expression = JsIrBuilder.buildCall(initFunction.symbol, expression.type) + (container.parent as IrDeclarationContainer).declarations += initFunction + initFunction + } else { + container + } + + patchDeclarationParents(actualParent) } - is IrFunction -> { - lower(declaration) - listOf(declaration) - } - is IrField -> lower(declaration, irDeclarationContainer) - else -> listOf(declaration) } } - irDeclarationContainer.transformChildrenVoid(CodeCleaner()) +// irDeclarationContainer.transformChildrenVoid(CodeCleaner()) TODO } private inner class CodeCleaner : IrElementTransformerVoid() { @@ -98,49 +123,13 @@ abstract class AbstractBlockDecomposerLowering(context: CommonBackendContext) : } } - fun lower(irScript: IrScript) { - irScript.transform(decomposerTransformer, null) - } - - fun lower(irFunction: IrFunction) { - (irFunction.body as? IrExpressionBody)?.apply { - irFunction.body = toBlockBody(irFunction) - } - irFunction.accept(decomposerTransformer, null) - } - private fun IrExpressionBody.toBlockBody(containingFunction: IrFunction): IrBlockBody { - expression.patchDeclarationParents(containingFunction) - val returnStatement = JsIrBuilder.buildReturn(containingFunction.symbol, expression, nothingType) - return IrBlockBodyImpl(expression.startOffset, expression.endOffset).apply { + return IrBlockBodyImpl(startOffset, endOffset) { + expression.patchDeclarationParents(containingFunction) + val returnStatement = JsIrBuilder.buildReturn(containingFunction.symbol, expression, nothingType) statements += returnStatement } } - - fun lower(irField: IrField, container: IrDeclarationContainer): List { - irField.initializer?.apply { - val initFunction = JsIrBuilder.buildFunction( - irField.name.asString() + "\$init\$", - expression.type, - container, - Visibilities.PRIVATE - ) - - val newBody = toBlockBody(initFunction) - newBody.patchDeclarationParents(initFunction) - initFunction.body = newBody - - lower(initFunction) - - val lastStatement = newBody.statements.last() - if (newBody.statements.size > 1 || lastStatement !is IrReturn || lastStatement.value != expression) { - expression = JsIrBuilder.buildCall(initFunction.symbol, expression.type) - return listOf(initFunction, irField) - } - } - - return listOf(irField) - } } class BlockDecomposerTransformer(