Mercurial > hg > truffle
comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @ 10755:b221e31d7b0b
Truffle: revise NodeUtil.replaceChild assertion
author | Andreas Woess <andreas.woess@jku.at> |
---|---|
date | Mon, 15 Jul 2013 15:26:39 +0200 |
parents | 99789440ce28 |
children | 7f6580db1e88 |
comparison
equal
deleted
inserted
replaced
10754:4c12d3756015 | 10755:b221e31d7b0b |
---|---|
350 } | 350 } |
351 | 351 |
352 public static void replaceChild(Node parent, Node oldChild, Node newChild) { | 352 public static void replaceChild(Node parent, Node oldChild, Node newChild) { |
353 NodeClass nodeClass = NodeClass.get(parent.getClass()); | 353 NodeClass nodeClass = NodeClass.get(parent.getClass()); |
354 | 354 |
355 long[] fieldOffsets = nodeClass.childOffsets; | 355 for (long fieldOffset : nodeClass.getChildOffsets()) { |
356 for (int i = 0; i < fieldOffsets.length; i++) { | |
357 long fieldOffset = fieldOffsets[i]; | |
358 if (unsafe.getObject(parent, fieldOffset) == oldChild) { | 356 if (unsafe.getObject(parent, fieldOffset) == oldChild) { |
359 assert assertAssignable(nodeClass, parent, oldChild, newChild); | 357 assert assertAssignable(nodeClass, fieldOffset, newChild); |
360 unsafe.putObject(parent, fieldOffset, newChild); | 358 unsafe.putObject(parent, fieldOffset, newChild); |
361 } | 359 } |
362 } | 360 } |
363 | 361 |
364 long[] childrenOffsets = nodeClass.childrenOffsets; | 362 for (long fieldOffset : nodeClass.getChildrenOffsets()) { |
365 for (int i = 0; i < childrenOffsets.length; i++) { | |
366 long fieldOffset = childrenOffsets[i]; | |
367 Object arrayObject = unsafe.getObject(parent, fieldOffset); | 363 Object arrayObject = unsafe.getObject(parent, fieldOffset); |
368 if (arrayObject != null) { | 364 if (arrayObject != null) { |
369 assert arrayObject instanceof Node[] : "Children must be instanceof Node[] "; | 365 assert arrayObject instanceof Node[] : "Children array must be instanceof Node[] "; |
370 Node[] array = (Node[]) arrayObject; | 366 Node[] array = (Node[]) arrayObject; |
371 for (int j = 0; j < array.length; j++) { | 367 for (int i = 0; i < array.length; i++) { |
372 if (array[j] == oldChild) { | 368 if (array[i] == oldChild) { |
373 assert newChild != null && array.getClass().getComponentType().isAssignableFrom(newChild.getClass()) : "Array type does not match"; | 369 assert assertAssignable(nodeClass, fieldOffset, newChild); |
374 array[j] = newChild; | 370 array[i] = newChild; |
375 return; | |
376 } | 371 } |
377 } | 372 } |
378 } | 373 } |
379 } | 374 } |
380 } | 375 } |
381 | 376 |
382 private static boolean assertAssignable(NodeClass clazz, Node parent, Object oldValue, Object newValue) { | 377 private static boolean assertAssignable(NodeClass clazz, long fieldOffset, Object newValue) { |
383 if (newValue == null) { | 378 if (newValue == null) { |
384 return true; | 379 return true; |
385 } | 380 } |
386 for (NodeField field : clazz.fields) { | 381 for (NodeField field : clazz.getFields()) { |
387 if (field.kind != NodeFieldKind.CHILD) { | 382 if (field.getOffset() == fieldOffset) { |
388 continue; | 383 if (field.getKind() == NodeFieldKind.CHILD) { |
389 } | 384 if (field.getType().isAssignableFrom(newValue.getClass())) { |
390 if (unsafe.getObject(parent, field.offset) == oldValue) { | 385 return true; |
391 if (!field.type.isAssignableFrom(newValue.getClass())) { | 386 } else { |
392 assert false : "Child class " + newValue.getClass() + " is not assignable to field " + field.type.getName() + " at " + field.name + " in "; | 387 assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); |
393 return false; | 388 return false; |
394 } else { | 389 } |
395 break; | 390 } else if (field.getKind() == NodeFieldKind.CHILDREN) { |
396 } | 391 if (field.getType().getComponentType().isAssignableFrom(newValue.getClass())) { |
397 } | 392 return true; |
398 } | 393 } else { |
399 return true; | 394 assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); |
395 return false; | |
396 } | |
397 } | |
398 } | |
399 } | |
400 throw new IllegalArgumentException(); | |
400 } | 401 } |
401 | 402 |
402 /** Returns all declared fields in the class hierarchy. */ | 403 /** Returns all declared fields in the class hierarchy. */ |
403 private static Field[] getAllFields(Class<? extends Object> clazz) { | 404 private static Field[] getAllFields(Class<? extends Object> clazz) { |
404 Field[] declaredFields = clazz.getDeclaredFields(); | 405 Field[] declaredFields = clazz.getDeclaredFields(); |