Mercurial > hg > truffle
comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @ 9537:e2965e5cd474
Fixed Truffle child iterator should only iterate children which are annotated with @Child or @Children.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Fri, 03 May 2013 14:59:46 +0200 |
parents | 0285fbb8b05d |
children | e6fe35d64b71 |
comparison
equal
deleted
inserted
replaced
9536:238431ec62a2 | 9537:e2965e5cd474 |
---|---|
27 import java.lang.reflect.*; | 27 import java.lang.reflect.*; |
28 import java.util.*; | 28 import java.util.*; |
29 | 29 |
30 import sun.misc.*; | 30 import sun.misc.*; |
31 | 31 |
32 import com.oracle.truffle.api.nodes.Node.Child; | |
33 import com.oracle.truffle.api.nodes.Node.Children; | |
34 | |
32 /** | 35 /** |
33 * Utility class that manages the special access methods for node instances. | 36 * Utility class that manages the special access methods for node instances. |
34 */ | 37 */ |
35 public class NodeUtil { | 38 public class NodeUtil { |
36 | 39 |
71 if (Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) { | 74 if (Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) { |
72 continue; | 75 continue; |
73 } | 76 } |
74 | 77 |
75 // Node fields | 78 // Node fields |
76 if (Node.class.isAssignableFrom(field.getType())) { | 79 if (Node.class.isAssignableFrom(field.getType()) && field.getName().equals("parent")) { |
77 if (!field.getName().equals("parent")) { | 80 parentOffsetTemp = unsafe.objectFieldOffset(field); |
78 nodeFieldOffsetsList.add(unsafe.objectFieldOffset(field)); | 81 parentClassTmp = field.getType(); |
79 nodeFieldClassesList.add(field.getType()); | 82 } else if (Node.class.isAssignableFrom(field.getType()) && field.getAnnotation(Child.class) != null) { |
80 } else { | 83 nodeFieldOffsetsList.add(unsafe.objectFieldOffset(field)); |
81 parentOffsetTemp = unsafe.objectFieldOffset(field); | 84 nodeFieldClassesList.add(field.getType()); |
82 parentClassTmp = field.getType(); | 85 } else if (field.getType().getComponentType() != null && Node.class.isAssignableFrom(field.getType().getComponentType()) && field.getAnnotation(Children.class) != null) { |
83 } | |
84 } else if (field.getType().getComponentType() != null && Node.class.isAssignableFrom(field.getType().getComponentType())) { | |
85 nodeArrayFieldOffsetsList.add(unsafe.objectFieldOffset(field)); | 86 nodeArrayFieldOffsetsList.add(unsafe.objectFieldOffset(field)); |
86 nodeArrayFieldClassesList.add(field.getType()); | 87 nodeArrayFieldClassesList.add(field.getType()); |
87 } else { | 88 } else { |
88 nodeDataFieldOffsetList.add(unsafe.objectFieldOffset(field)); | 89 nodeDataFieldOffsetList.add(unsafe.objectFieldOffset(field)); |
89 nodeDataFieldClassList.add(field.getType()); | 90 nodeDataFieldClassList.add(field.getType()); |
249 } | 250 } |
250 } | 251 } |
251 return (T) clone; | 252 return (T) clone; |
252 } | 253 } |
253 | 254 |
254 public static List<Object> findNodeChildren(Object node) { | 255 public static List<Node> findNodeChildren(Node node) { |
255 List<Object> nodes = new ArrayList<>(); | 256 List<Node> nodes = new ArrayList<>(); |
256 NodeClass nodeClass = NodeClass.get(node.getClass()); | 257 NodeClass nodeClass = NodeClass.get(node.getClass()); |
257 | 258 |
258 for (long fieldOffset : nodeClass.nodeFieldOffsets) { | 259 for (long fieldOffset : nodeClass.nodeFieldOffsets) { |
259 Object child = unsafe.getObject(node, fieldOffset); | 260 Object child = unsafe.getObject(node, fieldOffset); |
260 if (child != null) { | 261 if (child != null) { |
261 nodes.add(child); | 262 nodes.add((Node) child); |
262 } | 263 } |
263 } | 264 } |
264 for (long fieldOffset : nodeClass.nodeArrayFieldOffsets) { | 265 for (long fieldOffset : nodeClass.nodeArrayFieldOffsets) { |
265 Object[] children = (Object[]) unsafe.getObject(node, fieldOffset); | 266 Node[] children = (Node[]) unsafe.getObject(node, fieldOffset); |
266 if (children != null) { | 267 if (children != null) { |
267 nodes.addAll(Arrays.asList(children)); | 268 nodes.addAll(Arrays.asList(children)); |
268 } | 269 } |
269 } | 270 } |
270 | 271 |
384 return (start.getParent() != null ? findParentInterface(start.getParent(), clazz) : null); | 385 return (start.getParent() != null ? findParentInterface(start.getParent(), clazz) : null); |
385 } | 386 } |
386 } | 387 } |
387 | 388 |
388 @SuppressWarnings("unchecked") | 389 @SuppressWarnings("unchecked") |
389 public static <T> T findFirstNodeInstance(Object root, Class<T> clazz) { | 390 public static <T> T findFirstNodeInstance(Node root, Class<T> clazz) { |
390 List<Object> childNodes = findNodeChildren(root); | 391 for (Node childNode : findNodeChildren(root)) { |
391 | |
392 for (Object childNode : childNodes) { | |
393 if (clazz.isInstance(childNode)) { | 392 if (clazz.isInstance(childNode)) { |
394 return (T) childNode; | 393 return (T) childNode; |
395 } else { | 394 } else { |
396 T node = findFirstNodeInstance(childNode, clazz); | 395 T node = findFirstNodeInstance(childNode, clazz); |
397 if (node != null) { | 396 if (node != null) { |
637 return !isChildArrayObject(f) && !isChildObject(f); | 636 return !isChildArrayObject(f) && !isChildObject(f); |
638 } | 637 } |
639 | 638 |
640 @Override | 639 @Override |
641 public boolean isChildObject(Field f) { | 640 public boolean isChildObject(Field f) { |
642 return Node.class.isAssignableFrom(f.getType()); | 641 return Node.class.isAssignableFrom(f.getType()) && f.getAnnotation(Child.class) != null; |
643 } | 642 } |
644 | 643 |
645 @Override | 644 @Override |
646 public boolean isChildArrayObject(Field f) { | 645 public boolean isChildArrayObject(Field f) { |
647 return f.getType().getComponentType() != null && Node.class.isAssignableFrom(f.getType().getComponentType()); | 646 return f.getType().getComponentType() != null && Node.class.isAssignableFrom(f.getType().getComponentType()) && f.getAnnotation(Children.class) != null; |
648 } | 647 } |
649 | 648 |
650 @Override | 649 @Override |
651 public Object[] convertToArray(Field f, Object data) { | 650 public Object[] convertToArray(Field f, Object data) { |
652 return (Object[]) data; | 651 return (Object[]) data; |