import jdk.nashorn.internal.runtime.arrays.ArrayIndex; //導入方法依賴的package包/類
/**
* ECMA 15.4.5.1 [[DefineOwnProperty]] ( P, Desc, Throw )
*/
@Override
public boolean defineOwnProperty(final Object key, final Object propertyDesc, final boolean reject) {
final PropertyDescriptor desc = toPropertyDescriptor(Global.instance(), propertyDesc);
// never be undefined as "length" is always defined and can't be deleted for arrays
// Step 1
final PropertyDescriptor oldLenDesc = (PropertyDescriptor) super.getOwnPropertyDescriptor("length");
// Step 2
// get old length and convert to long. Always a Long/Uint32 but we take the safe road.
final long oldLen = JSType.toUint32(oldLenDesc.getValue());
// Step 3
if ("length".equals(key)) {
// check for length being made non-writable
final boolean result = defineLength(oldLen, oldLenDesc, desc, reject);
if (desc.has(WRITABLE) && !desc.isWritable()) {
setIsLengthNotWritable();
}
return result;
}
// Step 4a
final int index = ArrayIndex.getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
final long longIndex = ArrayIndex.toLongIndex(index);
// Step 4b
// setting an element beyond current length, but 'length' is not writable
if (longIndex >= oldLen && !oldLenDesc.isWritable()) {
if (reject) {
throw typeError("property.not.writable", Long.toString(longIndex), ScriptRuntime.safeToString(this));
}
return false;
}
// Step 4c
// set the new array element
final boolean succeeded = super.defineOwnProperty(key, desc, false);
// Step 4d
if (!succeeded) {
if (reject) {
throw typeError("cant.redefine.property", key.toString(), ScriptRuntime.safeToString(this));
}
return false;
}
// Step 4e -- adjust new length based on new element index that is set
if (longIndex >= oldLen) {
oldLenDesc.setValue(longIndex + 1);
super.defineOwnProperty("length", oldLenDesc, false);
}
// Step 4f
return true;
}
// not an index property
return super.defineOwnProperty(key, desc, reject);
}