diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/Label.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/Label.kt index 7aeb53c7a86..1b98a6f42f4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/Label.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/Label.kt @@ -16,6 +16,15 @@ package org.jetbrains.kotlin.cfg +import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode +import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction + interface Label { + val pseudocode: Pseudocode + val name: String + + val targetInstructionIndex: Int + + fun resolveToInstruction(): Instruction } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt index ad06bdd982e..c5efbd9c20f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt @@ -302,7 +302,7 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() { } override fun bindLabel(label: Label) { - pseudocode.bindLabel(label) + pseudocode.bindLabel(label as PseudocodeLabel) } override fun nondeterministicJump(label: Label, element: KtElement, inputValue: PseudoValue?) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/PseudocodeImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/PseudocodeImpl.kt index 15ca239b951..acf24c6330e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/PseudocodeImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/PseudocodeImpl.kt @@ -38,40 +38,8 @@ import org.jetbrains.kotlin.psi.KtElement import java.util.* class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode { - inner class PseudocodeLabel internal constructor(private val name: String, private val comment: String?) : Label { - var targetInstructionIndex: Int? = null - private set - override fun getName(): String { - return name - } - - override fun toString(): String { - return if (comment == null) name else "$name [$comment]" - } - - fun setTargetInstructionIndex(targetInstructionIndex: Int) { - this.targetInstructionIndex = targetInstructionIndex - } - - fun resolveToInstruction(): Instruction { - val index = targetInstructionIndex - if (index == null || index >= mutableInstructionList.size) { - error("resolveToInstruction: incorrect index $index for label $name " + - "in subroutine ${correspondingElement.text} with instructions $mutableInstructionList") - } - return mutableInstructionList[index] - } - - fun copy(newLabelIndex: Int): PseudocodeLabel { - return PseudocodeLabel("L" + newLabelIndex, "copy of $name, $comment") - } - - val pseudocode: PseudocodeImpl - get() = this@PseudocodeImpl - } - - private val mutableInstructionList = ArrayList() + internal val mutableInstructionList = ArrayList() override val instructions = ArrayList() private val elementsToValues = BidirectionalMap() @@ -130,7 +98,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode } fun createLabel(name: String, comment: String?): PseudocodeLabel { - val label = PseudocodeLabel(name, comment) + val label = PseudocodeLabel(this, name, comment) labels.add(label) return label } @@ -223,8 +191,8 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode elementsToValues.put(element, value) } - fun bindLabel(label: Label) { - (label as PseudocodeLabel).setTargetInstructionIndex(mutableInstructionList.size) + fun bindLabel(label: PseudocodeLabel) { + label.targetInstructionIndex = mutableInstructionList.size } private fun getMergedValues(value: PseudoValue) = mergedValues[value] ?: emptySet() @@ -363,7 +331,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode } private fun getJumpTarget(targetLabel: Label): Instruction { - return (targetLabel as PseudocodeLabel).resolveToInstruction() + return targetLabel.resolveToInstruction() } private fun getNextPosition(currentPosition: Int): Instruction { @@ -388,7 +356,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode } fun repeatPart(startLabel: Label, finishLabel: Label, labelCount: Int): Int { - return repeatInternal((startLabel as PseudocodeLabel).pseudocode, startLabel, finishLabel, labelCount) + return repeatInternal(startLabel.pseudocode as PseudocodeImpl, startLabel, finishLabel, labelCount) } private fun repeatInternal( @@ -396,17 +364,19 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode startLabel: Label?, finishLabel: Label?, labelCountArg: Int): Int { var labelCount = labelCountArg - val startIndex = (if (startLabel != null) (startLabel as PseudocodeLabel).targetInstructionIndex else Integer.valueOf(0))!! - val finishIndex = (if (finishLabel != null) - (finishLabel as PseudocodeLabel).targetInstructionIndex + val startIndex = if (startLabel != null) startLabel.targetInstructionIndex else 0 + val finishIndex = if (finishLabel != null) + finishLabel.targetInstructionIndex else - Integer.valueOf(originalPseudocode.mutableInstructionList.size))!! + originalPseudocode.mutableInstructionList.size - val originalToCopy = Maps.newLinkedHashMap() + val originalToCopy = Maps.newLinkedHashMap() val originalLabelsForInstruction = HashMultimap.create() for (label in originalPseudocode.labels) { - val index = label.targetInstructionIndex ?: continue + val index = label.targetInstructionIndex //label is not bounded yet + if (index < 0) continue + if (label === startLabel || label === finishLabel) continue if (startIndex <= index && index <= finishIndex) { @@ -415,7 +385,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode } } for (label in originalToCopy.values) { - labels.add(label as PseudocodeLabel) + labels.add(label) } for (index in startIndex..finishIndex - 1) { val originalInstruction = originalPseudocode.mutableInstructionList[index] @@ -442,14 +412,14 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode private fun repeatLabelsBindingForInstruction( originalInstruction: Instruction, - originalToCopy: Map, + originalToCopy: Map, originalLabelsForInstruction: Multimap) { for (originalLabel in originalLabelsForInstruction.get(originalInstruction)) { bindLabel(originalToCopy[originalLabel]!!) } } - private fun copyInstruction(instruction: Instruction, originalToCopy: Map): Instruction { + private fun copyInstruction(instruction: Instruction, originalToCopy: Map): Instruction { if (instruction is AbstractJumpInstruction) { val originalTarget = instruction.targetLabel if (originalToCopy.containsKey(originalTarget)) { @@ -464,7 +434,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode return (instruction as InstructionImpl).copy() } - private fun copyLabels(labels: Collection