From fb55e34b8fd8f873e4b8212ff0e10c5eaf8caac0 Mon Sep 17 00:00:00 2001 From: pyos Date: Wed, 27 Mar 2019 12:34:49 +0100 Subject: [PATCH] Merge generateBreakOrContinueExpression and doFinallyOnReturn --- .../backend/jvm/codegen/ExpressionCodegen.kt | 69 ++++++------------- 1 file changed, 22 insertions(+), 47 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 141d178bf4c..88a74e7b6d0 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 @@ -75,8 +75,6 @@ class BlockInfo private constructor(val parent: BlockInfo?) { this@apply.infos.addAll(this@BlockInfo.infos) } - fun isEmpty(): Boolean = infos.isEmpty() - fun hasFinallyBlocks(): Boolean = infos.firstIsInstanceOrNull() != null inline fun withBlock(info: ExpressionInfo, f: (ExpressionInfo) -> R): R { @@ -88,7 +86,10 @@ class BlockInfo private constructor(val parent: BlockInfo?) { } } - inline fun handleBlock(f: (ExpressionInfo) -> R): R { + inline fun handleBlock(f: (ExpressionInfo) -> R): R? { + if (infos.isEmpty()) { + return null + } val top = infos.pop() try { return f(top) @@ -955,37 +956,24 @@ class ExpressionCodegen( return StackValue.none() } - override fun visitBreakContinue(jump: IrBreakContinue, data: BlockInfo): StackValue { - jump.markLineNumber(startOffset = true) - generateBreakOrContinueExpression(jump, Label(), data) - return none() + private fun unwindBlockStack(endLabel: Label, data: BlockInfo, loop: IrLoop? = null): LoopInfo? { + return data.handleBlock { + when { + it is TryInfo -> genFinallyBlock(it, null, endLabel, data) + it is LoopInfo && it.loop == loop -> return it + } + unwindBlockStack(endLabel, data, loop) + } } - private fun generateBreakOrContinueExpression( - expression: IrBreakContinue, - afterBreakContinueLabel: Label, - data: BlockInfo - ) { - if (data.isEmpty()) { - throw UnsupportedOperationException("Target label for break/continue not found") - } - - data.handleBlock { stackElement -> - when (stackElement) { - is TryInfo -> genFinallyBlock(stackElement, null, afterBreakContinueLabel, data) - is LoopInfo -> { - val loop = expression.loop - if (loop == stackElement.loop) { - val label = if (expression is IrBreak) stackElement.breakLabel else stackElement.continueLabel - mv.fixStackAndJump(label) - mv.mark(afterBreakContinueLabel) - return - } - } - else -> throw UnsupportedOperationException("Wrong BlockStackElement in processing stack") - } - generateBreakOrContinueExpression(expression, afterBreakContinueLabel, data) - } + override fun visitBreakContinue(jump: IrBreakContinue, data: BlockInfo): StackValue { + jump.markLineNumber(startOffset = true) + val endLabel = Label() + val stackElement = unwindBlockStack(endLabel, data, jump.loop) + ?: throw AssertionError("Target label for break/continue not found") + mv.fixStackAndJump(if (jump is IrBreak) stackElement.breakLabel else stackElement.continueLabel) + mv.mark(endLabel) + return none() } override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: BlockInfo): StackValue { @@ -1126,24 +1114,11 @@ class ExpressionCodegen( val returnValIndex = frame.enterTemp(returnType) val localForReturnValue = StackValue.local(returnValIndex, returnType) localForReturnValue.store(StackValue.onStack(returnType), mv) - doFinallyOnReturn(afterReturnLabel, data) + unwindBlockStack(afterReturnLabel, data, null) localForReturnValue.put(returnType, mv) frame.leaveTemp(returnType) } else { - doFinallyOnReturn(afterReturnLabel, data) - } - } - } - - private fun doFinallyOnReturn(afterReturnLabel: Label, data: BlockInfo) { - if (!data.isEmpty()) { - data.handleBlock { stackElement -> - when (stackElement) { - is TryInfo -> genFinallyBlock(stackElement, null, afterReturnLabel, data) - is LoopInfo -> {} - else -> throw UnsupportedOperationException("Wrong BlockStackElement in processing stack") - } - doFinallyOnReturn(afterReturnLabel, data) + unwindBlockStack(afterReturnLabel, data, null) } } }