src/jdk/nashorn/internal/runtime/ScriptObject.java

Print this page




 103     public static final int IS_ARRAY       = 0b0000_0010;
 104 
 105     /** Per ScriptObject flag - is this an arguments object? */
 106     public static final int IS_ARGUMENTS   = 0b0000_0100;
 107 
 108     /** Is this a prototype PropertyMap? */
 109     public static final int IS_PROTOTYPE   = 0b0000_1000;
 110 
 111     /** Is length property not-writable? */
 112     public static final int IS_LENGTH_NOT_WRITABLE = 0b0001_0000;
 113 
 114     /** Spill growth rate - by how many elements does {@link ScriptObject#spill} when full */
 115     public static final int SPILL_RATE = 8;
 116 
 117     /** Map to property information and accessor functions. Ordered by insertion. */
 118     private PropertyMap map;
 119 
 120     /** objects proto. */
 121     private ScriptObject proto;
 122 
 123     /** Context of the object, lazily cached. */
 124     private Context context;
 125 
 126     /** Object flags. */
 127     private int flags;
 128 
 129     /** Area for properties added to object after instantiation, see {@link AccessorProperty} */
 130     public Object[] spill;
 131 
 132     /** Indexed array data. */
 133     private ArrayData arrayData;
 134 
 135     static final MethodHandle GETPROTO           = findOwnMH("getProto", ScriptObject.class);
 136     static final MethodHandle SETPROTOCHECK      = findOwnMH("setProtoCheck", void.class, Object.class);
 137 
 138     static final MethodHandle SETFIELD           = findOwnMH("setField",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
 139     static final MethodHandle SETSPILL           = findOwnMH("setSpill",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
 140     static final MethodHandle SETSPILLWITHNEW    = findOwnMH("setSpillWithNew",  void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
 141     static final MethodHandle SETSPILLWITHGROW   = findOwnMH("setSpillWithGrow", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, int.class, Object.class, Object.class);
 142 
 143     private static final MethodHandle TRUNCATINGFILTER   = findOwnMH("truncatingFilter", Object[].class, int.class, Object[].class);
 144     private static final MethodHandle KNOWNFUNCPROPGUARD = findOwnMH("knownFunctionPropertyGuard", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, Object.class, ScriptFunction.class);
 145 


1026      *
1027      * @return the argument at the given position, or undefined if not present
1028      */
1029     public Object getArgument(final int key) {
1030         return get(key);
1031     }
1032 
1033     /**
1034      * Overridden by {@link jdk.nashorn.internal.objects.NativeArguments} class (internal use.)
1035      * Used for argument access in a vararg function using parameter name.
1036      * Returns the argument at a given key (index)
1037      *
1038      * @param key   argument index
1039      * @param value the value to write at the given index
1040      */
1041     public void setArgument(final int key, final Object value) {
1042         set(key, value, false);
1043     }
1044 
1045     /**
1046      * Return true if the script object context is strict
1047      * @return true if strict context
1048      */
1049     public final boolean isStrictContext() {
1050         return getContext()._strict;
1051     }
1052 
1053     /**
1054      * Checks if this object belongs to the given context
1055      * @param ctx context to check against
1056      * @return true if this object belongs to the given context
1057      */
1058     public final boolean isOfContext(final Context ctx) {
1059         return context == ctx;
1060     }
1061 
1062     /**
1063      * Return the current context from the object's map.
1064      * @return Current context.
1065      */
1066     protected final Context getContext() {
1067         if (context == null) {
1068             context = Context.fromClass(getClass());
1069         }
1070         return context;
1071     }
1072 
1073     /**
1074      * Set the current context.
1075      * @param ctx context instance to set
1076      */
1077     protected final void setContext(final Context ctx) {
1078         ctx.getClass();
1079         this.context = ctx;
1080     }
1081 
1082     /**
1083      * Return the map of an object.
1084      * @return PropertyMap object.
1085      */
1086     public final PropertyMap getMap() {
1087         return map;
1088     }
1089 
1090     /**
1091      * Set the initial map.
1092      * @param map Initial map.
1093      */
1094     public final void setMap(final PropertyMap map) {
1095         this.map = map;
1096     }
1097 
1098     /**
1099      * Conditionally set the new map if the old map is the same.


1465      * Flag this ScriptObject as scope
1466      */
1467     public final void setIsScope() {
1468         if (Context.DEBUG) {
1469             scopeCount++;
1470         }
1471         flags |= IS_SCOPE;
1472     }
1473 
1474     /**
1475      * Check whether this ScriptObject is scope
1476      * @return true if scope
1477      */
1478     public final boolean isScope() {
1479         return (flags & IS_SCOPE) != 0;
1480     }
1481 
1482     /**
1483      * Clears the properties from a ScriptObject
1484      * (java.util.Map-like method to help ScriptObjectMirror implementation)


1485      */
1486     public void clear() {
1487         final boolean strict = isStrictContext();
1488         final Iterator<String> iter = propertyIterator();
1489         while (iter.hasNext()) {
1490             delete(iter.next(), strict);
1491         }
1492     }
1493 
1494     /**
1495      * Checks if a property with a given key is present in a ScriptObject
1496      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1497      *
1498      * @param key the key to check for
1499      * @return true if a property with the given key exists, false otherwise
1500      */
1501     public boolean containsKey(final Object key) {
1502         return has(key);
1503     }
1504 
1505     /**
1506      * Checks if a property with a given value is present in a ScriptObject
1507      * (java.util.Map-like method to help ScriptObjectMirror implementation)


1551      * in this ScriptObject
1552      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1553      *
1554      * @return keySet of this ScriptObject
1555      */
1556     public Set<Object> keySet() {
1557         final Iterator<String> iter = propertyIterator();
1558         final Set<Object> keySet = new HashSet<>();
1559         while (iter.hasNext()) {
1560             keySet.add(iter.next());
1561         }
1562         return Collections.unmodifiableSet(keySet);
1563     }
1564 
1565     /**
1566      * Put a property in the ScriptObject
1567      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1568      *
1569      * @param key property key
1570      * @param value property value

1571      * @return oldValue if property with same key existed already
1572      */
1573     public Object put(final Object key, final Object value) {
1574         final Object oldValue = get(key);
1575         set(key, value, isStrictContext());
1576         return oldValue;
1577     }
1578 
1579     /**
1580      * Put several properties in the ScriptObject given a mapping
1581      * of their keys to their values
1582      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1583      *
1584      * @param otherMap a {@literal <key,value>} map of properties to add

1585      */
1586     public void putAll(final Map<?, ?> otherMap) {
1587         final boolean strict = isStrictContext();
1588         for (final Map.Entry<?, ?> entry : otherMap.entrySet()) {
1589             set(entry.getKey(), entry.getValue(), strict);
1590         }
1591     }
1592 
1593     /**
1594      * Remove a property from the ScriptObject.
1595      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1596      *
1597      * @param key the key of the property

1598      * @return the oldValue of the removed property
1599      */
1600     public Object remove(final Object key) {
1601         final Object oldValue = get(key);
1602         delete(key, isStrictContext());
1603         return oldValue;
1604     }
1605 
1606     /**
1607      * Delete a property from the ScriptObject.
1608      * (to help ScriptObjectMirror implementation)
1609      *
1610      * @param key the key of the property
1611      * @return if the delete was successful or not
1612      */
1613     public boolean delete(final Object key) {
1614         return delete(key, isStrictContext());
1615     }
1616 
1617     /**
1618      * Return the size of the ScriptObject - i.e. the number of properties
1619      * it contains
1620      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1621      *
1622      * @return number of properties in ScriptObject
1623      */
1624     public int size() {
1625         int n = 0;
1626         for (final Iterator<String> iter = propertyIterator(); iter.hasNext(); iter.next()) {
1627             n++;
1628         }
1629         return n;
1630     }
1631 
1632     /**
1633      * Return the values of the properties in the ScriptObject
1634      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1635      *
1636      * @return collection of values for the properties in this ScriptObject
1637      */


2316 
2317             for (int i = length; i < n; i++) {
2318                 newArray[i] = fill;
2319             }
2320         }
2321 
2322         return newArray;
2323     }
2324 
2325     /**
2326       * Numeric length setter for length property
2327       *
2328       * @param newLength new length to set
2329       */
2330     public final void setLength(final long newLength) {
2331        final long arrayLength = getArray().length();
2332        if (newLength == arrayLength) {
2333            return;
2334        }
2335 
2336        final boolean isStrict = isStrictContext();
2337 
2338        if (newLength > arrayLength) {
2339            setArray(getArray().ensure(newLength - 1));
2340             if (getArray().canDelete(arrayLength, (newLength - 1), isStrict)) {
2341                setArray(getArray().delete(arrayLength, (newLength - 1)));
2342            }
2343            return;
2344        }
2345 
2346        if (newLength < arrayLength) {
2347            setArray(getArray().shrink(newLength));
2348            getArray().setLength(newLength);
2349        }
2350     }
2351 
2352     private int getInt(final int index, final String key) {
2353         if (ArrayIndex.isValidArrayIndex(index)) {
2354              for (ScriptObject object = this; ; ) {
2355                 final FindProperty find = object.findProperty(key, false, false, this);
2356 
2357                 if (find != null) {
2358                     return getIntValue(find);
2359                 }
2360 




 103     public static final int IS_ARRAY       = 0b0000_0010;
 104 
 105     /** Per ScriptObject flag - is this an arguments object? */
 106     public static final int IS_ARGUMENTS   = 0b0000_0100;
 107 
 108     /** Is this a prototype PropertyMap? */
 109     public static final int IS_PROTOTYPE   = 0b0000_1000;
 110 
 111     /** Is length property not-writable? */
 112     public static final int IS_LENGTH_NOT_WRITABLE = 0b0001_0000;
 113 
 114     /** Spill growth rate - by how many elements does {@link ScriptObject#spill} when full */
 115     public static final int SPILL_RATE = 8;
 116 
 117     /** Map to property information and accessor functions. Ordered by insertion. */
 118     private PropertyMap map;
 119 
 120     /** objects proto. */
 121     private ScriptObject proto;
 122 



 123     /** Object flags. */
 124     private int flags;
 125 
 126     /** Area for properties added to object after instantiation, see {@link AccessorProperty} */
 127     public Object[] spill;
 128 
 129     /** Indexed array data. */
 130     private ArrayData arrayData;
 131 
 132     static final MethodHandle GETPROTO           = findOwnMH("getProto", ScriptObject.class);
 133     static final MethodHandle SETPROTOCHECK      = findOwnMH("setProtoCheck", void.class, Object.class);
 134 
 135     static final MethodHandle SETFIELD           = findOwnMH("setField",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
 136     static final MethodHandle SETSPILL           = findOwnMH("setSpill",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
 137     static final MethodHandle SETSPILLWITHNEW    = findOwnMH("setSpillWithNew",  void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
 138     static final MethodHandle SETSPILLWITHGROW   = findOwnMH("setSpillWithGrow", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, int.class, Object.class, Object.class);
 139 
 140     private static final MethodHandle TRUNCATINGFILTER   = findOwnMH("truncatingFilter", Object[].class, int.class, Object[].class);
 141     private static final MethodHandle KNOWNFUNCPROPGUARD = findOwnMH("knownFunctionPropertyGuard", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, Object.class, ScriptFunction.class);
 142 


1023      *
1024      * @return the argument at the given position, or undefined if not present
1025      */
1026     public Object getArgument(final int key) {
1027         return get(key);
1028     }
1029 
1030     /**
1031      * Overridden by {@link jdk.nashorn.internal.objects.NativeArguments} class (internal use.)
1032      * Used for argument access in a vararg function using parameter name.
1033      * Returns the argument at a given key (index)
1034      *
1035      * @param key   argument index
1036      * @param value the value to write at the given index
1037      */
1038     public void setArgument(final int key, final Object value) {
1039         set(key, value, false);
1040     }
1041 
1042     /**

















1043      * Return the current context from the object's map.
1044      * @return Current context.
1045      */
1046     protected Context getContext() {
1047         return Context.fromClass(getClass());












1048     }
1049 
1050     /**
1051      * Return the map of an object.
1052      * @return PropertyMap object.
1053      */
1054     public final PropertyMap getMap() {
1055         return map;
1056     }
1057 
1058     /**
1059      * Set the initial map.
1060      * @param map Initial map.
1061      */
1062     public final void setMap(final PropertyMap map) {
1063         this.map = map;
1064     }
1065 
1066     /**
1067      * Conditionally set the new map if the old map is the same.


1433      * Flag this ScriptObject as scope
1434      */
1435     public final void setIsScope() {
1436         if (Context.DEBUG) {
1437             scopeCount++;
1438         }
1439         flags |= IS_SCOPE;
1440     }
1441 
1442     /**
1443      * Check whether this ScriptObject is scope
1444      * @return true if scope
1445      */
1446     public final boolean isScope() {
1447         return (flags & IS_SCOPE) != 0;
1448     }
1449 
1450     /**
1451      * Clears the properties from a ScriptObject
1452      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1453      *
1454      * @param strict strict mode or not
1455      */
1456     public void clear(final boolean strict) {

1457         final Iterator<String> iter = propertyIterator();
1458         while (iter.hasNext()) {
1459             delete(iter.next(), strict);
1460         }
1461     }
1462 
1463     /**
1464      * Checks if a property with a given key is present in a ScriptObject
1465      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1466      *
1467      * @param key the key to check for
1468      * @return true if a property with the given key exists, false otherwise
1469      */
1470     public boolean containsKey(final Object key) {
1471         return has(key);
1472     }
1473 
1474     /**
1475      * Checks if a property with a given value is present in a ScriptObject
1476      * (java.util.Map-like method to help ScriptObjectMirror implementation)


1520      * in this ScriptObject
1521      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1522      *
1523      * @return keySet of this ScriptObject
1524      */
1525     public Set<Object> keySet() {
1526         final Iterator<String> iter = propertyIterator();
1527         final Set<Object> keySet = new HashSet<>();
1528         while (iter.hasNext()) {
1529             keySet.add(iter.next());
1530         }
1531         return Collections.unmodifiableSet(keySet);
1532     }
1533 
1534     /**
1535      * Put a property in the ScriptObject
1536      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1537      *
1538      * @param key property key
1539      * @param value property value
1540      * @param strict strict mode or not
1541      * @return oldValue if property with same key existed already
1542      */
1543     public Object put(final Object key, final Object value, final boolean strict) {
1544         final Object oldValue = get(key);
1545         set(key, value, strict);
1546         return oldValue;
1547     }
1548 
1549     /**
1550      * Put several properties in the ScriptObject given a mapping
1551      * of their keys to their values
1552      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1553      *
1554      * @param otherMap a {@literal <key,value>} map of properties to add
1555      * @param strict strict mode or not
1556      */
1557     public void putAll(final Map<?, ?> otherMap, final boolean strict) {

1558         for (final Map.Entry<?, ?> entry : otherMap.entrySet()) {
1559             set(entry.getKey(), entry.getValue(), strict);
1560         }
1561     }
1562 
1563     /**
1564      * Remove a property from the ScriptObject.
1565      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1566      *
1567      * @param key the key of the property
1568      * @param strict strict mode or not
1569      * @return the oldValue of the removed property
1570      */
1571     public Object remove(final Object key, final boolean strict) {
1572         final Object oldValue = get(key);
1573         delete(key, strict);
1574         return oldValue;
1575     }
1576 
1577     /**











1578      * Return the size of the ScriptObject - i.e. the number of properties
1579      * it contains
1580      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1581      *
1582      * @return number of properties in ScriptObject
1583      */
1584     public int size() {
1585         int n = 0;
1586         for (final Iterator<String> iter = propertyIterator(); iter.hasNext(); iter.next()) {
1587             n++;
1588         }
1589         return n;
1590     }
1591 
1592     /**
1593      * Return the values of the properties in the ScriptObject
1594      * (java.util.Map-like method to help ScriptObjectMirror implementation)
1595      *
1596      * @return collection of values for the properties in this ScriptObject
1597      */


2276 
2277             for (int i = length; i < n; i++) {
2278                 newArray[i] = fill;
2279             }
2280         }
2281 
2282         return newArray;
2283     }
2284 
2285     /**
2286       * Numeric length setter for length property
2287       *
2288       * @param newLength new length to set
2289       */
2290     public final void setLength(final long newLength) {
2291        final long arrayLength = getArray().length();
2292        if (newLength == arrayLength) {
2293            return;
2294        }
2295 


2296        if (newLength > arrayLength) {
2297            setArray(getArray().ensure(newLength - 1));
2298             if (getArray().canDelete(arrayLength, (newLength - 1), false)) {
2299                setArray(getArray().delete(arrayLength, (newLength - 1)));
2300            }
2301            return;
2302        }
2303 
2304        if (newLength < arrayLength) {
2305            setArray(getArray().shrink(newLength));
2306            getArray().setLength(newLength);
2307        }
2308     }
2309 
2310     private int getInt(final int index, final String key) {
2311         if (ArrayIndex.isValidArrayIndex(index)) {
2312              for (ScriptObject object = this; ; ) {
2313                 final FindProperty find = object.findProperty(key, false, false, this);
2314 
2315                 if (find != null) {
2316                     return getIntValue(find);
2317                 }
2318