Spaces:
Configuration error
Configuration error
| ; | |
| var GetIntrinsic = require('get-intrinsic'); | |
| var $RangeError = GetIntrinsic('%RangeError%'); | |
| var $TypeError = GetIntrinsic('%TypeError%'); | |
| var assign = require('object.assign'); | |
| var isPropertyDescriptor = require('../helpers/isPropertyDescriptor'); | |
| var IsArray = require('./IsArray'); | |
| var IsAccessorDescriptor = require('./IsAccessorDescriptor'); | |
| var IsDataDescriptor = require('./IsDataDescriptor'); | |
| var OrdinaryDefineOwnProperty = require('./OrdinaryDefineOwnProperty'); | |
| var OrdinaryGetOwnProperty = require('./OrdinaryGetOwnProperty'); | |
| var ToNumber = require('./ToNumber'); | |
| var ToString = require('./ToString'); | |
| var ToUint32 = require('./ToUint32'); | |
| var Type = require('./Type'); | |
| // https://262.ecma-international.org/6.0/#sec-arraysetlength | |
| // eslint-disable-next-line max-statements, max-lines-per-function | |
| module.exports = function ArraySetLength(A, Desc) { | |
| if (!IsArray(A)) { | |
| throw new $TypeError('Assertion failed: A must be an Array'); | |
| } | |
| if (!isPropertyDescriptor({ | |
| Type: Type, | |
| IsDataDescriptor: IsDataDescriptor, | |
| IsAccessorDescriptor: IsAccessorDescriptor | |
| }, Desc)) { | |
| throw new $TypeError('Assertion failed: Desc must be a Property Descriptor'); | |
| } | |
| if (!('[[Value]]' in Desc)) { | |
| return OrdinaryDefineOwnProperty(A, 'length', Desc); | |
| } | |
| var newLenDesc = assign({}, Desc); | |
| var newLen = ToUint32(Desc['[[Value]]']); | |
| var numberLen = ToNumber(Desc['[[Value]]']); | |
| if (newLen !== numberLen) { | |
| throw new $RangeError('Invalid array length'); | |
| } | |
| newLenDesc['[[Value]]'] = newLen; | |
| var oldLenDesc = OrdinaryGetOwnProperty(A, 'length'); | |
| if (!IsDataDescriptor(oldLenDesc)) { | |
| throw new $TypeError('Assertion failed: an array had a non-data descriptor on `length`'); | |
| } | |
| var oldLen = oldLenDesc['[[Value]]']; | |
| if (newLen >= oldLen) { | |
| return OrdinaryDefineOwnProperty(A, 'length', newLenDesc); | |
| } | |
| if (!oldLenDesc['[[Writable]]']) { | |
| return false; | |
| } | |
| var newWritable; | |
| if (!('[[Writable]]' in newLenDesc) || newLenDesc['[[Writable]]']) { | |
| newWritable = true; | |
| } else { | |
| newWritable = false; | |
| newLenDesc['[[Writable]]'] = true; | |
| } | |
| var succeeded = OrdinaryDefineOwnProperty(A, 'length', newLenDesc); | |
| if (!succeeded) { | |
| return false; | |
| } | |
| while (newLen < oldLen) { | |
| oldLen -= 1; | |
| // eslint-disable-next-line no-param-reassign | |
| var deleteSucceeded = delete A[ToString(oldLen)]; | |
| if (!deleteSucceeded) { | |
| newLenDesc['[[Value]]'] = oldLen + 1; | |
| if (!newWritable) { | |
| newLenDesc['[[Writable]]'] = false; | |
| OrdinaryDefineOwnProperty(A, 'length', newLenDesc); | |
| return false; | |
| } | |
| } | |
| } | |
| if (!newWritable) { | |
| return OrdinaryDefineOwnProperty(A, 'length', { '[[Writable]]': false }); | |
| } | |
| return true; | |
| }; | |