private void deserializeChildFields(Node parent, NodeFieldAccessor[] nodeFields) { for (int i = nodeFields.length - 1; i >= 0; i--) { NodeFieldAccessor field = nodeFields[i]; if (field.getKind() == NodeFieldKind.CHILD) { unsafe.putObject(parent, field.getOffset(), popNode(parent, field.getType())); } } }
@SuppressWarnings({"deprecation", "unused"}) private static String findFieldName(NodeClass nodeClass, com.oracle.truffle.api.nodes.NodeFieldAccessor field) { return field.getName(); }
private int childrenCount() { int nodeCount = childFields.length; for (NodeFieldAccessor childrenField : childrenFields) { Object[] children = ((Object[]) childrenField.getObject(node)); if (children != null) { nodeCount += children.length; } } return nodeCount; }
/** @since 0.14 */ @Override public String toString() { return getDeclaringClass().getName() + "." + getName(); }
private static String getNodeFieldName(Node parent, Node node, String defaultName) { NodeFieldAccessor[] fields = parent.getNodeClass().getFields(); for (NodeFieldAccessor field : fields) { Object value = field.loadValue(parent); if (field.getKind() == NodeFieldKind.CHILD && value == node) { return field.getName(); } else if (field.getKind() == NodeFieldKind.CHILDREN) { int index = 0; for (Object arrayNode : (Object[]) value) { if (arrayNode == node) { return field.getName() + "[" + index + "]"; } index++; } } } return defaultName; }
private static boolean assertAssignable(NodeFieldAccessor field, Object newValue) { if (newValue == null) { return true; } if (field.getKind() == NodeFieldKind.CHILD) { if (field.getType().isAssignableFrom(newValue.getClass())) { return true; } else { assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); return false; } } else if (field.getKind() == NodeFieldKind.CHILDREN) { if (field.getType().getComponentType().isAssignableFrom(newValue.getClass())) { return true; } else { assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); return false; } } throw new IllegalArgumentException(); }
Field field; try { field = accessor.getDeclaringClass().getDeclaredField(accessor.getName()); } catch (NoSuchFieldException ex) { throw shouldNotReachHere(ex); if (accessor.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.PARENT || accessor.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.CHILD || accessor.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.CHILDREN) { if (accessor.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.DATA) {
/** * Finds the field in a parent node, if any, that holds a specified child node. * * @return the field (possibly an array) holding the child, {@code null} if not found. * @since 0.8 or earlier */ @SuppressWarnings("deprecation") @Deprecated public static NodeFieldAccessor findChildField(Node parent, Node child) { assert child != null; NodeClass parentNodeClass = parent.getNodeClass(); for (NodeFieldAccessor field : parentNodeClass.getFields()) { if (field.getKind() == NodeFieldAccessor.NodeFieldKind.CHILD) { if (field.getObject(parent) == child) { return field; } } else if (field.getKind() == NodeFieldAccessor.NodeFieldKind.CHILDREN) { Object arrayObject = field.getObject(parent); if (arrayObject != null) { Object[] array = (Object[]) arrayObject; for (int i = 0; i < array.length; i++) { if (array[i] == child) { return field; } } } } } return null; }
@SuppressWarnings("deprecation") private String getFieldName(Node parent, Node node) { for (com.oracle.truffle.api.nodes.NodeFieldAccessor field : NodeClass.get(parent).getFields()) { Object value = field.loadValue(parent); if (value == node) { return field.getName(); } else if (value instanceof Node[]) { int index = 0; for (Node arrayNode : (Node[]) value) { if (arrayNode == node) { return field.getName() + "[" + index + "]"; } index++; } } } return "unknownField"; }
@Override protected boolean isChildField(Object field) { return ((NodeFieldAccessor) field).getKind() == NodeFieldAccessor.NodeFieldKind.CHILD; }
private static void updateRootImpl(SpecializationNode start, Node node) { NodeFieldAccessor[] fields = NodeClass.get(start).getFields(); for (int i = fields.length - 1; i >= 0; i--) { NodeFieldAccessor f = fields[i]; if (f.getName().equals("root")) { f.putObject(start, node); break; } } if (start.next != null) { updateRootImpl(start.next, node); } }
NodeClass nodeClass = clone.getNodeClass(); nodeClass.getParentField().putObject(clone, null); Node child = (Node) childField.getObject(orig); if (child != null) { Node clonedChild = child.deepCopy(); nodeClass.getParentField().putObject(clonedChild, clone); childField.putObject(clone, clonedChild); Object[] children = (Object[]) childrenField.getObject(orig); if (children != null) { Object[] clonedChildren = (Object[]) Array.newInstance(children.getClass().getComponentType(), children.length); Node clonedChild = ((Node) children[i]).deepCopy(); clonedChildren[i] = clonedChild; nodeClass.getParentField().putObject(clonedChild, clone); childrenField.putObject(clone, clonedChildren); Object cloneable = cloneableField.getObject(clone); if (cloneable != null && cloneable == cloneableField.getObject(orig)) { cloneableField.putObject(clone, ((NodeCloneable) cloneable).clone());
private void serializeChildFields(VariableLengthIntBuffer buffer, Node nodeInstance, NodeFieldAccessor[] nodeFields) throws UnsupportedConstantPoolTypeException { for (int i = 0; i < nodeFields.length; i++) { NodeFieldAccessor field = nodeFields[i]; if (field.getKind() == NodeFieldKind.CHILD) { Object childObject = unsafe.getObject(nodeInstance, field.getOffset()); if (childObject != null && !(childObject instanceof Node)) { throw new AssertionError("Node children must be instanceof Node"); } serialize(buffer, (Node) childObject); } } }
@SuppressWarnings({"deprecation", "unused"}) private static Object findFieldValue(NodeClass nodeClass, com.oracle.truffle.api.nodes.NodeFieldAccessor field, Node node) { return field.loadValue(node); }
private static void collectInstanceFields(Class<? extends Object> clazz, List<NodeFieldAccessor> fieldsList) { if (clazz.getSuperclass() != null) { collectInstanceFields(clazz.getSuperclass(), fieldsList); } Field[] declaredFields = clazz.getDeclaredFields(); for (Field field : declaredFields) { if (Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) { continue; } NodeFieldAccessor nodeField; if (field.getDeclaringClass() == Node.class && (field.getName().equals("parent") || field.getName().equals("nodeClass"))) { continue; } else if (field.getAnnotation(Child.class) != null) { checkChildField(field); nodeField = NodeFieldAccessor.create(NodeFieldAccessor.NodeFieldKind.CHILD, field); } else if (field.getAnnotation(Children.class) != null) { checkChildrenField(field); nodeField = NodeFieldAccessor.create(NodeFieldAccessor.NodeFieldKind.CHILDREN, field); } else { nodeField = NodeFieldAccessor.create(NodeFieldAccessor.NodeFieldKind.DATA, field); } fieldsList.add(nodeField); } }
@Override protected void putFieldObject(Object field, Node receiver, Object value) { ((NodeFieldAccessor) field).putObject(receiver, value); }
@Override protected Class<?> getFieldType(Object field) { return ((NodeFieldAccessor) field).getType(); }
private static LinkedHashMap<String, Node> findNamedNodeChildren(Node node) { LinkedHashMap<String, Node> nodes = new LinkedHashMap<>(); NodeClass nodeClass = node.getNodeClass(); for (NodeFieldAccessor field : nodeClass.getFields()) { NodeFieldKind kind = field.getKind(); if (kind == NodeFieldKind.CHILD || kind == NodeFieldKind.CHILDREN) { Object value = field.loadValue(node); if (value != null) { if (kind == NodeFieldKind.CHILD) { nodes.put(field.getName(), (Node) value); } else if (kind == NodeFieldKind.CHILDREN) { Object[] children = (Object[]) value; for (int i = 0; i < children.length; i++) { if (children[i] != null) { nodes.put(field.getName() + "[" + i + "]", (Node) children[i]); } } } } } } return nodes; }