aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/ir/VarNode.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/ir/VarNode.java')
-rw-r--r--src/jdk/nashorn/internal/ir/VarNode.java131
1 files changed, 66 insertions, 65 deletions
diff --git a/src/jdk/nashorn/internal/ir/VarNode.java b/src/jdk/nashorn/internal/ir/VarNode.java
index b719c99d..fbc3eabe 100644
--- a/src/jdk/nashorn/internal/ir/VarNode.java
+++ b/src/jdk/nashorn/internal/ir/VarNode.java
@@ -25,21 +25,31 @@
package jdk.nashorn.internal.ir;
+import jdk.nashorn.internal.ir.annotations.Immutable;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.runtime.Source;
/**
* Node represents a var/let declaration.
*/
-public class VarNode extends Node implements Assignment<IdentNode> {
+@Immutable
+public final class VarNode extends Node implements Assignment<IdentNode> {
/** Var name. */
- private IdentNode name;
+ private final IdentNode name;
/** Initialization expression. */
- private Node init;
+ private final Node init;
/** Is this a var statement (as opposed to a "var" in a for loop statement) */
- private final boolean isStatement;
+ private final int flags;
+
+ /** Flag that determines if this function node is a statement */
+ public static final int IS_STATEMENT = 1 << 0;
+
+ /** Flag that determines if this is the last function declaration in a function
+ * This is used to micro optimize the placement of return value assignments for
+ * a program node */
+ public static final int IS_LAST_FUNCTION_DECLARATION = 1 << 1;
/**
* Constructor
@@ -51,7 +61,14 @@ public class VarNode extends Node implements Assignment<IdentNode> {
* @param init init node or null if just a declaration
*/
public VarNode(final Source source, final long token, final int finish, final IdentNode name, final Node init) {
- this(source, token, finish, name, init, true);
+ this(source, token, finish, name, init, IS_STATEMENT);
+ }
+
+ private VarNode(final VarNode varNode, final IdentNode name, final Node init, final int flags) {
+ super(varNode);
+ this.name = init == null ? name : name.setIsInitializedHere();
+ this.init = init;
+ this.flags = flags;
}
/**
@@ -62,28 +79,14 @@ public class VarNode extends Node implements Assignment<IdentNode> {
* @param finish finish
* @param name name of variable
* @param init init node or null if just a declaration
- * @param isStatement if this is a var statement (true), or a for-loop initializer (false)
+ * @param flags flags
*/
- public VarNode(final Source source, final long token, final int finish, final IdentNode name, final Node init, boolean isStatement) {
+ public VarNode(final Source source, final long token, final int finish, final IdentNode name, final Node init, final int flags) {
super(source, token, finish);
this.name = init == null ? name : name.setIsInitializedHere();
this.init = init;
- this.isStatement = isStatement;
- }
-
-
- private VarNode(final VarNode varNode, final CopyState cs) {
- super(varNode);
-
- this.name = (IdentNode)cs.existingOrCopy(varNode.name);
- this.init = cs.existingOrCopy(varNode.init);
- this.isStatement = varNode.isStatement;
- }
-
- @Override
- protected Node copy(final CopyState cs) {
- return new VarNode(this, cs);
+ this.flags = flags;
}
@Override
@@ -115,45 +118,17 @@ public class VarNode extends Node implements Assignment<IdentNode> {
}
/**
- * Test to see if two VarNodes are the same.
- * @param other Other VarNode.
- * @return True if the VarNodes are the same.
- */
- @Override
- public boolean equals(final Object other) {
- if (other instanceof VarNode) {
- final VarNode otherNode = (VarNode)other;
- final boolean nameMatches = name.equals(otherNode.name);
- if (hasInit() != otherNode.hasInit()) {
- return false;
- } else if (init == null) {
- return nameMatches;
- } else {
- return nameMatches && init.equals(otherNode.init);
- }
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return name.hashCode() ^ (init == null ? 0 : init.hashCode());
- }
-
- /**
* Assist in IR navigation.
* @param visitor IR navigating visitor.
*/
@Override
public Node accept(final NodeVisitor visitor) {
- if (visitor.enterVarNode(this) != null) {
+ if (visitor.enterVarNode(this)) {
final IdentNode newName = (IdentNode)name.accept(visitor);
- final Node newInit = init == null ? null : init.accept(visitor);
- final VarNode newThis;
- if(name != newName || init != newInit) {
- newThis = (VarNode)clone();
- newThis.init = newInit;
- newThis.name = newInit == null ? newName : newName.setIsInitializedHere();
+ final Node newInit = init == null ? null : init.accept(visitor);
+ final VarNode newThis;
+ if (name != newName || init != newInit) {
+ newThis = new VarNode(this, newName, newInit, flags);
} else {
newThis = this;
}
@@ -187,10 +162,10 @@ public class VarNode extends Node implements Assignment<IdentNode> {
* @return a node equivalent to this one except for the requested change.
*/
public VarNode setInit(final Node init) {
- if(this.init == init) return this;
- final VarNode n = (VarNode)clone();
- n.init = init;
- return n;
+ if (this.init == init) {
+ return this;
+ }
+ return new VarNode(this, name, init, flags);
}
/**
@@ -204,12 +179,38 @@ public class VarNode extends Node implements Assignment<IdentNode> {
/**
* Reset the identifier for this VarNode
* @param name new IdentNode representing the variable being set or declared
+ * @return a node equivalent to this one except for the requested change.
+ */
+ public VarNode setName(final IdentNode name) {
+ if (this.name == name) {
+ return this;
+ }
+ return new VarNode(this, name, init, flags);
+ }
+
+ private VarNode setFlags(final int flags) {
+ if (this.flags == flags) {
+ return this;
+ }
+ return new VarNode(this, name, init, flags);
+ }
+
+ /**
+ * Check if a flag is set for this var node
+ * @param flag flag
+ * @return true if flag is set
+ */
+ public boolean getFlag(final int flag) {
+ return (flags & flag) == flag;
+ }
+
+ /**
+ * Set a flag for this var node
+ * @param flag flag
+ * @return new node if flags changed, same otherwise
*/
- private VarNode setName(final IdentNode name) {
- if(this.name == name) return this;
- final VarNode n = (VarNode)clone();
- n.name = name;
- return n;
+ public VarNode setFlag(final int flag) {
+ return setFlags(flags | flag);
}
/**
@@ -217,7 +218,7 @@ public class VarNode extends Node implements Assignment<IdentNode> {
* @return true if this is a var statement (as opposed to a var initializer in a for loop).
*/
public boolean isStatement() {
- return isStatement;
+ return (flags & IS_STATEMENT) != 0;
}
/**