Skip to content

Commit 43525ab

Browse files
Alexey AndreevAlexey Andreev
Alexey Andreev
authored and
Alexey Andreev
committed
JS: don't treat return, break and continue as split points when possible
1 parent 14729b0 commit 43525ab

File tree

3 files changed

+48
-13
lines changed

3 files changed

+48
-13
lines changed

js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/JsFor.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,18 @@ public void traverse(JsVisitorWithContext v, JsContext ctx) {
107107
if (initExpression != null) {
108108
initExpression = v.accept(initExpression);
109109
} else if (initVars != null) {
110-
initVars = v.acceptStatement(initVars);
110+
JsStatement newInitVars = v.<JsStatement>acceptStatement(initVars);
111+
if (newInitVars instanceof JsVars) {
112+
initVars = (JsVars) newInitVars;
113+
}
114+
else {
115+
initVars = null;
116+
if (newInitVars instanceof JsExpressionStatement) {
117+
initExpression = ((JsExpressionStatement) newInitVars).getExpression();
118+
} else if (newInitVars != null) {
119+
ctx.addPrevious(newInitVars);
120+
}
121+
}
111122
}
112123

113124
if (condition != null) {

js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutineBodyTransformer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class CoroutineBodyTransformer(
5151

5252
fun preProcess(node: JsNode) {
5353
breakContinueTargetStatements += node.collectBreakContinueTargets()
54-
nodesToSplit = node.collectNodesToSplit()
54+
nodesToSplit = node.collectNodesToSplit(breakContinueTargetStatements)
5555
}
5656

5757
fun postProcess(): List<CoroutineBlock> {

js/js.inliner/src/org/jetbrains/kotlin/js/coroutine/CoroutinePasses.kt

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ import com.google.dart.compiler.backend.js.ast.metadata.*
2121
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
2222
import org.jetbrains.kotlin.utils.singletonOrEmptyList
2323

24-
fun JsNode.collectNodesToSplit(): Set<JsNode> {
24+
fun JsNode.collectNodesToSplit(breakContinueTargets: Map<JsContinue, JsStatement>): Set<JsNode> {
25+
val root = this
2526
val nodes = mutableSetOf<JsNode>()
2627

2728
val visitor = object : RecursiveJsVisitor() {
2829
var childrenInSet = false
30+
var finallyLevel = 0
2931

3032
override fun visitInvocation(invocation: JsInvocation) {
3133
super.visitInvocation(invocation)
@@ -37,23 +39,41 @@ fun JsNode.collectNodesToSplit(): Set<JsNode> {
3739

3840
override fun visitReturn(x: JsReturn) {
3941
super.visitReturn(x)
40-
nodes += x
41-
childrenInSet = true
42+
43+
if (root in nodes || finallyLevel > 0) {
44+
nodes += x
45+
childrenInSet = true
46+
}
4247
}
4348

4449
override fun visitBreak(x: JsBreak) {
4550
super.visitBreak(x)
4651

47-
// It's a simplification
48-
// TODO: don't split break and continue statements when possible
49-
nodes += x
50-
childrenInSet = true
52+
val breakTarget = breakContinueTargets[x]!!
53+
if (breakTarget in nodes) {
54+
nodes += x
55+
childrenInSet = true
56+
}
5157
}
5258

5359
override fun visitContinue(x: JsContinue) {
5460
super.visitContinue(x)
55-
nodes += x
56-
childrenInSet = true
61+
62+
val continueTarget = breakContinueTargets[x]!!
63+
if (continueTarget in nodes) {
64+
nodes += x
65+
childrenInSet = true
66+
}
67+
}
68+
69+
override fun visitTry(x: JsTry) {
70+
if (x.finallyBlock != null) {
71+
finallyLevel++
72+
}
73+
super.visitTry(x)
74+
if (x.finallyBlock != null) {
75+
finallyLevel--
76+
}
5777
}
5878

5979
override fun visitElement(node: JsNode) {
@@ -71,8 +91,12 @@ fun JsNode.collectNodesToSplit(): Set<JsNode> {
7191
}
7292
}
7393

74-
visitor.accept(this)
75-
visitor.accept(this)
94+
while (true) {
95+
val countBefore = nodes.size
96+
visitor.accept(this)
97+
val countAfter = nodes.size
98+
if (countAfter == countBefore) break
99+
}
76100

77101
return nodes
78102
}

0 commit comments

Comments
 (0)