8059371: Code duplication in handling of break and continue
Reviewed-by: jlaskey, lagergren
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Oct 01 10:26:25 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Oct 01 10:26:53 2014 +0200
@@ -104,6 +104,7 @@
import jdk.nashorn.internal.ir.IndexNode;
import jdk.nashorn.internal.ir.JoinPredecessor;
import jdk.nashorn.internal.ir.JoinPredecessorExpression;
+import jdk.nashorn.internal.ir.JumpStatement;
import jdk.nashorn.internal.ir.LabelNode;
import jdk.nashorn.internal.ir.LexicalContext;
import jdk.nashorn.internal.ir.LexicalContextNode;
@@ -1204,17 +1205,21 @@
@Override
public boolean enterBreakNode(final BreakNode breakNode) {
+ return enterJumpStatement(breakNode);
+ }
+
+ private boolean enterJumpStatement(final JumpStatement jump) {
if(!method.isReachable()) {
return false;
}
- enterStatement(breakNode);
-
- method.beforeJoinPoint(breakNode);
- final BreakableNode breakFrom = lc.getBreakable(breakNode.getLabelName());
- popScopesUntil(breakFrom);
- final Label breakLabel = breakFrom.getBreakLabel();
- breakLabel.markAsBreakTarget();
- method.splitAwareGoto(lc, breakLabel, breakFrom);
+ enterStatement(jump);
+
+ method.beforeJoinPoint(jump);
+ final BreakableNode target = jump.getTarget(lc);
+ popScopesUntil(target);
+ final Label targetLabel = jump.getTargetLabel(target);
+ targetLabel.markAsBreakTarget();
+ method.splitAwareGoto(lc, targetLabel, target);
return false;
}
@@ -1517,19 +1522,7 @@
@Override
public boolean enterContinueNode(final ContinueNode continueNode) {
- if(!method.isReachable()) {
- return false;
- }
- enterStatement(continueNode);
- method.beforeJoinPoint(continueNode);
-
- final LoopNode continueTo = lc.getContinueTo(continueNode.getLabelName());
- popScopesUntil(continueTo);
- final Label continueLabel = continueTo.getContinueLabel();
- continueLabel.markAsBreakTarget();
- method.splitAwareGoto(lc, continueLabel, continueTo);
-
- return false;
+ return enterJumpStatement(continueNode);
}
@Override
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java Wed Oct 01 10:26:25 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java Wed Oct 01 10:26:53 2014 +0200
@@ -464,21 +464,20 @@
@Override
public boolean enterBreakNode(final BreakNode breakNode) {
- if(!reachable) {
- return false;
- }
-
- final BreakableNode target = lc.getBreakable(breakNode.getLabelName());
- return splitAwareJumpToLabel(breakNode, target, target.getBreakLabel());
+ return enterJumpStatement(breakNode);
}
@Override
public boolean enterContinueNode(final ContinueNode continueNode) {
+ return enterJumpStatement(continueNode);
+ }
+
+ private boolean enterJumpStatement(final JumpStatement jump) {
if(!reachable) {
return false;
}
- final LoopNode target = lc.getContinueTo(continueNode.getLabelName());
- return splitAwareJumpToLabel(continueNode, target, target.getContinueLabel());
+ final BreakableNode target = jump.getTarget(lc);
+ return splitAwareJumpToLabel(jump, target, jump.getTargetLabel(target));
}
private boolean splitAwareJumpToLabel(final JumpStatement jumpStatement, final BreakableNode target, final Label targetLabel) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java Wed Oct 01 10:26:25 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java Wed Oct 01 10:26:53 2014 +0200
@@ -52,6 +52,7 @@
import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
import jdk.nashorn.internal.ir.IdentNode;
import jdk.nashorn.internal.ir.IfNode;
+import jdk.nashorn.internal.ir.JumpStatement;
import jdk.nashorn.internal.ir.LabelNode;
import jdk.nashorn.internal.ir.LexicalContext;
import jdk.nashorn.internal.ir.LiteralNode;
@@ -382,12 +383,16 @@
@Override
public Node leaveBreakNode(final BreakNode breakNode) {
- return copy(breakNode, (Node)Lower.this.lc.getBreakable(breakNode.getLabelName()));
+ return leaveJumpStatement(breakNode);
}
@Override
public Node leaveContinueNode(final ContinueNode continueNode) {
- return copy(continueNode, Lower.this.lc.getContinueTo(continueNode.getLabelName()));
+ return leaveJumpStatement(continueNode);
+ }
+
+ private Node leaveJumpStatement(final JumpStatement jump) {
+ return copy(jump, (Node)jump.getTarget(Lower.this.lc));
}
@Override
@@ -627,7 +632,7 @@
@Override
public Node leaveContinueNode(final ContinueNode node) {
// all inner loops have been popped.
- if (lex.contains(lex.getContinueTo(node.getLabelName()))) {
+ if (lex.contains(node.getTarget(lex))) {
escapes.add(node);
}
return node;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BreakNode.java Wed Oct 01 10:26:25 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BreakNode.java Wed Oct 01 10:26:53 2014 +0200
@@ -25,6 +25,7 @@
package jdk.nashorn.internal.ir;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.ir.annotations.Immutable;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
@@ -68,4 +69,14 @@
String getStatementName() {
return "break";
}
+
+ @Override
+ public BreakableNode getTarget(final LexicalContext lc) {
+ return lc.getBreakable(getLabelName());
+ }
+
+ @Override
+ public Label getTargetLabel(final BreakableNode target) {
+ return target.getBreakLabel();
+ }
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ContinueNode.java Wed Oct 01 10:26:25 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ContinueNode.java Wed Oct 01 10:26:53 2014 +0200
@@ -25,6 +25,7 @@
package jdk.nashorn.internal.ir;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.ir.annotations.Immutable;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
@@ -67,5 +68,16 @@
String getStatementName() {
return "continue";
}
+
+
+ @Override
+ public BreakableNode getTarget(final LexicalContext lc) {
+ return lc.getContinueTo(getLabelName());
+ }
+
+ @Override
+ public Label getTargetLabel(final BreakableNode target) {
+ return ((LoopNode)target).getContinueLabel();
+ }
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/JumpStatement.java Wed Oct 01 10:26:25 2014 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/JumpStatement.java Wed Oct 01 10:26:53 2014 +0200
@@ -25,6 +25,8 @@
package jdk.nashorn.internal.ir;
+import jdk.nashorn.internal.codegen.Label;
+
/**
* Common base class for jump statements (e.g. {@code break} and {@code continue}).
*/
@@ -82,6 +84,24 @@
abstract String getStatementName();
+ /**
+ * Finds the target for this jump statement in a lexical context.
+ * @param lc the lexical context
+ * @return the target, or null if not found
+ */
+ public abstract BreakableNode getTarget(final LexicalContext lc);
+
+ /**
+ * Returns the label corresponding to this kind of jump statement (either a break or continue label) in the target.
+ * @param target the target. Note that it need not be the target of this jump statement, as the method can retrieve
+ * a label on any passed target as long as the target has a label of the requisite kind. Of course, it is advisable
+ * to invoke the method on a jump statement that targets the breakable.
+ * @return the label of the target corresponding to the kind of jump statement.
+ * @throws ClassCastException if invoked on the kind of breakable node that this jump statement is not prepared to
+ * handle.
+ */
+ public abstract Label getTargetLabel(final BreakableNode target);
+
@Override
public JumpStatement setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
if(this.conversion == conversion) {