1 /* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.ir; 27 28 import java.util.Collections; 29 import java.util.List; 30 import jdk.nashorn.internal.codegen.Label; 31 import jdk.nashorn.internal.ir.annotations.Immutable; 32 33 @Immutable 34 abstract class BreakableStatement extends LexicalContextStatement implements BreakableNode { 35 private static final long serialVersionUID = 1L; 36 37 /** break label. */ 38 protected final Label breakLabel; 39 40 final LocalVariableConversion conversion; 41 42 /** 43 * Constructor 44 * 45 * @param lineNumber line number 46 * @param token token 47 * @param finish finish 48 * @param breakLabel break label 49 */ 50 protected BreakableStatement(final int lineNumber, final long token, final int finish, final Label breakLabel) { 51 super(lineNumber, token, finish); 52 this.breakLabel = breakLabel; 53 this.conversion = null; 54 } 55 56 /** 57 * Copy constructor 58 * 59 * @param breakableNode source node 60 * @param conversion the potentially new local variable conversion 61 */ 62 protected BreakableStatement(final BreakableStatement breakableNode, final LocalVariableConversion conversion) { 63 super(breakableNode); 64 this.breakLabel = new Label(breakableNode.getBreakLabel()); 65 this.conversion = conversion; 66 } 67 68 /** 69 * Check whether this can be broken out from without using a label, 70 * e.g. everything but Blocks, basically 71 * @return true if breakable without label 72 */ 73 @Override 74 public boolean isBreakableWithoutLabel() { 75 return true; 76 } 77 78 /** 79 * Return the break label, i.e. the location to go to on break. 80 * @return the break label 81 */ 82 @Override 83 public Label getBreakLabel() { 84 return breakLabel; 85 } 86 87 /** 88 * Return the labels associated with this node. Breakable nodes that 89 * aren't LoopNodes only have a break label - the location immediately 90 * afterwards the node in code 91 * @return list of labels representing locations around this node 92 */ 93 @Override 94 public List<Label> getLabels() { 95 return Collections.unmodifiableList(Collections.singletonList(breakLabel)); 96 } 97 98 @Override 99 public JoinPredecessor setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) { 100 if(this.conversion == conversion) { 101 return this; 102 } 103 return setLocalVariableConversionChanged(lc, conversion); 104 } 105 106 @Override 107 public LocalVariableConversion getLocalVariableConversion() { 108 return conversion; 109 } 110 111 abstract JoinPredecessor setLocalVariableConversionChanged(LexicalContext lc, LocalVariableConversion conversion); 112 }