aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/ir/Node.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/ir/Node.java')
-rw-r--r--src/jdk/nashorn/internal/ir/Node.java229
1 files changed, 51 insertions, 178 deletions
diff --git a/src/jdk/nashorn/internal/ir/Node.java b/src/jdk/nashorn/internal/ir/Node.java
index c5f01337..dfed903d 100644
--- a/src/jdk/nashorn/internal/ir/Node.java
+++ b/src/jdk/nashorn/internal/ir/Node.java
@@ -25,7 +25,9 @@
package jdk.nashorn.internal.ir;
-import java.util.IdentityHashMap;
+import java.util.ArrayList;
+import java.util.List;
+
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.parser.Token;
@@ -33,30 +35,17 @@ import jdk.nashorn.internal.runtime.Source;
/**
* Nodes are used to compose Abstract Syntax Trees.
- *
*/
public abstract class Node extends Location {
/** Node symbol. */
private Symbol symbol;
/** Start of source range. */
- protected int start;
+ protected final int start;
/** End of source range. */
protected int finish;
- /** Has this node been resolved - i.e. emitted code already */
- private boolean isResolved;
-
- /** Is this node terminal */
- private boolean isTerminal;
-
- /** Is this a goto node */
- private boolean hasGoto;
-
- /** Is this a discard */
- private boolean shouldDiscard;
-
/**
* Constructor
*
@@ -72,6 +61,21 @@ public abstract class Node extends Location {
}
/**
+ * Constructor
+ *
+ * @param source source
+ * @param token token
+ * @param start start
+ * @param finish finish
+ */
+ protected Node(final Source source, final long token, final int start, final int finish) {
+ super(source, token);
+
+ this.start = start;
+ this.finish = finish;
+ }
+
+ /**
* Copy constructor
*
* @param node source node
@@ -79,13 +83,9 @@ public abstract class Node extends Location {
protected Node(final Node node) {
super(node);
- this.symbol = node.symbol;
- this.isResolved = node.isResolved;
- this.isTerminal = node.isTerminal;
- this.hasGoto = node.hasGoto;
- this.shouldDiscard = node.shouldDiscard;
- this.start = node.start;
- this.finish = node.finish;
+ this.symbol = node.symbol;
+ this.start = node.start;
+ this.finish = node.finish;
}
/**
@@ -156,28 +156,6 @@ public abstract class Node extends Location {
}
/**
- * Test to see if code been generated for this node. Set isResolved if not.
- *
- * @return True if node has already been resolved.
- */
- public boolean testResolved() {
- if (isResolved()) {
- return true;
- }
-
- setIsResolved(true);
-
- return false;
- }
-
- /**
- * Reset the resolved flag.
- */
- public void resetResolved() {
- setIsResolved(false);
- }
-
- /**
* Is this a debug info node like LineNumberNode etc?
*
* @return true if this is a debug node
@@ -187,72 +165,13 @@ public abstract class Node extends Location {
}
/**
- * Helper class used for node cloning
- */
- public static final class CopyState {
- private final IdentityHashMap<Node, Node> cloneMap = new IdentityHashMap<>();
-
- /**
- * Find existing or create new copy of the node.
- *
- * @param node Node to copy.
- *
- * @return New object.
- */
- public Node existingOrCopy(final Node node) {
- if (node != null) {
- Node copy = cloneMap.get(node);
-
- if (copy == null) {
- copy = node.copy(this);
- cloneMap.put(node, copy);
- }
-
- return copy;
- }
-
- return node;
- }
-
- /**
- * Find existing or use old copy of the node.
- *
- * @param node Node to copy.
- *
- * @return new object.
- */
- public Node existingOrSame(final Node node) {
- if (node != null) {
- Node copy = cloneMap.get(node);
-
- if (copy == null) {
- copy = node;
- }
-
- return copy;
- }
-
- return node;
- }
- }
-
- /**
- * Deep copy the node.
- *
- * @return Deep copy of the Node.
- */
- public final Node copy() {
- return copy(new CopyState());
- }
-
- /**
- * Deep copy the node.
- *
- * @param cs CopyState passed around to re-use certain nodes.
- * @return Deep copy of the Node.
+ * For reference copies - ensure that labels in the copy node are unique
+ * using an appropriate copy constructor
+ * @param lc lexical context
+ * @return new node or same of no labels
*/
- protected Node copy(final CopyState cs) {
- return cs.existingOrCopy(this);
+ public Node ensureUniqueLabels(final LexicalContext lc) {
+ return this;
}
/**
@@ -283,35 +202,7 @@ public abstract class Node extends Location {
* @return true if terminal
*/
public boolean hasTerminalFlags() {
- return isTerminal || hasGoto;
- }
-
- /**
- * Copy the terminal flags state of a node to another node
- *
- * @param other source node
- */
- public void copyTerminalFlags(final Node other) {
- isTerminal = other.isTerminal;
- hasGoto = other.hasGoto;
- }
-
- /**
- * Check if the return value of this expression should be discarded
- * @return true if return value is discarded
- */
- public boolean shouldDiscard() {
- return shouldDiscard;
- }
-
- /**
- * Setter that determines whether this node's return value should be discarded
- * or not
- *
- * @param shouldDiscard true if return value is discarded, false otherwise
- */
- public void setDiscard(final boolean shouldDiscard) {
- this.shouldDiscard = shouldDiscard;
+ return isTerminal() || hasGoto();
}
/**
@@ -336,29 +227,7 @@ public abstract class Node extends Location {
* @return true if node has goto semantics
*/
public boolean hasGoto() {
- return hasGoto;
- }
-
- /**
- * Flag this node as having goto semantics as described in {@link Node#hasGoto()}
- */
- public void setHasGoto() {
- this.hasGoto = true;
- }
-
- /**
- * Check whether this node is resolved, i.e. code has been generated for it
- * @return true if node is resolved
- */
- public boolean isResolved() {
- return isResolved;
- }
-
- /**
- * Flag this node as resolved or not, i.e. code has been generated for it
- */
- private void setIsResolved(boolean isResolved) {
- this.isResolved = isResolved;
+ return false;
}
/**
@@ -370,14 +239,6 @@ public abstract class Node extends Location {
}
/**
- * Set start position for node
- * @param start start position
- */
- public void setStart(final int start) {
- this.start = start;
- }
-
- /**
* Return the Symbol the compiler has assigned to this Node. The symbol
* is the place where it's expression value is stored after evaluation
*
@@ -404,17 +265,29 @@ public abstract class Node extends Location {
* @return true if this node is terminal
*/
public boolean isTerminal() {
- return isTerminal;
+ return false;
}
- /**
- * Set this to be a terminal node, i.e. it terminates control flow as described
- * in {@link Node#isTerminal()}
- *
- * @param isTerminal true if this is a terminal node, false otherwise
- */
- public void setIsTerminal(final boolean isTerminal) {
- this.isTerminal = isTerminal;
+ //on change, we have to replace the entire list, that's we can't simple do ListIterator.set
+ static <T extends Node> List<T> accept(final NodeVisitor visitor, final Class<T> clazz, final List<T> list) {
+ boolean changed = false;
+ final List<T> newList = new ArrayList<>();
+
+ for (final Node node : list) {
+ final T newNode = clazz.cast(node.accept(visitor));
+ if (newNode != node) {
+ changed = true;
+ }
+ newList.add(newNode);
+ }
+
+ return changed ? newList : list;
}
+ static <T extends LexicalContextNode> T replaceInLexicalContext(final LexicalContext lc, final T oldNode, final T newNode) {
+ if (lc != null) {
+ lc.replace(oldNode, newNode);
+ }
+ return newNode;
+ }
}