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

Print this page

        

*** 44,53 **** --- 44,55 ---- import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid; import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex; import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex; + import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.isScopeFlag; + import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.isStrictFlag; import static jdk.nashorn.internal.runtime.linker.NashornGuards.explicitInstanceOfCheck; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType;
*** 96,106 **** * <li>Modifications of the map include adding/deleting attributes or changing a * function field value.</li> * </ul> */ ! public abstract class ScriptObject implements PropertyAccess { /** __proto__ special property name inside object literals. ES6 draft. */ public static final String PROTO_PROPERTY_NAME = "__proto__"; /** Search fall back routine name for "no such method" */ public static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__"; --- 98,108 ---- * <li>Modifications of the map include adding/deleting attributes or changing a * function field value.</li> * </ul> */ ! public abstract class ScriptObject implements PropertyAccess, Cloneable { /** __proto__ special property name inside object literals. ES6 draft. */ public static final String PROTO_PROPERTY_NAME = "__proto__"; /** Search fall back routine name for "no such method" */ public static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__";
*** 2200,2209 **** --- 2202,2214 ---- } } if (find != null) { if (!find.getProperty().isWritable() && !NashornCallSiteDescriptor.isDeclaration(desc)) { + if (NashornCallSiteDescriptor.isScope(desc) && find.getProperty().isLexicalBinding()) { + throw typeError("assign.constant", name); // Overwriting ES6 const should throw also in non-strict mode. + } // Existing, non-writable property return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true); } } else { if (!isExtensible()) {
*** 3101,3111 **** //value agnostic private boolean doesNotHaveEnsureLength(final long longIndex, final long oldLength, final int callSiteFlags) { if (longIndex >= oldLength) { if (!isExtensible()) { ! if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) { throw typeError("object.non.extensible", JSType.toString(longIndex), ScriptRuntime.safeToString(this)); } return true; } setArray(getArray().ensure(longIndex)); --- 3106,3116 ---- //value agnostic private boolean doesNotHaveEnsureLength(final long longIndex, final long oldLength, final int callSiteFlags) { if (longIndex >= oldLength) { if (!isExtensible()) { ! if (isStrictFlag(callSiteFlags)) { throw typeError("object.non.extensible", JSType.toString(longIndex), ScriptRuntime.safeToString(this)); } return true; } setArray(getArray().ensure(longIndex));
*** 3125,3165 **** private void doesNotHave(final int index, final int value, final int callSiteFlags) { final long oldLength = getArray().length(); final long longIndex = ArrayIndex.toLongIndex(index); if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { ! final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); setArray(getArray().set(index, value, strict)); doesNotHaveEnsureDelete(longIndex, oldLength, strict); } } private void doesNotHave(final int index, final long value, final int callSiteFlags) { final long oldLength = getArray().length(); final long longIndex = ArrayIndex.toLongIndex(index); if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { ! final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); setArray(getArray().set(index, value, strict)); doesNotHaveEnsureDelete(longIndex, oldLength, strict); } } private void doesNotHave(final int index, final double value, final int callSiteFlags) { final long oldLength = getArray().length(); final long longIndex = ArrayIndex.toLongIndex(index); if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { ! final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); setArray(getArray().set(index, value, strict)); doesNotHaveEnsureDelete(longIndex, oldLength, strict); } } private void doesNotHave(final int index, final Object value, final int callSiteFlags) { final long oldLength = getArray().length(); final long longIndex = ArrayIndex.toLongIndex(index); if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { ! final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); setArray(getArray().set(index, value, strict)); doesNotHaveEnsureDelete(longIndex, oldLength, strict); } } --- 3130,3170 ---- private void doesNotHave(final int index, final int value, final int callSiteFlags) { final long oldLength = getArray().length(); final long longIndex = ArrayIndex.toLongIndex(index); if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { ! final boolean strict = isStrictFlag(callSiteFlags); setArray(getArray().set(index, value, strict)); doesNotHaveEnsureDelete(longIndex, oldLength, strict); } } private void doesNotHave(final int index, final long value, final int callSiteFlags) { final long oldLength = getArray().length(); final long longIndex = ArrayIndex.toLongIndex(index); if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { ! final boolean strict = isStrictFlag(callSiteFlags); setArray(getArray().set(index, value, strict)); doesNotHaveEnsureDelete(longIndex, oldLength, strict); } } private void doesNotHave(final int index, final double value, final int callSiteFlags) { final long oldLength = getArray().length(); final long longIndex = ArrayIndex.toLongIndex(index); if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { ! final boolean strict = isStrictFlag(callSiteFlags); setArray(getArray().set(index, value, strict)); doesNotHaveEnsureDelete(longIndex, oldLength, strict); } } private void doesNotHave(final int index, final Object value, final int callSiteFlags) { final long oldLength = getArray().length(); final long longIndex = ArrayIndex.toLongIndex(index); if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { ! final boolean strict = isStrictFlag(callSiteFlags); setArray(getArray().set(index, value, strict)); doesNotHaveEnsureDelete(longIndex, oldLength, strict); } }
*** 3176,3186 **** FindProperty f = find; invalidateGlobalConstant(key); if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty)) { ! final boolean isScope = NashornCallSiteDescriptor.isScopeFlag(callSiteFlags); // If the start object of the find is not this object it means the property was found inside a // 'with' statement expression (see WithObject.findProperty()). In this case we forward the 'set' // to the 'with' object. // Note that although a 'set' operation involving a with statement follows scope rules outside // the 'with' expression (the 'set' operation is performed on the owning prototype if it exists), --- 3181,3191 ---- FindProperty f = find; invalidateGlobalConstant(key); if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty)) { ! final boolean isScope = isScopeFlag(callSiteFlags); // If the start object of the find is not this object it means the property was found inside a // 'with' statement expression (see WithObject.findProperty()). In this case we forward the 'set' // to the 'with' object. // Note that although a 'set' operation involving a with statement follows scope rules outside // the 'with' expression (the 'set' operation is performed on the owning prototype if it exists),
*** 3197,3216 **** } } if (f != null) { if (!f.getProperty().isWritable()) { ! if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) { throw typeError("property.not.writable", key, ScriptRuntime.safeToString(this)); } return; } ! f.setValue(value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)); } else if (!isExtensible()) { ! if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) { throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this)); } } else { ScriptObject sobj = this; // undefined scope properties are set in the global object. --- 3202,3224 ---- } } if (f != null) { if (!f.getProperty().isWritable()) { ! if (isScopeFlag(callSiteFlags) && f.getProperty().isLexicalBinding()) { ! throw typeError("assign.constant", key); // Overwriting ES6 const should throw also in non-strict mode. ! } ! if (isStrictFlag(callSiteFlags)) { throw typeError("property.not.writable", key, ScriptRuntime.safeToString(this)); } return; } ! f.setValue(value, isStrictFlag(callSiteFlags)); } else if (!isExtensible()) { ! if (isStrictFlag(callSiteFlags)) { throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this)); } } else { ScriptObject sobj = this; // undefined scope properties are set in the global object.
*** 3233,3243 **** final int index = getArrayIndex(primitiveKey); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3241,3251 ---- final int index = getArrayIndex(primitiveKey); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3253,3263 **** final int index = getArrayIndex(primitiveKey); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3261,3271 ---- final int index = getArrayIndex(primitiveKey); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3273,3283 **** final int index = getArrayIndex(primitiveKey); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3281,3291 ---- final int index = getArrayIndex(primitiveKey); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3293,3303 **** final int index = getArrayIndex(primitiveKey); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3301,3311 ---- final int index = getArrayIndex(primitiveKey); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3312,3322 **** final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3320,3330 ---- final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3331,3341 **** final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3339,3349 ---- final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3350,3360 **** final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3358,3368 ---- final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3369,3379 **** final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3377,3387 ---- final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3388,3398 **** final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3396,3406 ---- final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3407,3417 **** final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3415,3425 ---- final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3426,3436 **** final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3434,3444 ---- final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3445,3455 **** final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3453,3463 ---- final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3463,3473 **** public void set(final int key, final int value, final int callSiteFlags) { final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { if (getArray().has(index)) { final ArrayData data = getArray(); ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; } --- 3471,3481 ---- public void set(final int key, final int value, final int callSiteFlags) { final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { if (getArray().has(index)) { final ArrayData data = getArray(); ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; }
*** 3481,3491 **** final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3489,3499 ---- final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3500,3510 **** final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3508,3518 ---- final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3519,3529 **** final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return; --- 3527,3537 ---- final int index = getArrayIndex(key); if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { ! setArray(data.set(index, value, isStrictFlag(callSiteFlags))); } else { doesNotHave(index, value, callSiteFlags); } return;
*** 3684,3693 **** --- 3692,3724 ---- return true; } /** + * Return a shallow copy of this ScriptObject. + * @return a shallow copy. + */ + public final ScriptObject copy() { + try { + return clone(); + } catch (final CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + + @Override + protected ScriptObject clone() throws CloneNotSupportedException { + final ScriptObject clone = (ScriptObject) super.clone(); + if (objectSpill != null) { + clone.objectSpill = objectSpill.clone(); + clone.primitiveSpill = primitiveSpill.clone(); + } + clone.arrayData = arrayData.copy(); + return clone; + } + + /** * Make a new UserAccessorProperty property. getter and setter functions are stored in * this ScriptObject and slot values are used in property object. * * @param key the property name * @param propertyFlags attribute flags of the property