Tue, 08 Jan 2013 15:20:40 +0100
8005842: Loops in ASTWriter. Corrected @Reference and @Ignore node annotation for IR nodes
Reviewed-by: hannesw, sundar
1.1 --- a/src/jdk/nashorn/internal/ir/Block.java Tue Jan 08 14:14:17 2013 +0100 1.2 +++ b/src/jdk/nashorn/internal/ir/Block.java Tue Jan 08 15:20:40 2013 +0100 1.3 @@ -44,7 +44,6 @@ 1.4 import jdk.nashorn.internal.codegen.MethodEmitter.Label; 1.5 import jdk.nashorn.internal.ir.annotations.Ignore; 1.6 import jdk.nashorn.internal.ir.annotations.ParentNode; 1.7 -import jdk.nashorn.internal.ir.annotations.Reference; 1.8 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 1.9 import jdk.nashorn.internal.runtime.Source; 1.10 1.11 @@ -55,11 +54,11 @@ 1.12 */ 1.13 public class Block extends Node { 1.14 /** Parent context */ 1.15 - @ParentNode @Reference 1.16 + @ParentNode @Ignore 1.17 private Block parent; 1.18 1.19 /** Owning function. */ 1.20 - @Ignore @Reference 1.21 + @Ignore //don't print it, it is apparent in the tree 1.22 protected FunctionNode function; 1.23 1.24 /** List of statements */
2.1 --- a/src/jdk/nashorn/internal/ir/FunctionNode.java Tue Jan 08 14:14:17 2013 +0100 2.2 +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java Tue Jan 08 15:20:40 2013 +0100 2.3 @@ -46,7 +46,6 @@ 2.4 import jdk.nashorn.internal.codegen.Transform; 2.5 import jdk.nashorn.internal.codegen.types.Type; 2.6 import jdk.nashorn.internal.ir.annotations.Ignore; 2.7 -import jdk.nashorn.internal.ir.annotations.Reference; 2.8 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 2.9 import jdk.nashorn.internal.parser.Parser; 2.10 import jdk.nashorn.internal.runtime.Source; 2.11 @@ -142,11 +141,11 @@ 2.12 private final List<VarNode> declarations; 2.13 2.14 /** VarNode for this function statement */ 2.15 - @Reference @Ignore //this is explicit code anyway and should not be traverseda after lower 2.16 + @Ignore //this is explicit code anyway and should not be traversed after lower 2.17 private VarNode funcVarNode; 2.18 2.19 /** Line number for function declaration */ 2.20 - @Reference @Ignore 2.21 + @Ignore 2.22 private LineNumberNode funcVarLineNumberNode; 2.23 2.24 /** Function flags. */
3.1 --- a/src/jdk/nashorn/internal/ir/LabelNode.java Tue Jan 08 14:14:17 2013 +0100 3.2 +++ b/src/jdk/nashorn/internal/ir/LabelNode.java Tue Jan 08 15:20:40 2013 +0100 3.3 @@ -25,7 +25,7 @@ 3.4 3.5 package jdk.nashorn.internal.ir; 3.6 3.7 -import jdk.nashorn.internal.ir.annotations.Reference; 3.8 +import jdk.nashorn.internal.ir.annotations.Ignore; 3.9 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 3.10 import jdk.nashorn.internal.runtime.Source; 3.11 3.12 @@ -42,11 +42,11 @@ 3.13 private Block body; 3.14 3.15 /** Node to break from. */ 3.16 - @Reference 3.17 + @Ignore 3.18 private Node breakNode; 3.19 3.20 /** Node to continue. */ 3.21 - @Reference 3.22 + @Ignore 3.23 private Node continueNode; 3.24 3.25 /**
4.1 --- a/src/jdk/nashorn/internal/ir/LabeledNode.java Tue Jan 08 14:14:17 2013 +0100 4.2 +++ b/src/jdk/nashorn/internal/ir/LabeledNode.java Tue Jan 08 15:20:40 2013 +0100 4.3 @@ -26,7 +26,6 @@ 4.4 package jdk.nashorn.internal.ir; 4.5 4.6 import jdk.nashorn.internal.ir.annotations.Ignore; 4.7 -import jdk.nashorn.internal.ir.annotations.Reference; 4.8 import jdk.nashorn.internal.runtime.Source; 4.9 4.10 /** 4.11 @@ -39,11 +38,11 @@ 4.12 protected final LabelNode labelNode; 4.13 4.14 /** Target control node. */ 4.15 - @Reference @Ignore 4.16 + @Ignore 4.17 protected final Node targetNode; 4.18 4.19 /** Try chain. */ 4.20 - @Reference 4.21 + @Ignore 4.22 protected final TryNode tryChain; 4.23 4.24 /** scope nesting level */
5.1 --- a/src/jdk/nashorn/internal/ir/ObjectNode.java Tue Jan 08 14:14:17 2013 +0100 5.2 +++ b/src/jdk/nashorn/internal/ir/ObjectNode.java Tue Jan 08 15:20:40 2013 +0100 5.3 @@ -29,7 +29,6 @@ 5.4 import java.util.Collections; 5.5 import java.util.List; 5.6 import jdk.nashorn.internal.ir.annotations.Ignore; 5.7 -import jdk.nashorn.internal.ir.annotations.Reference; 5.8 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 5.9 import jdk.nashorn.internal.runtime.Source; 5.10 5.11 @@ -38,7 +37,7 @@ 5.12 */ 5.13 public class ObjectNode extends Node { 5.14 /** Literal context. */ 5.15 - @Reference @Ignore 5.16 + @Ignore 5.17 private Block context; 5.18 5.19 /** Literal elements. */
6.1 --- a/src/jdk/nashorn/internal/ir/ReferenceNode.java Tue Jan 08 14:14:17 2013 +0100 6.2 +++ b/src/jdk/nashorn/internal/ir/ReferenceNode.java Tue Jan 08 15:20:40 2013 +0100 6.3 @@ -25,7 +25,6 @@ 6.4 6.5 package jdk.nashorn.internal.ir; 6.6 6.7 -import jdk.nashorn.internal.ir.annotations.Ignore; 6.8 import jdk.nashorn.internal.ir.annotations.Reference; 6.9 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 6.10 import jdk.nashorn.internal.runtime.Source; 6.11 @@ -35,7 +34,7 @@ 6.12 */ 6.13 public class ReferenceNode extends Node { 6.14 /** Node referenced. */ 6.15 - @Reference @Ignore 6.16 + @Reference 6.17 private final FunctionNode reference; 6.18 6.19 /**
7.1 --- a/src/jdk/nashorn/internal/ir/ReturnNode.java Tue Jan 08 14:14:17 2013 +0100 7.2 +++ b/src/jdk/nashorn/internal/ir/ReturnNode.java Tue Jan 08 15:20:40 2013 +0100 7.3 @@ -29,7 +29,6 @@ 7.4 import static jdk.nashorn.internal.parser.TokenType.YIELD; 7.5 7.6 import jdk.nashorn.internal.ir.annotations.Ignore; 7.7 -import jdk.nashorn.internal.ir.annotations.Reference; 7.8 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 7.9 import jdk.nashorn.internal.runtime.Source; 7.10 7.11 @@ -42,7 +41,7 @@ 7.12 private Node expression; 7.13 7.14 /** Try chain. */ 7.15 - @Reference @Ignore 7.16 + @Ignore 7.17 private final TryNode tryChain; 7.18 7.19 /**
8.1 --- a/src/jdk/nashorn/internal/ir/SplitNode.java Tue Jan 08 14:14:17 2013 +0100 8.2 +++ b/src/jdk/nashorn/internal/ir/SplitNode.java Tue Jan 08 15:20:40 2013 +0100 8.3 @@ -30,6 +30,8 @@ 8.4 import java.util.List; 8.5 import jdk.nashorn.internal.codegen.CompileUnit; 8.6 import jdk.nashorn.internal.codegen.MethodEmitter; 8.7 +import jdk.nashorn.internal.ir.annotations.Ignore; 8.8 +import jdk.nashorn.internal.ir.annotations.Reference; 8.9 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 8.10 8.11 8.12 @@ -50,15 +52,18 @@ 8.13 private MethodEmitter caller; 8.14 8.15 /** Containing function. */ 8.16 + @Reference 8.17 private final FunctionNode functionNode; 8.18 8.19 /** A list of target labels in parent methods this split node may encounter. */ 8.20 + @Ignore 8.21 private final List<MethodEmitter.Label> externalTargets; 8.22 8.23 /** True if this split node or any of its children contain a return statement. */ 8.24 private boolean hasReturn; 8.25 8.26 /** Body of split code. */ 8.27 + @Ignore 8.28 private Node body; 8.29 8.30 /**
9.1 --- a/src/jdk/nashorn/internal/ir/SwitchNode.java Tue Jan 08 14:14:17 2013 +0100 9.2 +++ b/src/jdk/nashorn/internal/ir/SwitchNode.java Tue Jan 08 15:20:40 2013 +0100 9.3 @@ -30,7 +30,6 @@ 9.4 import java.util.List; 9.5 import jdk.nashorn.internal.codegen.MethodEmitter.Label; 9.6 import jdk.nashorn.internal.ir.annotations.Ignore; 9.7 -import jdk.nashorn.internal.ir.annotations.Reference; 9.8 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 9.9 import jdk.nashorn.internal.runtime.Source; 9.10 9.11 @@ -48,7 +47,7 @@ 9.12 private List<CaseNode> cases; 9.13 9.14 /** Switch default. */ 9.15 - @Reference @Ignore //points to one of the members in the list above, don't traverse twice 9.16 + @Ignore //points to one of the members in the list above, don't traverse twice 9.17 private CaseNode defaultCase; 9.18 9.19 /**
10.1 --- a/src/jdk/nashorn/internal/ir/ThrowNode.java Tue Jan 08 14:14:17 2013 +0100 10.2 +++ b/src/jdk/nashorn/internal/ir/ThrowNode.java Tue Jan 08 15:20:40 2013 +0100 10.3 @@ -26,7 +26,6 @@ 10.4 package jdk.nashorn.internal.ir; 10.5 10.6 import jdk.nashorn.internal.ir.annotations.Ignore; 10.7 -import jdk.nashorn.internal.ir.annotations.Reference; 10.8 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 10.9 import jdk.nashorn.internal.runtime.Source; 10.10 10.11 @@ -38,7 +37,7 @@ 10.12 private Node expression; 10.13 10.14 /** Try chain. */ 10.15 - @Reference @Ignore 10.16 + @Ignore 10.17 private final TryNode tryChain; 10.18 10.19 /**
11.1 --- a/src/jdk/nashorn/internal/ir/TryNode.java Tue Jan 08 14:14:17 2013 +0100 11.2 +++ b/src/jdk/nashorn/internal/ir/TryNode.java Tue Jan 08 15:20:40 2013 +0100 11.3 @@ -29,7 +29,7 @@ 11.4 import java.util.Collections; 11.5 import java.util.List; 11.6 import jdk.nashorn.internal.codegen.MethodEmitter.Label; 11.7 -import jdk.nashorn.internal.ir.annotations.Reference; 11.8 +import jdk.nashorn.internal.ir.annotations.Ignore; 11.9 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 11.10 import jdk.nashorn.internal.runtime.Source; 11.11 11.12 @@ -38,7 +38,7 @@ 11.13 */ 11.14 public class TryNode extends Node { 11.15 /** Try chain. */ 11.16 - @Reference 11.17 + @Ignore //don't print, will be apparent from the AST 11.18 private TryNode next; 11.19 11.20 /** Try statements. */
12.1 --- a/src/jdk/nashorn/internal/ir/debug/ASTWriter.java Tue Jan 08 14:14:17 2013 +0100 12.2 +++ b/src/jdk/nashorn/internal/ir/debug/ASTWriter.java Tue Jan 08 15:20:40 2013 +0100 12.3 @@ -71,12 +71,12 @@ 12.4 @Override 12.5 public String toString() { 12.6 final StringBuilder sb = new StringBuilder(); 12.7 - printAST(sb, "root", root, 0); 12.8 + printAST(sb, null, "root", root, 0); 12.9 return sb.toString(); 12.10 } 12.11 12.12 @SuppressWarnings("unchecked") 12.13 - private void printAST(final StringBuilder sb, final String name, final Node node, final int indent) { 12.14 + private void printAST(final StringBuilder sb, final Field field, final String name, final Node node, final int indent) { 12.15 ASTWriter.indent(sb, indent); 12.16 if (node == null) { 12.17 sb.append("[Object "); 12.18 @@ -85,59 +85,18 @@ 12.19 return; 12.20 } 12.21 12.22 + final boolean isReference = field != null && field.getAnnotation(Reference.class) != null; 12.23 + 12.24 Class<?> clazz = node.getClass(); 12.25 - String type = clazz.getName(); 12.26 + String type = clazz.getName(); 12.27 + 12.28 type = type.substring(type.lastIndexOf('.') + 1, type.length()); 12.29 - // type += "@" + Debug.id(node) + "#" + node.getSymbol(); 12.30 +// type += "@" + Debug.id(node) + "#" + node.getSymbol(); 12.31 12.32 final List<Field> children = new LinkedList<>(); 12.33 - final Deque<Class<?>> stack = new ArrayDeque<>(); 12.34 12.35 - /** 12.36 - * Here is some ugliness that can be overcome by proper ChildNode annotations 12.37 - * with proper orders. Right now we basically sort all classes up to Node 12.38 - * with super class first, as this often is the natural order, e.g. base 12.39 - * before index for an IndexNode. 12.40 - * 12.41 - * Also there are special cases as this is not true for UnaryNodes(lhs) and 12.42 - * BinaryNodes extends UnaryNode (with lhs), and TernaryNodes. 12.43 - * 12.44 - * TODO - generalize traversal with an order built on annotations and this 12.45 - * will go away. 12.46 - */ 12.47 - do { 12.48 - stack.push(clazz); 12.49 - clazz = clazz.getSuperclass(); 12.50 - } while (clazz != null); 12.51 - 12.52 - if (node instanceof TernaryNode) { 12.53 - // HACK juggle "third" 12.54 - stack.push(stack.removeLast()); 12.55 - } 12.56 - // HACK change operator order for BinaryNodes to get lhs first. 12.57 - final Iterator<Class<?>> iter = node instanceof BinaryNode ? stack.descendingIterator() : stack.iterator(); 12.58 - 12.59 - while (iter.hasNext()) { 12.60 - final Class<?> c = iter.next(); 12.61 - for (final Field f : c.getDeclaredFields()) { 12.62 - try { 12.63 - f.setAccessible(true); 12.64 - final Object child = f.get(node); 12.65 - if (child == null) { 12.66 - continue; 12.67 - } 12.68 - 12.69 - if (child instanceof Node) { 12.70 - children.add(f); 12.71 - } else if (child instanceof Collection) { 12.72 - if (!((Collection<?>)child).isEmpty()) { 12.73 - children.add(f); 12.74 - } 12.75 - } 12.76 - } catch (final IllegalArgumentException | IllegalAccessException e) { 12.77 - return; 12.78 - } 12.79 - } 12.80 + if (!isReference) { 12.81 + enqueueChildren(node, clazz, children); 12.82 } 12.83 12.84 String status = ""; 12.85 @@ -193,52 +152,98 @@ 12.86 append("]"). 12.87 append('\n'); 12.88 12.89 - for (final Field field : children) { 12.90 - 12.91 - if (field.getAnnotation(ParentNode.class) != null) { 12.92 + for (final Field child : children) { 12.93 + if (child.getAnnotation(ParentNode.class) != null) { 12.94 continue; 12.95 - } 12.96 - if (field.getAnnotation(Ignore.class) != null) { 12.97 - continue; 12.98 - } 12.99 - if (field.getAnnotation(Reference.class) != null) { 12.100 + } else if (child.getAnnotation(Ignore.class) != null) { 12.101 continue; 12.102 } 12.103 12.104 Object value; 12.105 try { 12.106 - value = field.get(node); 12.107 + value = child.get(node); 12.108 } catch (final IllegalArgumentException | IllegalAccessException e) { 12.109 Context.printStackTrace(e); 12.110 return; 12.111 } 12.112 12.113 if (value instanceof Node) { 12.114 - printAST(sb, field.getName(), (Node)value, indent + 1); 12.115 + printAST(sb, child, child.getName(), (Node)value, indent + 1); 12.116 } else if (value instanceof Collection) { 12.117 int pos = 0; 12.118 ASTWriter.indent(sb, indent + 1); 12.119 sb.append("[Collection "). 12.120 - append(field.getName()). 12.121 + append(child.getName()). 12.122 append("[0.."). 12.123 append(((Collection<Node>)value).size()). 12.124 append("]]"). 12.125 append('\n'); 12.126 12.127 - for (final Node child : (Collection<Node>)value) { 12.128 - printAST(sb, field.getName() + "[" + pos++ + "]", child, indent + 2); 12.129 + for (final Node member : (Collection<Node>)value) { 12.130 + printAST(sb, child, child.getName() + "[" + pos++ + "]", member, indent + 2); 12.131 } 12.132 } 12.133 } 12.134 } 12.135 } 12.136 12.137 + private static void enqueueChildren(final Node node, final Class<?> nodeClass, final List<Field> children) { 12.138 + final Deque<Class<?>> stack = new ArrayDeque<>(); 12.139 + 12.140 + /** 12.141 + * Here is some ugliness that can be overcome by proper ChildNode annotations 12.142 + * with proper orders. Right now we basically sort all classes up to Node 12.143 + * with super class first, as this often is the natural order, e.g. base 12.144 + * before index for an IndexNode. 12.145 + * 12.146 + * Also there are special cases as this is not true for UnaryNodes(lhs) and 12.147 + * BinaryNodes extends UnaryNode (with lhs), and TernaryNodes. 12.148 + * 12.149 + * TODO - generalize traversal with an order built on annotations and this 12.150 + * will go away. 12.151 + */ 12.152 + Class<?> clazz = nodeClass; 12.153 + do { 12.154 + stack.push(clazz); 12.155 + clazz = clazz.getSuperclass(); 12.156 + } while (clazz != null); 12.157 + 12.158 + if (node instanceof TernaryNode) { 12.159 + // HACK juggle "third" 12.160 + stack.push(stack.removeLast()); 12.161 + } 12.162 + // HACK change operator order for BinaryNodes to get lhs first. 12.163 + final Iterator<Class<?>> iter = node instanceof BinaryNode ? stack.descendingIterator() : stack.iterator(); 12.164 + 12.165 + while (iter.hasNext()) { 12.166 + final Class<?> c = iter.next(); 12.167 + for (final Field f : c.getDeclaredFields()) { 12.168 + try { 12.169 + f.setAccessible(true); 12.170 + final Object child = f.get(node); 12.171 + if (child == null) { 12.172 + continue; 12.173 + } 12.174 + 12.175 + if (child instanceof Node) { 12.176 + children.add(f); 12.177 + } else if (child instanceof Collection) { 12.178 + if (!((Collection<?>)child).isEmpty()) { 12.179 + children.add(f); 12.180 + } 12.181 + } 12.182 + } catch (final IllegalArgumentException | IllegalAccessException e) { 12.183 + return; 12.184 + } 12.185 + } 12.186 + } 12.187 + } 12.188 + 12.189 private static void indent(final StringBuilder sb, final int indent) { 12.190 for (int i = 0; i < indent; i++) { 12.191 - for (int j = 0 ; j < TABWIDTH ; j++) { 12.192 + for (int j = 0; j < TABWIDTH; j++) { 12.193 sb.append(' '); 12.194 } 12.195 } 12.196 } 12.197 - 12.198 }