Class DynamicObject.GetPropertyFlagsNode

java.lang.Object
com.oracle.truffle.api.nodes.Node
com.oracle.truffle.api.object.DynamicObject.GetPropertyFlagsNode
All Implemented Interfaces:
NodeInterface, Cloneable
Enclosing class:
DynamicObject

public abstract static class DynamicObject.GetPropertyFlagsNode extends Node
Gets the property flags associated with the requested property key.
Since:
25.1
See Also:
  • Method Details

    • execute

      public abstract int execute(DynamicObject receiver, Object key, int defaultValue)
      Gets the property flags associated with the requested property key. Returns the defaultValue 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:

      abstract static class GetPropertyEquivalentNode extends Node {
          abstract void execute(DynamicObject receiver, Object key);
      
          @Specialization
          int doGeneric(MyDynamicObjectSubclass receiver, Symbol key, int defaultValue,
                          @Cached DynamicObject.GetPropertyNode getPropertyNode) {
              Property property = getPropertyNode.execute(receiver, key);
              return property != null ? property.getFlags() : defaultValue;
          }
      }
      

      Usage example:

      Implementing read-only property check in writeMember:

      static final int READ_ONLY = 1;
      static final int MISSING = -1;
      static final int FROZEN = 1;
      
      @ExportMessage
      void writeMember(String member, Object value,
                      @Cached @Shared DynamicObject.GetShapeFlagsNode getShapeFlagsNode,
                      @Cached @Shared DynamicObject.GetPropertyFlagsNode getPropertyFlagsNode,
                      @Cached DynamicObject.PutNode putNode) throws UnknownIdentifierException, UnsupportedMessageException {
          if ((getShapeFlagsNode.execute(this) & FROZEN) == FROZEN) {
              throw UnsupportedMessageException.create();
          }
          int flags = getPropertyFlagsNode.execute(this, member, MISSING);
          if (flags == MISSING) {
              throw UnknownIdentifierException.create(member);
          } else if ((flags & READ_ONLY) == READ_ONLY) {
              throw UnsupportedMessageException.create();
          }
          putNode.execute(this, member, value);
      }
      
      @ExportMessage
      boolean isMemberModifiable(String member,
                      @Cached @Shared DynamicObject.GetShapeFlagsNode getShapeFlagsNode,
                      @Cached @Shared DynamicObject.GetPropertyFlagsNode getPropertyFlagsNode) {
          if ((getShapeFlagsNode.execute(this) & FROZEN) == FROZEN) {
              return false;
          }
          int flags = getPropertyFlagsNode.execute(this, member, MISSING);
          return flags != MISSING && (flags & READ_ONLY) == 0;
      }
      
      @ExportMessage
      boolean isMemberInsertable(String member,
                      @Cached @Shared DynamicObject.GetShapeFlagsNode getShapeFlagsNode,
                      @Cached @Shared DynamicObject.GetPropertyFlagsNode getPropertyFlagsNode) {
          if ((getShapeFlagsNode.execute(this) & FROZEN) == FROZEN) {
              return false;
          }
          return getPropertyFlagsNode.execute(this, member, MISSING) == MISSING;
      }
      
      Member name equality check omitted for brevity.
      Parameters:
      key - the property key, compared by identity (==), not equality (equals). See DynamicObject for more information.
      defaultValue - value to return if no such property exists
      Returns:
      the property flags if the property exists, else defaultValue
      See Also:
    • create

      public static DynamicObject.GetPropertyFlagsNode create()
      Since:
      25.1
    • getUncached

      public static DynamicObject.GetPropertyFlagsNode getUncached()
      Since:
      25.1