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;