[JS IR] Use label for continue loop in tailrec

^KT-46218 fixed
This commit is contained in:
Ilya Goncharov
2021-10-06 18:31:01 +03:00
committed by Space
parent eb901e4f32
commit a0fb60f201
2 changed files with 17 additions and 8 deletions
@@ -304,7 +304,7 @@ class LocalNameGenerator(parentScope: NameScope) : IrElementVisitorVoid {
val localLoopNames = NameTable<IrLoop>() val localLoopNames = NameTable<IrLoop>()
val localReturnableBlockNames = NameTable<IrReturnableBlock>() val localReturnableBlockNames = NameTable<IrReturnableBlock>()
private val breakableDeque: Deque<IrExpression> = LinkedList() private val jumpableDeque: Deque<IrExpression> = LinkedList()
override fun visitElement(element: IrElement) { override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this) element.acceptChildrenVoid(this)
@@ -319,13 +319,22 @@ class LocalNameGenerator(parentScope: NameScope) : IrElementVisitorVoid {
override fun visitBreak(jump: IrBreak) { override fun visitBreak(jump: IrBreak) {
val loop = jump.loop val loop = jump.loop
if (loop.label == null && loop != breakableDeque.firstOrNull()) { if (loop.label == null && loop != jumpableDeque.firstOrNull()) {
persistLoopName(SYNTHETIC_LOOP_LABEL, loop) persistLoopName(SYNTHETIC_LOOP_LABEL, loop)
} }
super.visitBreak(jump) super.visitBreak(jump)
} }
override fun visitContinue(jump: IrContinue) {
val loop = jump.loop
if (loop.label == null && loop != jumpableDeque.firstOrNull()) {
persistLoopName(SYNTHETIC_LOOP_LABEL, loop)
}
super.visitContinue(jump)
}
override fun visitReturn(expression: IrReturn) { override fun visitReturn(expression: IrReturn) {
val targetSymbol = expression.returnTargetSymbol val targetSymbol = expression.returnTargetSymbol
if (targetSymbol is IrReturnableBlockSymbol) { if (targetSymbol is IrReturnableBlockSymbol) {
@@ -336,19 +345,19 @@ class LocalNameGenerator(parentScope: NameScope) : IrElementVisitorVoid {
} }
override fun visitWhen(expression: IrWhen) { override fun visitWhen(expression: IrWhen) {
breakableDeque.push(expression) jumpableDeque.push(expression)
super.visitWhen(expression) super.visitWhen(expression)
breakableDeque.pop() jumpableDeque.pop()
} }
override fun visitLoop(loop: IrLoop) { override fun visitLoop(loop: IrLoop) {
breakableDeque.push(loop) jumpableDeque.push(loop)
super.visitLoop(loop) super.visitLoop(loop)
breakableDeque.pop() jumpableDeque.pop()
val label = loop.label val label = loop.label
@@ -384,5 +393,5 @@ fun sanitizeName(name: String): String {
return builder.toString() return builder.toString()
} }
private const val SYNTHETIC_LOOP_LABEL = "\$l\$break" private const val SYNTHETIC_LOOP_LABEL = "\$l\$loop"
private const val SYNTHETIC_BLOCK_LABEL = "\$l\$block" private const val SYNTHETIC_BLOCK_LABEL = "\$l\$block"
@@ -1,5 +1,5 @@
// KT-14961 // KT-14961
// IGNORE_BACKEND: JVM, JS_IR // IGNORE_BACKEND: JVM
// WITH_RUNTIME // WITH_RUNTIME
fun listOfFactor(number: Int): List<Int> { fun listOfFactor(number: Int): List<Int> {