From 17ba9aea47e496f5b2bc6ce7405b3f32e3cfbf7a Mon Sep 17 00:00:00 2001 From: Michael Ficarra Date: Mon, 15 Jan 2024 16:40:01 -0700 Subject: [PATCH] update constructor and Symbol.toStringTag properties on Iterator.prototype (#3970) * update constructor and toStringTag properties on Iterator.prototype * includes cannot be empty for some reason * update description * add esid * updates * freeze Iterator.prototype * don't try to use real GeneratorPrototype for these tests --- .../prototype/Symbol.toStringTag/prop-desc.js | 22 ++++--- .../Symbol.toStringTag/weird-setter.js | 57 +++++++++++++++++++ .../prototype/constructor/prop-desc.js | 18 ++++++ .../prototype/constructor/weird-setter.js | 57 +++++++++++++++++++ 4 files changed, 142 insertions(+), 12 deletions(-) create mode 100644 test/built-ins/Iterator/prototype/Symbol.toStringTag/weird-setter.js create mode 100644 test/built-ins/Iterator/prototype/constructor/prop-desc.js create mode 100644 test/built-ins/Iterator/prototype/constructor/weird-setter.js diff --git a/test/built-ins/Iterator/prototype/Symbol.toStringTag/prop-desc.js b/test/built-ins/Iterator/prototype/Symbol.toStringTag/prop-desc.js index 8048fcf5c70..424a15b79fd 100644 --- a/test/built-ins/Iterator/prototype/Symbol.toStringTag/prop-desc.js +++ b/test/built-ins/Iterator/prototype/Symbol.toStringTag/prop-desc.js @@ -1,20 +1,18 @@ // Copyright (C) 2023 Michael Ficarra. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 25.1.2.1 +esid: sec-iteratorprototype-@@tostringtag description: Property descriptor info: | - ES6 Section 17 - - Every other data property described in clauses 18 through 26 and in Annex - B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, - [[Configurable]]: true } unless otherwise specified. + `Iterator.prototype[@@toStringTag]` is an accessor property with attributes { [[Enumerable]]: *false*, [[Configurable]]: *true* } features: [iterator-helpers] includes: [propertyHelper.js] ---*/ -verifyProperty(Iterator.prototype, Symbol.toStringTag, { - value: 'Iterator', - writable: true, - enumerable: false, - configurable: true, -}); +verifyConfigurable(Iterator.prototype, Symbol.toStringTag); +verifyNotEnumerable(Iterator.prototype, Symbol.toStringTag); + +let desc = Object.getOwnPropertyDescriptor(Iterator.prototype, Symbol.toStringTag); +assert.sameValue(typeof desc.get, 'function'); +assert.sameValue(typeof desc.set, 'function'); +assert.sameValue(desc.value, undefined); +assert.sameValue(desc.writable, undefined); diff --git a/test/built-ins/Iterator/prototype/Symbol.toStringTag/weird-setter.js b/test/built-ins/Iterator/prototype/Symbol.toStringTag/weird-setter.js new file mode 100644 index 00000000000..281be755959 --- /dev/null +++ b/test/built-ins/Iterator/prototype/Symbol.toStringTag/weird-setter.js @@ -0,0 +1,57 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-set-iteratorprototype-@@tostringtag +description: weird setter +info: | + The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps when called: + 1. Return *"Iterator"*. + + The value of the [[Set]] attribute is a built-in function that takes an argument _v_. It performs the following steps when called: + 1. Perform ? SetterThatIgnoresPrototypeProperties(%Iterator.prototype%, %Symbol.toStringTag%, _v_). + 2. Return *undefined*. +features: [iterator-helpers] +---*/ + +let IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())) + +let sentinel = 'a'; + +let { get, set } = Object.getOwnPropertyDescriptor(Iterator.prototype, Symbol.toStringTag); + +assert.sameValue(Iterator.prototype[Symbol.toStringTag], 'Iterator'); +assert.sameValue(get.call(), 'Iterator'); + +// 1. If _this_ is not an Object, then +// 1. Throw a *TypeError* exception. +assert.throws(() => set.call(undefined, '')); +assert.throws(() => set.call(null, '')); +assert.throws(() => set.call(true, '')); + +// 1. If _this_ is _home_, then +// 1. NOTE: Throwing here emulates assignment to a non-writable data property on the _home_ object in strict mode code. +// 1. Throw a *TypeError* exception. +assert.throws(() => set.call(IteratorPrototype, '')); +assert.throws(() => IteratorPrototype[Symbol.toStringTag] = ''); + +assert.sameValue(Iterator.prototype[Symbol.toStringTag], 'Iterator'); +assert.sameValue(get.call(), 'Iterator'); + +// 1. If _desc_ is *undefined*, then +// 1. Perform ? CreateDataPropertyOrThrow(_this_, _p_, _v_). +let FakeGeneratorPrototype = Object.create(IteratorPrototype); +Object.freeze(IteratorPrototype); +FakeGeneratorPrototype[Symbol.toStringTag] = sentinel; +assert.sameValue(FakeGeneratorPrototype[Symbol.toStringTag], sentinel); + +assert.sameValue(Iterator.prototype[Symbol.toStringTag], 'Iterator'); +assert.sameValue(get.call(), 'Iterator'); + +// 1. Else, +// 1. Perform ? Set(_this_, _p_, _v_, *true*). +let o = { [Symbol.toStringTag]: sentinel + 'a' }; +set.call(o, sentinel); +assert.sameValue(o[Symbol.toStringTag], sentinel); + +assert.sameValue(Iterator.prototype[Symbol.toStringTag], 'Iterator'); +assert.sameValue(get.call(), 'Iterator'); diff --git a/test/built-ins/Iterator/prototype/constructor/prop-desc.js b/test/built-ins/Iterator/prototype/constructor/prop-desc.js new file mode 100644 index 00000000000..c67968fb64f --- /dev/null +++ b/test/built-ins/Iterator/prototype/constructor/prop-desc.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-iteratorprototype.constructor +description: Property descriptor +info: | + `Iterator.prototype.constructor` is an accessor property with attributes { [[Enumerable]]: *false*, [[Configurable]]: *true* } +features: [iterator-helpers] +includes: [propertyHelper.js] +---*/ +verifyConfigurable(Iterator.prototype, 'constructor'); +verifyNotEnumerable(Iterator.prototype, 'constructor'); + +let desc = Object.getOwnPropertyDescriptor(Iterator.prototype, 'constructor'); +assert.sameValue(typeof desc.get, 'function'); +assert.sameValue(typeof desc.set, 'function'); +assert.sameValue(desc.value, undefined); +assert.sameValue(desc.writable, undefined); diff --git a/test/built-ins/Iterator/prototype/constructor/weird-setter.js b/test/built-ins/Iterator/prototype/constructor/weird-setter.js new file mode 100644 index 00000000000..67d4b601e38 --- /dev/null +++ b/test/built-ins/Iterator/prototype/constructor/weird-setter.js @@ -0,0 +1,57 @@ +// Copyright (C) 2023 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-set-iteratorprototype-constructor +description: weird setter +info: | + The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps when called: + 1. Return %Iterator%. + + The value of the [[Set]] attribute is a built-in function that takes an argument _v_. It performs the following steps when called: + 1. Perform ? SetterThatIgnoresPrototypeProperties(%Iterator.prototype%, *"constructor"*, _v_). + 2. Return *undefined*. +features: [iterator-helpers] +---*/ + +let IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())) + +let sentinel = {}; + +let { get, set } = Object.getOwnPropertyDescriptor(Iterator.prototype, 'constructor'); + +assert.sameValue(Iterator.prototype.constructor, Iterator); +assert.sameValue(get.call(), Iterator); + +// 1. If _this_ is not an Object, then +// 1. Throw a *TypeError* exception. +assert.throws(() => set.call(undefined, '')); +assert.throws(() => set.call(null, '')); +assert.throws(() => set.call(true, '')); + +// 1. If _this_ is _home_, then +// 1. NOTE: Throwing here emulates assignment to a non-writable data property on the _home_ object in strict mode code. +// 1. Throw a *TypeError* exception. +assert.throws(() => set.call(IteratorPrototype, '')); +assert.throws(() => IteratorPrototype.constructor = ''); + +assert.sameValue(Iterator.prototype.constructor, Iterator); +assert.sameValue(get.call(), Iterator); + +// 1. If _desc_ is *undefined*, then +// 1. Perform ? CreateDataPropertyOrThrow(_this_, _p_, _v_). +let FakeGeneratorPrototype = Object.create(IteratorPrototype); +Object.freeze(IteratorPrototype); +FakeGeneratorPrototype.constructor = sentinel; +assert.sameValue(FakeGeneratorPrototype.constructor, sentinel); + +assert.sameValue(Iterator.prototype.constructor, Iterator); +assert.sameValue(get.call(), Iterator); + +// 1. Else, +// 1. Perform ? Set(_this_, _p_, _v_, *true*). +let o = { constructor: sentinel + 'a' }; +set.call(o, sentinel); +assert.sameValue(o.constructor, sentinel); + +assert.sameValue(Iterator.prototype.constructor, Iterator); +assert.sameValue(get.call(), Iterator);