8059371: Code duplication in handling of break and continue
Reviewed-by: jlaskey, lagergren
This commit is contained in:
parent
80fe5fad5c
commit
8f4114ee43
@ -104,6 +104,7 @@ import jdk.nashorn.internal.ir.IfNode;
|
||||
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 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
|
||||
@Override
|
||||
public boolean enterBreakNode(final BreakNode breakNode) {
|
||||
return enterJumpStatement(breakNode);
|
||||
}
|
||||
|
||||
private boolean enterJumpStatement(final JumpStatement jump) {
|
||||
if(!method.isReachable()) {
|
||||
return false;
|
||||
}
|
||||
enterStatement(breakNode);
|
||||
enterStatement(jump);
|
||||
|
||||
method.beforeJoinPoint(breakNode);
|
||||
final BreakableNode breakFrom = lc.getBreakable(breakNode.getLabelName());
|
||||
popScopesUntil(breakFrom);
|
||||
final Label breakLabel = breakFrom.getBreakLabel();
|
||||
breakLabel.markAsBreakTarget();
|
||||
method.splitAwareGoto(lc, breakLabel, breakFrom);
|
||||
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 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
|
||||
@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
|
||||
|
@ -464,21 +464,20 @@ final class LocalVariableTypesCalculator extends NodeVisitor<LexicalContext>{
|
||||
|
||||
@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) {
|
||||
|
@ -52,6 +52,7 @@ import jdk.nashorn.internal.ir.FunctionNode;
|
||||
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 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Lo
|
||||
|
||||
@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 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Lo
|
||||
@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;
|
||||
|
@ -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 @@ public final class BreakNode extends JumpStatement {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -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 @@ public class ContinueNode extends JumpStatement {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 @@ public abstract class JumpStatement extends Statement implements JoinPredecessor
|
||||
|
||||
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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user