Class DynamicObjectLibrary
- All Implemented Interfaces:
NodeInterface
,Cloneable
DynamicObject
access library.
This is the central interface for accessing and mutating properties and other state (flags,
dynamic type) of DynamicObject
s.
It is recommended that you use the CachedLibrary
annotation in Truffle DSL nodes. You can
also use the library either without caching or create a
manually or
automatically dispatched cached library. Cached
libraries must be adopted before use.
The cached library instances dispatch by object shape and, if applicable,
automatically by property key.
Property keys are compared using object identity (==
) first and then
Object.equals(Object)
. It is therefore recommended to use the same string/key instances
for each access of the property in order to avoid pulling in equals
. Keys must not be
null
.
Note: cached library nodes may not profile the class of the object parameter; it is therefore the caller's responsibility to do any desired profiling and ensure accurate type information.
Usage examples:
@Specialization(limit = "3") static Object read(DynamicObject receiver, Object key, @CachedLibrary("receiver") DynamicObjectLibrary objLib) { return objLib.getOrDefault(receiver, key, NULL_VALUE); }
@ExportMessage Object readMember(String name, @CachedLibrary("this") DynamicObjectLibrary objLib) throws UnknownIdentifierException { Object result = objLib.getOrDefault(this, name, null); if (result == null) { throw UnknownIdentifierException.create(name); } return result; }
- Since:
- 20.2.0
-
Nested Class Summary
Nested classes/interfaces inherited from class com.oracle.truffle.api.nodes.Node
Node.Child, Node.Children
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionabstract boolean
containsKey
(DynamicObject object, Object key) Returnstrue
if this object contains a property with the given key.double
getDoubleOrDefault
(DynamicObject object, Object key, Object defaultValue) Gets the value of an existing property or returns the provided default value if no such property exists.abstract Object
getDynamicType
(DynamicObject object) Gets the dynamic type identifier currently associated with this object.static LibraryFactory
<DynamicObjectLibrary> Returns the library factory forDynamicObjectLibrary
.int
getIntOrDefault
(DynamicObject object, Object key, Object defaultValue) Gets the value of an existing property or returns the provided default value if no such property exists.abstract Object[]
getKeyArray
(DynamicObject object) Gets a snapshot of the object's property keys, in insertion order.long
getLongOrDefault
(DynamicObject object, Object key, Object defaultValue) Gets the value of an existing property or returns the provided default value if no such property exists.abstract Object
getOrDefault
(DynamicObject object, Object key, Object defaultValue) Gets the value of an existing property or returns the provided default value if no such property exists.abstract Property
getProperty
(DynamicObject object, Object key) Gets a property descriptor for the requested property key.abstract Property[]
getPropertyArray
(DynamicObject object) Gets an array snapshot of the object's properties, in insertion order.final int
getPropertyFlagsOrDefault
(DynamicObject object, Object key, int defaultValue) Gets the property flags associated with the requested property key.abstract Shape
getShape
(DynamicObject object) Gets theshape
of the object.abstract int
getShapeFlags
(DynamicObject object) Gets the language-specific object shape flags previously set usingsetShapeFlags(DynamicObject, int)
orShape.Builder.shapeFlags(int)
.static DynamicObjectLibrary
Gets the sharedDynamicObjectLibrary
instance for uncached accesses.abstract boolean
isShared
(DynamicObject object) Checks whether this object is marked as shared.abstract void
markShared
(DynamicObject object) Marks this object as shared.abstract void
put
(DynamicObject object, Object key, Object value) Sets the value of an existing property or adds a new property if no such property exists.abstract void
putConstant
(DynamicObject object, Object key, Object value, int flags) Adds a property with a constant value or replaces an existing one.void
putDouble
(DynamicObject object, Object key, double value) Double-typed variant ofput(com.oracle.truffle.api.object.DynamicObject, java.lang.Object, java.lang.Object)
.abstract boolean
putIfPresent
(DynamicObject object, Object key, Object value) Sets the value of the property if present, otherwise returnsfalse
.void
putInt
(DynamicObject object, Object key, int value) Int-typed variant ofput(com.oracle.truffle.api.object.DynamicObject, java.lang.Object, java.lang.Object)
.void
putLong
(DynamicObject object, Object key, long value) Long-typed variant ofput(com.oracle.truffle.api.object.DynamicObject, java.lang.Object, java.lang.Object)
.abstract void
putWithFlags
(DynamicObject object, Object key, Object value, int flags) Likeput(com.oracle.truffle.api.object.DynamicObject, java.lang.Object, java.lang.Object)
, but additionally assigns flags to the property.abstract boolean
removeKey
(DynamicObject object, Object key) Removes the property with the given key from the object.abstract boolean
resetShape
(DynamicObject object, Shape otherShape) Empties and resets the object to the given root shape, which must not contain any instance properties (but may contain properties with a constant value).abstract boolean
setDynamicType
(DynamicObject object, Object type) Sets the object's dynamic type identifier.abstract boolean
setPropertyFlags
(DynamicObject object, Object key, int propertyFlags) Sets the property flags associated with the requested property.abstract boolean
setShapeFlags
(DynamicObject object, int flags) Sets language-specific object shape flags, changing the object's shape if need be.abstract boolean
updateShape
(DynamicObject object) Ensures the object's shape is up-to-date.Methods inherited from class com.oracle.truffle.api.nodes.Node
accept, adoptChildren, atomic, atomic, copy, deepCopy, getChildren, getCost, getDebugProperties, getDescription, getEncapsulatingSourceSection, getLock, getParent, getRootNode, getSourceSection, insert, insert, isAdoptable, isSafelyReplaceableBy, notifyInserted, onReplace, replace, replace, reportPolymorphicSpecialize, toString
-
Constructor Details
-
DynamicObjectLibrary
protected DynamicObjectLibrary()- Since:
- 20.2.0
-
-
Method Details
-
getFactory
Returns the library factory forDynamicObjectLibrary
.- Since:
- 20.2.0
-
getUncached
Gets the sharedDynamicObjectLibrary
instance for uncached accesses. Equivalent toDynamicObjectLibrary.getFactory().getUncached()
.- Returns:
- an uncached automatically dispatched version of the library
- Since:
- 20.2.0
-
getShape
Gets theshape
of the object. Returns the cached shape if the library is a cached library instance.- Returns:
- the object's current
Shape
- Since:
- 20.2.0
- See Also:
-
getOrDefault
Gets the value of an existing property or returns the provided default value if no such property exists.Usage example:
@Specialization(limit = "3") static Object read(DynamicObject receiver, Object key, @CachedLibrary("receiver") DynamicObjectLibrary objLib) { return objLib.getOrDefault(receiver, key, NULL_VALUE); }
- Parameters:
key
- the property keydefaultValue
- value to be returned if the property does not exist- Returns:
- the property's value if it exists, else
defaultValue
. - Since:
- 20.2.0
-
getIntOrDefault
public int getIntOrDefault(DynamicObject object, Object key, Object defaultValue) throws UnexpectedResultException Gets the value of an existing property or returns the provided default value if no such property exists.- Parameters:
key
- the property keydefaultValue
- the value to be returned if the property does not exist- Returns:
- the property's value if it exists, else
defaultValue
. - Throws:
UnexpectedResultException
- if the (default) value is not anint
- Since:
- 20.2.0
- See Also:
-
getDoubleOrDefault
public double getDoubleOrDefault(DynamicObject object, Object key, Object defaultValue) throws UnexpectedResultException Gets the value of an existing property or returns the provided default value if no such property exists.- Parameters:
key
- the property keydefaultValue
- the value to be returned if the property does not exist- Returns:
- the property's value if it exists, else
defaultValue
. - Throws:
UnexpectedResultException
- if the (default) value is not adouble
- Since:
- 20.2.0
- See Also:
-
getLongOrDefault
public long getLongOrDefault(DynamicObject object, Object key, Object defaultValue) throws UnexpectedResultException Gets the value of an existing property or returns the provided default value if no such property exists.- Parameters:
key
- the property keydefaultValue
- the value to be returned if the property does not exist- Returns:
- the property's value if it exists, else
defaultValue
. - Throws:
UnexpectedResultException
- if the (default) value is not along
- Since:
- 20.2.0
- See Also:
-
put
Sets the value of an existing property or adds a new property if no such property exists. A newly added property will have flags 0; flags of existing properties will not be changed. UseputWithFlags(com.oracle.truffle.api.object.DynamicObject, java.lang.Object, java.lang.Object, int)
to set property flags as well.Usage example:
@ExportMessage Object writeMember(String member, Object value, @CachedLibrary("this") DynamicObjectLibrary objLib) { objLib.put(this, member, value); }
- Parameters:
key
- the property keyvalue
- the value to be set- Since:
- 20.2.0
- See Also:
-
putInt
Int-typed variant ofput(com.oracle.truffle.api.object.DynamicObject, java.lang.Object, java.lang.Object)
.- Since:
- 20.2.0
- See Also:
-
putDouble
Double-typed variant ofput(com.oracle.truffle.api.object.DynamicObject, java.lang.Object, java.lang.Object)
.- Since:
- 20.2.0
- See Also:
-
putLong
Long-typed variant ofput(com.oracle.truffle.api.object.DynamicObject, java.lang.Object, java.lang.Object)
.- Since:
- 20.2.0
- See Also:
-
putIfPresent
Sets the value of the property if present, otherwise returnsfalse
.- Parameters:
key
- property identifiervalue
- value to be set- Returns:
true
if the property was present and the value set, otherwisefalse
- Since:
- 20.2.0
- See Also:
-
putWithFlags
Likeput(com.oracle.truffle.api.object.DynamicObject, java.lang.Object, java.lang.Object)
, but additionally assigns flags to the property. If the property already exists, its flags will be updated before the value is set.- Parameters:
key
- property identifiervalue
- value to be setflags
- flags to be set- Since:
- 20.2.0
- See Also:
-
putConstant
Adds a property with a constant value or replaces an existing one. If the property already exists, its flags will be updated. The constant value is stored in the shape rather than the object instance and a new shape will be allocated if it does not already exist. A typical use case for this method is setting the initial default value of a declared, but yet uninitialized, property. This defers storage allocation and type speculation until the first actual value is set.Warning: this method will lead to a shape transition every time a new value is set and should be used sparingly (with at most one constant value per property) since it could cause an excessive amount of shapes to be created.
Note: the value will be strongly referenced from the shape and should be a value type or light-weight object without any references to guest language objects in order to prevent potential memory leaks.
Usage example:
// declare property objLib.putConstant(receiver, key, NULL_VALUE, 0); // initialize property objLib.put(receiver, key, value);
- Parameters:
key
- property identifiervalue
- the constant value to be setflags
- property flags or 0- Since:
- 20.2.0
- See Also:
-
removeKey
Removes the property with the given key from the object.- Parameters:
key
- the property key- Returns:
true
if the property was removed orfalse
if property was not found- Since:
- 20.2.0
-
setDynamicType
Sets the object's dynamic type identifier. What this type represents is completely up to the language. For example, it could be a guest-language class. The type object is strongly referenced from the shape. It is important that this be a singleton or light-weight object without any references to guest language objects in order to keep the memory footprint low and prevent potential memory leaks. Type objects are always compared by object identity, neverequals
.- Parameters:
type
- a non-null type identifier defined by the guest language.- Returns:
true
if the type (and the object's shape) changed- Since:
- 20.2.0
- See Also:
-
getDynamicType
Gets the dynamic type identifier currently associated with this object. What this type represents is completely up to the language. For example, it could be a guest-language class.- Returns:
- the object type
- Since:
- 20.2.0
- See Also:
-
containsKey
Returnstrue
if this object contains a property with the given key.Usage example:
@ExportMessage boolean isMemberReadable(String name, @CachedLibrary("this") DynamicObjectLibrary objLib) { return objLib.containsKey(this, name); }
- Parameters:
key
- the property key- Returns:
true
if the object contains a property with this key, elsefalse
- Since:
- 20.2.0
-
getShapeFlags
Gets the language-specific object shape flags previously set usingsetShapeFlags(DynamicObject, int)
orShape.Builder.shapeFlags(int)
. If no shape flags were explicitly set, the default of 0 is returned. These flags may be used to tag objects that possess characteristics that need to be queried efficiently on fast and slow paths. For example, they can be used to mark objects as frozen.Usage example:
@ExportMessage Object writeMember(String member, Object value, @CachedLibrary("this") DynamicObjectLibrary objLib) throws UnsupportedMessageException { if ((objLib.getShapeFlags(receiver) & FROZEN) != 0) { throw UnsupportedMessageException.create(); } objLib.put(this, member, value); }
- Returns:
- shape flags
- Since:
- 20.2.0
- See Also:
-
setShapeFlags
Sets language-specific object shape flags, changing the object's shape if need be. These flags may be used to tag objects that possess characteristics that need to be queried efficiently on fast and slow paths. For example, they can be used to mark objects as frozen. Only the lowest 8 bits (i.e. values in the range 0 to 255) are allowed, the remaining bits are currently reserved.Usage example:
@Specialization(limit = "3") static void preventExtensions(DynamicObject receiver, @CachedLibrary("receiver") DynamicObjectLibrary objLib) { objLib.setShapeFlags(receiver, objLib.getShapeFlags(receiver) | FROZEN); }
- Parameters:
flags
- the flags to set; must be in the range from 0 to 255 (inclusive).- Returns:
true
if the object's shape changed,false
if no change was made.- Throws:
IllegalArgumentException
- if the flags are not in the allowed range.- Since:
- 20.2.0
- See Also:
-
getProperty
Gets a property descriptor for the requested property key. Returnsnull
if the object contains no such property.- Returns:
Property
if the property exists, elsenull
- Since:
- 20.2.0
-
getPropertyFlagsOrDefault
Gets the property flags associated with the requested property key. Returns thedefaultValue
if the object contains no such property. If the property exists but no flags were explicitly set, returns the default of 0.Convenience method equivalent to:
Property property = getProperty(object, key); return property != null ? property.getFlags() : defaultValue;
- Parameters:
key
- the property keydefaultValue
- value to return if no such property exists- Returns:
- the property flags if the property exists, else
defaultValue
- Since:
- 20.2.0
- See Also:
-
setPropertyFlags
Sets the property flags associated with the requested property.- Parameters:
key
- the property key- Returns:
true
if the property was found and its flags were changed, elsefalse
- Since:
- 20.2.0
-
updateShape
Ensures the object's shape is up-to-date. If the object's shape has been marked as invalid, this method will attempt to bring the object into a valid shape again. If the object's shape is already valid, this method will have no effect. This method does not need to be called normally; all the messages in this library will work on invalid shapes as well, but it can be useful in some cases to avoid such shapes being cached which can cause unnecessary cache polymorphism and invalidations.- Returns:
true
if the object's shape was changed, otherwisefalse
.- Since:
- 20.2.0
-
resetShape
Empties and resets the object to the given root shape, which must not contain any instance properties (but may contain properties with a constant value).- Parameters:
otherShape
- the desired shape- Returns:
true
if the object's shape was changed- Throws:
IllegalArgumentException
- if the shape contains instance properties- Since:
- 20.2.0
-
getKeyArray
Gets a snapshot of the object's property keys, in insertion order. The returned array may have been cached and must not be mutated. Properties with aHiddenKey
are not included.Usage example:
The example below shows how the returned keys array could be translated to an interop array for use with InteropLibrary.@ExportMessage Object getMembers( @CachedLibrary("this") DynamicObjectLibrary objLib) { return new Keys(objLib.getKeyArray(this)); } @ExportLibrary(InteropLibrary.class) static final class Keys implements TruffleObject { @CompilationFinal(dimensions = 1) final Object[] keys; Keys(Object[] keys) { this.keys = keys; } @ExportMessage boolean hasArrayElements() { return true; } @ExportMessage Object readArrayElement(long index) throws InvalidArrayIndexException { if (!isArrayElementReadable(index)) { throw InvalidArrayIndexException.create(index); } return keys[(int) index]; } @ExportMessage long getArraySize() { return keys.length; } @ExportMessage boolean isArrayElementReadable(long index) { return index >= 0 && index < keys.length; } }
- Returns:
- a read-only array of the object's property keys.
- Since:
- 20.2.0
-
getPropertyArray
Gets an array snapshot of the object's properties, in insertion order. The returned array may have been cached and must not be mutated. Properties with aHiddenKey
are not included. Similar togetKeyArray(com.oracle.truffle.api.object.DynamicObject)
but allows the properties' flags to be queried simultaneously which may be relevant for quick filtering.- Returns:
- a read-only array of the object's properties.
- Since:
- 20.2.0
- See Also:
-