define-own-prop-length-coercion-order.js (2009B)
1 // Copyright (C) 2020 Alexey Shvayka. All rights reserved. 2 // This code is governed by the BSD license found in the LICENSE file. 3 4 /*--- 5 author: André Bargull 6 esid: sec-arraysetlength 7 description: > 8 [[Value]] is coerced to number before descriptor validation. 9 info: | 10 ArraySetLength ( A, Desc ) 11 12 [...] 13 3. Let newLen be ? ToUint32(Desc.[[Value]]). 14 4. Let numberLen be ? ToNumber(Desc.[[Value]]). 15 [...] 16 7. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length"). 17 [...] 18 11. If newLen ≥ oldLen, then 19 a. Return OrdinaryDefineOwnProperty(A, "length", newLenDesc). 20 21 OrdinaryDefineOwnProperty ( O, P, Desc ) 22 23 [...] 24 3. Return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current). 25 26 ValidateAndApplyPropertyDescriptor ( O, P, extensible, Desc, current ) 27 28 [...] 29 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both true, then 30 a. If current.[[Configurable]] is false and current.[[Writable]] is false, then 31 i. If Desc.[[Writable]] is present and Desc.[[Writable]] is true, return false. 32 features: [Reflect] 33 ---*/ 34 35 var array = [1, 2]; 36 var valueOfCalls = 0; 37 var length = { 38 valueOf: function() { 39 valueOfCalls += 1; 40 if (valueOfCalls !== 1) { 41 // skip first coercion at step 3 42 Object.defineProperty(array, "length", {writable: false}); 43 } 44 return array.length; 45 }, 46 }; 47 48 assert.throws(TypeError, function() { 49 Object.defineProperty(array, "length", {value: length, writable: true}); 50 }, 'Object.defineProperty(array, "length", {value: length, writable: true}) throws a TypeError exception'); 51 assert.sameValue(valueOfCalls, 2, 'The value of valueOfCalls is expected to be 2'); 52 53 54 array = [1, 2]; 55 valueOfCalls = 0; 56 57 assert( 58 !Reflect.defineProperty(array, "length", {value: length, writable: true}), 59 'The value of !Reflect.defineProperty(array, "length", {value: length, writable: true}) is expected to be true' 60 ); 61 assert.sameValue(valueOfCalls, 2, 'The value of valueOfCalls is expected to be 2'); 62 63 reportCompare(0, 0);