protected Location getLocation(DynamicObject object, Object value) { object.updateShape(); final Shape oldShape = object.getShape(); final Property property = oldShape.getProperty(name); if (property != null && property.getLocation().canSet(object, value)) { return property.getLocation(); } else { return null; } }
@TruffleBoundary @Specialization public void writeUncached(DynamicObject object, Object value) { object.updateShape(); final Shape shape = object.getShape(); final Property property = shape.getProperty(name); if (property == null) { object.define(name, value, 0); } else { property.setGeneric(object, value, shape); } }
@Override public final void set(DynamicObject store, Object value, Shape oldShape, Shape newShape) throws IncompatibleLocationException { assert store.getShape() == oldShape : "wrong shape"; assert newShape.isValid(); assert getLocation() != null; getLocation().set(store, value, oldShape, newShape); }
protected static List<Property> getObjectProperties(Shape shape) { final List<Property> objectProperties = new ArrayList<>(); // User properties only, ShareInternalFieldsNode do the rest for (Property property : shape.getProperties()) { if (property.getLocation().canStore(SOME_OBJECT)) { objectProperties.add(property); } } return objectProperties; }
private void setWithShapeSlowCase( DynamicObject store, Object value, Shape currentShape, Shape nextShape) { Shape oldShape = currentShape; if (store.updateShape()) { oldShape = store.getShape(); } LayoutStrategy strategy = ((LayoutImpl) currentShape.getLayout()).getStrategy(); LayoutStrategy.ShapeAndProperty newShapeAndProperty = strategy.generalizeProperty(this, value, (ShapeImpl) oldShape, (ShapeImpl) nextShape); if (store.updateShape()) { oldShape = store.getShape(); } Shape newNextShape = newShapeAndProperty.getShape(); Property newProperty = newShapeAndProperty.getProperty(); assert newNextShape.isValid() && oldShape.isValid(); newProperty.setSafe(store, value, oldShape, newNextShape); }
@Override public final void setGeneric(DynamicObject store, Object value, Shape oldShape, Shape newShape) { assert store.getShape() == oldShape : "wrong old shape"; assert newShape.isValid(); assert getLocation() != null; try { getLocation().set(store, value, oldShape, newShape); } catch (IncompatibleLocationException ex) { setWithShapeSlowCase(store, value, oldShape, newShape); } }
@Override public final void setSafe(DynamicObject store, Object value, Shape oldShape, Shape newShape) { assert store.getShape() == oldShape : "wrong old shape"; assert newShape.isValid(); assert getLocation() != null; try { getLocation().set(store, value, oldShape, newShape); } catch (IncompatibleLocationException ex) { throw new IllegalStateException(); } }
protected Shape transitionWithNewField(Shape oldShape, Object value) { // This duplicates quite a bit of DynamicObject.define(), but should be fixed in Truffle soon. final Property oldProperty = oldShape.getProperty(name); if (oldProperty != null) { if (oldProperty.getFlags() == 0 && oldProperty.getLocation().canSet(null, value)) { return oldShape; // already the right shape } else { DynamicObject copy = oldShape.getLayout().newInstance(oldShape); copy.define(name, value, 0); return copy.getShape(); } } else { final Location location = oldShape .allocator() .locationForValue( value, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)); final Property newProperty = Property.create(name, location, 0); return oldShape.addProperty(newProperty); } }
private void setSlowCase(DynamicObject store, Object value) { Shape oldShape = store.getShape(); Shape newShape = oldShape.defineProperty(getKey(), value, getFlags()); if (store.updateShape()) { oldShape = store.getShape(); } assert newShape.isValid() && oldShape.isValid(); Property newProperty = newShape.getProperty(getKey()); newProperty.setSafe(store, value, oldShape, newShape); }
protected static Shape ensureSharedClasses(Shape shape) { final ObjectType objectType = shape.getObjectType(); SharedObjects.writeBarrier(Layouts.BASIC_OBJECT.getLogicalClass(objectType)); SharedObjects.writeBarrier(Layouts.BASIC_OBJECT.getMetaClass(objectType)); return shape; }
protected static Shape createSharedShape(DynamicObject object) { object.updateShape(); final Shape oldShape = object.getShape(); return oldShape.makeSharedShape(); }
public static boolean isBasicObjectShape(Shape shape) { return shape.getObjectType().getClass().getName().endsWith(".BasicObjectType"); // FIXME }
public static boolean isQueueShape(Shape shape) { return Layouts.QUEUE.isQueue(shape.getObjectType()); }
public static boolean isArrayShape(Shape shape) { return Layouts.ARRAY.isArray(shape.getObjectType()); }
/** * Allocate an empty object. All new objects initially have no properties. Properties are added * when they are first stored, i.e., the store triggers a shape change of the object. */ public DynamicObject createObject() { return emptyShape.newInstance(); }
protected Location getNewLocation(Shape newShape) { return newShape.getProperty(name).getLocation(); }