From a0d9d24c1f3abb0ecb6ca20e61080929d3cd47f9 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Sat, 1 Oct 2016 15:00:37 +0300 Subject: [PATCH] Introduced IrElseBranch --- .../kotlin/backend/jvm/codegen/ExpressionCodegen.kt | 11 ++++++----- .../src/org/jetbrains/kotlin/ir/expressions/IrWhen.kt | 9 +++++++++ .../kotlin/ir/expressions/impl/IrWhenImpl.kt | 9 +++++++-- .../org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt | 7 +++++++ .../kotlin/ir/visitors/IrElementTransformer.kt | 6 ++++++ .../kotlin/ir/visitors/IrElementTransformerVoid.kt | 3 +++ .../jetbrains/kotlin/ir/visitors/IrElementVisitor.kt | 1 + 7 files changed, 39 insertions(+), 7 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index b967b0cb4b0..bd74794202a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -351,16 +351,17 @@ class ExpressionCodegen( override fun visitWhen(expression: IrWhen, data: BlockInfo): StackValue { val resultType = expression.asmType - genIfWithBranches(expression.branches[0].condition, expression.branches[0].result, data, resultType, expression.branches.drop(1)) + genIfWithBranches(expression.branches[0], data, resultType, expression.branches.drop(1)) return expression.onStack } - fun genIfWithBranches(condition: IrExpression, thenBranch: IrExpression, data: BlockInfo, type: Type, otherBranches: List) { + fun genIfWithBranches(branch: IrBranch, data: BlockInfo, type: Type, otherBranches: List) { val elseLabel = Label() - + val condition = branch.condition + val thenBranch = branch.result //TODO don't generate condition for else branch - java verifier fails with empty stack - val elseBranch = condition is IrConst<*> && true == condition.value + val elseBranch = branch is IrElseBranch if (!elseBranch) { gen(condition, data) BranchedValue.condJump(StackValue.onStack(condition.asmType), elseLabel, true, mv) @@ -378,7 +379,7 @@ class ExpressionCodegen( if (!otherBranches.isEmpty()) { val nextBranch = otherBranches.first() - genIfWithBranches(nextBranch.condition, nextBranch.result, data, type, otherBranches.drop(1)) + genIfWithBranches(nextBranch, data, type, otherBranches.drop(1)) } mv.mark(end) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrWhen.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrWhen.kt index ebfd0e0e38c..42380dd2b30 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrWhen.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrWhen.kt @@ -36,3 +36,12 @@ interface IrBranch : IrElement { override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitBranch(this, data) } + +interface IrElseBranch : IrBranch { + override fun transform(transformer: IrElementTransformer, data: D): IrElseBranch = + transformer.visitElseBranch(this, data) + + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitElseBranch(this, data) +} + diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt index 4cc71331b23..ad7effe758e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrWhenImpl.kt @@ -56,7 +56,7 @@ class IrWhenImpl( override val branches: MutableList = ArrayList() } -class IrBranchImpl(startOffset: Int, endOffset: Int, override var condition: IrExpression, override var result: IrExpression) : +open class IrBranchImpl(startOffset: Int, endOffset: Int, override var condition: IrExpression, override var result: IrExpression) : IrElementBase(startOffset, endOffset), IrBranch { constructor(condition: IrExpression, result: IrExpression) : this(condition.startOffset, condition.endOffset, condition, result) @@ -72,9 +72,14 @@ class IrBranchImpl(startOffset: Int, endOffset: Int, override var condition: IrE companion object { fun elseBranch(result: IrExpression) = - IrBranchImpl( + IrElseBranchImpl( IrConstImpl.boolean(result.startOffset, result.endOffset, result.type.builtIns.booleanType, true), result ) } +} + +class IrElseBranchImpl(startOffset: Int, endOffset: Int, condition: IrExpression, result: IrExpression) : + IrBranchImpl(startOffset, endOffset, condition, result), IrElseBranch { + constructor(condition: IrExpression, result: IrExpression) : this(condition.startOffset, condition.endOffset, condition, result) } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt index 36773770591..f78956d7c88 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt @@ -389,6 +389,13 @@ open class DeepCopyIrTree : IrElementTransformerVoid() { branch.result.transform(this, null) ) + override fun visitElseBranch(branch: IrElseBranch): IrElseBranch = + IrElseBranchImpl( + branch.startOffset, branch.endOffset, + branch.condition.transform(this, null), + branch.result.transform(this, null) + ) + private val transformedLoops = HashMap() private fun getTransformedLoop(irLoop: IrLoop): IrLoop = diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt index 8836c8e12df..95d1efca6dc 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt @@ -97,6 +97,12 @@ interface IrElementTransformer : IrElementVisitor { result = result.transform(this@IrElementTransformer, data) } + override fun visitElseBranch(branch: IrElseBranch, data: D): IrElseBranch = + branch.apply { + condition = condition.transform(this@IrElementTransformer, data) + result = result.transform(this@IrElementTransformer, data) + } + override fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data) override fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data) override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt index 5db7fd42bb6..474bad2a624 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt @@ -164,6 +164,9 @@ abstract class IrElementTransformerVoid : IrElementTransformer { open fun visitBranch(branch: IrBranch) = branch.apply { transformChildrenVoid(this@IrElementTransformerVoid) } override final fun visitBranch(branch: IrBranch, data: Nothing?): IrBranch = visitBranch(branch) + open fun visitElseBranch(branch: IrElseBranch) = branch.apply { transformChildrenVoid(this@IrElementTransformerVoid) } + override final fun visitElseBranch(branch: IrElseBranch, data: Nothing?): IrElseBranch = visitElseBranch(branch) + open fun visitLoop(loop: IrLoop) = visitExpression(loop) override final fun visitLoop(loop: IrLoop, data: Nothing?) = visitLoop(loop) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt index 1bdc90df358..e17b8a42fbc 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt @@ -77,6 +77,7 @@ interface IrElementVisitor { fun visitWhen(expression: IrWhen, data: D) = visitExpression(expression, data) fun visitBranch(branch: IrBranch, data: D) = visitElement(branch, data) + fun visitElseBranch(branch: IrElseBranch, data: D) = visitBranch(branch, data) fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data) fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data) fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data)