From 318df8f01e37ee7e9e7561243e407e21a8c64bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Wed, 10 Jul 2024 18:32:27 +0200 Subject: [PATCH 01/90] Delete harness test for removed TemporalHelpers.oneShiftTimeZone function --- .../temporalHelpers-sample-time-zones.js | 109 ------------------ 1 file changed, 109 deletions(-) delete mode 100644 test/harness/temporalHelpers-sample-time-zones.js diff --git a/test/harness/temporalHelpers-sample-time-zones.js b/test/harness/temporalHelpers-sample-time-zones.js deleted file mode 100644 index 9fdde9a107..0000000000 --- a/test/harness/temporalHelpers-sample-time-zones.js +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (C) 2022 Igalia, S.L. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: > - Verify the time zone arithmetic used in TemporalHelpers.oneShiftTimeZone() - against known cases in the implementation's time zone database -includes: [compareArray.js, temporalHelpers.js] -features: [Temporal] ----*/ - -function checkTimeZoneArithmetic(shiftInstant, testWallTime, testWallDuration, tz, realTimeZoneName) { - // No need to test this on hosts that don't provide an Intl object. It's - // sufficient that the logic is tested on at least one host. - if (typeof globalThis.Intl === "undefined") - return; - - const realTz = new Temporal.TimeZone(realTimeZoneName); - - assert.sameValue( - tz.getOffsetNanosecondsFor(shiftInstant), - realTz.getOffsetNanosecondsFor(shiftInstant), - 'offset at shift instant' - ); - const minus1 = shiftInstant.subtract({ hours: 1 }); - assert.sameValue( - tz.getOffsetNanosecondsFor(minus1), - realTz.getOffsetNanosecondsFor(minus1), - 'offset at 1 hour before shift' - ); - const plus1 = shiftInstant.add({ hours: 1 }); - assert.sameValue( - tz.getOffsetNanosecondsFor(plus1), - realTz.getOffsetNanosecondsFor(plus1), - 'offset at 1 hour after shift' - ); - - assert.compareArray( - tz.getPossibleInstantsFor(testWallTime).map((i) => i.epochNanoseconds), - realTz.getPossibleInstantsFor(testWallTime).map((i) => i.epochNanoseconds), - 'possible instants for wall time' - ); - const before1 = testWallTime.subtract(testWallDuration); - assert.compareArray( - tz.getPossibleInstantsFor(before1).map((i) => i.epochNanoseconds), - realTz.getPossibleInstantsFor(before1).map((i) => i.epochNanoseconds), - 'possible instants before wall time' - ); - const after1 = testWallTime.add(testWallDuration); - assert.compareArray( - tz.getPossibleInstantsFor(after1).map((i) => i.epochNanoseconds), - realTz.getPossibleInstantsFor(after1).map((i) => i.epochNanoseconds), - 'possible instants after wall time' - ); -} - -// Check a positive DST shift from +00:00 to +01:00 -checkTimeZoneArithmetic( - new Temporal.Instant(1616893200000000000n), - new Temporal.PlainDateTime(2021, 3, 28, 1), - { hours: 1 }, - TemporalHelpers.oneShiftTimeZone(new Temporal.Instant(1616893200000000000n), 3600e9), - 'Europe/London', -); - -// Check a negative DST shift from +00:00 to -01:00 -checkTimeZoneArithmetic( - new Temporal.Instant(1635642000000000000n), - new Temporal.PlainDateTime(2021, 10, 31, 1), - { hours: 1 }, - TemporalHelpers.oneShiftTimeZone(new Temporal.Instant(1635642000000000000n), -3600e9), - 'Atlantic/Azores', -); - -// Check the no-shift case -checkTimeZoneArithmetic( - new Temporal.Instant(0n), - new Temporal.PlainDateTime(1970, 1, 1), - { hours: 1 }, - TemporalHelpers.oneShiftTimeZone(new Temporal.Instant(0n), 0), - 'UTC', -); - -// Check the cross-date-line sample time zone -checkTimeZoneArithmetic( - Temporal.Instant.from('2011-12-30T10:00:00Z'), - Temporal.PlainDateTime.from("2011-12-30T12:00"), - { days: 1 }, - TemporalHelpers.crossDateLineTimeZone(), - 'Pacific/Apia', -); - -// Check the spring-forward transition of the DST sample time zone -checkTimeZoneArithmetic( - new Temporal.Instant(954669600_000_000_000n), - new Temporal.PlainDateTime(2000, 4, 2, 2), - { minutes: 30 }, - TemporalHelpers.springForwardFallBackTimeZone(), - 'America/Vancouver', -); - -// Check the fall-back transition of the DST sample time zone -checkTimeZoneArithmetic( - new Temporal.Instant(972810000_000_000_000n), - new Temporal.PlainDateTime(2000, 10, 29, 2), - { minutes: 30 }, - TemporalHelpers.springForwardFallBackTimeZone(), - 'America/Vancouver', -); From 7b154389cef54d6b0a14a03b52f20db1aa3ab05c Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Tue, 9 Jul 2024 13:51:47 -0700 Subject: [PATCH 02/90] Update firstDay test to latest spec after PR 79 Spec Changes merged https://github.com/tc39/proposal-intl-locale-info/pull/79 --- ...structor-options-firstDayOfWeek-invalid.js | 10 ++-- ...onstructor-options-firstDayOfWeek-valid.js | 33 +++++++++---- .../prototype/firstDayOfWeek/valid-id.js | 14 +++--- .../prototype/firstDayOfWeek/valid-options.js | 46 +++++++++---------- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/test/intl402/Locale/constructor-options-firstDayOfWeek-invalid.js b/test/intl402/Locale/constructor-options-firstDayOfWeek-invalid.js index a2a754d923..727134d7f9 100644 --- a/test/intl402/Locale/constructor-options-firstDayOfWeek-invalid.js +++ b/test/intl402/Locale/constructor-options-firstDayOfWeek-invalid.js @@ -9,7 +9,10 @@ info: | Intl.Locale( tag [, options] ) ... - x. Let numberingSystem be ? GetOption(options, "firstDayOfWeek", "string", < *"mon"*, *"tue"*, *"wed"*, *"thu"*, *"fri"*, *"sat"*, *"sun"*, *"0"*, *"1"*, *"2"*, *"3"*, *"4"*, *"5"*, *"6"*, *"7"*> , undefined). + x. Let fw be ? GetOption(options, "firstDayOfWeek", "string", undefined, undefined). + x. If fw is not undefined, then + x. Set fw to !WeekdayToString(fw). + x. If fw does not match the type sequence (from UTS 35 Unicode Locale Identifier, section 3.2), throw a RangeError exception. ... features: [Intl.Locale,Intl.Locale-info] @@ -19,10 +22,7 @@ const invalidFirstDayOfWeekOptions = [ "", "m", "mo", - "monday", - true, - false, - null, + "longerThan8Chars", ]; for (const firstDayOfWeek of invalidFirstDayOfWeekOptions) { assert.throws(RangeError, function() { diff --git a/test/intl402/Locale/constructor-options-firstDayOfWeek-valid.js b/test/intl402/Locale/constructor-options-firstDayOfWeek-valid.js index d9efe8bf82..4905bfc0c8 100644 --- a/test/intl402/Locale/constructor-options-firstDayOfWeek-valid.js +++ b/test/intl402/Locale/constructor-options-firstDayOfWeek-valid.js @@ -9,18 +9,15 @@ info: | Intl.Locale( tag [, options] ) ... - x. Let numberingSystem be ? GetOption(options, "firstDayOfWeek", "string", < *"mon"*, *"tue"*, *"wed"*, *"thu"*, *"fri"*, *"sat"*, *"sun"*, *"0"*, *"1"*, *"2"*, *"3"*, *"4"*, *"5"*, *"6"*, *"7"*> , undefined). - x. Let firstDay be *undefined*. - x. If fw is not *undefined*, then - x. Set firstDay to !WeekdayToString(fw). - x. Set opt.[[fw]] to firstDay. + x. Let fw be ? GetOption(options, "firstDayOfWeek", "string", undefined, undefined). + x. If fw is not undefined, then + x. Set fw to !WeekdayToString(fw). + x. If fw does not match the type sequence (from UTS 35 Unicode Locale Identifier, section 3.2), throw a RangeError exception. + x. Set opt.[[fw]] to fw. ... x. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys). ... - x. Let firstDay be *undefined*. - x. If r.[[fw]] is not *undefined*, then - x. Set firstDay to ! WeekdayToNumber(r.[[fw]]). - x. Set locale.[[FirstDayOfWeek]] to firstDay. + x. Set locale.[[FirstDayOfWeek]] to r.[[fw]]. ... features: [Intl.Locale,Intl.Locale-info] @@ -50,6 +47,24 @@ const validFirstDayOfWeekOptions = [ [6, "en-u-fw-sat"], [7, "en-u-fw-sun"], [0, "en-u-fw-sun"], + [true, "en-u-fw-true"], + [false, "en-u-fw-false"], + [null, "en-u-fw-null"], + ["primidi", "en-u-fw-primidi"], + ["duodi", "en-u-fw-duodi"], + ["tridi", "en-u-fw-tridi"], + ["quartidi", "en-u-fw-quartidi"], + ["quintidi", "en-u-fw-quintidi"], + ["sextidi", "en-u-fw-sextidi"], + ["septidi", "en-u-fw-septidi"], + ["octidi", "en-u-fw-octidi"], + ["nonidi", "en-u-fw-nonidi"], + ["decadi", "en-u-fw-decadi"], + ["frank", "en-u-fw-frank"], + ["yungfong", "en-u-fw-yungfong"], + ["yung-fong", "en-u-fw-yung-fong"], + ["tang", "en-u-fw-tang"], + ["frank-yung-fong-tang", "en-u-fw-frank-yung-fong-tang"], ]; for (const [firstDayOfWeek, expected] of validFirstDayOfWeekOptions) { assert.sameValue( diff --git a/test/intl402/Locale/prototype/firstDayOfWeek/valid-id.js b/test/intl402/Locale/prototype/firstDayOfWeek/valid-id.js index 12acd526a9..d9aa88a33b 100644 --- a/test/intl402/Locale/prototype/firstDayOfWeek/valid-id.js +++ b/test/intl402/Locale/prototype/firstDayOfWeek/valid-id.js @@ -13,13 +13,13 @@ features: [Intl.Locale,Intl.Locale-info] ---*/ const validIds = [ - ["en-u-fw-mon", 1], - ["en-u-fw-tue", 2], - ["en-u-fw-wed", 3], - ["en-u-fw-thu", 4], - ["en-u-fw-fri", 5], - ["en-u-fw-sat", 6], - ["en-u-fw-sun", 7], + ["en-u-fw-mon", "mon"], + ["en-u-fw-tue", "tue"], + ["en-u-fw-wed", "wed"], + ["en-u-fw-thu", "thu"], + ["en-u-fw-fri", "fri"], + ["en-u-fw-sat", "sat"], + ["en-u-fw-sun", "sun"], ]; for (const [id, expected] of validIds) { assert.sameValue( diff --git a/test/intl402/Locale/prototype/firstDayOfWeek/valid-options.js b/test/intl402/Locale/prototype/firstDayOfWeek/valid-options.js index 6f1643afd2..bf6c8507cc 100644 --- a/test/intl402/Locale/prototype/firstDayOfWeek/valid-options.js +++ b/test/intl402/Locale/prototype/firstDayOfWeek/valid-options.js @@ -13,29 +13,29 @@ features: [Intl.Locale,Intl.Locale-info] ---*/ const validFirstDayOfWeekOptions = [ - ["mon", 1], - ["tue", 2], - ["wed", 3], - ["thu", 4], - ["fri", 5], - ["sat", 6], - ["sun", 7], - ["1", 1], - ["2", 2], - ["3", 3], - ["4", 4], - ["5", 5], - ["6", 6], - ["7", 7], - ["0", 7], - [1, 1], - [2, 2], - [3, 3], - [4, 4], - [5, 5], - [6, 6], - [7, 7], - [0, 7], + ["mon", "mon"], + ["tue", "tue"], + ["wed", "wed"], + ["thu", "thu"], + ["fri", "fri"], + ["sat", "sat"], + ["sun", "sun"], + ["1", "mon"], + ["2", "tue"], + ["3", "wed"], + ["4", "thu"], + ["5", "fri"], + ["6", "sat"], + ["7", "sun"], + ["0", "sun"], + [1, "mon"], + [2, "tue"], + [3, "wed"], + [4, "thu"], + [5, "fri"], + [6, "sat"], + [7, "sun"], + [0, "sun"], ]; for (const [firstDayOfWeek, expected] of validFirstDayOfWeekOptions) { assert.sameValue( From 830c52155dc635bb2b472e1868d1626eebfbb9f0 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Thu, 11 Jul 2024 00:08:33 +0100 Subject: [PATCH 03/90] Fix AbstractModuleSource verifyProperty calls --- test/built-ins/AbstractModuleSource/prototype.js | 3 ++- .../AbstractModuleSource/prototype/Symbol.toStringTag.js | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/test/built-ins/AbstractModuleSource/prototype.js b/test/built-ins/AbstractModuleSource/prototype.js index 4257d96218..e6a0ec4833 100644 --- a/test/built-ins/AbstractModuleSource/prototype.js +++ b/test/built-ins/AbstractModuleSource/prototype.js @@ -9,6 +9,7 @@ info: | The initial value of %AbstractModuleSource%.prototype is the %AbstractModuleSource% prototype object. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. +includes: [propertyHelper.js] features: [source-phase-imports] flags: [module] ---*/ @@ -18,5 +19,5 @@ verifyProperty($262.AbstractModuleSource, 'prototype', { value: $262.AbstractModuleSource.prototype, writable: false, enumerable: false, - configurable: false + configurable: true }); diff --git a/test/built-ins/AbstractModuleSource/prototype/Symbol.toStringTag.js b/test/built-ins/AbstractModuleSource/prototype/Symbol.toStringTag.js index 2fd23ca70b..38e1a2e8bb 100644 --- a/test/built-ins/AbstractModuleSource/prototype/Symbol.toStringTag.js +++ b/test/built-ins/AbstractModuleSource/prototype/Symbol.toStringTag.js @@ -23,8 +23,11 @@ includes: [propertyHelper.js] assert.sameValue(typeof $262.AbstractModuleSource, 'function'); verifyProperty($262.AbstractModuleSource.prototype, Symbol.toStringTag, { enumerable: false, - configurable: false, - writable: false, + configurable: true, + set: undefined, + value: undefined, +}, { + restore: true, }); // Return undefined if this value does not have a [[ModuleSourceClassName]] internal slot. From 58751ca335b95c05fd57f9e34cb0986a622861cd Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Thu, 11 Jul 2024 11:17:24 -0700 Subject: [PATCH 04/90] Add tests for Atomics.pause (#4147) * Add tests for Atomics.pause * Address review --- features.txt | 4 +++ test/built-ins/Atomics/pause/descriptor.js | 15 +++++++++ test/built-ins/Atomics/pause/length.js | 16 ++++++++++ test/built-ins/Atomics/pause/name.js | 16 ++++++++++ .../pause/negative-iterationnumber-throws.js | 19 +++++++++++ .../non-integral-iterationnumber-throws.js | 32 +++++++++++++++++++ .../Atomics/pause/not-a-constructor.js | 28 ++++++++++++++++ .../Atomics/pause/returns-undefined.js | 24 ++++++++++++++ 8 files changed, 154 insertions(+) create mode 100644 test/built-ins/Atomics/pause/descriptor.js create mode 100644 test/built-ins/Atomics/pause/length.js create mode 100644 test/built-ins/Atomics/pause/name.js create mode 100644 test/built-ins/Atomics/pause/negative-iterationnumber-throws.js create mode 100644 test/built-ins/Atomics/pause/non-integral-iterationnumber-throws.js create mode 100644 test/built-ins/Atomics/pause/not-a-constructor.js create mode 100644 test/built-ins/Atomics/pause/returns-undefined.js diff --git a/features.txt b/features.txt index e6e4242539..5721ffd2f8 100644 --- a/features.txt +++ b/features.txt @@ -106,6 +106,10 @@ source-phase-imports-module-source # https://github.com/tc39/proposal-arraybuffer-base64 uint8array-base64 +# Atomics.pause +# https://github.com/tc39/proposal-atomics-microwait +Atomics.pause + ## Standard language features # # Language features that have been included in a published version of the diff --git a/test/built-ins/Atomics/pause/descriptor.js b/test/built-ins/Atomics/pause/descriptor.js new file mode 100644 index 0000000000..89a7e104ca --- /dev/null +++ b/test/built-ins/Atomics/pause/descriptor.js @@ -0,0 +1,15 @@ +// Copyright 2024 the V8 project authors. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-atomics.pause +description: Testing descriptor property of Atomics.pause +includes: [propertyHelper.js] +features: [Atomics.pause] +---*/ + +verifyProperty(Atomics, 'pause', { + enumerable: false, + writable: true, + configurable: true, +}); diff --git a/test/built-ins/Atomics/pause/length.js b/test/built-ins/Atomics/pause/length.js new file mode 100644 index 0000000000..7c83f2a54c --- /dev/null +++ b/test/built-ins/Atomics/pause/length.js @@ -0,0 +1,16 @@ +// Copyright 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.pause +description: Atomics.pause.length is 0. +includes: [propertyHelper.js] +features: [Atomics.pause] +---*/ + +verifyProperty(Atomics.pause, 'length', { + value: 0, + enumerable: false, + writable: false, + configurable: true, +}); diff --git a/test/built-ins/Atomics/pause/name.js b/test/built-ins/Atomics/pause/name.js new file mode 100644 index 0000000000..09f1964e07 --- /dev/null +++ b/test/built-ins/Atomics/pause/name.js @@ -0,0 +1,16 @@ +// Copyright 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.pause +description: Atomics.pause.name is "pause". +includes: [propertyHelper.js] +features: [Atomics.pause] +---*/ + +verifyProperty(Atomics.pause, 'name', { + value: 'pause', + enumerable: false, + writable: false, + configurable: true, +}); diff --git a/test/built-ins/Atomics/pause/negative-iterationnumber-throws.js b/test/built-ins/Atomics/pause/negative-iterationnumber-throws.js new file mode 100644 index 0000000000..ea0d29bb49 --- /dev/null +++ b/test/built-ins/Atomics/pause/negative-iterationnumber-throws.js @@ -0,0 +1,19 @@ +// Copyright 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.pause +description: Atomics.pause throws on negative argument values +features: [Atomics.pause] +---*/ + +const values = [ + -1, + Number.MIN_SAFE_INTEGER, + Number.MIN_SAFE_INTEGER - 1 +]; + +for (const v of values) { + assert.throws(RangeError, () => { Atomics.pause(v); }, + `${v} is an illegal iterationNumber`); +} diff --git a/test/built-ins/Atomics/pause/non-integral-iterationnumber-throws.js b/test/built-ins/Atomics/pause/non-integral-iterationnumber-throws.js new file mode 100644 index 0000000000..394c2e3ce7 --- /dev/null +++ b/test/built-ins/Atomics/pause/non-integral-iterationnumber-throws.js @@ -0,0 +1,32 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.pause +description: Atomics.pause throws on non-integral Number argument values +features: [Atomics.pause] +---*/ + +const values = [ + true, + false, + null, + 42.42, + -42.42, + NaN, + Infinity, + Symbol("foo"), + "bar", + "42", + /baz/, + 42n, + {}, + [], + function() {}, + { valueOf() { return 42; } } +]; + +for (const v of values) { + assert.throws(TypeError, () => { Atomics.pause(v); }, + `${v ? v.toString() : v} is an illegal iterationNumber`); +} diff --git a/test/built-ins/Atomics/pause/not-a-constructor.js b/test/built-ins/Atomics/pause/not-a-constructor.js new file mode 100644 index 0000000000..3639a7d8db --- /dev/null +++ b/test/built-ins/Atomics/pause/not-a-constructor.js @@ -0,0 +1,28 @@ +// Copyright 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: Atomics.pause does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, Atomics.pause] +---*/ + +assert.sameValue(isConstructor(Atomics.pause), false, 'isConstructor(Atomics.pause) must return false'); + +assert.throws(TypeError, () => { + new Atomics.pause(); +}); + diff --git a/test/built-ins/Atomics/pause/returns-undefined.js b/test/built-ins/Atomics/pause/returns-undefined.js new file mode 100644 index 0000000000..7bf35fdce4 --- /dev/null +++ b/test/built-ins/Atomics/pause/returns-undefined.js @@ -0,0 +1,24 @@ +// Copyright 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.pause +description: Atomics.pause returns undefined +features: [Atomics.pause] +---*/ + +assert.sameValue(Atomics.pause(), undefined, + 'Atomics.pause returns undefined'); + +const values = [ + undefined, + 42, + 0, + -0, + Number.MAX_SAFE_INTEGER +]; + +for (const v of values) { + assert.sameValue(Atomics.pause(v), undefined, + 'Atomics.pause returns undefined'); +} From 753d502e9a582d3aa152c0296310dc0761973d2f Mon Sep 17 00:00:00 2001 From: Frank Yung-Fong Tang Date: Thu, 11 Jul 2024 15:20:15 -0700 Subject: [PATCH 05/90] Update the expctation of constructor-options-firstDayOfWeek-valid.js true will be dropped inside UTS35 --- test/intl402/Locale/constructor-options-firstDayOfWeek-valid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/intl402/Locale/constructor-options-firstDayOfWeek-valid.js b/test/intl402/Locale/constructor-options-firstDayOfWeek-valid.js index 4905bfc0c8..0c60306257 100644 --- a/test/intl402/Locale/constructor-options-firstDayOfWeek-valid.js +++ b/test/intl402/Locale/constructor-options-firstDayOfWeek-valid.js @@ -47,7 +47,7 @@ const validFirstDayOfWeekOptions = [ [6, "en-u-fw-sat"], [7, "en-u-fw-sun"], [0, "en-u-fw-sun"], - [true, "en-u-fw-true"], + [true, "en-u-fw"], [false, "en-u-fw-false"], [null, "en-u-fw-null"], ["primidi", "en-u-fw-primidi"], From 8ca7c1a42a4d95b1a3737d24ab2ea48f1cf8c736 Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Tue, 9 Jul 2024 19:15:15 +0200 Subject: [PATCH 06/90] Adds missing Array.prototype.filter \'shrink\' tests and some typesetting --- .../resizable-buffer-grow-mid-iteration.js | 15 ++-- .../resizable-buffer-shrink-mid-iteration.js | 79 +++++++++++++++++++ .../prototype/filter/resizable-buffer.js | 3 +- .../resizable-buffer-grow-mid-iteration.js | 14 ++-- .../resizable-buffer-shrink-mid-iteration.js | 15 ++-- .../prototype/filter/resizable-buffer.js | 2 +- 6 files changed, 102 insertions(+), 26 deletions(-) create mode 100644 test/built-ins/Array/prototype/filter/resizable-buffer-shrink-mid-iteration.js diff --git a/test/built-ins/Array/prototype/filter/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/filter/resizable-buffer-grow-mid-iteration.js index 5a24fc9b2c..5ce7c6b2fc 100644 --- a/test/built-ins/Array/prototype/filter/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/Array/prototype/filter/resizable-buffer-grow-mid-iteration.js @@ -4,8 +4,8 @@ /*--- esid: sec-array.prototype.filter description: > - Array.p.filter behaves correctly on receivers backed by resizable - buffers that grow mid-iteration + Array.p.filter behaves correctly on TypedArrays backed by resizable buffers + that grow mid-iteration. includes: [compareArray.js, resizableArrayBufferUtils.js] features: [resizable-arraybuffer] ---*/ @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset // before calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -36,7 +36,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(Array.prototype.filter.call(fixedLength, ResizeBufferMidIteration)), []); + assert.compareArray(ToNumbers(Array.prototype.filter.call(fixedLength, ResizeMidIteration)), []); assert.compareArray(values, [ 0, 2, @@ -50,7 +50,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(Array.prototype.filter.call(fixedLengthWithOffset, ResizeBufferMidIteration)), []); + assert.compareArray(ToNumbers(Array.prototype.filter.call(fixedLengthWithOffset, ResizeMidIteration)), []); assert.compareArray(values, [ 4, 6 @@ -62,7 +62,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(Array.prototype.filter.call(lengthTracking, ResizeBufferMidIteration)), []); + assert.compareArray(ToNumbers(Array.prototype.filter.call(lengthTracking, ResizeMidIteration)), []); assert.compareArray(values, [ 0, 2, @@ -76,10 +76,9 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(Array.prototype.filter.call(lengthTrackingWithOffset, ResizeBufferMidIteration)), []); + assert.compareArray(ToNumbers(Array.prototype.filter.call(lengthTrackingWithOffset, ResizeMidIteration)), []); assert.compareArray(values, [ 4, 6 ]); } - diff --git a/test/built-ins/Array/prototype/filter/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/Array/prototype/filter/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..5af5f62412 --- /dev/null +++ b/test/built-ins/Array/prototype/filter/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,79 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%array%.prototype.filter +description: > + Array.p.filter behaves correctly on TypedArrays backed by resizable buffers + that shrink mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset +// before calling this. +function ResizeMidIteration(n) { + CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); + return false; +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + values = []; + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert.compareArray(ToNumbers(Array.prototype.filter.call(fixedLength, ResizeMidIteration)),[]); + assert.compareArray(values, [ + 0, + 2 + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + values = []; + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert.compareArray(ToNumbers(Array.prototype.filter.call(fixedLengthWithOffset, ResizeMidIteration)),[]); + assert.compareArray(values, [ + 4 + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + values = []; + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert.compareArray(ToNumbers(Array.prototype.filter.call(lengthTracking, ResizeMidIteration)),[]); + assert.compareArray(values, [ + 0, + 2, + 4 + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + values = []; + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert.compareArray(ToNumbers(Array.prototype.filter.call(lengthTrackingWithOffset, ResizeMidIteration)),[]); + assert.compareArray(values, [ + 4 + ]); +} diff --git a/test/built-ins/Array/prototype/filter/resizable-buffer.js b/test/built-ins/Array/prototype/filter/resizable-buffer.js index 85174a5f20..df38c65791 100644 --- a/test/built-ins/Array/prototype/filter/resizable-buffer.js +++ b/test/built-ins/Array/prototype/filter/resizable-buffer.js @@ -4,8 +4,7 @@ /*--- esid: sec-array.prototype.filter description: > - Array.p.filter behaves correctly on receivers backed by resizable - buffers + Array.p.filter behaves correctly on TypedArrays backed by resizable buffers. includes: [compareArray.js, resizableArrayBufferUtils.js] features: [resizable-arraybuffer] ---*/ diff --git a/test/built-ins/TypedArray/prototype/filter/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/filter/resizable-buffer-grow-mid-iteration.js index b3a75ea5cc..d0ad21029a 100644 --- a/test/built-ins/TypedArray/prototype/filter/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/filter/resizable-buffer-grow-mid-iteration.js @@ -4,8 +4,8 @@ /*--- esid: sec-%typedarray%.prototype.filter description: > - TypedArray.p.filter behaves correctly on receivers backed by resizable - buffers that grow mid-iteration + TypedArray.p.filter behaves correctly on TypedArrays backed by resizable + buffers that grow mid-iteration. includes: [compareArray.js, resizableArrayBufferUtils.js] features: [resizable-arraybuffer] ---*/ @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset // before calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -36,7 +36,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(fixedLength.filter(ResizeBufferMidIteration)), []); + assert.compareArray(ToNumbers(fixedLength.filter(ResizeMidIteration)), []); assert.compareArray(values, [ 0, 2, @@ -50,7 +50,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(fixedLengthWithOffset.filter(ResizeBufferMidIteration)), []); + assert.compareArray(ToNumbers(fixedLengthWithOffset.filter(ResizeMidIteration)), []); assert.compareArray(values, [ 4, 6 @@ -62,7 +62,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(lengthTracking.filter(ResizeBufferMidIteration)), []); + assert.compareArray(ToNumbers(lengthTracking.filter(ResizeMidIteration)), []); assert.compareArray(values, [ 0, 2, @@ -76,7 +76,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(lengthTrackingWithOffset.filter(ResizeBufferMidIteration)), []); + assert.compareArray(ToNumbers(lengthTrackingWithOffset.filter(ResizeMidIteration)), []); assert.compareArray(values, [ 4, 6 diff --git a/test/built-ins/TypedArray/prototype/filter/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/filter/resizable-buffer-shrink-mid-iteration.js index 1e72a7ff8e..409a138890 100644 --- a/test/built-ins/TypedArray/prototype/filter/resizable-buffer-shrink-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/filter/resizable-buffer-shrink-mid-iteration.js @@ -4,8 +4,8 @@ /*--- esid: sec-%typedarray%.prototype.filter description: > - TypedArray.p.filter behaves correctly when receiver is backed by resizable - buffer that is shrunk mid-iteration + TypedArray.p.filter behaves correctly on TypedArrays backed by resizable + buffers that are shrunk mid-iteration. includes: [compareArray.js, resizableArrayBufferUtils.js] features: [resizable-arraybuffer] ---*/ @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset // before calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -36,7 +36,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(fixedLength.filter(ResizeBufferMidIteration)),[]); + assert.compareArray(ToNumbers(fixedLength.filter(ResizeMidIteration)),[]); assert.compareArray(values, [ 0, 2, @@ -50,7 +50,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(fixedLengthWithOffset.filter(ResizeBufferMidIteration)),[]); + assert.compareArray(ToNumbers(fixedLengthWithOffset.filter(ResizeMidIteration)),[]); assert.compareArray(values, [ 4, undefined @@ -62,7 +62,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(lengthTracking.filter(ResizeBufferMidIteration)),[]); + assert.compareArray(ToNumbers(lengthTracking.filter(ResizeMidIteration)),[]); assert.compareArray(values, [ 0, 2, @@ -76,10 +76,9 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.compareArray(ToNumbers(lengthTrackingWithOffset.filter(ResizeBufferMidIteration)),[]); + assert.compareArray(ToNumbers(lengthTrackingWithOffset.filter(ResizeMidIteration)),[]); assert.compareArray(values, [ 4, undefined ]); } - diff --git a/test/built-ins/TypedArray/prototype/filter/resizable-buffer.js b/test/built-ins/TypedArray/prototype/filter/resizable-buffer.js index da2111408c..de536e2912 100644 --- a/test/built-ins/TypedArray/prototype/filter/resizable-buffer.js +++ b/test/built-ins/TypedArray/prototype/filter/resizable-buffer.js @@ -4,7 +4,7 @@ /*--- esid: sec-%typedarray%.prototype.filter description: > - TypedArray.p.filter behaves correctly on receivers backed by resizable + TypedArray.p.filter behaves correctly on TypedArrays backed by resizable buffers includes: [compareArray.js, resizableArrayBufferUtils.js] features: [resizable-arraybuffer] From 0ce0bd73147f4a583ba61ec2680298d90caf04c3 Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Tue, 9 Jul 2024 19:23:23 +0200 Subject: [PATCH 07/90] Renames ResizeBufferMidIteration to ResizeMidIteration --- .../every/resizable-buffer-grow-mid-iteration.js | 10 +++++----- .../every/resizable-buffer-shrink-mid-iteration.js | 10 +++++----- .../find/resizable-buffer-grow-mid-iteration.js | 10 +++++----- .../findIndex/resizable-buffer-grow-mid-iteration.js | 10 +++++----- .../resizable-buffer-shrink-mid-iteration.js | 10 +++++----- .../findLast/resizable-buffer-grow-mid-iteration.js | 10 +++++----- .../resizable-buffer-shrink-mid-iteration.js | 10 +++++----- .../resizable-buffer-grow-mid-iteration.js | 10 +++++----- .../resizable-buffer-shrink-mid-iteration.js | 12 ++++++------ .../every/resizable-buffer-grow-mid-iteration.js | 10 +++++----- .../every/resizable-buffer-shrink-mid-iteration.js | 10 +++++----- .../find/resizable-buffer-grow-mid-iteration.js | 10 +++++----- .../find/resizable-buffer-shrink-mid-iteration.js | 10 +++++----- .../findIndex/resizable-buffer-grow-mid-iteration.js | 10 +++++----- .../resizable-buffer-shrink-mid-iteration.js | 10 +++++----- .../findLast/resizable-buffer-grow-mid-iteration.js | 10 +++++----- .../resizable-buffer-shrink-mid-iteration.js | 10 +++++----- .../resizable-buffer-grow-mid-iteration.js | 10 +++++----- .../resizable-buffer-shrink-mid-iteration.js | 12 ++++++------ 19 files changed, 97 insertions(+), 97 deletions(-) diff --git a/test/built-ins/Array/prototype/every/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/every/resizable-buffer-grow-mid-iteration.js index 86335ebbb0..0ecc02e9ed 100644 --- a/test/built-ins/Array/prototype/every/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/Array/prototype/every/resizable-buffer-grow-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset // before calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { // Returns true by default. return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert(Array.prototype.every.call(fixedLength, ResizeBufferMidIteration)); + assert(Array.prototype.every.call(fixedLength, ResizeMidIteration)); assert.compareArray(values, [ 0, 2, @@ -49,7 +49,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert(Array.prototype.every.call(fixedLengthWithOffset, ResizeBufferMidIteration)); + assert(Array.prototype.every.call(fixedLengthWithOffset, ResizeMidIteration)); assert.compareArray(values, [ 4, 6 @@ -61,7 +61,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert(Array.prototype.every.call(lengthTracking, ResizeBufferMidIteration)); + assert(Array.prototype.every.call(lengthTracking, ResizeMidIteration)); assert.compareArray(values, [ 0, 2, @@ -75,7 +75,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert(Array.prototype.every.call(lengthTrackingWithOffset, ResizeBufferMidIteration)); + assert(Array.prototype.every.call(lengthTrackingWithOffset, ResizeMidIteration)); assert.compareArray(values, [ 4, 6 diff --git a/test/built-ins/Array/prototype/every/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/Array/prototype/every/resizable-buffer-shrink-mid-iteration.js index 69179672a1..46ff82de6d 100644 --- a/test/built-ins/Array/prototype/every/resizable-buffer-shrink-mid-iteration.js +++ b/test/built-ins/Array/prototype/every/resizable-buffer-shrink-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset // before calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { // Returns true by default. return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert(Array.prototype.every.call(fixedLength, ResizeBufferMidIteration)); + assert(Array.prototype.every.call(fixedLength, ResizeMidIteration)); assert.compareArray(values, [ 0, 2 @@ -47,7 +47,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert(Array.prototype.every.call(fixedLengthWithOffset, ResizeBufferMidIteration)); + assert(Array.prototype.every.call(fixedLengthWithOffset, ResizeMidIteration)); assert.compareArray(values, [4]); } for (let ctor of ctors) { @@ -56,7 +56,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert(Array.prototype.every.call(lengthTracking, ResizeBufferMidIteration)); + assert(Array.prototype.every.call(lengthTracking, ResizeMidIteration)); assert.compareArray(values, [ 0, 2, @@ -69,6 +69,6 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert(Array.prototype.every.call(lengthTrackingWithOffset, ResizeBufferMidIteration)); + assert(Array.prototype.every.call(lengthTrackingWithOffset, ResizeMidIteration)); assert.compareArray(values, [4]); } diff --git a/test/built-ins/Array/prototype/find/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/find/resizable-buffer-grow-mid-iteration.js index 06cb0df6af..ab2a3dbc3b 100644 --- a/test/built-ins/Array/prototype/find/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/Array/prototype/find/resizable-buffer-grow-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset // before calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -36,7 +36,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.find.call(fixedLength, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.find.call(fixedLength, ResizeMidIteration), undefined); assert.compareArray(values, [ 0, 2, @@ -50,7 +50,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.find.call(fixedLengthWithOffset, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.find.call(fixedLengthWithOffset, ResizeMidIteration), undefined); assert.compareArray(values, [ 4, 6 @@ -62,7 +62,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.find.call(lengthTracking, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.find.call(lengthTracking, ResizeMidIteration), undefined); assert.compareArray(values, [ 0, 2, @@ -76,7 +76,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.find.call(lengthTrackingWithOffset, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.find.call(lengthTrackingWithOffset, ResizeMidIteration), undefined); assert.compareArray(values, [ 4, 6 diff --git a/test/built-ins/Array/prototype/findIndex/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/findIndex/resizable-buffer-grow-mid-iteration.js index 587f874640..4833103f71 100644 --- a/test/built-ins/Array/prototype/findIndex/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/Array/prototype/findIndex/resizable-buffer-grow-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findIndex.call(fixedLength, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findIndex.call(fixedLength, ResizeMidIteration), -1); assert.compareArray(values, [ 0, 2, @@ -49,7 +49,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findIndex.call(fixedLengthWithOffset, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findIndex.call(fixedLengthWithOffset, ResizeMidIteration), -1); assert.compareArray(values, [ 4, 6 @@ -61,7 +61,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findIndex.call(lengthTracking, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findIndex.call(lengthTracking, ResizeMidIteration), -1); assert.compareArray(values, [ 0, 2, @@ -75,7 +75,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findIndex.call(lengthTrackingWithOffset, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findIndex.call(lengthTrackingWithOffset, ResizeMidIteration), -1); assert.compareArray(values, [ 4, 6 diff --git a/test/built-ins/Array/prototype/findIndex/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/Array/prototype/findIndex/resizable-buffer-shrink-mid-iteration.js index d24f825c7c..ace51c60e1 100644 --- a/test/built-ins/Array/prototype/findIndex/resizable-buffer-shrink-mid-iteration.js +++ b/test/built-ins/Array/prototype/findIndex/resizable-buffer-shrink-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findIndex.call(fixedLength, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findIndex.call(fixedLength, ResizeMidIteration), -1); assert.compareArray(values, [ 0, 2, @@ -49,7 +49,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findIndex.call(fixedLengthWithOffset, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findIndex.call(fixedLengthWithOffset, ResizeMidIteration), -1); assert.compareArray(values, [ 4, undefined @@ -61,7 +61,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findIndex.call(lengthTracking, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findIndex.call(lengthTracking, ResizeMidIteration), -1); assert.compareArray(values, [ 0, 2, @@ -75,7 +75,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findIndex.call(lengthTrackingWithOffset, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findIndex.call(lengthTrackingWithOffset, ResizeMidIteration), -1); assert.compareArray(values, [ 4, undefined diff --git a/test/built-ins/Array/prototype/findLast/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/findLast/resizable-buffer-grow-mid-iteration.js index d2b63ecab6..4244a317c0 100644 --- a/test/built-ins/Array/prototype/findLast/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/Array/prototype/findLast/resizable-buffer-grow-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLast.call(fixedLength, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.findLast.call(fixedLength, ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4, @@ -49,7 +49,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLast.call(fixedLengthWithOffset, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.findLast.call(fixedLengthWithOffset, ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4 @@ -61,7 +61,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLast.call(lengthTracking, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.findLast.call(lengthTracking, ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4, @@ -75,7 +75,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLast.call(lengthTrackingWithOffset, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.findLast.call(lengthTrackingWithOffset, ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4 diff --git a/test/built-ins/Array/prototype/findLast/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/Array/prototype/findLast/resizable-buffer-shrink-mid-iteration.js index 6c27e7cb09..2f00ad2061 100644 --- a/test/built-ins/Array/prototype/findLast/resizable-buffer-shrink-mid-iteration.js +++ b/test/built-ins/Array/prototype/findLast/resizable-buffer-shrink-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -36,7 +36,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLast.call(fixedLength, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.findLast.call(fixedLength, ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4, @@ -50,7 +50,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLast.call(fixedLengthWithOffset, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.findLast.call(fixedLengthWithOffset, ResizeMidIteration), undefined); assert.compareArray(values, [ 6, undefined @@ -62,7 +62,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLast.call(lengthTracking, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.findLast.call(lengthTracking, ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4, @@ -76,7 +76,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLast.call(lengthTrackingWithOffset, ResizeBufferMidIteration), undefined); + assert.sameValue(Array.prototype.findLast.call(lengthTrackingWithOffset, ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4 diff --git a/test/built-ins/Array/prototype/findLastIndex/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/findLastIndex/resizable-buffer-grow-mid-iteration.js index 7c8e1c873c..3de0da3c5e 100644 --- a/test/built-ins/Array/prototype/findLastIndex/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/Array/prototype/findLastIndex/resizable-buffer-grow-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLastIndex.call(fixedLength, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findLastIndex.call(fixedLength, ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4, @@ -49,7 +49,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLastIndex.call(fixedLengthWithOffset, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findLastIndex.call(fixedLengthWithOffset, ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4 @@ -61,7 +61,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLastIndex.call(lengthTracking, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findLastIndex.call(lengthTracking, ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4, @@ -75,7 +75,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLastIndex.call(lengthTrackingWithOffset, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findLastIndex.call(lengthTrackingWithOffset, ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4 diff --git a/test/built-ins/Array/prototype/findLastIndex/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/Array/prototype/findLastIndex/resizable-buffer-shrink-mid-iteration.js index 0823629c90..918454c40b 100644 --- a/test/built-ins/Array/prototype/findLastIndex/resizable-buffer-shrink-mid-iteration.js +++ b/test/built-ins/Array/prototype/findLastIndex/resizable-buffer-shrink-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLastIndex.call(fixedLength, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findLastIndex.call(fixedLength, ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4, @@ -49,7 +49,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLastIndex.call(fixedLengthWithOffset, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findLastIndex.call(fixedLengthWithOffset, ResizeMidIteration), -1); assert.compareArray(values, [ 6, undefined @@ -61,7 +61,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLastIndex.call(lengthTracking, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findLastIndex.call(lengthTracking, ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4, @@ -75,7 +75,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 2 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLastIndex.call(lengthTracking, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findLastIndex.call(lengthTracking, ResizeMidIteration), -1); assert.compareArray(values, [ 6, undefined, @@ -89,7 +89,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(Array.prototype.findLastIndex.call(lengthTrackingWithOffset, ResizeBufferMidIteration), -1); + assert.sameValue(Array.prototype.findLastIndex.call(lengthTrackingWithOffset, ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4 diff --git a/test/built-ins/TypedArray/prototype/every/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/every/resizable-buffer-grow-mid-iteration.js index e588f165be..9427d5f1fc 100644 --- a/test/built-ins/TypedArray/prototype/every/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/every/resizable-buffer-grow-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset // before calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { // Returns true by default. return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert(fixedLength.every(ResizeBufferMidIteration)); + assert(fixedLength.every(ResizeMidIteration)); assert.compareArray(values, [ 0, 2, @@ -49,7 +49,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert(fixedLengthWithOffset.every(ResizeBufferMidIteration)); + assert(fixedLengthWithOffset.every(ResizeMidIteration)); assert.compareArray(values, [ 4, 6 @@ -61,7 +61,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert(lengthTracking.every(ResizeBufferMidIteration)); + assert(lengthTracking.every(ResizeMidIteration)); assert.compareArray(values, [ 0, 2, @@ -75,7 +75,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert(lengthTrackingWithOffset.every(ResizeBufferMidIteration)); + assert(lengthTrackingWithOffset.every(ResizeMidIteration)); assert.compareArray(values, [ 4, 6 diff --git a/test/built-ins/TypedArray/prototype/every/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/every/resizable-buffer-shrink-mid-iteration.js index b677ae1db8..889d56f193 100644 --- a/test/built-ins/TypedArray/prototype/every/resizable-buffer-shrink-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/every/resizable-buffer-shrink-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset // before calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { // Returns true by default. return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert(fixedLength.every(ResizeBufferMidIteration)); + assert(fixedLength.every(ResizeMidIteration)); assert.compareArray(values, [ 0, 2, @@ -49,7 +49,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert(fixedLengthWithOffset.every(ResizeBufferMidIteration)); + assert(fixedLengthWithOffset.every(ResizeMidIteration)); assert.compareArray(values, [ 4, undefined @@ -61,7 +61,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert(lengthTracking.every(ResizeBufferMidIteration)); + assert(lengthTracking.every(ResizeMidIteration)); assert.compareArray(values, [ 0, 2, @@ -75,7 +75,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert(lengthTrackingWithOffset.every(ResizeBufferMidIteration)); + assert(lengthTrackingWithOffset.every(ResizeMidIteration)); assert.compareArray(values, [ 4, undefined diff --git a/test/built-ins/TypedArray/prototype/find/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/find/resizable-buffer-grow-mid-iteration.js index d1a148f91c..c68659605c 100644 --- a/test/built-ins/TypedArray/prototype/find/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/find/resizable-buffer-grow-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -36,7 +36,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLength.find(ResizeBufferMidIteration), undefined); + assert.sameValue(fixedLength.find(ResizeMidIteration), undefined); assert.compareArray(values, [ 0, 2, @@ -50,7 +50,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLengthWithOffset.find(ResizeBufferMidIteration), undefined); + assert.sameValue(fixedLengthWithOffset.find(ResizeMidIteration), undefined); assert.compareArray(values, [ 4, 6 @@ -62,7 +62,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTracking.find(ResizeBufferMidIteration), undefined); + assert.sameValue(lengthTracking.find(ResizeMidIteration), undefined); assert.compareArray(values, [ 0, 2, @@ -76,7 +76,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTrackingWithOffset.find(ResizeBufferMidIteration), undefined); + assert.sameValue(lengthTrackingWithOffset.find(ResizeMidIteration), undefined); assert.compareArray(values, [ 4, 6 diff --git a/test/built-ins/TypedArray/prototype/find/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/find/resizable-buffer-shrink-mid-iteration.js index 5fa0823d73..57adb7eddc 100644 --- a/test/built-ins/TypedArray/prototype/find/resizable-buffer-shrink-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/find/resizable-buffer-shrink-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -36,7 +36,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLength.find(ResizeBufferMidIteration), undefined); + assert.sameValue(fixedLength.find(ResizeMidIteration), undefined); assert.compareArray(values, [ 0, 2, @@ -50,7 +50,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLengthWithOffset.find(ResizeBufferMidIteration), undefined); + assert.sameValue(fixedLengthWithOffset.find(ResizeMidIteration), undefined); assert.compareArray(values, [ 4, undefined @@ -62,7 +62,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTracking.find(ResizeBufferMidIteration), undefined); + assert.sameValue(lengthTracking.find(ResizeMidIteration), undefined); assert.compareArray(values, [ 0, 2, @@ -76,7 +76,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTrackingWithOffset.find(ResizeBufferMidIteration), undefined); + assert.sameValue(lengthTrackingWithOffset.find(ResizeMidIteration), undefined); assert.compareArray(values, [ 4, undefined diff --git a/test/built-ins/TypedArray/prototype/findIndex/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/findIndex/resizable-buffer-grow-mid-iteration.js index 505578bc19..a1753720e8 100644 --- a/test/built-ins/TypedArray/prototype/findIndex/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/findIndex/resizable-buffer-grow-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -36,7 +36,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLength.findIndex(ResizeBufferMidIteration), -1); + assert.sameValue(fixedLength.findIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 0, 2, @@ -50,7 +50,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLengthWithOffset.findIndex(ResizeBufferMidIteration), -1); + assert.sameValue(fixedLengthWithOffset.findIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 4, 6 @@ -62,7 +62,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTracking.findIndex(ResizeBufferMidIteration), -1); + assert.sameValue(lengthTracking.findIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 0, 2, @@ -76,7 +76,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTrackingWithOffset.findIndex(ResizeBufferMidIteration), -1); + assert.sameValue(lengthTrackingWithOffset.findIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 4, 6 diff --git a/test/built-ins/TypedArray/prototype/findIndex/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/findIndex/resizable-buffer-shrink-mid-iteration.js index 1601e2a59b..21e47be0ce 100644 --- a/test/built-ins/TypedArray/prototype/findIndex/resizable-buffer-shrink-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/findIndex/resizable-buffer-shrink-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -36,7 +36,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLength.findIndex(ResizeBufferMidIteration), -1); + assert.sameValue(fixedLength.findIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 0, 2, @@ -50,7 +50,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLengthWithOffset.findIndex(ResizeBufferMidIteration), -1); + assert.sameValue(fixedLengthWithOffset.findIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 4, undefined @@ -62,7 +62,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTracking.findIndex(ResizeBufferMidIteration), -1); + assert.sameValue(lengthTracking.findIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 0, 2, @@ -76,7 +76,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTrackingWithOffset.findIndex(ResizeBufferMidIteration), -1); + assert.sameValue(lengthTrackingWithOffset.findIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 4, undefined diff --git a/test/built-ins/TypedArray/prototype/findLast/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/findLast/resizable-buffer-grow-mid-iteration.js index 87fe0cc24e..756d48236c 100644 --- a/test/built-ins/TypedArray/prototype/findLast/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/findLast/resizable-buffer-grow-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLength.findLast(ResizeBufferMidIteration), undefined); + assert.sameValue(fixedLength.findLast(ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4, @@ -49,7 +49,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLengthWithOffset.findLast(ResizeBufferMidIteration), undefined); + assert.sameValue(fixedLengthWithOffset.findLast(ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4 @@ -61,7 +61,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTracking.findLast(ResizeBufferMidIteration), undefined); + assert.sameValue(lengthTracking.findLast(ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4, @@ -75,7 +75,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTrackingWithOffset.findLast(ResizeBufferMidIteration), undefined); + assert.sameValue(lengthTrackingWithOffset.findLast(ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4 diff --git a/test/built-ins/TypedArray/prototype/findLast/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/findLast/resizable-buffer-shrink-mid-iteration.js index 0bbe4c4d74..fffdfe55bc 100644 --- a/test/built-ins/TypedArray/prototype/findLast/resizable-buffer-shrink-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/findLast/resizable-buffer-shrink-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -36,7 +36,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLength.findLast(ResizeBufferMidIteration), undefined); + assert.sameValue(fixedLength.findLast(ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4, @@ -50,7 +50,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLengthWithOffset.findLast(ResizeBufferMidIteration), undefined); + assert.sameValue(fixedLengthWithOffset.findLast(ResizeMidIteration), undefined); assert.compareArray(values, [ 6, undefined @@ -62,7 +62,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTracking.findLast(ResizeBufferMidIteration), undefined); + assert.sameValue(lengthTracking.findLast(ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4, @@ -76,7 +76,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTrackingWithOffset.findLast(ResizeBufferMidIteration), undefined); + assert.sameValue(lengthTrackingWithOffset.findLast(ResizeMidIteration), undefined); assert.compareArray(values, [ 6, 4 diff --git a/test/built-ins/TypedArray/prototype/findLastIndex/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/findLastIndex/resizable-buffer-grow-mid-iteration.js index b8d2f75474..964fdb6865 100644 --- a/test/built-ins/TypedArray/prototype/findLastIndex/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/findLastIndex/resizable-buffer-grow-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLength.findLastIndex(ResizeBufferMidIteration), -1); + assert.sameValue(fixedLength.findLastIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4, @@ -49,7 +49,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLengthWithOffset.findLastIndex(ResizeBufferMidIteration), -1); + assert.sameValue(fixedLengthWithOffset.findLastIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4 @@ -61,7 +61,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTracking.findLastIndex(ResizeBufferMidIteration), -1); + assert.sameValue(lengthTracking.findLastIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4, @@ -75,7 +75,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 5 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTrackingWithOffset.findLastIndex(ResizeBufferMidIteration), -1); + assert.sameValue(lengthTrackingWithOffset.findLastIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4 diff --git a/test/built-ins/TypedArray/prototype/findLastIndex/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/findLastIndex/resizable-buffer-shrink-mid-iteration.js index 409c12f23b..c216f34267 100644 --- a/test/built-ins/TypedArray/prototype/findLastIndex/resizable-buffer-shrink-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/findLastIndex/resizable-buffer-shrink-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset before // calling this. -function ResizeBufferMidIteration(n) { +function ResizeMidIteration(n) { CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); return false; } @@ -35,7 +35,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLength.findLastIndex(ResizeBufferMidIteration), -1); + assert.sameValue(fixedLength.findLastIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4, @@ -49,7 +49,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(fixedLengthWithOffset.findLastIndex(ResizeBufferMidIteration), -1); + assert.sameValue(fixedLengthWithOffset.findLastIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 6, undefined @@ -61,7 +61,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 2; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTracking.findLastIndex(ResizeBufferMidIteration), -1); + assert.sameValue(lengthTracking.findLastIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4, @@ -75,7 +75,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 2 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTracking.findLastIndex(ResizeBufferMidIteration), -1); + assert.sameValue(lengthTracking.findLastIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 6, undefined, @@ -89,7 +89,7 @@ for (let ctor of ctors) { values = []; resizeAfter = 1; resizeTo = 3 * ctor.BYTES_PER_ELEMENT; - assert.sameValue(lengthTrackingWithOffset.findLastIndex(ResizeBufferMidIteration), -1); + assert.sameValue(lengthTrackingWithOffset.findLastIndex(ResizeMidIteration), -1); assert.compareArray(values, [ 6, 4 From 14de2ce38848f1ffbb0f631d1ef872e6fa2eb2e9 Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Sat, 29 Jun 2024 01:40:39 +0200 Subject: [PATCH 08/90] Import relevant files from #3888 --- .../coerced-searchelement-fromindex-resize.js | 134 +++++++++++++ .../prototype/includes/resizable-buffer.js | 168 ++++++++++++++++ .../coerced-searchelement-fromindex-resize.js | 134 +++++++++++++ .../resizable-buffer-special-float-values.js | 34 ++++ .../prototype/includes/resizable-buffer.js | 183 ++++++++++++++++++ 5 files changed, 653 insertions(+) create mode 100644 test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js create mode 100644 test/built-ins/Array/prototype/includes/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js create mode 100644 test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js create mode 100644 test/built-ins/TypedArray/prototype/includes/resizable-buffer.js diff --git a/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js b/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js new file mode 100644 index 0000000000..2952b80d11 --- /dev/null +++ b/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js @@ -0,0 +1,134 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.includes +description: > + Array.p.includes behaves correctly when the receiver is resized during + argument coercion +features: [resizable-arraybuffer, Array.prototype.includes] +---*/ + +class MyUint8Array extends Uint8Array { +} + +class MyFloat32Array extends Float32Array { +} + +class MyBigInt64Array extends BigInt64Array { +} + +const builtinCtors = [ + Uint8Array, + Int8Array, + Uint16Array, + Int16Array, + Uint32Array, + Int32Array, + Float32Array, + Float64Array, + Uint8ClampedArray, + BigUint64Array, + BigInt64Array +]; + +const ctors = [ + ...builtinCtors, + MyUint8Array, + MyFloat32Array, + MyBigInt64Array +]; + +function CreateResizableArrayBuffer(byteLength, maxByteLength) { + return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); +} + +function WriteToTypedArray(array, index, value) { + if (array instanceof BigInt64Array || array instanceof BigUint64Array) { + array[index] = BigInt(value); + } else { + array[index] = value; + } +} + +function ArrayIncludesHelper(array, n, fromIndex) { + if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { + return Array.prototype.includes.call(array, BigInt(n), fromIndex); + } + return Array.prototype.includes.call(array, n, fromIndex); +} + +function IncludesParameterConversionResizes() { + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!ArrayIncludesHelper(fixedLength, undefined)); + // The TA is OOB so it includes only "undefined". + assert(ArrayIncludesHelper(fixedLength, undefined, evil)); + } + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(ArrayIncludesHelper(fixedLength, 0)); + // The TA is OOB so it includes only "undefined". + assert(!ArrayIncludesHelper(fixedLength, 0, evil)); + } + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!ArrayIncludesHelper(lengthTracking, undefined)); + // "includes" iterates until the original length and sees "undefined"s. + assert(ArrayIncludesHelper(lengthTracking, undefined, evil)); + } + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, 1); + } + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!ArrayIncludesHelper(lengthTracking, 0)); + // The TA grew but we only look at the data until the original length. + assert(!ArrayIncludesHelper(lengthTracking, 0, evil)); + } + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + WriteToTypedArray(lengthTracking, 0, 1); + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -4; + } + }; + assert(ArrayIncludesHelper(lengthTracking, 1, -4)); + // The TA grew but the start index conversion is done based on the original + // length. + assert(ArrayIncludesHelper(lengthTracking, 1, evil)); + } +} + +IncludesParameterConversionResizes(); diff --git a/test/built-ins/Array/prototype/includes/resizable-buffer.js b/test/built-ins/Array/prototype/includes/resizable-buffer.js new file mode 100644 index 0000000000..bd8f6d93c7 --- /dev/null +++ b/test/built-ins/Array/prototype/includes/resizable-buffer.js @@ -0,0 +1,168 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.includes +description: > + Array.p.includes behaves correctly when receiver is backed by resizable + buffer +features: [resizable-arraybuffer, Array.prototype.includes] +---*/ + +class MyUint8Array extends Uint8Array { +} + +class MyFloat32Array extends Float32Array { +} + +class MyBigInt64Array extends BigInt64Array { +} + +const builtinCtors = [ + Uint8Array, + Int8Array, + Uint16Array, + Int16Array, + Uint32Array, + Int32Array, + Float32Array, + Float64Array, + Uint8ClampedArray, + BigUint64Array, + BigInt64Array +]; + +const ctors = [ + ...builtinCtors, + MyUint8Array, + MyFloat32Array, + MyBigInt64Array +]; + +function CreateResizableArrayBuffer(byteLength, maxByteLength) { + return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); +} + +function WriteToTypedArray(array, index, value) { + if (array instanceof BigInt64Array || array instanceof BigUint64Array) { + array[index] = BigInt(value); + } else { + array[index] = value; + } +} + +function ArrayIncludesHelper(array, n, fromIndex) { + if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { + return Array.prototype.includes.call(array, BigInt(n), fromIndex); + } + return Array.prototype.includes.call(array, n, fromIndex); +} + +function TestIncludes() { + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert(ArrayIncludesHelper(fixedLength, 2)); + assert(!ArrayIncludesHelper(fixedLength, undefined)); + assert(ArrayIncludesHelper(fixedLength, 2, 1)); + assert(!ArrayIncludesHelper(fixedLength, 2, 2)); + assert(ArrayIncludesHelper(fixedLength, 2, -3)); + assert(!ArrayIncludesHelper(fixedLength, 2, -2)); + assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); + assert(ArrayIncludesHelper(fixedLengthWithOffset, 4)); + assert(!ArrayIncludesHelper(fixedLengthWithOffset, undefined)); + assert(ArrayIncludesHelper(fixedLengthWithOffset, 4, 0)); + assert(!ArrayIncludesHelper(fixedLengthWithOffset, 4, 1)); + assert(ArrayIncludesHelper(fixedLengthWithOffset, 4, -2)); + assert(!ArrayIncludesHelper(fixedLengthWithOffset, 4, -1)); + assert(ArrayIncludesHelper(lengthTracking, 2)); + assert(!ArrayIncludesHelper(lengthTracking, undefined)); + assert(ArrayIncludesHelper(lengthTracking, 2, 1)); + assert(!ArrayIncludesHelper(lengthTracking, 2, 2)); + assert(ArrayIncludesHelper(lengthTracking, 2, -3)); + assert(!ArrayIncludesHelper(lengthTracking, 2, -2)); + assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); + assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4)); + assert(!ArrayIncludesHelper(lengthTrackingWithOffset, undefined)); + assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4, 0)); + assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 4, 1)); + assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4, -2)); + assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 4, -1)); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert(!ArrayIncludesHelper(fixedLength, 2)); + assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); + + assert(ArrayIncludesHelper(lengthTracking, 2)); + assert(!ArrayIncludesHelper(lengthTracking, undefined)); + assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); + assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4)); + assert(!ArrayIncludesHelper(lengthTrackingWithOffset, undefined)); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert(!ArrayIncludesHelper(fixedLength, 2)); + assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); + assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); + + // Shrink to zero. + rab.resize(0); + assert(!ArrayIncludesHelper(fixedLength, 2)); + assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); + assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); + + assert(!ArrayIncludesHelper(lengthTracking, 2)); + assert(!ArrayIncludesHelper(lengthTracking, undefined)); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert(ArrayIncludesHelper(fixedLength, 2)); + assert(!ArrayIncludesHelper(fixedLength, undefined)); + assert(!ArrayIncludesHelper(fixedLength, 8)); + assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); + assert(ArrayIncludesHelper(fixedLengthWithOffset, 4)); + assert(!ArrayIncludesHelper(fixedLengthWithOffset, undefined)); + assert(!ArrayIncludesHelper(fixedLengthWithOffset, 8)); + assert(ArrayIncludesHelper(lengthTracking, 2)); + assert(!ArrayIncludesHelper(lengthTracking, undefined)); + assert(ArrayIncludesHelper(lengthTracking, 8)); + assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); + assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4)); + assert(!ArrayIncludesHelper(lengthTrackingWithOffset, undefined)); + assert(ArrayIncludesHelper(lengthTrackingWithOffset, 8)); + } +} + +TestIncludes(); diff --git a/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js b/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js new file mode 100644 index 0000000000..8daa449fc3 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js @@ -0,0 +1,134 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.includes +description: > + TypedArray.p.includes behaves correctly when the receiver is resized during + argument coercion +features: [resizable-arraybuffer, Array.prototype.includes] +---*/ + +class MyUint8Array extends Uint8Array { +} + +class MyFloat32Array extends Float32Array { +} + +class MyBigInt64Array extends BigInt64Array { +} + +const builtinCtors = [ + Uint8Array, + Int8Array, + Uint16Array, + Int16Array, + Uint32Array, + Int32Array, + Float32Array, + Float64Array, + Uint8ClampedArray, + BigUint64Array, + BigInt64Array +]; + +const ctors = [ + ...builtinCtors, + MyUint8Array, + MyFloat32Array, + MyBigInt64Array +]; + +function CreateResizableArrayBuffer(byteLength, maxByteLength) { + return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); +} + +function WriteToTypedArray(array, index, value) { + if (array instanceof BigInt64Array || array instanceof BigUint64Array) { + array[index] = BigInt(value); + } else { + array[index] = value; + } +} + +function TypedArrayIncludesHelper(array, n, fromIndex) { + if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { + return array.includes(BigInt(n), fromIndex); + } + return array.includes(n, fromIndex); +} + +function IncludesParameterConversionResizes() { + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!TypedArrayIncludesHelper(fixedLength, undefined)); + // The TA is OOB so it includes only "undefined". + assert(TypedArrayIncludesHelper(fixedLength, undefined, evil)); + } + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(TypedArrayIncludesHelper(fixedLength, 0)); + // The TA is OOB so it includes only "undefined". + assert(!TypedArrayIncludesHelper(fixedLength, 0, evil)); + } + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); + // "includes" iterates until the original length and sees "undefined"s. + assert(TypedArrayIncludesHelper(lengthTracking, undefined, evil)); + } + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, 1); + } + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!TypedArrayIncludesHelper(lengthTracking, 0)); + // The TA grew but we only look at the data until the original length. + assert(!TypedArrayIncludesHelper(lengthTracking, 0, evil)); + } + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + WriteToTypedArray(lengthTracking, 0, 1); + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -4; + } + }; + assert(TypedArrayIncludesHelper(lengthTracking, 1, -4)); + // The TA grew but the start index conversion is done based on the original + // length. + assert(TypedArrayIncludesHelper(lengthTracking, 1, evil)); + } +} + +IncludesParameterConversionResizes(); diff --git a/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js b/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js new file mode 100644 index 0000000000..19d4b9c4e9 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js @@ -0,0 +1,34 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.includes +description: > + TypedArray.p.includes behaves correctly for special float values when + receiver is a float TypedArray backed by a resizable buffer +features: [resizable-arraybuffer, Array.prototype.includes] +---*/ + +class MyFloat32Array extends Float32Array { +} + +const floatCtors = [ + Float32Array, + Float64Array, + MyFloat32Array +]; + +function CreateResizableArrayBuffer(byteLength, maxByteLength) { + return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); +} + +for (let ctor of floatCtors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + lengthTracking[0] = -Infinity; + lengthTracking[1] = Infinity; + lengthTracking[2] = NaN; + assert(lengthTracking.includes(-Infinity)); + assert(lengthTracking.includes(Infinity)); + assert(lengthTracking.includes(NaN)); +} diff --git a/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js b/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js new file mode 100644 index 0000000000..284e527682 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js @@ -0,0 +1,183 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.includes +description: > + TypedArray.p.includes behaves correctly when receiver is backed by resizable + buffer +features: [resizable-arraybuffer, Array.prototype.includes] +---*/ + +class MyUint8Array extends Uint8Array { +} + +class MyFloat32Array extends Float32Array { +} + +class MyBigInt64Array extends BigInt64Array { +} + +const builtinCtors = [ + Uint8Array, + Int8Array, + Uint16Array, + Int16Array, + Uint32Array, + Int32Array, + Float32Array, + Float64Array, + Uint8ClampedArray, + BigUint64Array, + BigInt64Array +]; + +const ctors = [ + ...builtinCtors, + MyUint8Array, + MyFloat32Array, + MyBigInt64Array +]; + +function CreateResizableArrayBuffer(byteLength, maxByteLength) { + return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); +} + +function WriteToTypedArray(array, index, value) { + if (array instanceof BigInt64Array || array instanceof BigUint64Array) { + array[index] = BigInt(value); + } else { + array[index] = value; + } +} + +function TypedArrayIncludesHelper(array, n, fromIndex) { + if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { + return array.includes(BigInt(n), fromIndex); + } + return array.includes(n, fromIndex); +} + +function TestIncludes() { + for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert(TypedArrayIncludesHelper(fixedLength, 2)); + assert(!TypedArrayIncludesHelper(fixedLength, undefined)); + assert(TypedArrayIncludesHelper(fixedLength, 2, 1)); + assert(!TypedArrayIncludesHelper(fixedLength, 2, 2)); + assert(TypedArrayIncludesHelper(fixedLength, 2, -3)); + assert(!TypedArrayIncludesHelper(fixedLength, 2, -2)); + assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 2)); + assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4)); + assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, undefined)); + assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4, 0)); + assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 4, 1)); + assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4, -2)); + assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 4, -1)); + assert(TypedArrayIncludesHelper(lengthTracking, 2)); + assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); + assert(TypedArrayIncludesHelper(lengthTracking, 2, 1)); + assert(!TypedArrayIncludesHelper(lengthTracking, 2, 2)); + assert(TypedArrayIncludesHelper(lengthTracking, 2, -3)); + assert(!TypedArrayIncludesHelper(lengthTracking, 2, -2)); + assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 2)); + assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4)); + assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, undefined)); + assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, 0)); + assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, 1)); + assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, -2)); + assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, -1)); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + TypedArrayIncludesHelper(fixedLength, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesHelper(fixedLengthWithOffset, 2); + }); + + assert(TypedArrayIncludesHelper(lengthTracking, 2)); + assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); + assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 2)); + assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4)); + assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, undefined)); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + TypedArrayIncludesHelper(fixedLength, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesHelper(fixedLengthWithOffset, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesHelper(lengthTrackingWithOffset, 2); + }); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + TypedArrayIncludesHelper(fixedLength, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesHelper(fixedLengthWithOffset, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesHelper(lengthTrackingWithOffset, 2); + }); + assert(!TypedArrayIncludesHelper(lengthTracking, 2)); + assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert(TypedArrayIncludesHelper(fixedLength, 2)); + assert(!TypedArrayIncludesHelper(fixedLength, undefined)); + assert(!TypedArrayIncludesHelper(fixedLength, 8)); + assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 2)); + assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4)); + assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, undefined)); + assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 8)); + assert(TypedArrayIncludesHelper(lengthTracking, 2)); + assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); + assert(TypedArrayIncludesHelper(lengthTracking, 8)); + assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 2)); + assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4)); + assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, undefined)); + assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 8)); + } +} + +TestIncludes(); From 3dde047c84e1bec24dde4b2c862ff2b6c6dd0948 Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Sat, 29 Jun 2024 01:40:39 +0200 Subject: [PATCH 09/90] Removing parts in resizableArrayBufferUtils.js and adding it in includes, while applying review changes from PRs for previously tested methods. --- .../coerced-searchelement-fromindex-resize.js | 185 +++++------- .../prototype/includes/resizable-buffer.js | 251 +++++++--------- .../coerced-searchelement-fromindex-resize.js | 185 +++++------- .../resizable-buffer-special-float-values.js | 14 +- .../prototype/includes/resizable-buffer.js | 281 ++++++++---------- 5 files changed, 362 insertions(+), 554 deletions(-) diff --git a/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js b/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js index 2952b80d11..448709b5af 100644 --- a/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js +++ b/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js @@ -6,129 +6,84 @@ esid: sec-array.prototype.includes description: > Array.p.includes behaves correctly when the receiver is resized during argument coercion +includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -class MyUint8Array extends Uint8Array { -} - -class MyFloat32Array extends Float32Array { -} - -class MyBigInt64Array extends BigInt64Array { -} - -const builtinCtors = [ - Uint8Array, - Int8Array, - Uint16Array, - Int16Array, - Uint32Array, - Int32Array, - Float32Array, - Float64Array, - Uint8ClampedArray, - BigUint64Array, - BigInt64Array -]; - -const ctors = [ - ...builtinCtors, - MyUint8Array, - MyFloat32Array, - MyBigInt64Array -]; - -function CreateResizableArrayBuffer(byteLength, maxByteLength) { - return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); -} - -function WriteToTypedArray(array, index, value) { - if (array instanceof BigInt64Array || array instanceof BigUint64Array) { - array[index] = BigInt(value); - } else { - array[index] = value; - } -} - -function ArrayIncludesHelper(array, n, fromIndex) { +function ArrayIncludesNumOrBigInt(array, n, fromIndex) { if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { return Array.prototype.includes.call(array, BigInt(n), fromIndex); } return Array.prototype.includes.call(array, n, fromIndex); } -function IncludesParameterConversionResizes() { - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const fixedLength = new ctor(rab, 0, 4); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!ArrayIncludesHelper(fixedLength, undefined)); - // The TA is OOB so it includes only "undefined". - assert(ArrayIncludesHelper(fixedLength, undefined, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const fixedLength = new ctor(rab, 0, 4); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(ArrayIncludesHelper(fixedLength, 0)); - // The TA is OOB so it includes only "undefined". - assert(!ArrayIncludesHelper(fixedLength, 0, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const lengthTracking = new ctor(rab); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!ArrayIncludesHelper(lengthTracking, undefined)); - // "includes" iterates until the original length and sees "undefined"s. - assert(ArrayIncludesHelper(lengthTracking, undefined, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const lengthTracking = new ctor(rab); - for (let i = 0; i < 4; ++i) { - WriteToTypedArray(lengthTracking, i, 1); +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; } - let evil = { - valueOf: () => { - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!ArrayIncludesHelper(lengthTracking, 0)); - // The TA grew but we only look at the data until the original length. - assert(!ArrayIncludesHelper(lengthTracking, 0, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const lengthTracking = new ctor(rab); - WriteToTypedArray(lengthTracking, 0, 1); - let evil = { - valueOf: () => { - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - return -4; - } - }; - assert(ArrayIncludesHelper(lengthTracking, 1, -4)); - // The TA grew but the start index conversion is done based on the original - // length. - assert(ArrayIncludesHelper(lengthTracking, 1, evil)); - } + }; + assert(!ArrayIncludesNumOrBigInt(fixedLength, undefined)); + // The TA is OOB so it includes only "undefined". + assert(ArrayIncludesNumOrBigInt(fixedLength, undefined, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(ArrayIncludesNumOrBigInt(fixedLength, 0)); + // The TA is OOB so it includes only "undefined". + assert(!ArrayIncludesNumOrBigInt(fixedLength, 0, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + // "includes" iterates until the original length and sees "undefined"s. + assert(ArrayIncludesNumOrBigInt(lengthTracking, undefined, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, 1); + } + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!ArrayIncludesNumOrBigInt(lengthTracking, 0)); + // The TA grew but we only look at the data until the original length. + assert(!ArrayIncludesNumOrBigInt(lengthTracking, 0, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + WriteToTypedArray(lengthTracking, 0, 1); + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -4; + } + }; + assert(ArrayIncludesNumOrBigInt(lengthTracking, 1, -4)); + // The TA grew but the start index conversion is done based on the original + // length. + assert(ArrayIncludesNumOrBigInt(lengthTracking, 1, evil)); } - -IncludesParameterConversionResizes(); diff --git a/test/built-ins/Array/prototype/includes/resizable-buffer.js b/test/built-ins/Array/prototype/includes/resizable-buffer.js index bd8f6d93c7..49894ef40b 100644 --- a/test/built-ins/Array/prototype/includes/resizable-buffer.js +++ b/test/built-ins/Array/prototype/includes/resizable-buffer.js @@ -6,163 +6,118 @@ esid: sec-array.prototype.includes description: > Array.p.includes behaves correctly when receiver is backed by resizable buffer +includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -class MyUint8Array extends Uint8Array { -} - -class MyFloat32Array extends Float32Array { -} - -class MyBigInt64Array extends BigInt64Array { -} - -const builtinCtors = [ - Uint8Array, - Int8Array, - Uint16Array, - Int16Array, - Uint32Array, - Int32Array, - Float32Array, - Float64Array, - Uint8ClampedArray, - BigUint64Array, - BigInt64Array -]; - -const ctors = [ - ...builtinCtors, - MyUint8Array, - MyFloat32Array, - MyBigInt64Array -]; - -function CreateResizableArrayBuffer(byteLength, maxByteLength) { - return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); -} - -function WriteToTypedArray(array, index, value) { - if (array instanceof BigInt64Array || array instanceof BigUint64Array) { - array[index] = BigInt(value); - } else { - array[index] = value; - } -} - -function ArrayIncludesHelper(array, n, fromIndex) { +function ArrayIncludesNumOrBigInt(array, n, fromIndex) { if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { return Array.prototype.includes.call(array, BigInt(n), fromIndex); } return Array.prototype.includes.call(array, n, fromIndex); } -function TestIncludes() { - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const fixedLength = new ctor(rab, 0, 4); - const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); - const lengthTracking = new ctor(rab, 0); - const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); - // Write some data into the array. - const taWrite = new ctor(rab); - for (let i = 0; i < 4; ++i) { - WriteToTypedArray(taWrite, i, 2 * i); - } - - // Orig. array: [0, 2, 4, 6] - // [0, 2, 4, 6] << fixedLength - // [4, 6] << fixedLengthWithOffset - // [0, 2, 4, 6, ...] << lengthTracking - // [4, 6, ...] << lengthTrackingWithOffset - - assert(ArrayIncludesHelper(fixedLength, 2)); - assert(!ArrayIncludesHelper(fixedLength, undefined)); - assert(ArrayIncludesHelper(fixedLength, 2, 1)); - assert(!ArrayIncludesHelper(fixedLength, 2, 2)); - assert(ArrayIncludesHelper(fixedLength, 2, -3)); - assert(!ArrayIncludesHelper(fixedLength, 2, -2)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(ArrayIncludesHelper(fixedLengthWithOffset, 4)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, undefined)); - assert(ArrayIncludesHelper(fixedLengthWithOffset, 4, 0)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 4, 1)); - assert(ArrayIncludesHelper(fixedLengthWithOffset, 4, -2)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 4, -1)); - assert(ArrayIncludesHelper(lengthTracking, 2)); - assert(!ArrayIncludesHelper(lengthTracking, undefined)); - assert(ArrayIncludesHelper(lengthTracking, 2, 1)); - assert(!ArrayIncludesHelper(lengthTracking, 2, 2)); - assert(ArrayIncludesHelper(lengthTracking, 2, -3)); - assert(!ArrayIncludesHelper(lengthTracking, 2, -2)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4, 0)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 4, 1)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4, -2)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 4, -1)); - - // Shrink so that fixed length TAs go out of bounds. - rab.resize(3 * ctor.BYTES_PER_ELEMENT); - - // Orig. array: [0, 2, 4] - // [0, 2, 4, ...] << lengthTracking - // [4, ...] << lengthTrackingWithOffset - - assert(!ArrayIncludesHelper(fixedLength, 2)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); - - assert(ArrayIncludesHelper(lengthTracking, 2)); - assert(!ArrayIncludesHelper(lengthTracking, undefined)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - - // Shrink so that the TAs with offset go out of bounds. - rab.resize(1 * ctor.BYTES_PER_ELEMENT); - assert(!ArrayIncludesHelper(fixedLength, 2)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); - - // Shrink to zero. - rab.resize(0); - assert(!ArrayIncludesHelper(fixedLength, 2)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); - - assert(!ArrayIncludesHelper(lengthTracking, 2)); - assert(!ArrayIncludesHelper(lengthTracking, undefined)); - - // Grow so that all TAs are back in-bounds. - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - for (let i = 0; i < 6; ++i) { - WriteToTypedArray(taWrite, i, 2 * i); - } - - // Orig. array: [0, 2, 4, 6, 8, 10] - // [0, 2, 4, 6] << fixedLength - // [4, 6] << fixedLengthWithOffset - // [0, 2, 4, 6, 8, 10, ...] << lengthTracking - // [4, 6, 8, 10, ...] << lengthTrackingWithOffset - - assert(ArrayIncludesHelper(fixedLength, 2)); - assert(!ArrayIncludesHelper(fixedLength, undefined)); - assert(!ArrayIncludesHelper(fixedLength, 8)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(ArrayIncludesHelper(fixedLengthWithOffset, 4)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, undefined)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 8)); - assert(ArrayIncludesHelper(lengthTracking, 2)); - assert(!ArrayIncludesHelper(lengthTracking, undefined)); - assert(ArrayIncludesHelper(lengthTracking, 8)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 8)); + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); } -} -TestIncludes(); + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert(ArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!ArrayIncludesNumOrBigInt(fixedLength, undefined)); + assert(ArrayIncludesNumOrBigInt(fixedLength, 2, 1)); + assert(!ArrayIncludesNumOrBigInt(fixedLength, 2, 2)); + assert(ArrayIncludesNumOrBigInt(fixedLength, 2, -3)); + assert(!ArrayIncludesNumOrBigInt(fixedLength, 2, -2)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); + assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 0)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 1)); + assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -2)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -1)); + assert(ArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(ArrayIncludesNumOrBigInt(lengthTracking, 2, 1)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, 2, 2)); + assert(ArrayIncludesNumOrBigInt(lengthTracking, 2, -3)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, 2, -2)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 0)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 1)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -2)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -1)); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert(!ArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + + assert(ArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert(!ArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + + // Shrink to zero. + rab.resize(0); + assert(!ArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + + assert(!ArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert(ArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!ArrayIncludesNumOrBigInt(fixedLength, undefined)); + assert(!ArrayIncludesNumOrBigInt(fixedLength, 8)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 8)); + assert(ArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(ArrayIncludesNumOrBigInt(lengthTracking, 8)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 8)); +} diff --git a/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js b/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js index 8daa449fc3..63727c8cc5 100644 --- a/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js +++ b/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js @@ -6,129 +6,84 @@ esid: sec-%typedarray%.prototype.includes description: > TypedArray.p.includes behaves correctly when the receiver is resized during argument coercion +includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -class MyUint8Array extends Uint8Array { -} - -class MyFloat32Array extends Float32Array { -} - -class MyBigInt64Array extends BigInt64Array { -} - -const builtinCtors = [ - Uint8Array, - Int8Array, - Uint16Array, - Int16Array, - Uint32Array, - Int32Array, - Float32Array, - Float64Array, - Uint8ClampedArray, - BigUint64Array, - BigInt64Array -]; - -const ctors = [ - ...builtinCtors, - MyUint8Array, - MyFloat32Array, - MyBigInt64Array -]; - -function CreateResizableArrayBuffer(byteLength, maxByteLength) { - return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); -} - -function WriteToTypedArray(array, index, value) { - if (array instanceof BigInt64Array || array instanceof BigUint64Array) { - array[index] = BigInt(value); - } else { - array[index] = value; - } -} - -function TypedArrayIncludesHelper(array, n, fromIndex) { +function TypedArrayIncludesNumOrBigInt(array, n, fromIndex) { if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { return array.includes(BigInt(n), fromIndex); } return array.includes(n, fromIndex); } -function IncludesParameterConversionResizes() { - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const fixedLength = new ctor(rab, 0, 4); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!TypedArrayIncludesHelper(fixedLength, undefined)); - // The TA is OOB so it includes only "undefined". - assert(TypedArrayIncludesHelper(fixedLength, undefined, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const fixedLength = new ctor(rab, 0, 4); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(TypedArrayIncludesHelper(fixedLength, 0)); - // The TA is OOB so it includes only "undefined". - assert(!TypedArrayIncludesHelper(fixedLength, 0, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const lengthTracking = new ctor(rab); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); - // "includes" iterates until the original length and sees "undefined"s. - assert(TypedArrayIncludesHelper(lengthTracking, undefined, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const lengthTracking = new ctor(rab); - for (let i = 0; i < 4; ++i) { - WriteToTypedArray(lengthTracking, i, 1); +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; } - let evil = { - valueOf: () => { - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!TypedArrayIncludesHelper(lengthTracking, 0)); - // The TA grew but we only look at the data until the original length. - assert(!TypedArrayIncludesHelper(lengthTracking, 0, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const lengthTracking = new ctor(rab); - WriteToTypedArray(lengthTracking, 0, 1); - let evil = { - valueOf: () => { - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - return -4; - } - }; - assert(TypedArrayIncludesHelper(lengthTracking, 1, -4)); - // The TA grew but the start index conversion is done based on the original - // length. - assert(TypedArrayIncludesHelper(lengthTracking, 1, evil)); - } + }; + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, undefined)); + // The TA is OOB so it includes only "undefined". + assert(TypedArrayIncludesNumOrBigInt(fixedLength, undefined, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(TypedArrayIncludesNumOrBigInt(fixedLength, 0)); + // The TA is OOB so it includes only "undefined". + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 0, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + // "includes" iterates until the original length and sees "undefined"s. + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, undefined, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, 1); + } + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 0)); + // The TA grew but we only look at the data until the original length. + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 0, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + WriteToTypedArray(lengthTracking, 0, 1); + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -4; + } + }; + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 1, -4)); + // The TA grew but the start index conversion is done based on the original + // length. + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 1, evil)); } - -IncludesParameterConversionResizes(); diff --git a/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js b/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js index 19d4b9c4e9..f621d95838 100644 --- a/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js +++ b/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js @@ -6,22 +6,10 @@ esid: sec-%typedarray%.prototype.includes description: > TypedArray.p.includes behaves correctly for special float values when receiver is a float TypedArray backed by a resizable buffer +includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -class MyFloat32Array extends Float32Array { -} - -const floatCtors = [ - Float32Array, - Float64Array, - MyFloat32Array -]; - -function CreateResizableArrayBuffer(byteLength, maxByteLength) { - return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); -} - for (let ctor of floatCtors) { const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); const lengthTracking = new ctor(rab); diff --git a/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js b/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js index 284e527682..77fa05960d 100644 --- a/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js +++ b/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js @@ -6,178 +6,133 @@ esid: sec-%typedarray%.prototype.includes description: > TypedArray.p.includes behaves correctly when receiver is backed by resizable buffer +includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -class MyUint8Array extends Uint8Array { -} - -class MyFloat32Array extends Float32Array { -} - -class MyBigInt64Array extends BigInt64Array { -} - -const builtinCtors = [ - Uint8Array, - Int8Array, - Uint16Array, - Int16Array, - Uint32Array, - Int32Array, - Float32Array, - Float64Array, - Uint8ClampedArray, - BigUint64Array, - BigInt64Array -]; - -const ctors = [ - ...builtinCtors, - MyUint8Array, - MyFloat32Array, - MyBigInt64Array -]; - -function CreateResizableArrayBuffer(byteLength, maxByteLength) { - return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); -} - -function WriteToTypedArray(array, index, value) { - if (array instanceof BigInt64Array || array instanceof BigUint64Array) { - array[index] = BigInt(value); - } else { - array[index] = value; - } -} - -function TypedArrayIncludesHelper(array, n, fromIndex) { +function TypedArrayIncludesNumOrBigInt(array, n, fromIndex) { if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { return array.includes(BigInt(n), fromIndex); } return array.includes(n, fromIndex); } -function TestIncludes() { - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const fixedLength = new ctor(rab, 0, 4); - const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); - const lengthTracking = new ctor(rab, 0); - const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); - // Write some data into the array. - const taWrite = new ctor(rab); - for (let i = 0; i < 4; ++i) { - WriteToTypedArray(taWrite, i, 2 * i); - } - - // Orig. array: [0, 2, 4, 6] - // [0, 2, 4, 6] << fixedLength - // [4, 6] << fixedLengthWithOffset - // [0, 2, 4, 6, ...] << lengthTracking - // [4, 6, ...] << lengthTrackingWithOffset - - assert(TypedArrayIncludesHelper(fixedLength, 2)); - assert(!TypedArrayIncludesHelper(fixedLength, undefined)); - assert(TypedArrayIncludesHelper(fixedLength, 2, 1)); - assert(!TypedArrayIncludesHelper(fixedLength, 2, 2)); - assert(TypedArrayIncludesHelper(fixedLength, 2, -3)); - assert(!TypedArrayIncludesHelper(fixedLength, 2, -2)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, undefined)); - assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4, 0)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 4, 1)); - assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4, -2)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 4, -1)); - assert(TypedArrayIncludesHelper(lengthTracking, 2)); - assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); - assert(TypedArrayIncludesHelper(lengthTracking, 2, 1)); - assert(!TypedArrayIncludesHelper(lengthTracking, 2, 2)); - assert(TypedArrayIncludesHelper(lengthTracking, 2, -3)); - assert(!TypedArrayIncludesHelper(lengthTracking, 2, -2)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, 0)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, 1)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, -2)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, -1)); - - // Shrink so that fixed length TAs go out of bounds. - rab.resize(3 * ctor.BYTES_PER_ELEMENT); - - // Orig. array: [0, 2, 4] - // [0, 2, 4, ...] << lengthTracking - // [4, ...] << lengthTrackingWithOffset - - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLength, 2); - }); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLengthWithOffset, 2); - }); - - assert(TypedArrayIncludesHelper(lengthTracking, 2)); - assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - - // Shrink so that the TAs with offset go out of bounds. - rab.resize(1 * ctor.BYTES_PER_ELEMENT); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLength, 2); - }); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLengthWithOffset, 2); - }); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(lengthTrackingWithOffset, 2); - }); - - // Shrink to zero. - rab.resize(0); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLength, 2); - }); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLengthWithOffset, 2); - }); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(lengthTrackingWithOffset, 2); - }); - assert(!TypedArrayIncludesHelper(lengthTracking, 2)); - assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); - - // Grow so that all TAs are back in-bounds. - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - for (let i = 0; i < 6; ++i) { - WriteToTypedArray(taWrite, i, 2 * i); - } - - // Orig. array: [0, 2, 4, 6, 8, 10] - // [0, 2, 4, 6] << fixedLength - // [4, 6] << fixedLengthWithOffset - // [0, 2, 4, 6, 8, 10, ...] << lengthTracking - // [4, 6, 8, 10, ...] << lengthTrackingWithOffset - - assert(TypedArrayIncludesHelper(fixedLength, 2)); - assert(!TypedArrayIncludesHelper(fixedLength, undefined)); - assert(!TypedArrayIncludesHelper(fixedLength, 8)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, undefined)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 8)); - assert(TypedArrayIncludesHelper(lengthTracking, 2)); - assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); - assert(TypedArrayIncludesHelper(lengthTracking, 8)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 8)); + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); } -} -TestIncludes(); + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, undefined)); + assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2, 1)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 2, 2)); + assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2, -3)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 2, -2)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); + assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 0)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 1)); + assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -2)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -1)); + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2, 1)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 2, 2)); + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2, -3)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 2, -2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 0)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 1)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -1)); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLength, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2); + }); + + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLength, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2); + }); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLength, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2); + }); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, undefined)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 8)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 8)); + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 8)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 8)); +} From 441cbef061b6cd3f5baded300c48408edacad1b4 Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Tue, 9 Jul 2024 20:17:11 +0200 Subject: [PATCH 10/90] Restructures ArrayIncludesNumOrBigInt to use MayNeedBigInt as it seems clearer. --- .../coerced-searchelement-fromindex-resize.js | 35 ++--- .../prototype/includes/resizable-buffer.js | 127 ++++++++--------- .../coerced-searchelement-fromindex-resize.js | 35 ++--- .../resizable-buffer-special-float-values.js | 2 +- .../prototype/includes/resizable-buffer.js | 128 +++++++++--------- 5 files changed, 172 insertions(+), 155 deletions(-) diff --git a/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js b/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js index 448709b5af..96c5ca2ff4 100644 --- a/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js +++ b/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js @@ -4,17 +4,17 @@ /*--- esid: sec-array.prototype.includes description: > - Array.p.includes behaves correctly when the receiver is resized during - argument coercion + Array.p.includes behaves correctly on TypedArrays backed by resizable buffers + that are resized during argument coercion. includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -function ArrayIncludesNumOrBigInt(array, n, fromIndex) { - if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { - return Array.prototype.includes.call(array, BigInt(n), fromIndex); +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); } - return Array.prototype.includes.call(array, n, fromIndex); + return n; } for (let ctor of ctors) { @@ -26,9 +26,9 @@ for (let ctor of ctors) { return 0; } }; - assert(!ArrayIncludesNumOrBigInt(fixedLength, undefined)); + assert(!Array.prototype.includes.call(fixedLength, undefined)); // The TA is OOB so it includes only "undefined". - assert(ArrayIncludesNumOrBigInt(fixedLength, undefined, evil)); + assert(Array.prototype.includes.call(fixedLength, undefined, evil)); } for (let ctor of ctors) { const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); @@ -39,9 +39,10 @@ for (let ctor of ctors) { return 0; } }; - assert(ArrayIncludesNumOrBigInt(fixedLength, 0)); + let n0 = MayNeedBigInt(fixedLength, 0); + assert(Array.prototype.includes.call(fixedLength, n0)); // The TA is OOB so it includes only "undefined". - assert(!ArrayIncludesNumOrBigInt(fixedLength, 0, evil)); + assert(!Array.prototype.includes.call(fixedLength, n0, evil)); } for (let ctor of ctors) { const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); @@ -52,9 +53,9 @@ for (let ctor of ctors) { return 0; } }; - assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(!Array.prototype.includes.call(lengthTracking, undefined)); // "includes" iterates until the original length and sees "undefined"s. - assert(ArrayIncludesNumOrBigInt(lengthTracking, undefined, evil)); + assert(Array.prototype.includes.call(lengthTracking, undefined, evil)); } for (let ctor of ctors) { const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); @@ -68,9 +69,10 @@ for (let ctor of ctors) { return 0; } }; - assert(!ArrayIncludesNumOrBigInt(lengthTracking, 0)); + let n0 = MayNeedBigInt(lengthTracking, 0); + assert(!Array.prototype.includes.call(lengthTracking, n0)); // The TA grew but we only look at the data until the original length. - assert(!ArrayIncludesNumOrBigInt(lengthTracking, 0, evil)); + assert(!Array.prototype.includes.call(lengthTracking, n0, evil)); } for (let ctor of ctors) { const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); @@ -82,8 +84,9 @@ for (let ctor of ctors) { return -4; } }; - assert(ArrayIncludesNumOrBigInt(lengthTracking, 1, -4)); + let n1 = MayNeedBigInt(lengthTracking, 1); + assert(Array.prototype.includes.call(lengthTracking, n1, -4)); // The TA grew but the start index conversion is done based on the original // length. - assert(ArrayIncludesNumOrBigInt(lengthTracking, 1, evil)); + assert(Array.prototype.includes.call(lengthTracking, n1, evil)); } diff --git a/test/built-ins/Array/prototype/includes/resizable-buffer.js b/test/built-ins/Array/prototype/includes/resizable-buffer.js index 49894ef40b..b9a78cef9a 100644 --- a/test/built-ins/Array/prototype/includes/resizable-buffer.js +++ b/test/built-ins/Array/prototype/includes/resizable-buffer.js @@ -4,17 +4,16 @@ /*--- esid: sec-array.prototype.includes description: > - Array.p.includes behaves correctly when receiver is backed by resizable - buffer + Array.p.includes behaves correctly on TypedArrays backed by resizable buffers. includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -function ArrayIncludesNumOrBigInt(array, n, fromIndex) { - if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { - return Array.prototype.includes.call(array, BigInt(n), fromIndex); +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); } - return Array.prototype.includes.call(array, n, fromIndex); + return n; } for (let ctor of ctors) { @@ -36,32 +35,36 @@ for (let ctor of ctors) { // [0, 2, 4, 6, ...] << lengthTracking // [4, 6, ...] << lengthTrackingWithOffset - assert(ArrayIncludesNumOrBigInt(fixedLength, 2)); - assert(!ArrayIncludesNumOrBigInt(fixedLength, undefined)); - assert(ArrayIncludesNumOrBigInt(fixedLength, 2, 1)); - assert(!ArrayIncludesNumOrBigInt(fixedLength, 2, 2)); - assert(ArrayIncludesNumOrBigInt(fixedLength, 2, -3)); - assert(!ArrayIncludesNumOrBigInt(fixedLength, 2, -2)); - assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); - assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); - assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); - assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 0)); - assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 1)); - assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -2)); - assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -1)); - assert(ArrayIncludesNumOrBigInt(lengthTracking, 2)); - assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); - assert(ArrayIncludesNumOrBigInt(lengthTracking, 2, 1)); - assert(!ArrayIncludesNumOrBigInt(lengthTracking, 2, 2)); - assert(ArrayIncludesNumOrBigInt(lengthTracking, 2, -3)); - assert(!ArrayIncludesNumOrBigInt(lengthTracking, 2, -2)); - assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); - assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); - assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); - assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 0)); - assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 1)); - assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -2)); - assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -1)); + // If fixedLength is a BigInt array, they all are BigInt Arrays. + let n2 = MayNeedBigInt(fixedLength, 2); + let n4 = MayNeedBigInt(fixedLength, 4); + + assert(Array.prototype.includes.call(fixedLength, n2)); + assert(!Array.prototype.includes.call(fixedLength, undefined)); + assert(Array.prototype.includes.call(fixedLength, n2, 1)); + assert(!Array.prototype.includes.call(fixedLength, n2, 2)); + assert(Array.prototype.includes.call(fixedLength, n2, -3)); + assert(!Array.prototype.includes.call(fixedLength, n2, -2)); + assert(!Array.prototype.includes.call(fixedLengthWithOffset, n2)); + assert(Array.prototype.includes.call(fixedLengthWithOffset, n4)); + assert(!Array.prototype.includes.call(fixedLengthWithOffset, undefined)); + assert(Array.prototype.includes.call(fixedLengthWithOffset, n4, 0)); + assert(!Array.prototype.includes.call(fixedLengthWithOffset, n4, 1)); + assert(Array.prototype.includes.call(fixedLengthWithOffset, n4, -2)); + assert(!Array.prototype.includes.call(fixedLengthWithOffset, n4, -1)); + assert(Array.prototype.includes.call(lengthTracking, n2)); + assert(!Array.prototype.includes.call(lengthTracking, undefined)); + assert(Array.prototype.includes.call(lengthTracking, n2, 1)); + assert(!Array.prototype.includes.call(lengthTracking, n2, 2)); + assert(Array.prototype.includes.call(lengthTracking, n2, -3)); + assert(!Array.prototype.includes.call(lengthTracking, n2, -2)); + assert(!Array.prototype.includes.call(lengthTrackingWithOffset, n2)); + assert(Array.prototype.includes.call(lengthTrackingWithOffset, n4)); + assert(!Array.prototype.includes.call(lengthTrackingWithOffset, undefined)); + assert(Array.prototype.includes.call(lengthTrackingWithOffset, n4, 0)); + assert(!Array.prototype.includes.call(lengthTrackingWithOffset, n4, 1)); + assert(Array.prototype.includes.call(lengthTrackingWithOffset, n4, -2)); + assert(!Array.prototype.includes.call(lengthTrackingWithOffset, n4, -1)); // Shrink so that fixed length TAs go out of bounds. rab.resize(3 * ctor.BYTES_PER_ELEMENT); @@ -70,29 +73,29 @@ for (let ctor of ctors) { // [0, 2, 4, ...] << lengthTracking // [4, ...] << lengthTrackingWithOffset - assert(!ArrayIncludesNumOrBigInt(fixedLength, 2)); - assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(!Array.prototype.includes.call(fixedLength, n2)); + assert(!Array.prototype.includes.call(fixedLengthWithOffset, n2)); - assert(ArrayIncludesNumOrBigInt(lengthTracking, 2)); - assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); - assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); - assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); - assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + assert(Array.prototype.includes.call(lengthTracking, n2)); + assert(!Array.prototype.includes.call(lengthTracking, undefined)); + assert(!Array.prototype.includes.call(lengthTrackingWithOffset, n2)); + assert(Array.prototype.includes.call(lengthTrackingWithOffset, n4)); + assert(!Array.prototype.includes.call(lengthTrackingWithOffset, undefined)); // Shrink so that the TAs with offset go out of bounds. rab.resize(1 * ctor.BYTES_PER_ELEMENT); - assert(!ArrayIncludesNumOrBigInt(fixedLength, 2)); - assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); - assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(!Array.prototype.includes.call(fixedLength, n2)); + assert(!Array.prototype.includes.call(fixedLengthWithOffset, n2)); + assert(!Array.prototype.includes.call(lengthTrackingWithOffset, n2)); // Shrink to zero. rab.resize(0); - assert(!ArrayIncludesNumOrBigInt(fixedLength, 2)); - assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); - assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(!Array.prototype.includes.call(fixedLength, n2)); + assert(!Array.prototype.includes.call(fixedLengthWithOffset, n2)); + assert(!Array.prototype.includes.call(lengthTrackingWithOffset, n2)); - assert(!ArrayIncludesNumOrBigInt(lengthTracking, 2)); - assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(!Array.prototype.includes.call(lengthTracking, n2)); + assert(!Array.prototype.includes.call(lengthTracking, undefined)); // Grow so that all TAs are back in-bounds. rab.resize(6 * ctor.BYTES_PER_ELEMENT); @@ -106,18 +109,20 @@ for (let ctor of ctors) { // [0, 2, 4, 6, 8, 10, ...] << lengthTracking // [4, 6, 8, 10, ...] << lengthTrackingWithOffset - assert(ArrayIncludesNumOrBigInt(fixedLength, 2)); - assert(!ArrayIncludesNumOrBigInt(fixedLength, undefined)); - assert(!ArrayIncludesNumOrBigInt(fixedLength, 8)); - assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); - assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); - assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); - assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 8)); - assert(ArrayIncludesNumOrBigInt(lengthTracking, 2)); - assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); - assert(ArrayIncludesNumOrBigInt(lengthTracking, 8)); - assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); - assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); - assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); - assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 8)); + let n8 = MayNeedBigInt(fixedLength, 8); + + assert(Array.prototype.includes.call(fixedLength, n2)); + assert(!Array.prototype.includes.call(fixedLength, undefined)); + assert(!Array.prototype.includes.call(fixedLength, n8)); + assert(!Array.prototype.includes.call(fixedLengthWithOffset, n2)); + assert(Array.prototype.includes.call(fixedLengthWithOffset, n4)); + assert(!Array.prototype.includes.call(fixedLengthWithOffset, undefined)); + assert(!Array.prototype.includes.call(fixedLengthWithOffset, n8)); + assert(Array.prototype.includes.call(lengthTracking, n2)); + assert(!Array.prototype.includes.call(lengthTracking, undefined)); + assert(Array.prototype.includes.call(lengthTracking, n8)); + assert(!Array.prototype.includes.call(lengthTrackingWithOffset, n2)); + assert(Array.prototype.includes.call(lengthTrackingWithOffset, n4)); + assert(!Array.prototype.includes.call(lengthTrackingWithOffset, undefined)); + assert(Array.prototype.includes.call(lengthTrackingWithOffset, n8)); } diff --git a/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js b/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js index 63727c8cc5..8fed6fec14 100644 --- a/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js +++ b/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js @@ -4,17 +4,17 @@ /*--- esid: sec-%typedarray%.prototype.includes description: > - TypedArray.p.includes behaves correctly when the receiver is resized during - argument coercion + TypedArray.p.includes behaves correctly on TypedArrays backed by resizable + buffers that are resized during argument coercion. includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -function TypedArrayIncludesNumOrBigInt(array, n, fromIndex) { - if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { - return array.includes(BigInt(n), fromIndex); +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); } - return array.includes(n, fromIndex); + return n; } for (let ctor of ctors) { @@ -26,9 +26,9 @@ for (let ctor of ctors) { return 0; } }; - assert(!TypedArrayIncludesNumOrBigInt(fixedLength, undefined)); + assert(!fixedLength.includes(undefined)); // The TA is OOB so it includes only "undefined". - assert(TypedArrayIncludesNumOrBigInt(fixedLength, undefined, evil)); + assert(fixedLength.includes(undefined, evil)); } for (let ctor of ctors) { const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); @@ -39,9 +39,10 @@ for (let ctor of ctors) { return 0; } }; - assert(TypedArrayIncludesNumOrBigInt(fixedLength, 0)); + let n0 = MayNeedBigInt(fixedLength, 0); + assert(fixedLength.includes(n0)); // The TA is OOB so it includes only "undefined". - assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 0, evil)); + assert(!fixedLength.includes(n0, evil)); } for (let ctor of ctors) { const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); @@ -52,9 +53,9 @@ for (let ctor of ctors) { return 0; } }; - assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(!lengthTracking.includes(undefined)); // "includes" iterates until the original length and sees "undefined"s. - assert(TypedArrayIncludesNumOrBigInt(lengthTracking, undefined, evil)); + assert(lengthTracking.includes(undefined, evil)); } for (let ctor of ctors) { const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); @@ -68,9 +69,10 @@ for (let ctor of ctors) { return 0; } }; - assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 0)); + let n0 = MayNeedBigInt(lengthTracking, 0); + assert(!lengthTracking.includes(n0)); // The TA grew but we only look at the data until the original length. - assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 0, evil)); + assert(!lengthTracking.includes(n0, evil)); } for (let ctor of ctors) { const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); @@ -82,8 +84,9 @@ for (let ctor of ctors) { return -4; } }; - assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 1, -4)); + let n1 = MayNeedBigInt(lengthTracking, 1); + assert(lengthTracking.includes(n1, -4)); // The TA grew but the start index conversion is done based on the original // length. - assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 1, evil)); + assert(lengthTracking.includes(n1, evil)); } diff --git a/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js b/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js index f621d95838..36429d4041 100644 --- a/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js +++ b/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js @@ -5,7 +5,7 @@ esid: sec-%typedarray%.prototype.includes description: > TypedArray.p.includes behaves correctly for special float values when - receiver is a float TypedArray backed by a resizable buffer + receiver is a float TypedArray backed by a resizable buffer. includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ diff --git a/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js b/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js index 77fa05960d..8e99ce5db6 100644 --- a/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js +++ b/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js @@ -4,17 +4,17 @@ /*--- esid: sec-%typedarray%.prototype.includes description: > - TypedArray.p.includes behaves correctly when receiver is backed by resizable - buffer + TypedArray.p.includes behaves correctly on TypedArrays backed by resizable + buffers. includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -function TypedArrayIncludesNumOrBigInt(array, n, fromIndex) { - if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { - return array.includes(BigInt(n), fromIndex); +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); } - return array.includes(n, fromIndex); + return n; } for (let ctor of ctors) { @@ -36,32 +36,36 @@ for (let ctor of ctors) { // [0, 2, 4, 6, ...] << lengthTracking // [4, 6, ...] << lengthTrackingWithOffset - assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLength, undefined)); - assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2, 1)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 2, 2)); - assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2, -3)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 2, -2)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); - assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); - assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 0)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 1)); - assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -2)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -1)); - assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); - assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2, 1)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 2, 2)); - assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2, -3)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 2, -2)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); - assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); - assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 0)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 1)); - assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -2)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -1)); + // If fixedLength is a BigInt array, they all are BigInt Arrays. + let n2 = MayNeedBigInt(fixedLength, 2); + let n4 = MayNeedBigInt(fixedLength, 4); + + assert(fixedLength.includes(n2)); + assert(!fixedLength.includes(undefined)); + assert(fixedLength.includes(n2, 1)); + assert(!fixedLength.includes(n2, 2)); + assert(fixedLength.includes(n2, -3)); + assert(!fixedLength.includes(n2, -2)); + assert(!fixedLengthWithOffset.includes(n2)); + assert(fixedLengthWithOffset.includes(n4)); + assert(!fixedLengthWithOffset.includes(undefined)); + assert(fixedLengthWithOffset.includes(n4, 0)); + assert(!fixedLengthWithOffset.includes(n4, 1)); + assert(fixedLengthWithOffset.includes(n4, -2)); + assert(!fixedLengthWithOffset.includes(n4, -1)); + assert(lengthTracking.includes(n2)); + assert(!lengthTracking.includes(undefined)); + assert(lengthTracking.includes(n2, 1)); + assert(!lengthTracking.includes(n2, 2)); + assert(lengthTracking.includes(n2, -3)); + assert(!lengthTracking.includes(n2, -2)); + assert(!lengthTrackingWithOffset.includes(n2)); + assert(lengthTrackingWithOffset.includes(n4)); + assert(!lengthTrackingWithOffset.includes(undefined)); + assert(lengthTrackingWithOffset.includes(n4, 0)); + assert(!lengthTrackingWithOffset.includes(n4, 1)); + assert(lengthTrackingWithOffset.includes(n4, -2)); + assert(!lengthTrackingWithOffset.includes(n4, -1)); // Shrink so that fixed length TAs go out of bounds. rab.resize(3 * ctor.BYTES_PER_ELEMENT); @@ -71,43 +75,43 @@ for (let ctor of ctors) { // [4, ...] << lengthTrackingWithOffset assert.throws(TypeError, () => { - TypedArrayIncludesNumOrBigInt(fixedLength, 2); + fixedLength.includes(n2); }); assert.throws(TypeError, () => { - TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2); + fixedLengthWithOffset.includes(n2); }); - assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); - assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + assert(lengthTracking.includes(n2)); + assert(!lengthTracking.includes(undefined)); + assert(!lengthTrackingWithOffset.includes(n2)); + assert(lengthTrackingWithOffset.includes(n4)); + assert(!lengthTrackingWithOffset.includes(undefined)); // Shrink so that the TAs with offset go out of bounds. rab.resize(1 * ctor.BYTES_PER_ELEMENT); assert.throws(TypeError, () => { - TypedArrayIncludesNumOrBigInt(fixedLength, 2); + fixedLength.includes(n2); }); assert.throws(TypeError, () => { - TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2); + fixedLengthWithOffset.includes(n2); }); assert.throws(TypeError, () => { - TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2); + lengthTrackingWithOffset.includes(n2); }); // Shrink to zero. rab.resize(0); assert.throws(TypeError, () => { - TypedArrayIncludesNumOrBigInt(fixedLength, 2); + fixedLength.includes(n2); }); assert.throws(TypeError, () => { - TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2); + fixedLengthWithOffset.includes(n2); }); assert.throws(TypeError, () => { - TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2); + lengthTrackingWithOffset.includes(n2); }); - assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(!lengthTracking.includes(n2)); + assert(!lengthTracking.includes(undefined)); // Grow so that all TAs are back in-bounds. rab.resize(6 * ctor.BYTES_PER_ELEMENT); @@ -121,18 +125,20 @@ for (let ctor of ctors) { // [0, 2, 4, 6, 8, 10, ...] << lengthTracking // [4, 6, 8, 10, ...] << lengthTrackingWithOffset - assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLength, undefined)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 8)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); - assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); - assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 8)); - assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); - assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 8)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); - assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); - assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); - assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 8)); + let n8 = MayNeedBigInt(fixedLength, 8); + + assert(fixedLength.includes(n2)); + assert(!fixedLength.includes(undefined)); + assert(!fixedLength.includes(n8)); + assert(!fixedLengthWithOffset.includes(n2)); + assert(fixedLengthWithOffset.includes(n4)); + assert(!fixedLengthWithOffset.includes(undefined)); + assert(!fixedLengthWithOffset.includes(n8)); + assert(lengthTracking.includes(n2)); + assert(!lengthTracking.includes(undefined)); + assert(lengthTracking.includes(n8)); + assert(!lengthTrackingWithOffset.includes(n2)); + assert(lengthTrackingWithOffset.includes(n4)); + assert(!lengthTrackingWithOffset.includes(undefined)); + assert(lengthTrackingWithOffset.includes(n8)); } From 88b013ff7f8d5811cc4d61c60efacccfe584ff9d Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Tue, 9 Jul 2024 20:21:09 +0200 Subject: [PATCH 11/90] Adds missing test file for Array.prototype.includes --- .../resizable-buffer-special-float-values.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 test/built-ins/Array/prototype/includes/resizable-buffer-special-float-values.js diff --git a/test/built-ins/Array/prototype/includes/resizable-buffer-special-float-values.js b/test/built-ins/Array/prototype/includes/resizable-buffer-special-float-values.js new file mode 100644 index 0000000000..1908d833eb --- /dev/null +++ b/test/built-ins/Array/prototype/includes/resizable-buffer-special-float-values.js @@ -0,0 +1,22 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%array%.prototype.includes +description: > + Array.p.includes behaves correctly for special float values on float + TypedArrays backed by resizable buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer, Array.prototype.includes] +---*/ + +for (let ctor of floatCtors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + lengthTracking[0] = -Infinity; + lengthTracking[1] = Infinity; + lengthTracking[2] = NaN; + assert(Array.prototype.includes.call(lengthTracking, -Infinity)); + assert(Array.prototype.includes.call(lengthTracking, Infinity)); + assert(Array.prototype.includes.call(lengthTracking, NaN)); +} From ab0c31a4581dff94230bf5af9f45f682701760eb Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Fri, 12 Jul 2024 01:05:07 +0200 Subject: [PATCH 12/90] RAB: Integrate staging tests for the .indexOf method (#4136) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while applying review changes from PRs for previously tested methods. * Restructures ArrayIndexOfNumOrBigInt to use MayNeedBigInt as it seems clearer. * Adds missing test file for Array.prototype.indexOf --- .../coerced-searchelement-fromindex-grow.js | 55 +++++++ .../coerced-searchelement-fromindex-shrink.js | 67 ++++++++ .../resizable-buffer-special-float-values.js | 26 ++++ .../prototype/indexOf/resizable-buffer.js | 126 +++++++++++++++ .../coerced-searchelement-fromindex-grow.js | 55 +++++++ .../coerced-searchelement-fromindex-shrink.js | 67 ++++++++ .../resizable-buffer-special-float-values.js | 26 ++++ .../prototype/indexOf/resizable-buffer.js | 144 ++++++++++++++++++ 8 files changed, 566 insertions(+) create mode 100644 test/built-ins/Array/prototype/indexOf/coerced-searchelement-fromindex-grow.js create mode 100644 test/built-ins/Array/prototype/indexOf/coerced-searchelement-fromindex-shrink.js create mode 100644 test/built-ins/Array/prototype/indexOf/resizable-buffer-special-float-values.js create mode 100644 test/built-ins/Array/prototype/indexOf/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/indexOf/coerced-searchelement-fromindex-grow.js create mode 100644 test/built-ins/TypedArray/prototype/indexOf/coerced-searchelement-fromindex-shrink.js create mode 100644 test/built-ins/TypedArray/prototype/indexOf/resizable-buffer-special-float-values.js create mode 100644 test/built-ins/TypedArray/prototype/indexOf/resizable-buffer.js diff --git a/test/built-ins/Array/prototype/indexOf/coerced-searchelement-fromindex-grow.js b/test/built-ins/Array/prototype/indexOf/coerced-searchelement-fromindex-grow.js new file mode 100644 index 0000000000..fc1c3e0f7d --- /dev/null +++ b/test/built-ins/Array/prototype/indexOf/coerced-searchelement-fromindex-grow.js @@ -0,0 +1,55 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.indexof +description: > + Array.p.indexOf behaves correctly when the backing resizable buffer is grown + during argument coercion. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +// Growing + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, 1); + } + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + let n0 = MayNeedBigInt(lengthTracking, 0); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n0), -1); + // The TA grew but we only look at the data until the original length. + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n0, evil), -1); +} + +// Growing + length-tracking TA, index conversion. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + WriteToTypedArray(lengthTracking, 0, 1); + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -4; + } + }; + let n1 = MayNeedBigInt(lengthTracking, 1); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n1, -4), 0); + // The TA grew but the start index conversion is done based on the original + // length. + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n1, evil), 0); +} diff --git a/test/built-ins/Array/prototype/indexOf/coerced-searchelement-fromindex-shrink.js b/test/built-ins/Array/prototype/indexOf/coerced-searchelement-fromindex-shrink.js new file mode 100644 index 0000000000..9e803e491a --- /dev/null +++ b/test/built-ins/Array/prototype/indexOf/coerced-searchelement-fromindex-shrink.js @@ -0,0 +1,67 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.indexof +description: > + Array.p.indexOf behaves correctly when the backing resizable buffer is shrunk + during argument coercion. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +// Shrinking + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + let n0 = MayNeedBigInt(fixedLength, 0); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n0), 0); + // The TA is OOB so indexOf returns -1. + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n0, evil), -1); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + let n0 = MayNeedBigInt(fixedLength, 0); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n0), 0); + // The TA is OOB so indexOf returns -1, also for undefined). + assert.sameValue(Array.prototype.indexOf.call(fixedLength, undefined, evil), -1); +} + +// Shrinking + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i); + } + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + let n2 = MayNeedBigInt(lengthTracking, 2); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n2), 2); + // 2 no longer found. + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n2, evil), -1); +} diff --git a/test/built-ins/Array/prototype/indexOf/resizable-buffer-special-float-values.js b/test/built-ins/Array/prototype/indexOf/resizable-buffer-special-float-values.js new file mode 100644 index 0000000000..ca8ba77433 --- /dev/null +++ b/test/built-ins/Array/prototype/indexOf/resizable-buffer-special-float-values.js @@ -0,0 +1,26 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%array%.prototype.indexof +description: > + Array.p.indexOf behaves correctly for special float values on TypedArrays + backed by resizable buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer, Array.prototype.includes] +---*/ + +for (let ctor of floatCtors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + lengthTracking[0] = -Infinity; + lengthTracking[1] = -Infinity; + lengthTracking[2] = Infinity; + lengthTracking[3] = Infinity; + lengthTracking[4] = NaN; + lengthTracking[5] = NaN; + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, -Infinity), 0); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, Infinity), 2); + // NaN is never found. + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, NaN), -1); +} diff --git a/test/built-ins/Array/prototype/indexOf/resizable-buffer.js b/test/built-ins/Array/prototype/indexOf/resizable-buffer.js new file mode 100644 index 0000000000..74f232dd2c --- /dev/null +++ b/test/built-ins/Array/prototype/indexOf/resizable-buffer.js @@ -0,0 +1,126 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.indexof +description: > + Array.p.indexOf behaves correctly on TypedArrays backed by resizable buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, Math.floor(i / 2)); + } + + // Orig. array: [0, 0, 1, 1] + // [0, 0, 1, 1] << fixedLength + // [1, 1] << fixedLengthWithOffset + // [0, 0, 1, 1, ...] << lengthTracking + // [1, 1, ...] << lengthTrackingWithOffset + + // If fixedLength is a BigInt array, they all are BigInt Arrays. + let n0 = MayNeedBigInt(fixedLength, 0); + let n1 = MayNeedBigInt(fixedLength, 1); + + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n0), 0); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n0, 1), 1); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n0, 2), -1); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n0, -2), -1); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n0, -3), 1); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n1, 1), 2); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n1, -3), 2); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n1, -2), 2); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, undefined), -1); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, n0), -1); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, n1), 0); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, n1, -2), 0); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, n1, -1), 1); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, undefined), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n0), 0); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n0, 2), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n1, -3), 2); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, undefined), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, n0), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, n1), 0); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, n1, 1), 1); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, n1, -2), 0); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, undefined), -1); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 0, 1] + // [0, 0, 1, ...] << lengthTracking + // [1, ...] << lengthTrackingWithOffset + + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n1), -1); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, n1), -1); + + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n1), 2); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, undefined), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, n0), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, n1), 0); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, undefined), -1); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n0), -1); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, n0), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, n0), -1); + + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n0), 0); + + // Shrink to zero. + rab.resize(0); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n0), -1); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, n0), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, n0), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n0), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, undefined), -1); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, Math.floor(i / 2)); + } + + // Orig. array: [0, 0, 1, 1, 2, 2] + // [0, 0, 1, 1] << fixedLength + // [1, 1] << fixedLengthWithOffset + // [0, 0, 1, 1, 2, 2, ...] << lengthTracking + // [1, 1, 2, 2, ...] << lengthTrackingWithOffset + + let n2 = MayNeedBigInt(fixedLength, 2); + + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n1), 2); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, n2), -1); + assert.sameValue(Array.prototype.indexOf.call(fixedLength, undefined), -1); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, n0), -1); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, n1), 0); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, n2), -1); + assert.sameValue(Array.prototype.indexOf.call(fixedLengthWithOffset, undefined), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n1), 2); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, n2), 4); + assert.sameValue(Array.prototype.indexOf.call(lengthTracking, undefined), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, n0), -1); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, n1), 0); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, n2), 2); + assert.sameValue(Array.prototype.indexOf.call(lengthTrackingWithOffset, undefined), -1); +} diff --git a/test/built-ins/TypedArray/prototype/indexOf/coerced-searchelement-fromindex-grow.js b/test/built-ins/TypedArray/prototype/indexOf/coerced-searchelement-fromindex-grow.js new file mode 100644 index 0000000000..7b63c5009c --- /dev/null +++ b/test/built-ins/TypedArray/prototype/indexOf/coerced-searchelement-fromindex-grow.js @@ -0,0 +1,55 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.indexof +description: > + TypedArray.p.indexOf behaves correctly when the backing resizable buffer is + grown during argument coercion. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +// Growing + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, 1); + } + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + let n0 = MayNeedBigInt(lengthTracking, 0); + assert.sameValue(lengthTracking.indexOf(n0), -1); + // The TA grew but we only look at the data until the original length. + assert.sameValue(lengthTracking.indexOf(n0, evil), -1); +} + +// Growing + length-tracking TA, index conversion. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + WriteToTypedArray(lengthTracking, 0, 1); + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -4; + } + }; + let n1 = MayNeedBigInt(lengthTracking, 1); + assert.sameValue(lengthTracking.indexOf(n1, -4), 0); + // The TA grew but the start index conversion is done based on the original + // length. + assert.sameValue(lengthTracking.indexOf(n1, evil), 0); +} diff --git a/test/built-ins/TypedArray/prototype/indexOf/coerced-searchelement-fromindex-shrink.js b/test/built-ins/TypedArray/prototype/indexOf/coerced-searchelement-fromindex-shrink.js new file mode 100644 index 0000000000..befab22a27 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/indexOf/coerced-searchelement-fromindex-shrink.js @@ -0,0 +1,67 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.indexof +description: > + TypedArray.p.indexOf behaves correctly when receiver is shrunk + during argument coercion +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +// Shrinking + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + let n0 = MayNeedBigInt(fixedLength, 0); + assert.sameValue(fixedLength.indexOf(n0), 0); + // The TA is OOB so indexOf returns -1. + assert.sameValue(fixedLength.indexOf(n0, evil), -1); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + let n0 = MayNeedBigInt(fixedLength, 0); + assert.sameValue(fixedLength.indexOf(n0), 0); + // The TA is OOB so indexOf returns -1, also for undefined). + assert.sameValue(fixedLength.indexOf(undefined, evil), -1); +} + +// Shrinking + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i); + } + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + let n2 = MayNeedBigInt(lengthTracking, 2); + assert.sameValue(lengthTracking.indexOf(n2), 2); + // 2 no longer found. + assert.sameValue(lengthTracking.indexOf(n2, evil), -1); +} diff --git a/test/built-ins/TypedArray/prototype/indexOf/resizable-buffer-special-float-values.js b/test/built-ins/TypedArray/prototype/indexOf/resizable-buffer-special-float-values.js new file mode 100644 index 0000000000..c66ca7031c --- /dev/null +++ b/test/built-ins/TypedArray/prototype/indexOf/resizable-buffer-special-float-values.js @@ -0,0 +1,26 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.indexof +description: > + TypedArray.p.indexOf behaves correctly for special float values on float + TypedArrays backed by resizable buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer, Array.prototype.includes] +---*/ + +for (let ctor of floatCtors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + lengthTracking[0] = -Infinity; + lengthTracking[1] = -Infinity; + lengthTracking[2] = Infinity; + lengthTracking[3] = Infinity; + lengthTracking[4] = NaN; + lengthTracking[5] = NaN; + assert.sameValue(lengthTracking.indexOf(-Infinity), 0); + assert.sameValue(lengthTracking.indexOf(Infinity), 2); + // NaN is never found. + assert.sameValue(lengthTracking.indexOf(NaN), -1); +} diff --git a/test/built-ins/TypedArray/prototype/indexOf/resizable-buffer.js b/test/built-ins/TypedArray/prototype/indexOf/resizable-buffer.js new file mode 100644 index 0000000000..43519225f0 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/indexOf/resizable-buffer.js @@ -0,0 +1,144 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.indexof +description: > + TypedArray.p.indexOf behaves correctly on TypedArrays backed by resizable + buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, Math.floor(i / 2)); + } + + // Orig. array: [0, 0, 1, 1] + // [0, 0, 1, 1] << fixedLength + // [1, 1] << fixedLengthWithOffset + // [0, 0, 1, 1, ...] << lengthTracking + // [1, 1, ...] << lengthTrackingWithOffset + + // If fixedLength is a BigInt array, they all are BigInt Arrays. + let n0 = MayNeedBigInt(fixedLength, 0); + let n1 = MayNeedBigInt(fixedLength, 1); + + assert.sameValue(fixedLength.indexOf(n0), 0); + assert.sameValue(fixedLength.indexOf(n0, 1), 1); + assert.sameValue(fixedLength.indexOf(n0, 2), -1); + assert.sameValue(fixedLength.indexOf(n0, -2), -1); + assert.sameValue(fixedLength.indexOf(n0, -3), 1); + assert.sameValue(fixedLength.indexOf(n1, 1), 2); + assert.sameValue(fixedLength.indexOf(n1, -3), 2); + assert.sameValue(fixedLength.indexOf(n1, -2), 2); + assert.sameValue(fixedLength.indexOf(undefined), -1); + assert.sameValue(fixedLengthWithOffset.indexOf(n0), -1); + assert.sameValue(fixedLengthWithOffset.indexOf(n1), 0); + assert.sameValue(fixedLengthWithOffset.indexOf(n1, -2), 0); + assert.sameValue(fixedLengthWithOffset.indexOf(n1, -1), 1); + assert.sameValue(fixedLengthWithOffset.indexOf(undefined), -1); + assert.sameValue(lengthTracking.indexOf(n0), 0); + assert.sameValue(lengthTracking.indexOf(n0, 2), -1); + assert.sameValue(lengthTracking.indexOf(n1, -3), 2); + assert.sameValue(lengthTracking.indexOf(undefined), -1); + assert.sameValue(lengthTrackingWithOffset.indexOf(n0), -1); + assert.sameValue(lengthTrackingWithOffset.indexOf(n1), 0); + assert.sameValue(lengthTrackingWithOffset.indexOf(n1, 1), 1); + assert.sameValue(lengthTrackingWithOffset.indexOf(n1, -2), 0); + assert.sameValue(lengthTrackingWithOffset.indexOf(undefined), -1); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 0, 1] + // [0, 0, 1, ...] << lengthTracking + // [1, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + fixedLength.indexOf(n1); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.indexOf(n1); + }); + + assert.sameValue(lengthTracking.indexOf(n1), 2); + assert.sameValue(lengthTracking.indexOf(undefined), -1); + assert.sameValue(lengthTrackingWithOffset.indexOf(n0), -1); + assert.sameValue(lengthTrackingWithOffset.indexOf(n1), 0); + assert.sameValue(lengthTrackingWithOffset.indexOf(undefined), -1); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + fixedLength.indexOf(n0); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.indexOf(n0); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.indexOf(n0); + }); + + assert.sameValue(lengthTracking.indexOf(n0), 0); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + fixedLength.indexOf(n0); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.indexOf(n0); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.indexOf(n0); + }); + + assert.sameValue(lengthTracking.indexOf(n0), -1); + assert.sameValue(lengthTracking.indexOf(undefined), -1); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, Math.floor(i / 2)); + } + + // Orig. array: [0, 0, 1, 1, 2, 2] + // [0, 0, 1, 1] << fixedLength + // [1, 1] << fixedLengthWithOffset + // [0, 0, 1, 1, 2, 2, ...] << lengthTracking + // [1, 1, 2, 2, ...] << lengthTrackingWithOffset + + let n2 = MayNeedBigInt(fixedLength, 2); + + assert.sameValue(fixedLength.indexOf(n1), 2); + assert.sameValue(fixedLength.indexOf(n2), -1); + assert.sameValue(fixedLength.indexOf(undefined), -1); + assert.sameValue(fixedLengthWithOffset.indexOf(n0), -1); + assert.sameValue(fixedLengthWithOffset.indexOf(n1), 0); + assert.sameValue(fixedLengthWithOffset.indexOf(n2), -1); + assert.sameValue(fixedLengthWithOffset.indexOf(undefined), -1); + assert.sameValue(lengthTracking.indexOf(n1), 2); + assert.sameValue(lengthTracking.indexOf(n2), 4); + assert.sameValue(lengthTracking.indexOf(undefined), -1); + assert.sameValue(lengthTrackingWithOffset.indexOf(n0), -1); + assert.sameValue(lengthTrackingWithOffset.indexOf(n1), 0); + assert.sameValue(lengthTrackingWithOffset.indexOf(n2), 2); + assert.sameValue(lengthTrackingWithOffset.indexOf(undefined), -1); +} From 694fae5b10fa760951dbc9c2fe22a2fa38383c66 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Fri, 12 Jul 2024 18:32:10 +0200 Subject: [PATCH 13/90] RAB: Integrate staging tests for the .join method (#4137) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while applying review changes from PRs for previously tested methods. * Removes forgotten ArrayJoinHelper --- .../prototype/join/coerced-separator-grow.js | 38 +++++++ .../join/coerced-separator-shrink.js | 42 ++++++++ .../Array/prototype/join/resizable-buffer.js | 82 ++++++++++++++++ .../prototype/join/coerced-separator-grow.js | 38 +++++++ .../join/coerced-separator-shrink.js | 42 ++++++++ .../prototype/join/resizable-buffer.js | 98 +++++++++++++++++++ 6 files changed, 340 insertions(+) create mode 100644 test/built-ins/Array/prototype/join/coerced-separator-grow.js create mode 100644 test/built-ins/Array/prototype/join/coerced-separator-shrink.js create mode 100644 test/built-ins/Array/prototype/join/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/join/coerced-separator-grow.js create mode 100644 test/built-ins/TypedArray/prototype/join/coerced-separator-shrink.js create mode 100644 test/built-ins/TypedArray/prototype/join/resizable-buffer.js diff --git a/test/built-ins/Array/prototype/join/coerced-separator-grow.js b/test/built-ins/Array/prototype/join/coerced-separator-grow.js new file mode 100644 index 0000000000..37cce09032 --- /dev/null +++ b/test/built-ins/Array/prototype/join/coerced-separator-grow.js @@ -0,0 +1,38 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.join +description: > + Array.p.join behaves correctly when the receiver is grown during + argument coercion +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Growing + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + toString: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return '.'; + } + }; + assert.sameValue(Array.prototype.join.call(fixedLength, evil), '0.0.0.0'); +} + +// Growing + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + toString: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return '.'; + } + }; + // We iterate 4 elements, since it was the starting length. + assert.sameValue(Array.prototype.join.call(lengthTracking, evil), '0.0.0.0'); +} diff --git a/test/built-ins/Array/prototype/join/coerced-separator-shrink.js b/test/built-ins/Array/prototype/join/coerced-separator-shrink.js new file mode 100644 index 0000000000..302c433fad --- /dev/null +++ b/test/built-ins/Array/prototype/join/coerced-separator-shrink.js @@ -0,0 +1,42 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.join +description: > + Array.p.join behaves correctly when the receiver is shrunk during + argument coercion +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Shrinking + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + toString: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return '.'; + } + }; + // We iterate 4 elements, since it was the starting length, but the TA is + // OOB right after parameter conversion, so all elements are converted to + // the empty string. + assert.sameValue(Array.prototype.join.call(fixedLength, evil), '...'); +} + +// Shrinking + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + toString: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return '.'; + } + }; + // We iterate 4 elements, since it was the starting length. Elements beyond + // the new length are converted to the empty string. + assert.sameValue(Array.prototype.join.call(lengthTracking, evil), '0.0..'); +} diff --git a/test/built-ins/Array/prototype/join/resizable-buffer.js b/test/built-ins/Array/prototype/join/resizable-buffer.js new file mode 100644 index 0000000000..e28414ab00 --- /dev/null +++ b/test/built-ins/Array/prototype/join/resizable-buffer.js @@ -0,0 +1,82 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.join +description: > + Array.p.join behaves correctly when the receiver is backed by resizable + buffer +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taWrite = new ctor(rab); + + // Write some data into the array. + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert.sameValue(Array.prototype.join.call(fixedLength), '0,2,4,6'); + assert.sameValue(Array.prototype.join.call(fixedLengthWithOffset), '4,6'); + assert.sameValue(Array.prototype.join.call(lengthTracking), '0,2,4,6'); + assert.sameValue(Array.prototype.join.call(lengthTrackingWithOffset), '4,6'); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.sameValue(Array.prototype.join.call(fixedLength), ''); + assert.sameValue(Array.prototype.join.call(fixedLengthWithOffset), ''); + + assert.sameValue(Array.prototype.join.call(lengthTracking), '0,2,4'); + assert.sameValue(Array.prototype.join.call(lengthTrackingWithOffset), '4'); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.sameValue(Array.prototype.join.call(fixedLength), ''); + assert.sameValue(Array.prototype.join.call(fixedLengthWithOffset), ''); + assert.sameValue(Array.prototype.join.call(lengthTrackingWithOffset), ''); + + assert.sameValue(Array.prototype.join.call(lengthTracking), '0'); + + // Shrink to zero. + rab.resize(0); + assert.sameValue(Array.prototype.join.call(fixedLength), ''); + assert.sameValue(Array.prototype.join.call(fixedLengthWithOffset), ''); + assert.sameValue(Array.prototype.join.call(lengthTrackingWithOffset), ''); + + assert.sameValue(Array.prototype.join.call(lengthTracking), ''); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.sameValue(Array.prototype.join.call(fixedLength), '0,2,4,6'); + assert.sameValue(Array.prototype.join.call(fixedLengthWithOffset), '4,6'); + assert.sameValue(Array.prototype.join.call(lengthTracking), '0,2,4,6,8,10'); + assert.sameValue(Array.prototype.join.call(lengthTrackingWithOffset), '4,6,8,10'); +} diff --git a/test/built-ins/TypedArray/prototype/join/coerced-separator-grow.js b/test/built-ins/TypedArray/prototype/join/coerced-separator-grow.js new file mode 100644 index 0000000000..76cec6a13c --- /dev/null +++ b/test/built-ins/TypedArray/prototype/join/coerced-separator-grow.js @@ -0,0 +1,38 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.join +description: > + TypedArray.p.join behaves correctly when the receiver is grown during + argument coercion +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Growing + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + toString: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return '.'; + } + }; + assert.sameValue(fixedLength.join(evil), '0.0.0.0'); +} + +// Growing + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + toString: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return '.'; + } + }; + // We iterate 4 elements, since it was the starting length. + assert.sameValue(lengthTracking.join(evil), '0.0.0.0'); +} diff --git a/test/built-ins/TypedArray/prototype/join/coerced-separator-shrink.js b/test/built-ins/TypedArray/prototype/join/coerced-separator-shrink.js new file mode 100644 index 0000000000..aac4d7b108 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/join/coerced-separator-shrink.js @@ -0,0 +1,42 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.join +description: > + TypedArray.p.join behaves correctly when the receiver is shrunk during + argument coercion +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Shrinking + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + toString: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return '.'; + } + }; + // We iterate 4 elements, since it was the starting length, but the TA is + // OOB right after parameter conversion, so all elements are converted to + // the empty string. + assert.sameValue(fixedLength.join(evil), '...'); +} + +// Shrinking + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + toString: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return '.'; + } + }; + // We iterate 4 elements, since it was the starting length. Elements beyond + // the new length are converted to the empty string. + assert.sameValue(lengthTracking.join(evil), '0.0..'); +} diff --git a/test/built-ins/TypedArray/prototype/join/resizable-buffer.js b/test/built-ins/TypedArray/prototype/join/resizable-buffer.js new file mode 100644 index 0000000000..02d96a4f0c --- /dev/null +++ b/test/built-ins/TypedArray/prototype/join/resizable-buffer.js @@ -0,0 +1,98 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.join +description: > + TypedArray.p.join behaves correctly when the receiver is backed by resizable + buffer +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taWrite = new ctor(rab); + + // Write some data into the array. + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert.sameValue(fixedLength.join(), '0,2,4,6'); + assert.sameValue(fixedLengthWithOffset.join(), '4,6'); + assert.sameValue(lengthTracking.join(), '0,2,4,6'); + assert.sameValue(lengthTrackingWithOffset.join(), '4,6'); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + fixedLength.join(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.join(); + }); + + assert.sameValue(lengthTracking.join(), '0,2,4'); + assert.sameValue(lengthTrackingWithOffset.join(), '4'); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + fixedLength.join(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.join(); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.join(); + }); + + assert.sameValue(lengthTracking.join(), '0'); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + fixedLength.join(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.join(); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.join(); + }); + + assert.sameValue(lengthTracking.join(), ''); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.sameValue(fixedLength.join(), '0,2,4,6'); + assert.sameValue(fixedLengthWithOffset.join(), '4,6'); + assert.sameValue(lengthTracking.join(), '0,2,4,6,8,10'); + assert.sameValue(lengthTrackingWithOffset.join(), '4,6,8,10'); +} From c6a36ccc64b3153ee5baaa54f6a364d744da4e02 Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Sat, 13 Jul 2024 12:35:04 +0300 Subject: [PATCH 14/90] Add missing compareArray includes --- .../Uint8Array/prototype/setFromBase64/writes-up-to-error.js | 1 + .../Uint8Array/prototype/setFromHex/writes-up-to-error.js | 1 + 2 files changed, 2 insertions(+) diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/writes-up-to-error.js b/test/built-ins/Uint8Array/prototype/setFromBase64/writes-up-to-error.js index 4d11bf4959..f04ffad972 100644 --- a/test/built-ins/Uint8Array/prototype/setFromBase64/writes-up-to-error.js +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/writes-up-to-error.js @@ -3,6 +3,7 @@ /*--- esid: sec-uint8array.prototype.setfrombase64 description: Uint8Array.prototype.setFromBase64 decodes and writes chunks which occur prior to bad data +includes: [compareArray.js] features: [uint8array-base64, TypedArray] ---*/ diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/writes-up-to-error.js b/test/built-ins/Uint8Array/prototype/setFromHex/writes-up-to-error.js index 180e5ced84..4e58c18a5e 100644 --- a/test/built-ins/Uint8Array/prototype/setFromHex/writes-up-to-error.js +++ b/test/built-ins/Uint8Array/prototype/setFromHex/writes-up-to-error.js @@ -3,6 +3,7 @@ /*--- esid: sec-uint8array.prototype.setfromhex description: Uint8Array.prototype.setFromHex decodes and writes pairs which occur prior to bad data +includes: [compareArray.js] features: [uint8array-base64, TypedArray] ---*/ From 03ade8b46a7428b1c189a47df5dc621e3f2ec94f Mon Sep 17 00:00:00 2001 From: magic-akari Date: Mon, 15 Jul 2024 19:58:33 +0800 Subject: [PATCH 15/90] Add missing test for `Math.pow(1, NaN)` (#4149) --- test/built-ins/Math/pow/applying-the-exp-operator_A1.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/built-ins/Math/pow/applying-the-exp-operator_A1.js b/test/built-ins/Math/pow/applying-the-exp-operator_A1.js index 08a4911c1b..347987fa5e 100644 --- a/test/built-ins/Math/pow/applying-the-exp-operator_A1.js +++ b/test/built-ins/Math/pow/applying-the-exp-operator_A1.js @@ -18,7 +18,8 @@ base[5] = 0.000000000000001; base[6] = 1.7976931348623157E308; //largest finite number base[7] = +Infinity; base[8] = NaN; -var basenum = 9; +base[9] = 1; +var basenum = 10; for (var i = 0; i < basenum; i++) { assert.sameValue( From 5e602555d051db5364b8e7e7f28654bfcc3f683d Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Fri, 12 Jul 2024 22:52:58 -0700 Subject: [PATCH 16/90] features.txt: arraybuffer-transfer is stage 4 --- features.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/features.txt b/features.txt index 5721ffd2f8..58a6b831b0 100644 --- a/features.txt +++ b/features.txt @@ -41,10 +41,6 @@ import-assertions # https://github.com/tc39/proposal-json-modules json-modules -# ArrayBuffer transfer -# https://github.com/tc39/proposal-arraybuffer-transfer -arraybuffer-transfer - # Temporal # https://github.com/tc39/proposal-temporal Temporal @@ -129,6 +125,7 @@ Array.prototype.includes Array.prototype.values Atomics.waitAsync array-grouping +arraybuffer-transfer arrow-function async-iteration async-functions From 97cf4fd6e9625c4a53ba18eea6dc9cebb847bd0d Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Tue, 16 Jul 2024 18:25:18 +0200 Subject: [PATCH 17/90] RAB: Integrate staging tests for the .keys method (#4138) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while applying review changes from PRs for previously tested methods. * Removes redundant documentation * Address review comments. --- .../resizable-buffer-grow-mid-iteration.js | 60 ++++++++ .../resizable-buffer-shrink-mid-iteration.js | 53 +++++++ .../Array/prototype/keys/resizable-buffer.js | 142 ++++++++++++++++++ .../resizable-buffer-grow-mid-iteration.js | 60 ++++++++ .../resizable-buffer-shrink-mid-iteration.js | 53 +++++++ .../prototype/keys/resizable-buffer.js | 141 +++++++++++++++++ 6 files changed, 509 insertions(+) create mode 100644 test/built-ins/Array/prototype/keys/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/keys/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/keys/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/keys/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/keys/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/keys/resizable-buffer.js diff --git a/test/built-ins/Array/prototype/keys/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/keys/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..efc92706c7 --- /dev/null +++ b/test/built-ins/Array/prototype/keys/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,60 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.keys +description: > + Array.p.keys behaves correctly when receiver is backed by a resizable + buffer and is grown mid-iteration +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + // The fixed length array is not affected by resizing. + TestIterationAndResize(Array.prototype.keys.call(fixedLength), [ + 0, + 1, + 2, + 3 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + // The fixed length array is not affected by resizing. + TestIterationAndResize(Array.prototype.keys.call(fixedLengthWithOffset), [ + 0, + 1 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + TestIterationAndResize(Array.prototype.keys.call(lengthTracking), [ + 0, + 1, + 2, + 3, + 4, + 5 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + TestIterationAndResize(Array.prototype.keys.call(lengthTrackingWithOffset), [ + 0, + 1, + 2, + 3 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/Array/prototype/keys/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/Array/prototype/keys/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..c432b7309b --- /dev/null +++ b/test/built-ins/Array/prototype/keys/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,53 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.keys +description: > + Array.p.keys behaves correctly when receiver is backed by resizable + buffer that is shrunk mid-iteration +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + + // The fixed length array goes out of bounds when the RAB is resized. + assert.throws(TypeError, () => { + TestIterationAndResize(Array.prototype.keys.call(fixedLength), null, rab, 2, 3 * ctor.BYTES_PER_ELEMENT); + }); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + + // The fixed length array goes out of bounds when the RAB is resized. + assert.throws(TypeError, () => { + TestIterationAndResize(Array.prototype.keys.call(fixedLengthWithOffset), null, rab, 2, 3 * ctor.BYTES_PER_ELEMENT); + }); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + TestIterationAndResize(Array.prototype.keys.call(lengthTracking), [ + 0, + 1, + 2 + ], rab, 2, 3 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + TestIterationAndResize(Array.prototype.keys.call(lengthTrackingWithOffset), [ + 0, + 1 + ], rab, 2, 3 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/Array/prototype/keys/resizable-buffer.js b/test/built-ins/Array/prototype/keys/resizable-buffer.js new file mode 100644 index 0000000000..295ce3612b --- /dev/null +++ b/test/built-ins/Array/prototype/keys/resizable-buffer.js @@ -0,0 +1,142 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.keys +description: > + Array.p.keys behaves correctly when receiver is backed by resizable + buffer +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + assert.compareArray(Array.from(Array.prototype.keys.call(fixedLength)), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(Array.from(Array.prototype.keys.call(fixedLengthWithOffset)), [ + 0, + 1 + ]); + assert.compareArray(Array.from(Array.prototype.keys.call(lengthTracking)), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(Array.from(Array.prototype.keys.call(lengthTrackingWithOffset)), [ + 0, + 1 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + // TypedArray.prototype.{entries, keys, values} throw right away when + // called. Array.prototype.{entries, keys, values} don't throw, but when + // we try to iterate the returned ArrayIterator, that throws. + Array.prototype.keys.call(fixedLength); + Array.prototype.keys.call(fixedLengthWithOffset); + assert.throws(TypeError, () => { + Array.from(Array.prototype.keys.call(fixedLength)); + }); + assert.throws(TypeError, () => { + Array.from(Array.prototype.keys.call(fixedLengthWithOffset)); + }); + assert.compareArray(Array.from(Array.prototype.keys.call(lengthTracking)), [ + 0, + 1, + 2 + ]); + assert.compareArray(Array.from(Array.prototype.keys.call(lengthTrackingWithOffset)), [0]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + Array.prototype.keys.call(fixedLength); + Array.prototype.keys.call(fixedLengthWithOffset); + Array.prototype.keys.call(lengthTrackingWithOffset); + + assert.throws(TypeError, () => { + Array.from(Array.prototype.keys.call(fixedLength)); + }); + assert.throws(TypeError, () => { + Array.from(Array.prototype.keys.call(fixedLengthWithOffset)); + }); + assert.throws(TypeError, () => { + Array.from(Array.prototype.keys.call(lengthTrackingWithOffset)); + }); + assert.compareArray(Array.from(Array.prototype.keys.call(lengthTracking)), [0]); + + // Shrink to zero. + rab.resize(0); + Array.prototype.keys.call(fixedLength); + Array.prototype.keys.call(fixedLengthWithOffset); + Array.prototype.keys.call(lengthTrackingWithOffset); + + assert.throws(TypeError, () => { + Array.from(Array.prototype.keys.call(fixedLength)); + }); + assert.throws(TypeError, () => { + Array.from(Array.prototype.keys.call(fixedLengthWithOffset)); + }); + assert.throws(TypeError, () => { + Array.from(Array.prototype.keys.call(lengthTrackingWithOffset)); + }); + assert.compareArray(Array.from(Array.prototype.keys.call(lengthTracking)), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.compareArray(Array.from(Array.prototype.keys.call(fixedLength)), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(Array.from(Array.prototype.keys.call(fixedLengthWithOffset)), [ + 0, + 1 + ]); + assert.compareArray(Array.from(Array.prototype.keys.call(lengthTracking)), [ + 0, + 1, + 2, + 3, + 4, + 5 + ]); + assert.compareArray(Array.from(Array.prototype.keys.call(lengthTrackingWithOffset)), [ + 0, + 1, + 2, + 3 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/keys/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/keys/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..fadb221b1c --- /dev/null +++ b/test/built-ins/TypedArray/prototype/keys/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,60 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.keys +description: > + TypedArray.p.keys behaves correctly when receiver is backed by a resizable + buffer and is grown mid-iteration +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + // The fixed length array is not affected by resizing. + TestIterationAndResize(fixedLength.keys(), [ + 0, + 1, + 2, + 3 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + // The fixed length array is not affected by resizing. + TestIterationAndResize(fixedLengthWithOffset.keys(), [ + 0, + 1 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + TestIterationAndResize(lengthTracking.keys(), [ + 0, + 1, + 2, + 3, + 4, + 5 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + TestIterationAndResize(lengthTrackingWithOffset.keys(), [ + 0, + 1, + 2, + 3 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/TypedArray/prototype/keys/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/keys/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..86f03483d0 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/keys/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,53 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.keys +description: > + TypedArray.p.keys behaves correctly when receiver is backed by resizable + buffer that is shrunk mid-iteration +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + + // The fixed length array goes out of bounds when the RAB is resized. + assert.throws(TypeError, () => { + TestIterationAndResize(fixedLength.keys(), null, rab, 2, 3 * ctor.BYTES_PER_ELEMENT); + }); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + + // The fixed length array goes out of bounds when the RAB is resized. + assert.throws(TypeError, () => { + TestIterationAndResize(fixedLengthWithOffset.keys(), null, rab, 2, 3 * ctor.BYTES_PER_ELEMENT); + }); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + TestIterationAndResize(lengthTracking.keys(), [ + 0, + 1, + 2 + ], rab, 2, 3 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + TestIterationAndResize(lengthTrackingWithOffset.keys(), [ + 0, + 1 + ], rab, 2, 3 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/TypedArray/prototype/keys/resizable-buffer.js b/test/built-ins/TypedArray/prototype/keys/resizable-buffer.js new file mode 100644 index 0000000000..694087c7e8 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/keys/resizable-buffer.js @@ -0,0 +1,141 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.keys +description: > + TypedArray.p.keys behaves correctly when receiver is backed by resizable + buffer +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert.compareArray(Array.from(fixedLength.keys()), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(Array.from(fixedLengthWithOffset.keys()), [ + 0, + 1 + ]); + assert.compareArray(Array.from(lengthTracking.keys()), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(Array.from(lengthTrackingWithOffset.keys()), [ + 0, + 1 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + // TypedArray.prototype.{entries, keys, values} throw right away when + // called. Array.prototype.{entries, keys, values} don't throw, but when + // we try to iterate the returned ArrayIterator, that throws. + assert.throws(TypeError, () => { + fixedLength.keys(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.keys(); + }); + + assert.compareArray(Array.from(lengthTracking.keys()), [ + 0, + 1, + 2 + ]); + assert.compareArray(Array.from(lengthTrackingWithOffset.keys()), [0]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + fixedLength.keys(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.keys(); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.keys(); + }); + + assert.compareArray(Array.from(lengthTracking.keys()), [0]); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + fixedLength.keys(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.keys(); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.keys(); + }); + + assert.compareArray(Array.from(lengthTracking.keys()), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.compareArray(Array.from(fixedLength.keys()), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(Array.from(fixedLengthWithOffset.keys()), [ + 0, + 1 + ]); + assert.compareArray(Array.from(lengthTracking.keys()), [ + 0, + 1, + 2, + 3, + 4, + 5 + ]); + assert.compareArray(Array.from(lengthTrackingWithOffset.keys()), [ + 0, + 1, + 2, + 3 + ]); +} From 63e81baf5ba594aeec05782f85e6362f5cf06f3f Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Thu, 18 Jul 2024 02:37:17 +0200 Subject: [PATCH 18/90] RAB: Integrate staging tests for the .lastIndexOf method (#4153) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while applying review changes from PRs for previously tested methods. * Some changes for readability. --- .../lastIndexOf/coerced-position-grow.js | 57 +++++++ .../lastIndexOf/coerced-position-shrink.js | 66 ++++++++ .../prototype/lastIndexOf/resizable-buffer.js | 132 ++++++++++++++++ .../lastIndexOf/coerced-position-grow.js | 57 +++++++ .../lastIndexOf/coerced-position-shrink.js | 67 ++++++++ .../resizable-buffer-special-float-values.js | 26 +++ .../prototype/lastIndexOf/resizable-buffer.js | 148 ++++++++++++++++++ 7 files changed, 553 insertions(+) create mode 100644 test/built-ins/Array/prototype/lastIndexOf/coerced-position-grow.js create mode 100644 test/built-ins/Array/prototype/lastIndexOf/coerced-position-shrink.js create mode 100644 test/built-ins/Array/prototype/lastIndexOf/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/lastIndexOf/coerced-position-grow.js create mode 100644 test/built-ins/TypedArray/prototype/lastIndexOf/coerced-position-shrink.js create mode 100644 test/built-ins/TypedArray/prototype/lastIndexOf/resizable-buffer-special-float-values.js create mode 100644 test/built-ins/TypedArray/prototype/lastIndexOf/resizable-buffer.js diff --git a/test/built-ins/Array/prototype/lastIndexOf/coerced-position-grow.js b/test/built-ins/Array/prototype/lastIndexOf/coerced-position-grow.js new file mode 100644 index 0000000000..76f95eed3f --- /dev/null +++ b/test/built-ins/Array/prototype/lastIndexOf/coerced-position-grow.js @@ -0,0 +1,57 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.lastindexof +description: > + Array.p.lastIndexOf behaves correctly when the resizable buffer is grown by + argument coercion. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +// Growing + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, 1); + } + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -1; + } + }; + let n0 = MayNeedBigInt(lengthTracking, 0); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n0), -1); + // Because lastIndexOf iterates from the given index downwards, it's not + // possible to test that "we only look at the data until the original + // length" without also testing that the index conversion happening with the + // original length. + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n0, evil), -1); +} + +// Growing + length-tracking TA, index conversion. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -4; + } + }; + let n0 = MayNeedBigInt(lengthTracking, 0); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n0, -4), 0); + // The TA grew but the start index conversion is done based on the original + // length. + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n0, evil), 0); +} diff --git a/test/built-ins/Array/prototype/lastIndexOf/coerced-position-shrink.js b/test/built-ins/Array/prototype/lastIndexOf/coerced-position-shrink.js new file mode 100644 index 0000000000..13e07043b4 --- /dev/null +++ b/test/built-ins/Array/prototype/lastIndexOf/coerced-position-shrink.js @@ -0,0 +1,66 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.lastindexof +description: > + Array.p.lastIndexOf behaves correctly when the resizable buffer is shrunk by + argument coercion. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +// Shrinking + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 2; + } + }; + let n = MayNeedBigInt(fixedLength, 0); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n), 3); + // The TA is OOB so lastIndexOf returns -1. + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n, evil), -1); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 2; + } + }; + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, MayNeedBigInt(fixedLength, 0)), 3); + // The TA is OOB so lastIndexOf returns -1, also for undefined). + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, undefined, evil), -1); +} + +// Shrinking + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i); + } + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 2; + } + }; + let n = MayNeedBigInt(lengthTracking, 2); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n), 2); + // 2 no longer found. + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n, evil), -1); +} diff --git a/test/built-ins/Array/prototype/lastIndexOf/resizable-buffer.js b/test/built-ins/Array/prototype/lastIndexOf/resizable-buffer.js new file mode 100644 index 0000000000..5e93b68598 --- /dev/null +++ b/test/built-ins/Array/prototype/lastIndexOf/resizable-buffer.js @@ -0,0 +1,132 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.lastindexof +description: > + Array.p.lastIndexOf behaves correctly on TypedArrays backed by resizable + buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, Math.floor(i / 2)); + } + + // Orig. array: [0, 0, 1, 1] + // [0, 0, 1, 1] << fixedLength + // [1, 1] << fixedLengthWithOffset + // [0, 0, 1, 1, ...] << lengthTracking + // [1, 1, ...] << lengthTrackingWithOffset + + // If fixedLength is a BigInt array, they all are BigInt Arrays. + let n0 = MayNeedBigInt(fixedLength, 0); + let n1 = MayNeedBigInt(fixedLength, 1); + + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n0), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n0, 1), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n0, 2), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n0, -2), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n0, -3), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n1, 1), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n1, -2), 2); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n1, -3), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, undefined), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, n0), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, n1), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, n1, -2), 0); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, n1, -1), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, undefined), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n0), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n0, 2), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n0, -3), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n1, 1), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n1, 2), 2); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n1, -3), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, undefined), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n0), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n1), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n1, 1), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n1, -2), 0); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n1, -1), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, undefined), -1); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 0, 1] + // [0, 0, 1, ...] << lengthTracking + // [1, ...] << lengthTrackingWithOffset + + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n1), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, n1), -1); + + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n0), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, undefined), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n0), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n1), 0); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, undefined), -1); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n0), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, n0), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n0), -1); + + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n0), 0); + + // Shrink to zero. + rab.resize(0); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n0), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, n0), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n0), -1); + + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n0), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, undefined), -1); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, Math.floor(i / 2)); + } + + // Orig. array: [0, 0, 1, 1, 2, 2] + // [0, 0, 1, 1] << fixedLength + // [1, 1] << fixedLengthWithOffset + // [0, 0, 1, 1, 2, 2, ...] << lengthTracking + // [1, 1, 2, 2, ...] << lengthTrackingWithOffset + + let n2 = MayNeedBigInt(fixedLength, 2); + + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n1), 3); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, n2), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLength, undefined), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, n0), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, n1), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, n2), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(fixedLengthWithOffset, undefined), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n1), 3); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, n2), 5); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTracking, undefined), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n0), -1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n1), 1); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, n2), 3); + assert.sameValue(Array.prototype.lastIndexOf.call(lengthTrackingWithOffset, undefined), -1); +} diff --git a/test/built-ins/TypedArray/prototype/lastIndexOf/coerced-position-grow.js b/test/built-ins/TypedArray/prototype/lastIndexOf/coerced-position-grow.js new file mode 100644 index 0000000000..8ac8387581 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/lastIndexOf/coerced-position-grow.js @@ -0,0 +1,57 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.lastindexof +description: > + TypedArray.p.lastIndexOf behaves correctly on TypedArrays backed by resizable + buffers that are grown by argument coercion. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +// Growing + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, 1); + } + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -1; + } + }; + let n0 = MayNeedBigInt(lengthTracking, 0); + assert.sameValue(lengthTracking.lastIndexOf(n0), -1); + // Because lastIndexOf iterates from the given index downwards, it's not + // possible to test that "we only look at the data until the original + // length" without also testing that the index conversion happening with the + // original length. + assert.sameValue(lengthTracking.lastIndexOf(n0, evil), -1); +} + +// Growing + length-tracking TA, index conversion. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -4; + } + }; + let n0 = MayNeedBigInt(lengthTracking, 0); + assert.sameValue(lengthTracking.lastIndexOf(n0, -4), 0); + // The TA grew but the start index conversion is done based on the original + // length. + assert.sameValue(lengthTracking.lastIndexOf(n0, evil), 0); +} diff --git a/test/built-ins/TypedArray/prototype/lastIndexOf/coerced-position-shrink.js b/test/built-ins/TypedArray/prototype/lastIndexOf/coerced-position-shrink.js new file mode 100644 index 0000000000..2879e776ed --- /dev/null +++ b/test/built-ins/TypedArray/prototype/lastIndexOf/coerced-position-shrink.js @@ -0,0 +1,67 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.lastindexof +description: > + TypedArray.p.lastIndexOf behaves correctly on TypedArrays backed by resizable + buffers that are shrunk by argument coercion. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +// Shrinking + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 2; + } + }; + let n0 = MayNeedBigInt(fixedLength, 0); + assert.sameValue(fixedLength.lastIndexOf(n0), 3); + // The TA is OOB so lastIndexOf returns -1. + assert.sameValue(fixedLength.lastIndexOf(n0, evil), -1); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 2; + } + }; + let n0 = MayNeedBigInt(fixedLength, 0); + assert.sameValue(fixedLength.lastIndexOf(n0), 3); + // The TA is OOB so lastIndexOf returns -1, also for undefined). + assert.sameValue(fixedLength.lastIndexOf(undefined, evil), -1); +} + +// Shrinking + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i); + } + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 2; + } + }; + let n2 = MayNeedBigInt(lengthTracking, 2); + assert.sameValue(lengthTracking.lastIndexOf(n2), 2); + // 2 no longer found. + assert.sameValue(lengthTracking.lastIndexOf(n2, evil), -1); +} diff --git a/test/built-ins/TypedArray/prototype/lastIndexOf/resizable-buffer-special-float-values.js b/test/built-ins/TypedArray/prototype/lastIndexOf/resizable-buffer-special-float-values.js new file mode 100644 index 0000000000..99e7991de2 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/lastIndexOf/resizable-buffer-special-float-values.js @@ -0,0 +1,26 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.lastindexof +description: > + TypedArray.p.lastIndexOf behaves correctly for special float values on float + TypedArrays backed by resizable buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer, Array.prototype.includes] +---*/ + +for (let ctor of floatCtors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + lengthTracking[0] = -Infinity; + lengthTracking[1] = -Infinity; + lengthTracking[2] = Infinity; + lengthTracking[3] = Infinity; + lengthTracking[4] = NaN; + lengthTracking[5] = NaN; + assert.sameValue(lengthTracking.lastIndexOf(-Infinity), 1); + assert.sameValue(lengthTracking.lastIndexOf(Infinity), 3); + // NaN is never found. + assert.sameValue(lengthTracking.lastIndexOf(NaN), -1); +} diff --git a/test/built-ins/TypedArray/prototype/lastIndexOf/resizable-buffer.js b/test/built-ins/TypedArray/prototype/lastIndexOf/resizable-buffer.js new file mode 100644 index 0000000000..bba8d75a97 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/lastIndexOf/resizable-buffer.js @@ -0,0 +1,148 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.lastindexof +description: > + TypedArray.p.lastIndexOf behaves correctly on TypedArrays backed by resizable + buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, n) { + if (typeof n == 'number' && (ta instanceof BigInt64Array || ta instanceof BigUint64Array)) { + return BigInt(n); + } + return n; +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, Math.floor(i / 2)); + } + + // Orig. array: [0, 0, 1, 1] + // [0, 0, 1, 1] << fixedLength + // [1, 1] << fixedLengthWithOffset + // [0, 0, 1, 1, ...] << lengthTracking + // [1, 1, ...] << lengthTrackingWithOffset + + // If fixedLength is a BigInt array, they all are BigInt Arrays. + let n0 = MayNeedBigInt(fixedLength, 0); + let n1 = MayNeedBigInt(fixedLength, 1); + + assert.sameValue(fixedLength.lastIndexOf(n0), 1); + assert.sameValue(fixedLength.lastIndexOf(n0, 1), 1); + assert.sameValue(fixedLength.lastIndexOf(n0, 2), 1); + assert.sameValue(fixedLength.lastIndexOf(n0, -2), 1); + assert.sameValue(fixedLength.lastIndexOf(n0, -3), 1); + assert.sameValue(fixedLength.lastIndexOf(n1, 1), -1); + assert.sameValue(fixedLength.lastIndexOf(n1, -2), 2); + assert.sameValue(fixedLength.lastIndexOf(n1, -3), -1); + assert.sameValue(fixedLength.lastIndexOf(undefined), -1); + assert.sameValue(fixedLengthWithOffset.lastIndexOf(n0), -1); + assert.sameValue(fixedLengthWithOffset.lastIndexOf(n1), 1); + assert.sameValue(fixedLengthWithOffset.lastIndexOf(n1, -2), 0); + assert.sameValue(fixedLengthWithOffset.lastIndexOf(n1, -1), 1); + assert.sameValue(fixedLengthWithOffset.lastIndexOf(undefined), -1); + assert.sameValue(lengthTracking.lastIndexOf(n0), 1); + assert.sameValue(lengthTracking.lastIndexOf(n0, 2), 1); + assert.sameValue(lengthTracking.lastIndexOf(n0, -3), 1); + assert.sameValue(lengthTracking.lastIndexOf(n1, 1), -1); + assert.sameValue(lengthTracking.lastIndexOf(n1, 2), 2); + assert.sameValue(lengthTracking.lastIndexOf(n1, -3), -1); + assert.sameValue(lengthTracking.lastIndexOf(undefined), -1); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(n0), -1); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(n1), 1); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(n1, 1), 1); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(n1, -2), 0); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(n1, -1), 1); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(undefined), -1); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 0, 1] + // [0, 0, 1, ...] << lengthTracking + // [1, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + fixedLength.lastIndexOf(n1); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.lastIndexOf(n1); + }); + + assert.sameValue(lengthTracking.lastIndexOf(n0), 1); + assert.sameValue(lengthTracking.lastIndexOf(undefined), -1); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(n0), -1); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(n1), 0); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(undefined), -1); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + fixedLength.lastIndexOf(n0); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.lastIndexOf(n0); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.lastIndexOf(n0); + }); + + assert.sameValue(lengthTracking.lastIndexOf(n0), 0); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + fixedLength.lastIndexOf(n0); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.lastIndexOf(n0); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.lastIndexOf(n0); + }); + + assert.sameValue(lengthTracking.lastIndexOf(n0), -1); + assert.sameValue(lengthTracking.lastIndexOf(undefined), -1); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, Math.floor(i / 2)); + } + + // Orig. array: [0, 0, 1, 1, 2, 2] + // [0, 0, 1, 1] << fixedLength + // [1, 1] << fixedLengthWithOffset + // [0, 0, 1, 1, 2, 2, ...] << lengthTracking + // [1, 1, 2, 2, ...] << lengthTrackingWithOffset + + let n2 = MayNeedBigInt(fixedLength, 2); + + assert.sameValue(fixedLength.lastIndexOf(n1), 3); + assert.sameValue(fixedLength.lastIndexOf(n2), -1); + assert.sameValue(fixedLength.lastIndexOf(undefined), -1); + assert.sameValue(fixedLengthWithOffset.lastIndexOf(n0), -1); + assert.sameValue(fixedLengthWithOffset.lastIndexOf(n1), 1); + assert.sameValue(fixedLengthWithOffset.lastIndexOf(n2), -1); + assert.sameValue(fixedLengthWithOffset.lastIndexOf(undefined), -1); + assert.sameValue(lengthTracking.lastIndexOf(n1), 3); + assert.sameValue(lengthTracking.lastIndexOf(n2), 5); + assert.sameValue(lengthTracking.lastIndexOf(undefined), -1); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(n0), -1); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(n1), 1); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(n2), 3); + assert.sameValue(lengthTrackingWithOffset.lastIndexOf(undefined), -1); +} From d09ecdb57b7cbf6eee1735b82dfd3b90504f3a74 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Thu, 18 Jul 2024 13:39:59 +0900 Subject: [PATCH 19/90] Use spaces instead of tabs --- test/built-ins/Array/prototype/every/15.4.4.16-3-23.js | 4 ++-- test/built-ins/Array/prototype/reduceRight/15.4.4.22-3-23.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/built-ins/Array/prototype/every/15.4.4.16-3-23.js b/test/built-ins/Array/prototype/every/15.4.4.16-3-23.js index 6a064d73f2..5228e43c8e 100644 --- a/test/built-ins/Array/prototype/every/15.4.4.16-3-23.js +++ b/test/built-ins/Array/prototype/every/15.4.4.16-3-23.js @@ -33,8 +33,8 @@ var child = new Con(); Object.defineProperty(child, "toString", { value: function() { - toStringAccessed = true; - return '1'; + toStringAccessed = true; + return '1'; } }); diff --git a/test/built-ins/Array/prototype/reduceRight/15.4.4.22-3-23.js b/test/built-ins/Array/prototype/reduceRight/15.4.4.22-3-23.js index 71af713dae..7d3c87fbcc 100644 --- a/test/built-ins/Array/prototype/reduceRight/15.4.4.22-3-23.js +++ b/test/built-ins/Array/prototype/reduceRight/15.4.4.22-3-23.js @@ -37,8 +37,8 @@ function callbackfn(prevVal, curVal, idx, obj) { Object.defineProperty(child, "toString", { value: function() { - toStringAccessed = true; - return '1'; + toStringAccessed = true; + return '1'; } }); From 880f8a5ba64d4e9df02e4c961e5abb9dec380f2b Mon Sep 17 00:00:00 2001 From: Leo Balter <301201+leobalter@users.noreply.github.com> Date: Fri, 28 Jun 2024 13:25:06 -0700 Subject: [PATCH 20/90] Add tests for RegExp.escape --- features.txt | 4 + test/built-ins/RegExp/escape/cross-realm.js | 17 ++ .../escape/escaped-control-characters.js | 25 +++ .../RegExp/escape/escaped-lineterminator.js | 48 ++++++ .../RegExp/escape/escaped-otherpunctuators.js | 58 +++++++ .../escape/escaped-solidus-character-mixed.js | 17 ++ .../escaped-solidus-character-simple.js | 18 ++ .../RegExp/escape/escaped-surrogates.js | 97 +++++++++++ .../escape/escaped-syntax-characters-mixed.js | 35 ++++ .../escaped-syntax-characters-simple.js | 29 ++++ .../escape/escaped-utf16encodecodepoint.js | 35 ++++ .../RegExp/escape/escaped-whitespace.js | 55 ++++++ .../RegExp/escape/initial-char-escape.js | 156 ++++++++++++++++++ test/built-ins/RegExp/escape/is-function.js | 12 ++ test/built-ins/RegExp/escape/length.js | 19 +++ test/built-ins/RegExp/escape/name.js | 19 +++ .../RegExp/escape/non-string-inputs.js | 22 +++ .../RegExp/escape/not-a-constructor.js | 28 ++++ .../RegExp/escape/not-escaped-underscore.js | 23 +++ test/built-ins/RegExp/escape/not-escaped.js | 33 ++++ test/built-ins/RegExp/escape/prop-desc.js | 17 ++ 21 files changed, 767 insertions(+) create mode 100644 test/built-ins/RegExp/escape/cross-realm.js create mode 100644 test/built-ins/RegExp/escape/escaped-control-characters.js create mode 100644 test/built-ins/RegExp/escape/escaped-lineterminator.js create mode 100644 test/built-ins/RegExp/escape/escaped-otherpunctuators.js create mode 100644 test/built-ins/RegExp/escape/escaped-solidus-character-mixed.js create mode 100644 test/built-ins/RegExp/escape/escaped-solidus-character-simple.js create mode 100644 test/built-ins/RegExp/escape/escaped-surrogates.js create mode 100644 test/built-ins/RegExp/escape/escaped-syntax-characters-mixed.js create mode 100644 test/built-ins/RegExp/escape/escaped-syntax-characters-simple.js create mode 100644 test/built-ins/RegExp/escape/escaped-utf16encodecodepoint.js create mode 100644 test/built-ins/RegExp/escape/escaped-whitespace.js create mode 100644 test/built-ins/RegExp/escape/initial-char-escape.js create mode 100644 test/built-ins/RegExp/escape/is-function.js create mode 100644 test/built-ins/RegExp/escape/length.js create mode 100644 test/built-ins/RegExp/escape/name.js create mode 100644 test/built-ins/RegExp/escape/non-string-inputs.js create mode 100644 test/built-ins/RegExp/escape/not-a-constructor.js create mode 100644 test/built-ins/RegExp/escape/not-escaped-underscore.js create mode 100644 test/built-ins/RegExp/escape/not-escaped.js create mode 100644 test/built-ins/RegExp/escape/prop-desc.js diff --git a/features.txt b/features.txt index 58a6b831b0..566686c661 100644 --- a/features.txt +++ b/features.txt @@ -68,6 +68,10 @@ Array.fromAsync # https://github.com/tc39/proposal-json-parse-with-source json-parse-with-source +# RegExp.escape +# https://github.com/tc39/proposal-regex-escaping +RegExp.escape + # Regular expression modifiers # https://github.com/tc39/proposal-regexp-modifiers regexp-modifiers diff --git a/test/built-ins/RegExp/escape/cross-realm.js b/test/built-ins/RegExp/escape/cross-realm.js new file mode 100644 index 0000000000..71535b578b --- /dev/null +++ b/test/built-ins/RegExp/escape/cross-realm.js @@ -0,0 +1,17 @@ +// Copyright 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: escape called with a RegExp object from another realm +features: [RegExp.escape, cross-realm] +---*/ + +const str = "oi+hello"; +const other = $262.createRealm().global; + +assert.sameValue(typeof other.RegExp.escape, "function", "other.RegExp.escape is a function"); + +const res = other.RegExp.escape.call(RegExp, str); + +assert.sameValue(res, RegExp.escape(str), "cross-realm escape works correctly"); diff --git a/test/built-ins/RegExp/escape/escaped-control-characters.js b/test/built-ins/RegExp/escape/escaped-control-characters.js new file mode 100644 index 0000000000..082dcba4b6 --- /dev/null +++ b/test/built-ins/RegExp/escape/escaped-control-characters.js @@ -0,0 +1,25 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-encodeforregexescape +description: Encodes control characters with their ControlEscape sequences +info: | + EncodeForRegExpEscape ( c ) + + 2. If c is the code point listed in some cell of the “Code Point” column of Table 64, then + a. Return the string-concatenation of 0x005C (REVERSE SOLIDUS) and the string in the “ControlEscape” column of the row whose “Code Point” column contains c. + + ControlEscape, Numeric Value, Code Point, Unicode Name, Symbol + t 9 U+0009 CHARACTER TABULATION + n 10 U+000A LINE FEED (LF) + v 11 U+000B LINE TABULATION + f 12 U+000C FORM FEED (FF) + r 13 U+000D CARRIAGE RETURN (CR) +features: [RegExp.escape] +---*/ + +const controlCharacters = '\t\n\v\f\r'; +const expectedEscapedCharacters = '\\t\\n\\v\\f\\r'; + +assert.sameValue(RegExp.escape(controlCharacters), expectedEscapedCharacters, 'Control characters are correctly escaped'); diff --git a/test/built-ins/RegExp/escape/escaped-lineterminator.js b/test/built-ins/RegExp/escape/escaped-lineterminator.js new file mode 100644 index 0000000000..968d81f6ad --- /dev/null +++ b/test/built-ins/RegExp/escape/escaped-lineterminator.js @@ -0,0 +1,48 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: Escaped lineterminator characters (simple assertions) +info: | + EncodeForRegExpEscape ( c ) + + ... + 3. Let otherPunctuators be the string-concatenation of ",-=<>#&!%:;@~'`" and the code unit 0x0022 (QUOTATION MARK). + 4. Let toEscape be StringToCodePoints(otherPunctuators). + 5. If toEscape ..., c is matched by WhiteSpace or LineTerminator, ..., then + a. If c ≤ 0xFF, then + i. Let hex be Number::toString(𝔽(c), 16). + ii. Return the string-concatenation of the code unit 0x005C (REVERSE SOLIDUS), "x", and StringPad(hex, 2, "0", START). + b. Let escaped be the empty String. + c. Let codeUnits be UTF16EncodeCodePoint(c). + d. For each code unit cu of codeUnits, do + i. Set escaped to the string-concatenation of escaped and UnicodeEscape(cu). + e. Return escaped. + 6. Return UTF16EncodeCodePoint(c). + + LineTerminator :: + + + + + + Exceptions: + + 2. If c is the code point listed in some cell of the “Code Point” column of Table 64, then + a. Return the string-concatenation of 0x005C (REVERSE SOLIDUS) and the string in the “ControlEscape” column of the row whose “Code Point” column contains c. + + ControlEscape, Numeric Value, Code Point, Unicode Name, Symbol + t 9 U+0009 CHARACTER TABULATION + n 10 U+000A LINE FEED (LF) + v 11 U+000B LINE TABULATION + f 12 U+000C FORM FEED (FF) + r 13 U+000D CARRIAGE RETURN (CR) +features: [RegExp.escape] +---*/ + +assert.sameValue(RegExp.escape('\u2028'), '\\u2028', 'line terminator \\u2028 is escaped correctly to \\u2028'); +assert.sameValue(RegExp.escape('\u2029'), '\\u2029', 'line terminator \\u2029 is escaped correctly to \\u2029'); + +assert.sameValue(RegExp.escape('\u2028\u2029'), '\\u2028\\u2029', 'line terminators are escaped correctly'); +assert.sameValue(RegExp.escape('\u2028a\u2029a'), '\\u2028a\\u2029a', 'mixed line terminators are escaped correctly'); diff --git a/test/built-ins/RegExp/escape/escaped-otherpunctuators.js b/test/built-ins/RegExp/escape/escaped-otherpunctuators.js new file mode 100644 index 0000000000..edd8009ee8 --- /dev/null +++ b/test/built-ins/RegExp/escape/escaped-otherpunctuators.js @@ -0,0 +1,58 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: Escaped other punctuators characters +info: | + EncodeForRegExpEscape ( c ) + + ... + 3. Let otherPunctuators be the string-concatenation of ",-=<>#&!%:;@~'`" and the code unit 0x0022 (QUOTATION MARK). + 4. Let toEscape be StringToCodePoints(otherPunctuators). + 5. If toEscape contains c, (...), then + a. If c ≤ 0xFF, then + i. Let hex be Number::toString(𝔽(c), 16). + ii. Return the string-concatenation of the code unit 0x005C (REVERSE SOLIDUS), "x", and StringPad(hex, 2, "0", START). + b. Let escaped be the empty String. + c. Let codeUnits be UTF16EncodeCodePoint(c). + d. For each code unit cu of codeUnits, do + i. Set escaped to the string-concatenation of escaped and UnicodeEscape(cu). + e. Return escaped. + 6. Return UTF16EncodeCodePoint(c). + + codePoints + 0x002c , + 0x002d - + 0x003d = + 0x003c < + 0x003e > + 0x0023 # + 0x0026 & + 0x0021 ! + 0x0025 % + 0x003a : + 0x003b ; + 0x0040 @ + 0x007e ~ + 0x0027 ' + 0x0060 ` + 0x0022 " +features: [RegExp.escape] +---*/ + +const otherPunctuators = ",-=<>#&!%:;@~'`\""; + +// Return the string-concatenation of the code unit 0x005C (REVERSE SOLIDUS), "x", and StringPad(hex, 2, "0", START). +for (const c of otherPunctuators) { + const expected = `\\x${c.codePointAt(0).toString(16)}`; + assert.sameValue(RegExp.escape(c), expected, `${c} is escaped correctly`); +} + +const otherPunctuatorsExpected = "\\x2c\\x2d\\x3d\\x3c\\x3e\\x23\\x26\\x21\\x25\\x3a\\x3b\\x40\\x7e\\x27\\x60\\x22"; + +assert.sameValue( + RegExp.escape(otherPunctuators), + otherPunctuatorsExpected, + 'all other punctuators are escaped correctly' +); diff --git a/test/built-ins/RegExp/escape/escaped-solidus-character-mixed.js b/test/built-ins/RegExp/escape/escaped-solidus-character-mixed.js new file mode 100644 index 0000000000..f5a1889ca3 --- /dev/null +++ b/test/built-ins/RegExp/escape/escaped-solidus-character-mixed.js @@ -0,0 +1,17 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: Escaped U+002F (SOLIDUS) characters (mixed assertions) +info: | + EncodeForRegExpEscape ( c ) + + 1. If c is matched by SyntaxCharacter or c is U+002F (SOLIDUS), then + a. Return the string-concatenation of 0x005C (REVERSE SOLIDUS) and UTF16EncodeCodePoint(c). +features: [RegExp.escape] +---*/ + +assert.sameValue(RegExp.escape('.a/b'), '\\.a\\/b', 'mixed string with solidus character is escaped correctly'); +assert.sameValue(RegExp.escape('/./'), '\\/\\.\\/', 'solidus character is escaped correctly - regexp similar'); +assert.sameValue(RegExp.escape('./a\\/*b+c?d^e$f|g{2}h[i]j\\k'), '\\.\\/a\\\\\\/\\*b\\+c\\?d\\^e\\$f\\|g\\{2\\}h\\[i\\]j\\\\k', 'complex string with multiple special characters is escaped correctly'); diff --git a/test/built-ins/RegExp/escape/escaped-solidus-character-simple.js b/test/built-ins/RegExp/escape/escaped-solidus-character-simple.js new file mode 100644 index 0000000000..955d7652d4 --- /dev/null +++ b/test/built-ins/RegExp/escape/escaped-solidus-character-simple.js @@ -0,0 +1,18 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: Escaped U+002F (SOLIDUS) character (simple assertions) +info: | + EncodeForRegExpEscape ( c ) + + 1. If c is matched by SyntaxCharacter or c is U+002F (SOLIDUS), then + a. Return the string-concatenation of 0x005C (REVERSE SOLIDUS) and UTF16EncodeCodePoint(c). +features: [RegExp.escape] +---*/ + +assert.sameValue(RegExp.escape('/'), '\\/', 'solidus character is escaped correctly'); +assert.sameValue(RegExp.escape('//'), '\\/\\/', 'solidus character is escaped correctly - multiple occurrences 1'); +assert.sameValue(RegExp.escape('///'), '\\/\\/\\/', 'solidus character is escaped correctly - multiple occurrences 2'); +assert.sameValue(RegExp.escape('////'), '\\/\\/\\/\\/', 'solidus character is escaped correctly - multiple occurrences 3'); diff --git a/test/built-ins/RegExp/escape/escaped-surrogates.js b/test/built-ins/RegExp/escape/escaped-surrogates.js new file mode 100644 index 0000000000..d7787288f6 --- /dev/null +++ b/test/built-ins/RegExp/escape/escaped-surrogates.js @@ -0,0 +1,97 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-encodeforregexescape +description: Encodes surrogates correctly +info: | + EncodeForRegExpEscape ( c ) + + 4. Let toEscape be StringToCodePoints(otherPunctuators). + 5. If toEscape contains c, c is matched by WhiteSpace or LineTerminator, or c has the same numeric value as a leading surrogate or trailing surrogate, then + a. If c ≤ 0xFF, then + ... + b. Let escaped be the empty String. + c. Let codeUnits be UTF16EncodeCodePoint(c). + d. For each code unit cu of codeUnits, do + i. Set escaped to the string-concatenation of escaped and UnicodeEscape(cu). + e. Return escaped. + 6. Return UTF16EncodeCodePoint(c). +features: [RegExp.escape] +---*/ + +// Specific surrogate points +assert.sameValue(RegExp.escape('\uD800'), '\\ud800', 'High surrogate \\uD800 is correctly escaped'); +assert.sameValue(RegExp.escape('\uDBFF'), '\\udbff', 'High surrogate \\uDBFF is correctly escaped'); +assert.sameValue(RegExp.escape('\uDC00'), '\\udc00', 'Low surrogate \\uDC00 is correctly escaped'); +assert.sameValue(RegExp.escape('\uDFFF'), '\\udfff', 'Low surrogate \\uDFFF is correctly escaped'); + +// Leading Surrogates +const highSurrogatesGroup1 = '\uD800\uD801\uD802\uD803\uD804\uD805\uD806\uD807\uD808\uD809\uD80A\uD80B\uD80C\uD80D\uD80E\uD80F'; +const highSurrogatesGroup2 = '\uD810\uD811\uD812\uD813\uD814\uD815\uD816\uD817\uD818\uD819\uD81A\uD81B\uD81C\uD81D\uD81E\uD81F'; +const highSurrogatesGroup3 = '\uD820\uD821\uD822\uD823\uD824\uD825\uD826\uD827\uD828\uD829\uD82A\uD82B\uD82C\uD82D\uD82E\uD82F'; +const highSurrogatesGroup4 = '\uD830\uD831\uD832\uD833\uD834\uD835\uD836\uD837\uD838\uD839\uD83A\uD83B\uD83C\uD83D\uD83E\uD83F'; +const highSurrogatesGroup5 = '\uD840\uD841\uD842\uD843\uD844\uD845\uD846\uD847\uD848\uD849\uD84A\uD84B\uD84C\uD84D\uD84E\uD84F'; +const highSurrogatesGroup6 = '\uD850\uD851\uD852\uD853\uD854\uD855\uD856\uD857\uD858\uD859\uD85A\uD85B\uD85C\uD85D\uD85E\uD85F'; +const highSurrogatesGroup7 = '\uD860\uD861\uD862\uD863\uD864\uD865\uD866\uD867\uD868\uD869\uD86A\uD86B\uD86C\uD86D\uD86E\uD86F'; +const highSurrogatesGroup8 = '\uD870\uD871\uD872\uD873\uD874\uD875\uD876\uD877\uD878\uD879\uD87A\uD87B\uD87C\uD87D\uD87E\uD87F'; +const highSurrogatesGroup9 = '\uD880\uD881\uD882\uD883\uD884\uD885\uD886\uD887\uD888\uD889\uD88A\uD88B\uD88C\uD88D\uD88E\uD88F'; +const highSurrogatesGroup10 = '\uD890\uD891\uD892\uD893\uD894\uD895\uD896\uD897\uD898\uD899\uD89A\uD89B\uD89C\uD89D\uD89E\uD89F'; +const highSurrogatesGroup11 = '\uD8A0\uD8A1\uD8A2\uD8A3\uD8A4\uD8A5\uD8A6\uD8A7\uD8A8\uD8A9\uD8AA\uD8AB\uD8AC\uD8AD\uD8AE\uD8AF'; +const highSurrogatesGroup12 = '\uD8B0\uD8B1\uD8B2\uD8B3\uD8B4\uD8B5\uD8B6\uD8B7\uD8B8\uD8B9\uD8BA\uD8BB\uD8BC\uD8BD\uD8BE\uD8BF'; +const highSurrogatesGroup13 = '\uD8C0\uD8C1\uD8C2\uD8C3\uD8C4\uD8C5\uD8C6\uD8C7\uD8C8\uD8C9\uD8CA\uD8CB\uD8CC\uD8CD\uD8CE\uD8CF'; +const highSurrogatesGroup14 = '\uD8D0\uD8D1\uD8D2\uD8D3\uD8D4\uD8D5\uD8D6\uD8D7\uD8D8\uD8D9\uD8DA\uD8DB\uD8DC\uD8DD\uD8DE\uD8DF'; +const highSurrogatesGroup15 = '\uD8E0\uD8E1\uD8E2\uD8E3\uD8E4\uD8E5\uD8E6\uD8E7\uD8E8\uD8E9\uD8EA\uD8EB\uD8EC\uD8ED\uD8EE\uD8EF'; +const highSurrogatesGroup16 = '\uD8F0\uD8F1\uD8F2\uD8F3\uD8F4\uD8F5\uD8F6\uD8F7\uD8F8\uD8F9\uD8FA\uD8FB\uD8FC\uD8FD\uD8FE\uD8FF'; + +assert.sameValue(RegExp.escape(highSurrogatesGroup1), '\\ud800\\ud801\\ud802\\ud803\\ud804\\ud805\\ud806\\ud807\\ud808\\ud809\\ud80a\\ud80b\\ud80c\\ud80d\\ud80e\\ud80f', 'High surrogates group 1 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup2), '\\ud810\\ud811\\ud812\\ud813\\ud814\\ud815\\ud816\\ud817\\ud818\\ud819\\ud81a\\ud81b\\ud81c\\ud81d\\ud81e\\ud81f', 'High surrogates group 2 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup3), '\\ud820\\ud821\\ud822\\ud823\\ud824\\ud825\\ud826\\ud827\\ud828\\ud829\\ud82a\\ud82b\\ud82c\\ud82d\\ud82e\\ud82f', 'High surrogates group 3 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup4), '\\ud830\\ud831\\ud832\\ud833\\ud834\\ud835\\ud836\\ud837\\ud838\\ud839\\ud83a\\ud83b\\ud83c\\ud83d\\ud83e\\ud83f', 'High surrogates group 4 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup5), '\\ud840\\ud841\\ud842\\ud843\\ud844\\ud845\\ud846\\ud847\\ud848\\ud849\\ud84a\\ud84b\\ud84c\\ud84d\\ud84e\\ud84f', 'High surrogates group 5 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup6), '\\ud850\\ud851\\ud852\\ud853\\ud854\\ud855\\ud856\\ud857\\ud858\\ud859\\ud85a\\ud85b\\ud85c\\ud85d\\ud85e\\ud85f', 'High surrogates group 6 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup7), '\\ud860\\ud861\\ud862\\ud863\\ud864\\ud865\\ud866\\ud867\\ud868\\ud869\\ud86a\\ud86b\\ud86c\\ud86d\\ud86e\\ud86f', 'High surrogates group 7 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup8), '\\ud870\\ud871\\ud872\\ud873\\ud874\\ud875\\ud876\\ud877\\ud878\\ud879\\ud87a\\ud87b\\ud87c\\ud87d\\ud87e\\ud87f', 'High surrogates group 8 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup9), '\\ud880\\ud881\\ud882\\ud883\\ud884\\ud885\\ud886\\ud887\\ud888\\ud889\\ud88a\\ud88b\\ud88c\\ud88d\\ud88e\\ud88f', 'High surrogates group 9 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup10), '\\ud890\\ud891\\ud892\\ud893\\ud894\\ud895\\ud896\\ud897\\ud898\\ud899\\ud89a\\ud89b\\ud89c\\ud89d\\ud89e\\ud89f', 'High surrogates group 10 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup11), '\\ud8a0\\ud8a1\\ud8a2\\ud8a3\\ud8a4\\ud8a5\\ud8a6\\ud8a7\\ud8a8\\ud8a9\\ud8aa\\ud8ab\\ud8ac\\ud8ad\\ud8ae\\ud8af', 'High surrogates group 11 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup12), '\\ud8b0\\ud8b1\\ud8b2\\ud8b3\\ud8b4\\ud8b5\\ud8b6\\ud8b7\\ud8b8\\ud8b9\\ud8ba\\ud8bb\\ud8bc\\ud8bd\\ud8be\\ud8bf', 'High surrogates group 12 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup13), '\\ud8c0\\ud8c1\\ud8c2\\ud8c3\\ud8c4\\ud8c5\\ud8c6\\ud8c7\\ud8c8\\ud8c9\\ud8ca\\ud8cb\\ud8cc\\ud8cd\\ud8ce\\ud8cf', 'High surrogates group 13 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup14), '\\ud8d0\\ud8d1\\ud8d2\\ud8d3\\ud8d4\\ud8d5\\ud8d6\\ud8d7\\ud8d8\\ud8d9\\ud8da\\ud8db\\ud8dc\\ud8dd\\ud8de\\ud8df', 'High surrogates group 14 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup15), '\\ud8e0\\ud8e1\\ud8e2\\ud8e3\\ud8e4\\ud8e5\\ud8e6\\ud8e7\\ud8e8\\ud8e9\\ud8ea\\ud8eb\\ud8ec\\ud8ed\\ud8ee\\ud8ef', 'High surrogates group 15 are correctly escaped'); +assert.sameValue(RegExp.escape(highSurrogatesGroup16), '\\ud8f0\\ud8f1\\ud8f2\\ud8f3\\ud8f4\\ud8f5\\ud8f6\\ud8f7\\ud8f8\\ud8f9\\ud8fa\\ud8fb\\ud8fc\\ud8fd\\ud8fe\\ud8ff', 'High surrogates group 16 are correctly escaped'); + +// Trailing Surrogates +const lowSurrogatesGroup1 = '\uDC00\uDC01\uDC02\uDC03\uDC04\uDC05\uDC06\uDC07\uDC08\uDC09\uDC0A\uDC0B\uDC0C\uDC0D\uDC0E\uDC0F'; +const lowSurrogatesGroup2 = '\uDC10\uDC11\uDC12\uDC13\uDC14\uDC15\uDC16\uDC17\uDC18\uDC19\uDC1A\uDC1B\uDC1C\uDC1D\uDC1E\uDC1F'; +const lowSurrogatesGroup3 = '\uDC20\uDC21\uDC22\uDC23\uDC24\uDC25\uDC26\uDC27\uDC28\uDC29\uDC2A\uDC2B\uDC2C\uDC2D\uDC2E\uDC2F'; +const lowSurrogatesGroup4 = '\uDC30\uDC31\uDC32\uDC33\uDC34\uDC35\uDC36\uDC37\uDC38\uDC39\uDC3A\uDC3B\uDC3C\uDC3D\uDC3E\uDC3F'; +const lowSurrogatesGroup5 = '\uDC40\uDC41\uDC42\uDC43\uDC44\uDC45\uDC46\uDC47\uDC48\uDC49\uDC4A\uDC4B\uDC4C\uDC4D\uDC4E\uDC4F'; +const lowSurrogatesGroup6 = '\uDC50\uDC51\uDC52\uDC53\uDC54\uDC55\uDC56\uDC57\uDC58\uDC59\uDC5A\uDC5B\uDC5C\uDC5D\uDC5E\uDC5F'; +const lowSurrogatesGroup7 = '\uDC60\uDC61\uDC62\uDC63\uDC64\uDC65\uDC66\uDC67\uDC68\uDC69\uDC6A\uDC6B\uDC6C\uDC6D\uDC6E\uDC6F'; +const lowSurrogatesGroup8 = '\uDC70\uDC71\uDC72\uDC73\uDC74\uDC75\uDC76\uDC77\uDC78\uDC79\uDC7A\uDC7B\uDC7C\uDC7D\uDC7E\uDC7F'; +const lowSurrogatesGroup9 = '\uDC80\uDC81\uDC82\uDC83\uDC84\uDC85\uDC86\uDC87\uDC88\uDC89\uDC8A\uDC8B\uDC8C\uDC8D\uDC8E\uDC8F'; +const lowSurrogatesGroup10 = '\uDC90\uDC91\uDC92\uDC93\uDC94\uDC95\uDC96\uDC97\uDC98\uDC99\uDC9A\uDC9B\uDC9C\uDC9D\uDC9E\uDC9F'; +const lowSurrogatesGroup11 = '\uDCA0\uDCA1\uDCA2\uDCA3\uDCA4\uDCA5\uDCA6\uDCA7\uDCA8\uDCA9\uDCAA\uDCAB\uDCAC\uDCAD\uDCAE\uDCAF'; +const lowSurrogatesGroup12 = '\uDCB0\uDCB1\uDCB2\uDCB3\uDCB4\uDCB5\uDCB6\uDCB7\uDCB8\uDCB9\uDCBA\uDCBB\uDCBC\uDCBD\uDCBE\uDCBF'; +const lowSurrogatesGroup13 = '\uDCC0\uDCC1\uDCC2\uDCC3\uDCC4\uDCC5\uDCC6\uDCC7\uDCC8\uDCC9\uDCCA\uDCCB\uDCCC\uDCCD\uDCCE\uDCCF'; +const lowSurrogatesGroup14 = '\uDCD0\uDCD1\uDCD2\uDCD3\uDCD4\uDCD5\uDCD6\uDCD7\uDCD8\uDCD9\uDCDA\uDCDB\uDCDC\uDCDD\uDCDE\uDCDF'; +const lowSurrogatesGroup15 = '\uDCE0\uDCE1\uDCE2\uDCE3\uDCE4\uDCE5\uDCE6\uDCE7\uDCE8\uDCE9\uDCEA\uDCEB\uDCEC\uDCED\uDCEE\uDCEF'; +const lowSurrogatesGroup16 = '\uDCF0\uDCF1\uDCF2\uDCF3\uDCF4\uDCF5\uDCF6\uDCF7\uDCF8\uDCF9\uDCFA\uDCFB\uDCFC\uDCFD\uDCFE\uDCFF'; + +assert.sameValue(RegExp.escape(lowSurrogatesGroup1), '\\udc00\\udc01\\udc02\\udc03\\udc04\\udc05\\udc06\\udc07\\udc08\\udc09\\udc0a\\udc0b\\udc0c\\udc0d\\udc0e\\udc0f', 'Low surrogates group 1 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup2), '\\udc10\\udc11\\udc12\\udc13\\udc14\\udc15\\udc16\\udc17\\udc18\\udc19\\udc1a\\udc1b\\udc1c\\udc1d\\udc1e\\udc1f', 'Low surrogates group 2 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup3), '\\udc20\\udc21\\udc22\\udc23\\udc24\\udc25\\udc26\\udc27\\udc28\\udc29\\udc2a\\udc2b\\udc2c\\udc2d\\udc2e\\udc2f', 'Low surrogates group 3 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup4), '\\udc30\\udc31\\udc32\\udc33\\udc34\\udc35\\udc36\\udc37\\udc38\\udc39\\udc3a\\udc3b\\udc3c\\udc3d\\udc3e\\udc3f', 'Low surrogates group 4 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup5), '\\udc40\\udc41\\udc42\\udc43\\udc44\\udc45\\udc46\\udc47\\udc48\\udc49\\udc4a\\udc4b\\udc4c\\udc4d\\udc4e\\udc4f', 'Low surrogates group 5 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup6), '\\udc50\\udc51\\udc52\\udc53\\udc54\\udc55\\udc56\\udc57\\udc58\\udc59\\udc5a\\udc5b\\udc5c\\udc5d\\udc5e\\udc5f', 'Low surrogates group 6 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup7), '\\udc60\\udc61\\udc62\\udc63\\udc64\\udc65\\udc66\\udc67\\udc68\\udc69\\udc6a\\udc6b\\udc6c\\udc6d\\udc6e\\udc6f', 'Low surrogates group 7 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup8), '\\udc70\\udc71\\udc72\\udc73\\udc74\\udc75\\udc76\\udc77\\udc78\\udc79\\udc7a\\udc7b\\udc7c\\udc7d\\udc7e\\udc7f', 'Low surrogates group 8 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup9), '\\udc80\\udc81\\udc82\\udc83\\udc84\\udc85\\udc86\\udc87\\udc88\\udc89\\udc8a\\udc8b\\udc8c\\udc8d\\udc8e\\udc8f', 'Low surrogates group 9 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup10), '\\udc90\\udc91\\udc92\\udc93\\udc94\\udc95\\udc96\\udc97\\udc98\\udc99\\udc9a\\udc9b\\udc9c\\udc9d\\udc9e\\udc9f', 'Low surrogates group 10 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup11), '\\udca0\\udca1\\udca2\\udca3\\udca4\\udca5\\udca6\\udca7\\udca8\\udca9\\udcaa\\udcab\\udcac\\udcad\\udcae\\udcaf', 'Low surrogates group 11 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup12), '\\udcb0\\udcb1\\udcb2\\udcb3\\udcb4\\udcb5\\udcb6\\udcb7\\udcb8\\udcb9\\udcba\\udcbb\\udcbc\\udcbd\\udcbe\\udcbf', 'Low surrogates group 12 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup13), '\\udcc0\\udcc1\\udcc2\\udcc3\\udcc4\\udcc5\\udcc6\\udcc7\\udcc8\\udcc9\\udcca\\udccb\\udccc\\udccd\\udcce\\udccf', 'Low surrogates group 13 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup14), '\\udcd0\\udcd1\\udcd2\\udcd3\\udcd4\\udcd5\\udcd6\\udcd7\\udcd8\\udcd9\\udcda\\udcdb\\udcdc\\udcdd\\udcde\\udcdf', 'Low surrogates group 14 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup15), '\\udce0\\udce1\\udce2\\udce3\\udce4\\udce5\\udce6\\udce7\\udce8\\udce9\\udcea\\udceb\\udcec\\udced\\udcee\\udcef', 'Low surrogates group 15 are correctly escaped'); +assert.sameValue(RegExp.escape(lowSurrogatesGroup16), '\\udcf0\\udcf1\\udcf2\\udcf3\\udcf4\\udcf5\\udcf6\\udcf7\\udcf8\\udcf9\\udcfa\\udcfb\\udcfc\\udcfd\\udcfe\\udcff', 'Low surrogates group 16 are correctly escaped'); diff --git a/test/built-ins/RegExp/escape/escaped-syntax-characters-mixed.js b/test/built-ins/RegExp/escape/escaped-syntax-characters-mixed.js new file mode 100644 index 0000000000..0096c20eac --- /dev/null +++ b/test/built-ins/RegExp/escape/escaped-syntax-characters-mixed.js @@ -0,0 +1,35 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: Escaped characters (mixed assertions) +info: | + RegExp.escape ( string ) + + This method produces a new string in which certain characters have been escaped. + These characters are: . * + ? ^ $ | ( ) [ ] { } \ + +features: [RegExp.escape] +---*/ + +assert.sameValue(RegExp.escape('.a.b'), '\\.a\\.b', 'mixed string with dot character is escaped correctly'); +assert.sameValue(RegExp.escape('.1+2'), '\\.1\\+2', 'mixed string with plus character is escaped correctly'); +assert.sameValue(RegExp.escape('.a(b)c'), '\\.a\\(b\\)c', 'mixed string with parentheses is escaped correctly'); +assert.sameValue(RegExp.escape('.a*b+c'), '\\.a\\*b\\+c', 'mixed string with asterisk and plus characters is escaped correctly'); +assert.sameValue(RegExp.escape('.a?b^c'), '\\.a\\?b\\^c', 'mixed string with question mark and caret characters is escaped correctly'); +assert.sameValue(RegExp.escape('.a{2}'), '\\.a\\{2\\}', 'mixed string with curly braces is escaped correctly'); +assert.sameValue(RegExp.escape('.a|b'), '\\.a\\|b', 'mixed string with pipe character is escaped correctly'); +assert.sameValue(RegExp.escape('.a\\b'), '\\.a\\\\b', 'mixed string with backslash is escaped correctly'); +assert.sameValue(RegExp.escape('.a\\\\b'), '\\.a\\\\\\\\b', 'mixed string with backslash is escaped correctly'); +assert.sameValue(RegExp.escape('.a^b'), '\\.a\\^b', 'mixed string with caret character is escaped correctly'); +assert.sameValue(RegExp.escape('.a$b'), '\\.a\\$b', 'mixed string with dollar sign is escaped correctly'); +assert.sameValue(RegExp.escape('.a[b]'), '\\.a\\[b\\]', 'mixed string with square brackets is escaped correctly'); +assert.sameValue(RegExp.escape('.a.b(c)'), '\\.a\\.b\\(c\\)', 'mixed string with dot and parentheses is escaped correctly'); +assert.sameValue(RegExp.escape('.a*b+c?d^e$f|g{2}h[i]j\\k'), '\\.a\\*b\\+c\\?d\\^e\\$f\\|g\\{2\\}h\\[i\\]j\\\\k', 'complex string with multiple special characters is escaped correctly'); + +assert.sameValue( + RegExp.escape('^$\\.*+?()[]{}|'), + '\\^\\$\\\\\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|', + 'Syntax characters are correctly escaped' +); diff --git a/test/built-ins/RegExp/escape/escaped-syntax-characters-simple.js b/test/built-ins/RegExp/escape/escaped-syntax-characters-simple.js new file mode 100644 index 0000000000..ffd5346460 --- /dev/null +++ b/test/built-ins/RegExp/escape/escaped-syntax-characters-simple.js @@ -0,0 +1,29 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: Escaped characters (simple assertions) +info: | + RegExp.escape ( string ) + + This method produces a new string in which certain characters have been escaped. + These characters are: . * + ? ^ $ | ( ) [ ] { } \ + +features: [RegExp.escape] +---*/ + +assert.sameValue(RegExp.escape('.'), '\\.', 'dot character is escaped correctly'); +assert.sameValue(RegExp.escape('*'), '\\*', 'asterisk character is escaped correctly'); +assert.sameValue(RegExp.escape('+'), '\\+', 'plus character is escaped correctly'); +assert.sameValue(RegExp.escape('?'), '\\?', 'question mark character is escaped correctly'); +assert.sameValue(RegExp.escape('^'), '\\^', 'caret character is escaped correctly'); +assert.sameValue(RegExp.escape('$'), '\\$', 'dollar character is escaped correctly'); +assert.sameValue(RegExp.escape('|'), '\\|', 'pipe character is escaped correctly'); +assert.sameValue(RegExp.escape('('), '\\(', 'open parenthesis character is escaped correctly'); +assert.sameValue(RegExp.escape(')'), '\\)', 'close parenthesis character is escaped correctly'); +assert.sameValue(RegExp.escape('['), '\\[', 'open bracket character is escaped correctly'); +assert.sameValue(RegExp.escape(']'), '\\]', 'close bracket character is escaped correctly'); +assert.sameValue(RegExp.escape('{'), '\\{', 'open brace character is escaped correctly'); +assert.sameValue(RegExp.escape('}'), '\\}', 'close brace character is escaped correctly'); +assert.sameValue(RegExp.escape('\\'), '\\\\', 'backslash character is escaped correctly'); diff --git a/test/built-ins/RegExp/escape/escaped-utf16encodecodepoint.js b/test/built-ins/RegExp/escape/escaped-utf16encodecodepoint.js new file mode 100644 index 0000000000..0f02956a4c --- /dev/null +++ b/test/built-ins/RegExp/escape/escaped-utf16encodecodepoint.js @@ -0,0 +1,35 @@ +// Copyright (C) 2024 Leo Balter, Jordan Harband. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-encodeforregexescape +description: UTF16EncodeCodePoint is called for remaining codepoints +info: | + EncodeForRegExpEscape ( c ) + + 3. Let otherPunctuators be the string-concatenation of ",-=<>#&!%:;@~'`" and the code unit 0x0022 (QUOTATION MARK). + 4. Let toEscape be StringToCodePoints(otherPunctuators). + 5. If toEscape contains c, c is matched by WhiteSpace or LineTerminator, or c has the same numeric value as a leading surrogate or trailing surrogate, then + ... + 6. Return UTF16EncodeCodePoint(c). +features: [RegExp.escape] +---*/ + +const codePoints = String.fromCharCode(0x100, 0x200, 0x300); + +assert.sameValue(RegExp.escape(codePoints), codePoints, 'characters are correctly not escaped'); + +assert.sameValue(RegExp.escape('你好'), '你好', 'Chinese characters are correctly not escaped'); +assert.sameValue(RegExp.escape('こんにちは'), 'こんにちは', 'Japanese characters are correctly not escaped'); +assert.sameValue(RegExp.escape('안녕하세요'), '안녕하세요', 'Korean characters are correctly not escaped'); +assert.sameValue(RegExp.escape('Привет'), 'Привет', 'Cyrillic characters are correctly not escaped'); +assert.sameValue(RegExp.escape('مرحبا'), 'مرحبا', 'Arabic characters are correctly not escaped'); +assert.sameValue(RegExp.escape('हेलो'), 'हेलो', 'Devanagari characters are correctly not escaped'); +assert.sameValue(RegExp.escape('Γειά σου'), 'Γειά\\x20σου', 'Greek characters are correctly not escaped'); +assert.sameValue(RegExp.escape('שלום'), 'שלום', 'Hebrew characters are correctly not escaped'); +assert.sameValue(RegExp.escape('สวัสดี'), 'สวัสดี', 'Thai characters are correctly not escaped'); +assert.sameValue(RegExp.escape('नमस्ते'), 'नमस्ते', 'Hindi characters are correctly not escaped'); +assert.sameValue(RegExp.escape('ሰላም'), 'ሰላም', 'Amharic characters are correctly not escaped'); +assert.sameValue(RegExp.escape('हैलो'), 'हैलो', 'Hindi characters with diacritics are correctly not escaped'); +assert.sameValue(RegExp.escape('안녕!'), '안녕\\x21', 'Korean character with special character is correctly escaped'); +assert.sameValue(RegExp.escape('.hello\uD7FFworld'), '\\.hello\uD7FFworld', 'Mixed ASCII and Unicode characters are correctly escaped'); diff --git a/test/built-ins/RegExp/escape/escaped-whitespace.js b/test/built-ins/RegExp/escape/escaped-whitespace.js new file mode 100644 index 0000000000..19a31a8f93 --- /dev/null +++ b/test/built-ins/RegExp/escape/escaped-whitespace.js @@ -0,0 +1,55 @@ +// Copyright (C) 2024 Leo Balter, Jordan Harband. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: Escaped WhiteSpace characters (simple assertions) +info: | + EncodeForRegExpEscape ( c ) + + ... + 3. Let otherPunctuators be the string-concatenation of ",-=<>#&!%:;@~'`" and the code unit 0x0022 (QUOTATION MARK). + 4. Let toEscape be StringToCodePoints(otherPunctuators). + 5. If toEscape ..., c is matched by WhiteSpace or LineTerminator, ..., then + a. If c ≤ 0xFF, then + i. Let hex be Number::toString(𝔽(c), 16). + ii. Return the string-concatenation of the code unit 0x005C (REVERSE SOLIDUS), "x", and StringPad(hex, 2, "0", START). + b. Let escaped be the empty String. + c. Let codeUnits be UTF16EncodeCodePoint(c). + d. For each code unit cu of codeUnits, do + i. Set escaped to the string-concatenation of escaped and UnicodeEscape(cu). + e. Return escaped. + 6. Return UTF16EncodeCodePoint(c). + + WhiteSpace :: + U+0009 CHARACTER TABULATION + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+FEFF ZERO WIDTH NO-BREAK SPACE + + + U+0020 (SPACE) and U+00A0 (NO-BREAK SPACE) code points are part of + Other USP U+202F NARROW NO-BREAK SPACE + + Exceptions: + + 2. If c is the code point listed in some cell of the “Code Point” column of Table 64, then + a. Return the string-concatenation of 0x005C (REVERSE SOLIDUS) and the string in the “ControlEscape” column of the row whose “Code Point” column contains c. + + ControlEscape, Numeric Value, Code Point, Unicode Name, Symbol + t 9 U+0009 CHARACTER TABULATION + n 10 U+000A LINE FEED (LF) + v 11 U+000B LINE TABULATION + f 12 U+000C FORM FEED (FF) + r 13 U+000D CARRIAGE RETURN (CR) +features: [RegExp.escape] +---*/ + +const WhiteSpace = '\uFEFF\u0020\u00A0\u202F'; + +assert.sameValue(RegExp.escape('\uFEFF'), '\\ufeff', `whitespace \\uFEFF is escaped correctly to \\uFEFF`); +assert.sameValue(RegExp.escape('\u0020'), '\\x20', `whitespace \\u0020 is escaped correctly to \\x20`); +assert.sameValue(RegExp.escape('\u00A0'), '\\xa0', `whitespace \\u00A0 is escaped correctly to \\xA0`); +assert.sameValue(RegExp.escape('\u202F'), '\\u202f', `whitespace \\u202F is escaped correctly to \\u202F`); + +assert.sameValue(RegExp.escape(WhiteSpace), '\\ufeff\\x20\\xa0\\u202f', `whitespaces are escaped correctly`); diff --git a/test/built-ins/RegExp/escape/initial-char-escape.js b/test/built-ins/RegExp/escape/initial-char-escape.js new file mode 100644 index 0000000000..5d6ce26318 --- /dev/null +++ b/test/built-ins/RegExp/escape/initial-char-escape.js @@ -0,0 +1,156 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: Escapes the initial character if it is a decimal digit or an ASCII letter +info: | + RegExp.escape ( string ) + + 1. If S is not a String, throw a TypeError exception. + 2. Let escaped be the empty String. + 3. Let cpList be StringToCodePoints(S). + 4. For each code point c in cpList, do + a. If escaped is the empty String, and c is matched by DecimalDigit or AsciiLetter, then + i. NOTE: Escaping a leading digit ensures that output corresponds with pattern text which may be used after a \0 character escape or a DecimalEscape such as \1 and still match S rather than be interpreted as an extension of the preceding escape sequence. Escaping a leading ASCII letter does the same for the context after \c. + ii. Let numericValue be the numeric value of c. + iii. Let hex be Number::toString(𝔽(numericValue), 16). + iv. Assert: The length of hex is 2. + v. Set escaped to the string-concatenation of the code unit 0x005C (REVERSE SOLIDUS), "x", and hex. + b. Else, + i. Set escaped to the string-concatenation of escaped and EncodeForRegExpEscape(c). + 5. Return escaped. + +features: [RegExp.escape] +---*/ + +// Escaping initial digits +assert.sameValue(RegExp.escape('1111'), '\\x31111', 'Initial decimal digit 1 is escaped'); +assert.sameValue(RegExp.escape('2222'), '\\x32222', 'Initial decimal digit 2 is escaped'); +assert.sameValue(RegExp.escape('3333'), '\\x33333', 'Initial decimal digit 3 is escaped'); +assert.sameValue(RegExp.escape('4444'), '\\x34444', 'Initial decimal digit 4 is escaped'); +assert.sameValue(RegExp.escape('5555'), '\\x35555', 'Initial decimal digit 5 is escaped'); +assert.sameValue(RegExp.escape('6666'), '\\x36666', 'Initial decimal digit 6 is escaped'); +assert.sameValue(RegExp.escape('7777'), '\\x37777', 'Initial decimal digit 7 is escaped'); +assert.sameValue(RegExp.escape('8888'), '\\x38888', 'Initial decimal digit 8 is escaped'); +assert.sameValue(RegExp.escape('9999'), '\\x39999', 'Initial decimal digit 9 is escaped'); +assert.sameValue(RegExp.escape('0000'), '\\x30000', 'Initial decimal digit 0 is escaped'); + +// Escaping initial ASCII letters +assert.sameValue(RegExp.escape('aaa'), '\\x61aa', 'Initial ASCII letter a is escaped'); +assert.sameValue(RegExp.escape('bbb'), '\\x62bb', 'Initial ASCII letter b is escaped'); +assert.sameValue(RegExp.escape('ccc'), '\\x63cc', 'Initial ASCII letter c is escaped'); +assert.sameValue(RegExp.escape('ddd'), '\\x64dd', 'Initial ASCII letter d is escaped'); +assert.sameValue(RegExp.escape('eee'), '\\x65ee', 'Initial ASCII letter e is escaped'); +assert.sameValue(RegExp.escape('fff'), '\\x66ff', 'Initial ASCII letter f is escaped'); +assert.sameValue(RegExp.escape('ggg'), '\\x67gg', 'Initial ASCII letter g is escaped'); +assert.sameValue(RegExp.escape('hhh'), '\\x68hh', 'Initial ASCII letter h is escaped'); +assert.sameValue(RegExp.escape('iii'), '\\x69ii', 'Initial ASCII letter i is escaped'); +assert.sameValue(RegExp.escape('jjj'), '\\x6ajj', 'Initial ASCII letter j is escaped'); +assert.sameValue(RegExp.escape('kkk'), '\\x6bkk', 'Initial ASCII letter k is escaped'); +assert.sameValue(RegExp.escape('lll'), '\\x6cll', 'Initial ASCII letter l is escaped'); +assert.sameValue(RegExp.escape('mmm'), '\\x6dmm', 'Initial ASCII letter m is escaped'); +assert.sameValue(RegExp.escape('nnn'), '\\x6enn', 'Initial ASCII letter n is escaped'); +assert.sameValue(RegExp.escape('ooo'), '\\x6foo', 'Initial ASCII letter o is escaped'); +assert.sameValue(RegExp.escape('ppp'), '\\x70pp', 'Initial ASCII letter p is escaped'); +assert.sameValue(RegExp.escape('qqq'), '\\x71qq', 'Initial ASCII letter q is escaped'); +assert.sameValue(RegExp.escape('rrr'), '\\x72rr', 'Initial ASCII letter r is escaped'); +assert.sameValue(RegExp.escape('sss'), '\\x73ss', 'Initial ASCII letter s is escaped'); +assert.sameValue(RegExp.escape('ttt'), '\\x74tt', 'Initial ASCII letter t is escaped'); +assert.sameValue(RegExp.escape('uuu'), '\\x75uu', 'Initial ASCII letter u is escaped'); +assert.sameValue(RegExp.escape('vvv'), '\\x76vv', 'Initial ASCII letter v is escaped'); +assert.sameValue(RegExp.escape('www'), '\\x77ww', 'Initial ASCII letter w is escaped'); +assert.sameValue(RegExp.escape('xxx'), '\\x78xx', 'Initial ASCII letter x is escaped'); +assert.sameValue(RegExp.escape('yyy'), '\\x79yy', 'Initial ASCII letter y is escaped'); +assert.sameValue(RegExp.escape('zzz'), '\\x7azz', 'Initial ASCII letter z is escaped'); +assert.sameValue(RegExp.escape('AAA'), '\\x41AA', 'Initial ASCII letter A is escaped'); +assert.sameValue(RegExp.escape('BBB'), '\\x42BB', 'Initial ASCII letter B is escaped'); +assert.sameValue(RegExp.escape('CCC'), '\\x43CC', 'Initial ASCII letter C is escaped'); +assert.sameValue(RegExp.escape('DDD'), '\\x44DD', 'Initial ASCII letter D is escaped'); +assert.sameValue(RegExp.escape('EEE'), '\\x45EE', 'Initial ASCII letter E is escaped'); +assert.sameValue(RegExp.escape('FFF'), '\\x46FF', 'Initial ASCII letter F is escaped'); +assert.sameValue(RegExp.escape('GGG'), '\\x47GG', 'Initial ASCII letter G is escaped'); +assert.sameValue(RegExp.escape('HHH'), '\\x48HH', 'Initial ASCII letter H is escaped'); +assert.sameValue(RegExp.escape('III'), '\\x49II', 'Initial ASCII letter I is escaped'); +assert.sameValue(RegExp.escape('JJJ'), '\\x4aJJ', 'Initial ASCII letter J is escaped'); +assert.sameValue(RegExp.escape('KKK'), '\\x4bKK', 'Initial ASCII letter K is escaped'); +assert.sameValue(RegExp.escape('LLL'), '\\x4cLL', 'Initial ASCII letter L is escaped'); +assert.sameValue(RegExp.escape('MMM'), '\\x4dMM', 'Initial ASCII letter M is escaped'); +assert.sameValue(RegExp.escape('NNN'), '\\x4eNN', 'Initial ASCII letter N is escaped'); +assert.sameValue(RegExp.escape('OOO'), '\\x4fOO', 'Initial ASCII letter O is escaped'); +assert.sameValue(RegExp.escape('PPP'), '\\x50PP', 'Initial ASCII letter P is escaped'); +assert.sameValue(RegExp.escape('QQQ'), '\\x51QQ', 'Initial ASCII letter Q is escaped'); +assert.sameValue(RegExp.escape('RRR'), '\\x52RR', 'Initial ASCII letter R is escaped'); +assert.sameValue(RegExp.escape('SSS'), '\\x53SS', 'Initial ASCII letter S is escaped'); +assert.sameValue(RegExp.escape('TTT'), '\\x54TT', 'Initial ASCII letter T is escaped'); +assert.sameValue(RegExp.escape('UUU'), '\\x55UU', 'Initial ASCII letter U is escaped'); +assert.sameValue(RegExp.escape('VVV'), '\\x56VV', 'Initial ASCII letter V is escaped'); +assert.sameValue(RegExp.escape('WWW'), '\\x57WW', 'Initial ASCII letter W is escaped'); +assert.sameValue(RegExp.escape('XXX'), '\\x58XX', 'Initial ASCII letter X is escaped'); +assert.sameValue(RegExp.escape('YYY'), '\\x59YY', 'Initial ASCII letter Y is escaped'); +assert.sameValue(RegExp.escape('ZZZ'), '\\x5aZZ', 'Initial ASCII letter Z is escaped'); + +// Mixed case with special characters +assert.sameValue(RegExp.escape('1+1'), '\\x31\\+1', 'Initial decimal digit 1 with special character is escaped'); +assert.sameValue(RegExp.escape('2+2'), '\\x32\\+2', 'Initial decimal digit 2 with special character is escaped'); +assert.sameValue(RegExp.escape('3+3'), '\\x33\\+3', 'Initial decimal digit 3 with special character is escaped'); +assert.sameValue(RegExp.escape('4+4'), '\\x34\\+4', 'Initial decimal digit 4 with special character is escaped'); +assert.sameValue(RegExp.escape('5+5'), '\\x35\\+5', 'Initial decimal digit 5 with special character is escaped'); +assert.sameValue(RegExp.escape('6+6'), '\\x36\\+6', 'Initial decimal digit 6 with special character is escaped'); +assert.sameValue(RegExp.escape('7+7'), '\\x37\\+7', 'Initial decimal digit 7 with special character is escaped'); +assert.sameValue(RegExp.escape('8+8'), '\\x38\\+8', 'Initial decimal digit 8 with special character is escaped'); +assert.sameValue(RegExp.escape('9+9'), '\\x39\\+9', 'Initial decimal digit 9 with special character is escaped'); +assert.sameValue(RegExp.escape('0+0'), '\\x30\\+0', 'Initial decimal digit 0 with special character is escaped'); + +assert.sameValue(RegExp.escape('a*a'), '\\x62\\*a', 'Initial ASCII letter a with special character is escaped'); +assert.sameValue(RegExp.escape('b*b'), '\\x62\\*b', 'Initial ASCII letter b with special character is escaped'); +assert.sameValue(RegExp.escape('c*c'), '\\x63\\*c', 'Initial ASCII letter c with special character is escaped'); +assert.sameValue(RegExp.escape('d*d'), '\\x64\\*d', 'Initial ASCII letter d with special character is escaped'); +assert.sameValue(RegExp.escape('e*e'), '\\x65\\*e', 'Initial ASCII letter e with special character is escaped'); +assert.sameValue(RegExp.escape('f*f'), '\\x66\\*f', 'Initial ASCII letter f with special character is escaped'); +assert.sameValue(RegExp.escape('g*g'), '\\x67\\*g', 'Initial ASCII letter g with special character is escaped'); +assert.sameValue(RegExp.escape('h*h'), '\\x68\\*h', 'Initial ASCII letter h with special character is escaped'); +assert.sameValue(RegExp.escape('i*i'), '\\x69\\*i', 'Initial ASCII letter i with special character is escaped'); +assert.sameValue(RegExp.escape('j*j'), '\\x6a\\*j', 'Initial ASCII letter j with special character is escaped'); +assert.sameValue(RegExp.escape('k*k'), '\\x6b\\*k', 'Initial ASCII letter k with special character is escaped'); +assert.sameValue(RegExp.escape('l*l'), '\\x6c\\*l', 'Initial ASCII letter l with special character is escaped'); +assert.sameValue(RegExp.escape('m*m'), '\\x6d\\*m', 'Initial ASCII letter m with special character is escaped'); +assert.sameValue(RegExp.escape('n*n'), '\\x6e\\*n', 'Initial ASCII letter n with special character is escaped'); +assert.sameValue(RegExp.escape('o*o'), '\\x6f\\*o', 'Initial ASCII letter o with special character is escaped'); +assert.sameValue(RegExp.escape('p*p'), '\\x70\\*p', 'Initial ASCII letter p with special character is escaped'); +assert.sameValue(RegExp.escape('q*q'), '\\x71\\*q', 'Initial ASCII letter q with special character is escaped'); +assert.sameValue(RegExp.escape('r*r'), '\\x72\\*r', 'Initial ASCII letter r with special character is escaped'); +assert.sameValue(RegExp.escape('s*s'), '\\x73\\*s', 'Initial ASCII letter s with special character is escaped'); +assert.sameValue(RegExp.escape('t*t'), '\\x74\\*t', 'Initial ASCII letter t with special character is escaped'); +assert.sameValue(RegExp.escape('u*u'), '\\x75\\*u', 'Initial ASCII letter u with special character is escaped'); +assert.sameValue(RegExp.escape('v*v'), '\\x76\\*v', 'Initial ASCII letter v with special character is escaped'); +assert.sameValue(RegExp.escape('w*w'), '\\x77\\*w', 'Initial ASCII letter w with special character is escaped'); +assert.sameValue(RegExp.escape('x*x'), '\\x78\\*x', 'Initial ASCII letter x with special character is escaped'); +assert.sameValue(RegExp.escape('y*y'), '\\x79\\*y', 'Initial ASCII letter y with special character is escaped'); +assert.sameValue(RegExp.escape('z*z'), '\\x7a\\*z', 'Initial ASCII letter z with special character is escaped'); +assert.sameValue(RegExp.escape('A*A'), '\\x41\\*A', 'Initial ASCII letter A with special character is escaped'); +assert.sameValue(RegExp.escape('B*B'), '\\x42\\*B', 'Initial ASCII letter B with special character is escaped'); +assert.sameValue(RegExp.escape('C*C'), '\\x43\\*C', 'Initial ASCII letter C with special character is escaped'); +assert.sameValue(RegExp.escape('D*D'), '\\x44\\*D', 'Initial ASCII letter D with special character is escaped'); +assert.sameValue(RegExp.escape('E*E'), '\\x45\\*E', 'Initial ASCII letter E with special character is escaped'); +assert.sameValue(RegExp.escape('F*F'), '\\x46\\*F', 'Initial ASCII letter F with special character is escaped'); +assert.sameValue(RegExp.escape('G*G'), '\\x47\\*G', 'Initial ASCII letter G with special character is escaped'); +assert.sameValue(RegExp.escape('H*H'), '\\x48\\*H', 'Initial ASCII letter H with special character is escaped'); +assert.sameValue(RegExp.escape('I*I'), '\\x49\\*I', 'Initial ASCII letter I with special character is escaped'); +assert.sameValue(RegExp.escape('J*J'), '\\x4a\\*J', 'Initial ASCII letter J with special character is escaped'); +assert.sameValue(RegExp.escape('K*K'), '\\x4b\\*K', 'Initial ASCII letter K with special character is escaped'); +assert.sameValue(RegExp.escape('L*L'), '\\x4c\\*L', 'Initial ASCII letter L with special character is escaped'); +assert.sameValue(RegExp.escape('M*M'), '\\x4d\\*M', 'Initial ASCII letter M with special character is escaped'); +assert.sameValue(RegExp.escape('N*N'), '\\x4e\\*N', 'Initial ASCII letter N with special character is escaped'); +assert.sameValue(RegExp.escape('O*O'), '\\x4f\\*O', 'Initial ASCII letter O with special character is escaped'); +assert.sameValue(RegExp.escape('P*P'), '\\x50\\*P', 'Initial ASCII letter P with special character is escaped'); +assert.sameValue(RegExp.escape('Q*Q'), '\\x51\\*Q', 'Initial ASCII letter Q with special character is escaped'); +assert.sameValue(RegExp.escape('R*R'), '\\x52\\*R', 'Initial ASCII letter R with special character is escaped'); +assert.sameValue(RegExp.escape('S*S'), '\\x53\\*S', 'Initial ASCII letter S with special character is escaped'); +assert.sameValue(RegExp.escape('T*T'), '\\x54\\*T', 'Initial ASCII letter T with special character is escaped'); +assert.sameValue(RegExp.escape('U*U'), '\\x55\\*U', 'Initial ASCII letter U with special character is escaped'); +assert.sameValue(RegExp.escape('V*V'), '\\x56\\*V', 'Initial ASCII letter V with special character is escaped'); +assert.sameValue(RegExp.escape('W*W'), '\\x57\\*W', 'Initial ASCII letter W with special character is escaped'); +assert.sameValue(RegExp.escape('X*X'), '\\x58\\*X', 'Initial ASCII letter X with special character is escaped'); +assert.sameValue(RegExp.escape('Y*Y'), '\\x59\\*Y', 'Initial ASCII letter Y with special character is escaped'); +assert.sameValue(RegExp.escape('Z*Z'), '\\x5a\\*Z', 'Initial ASCII letter Z with special character is escaped'); diff --git a/test/built-ins/RegExp/escape/is-function.js b/test/built-ins/RegExp/escape/is-function.js new file mode 100644 index 0000000000..1614a27a38 --- /dev/null +++ b/test/built-ins/RegExp/escape/is-function.js @@ -0,0 +1,12 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: RegExp.escape is a function +info: | + RegExp.escape is a built-in function of the RegExp object. +features: [RegExp.escape] +---*/ + +assert.sameValue(typeof RegExp.escape, 'function', 'RegExp.escape is a function'); diff --git a/test/built-ins/RegExp/escape/length.js b/test/built-ins/RegExp/escape/length.js new file mode 100644 index 0000000000..54c6855a13 --- /dev/null +++ b/test/built-ins/RegExp/escape/length.js @@ -0,0 +1,19 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: > + RegExp.escape.length property descriptor +info: | + 17 ECMAScript Standard Built-in Objects +includes: [propertyHelper.js] +features: [RegExp.escape] +---*/ + +verifyProperty(RegExp.escape, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/RegExp/escape/name.js b/test/built-ins/RegExp/escape/name.js new file mode 100644 index 0000000000..4dd070e24e --- /dev/null +++ b/test/built-ins/RegExp/escape/name.js @@ -0,0 +1,19 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: > + RegExp.escape.name property descriptor +info: | + 17 ECMAScript Standard Built-in Objects +includes: [propertyHelper.js] +features: [RegExp.escape] +---*/ + +verifyProperty(RegExp.escape, "name", { + value: 'escape', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/RegExp/escape/non-string-inputs.js b/test/built-ins/RegExp/escape/non-string-inputs.js new file mode 100644 index 0000000000..d153618e40 --- /dev/null +++ b/test/built-ins/RegExp/escape/non-string-inputs.js @@ -0,0 +1,22 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: Non-string inputs throw a TypeError +info: | + RegExp.escape ( string ) + + This method throws a TypeError if the input is not a string. + +features: [RegExp.escape] +---*/ + +// Avoids a false positive when the feature is not supported +assert.sameValue(typeof RegExp.escape, 'function', 'RegExp.escape is a function'); + +assert.throws(TypeError, function () { RegExp.escape(123); }, 'non-string input (number) throws TypeError'); +assert.throws(TypeError, function () { RegExp.escape({}); }, 'non-string input (object) throws TypeError'); +assert.throws(TypeError, function () { RegExp.escape([]); }, 'non-string input (array) throws TypeError'); +assert.throws(TypeError, function () { RegExp.escape(null); }, 'non-string input (null) throws TypeError'); +assert.throws(TypeError, function () { RegExp.escape(undefined); }, 'non-string input (undefined) throws TypeError'); diff --git a/test/built-ins/RegExp/escape/not-a-constructor.js b/test/built-ins/RegExp/escape/not-a-constructor.js new file mode 100644 index 0000000000..06eacbfc14 --- /dev/null +++ b/test/built-ins/RegExp/escape/not-a-constructor.js @@ -0,0 +1,28 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: > + RegExp.escape does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [RegExp.escape, Reflect.construct] +---*/ + +assert.sameValue(isConstructor(RegExp.escape), false, 'isConstructor(RegExp.escape) must return false'); + +assert.throws(TypeError, function () { + new RegExp.escape(); +}); diff --git a/test/built-ins/RegExp/escape/not-escaped-underscore.js b/test/built-ins/RegExp/escape/not-escaped-underscore.js new file mode 100644 index 0000000000..7351c27b3b --- /dev/null +++ b/test/built-ins/RegExp/escape/not-escaped-underscore.js @@ -0,0 +1,23 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-encodeforregexescape +description: Ensures the underscore character is not escaped +info: | + RegExp.escape ( string ) + + This method produces a new string in which certain characters have been escaped. + These characters are: . * + ? ^ $ | ( ) [ ] { } \ , - = < > # & ! % : ; @ ~ ' ` " and white space or line terminators. +features: [RegExp.escape] +---*/ + +assert.sameValue(RegExp.escape('_'), '_', 'Single underscore character is not escaped'); +assert.sameValue(RegExp.escape('__'), '__', 'Thunderscore character is not escaped'); +assert.sameValue(RegExp.escape('hello_world'), '\\x68ello_world', 'String starting with ASCII letter and containing underscore is correctly escaped'); +assert.sameValue(RegExp.escape('1_hello_world'), '\\x31_hello_world', 'String starting with digit and containing underscore is correctly escaped'); +assert.sameValue(RegExp.escape('a_b_c'), '\\x61_b_c', 'String starting with ASCII letter and containing multiple underscores is correctly escaped'); +assert.sameValue(RegExp.escape('3_b_4'), '\\x33_b_4', 'String starting with digit and containing multiple underscores is correctly escaped'); +assert.sameValue(RegExp.escape('_hello'), '_hello', 'String starting with underscore and containing other characters is not escaped'); +assert.sameValue(RegExp.escape('_1hello'), '_1hello', 'String starting with underscore and digit is not escaped'); +assert.sameValue(RegExp.escape('_a_1_2'), '_a_1_2', 'String starting with underscore and mixed characters is not escaped'); diff --git a/test/built-ins/RegExp/escape/not-escaped.js b/test/built-ins/RegExp/escape/not-escaped.js new file mode 100644 index 0000000000..3cfcede9a7 --- /dev/null +++ b/test/built-ins/RegExp/escape/not-escaped.js @@ -0,0 +1,33 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-regexp.escape +description: Numbers and alphabetic characters are not escaped +info: | + RegExp.escape ( string ) + + This method produces a new string in which certain characters have been escaped. + These characters are: . * + ? ^ $ | ( ) [ ] { } \ + +features: [RegExp.escape] +---*/ + +const asciiletter = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; +const decimaldigits = '0123456789'; + +assert.sameValue(RegExp.escape(''), '', 'the empty string is not escaped'); + +asciiletter.split('').forEach(char => { + assert.sameValue(RegExp.escape(`.${char}`), `\\.${char}`, `ASCII letter ${char} is not escaped`); +}); + +assert.sameValue(RegExp.escape(`.${asciiletter}`), `\\.${asciiletter}`, 'ASCII letters are not escaped'); + +decimaldigits.split('').forEach(char => { + assert.sameValue(RegExp.escape(`.${char}`), `\\.${char}`, `decimal digit ${char} is not escaped`); +}); + +assert.sameValue(RegExp.escape(`.${decimaldigits}`), `\\.${decimaldigits}`, 'decimal digits are not escaped'); + +assert.sameValue(RegExp.escape('.a1b2c3D4E5F6'), '\\.a1b2c3D4E5F6', 'mixed string with ASCII letters and decimal digits is not escaped'); diff --git a/test/built-ins/RegExp/escape/prop-desc.js b/test/built-ins/RegExp/escape/prop-desc.js new file mode 100644 index 0000000000..8f8ef49c95 --- /dev/null +++ b/test/built-ins/RegExp/escape/prop-desc.js @@ -0,0 +1,17 @@ +// Copyright (C) 2024 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: The property descriptor RegExp.escape +esid: sec-regexp.escape +info: | + 17 ECMAScript Standard Built-in Objects +features: [RegExp.escape] +includes: [propertyHelper.js] +---*/ + +verifyProperty(RegExp, "escape", { + writable: true, + enumerable: false, + configurable: true +}); From 0a8622de688ad9f9b71a7e6f54e6643c456f9147 Mon Sep 17 00:00:00 2001 From: Paul Bakker <4981149+p-bakker@users.noreply.github.com> Date: Tue, 23 Jul 2024 13:45:09 +0200 Subject: [PATCH 21/90] Dont use const in for (of) loops, for when those aren't properly supported --- harness/regExpUtils.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/harness/regExpUtils.js b/harness/regExpUtils.js index b55f3c6c13..b397be070b 100644 --- a/harness/regExpUtils.js +++ b/harness/regExpUtils.js @@ -13,20 +13,20 @@ function buildString(args) { const loneCodePoints = args.loneCodePoints; const ranges = args.ranges; const CHUNK_SIZE = 10000; - let result = Reflect.apply(String.fromCodePoint, null, loneCodePoints); + let result = String.fromCodePoint.apply(null, loneCodePoints); for (let i = 0; i < ranges.length; i++) { - const range = ranges[i]; - const start = range[0]; - const end = range[1]; - const codePoints = []; + let range = ranges[i]; + let start = range[0]; + let end = range[1]; + let codePoints = []; for (let length = 0, codePoint = start; codePoint <= end; codePoint++) { codePoints[length++] = codePoint; if (length === CHUNK_SIZE) { - result += Reflect.apply(String.fromCodePoint, null, codePoints); + result += String.fromCodePoint.apply(null, codePoints); codePoints.length = length = 0; } } - result += Reflect.apply(String.fromCodePoint, null, codePoints); + result += String.fromCodePoint.apply(null, codePoints); } return result; } @@ -41,8 +41,8 @@ function printCodePoint(codePoint) { function printStringCodePoints(string) { const buf = []; - for (const symbol of string) { - const formatted = printCodePoint(symbol.codePointAt(0)); + for (let symbol of string) { + let formatted = printCodePoint(symbol.codePointAt(0)); buf.push(formatted); } return buf.join(' '); @@ -50,8 +50,8 @@ function printStringCodePoints(string) { function testPropertyEscapes(regExp, string, expression) { if (!regExp.test(string)) { - for (const symbol of string) { - const formatted = printCodePoint(symbol.codePointAt(0)); + for (let symbol of string) { + let formatted = printCodePoint(symbol.codePointAt(0)); assert( regExp.test(symbol), `\`${ expression }\` should match ${ formatted } (\`${ symbol }\`)` @@ -70,7 +70,7 @@ function testPropertyOfStrings(args) { const nonMatchStrings = args.nonMatchStrings; const allStrings = matchStrings.join(''); if (!regExp.test(allStrings)) { - for (const string of matchStrings) { + for (let string of matchStrings) { assert( regExp.test(string), `\`${ expression }\` should match ${ string } (${ printStringCodePoints(string) })` @@ -82,7 +82,7 @@ function testPropertyOfStrings(args) { const allNonMatchStrings = nonMatchStrings.join(''); if (regExp.test(allNonMatchStrings)) { - for (const string of nonMatchStrings) { + for (let string of nonMatchStrings) { assert( !regExp.test(string), `\`${ expression }\` should not match ${ string } (${ printStringCodePoints(string) })` From ba9288174843db42dea1926116602e7395393382 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Wed, 24 Jul 2024 01:42:45 +0200 Subject: [PATCH 22/90] RAB: Integrate staging tests for the .length method (#4154) * Import relevant files from #3888 * Adds resizableArrayBufferUtils.js to includes and removes its content from each test. Also splits tests for .byteLength and .byteOffset to new files in the respective directories. Test lines calling .buffer in .../length/resizable-buffer-assorted.js were not split to .../buffer/ as they seem to only do a check for the test on .length but perhaps they need to be also split to a new file .../buffer/resizable-buffer-assorted.js --- .../byteLength/resized-out-of-bounds-1.js | 39 ++++++++++++++++++ .../byteLength/resized-out-of-bounds-2.js | 39 ++++++++++++++++++ .../byteOffset/resized-out-of-bounds.js | 39 ++++++++++++++++++ .../length/resizable-buffer-assorted.js | 37 +++++++++++++++++ .../length/resized-out-of-bounds-1.js | 39 ++++++++++++++++++ .../length/resized-out-of-bounds-2.js | 41 +++++++++++++++++++ 6 files changed, 234 insertions(+) create mode 100644 test/built-ins/TypedArray/prototype/byteLength/resized-out-of-bounds-1.js create mode 100644 test/built-ins/TypedArray/prototype/byteLength/resized-out-of-bounds-2.js create mode 100644 test/built-ins/TypedArray/prototype/byteOffset/resized-out-of-bounds.js create mode 100644 test/built-ins/TypedArray/prototype/length/resizable-buffer-assorted.js create mode 100644 test/built-ins/TypedArray/prototype/length/resized-out-of-bounds-1.js create mode 100644 test/built-ins/TypedArray/prototype/length/resized-out-of-bounds-2.js diff --git a/test/built-ins/TypedArray/prototype/byteLength/resized-out-of-bounds-1.js b/test/built-ins/TypedArray/prototype/byteLength/resized-out-of-bounds-1.js new file mode 100644 index 0000000000..1388960568 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/byteLength/resized-out-of-bounds-1.js @@ -0,0 +1,39 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-%typedarray%.prototype.byteLength +description: > + TypedArray.p.byteLength behaves correctly when the underlying resizable buffer + is resized such that the TypedArray becomes out of bounds. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const rab = CreateResizableArrayBuffer(16, 40); + +// Create TAs which cover the bytes 0-7. +let tas_and_lengths = []; +for (let ctor of ctors) { + const length = 8 / ctor.BYTES_PER_ELEMENT; + tas_and_lengths.push([ + new ctor(rab, 0, length), + length + ]); +} +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteLength, length * ta.BYTES_PER_ELEMENT); +} +rab.resize(2); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteLength, 0); +} +// Resize the rab so that it just barely covers the needed 8 bytes. +rab.resize(8); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteLength, length * ta.BYTES_PER_ELEMENT); +} +rab.resize(40); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteLength, length * ta.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/TypedArray/prototype/byteLength/resized-out-of-bounds-2.js b/test/built-ins/TypedArray/prototype/byteLength/resized-out-of-bounds-2.js new file mode 100644 index 0000000000..31b0aa2222 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/byteLength/resized-out-of-bounds-2.js @@ -0,0 +1,39 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-%typedarray%.prototype.byteLength +description: > + TypedArray.p.byteLength behaves as expected when the underlying resizable + buffer is resized such that the TypedArray becomes out of bounds. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const rab = CreateResizableArrayBuffer(20, 40); + +// Create TAs with offset, which cover the bytes 8-15. +let tas_and_lengths = []; +for (let ctor of ctors) { + const length = 8 / ctor.BYTES_PER_ELEMENT; + tas_and_lengths.push([ + new ctor(rab, 8, length), + length + ]); +} +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteLength, length * ta.BYTES_PER_ELEMENT); +} +rab.resize(10); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteLength, 0); +} +// Resize the rab so that it just barely covers the needed 8 bytes. +rab.resize(16); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteLength, length * ta.BYTES_PER_ELEMENT); +} +rab.resize(40); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteLength, length * ta.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/TypedArray/prototype/byteOffset/resized-out-of-bounds.js b/test/built-ins/TypedArray/prototype/byteOffset/resized-out-of-bounds.js new file mode 100644 index 0000000000..483953d0da --- /dev/null +++ b/test/built-ins/TypedArray/prototype/byteOffset/resized-out-of-bounds.js @@ -0,0 +1,39 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-%typedarray%.prototype.byteOffset +description: > + TypedArray.p.byteOffset behaves as expected when the underlying resizable + buffer is resized such that the TypedArray becomes out of bounds. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const rab = CreateResizableArrayBuffer(20, 40); + +// Create TAs which cover the bytes 8-15. +let tas_and_lengths = []; +for (let ctor of ctors) { + const length = 8 / ctor.BYTES_PER_ELEMENT; + tas_and_lengths.push([ + new ctor(rab, 8, length), + length + ]); +} +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteOffset, 8); +} +rab.resize(10); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteOffset, 0); +} +// Resize the rab so that it just barely covers the needed 8 bytes. +rab.resize(16); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteOffset, 8); +} +rab.resize(40); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.byteOffset, 8); +} diff --git a/test/built-ins/TypedArray/prototype/length/resizable-buffer-assorted.js b/test/built-ins/TypedArray/prototype/length/resizable-buffer-assorted.js new file mode 100644 index 0000000000..978451bfa2 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/length/resizable-buffer-assorted.js @@ -0,0 +1,37 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-%typedarray%.prototype.length +description: > + TypedArray.p.length behaves correctly on TypedArrays backed by resizable + buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const rab = CreateResizableArrayBuffer(40, 80); +for (let ctor of ctors) { + const ta = new ctor(rab, 0, 3); + assert.compareArray(ta.buffer, rab); + assert.sameValue(ta.length, 3); + const empty_ta = new ctor(rab, 0, 0); + assert.compareArray(empty_ta.buffer, rab); + assert.sameValue(empty_ta.length, 0); + const ta_with_offset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 3); + assert.compareArray(ta_with_offset.buffer, rab); + assert.sameValue(ta_with_offset.length, 3); + const empty_ta_with_offset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 0); + assert.compareArray(empty_ta_with_offset.buffer, rab); + assert.sameValue(empty_ta_with_offset.length, 0); + const length_tracking_ta = new ctor(rab); + assert.compareArray(length_tracking_ta.buffer, rab); + assert.sameValue(length_tracking_ta.length, 40 / ctor.BYTES_PER_ELEMENT); + const offset = 8; + const length_tracking_ta_with_offset = new ctor(rab, offset); + assert.compareArray(length_tracking_ta_with_offset.buffer, rab); + assert.sameValue(length_tracking_ta_with_offset.length, (40 - offset) / ctor.BYTES_PER_ELEMENT); + const empty_length_tracking_ta_with_offset = new ctor(rab, 40); + assert.compareArray(empty_length_tracking_ta_with_offset.buffer, rab); + assert.sameValue(empty_length_tracking_ta_with_offset.length, 0); +} diff --git a/test/built-ins/TypedArray/prototype/length/resized-out-of-bounds-1.js b/test/built-ins/TypedArray/prototype/length/resized-out-of-bounds-1.js new file mode 100644 index 0000000000..9acfd44255 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/length/resized-out-of-bounds-1.js @@ -0,0 +1,39 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-%typedarray%.prototype.length +description: > + TypedArray.p.length behaves correctly when the underlying resizable buffer is + resized such that the TypedArray becomes out of bounds. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const rab = CreateResizableArrayBuffer(16, 40); + +// Create TAs which cover the bytes 0-7. +let tas_and_lengths = []; +for (let ctor of ctors) { + const length = 8 / ctor.BYTES_PER_ELEMENT; + tas_and_lengths.push([ + new ctor(rab, 0, length), + length + ]); +} +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.length, length); +} +rab.resize(2); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.length, 0); +} +// Resize the rab so that it just barely covers the needed 8 bytes. +rab.resize(8); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.length, length); +} +rab.resize(40); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.length, length); +} diff --git a/test/built-ins/TypedArray/prototype/length/resized-out-of-bounds-2.js b/test/built-ins/TypedArray/prototype/length/resized-out-of-bounds-2.js new file mode 100644 index 0000000000..d2eaf48b9d --- /dev/null +++ b/test/built-ins/TypedArray/prototype/length/resized-out-of-bounds-2.js @@ -0,0 +1,41 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-%typedarray%.prototype.length +description: > + TypedArray.p.length behaves correctly when the underlying resizable buffer is + resized such that the TypedArray becomes out of bounds. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Like resized-out-of-bounds-1.js but with offsets. + +const rab = CreateResizableArrayBuffer(20, 40); + +// Create TAs with offset, which cover the bytes 8-15. +let tas_and_lengths = []; +for (let ctor of ctors) { + const length = 8 / ctor.BYTES_PER_ELEMENT; + tas_and_lengths.push([ + new ctor(rab, 8, length), + length + ]); +} +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.length, length); +} +rab.resize(10); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.length, 0); +} +// Resize the rab so that it just barely covers the needed 8 bytes. +rab.resize(16); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.length, length); +} +rab.resize(40); +for (let [ta, length] of tas_and_lengths) { + assert.sameValue(ta.length, length); +} From d8aa2e4ef7ac717c36421fbd1576ff708658f58c Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Thu, 18 Apr 2024 12:24:14 -0400 Subject: [PATCH 23/90] Update NumberFormat.prototype.useGrouping test for CLDR 45 In CLDR 45, in the en-IN locale, the compact thousands symbol changed from 'T' to 'K' after a survey was conducted in India: https://github.com/unicode-org/cldr/commit/b8d447297556ee01575da2b5b710554af34b3482 --- .../prototype/format/useGrouping-extended-en-IN.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/intl402/NumberFormat/prototype/format/useGrouping-extended-en-IN.js b/test/intl402/NumberFormat/prototype/format/useGrouping-extended-en-IN.js index 2e19ff789f..1b0b859e03 100644 --- a/test/intl402/NumberFormat/prototype/format/useGrouping-extended-en-IN.js +++ b/test/intl402/NumberFormat/prototype/format/useGrouping-extended-en-IN.js @@ -28,6 +28,6 @@ assert.sameValue(nf.format(100000), '1,00,000', '"min2"'); nf = new Intl.NumberFormat('en-IN', {notation: 'compact'}); assert.sameValue(nf.format(100), '100', 'notation: "compact"'); -assert.sameValue(nf.format(1000), '1T', 'notation: "compact"'); -assert.sameValue(nf.format(10000), '10T', 'notation: "compact"'); +assert.sameValue(nf.format(1000), '1K', 'notation: "compact"'); +assert.sameValue(nf.format(10000), '10K', 'notation: "compact"'); assert.sameValue(nf.format(100000), '1L', 'notation: "compact"'); From f55e99796fe38aa13dc6fa20d6588882169eac6f Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Wed, 24 Jul 2024 18:18:02 +0200 Subject: [PATCH 24/90] Prevent harness code not loading when async/generator/asyncGenerator not supported (#4164) * Dont throw when async/generato/asyncGenerator not supported * Apply suggestions from code review --- harness/hidden-constructors.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/harness/hidden-constructors.js b/harness/hidden-constructors.js index 8a517475a2..d73facfbcf 100644 --- a/harness/hidden-constructors.js +++ b/harness/hidden-constructors.js @@ -10,6 +10,18 @@ defines: - GeneratorFunction ---*/ -var AsyncFunction = Object.getPrototypeOf(async function () {}).constructor; -var AsyncGeneratorFunction = Object.getPrototypeOf(async function* () {}).constructor; -var GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor; +var AsyncFunction; +var AsyncGeneratorFunction; +var GeneratorFunction; + +try { + AsyncFunction = Object.getPrototypeOf(new Function('async function () {}')).constructor; +} catch(e) {} + +try { + AsyncGeneratorFunction = Object.getPrototypeOf(new Function('async function* () {}')).constructor; +} catch(e) {} + +try { + GeneratorFunction = Object.getPrototypeOf(new Function('function* () {}')).constructor; +} catch(e) {} From 29fe58bc8f9a861b02f87b2212753f24f2494660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 24 Jul 2024 18:36:44 +0200 Subject: [PATCH 25/90] Update LICENSE (#4107) * Update LICENSE * Update LICENSE * Update LICENSE Co-authored-by: Jordan Harband --------- Co-authored-by: Jordan Harband --- LICENSE | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/LICENSE b/LICENSE index a4ff57b807..a56b038f0e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,11 +1,11 @@ -The << Software identified by reference to the Ecma Standard* ("Software)">> is protected by copyright and is being +Test262: ECMAScript Test Suite ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA -CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT http://www.ecma-international.org/memento/codeofconduct.htm FOR +CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://www.ecma-international.org/ipr FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS*. -Copyright (C) 2012-2013 Ecma International +Copyright (C) 2012 Ecma International All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the @@ -25,4 +25,4 @@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* Ecma International Standards hereafter means Ecma International Standards as well as Ecma Technical Reports \ No newline at end of file +* Ecma International Standards hereafter means Ecma International Standards as well as Ecma Technical Reports From 50b023e6c9498fddbd6d11bb27be38008127b365 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Wed, 24 Jul 2024 10:29:51 -0700 Subject: [PATCH 26/90] Fix syntax error from #4164 (#4167) * Fix syntax error from #4164 Function statements require a name. See #4166 * Apply suggestions from code review Co-authored-by: Jordan Harband --------- Co-authored-by: Jordan Harband --- harness/hidden-constructors.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/harness/hidden-constructors.js b/harness/hidden-constructors.js index d73facfbcf..d721379470 100644 --- a/harness/hidden-constructors.js +++ b/harness/hidden-constructors.js @@ -15,13 +15,13 @@ var AsyncGeneratorFunction; var GeneratorFunction; try { - AsyncFunction = Object.getPrototypeOf(new Function('async function () {}')).constructor; + AsyncFunction = Object.getPrototypeOf(new Function('return async function dummy() {}')()).constructor; } catch(e) {} try { - AsyncGeneratorFunction = Object.getPrototypeOf(new Function('async function* () {}')).constructor; + AsyncGeneratorFunction = Object.getPrototypeOf(new Function('return async function* dummy() {}')()).constructor; } catch(e) {} try { - GeneratorFunction = Object.getPrototypeOf(new Function('function* () {}')).constructor; + GeneratorFunction = Object.getPrototypeOf(new Function('return function* dummy() {}')()).constructor; } catch(e) {} From b6c2f5595401b894adfc5fc2cc157ccee8884b24 Mon Sep 17 00:00:00 2001 From: Paul Bakker <4981149+p-bakker@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:20:44 +0200 Subject: [PATCH 27/90] Remove unneeded /u flag within harness/nativeFunctionMatcher --- harness/nativeFunctionMatcher.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/harness/nativeFunctionMatcher.js b/harness/nativeFunctionMatcher.js index 82ff9a88c3..591447b9f1 100644 --- a/harness/nativeFunctionMatcher.js +++ b/harness/nativeFunctionMatcher.js @@ -23,8 +23,8 @@ const validateNativeFunctionSource = function(source) { // `/\p{Space_Separator}/u` const UnicodeSpaceSeparator = /[ \xA0\u1680\u2000-\u200A\u202F\u205F\u3000]/; - const isNewline = (c) => /[\u000A\u000D\u2028\u2029]/u.test(c); - const isWhitespace = (c) => /[\u0009\u000B\u000C\u0020\u00A0\uFEFF]/u.test(c) || UnicodeSpaceSeparator.test(c); + const isNewline = (c) => /[\u000A\u000D\u2028\u2029]/.test(c); + const isWhitespace = (c) => /[\u0009\u000B\u000C\u0020\u00A0\uFEFF]/.test(c) || UnicodeSpaceSeparator.test(c); let pos = 0; From 79df6ec2e126db9d7186621115d681f6e06d4fb8 Mon Sep 17 00:00:00 2001 From: Paul Bakker <4981149+p-bakker@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:13:44 +0200 Subject: [PATCH 28/90] Make resizableArrayBufferUtils not depend on syntax that may not be supported --- harness/resizableArrayBufferUtils.js | 33 ++++++++++++---------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/harness/resizableArrayBufferUtils.js b/harness/resizableArrayBufferUtils.js index e6d9d7167f..097ff5a232 100644 --- a/harness/resizableArrayBufferUtils.js +++ b/harness/resizableArrayBufferUtils.js @@ -18,14 +18,10 @@ defines: features: [BigInt] ---*/ -class MyUint8Array extends Uint8Array { -} - -class MyFloat32Array extends Float32Array { -} - -class MyBigInt64Array extends BigInt64Array { -} +// Using new Function()(); instead of just 'class x extends Y' as to not bomb out when `class` isn't supported +const MyUint8Array = new Function('return class MyUint8Array extends Uint8Array {}')(); +const MyFloat32Array = new Function('return class MyFloat32Array extends Float32Array {}')(); +const MyBigInt64Array = new Function('return class MyBigInt64Array extends BigInt64Array {}')(); const builtinCtors = [ Uint8Array, @@ -39,15 +35,18 @@ const builtinCtors = [ Uint8ClampedArray, ]; -// BigInt and Float16Array are newer features adding them above unconditionally +// Big(U)int64Array and Float16Array are newer features adding them above unconditionally // would cause implementations lacking it to fail every test which uses it. if (typeof Float16Array !== 'undefined') { builtinCtors.push(Float16Array); } -if (typeof BigInt !== 'undefined') { - builtinCtors.push(BigUint64Array); - builtinCtors.push(BigInt64Array); +if (typeof BigUint64Array !== 'undefined') { + builtinCtors.push(BigUint64Array); +} + +if (typeof BigInt64Array !== 'undefined') { + builtinCtors.push(BigInt64Array); } const floatCtors = [ @@ -60,13 +59,9 @@ if (typeof Float16Array !== 'undefined') { floatCtors.push(Float16Array); } -const ctors = [ - ...builtinCtors, - MyUint8Array, - MyFloat32Array -]; +const ctors = builtinCtors.concat(MyUint8Array, MyFloat32Array); -if (typeof BigInt !== 'undefined') { +if (typeof MyBigInt64Array !== 'undefined') { ctors.push(MyBigInt64Array); } @@ -125,7 +120,7 @@ function TestIterationAndResize(iterable, expected, rab, resizeAfter, newByteLen let resized = false; var arrayValues = false; - for (const value of iterable) { + for (let value of iterable) { if (Array.isArray(value)) { arrayValues = true; values.push([ From 12416e0fa9c2c4c03d6089228989ef82888b782f Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Fri, 8 Sep 2023 21:54:53 -0700 Subject: [PATCH 29/90] Add tests for DurationFormat PR 172 and 167 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test the order of resolvedOptions in default setting Also add test to check the reading order of options based on the property returned in the default setting resolvedOptions. https://github.com/tc39/proposal-intl-duration-format/pull/167 https://github.com/tc39/proposal-intl-duration-format/pull/172 https://tc39.es/proposal-intl-duration-format/#sec-Intl.DurationFormat.prototype.resolvedOptions These two PRs are presenting to TC39 2023-09 meeting Swap actual/expected order Update test/intl402/DurationFormat/constructor-option-read-order.js Co-authored-by: André Bargull Fix per anba suggestion --- .../constructor-option-read-order.js | 47 +++++++++++++++++++ .../return-keys-order-default.js | 34 ++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 test/intl402/DurationFormat/constructor-option-read-order.js create mode 100644 test/intl402/DurationFormat/prototype/resolvedOptions/return-keys-order-default.js diff --git a/test/intl402/DurationFormat/constructor-option-read-order.js b/test/intl402/DurationFormat/constructor-option-read-order.js new file mode 100644 index 0000000000..a37cf5ed59 --- /dev/null +++ b/test/intl402/DurationFormat/constructor-option-read-order.js @@ -0,0 +1,47 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DurationFormat +description: Checks the order of option read. +features: [Intl.DurationFormat] +includes: [compareArray.js] +---*/ + +let optionKeys = Object.keys((new Intl.DurationFormat()).resolvedOptions()); +let opt = {}; +let readKeys = new Array(); +// For each item returned by resolvedOptions of default, add a getter +// to track the reading order. +optionKeys.forEach((property) => + Object.defineProperty(opt, property, { + get() { + readKeys[readKeys.length] = property; + return undefined; + }, + })); +let p = new Intl.DurationFormat(undefined, opt); +assert.compareArray( + readKeys, + ['numberingSystem', + 'style', + 'years', + 'yearsDisplay', + 'months', + 'monthsDisplay', + 'weeks', + 'weeksDisplay', + 'days', + 'daysDisplay', + 'hours', + 'hoursDisplay', + 'minutes', + 'minutesDisplay', + 'seconds', + 'secondsDisplay', + 'milliseconds', + 'millisecondsDisplay', + 'microseconds', + 'microsecondsDisplay', + 'nanoseconds', + 'nanosecondsDisplay']); diff --git a/test/intl402/DurationFormat/prototype/resolvedOptions/return-keys-order-default.js b/test/intl402/DurationFormat/prototype/resolvedOptions/return-keys-order-default.js new file mode 100644 index 0000000000..a817731948 --- /dev/null +++ b/test/intl402/DurationFormat/prototype/resolvedOptions/return-keys-order-default.js @@ -0,0 +1,34 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-intl.durationformat.prototype.resolvedoptions +description: order of property keys for the object returned by resolvedOptions() +features: [Intl.DurationFormat] +includes: [compareArray.js] +---*/ + +assert.compareArray( + Object.keys((new Intl.DurationFormat()).resolvedOptions()), + ['locale', + 'numberingSystem', + 'style', + 'years', + 'yearsDisplay', + 'months', + 'monthsDisplay', + 'weeks', + 'weeksDisplay', + 'days', + 'daysDisplay', + 'hours', + 'hoursDisplay', + 'minutes', + 'minutesDisplay', + 'seconds', + 'secondsDisplay', + 'milliseconds', + 'millisecondsDisplay', + 'microseconds', + 'microsecondsDisplay', + 'nanoseconds', + 'nanosecondsDisplay']); From 1dd1b91d14cd4915dfa8f8c25aba4e4152a92c65 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Thu, 25 Jul 2024 01:39:27 +0200 Subject: [PATCH 30/90] RAB: Integrate staging tests for the .reduceRight method (#4157) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while adjusting usage of CollectValuesAndResize and applying review changes from PRs for previously tested methods. * Added missing 'shrink' test for Array.prototype.reduceRight --- .../resizable-buffer-grow-mid-iteration.js | 83 ++++++++++ .../resizable-buffer-shrink-mid-iteration.js | 95 ++++++++++++ .../prototype/reduceRight/resizable-buffer.js | 129 ++++++++++++++++ .../resizable-buffer-grow-mid-iteration.js | 85 ++++++++++ .../resizable-buffer-shrink-mid-iteration.js | 101 ++++++++++++ .../prototype/reduceRight/resizable-buffer.js | 146 ++++++++++++++++++ 6 files changed, 639 insertions(+) create mode 100644 test/built-ins/Array/prototype/reduceRight/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/reduceRight/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/reduceRight/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer.js diff --git a/test/built-ins/Array/prototype/reduceRight/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/reduceRight/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..875c905817 --- /dev/null +++ b/test/built-ins/Array/prototype/reduceRight/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,83 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.reduceright +description: > + Array.p.reduceRight behaves correctly on TypedArrays backed by resizable + buffers that are grown mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset before +// calling this. +function ResizeBufferMidIteration(acc, n) { + return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduceRight.call(fixedLength, ResizeBufferMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4, + 2, + 0 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduceRight.call(fixedLengthWithOffset, ResizeBufferMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduceRight.call(lengthTracking, ResizeBufferMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4, + 2, + 0 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduceRight.call(lengthTrackingWithOffset, ResizeBufferMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4 + ]); +} diff --git a/test/built-ins/Array/prototype/reduceRight/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/Array/prototype/reduceRight/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..5c14e80dc1 --- /dev/null +++ b/test/built-ins/Array/prototype/reduceRight/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,95 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%array%.prototype.reduceright +description: > + Array.p.reduceRight behaves correctly when the backing resizable buffer is + shrunk mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset before +// calling this. +function ResizeMidIteration(acc, n) { + return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduceRight.call(fixedLength, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduceRight.call(fixedLengthWithOffset, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + // Unaffected by the shrinking, since we've already iterated past the point. + Array.prototype.reduceRight.call(lengthTracking, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4, + 2, + 0 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 1; + resizeTo = 2 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduceRight.call(lengthTracking, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 2, + 0 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + // Unaffected by the shrinking, since we've already iterated past the point. + Array.prototype.reduceRight.call(lengthTrackingWithOffset, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4 + ]); +} diff --git a/test/built-ins/Array/prototype/reduceRight/resizable-buffer.js b/test/built-ins/Array/prototype/reduceRight/resizable-buffer.js new file mode 100644 index 0000000000..a1fa69c6b0 --- /dev/null +++ b/test/built-ins/Array/prototype/reduceRight/resizable-buffer.js @@ -0,0 +1,129 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.reduceright +description: > + Array.p.reduceRight behaves correctly on TypedArrays backed by resizable + buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + function ReduceRightCollecting(array) { + const reduceRightValues = []; + Array.prototype.reduceRight.call(array, (acc, n) => { + reduceRightValues.push(n); + }, 'initial value'); + reduceRightValues.reverse(); + return ToNumbers(reduceRightValues); + } + assert.compareArray(ReduceRightCollecting(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceRightCollecting(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(ReduceRightCollecting(lengthTracking), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceRightCollecting(lengthTrackingWithOffset), [ + 4, + 6 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.compareArray(ReduceRightCollecting(fixedLength), []); + assert.compareArray(ReduceRightCollecting(fixedLengthWithOffset), []); + + assert.compareArray(ReduceRightCollecting(lengthTracking), [ + 0, + 2, + 4 + ]); + assert.compareArray(ReduceRightCollecting(lengthTrackingWithOffset), [4]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.compareArray(ReduceRightCollecting(fixedLength), []); + assert.compareArray(ReduceRightCollecting(fixedLengthWithOffset), []); + + assert.compareArray(ReduceRightCollecting(lengthTracking), [0]); + + // Shrink to zero. + rab.resize(0); + assert.compareArray(ReduceRightCollecting(fixedLength), []); + assert.compareArray(ReduceRightCollecting(fixedLengthWithOffset), []); + assert.compareArray(ReduceRightCollecting(lengthTrackingWithOffset), []); + + assert.compareArray(ReduceRightCollecting(lengthTracking), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.compareArray(ReduceRightCollecting(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceRightCollecting(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(ReduceRightCollecting(lengthTracking), [ + 0, + 2, + 4, + 6, + 8, + 10 + ]); + assert.compareArray(ReduceRightCollecting(lengthTrackingWithOffset), [ + 4, + 6, + 8, + 10 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..48f935e89b --- /dev/null +++ b/test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,85 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.reduceright +description: > + TypedArray.p.reduceRight behaves correctly on TypedArrays backed by resizable + buffers that are grown mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset before +// calling this. +function ResizeMidIteration(acc, n) { + return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +// Test for reduceRight. + +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + fixedLength.reduceRight(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4, + 2, + 0 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + fixedLengthWithOffset.reduceRight(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + lengthTracking.reduceRight(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4, + 2, + 0 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.reduceRight(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..9f2745fcf4 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,101 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.reduceright +description: > + TypedArray.p.reduceRight behaves correctly on TypedArrays backed by resizable + buffer that is shrunk mid-iteration +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset before +// calling this. +function ResizeMidIteration(acc, n) { + return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +// Tests for reduceRight. + +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLength.reduceRight(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4, + undefined, + undefined + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLengthWithOffset.reduceRight(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + undefined + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + // Unaffected by the shrinking, since we've already iterated past the point. + lengthTracking.reduceRight(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4, + 2, + 0 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 1; + resizeTo = 2 * ctor.BYTES_PER_ELEMENT; + lengthTracking.reduceRight(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + undefined, + 2, + 0 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + // Unaffected by the shrinking, since we've already iterated past the point. + lengthTrackingWithOffset.reduceRight(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 6, + 4 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer.js b/test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer.js new file mode 100644 index 0000000000..a3c2770c06 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/reduceRight/resizable-buffer.js @@ -0,0 +1,146 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.reduceright +description: > + TypedArray.p.reduceRight behaves correctly on TypedArrays backed by resizable + buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + function ReduceRightCollecting(array) { + const reduceRightValues = []; + array.reduceRight((acc, n) => { + reduceRightValues.push(n); + }, 'initial value'); + reduceRightValues.reverse(); + return ToNumbers(reduceRightValues); + } + assert.compareArray(ReduceRightCollecting(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceRightCollecting(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(ReduceRightCollecting(lengthTracking), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceRightCollecting(lengthTrackingWithOffset), [ + 4, + 6 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + ReduceRightCollecting(fixedLength); + }); + assert.throws(TypeError, () => { + ReduceRightCollecting(fixedLengthWithOffset); + }); + + assert.compareArray(ReduceRightCollecting(lengthTracking), [ + 0, + 2, + 4 + ]); + assert.compareArray(ReduceRightCollecting(lengthTrackingWithOffset), [4]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + ReduceRightCollecting(fixedLength); + }); + assert.throws(TypeError, () => { + ReduceRightCollecting(fixedLengthWithOffset); + }); + assert.throws(TypeError, () => { + ReduceRightCollecting(lengthTrackingWithOffset); + }); + + assert.compareArray(ReduceRightCollecting(lengthTracking), [0]); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + ReduceRightCollecting(fixedLength); + }); + assert.throws(TypeError, () => { + ReduceRightCollecting(fixedLengthWithOffset); + }); + assert.throws(TypeError, () => { + ReduceRightCollecting(lengthTrackingWithOffset); + }); + + assert.compareArray(ReduceRightCollecting(lengthTracking), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.compareArray(ReduceRightCollecting(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceRightCollecting(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(ReduceRightCollecting(lengthTracking), [ + 0, + 2, + 4, + 6, + 8, + 10 + ]); + assert.compareArray(ReduceRightCollecting(lengthTrackingWithOffset), [ + 4, + 6, + 8, + 10 + ]); +} From 18ebac8122117bdc55a0d4bba972ba80c0194b41 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Thu, 25 Jul 2024 01:55:16 +0200 Subject: [PATCH 31/90] RAB: Integrate staging tests for the .reverse method (#4160) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while adjusting usage of CollectValuesAndResize and applying review changes from PRs for previously tested methods. --- .../prototype/reverse/resizable-buffer.js | 164 +++++++++++++++++ .../prototype/reverse/resizable-buffer.js | 165 ++++++++++++++++++ 2 files changed, 329 insertions(+) create mode 100644 test/built-ins/Array/prototype/reverse/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/reverse/resizable-buffer.js diff --git a/test/built-ins/Array/prototype/reverse/resizable-buffer.js b/test/built-ins/Array/prototype/reverse/resizable-buffer.js new file mode 100644 index 0000000000..f3b06228e7 --- /dev/null +++ b/test/built-ins/Array/prototype/reverse/resizable-buffer.js @@ -0,0 +1,164 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.reverse +description: > + Array.p.reverse behaves correctly on TypedArrays backed by resizable buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const wholeArrayView = new ctor(rab); + function WriteData() { + // Write some data into the array. + for (let i = 0; i < wholeArrayView.length; ++i) { + WriteToTypedArray(wholeArrayView, i, 2 * i); + } + } + WriteData(); + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + Array.prototype.reverse.call(fixedLength); + assert.compareArray(ToNumbers(wholeArrayView), [ + 6, + 4, + 2, + 0 + ]); + Array.prototype.reverse.call(fixedLengthWithOffset); + assert.compareArray(ToNumbers(wholeArrayView), [ + 6, + 4, + 0, + 2 + ]); + Array.prototype.reverse.call(lengthTracking); + assert.compareArray(ToNumbers(wholeArrayView), [ + 2, + 0, + 4, + 6 + ]); + Array.prototype.reverse.call(lengthTrackingWithOffset); + assert.compareArray(ToNumbers(wholeArrayView), [ + 2, + 0, + 6, + 4 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + WriteData(); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + Array.prototype.reverse.call(fixedLength); + assert.compareArray(ToNumbers(wholeArrayView), [ + 0, + 2, + 4 + ]); + Array.prototype.reverse.call(fixedLengthWithOffset); + assert.compareArray(ToNumbers(wholeArrayView), [ + 0, + 2, + 4 + ]); + Array.prototype.reverse.call(lengthTracking); + assert.compareArray(ToNumbers(wholeArrayView), [ + 4, + 2, + 0 + ]); + Array.prototype.reverse.call(lengthTrackingWithOffset); + assert.compareArray(ToNumbers(wholeArrayView), [ + 4, + 2, + 0 + ]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + WriteData(); + Array.prototype.reverse.call(fixedLength); + assert.compareArray(ToNumbers(wholeArrayView), [0]); + Array.prototype.reverse.call(fixedLengthWithOffset); + assert.compareArray(ToNumbers(wholeArrayView), [0]); + Array.prototype.reverse.call(lengthTrackingWithOffset); + assert.compareArray(ToNumbers(wholeArrayView), [0]); + Array.prototype.reverse.call(lengthTracking); + assert.compareArray(ToNumbers(wholeArrayView), [0]); + + // Shrink to zero. + rab.resize(0); + Array.prototype.reverse.call(fixedLength); + assert.compareArray(ToNumbers(wholeArrayView), []); + Array.prototype.reverse.call(fixedLengthWithOffset); + assert.compareArray(ToNumbers(wholeArrayView), []); + Array.prototype.reverse.call(lengthTrackingWithOffset); + assert.compareArray(ToNumbers(wholeArrayView), []); + Array.prototype.reverse.call(lengthTracking); + assert.compareArray(ToNumbers(wholeArrayView), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + WriteData(); + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + Array.prototype.reverse.call(fixedLength); + assert.compareArray(ToNumbers(wholeArrayView), [ + 6, + 4, + 2, + 0, + 8, + 10 + ]); + Array.prototype.reverse.call(fixedLengthWithOffset); + assert.compareArray(ToNumbers(wholeArrayView), [ + 6, + 4, + 0, + 2, + 8, + 10 + ]); + Array.prototype.reverse.call(lengthTracking); + assert.compareArray(ToNumbers(wholeArrayView), [ + 10, + 8, + 2, + 0, + 4, + 6 + ]); + Array.prototype.reverse.call(lengthTrackingWithOffset); + assert.compareArray(ToNumbers(wholeArrayView), [ + 10, + 8, + 6, + 4, + 0, + 2 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/reverse/resizable-buffer.js b/test/built-ins/TypedArray/prototype/reverse/resizable-buffer.js new file mode 100644 index 0000000000..7c30bb0c1b --- /dev/null +++ b/test/built-ins/TypedArray/prototype/reverse/resizable-buffer.js @@ -0,0 +1,165 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.reverse +description: > + TypedArray.p.reverse behaves correctly on TypedArrays backed by resizable + buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const wholeArrayView = new ctor(rab); + function WriteData() { + // Write some data into the array. + for (let i = 0; i < wholeArrayView.length; ++i) { + WriteToTypedArray(wholeArrayView, i, 2 * i); + } + } + WriteData(); + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + fixedLength.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), [ + 6, + 4, + 2, + 0 + ]); + fixedLengthWithOffset.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), [ + 6, + 4, + 0, + 2 + ]); + lengthTracking.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), [ + 2, + 0, + 4, + 6 + ]); + lengthTrackingWithOffset.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), [ + 2, + 0, + 6, + 4 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + WriteData(); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + fixedLength.reverse(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.reverse(); + }); + lengthTracking.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), [ + 4, + 2, + 0 + ]); + lengthTrackingWithOffset.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), [ + 4, + 2, + 0 + ]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + WriteData(); + assert.throws(TypeError, () => { + fixedLength.reverse(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.reverse(); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.reverse(); + }); + lengthTracking.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), [0]); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + fixedLength.reverse(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.reverse(); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.reverse(); + }); + lengthTracking.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + WriteData(); + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + fixedLength.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), [ + 6, + 4, + 2, + 0, + 8, + 10 + ]); + fixedLengthWithOffset.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), [ + 6, + 4, + 0, + 2, + 8, + 10 + ]); + lengthTracking.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), [ + 10, + 8, + 2, + 0, + 4, + 6 + ]); + lengthTrackingWithOffset.reverse(); + assert.compareArray(ToNumbers(wholeArrayView), [ + 10, + 8, + 6, + 4, + 0, + 2 + ]); +} From e7d9c0d698b5f6fba871b57c9fe28365ffd2d87f Mon Sep 17 00:00:00 2001 From: Paul Bakker Date: Thu, 25 Jul 2024 08:49:23 +0200 Subject: [PATCH 32/90] Follow-up to #4165 Added catch to achieve the entire goal of the previous PR to prevent the harness from loading if 'class' syntax isn't supported --- harness/resizableArrayBufferUtils.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/harness/resizableArrayBufferUtils.js b/harness/resizableArrayBufferUtils.js index 097ff5a232..db58f521f8 100644 --- a/harness/resizableArrayBufferUtils.js +++ b/harness/resizableArrayBufferUtils.js @@ -17,11 +17,16 @@ defines: - TestIterationAndResize features: [BigInt] ---*/ +// Helper to create subclasses without bombing out when `class` isn't supported +function subClass(type) { + try { + return new Function('return class My' + type + ' extends ' + type + ' {}')(); + } catch (e) {} +} -// Using new Function()(); instead of just 'class x extends Y' as to not bomb out when `class` isn't supported -const MyUint8Array = new Function('return class MyUint8Array extends Uint8Array {}')(); -const MyFloat32Array = new Function('return class MyFloat32Array extends Float32Array {}')(); -const MyBigInt64Array = new Function('return class MyBigInt64Array extends BigInt64Array {}')(); +const MyUint8Array = subClass('Uint8Array'); +const MyFloat32Array = subClass('Float32Array'); +const MyBigInt64Array = subClass('BigInt64Array'); const builtinCtors = [ Uint8Array, From dcaed0523c4e301ae927d3252a35ab94eca03eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Wed, 29 May 2024 14:18:19 +0200 Subject: [PATCH 33/90] Allow implementation-defined behaviour for constraining leap months --- .../from/reference-day-chinese.js | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/intl402/Temporal/PlainYearMonth/from/reference-day-chinese.js b/test/intl402/Temporal/PlainYearMonth/from/reference-day-chinese.js index 0a8e3581bf..08cee90394 100644 --- a/test/intl402/Temporal/PlainYearMonth/from/reference-day-chinese.js +++ b/test/intl402/Temporal/PlainYearMonth/from/reference-day-chinese.js @@ -33,13 +33,34 @@ const months2022TestData = [ ["M11", 11, 24], ["M12", 12, 23], ]; -for (const [nonLeapMonthCode, month, referenceISODay] of months2022TestData) { +for (let [nonLeapMonthCode, month, referenceISODay] of months2022TestData) { // Allow implementation-defined "epoch year" for the Chinese calendar. const year = new Temporal.PlainDate(2022, 3, 1).withCalendar("chinese").year; const leapMonthCode = nonLeapMonthCode + "L"; const fields = { year, monthCode: leapMonthCode, calendar: "chinese" }; const result = Temporal.PlainYearMonth.from(fields, { overflow: "constrain" }); + + // CalendarDateToISO ( calendar, fields, overflow ) + // + // > If the month is a leap month that doesn't exist in the year, pick another + // > date according to the cultural conventions of that calendar's users. + // > Usually this will result in the same day in the month before or after + // > where that month would normally fall in a leap year. + // + // Without clear information in which direction the month has to be adjusted, + // we have to allow two possible implementations: + // 1. The previous month is used, i.e. "M01L" is constrained to "M01". + // 2. The next month is used, i.e. "M01L" is constrained to "M02". + if (result.month !== month) { + assert.sameValue(result.month, month + 1); + + // Adjust nonLeapMonthCode, month, referenceISODay using the data from the + // next month. + const nextMonth = months2022TestData.find(e => e[1] === month + 1); + [nonLeapMonthCode, month, referenceISODay] = nextMonth; + } + TemporalHelpers.assertPlainYearMonth( result, year, month, nonLeapMonthCode, From a238ad6a1efe1190061528067a390a940bfdef1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Thu, 30 May 2024 10:36:14 +0200 Subject: [PATCH 34/90] Move test for dates before start of the Japanese era into a new file See also requesting for more information how this case should actually be handled. --- .../Temporal/old/japanese-before-era.js | 63 +++++++++++++++++++ .../Intl402/Temporal/old/japanese-era.js | 55 ---------------- 2 files changed, 63 insertions(+), 55 deletions(-) create mode 100644 test/staging/Intl402/Temporal/old/japanese-before-era.js diff --git a/test/staging/Intl402/Temporal/old/japanese-before-era.js b/test/staging/Intl402/Temporal/old/japanese-before-era.js new file mode 100644 index 0000000000..c0bf973fc1 --- /dev/null +++ b/test/staging/Intl402/Temporal/old/japanese-before-era.js @@ -0,0 +1,63 @@ +// Copyright (C) 2018 Bloomberg LP. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal-intl +description: Japanese eras +features: [Temporal] +---*/ + +// Dates in same year before Japanese era starts will resolve to previous era +var date = Temporal.PlainDate.from({ + era: "reiwa", + eraYear: 1, + month: 1, + day: 1, + calendar: "japanese" +}); +assert.sameValue(`${ date }`, "2019-01-01[u-ca=japanese]"); +assert.sameValue(date.era, "heisei"); +assert.sameValue(date.eraYear, 31); + +date = Temporal.PlainDate.from({ + era: "heisei", + eraYear: 1, + month: 1, + day: 1, + calendar: "japanese" +}); +assert.sameValue(`${ date }`, "1989-01-01[u-ca=japanese]"); +assert.sameValue(date.era, "showa"); +assert.sameValue(date.eraYear, 64); +date = Temporal.PlainDate.from({ + era: "showa", + eraYear: 1, + month: 1, + day: 1, + calendar: "japanese" +}); +assert.sameValue(`${ date }`, "1926-01-01[u-ca=japanese]"); +assert.sameValue(date.era, "taisho"); +assert.sameValue(date.eraYear, 15); + +date = Temporal.PlainDate.from({ + era: "taisho", + eraYear: 1, + month: 1, + day: 1, + calendar: "japanese" +}); +assert.sameValue(`${ date }`, "1912-01-01[u-ca=japanese]"); +assert.sameValue(date.era, "meiji"); +assert.sameValue(date.eraYear, 45); + +date = Temporal.PlainDate.from({ + era: "meiji", + eraYear: 1, + month: 1, + day: 1, + calendar: "japanese" +}); +assert.sameValue(`${ date }`, "1868-01-01[u-ca=japanese]"); +assert.sameValue(date.era, "ce"); +assert.sameValue(date.eraYear, 1868); diff --git a/test/staging/Intl402/Temporal/old/japanese-era.js b/test/staging/Intl402/Temporal/old/japanese-era.js index 17d2572cf4..13c63eab5e 100644 --- a/test/staging/Intl402/Temporal/old/japanese-era.js +++ b/test/staging/Intl402/Temporal/old/japanese-era.js @@ -58,61 +58,6 @@ var date = Temporal.PlainDate.from({ }); assert.sameValue(`${ date }`, "1869-01-01[u-ca=japanese]"); -// Dates in same year before Japanese era starts will resolve to previous era -var date = Temporal.PlainDate.from({ - era: "reiwa", - eraYear: 1, - month: 1, - day: 1, - calendar: "japanese" -}); -assert.sameValue(`${ date }`, "2019-01-01[u-ca=japanese]"); -assert.sameValue(date.era, "heisei"); -assert.sameValue(date.eraYear, 31); - -date = Temporal.PlainDate.from({ - era: "heisei", - eraYear: 1, - month: 1, - day: 1, - calendar: "japanese" -}); -assert.sameValue(`${ date }`, "1989-01-01[u-ca=japanese]"); -assert.sameValue(date.era, "showa"); -assert.sameValue(date.eraYear, 64); -date = Temporal.PlainDate.from({ - era: "showa", - eraYear: 1, - month: 1, - day: 1, - calendar: "japanese" -}); -assert.sameValue(`${ date }`, "1926-01-01[u-ca=japanese]"); -assert.sameValue(date.era, "taisho"); -assert.sameValue(date.eraYear, 15); - -date = Temporal.PlainDate.from({ - era: "taisho", - eraYear: 1, - month: 1, - day: 1, - calendar: "japanese" -}); -assert.sameValue(`${ date }`, "1912-01-01[u-ca=japanese]"); -assert.sameValue(date.era, "meiji"); -assert.sameValue(date.eraYear, 45); - -date = Temporal.PlainDate.from({ - era: "meiji", - eraYear: 1, - month: 1, - day: 1, - calendar: "japanese" -}); -assert.sameValue(`${ date }`, "1868-01-01[u-ca=japanese]"); -assert.sameValue(date.era, "ce"); -assert.sameValue(date.eraYear, 1868); - // Verify that CE and BCE eras (before Meiji) are recognized date = Temporal.PlainDate.from({ era: "ce", From 7f81bb212674bf6593c041f330fe3c9f4015270f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Thu, 30 May 2024 10:38:56 +0200 Subject: [PATCH 35/90] Allow canonical era codes for Japanese era test --- test/staging/Intl402/Temporal/old/japanese-era.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/staging/Intl402/Temporal/old/japanese-era.js b/test/staging/Intl402/Temporal/old/japanese-era.js index 13c63eab5e..60155fd77d 100644 --- a/test/staging/Intl402/Temporal/old/japanese-era.js +++ b/test/staging/Intl402/Temporal/old/japanese-era.js @@ -4,6 +4,7 @@ /*--- esid: sec-temporal-intl description: Japanese eras +includes: [temporalHelpers.js] features: [Temporal] ---*/ @@ -67,7 +68,10 @@ date = Temporal.PlainDate.from({ calendar: "japanese" }); assert.sameValue(`${date}`, "1000-01-01[u-ca=japanese]"); -assert.sameValue(date.era, "ce"); +assert.sameValue( + TemporalHelpers.canonicalizeEraInCalendar(date, date.era), + TemporalHelpers.canonicalizeEraInCalendar(date, "ce"), +); assert.sameValue(date.eraYear, 1000); date = Temporal.PlainDate.from({ @@ -78,5 +82,8 @@ date = Temporal.PlainDate.from({ calendar: "japanese" }); assert.sameValue(`${date}`, "0000-01-01[u-ca=japanese]"); -assert.sameValue(date.era, "bce"); +assert.sameValue( + TemporalHelpers.canonicalizeEraInCalendar(date, date.era), + TemporalHelpers.canonicalizeEraInCalendar(date, "bce"), +); assert.sameValue(date.eraYear, 1); From 242f6f98f0f86c0a3276929b4a450438526057cb Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Fri, 26 Jul 2024 01:04:41 +0200 Subject: [PATCH 36/90] RAB: Integrate staging tests for the .map method (#4155) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while adjusting usage of CollectValuesAndResize and applying review changes from PRs for previously tested methods. * Apply suggestions from code review --- .../resizable-buffer-grow-mid-iteration.js | 82 +++++++++ .../resizable-buffer-shrink-mid-iteration.js | 79 +++++++++ .../Array/prototype/map/resizable-buffer.js | 141 ++++++++++++++++ .../resizable-buffer-grow-mid-iteration.js | 83 +++++++++ .../resizable-buffer-shrink-mid-iteration.js | 89 ++++++++++ .../prototype/map/resizable-buffer.js | 158 ++++++++++++++++++ .../map/speciesctor-resizable-buffer-grow.js | 85 ++++++++++ .../speciesctor-resizable-buffer-shrink.js | 82 +++++++++ 8 files changed, 799 insertions(+) create mode 100644 test/built-ins/Array/prototype/map/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/map/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/map/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/map/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/map/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/map/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/map/speciesctor-resizable-buffer-grow.js create mode 100644 test/built-ins/TypedArray/prototype/map/speciesctor-resizable-buffer-shrink.js diff --git a/test/built-ins/Array/prototype/map/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/map/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..4bcd91b4f6 --- /dev/null +++ b/test/built-ins/Array/prototype/map/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,82 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.map +description: > + Array.p.map behaves correctly when the resizable buffer is grown mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset +// before calling this. +function ResizeMidIteration(n) { + CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); + return n; +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.map.call(fixedLength, ResizeMidIteration); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.map.call(fixedLengthWithOffset, ResizeMidIteration); + assert.compareArray(values, [ + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.map.call(lengthTracking, ResizeMidIteration); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.map.call(lengthTrackingWithOffset, ResizeMidIteration); + assert.compareArray(values, [ + 4, + 6 + ]); +} diff --git a/test/built-ins/Array/prototype/map/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/Array/prototype/map/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..0c305ea252 --- /dev/null +++ b/test/built-ins/Array/prototype/map/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,79 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.map +description: > + Array.p.map behaves correctly when the resizable buffer is shrunk mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset +// before calling this. This version can deal with the undefined values +// resulting by shrinking rab. +function ShrinkMidIteration(n, ix, ta) { + CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); + // We still need to return a valid BigInt / non-BigInt, even if + // n is `undefined`. + if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) { + return 0n; + } + return 0; +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + Array.prototype.map.call(fixedLength, ShrinkMidIteration); + assert.compareArray(values, [ + 0, + 2 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + Array.prototype.map.call(fixedLengthWithOffset, ShrinkMidIteration); + assert.compareArray(values, [4]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + Array.prototype.map.call(lengthTracking, ShrinkMidIteration); + assert.compareArray(values, [ + 0, + 2, + 4 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + Array.prototype.map.call(lengthTrackingWithOffset, ShrinkMidIteration); + assert.compareArray(values, [4]); +} diff --git a/test/built-ins/Array/prototype/map/resizable-buffer.js b/test/built-ins/Array/prototype/map/resizable-buffer.js new file mode 100644 index 0000000000..e108395fcb --- /dev/null +++ b/test/built-ins/Array/prototype/map/resizable-buffer.js @@ -0,0 +1,141 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.map +description: > + Array.p.map behaves as expected on TypedArrays backed by resizable buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < taWrite.length; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + function MapGatherCompare(array) { + const values = []; + function GatherValues(n, ix) { + assert.sameValue(ix, values.length); + values.push(n); + if (typeof n == 'bigint') { + return n + 1n; + } + return n + 1; + } + const newValues = Array.prototype.map.call(array, GatherValues); + for (let i = 0; i < values.length; ++i) { + if (typeof values[i] == 'bigint') { + assert.sameValue(values[i] + 1n, newValues[i]); + } else { + assert.sameValue(values[i] + 1, newValues[i]); + } + } + return ToNumbers(values); + } + assert.compareArray(MapGatherCompare(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(MapGatherCompare(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(MapGatherCompare(lengthTracking), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(MapGatherCompare(lengthTrackingWithOffset), [ + 4, + 6 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.compareArray(MapGatherCompare(fixedLength), []); + assert.compareArray(MapGatherCompare(fixedLengthWithOffset), []); + + assert.compareArray(MapGatherCompare(lengthTracking), [ + 0, + 2, + 4 + ]); + assert.compareArray(MapGatherCompare(lengthTrackingWithOffset), [4]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.compareArray(MapGatherCompare(fixedLength), []); + assert.compareArray(MapGatherCompare(fixedLengthWithOffset), []); + assert.compareArray(MapGatherCompare(lengthTrackingWithOffset), []); + + assert.compareArray(MapGatherCompare(lengthTracking), [0]); + + // Shrink to zero. + rab.resize(0); + assert.compareArray(MapGatherCompare(fixedLength), []); + assert.compareArray(MapGatherCompare(fixedLengthWithOffset), []); + assert.compareArray(MapGatherCompare(lengthTrackingWithOffset), []); + + assert.compareArray(MapGatherCompare(lengthTracking), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.compareArray(MapGatherCompare(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(MapGatherCompare(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(MapGatherCompare(lengthTracking), [ + 0, + 2, + 4, + 6, + 8, + 10 + ]); + assert.compareArray(MapGatherCompare(lengthTrackingWithOffset), [ + 4, + 6, + 8, + 10 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/map/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/map/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..a6f6d4545f --- /dev/null +++ b/test/built-ins/TypedArray/prototype/map/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,83 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.map +description: > + TypedArray.p.map behaves correctly on TypedArrays backed by resizable buffers + that are grown mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset +// before calling this. +function ResizeMidIteration(n) { + CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); + return n; +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + fixedLength.map(ResizeMidIteration); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + fixedLengthWithOffset.map(ResizeMidIteration); + assert.compareArray(values, [ + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + lengthTracking.map(ResizeMidIteration); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.map(ResizeMidIteration); + assert.compareArray(values, [ + 4, + 6 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/map/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/map/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..e72aba9750 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/map/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,89 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.map +description: > + TypedArray.p.map behaves correctly on TypedArrays backed by resizable buffers + that are shrunk mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset +// before calling this. This version can deal with the undefined values +// resulting by shrinking rab. +function ShrinkMidIteration(n, ix, ta) { + CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); + // We still need to return a valid BigInt / non-BigInt, even if + // n is `undefined`. + if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) { + return 0n; + } + return 0; +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLength.map(ShrinkMidIteration); + assert.compareArray(values, [ + 0, + 2, + undefined, + undefined + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLengthWithOffset.map(ShrinkMidIteration); + assert.compareArray(values, [ + 4, + undefined + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + lengthTracking.map(ShrinkMidIteration); + assert.compareArray(values, [ + 0, + 2, + 4, + undefined + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.map(ShrinkMidIteration); + assert.compareArray(values, [ + 4, + undefined + ]); +} diff --git a/test/built-ins/TypedArray/prototype/map/resizable-buffer.js b/test/built-ins/TypedArray/prototype/map/resizable-buffer.js new file mode 100644 index 0000000000..24c7cf1bb4 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/map/resizable-buffer.js @@ -0,0 +1,158 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.map +description: > + TypedArray.p.map behaves as expected on TypedArrays backed by resizable + buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < taWrite.length; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + function MapGathering(array) { + const values = []; + function GatherValues(n, ix) { + assert.sameValue(ix, values.length); + values.push(n); + if (typeof n == 'bigint') { + return n + 1n; + } + return n + 1; + } + const newValues = array.map(GatherValues); + for (let i = 0; i < values.length; ++i) { + if (typeof values[i] == 'bigint') { + assert.sameValue(values[i] + 1n, newValues[i]); + } else { + assert.sameValue(values[i] + 1, newValues[i]); + } + } + return ToNumbers(values); + } + assert.compareArray(MapGathering(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(MapGathering(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(MapGathering(lengthTracking), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(MapGathering(lengthTrackingWithOffset), [ + 4, + 6 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + MapGathering(fixedLength); + }); + assert.throws(TypeError, () => { + MapGathering(fixedLengthWithOffset); + }); + + assert.compareArray(MapGathering(lengthTracking), [ + 0, + 2, + 4 + ]); + assert.compareArray(MapGathering(lengthTrackingWithOffset), [4]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + MapGathering(fixedLength); + }); + assert.throws(TypeError, () => { + MapGathering(fixedLengthWithOffset); + }); + assert.throws(TypeError, () => { + MapGathering(lengthTrackingWithOffset); + }); + + assert.compareArray(MapGathering(lengthTracking), [0]); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + MapGathering(fixedLength); + }); + assert.throws(TypeError, () => { + MapGathering(fixedLengthWithOffset); + }); + assert.throws(TypeError, () => { + MapGathering(lengthTrackingWithOffset); + }); + + assert.compareArray(MapGathering(lengthTracking), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.compareArray(MapGathering(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(MapGathering(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(MapGathering(lengthTracking), [ + 0, + 2, + 4, + 6, + 8, + 10 + ]); + assert.compareArray(MapGathering(lengthTrackingWithOffset), [ + 4, + 6, + 8, + 10 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/map/speciesctor-resizable-buffer-grow.js b/test/built-ins/TypedArray/prototype/map/speciesctor-resizable-buffer-grow.js new file mode 100644 index 0000000000..d9999cb8a2 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/map/speciesctor-resizable-buffer-grow.js @@ -0,0 +1,85 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.map +description: > + TypedArray.p.map behaves correctly on TypedArrays backed by resizable buffers + that are grown by the species constructor. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Returns a function that collects an appropriate typed array into values. Such +// a result can be used as an argument to .map. +function CollectWithUndefined(values) { + return (n, ix, ta) => { + if (typeof n == 'bigint') { + values.push(Number(n)); + } else { + values.push(n); + } + if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) { + // We still need to return a valid BigInt / non-BigInt, even if + // n is `undefined`. + return 0n; + } + return 0; + } +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, i); + } + let resizeWhenConstructorCalled = false; + class MyArray extends ctor { + constructor(...params) { + super(...params); + if (resizeWhenConstructorCalled) { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + } + } + }; + const fixedLength = new MyArray(rab, 0, 4); + resizeWhenConstructorCalled = true; + const values = []; + fixedLength.map(CollectWithUndefined(values)); + assert.compareArray(values, [ + 0, + 1, + 2, + 3 + ]); + assert.sameValue(rab.byteLength, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, i); + } + let resizeWhenConstructorCalled = false; + class MyArray extends ctor { + constructor(...params) { + super(...params); + if (resizeWhenConstructorCalled) { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + } + } + } + ; + const lengthTracking = new MyArray(rab); + resizeWhenConstructorCalled = true; + const values = []; + lengthTracking.map(CollectWithUndefined(values)); + assert.compareArray(values, [ + 0, + 1, + 2, + 3 + ]); + assert.sameValue(rab.byteLength, 6 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/TypedArray/prototype/map/speciesctor-resizable-buffer-shrink.js b/test/built-ins/TypedArray/prototype/map/speciesctor-resizable-buffer-shrink.js new file mode 100644 index 0000000000..7b4e47d99a --- /dev/null +++ b/test/built-ins/TypedArray/prototype/map/speciesctor-resizable-buffer-shrink.js @@ -0,0 +1,82 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.map +description: > + TypedArray.p.map behaves correctly on TypedArrays backed by resizable buffers + that are shrunk by the species constructor. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Returns a function that collects an appropriate typed array into values. Such +// a result can be used as an argument to .map. +function CollectWithUndefined(values) { + return (n, ix, ta) => { + if (typeof n == 'bigint') { + values.push(Number(n)); + } else { + values.push(n); + } + if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) { + // We still need to return a valid BigInt / non-BigInt, even if + // n is `undefined`. + return 0n; + } + return 0; + } +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + let resizeWhenConstructorCalled = false; + class MyArray extends ctor { + constructor(...params) { + super(...params); + if (resizeWhenConstructorCalled) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + } + } + ; + const fixedLength = new MyArray(rab, 0, 4); + resizeWhenConstructorCalled = true; + const values = []; + fixedLength.map(CollectWithUndefined(values)); + assert.compareArray(values, [ + undefined, + undefined, + undefined, + undefined + ]); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, i); + } + let resizeWhenConstructorCalled = false; + class MyArray extends ctor { + constructor(...params) { + super(...params); + if (resizeWhenConstructorCalled) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + } + } + ; + const lengthTracking = new MyArray(rab); + resizeWhenConstructorCalled = true; + const values = []; + lengthTracking.map(CollectWithUndefined(values)); + assert.compareArray(values, [ + 0, + 1, + undefined, + undefined + ]); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); +} From 3b89be9c5d6af045da5fe56b9de30daf8fa4d68d Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 25 Jul 2024 13:35:01 -0700 Subject: [PATCH 37/90] Temporal: Fix Japanese era test This mistakenly used a previous name for the helper function. Also adds a couple of debugging messages. --- harness/temporalHelpers.js | 4 ++-- test/staging/Intl402/Temporal/old/japanese-era.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/harness/temporalHelpers.js b/harness/temporalHelpers.js index 20de03635b..6aba4a03cf 100644 --- a/harness/temporalHelpers.js +++ b/harness/temporalHelpers.js @@ -127,7 +127,7 @@ var TemporalHelpers = { * Return the canonical era code. */ canonicalizeCalendarEra(calendarId, eraName) { - assert.sameValue(typeof calendarId, "string"); + assert.sameValue(typeof calendarId, "string", "calendar must be string in canonicalizeCalendarEra"); if (calendarId === "iso8601") { assert.sameValue(eraName, undefined); @@ -138,7 +138,7 @@ var TemporalHelpers = { if (eraName === undefined) { return undefined; } - assert.sameValue(typeof eraName, "string"); + assert.sameValue(typeof eraName, "string", "eraName must be string or undefined in canonicalizeCalendarEra"); for (let {era, aliases = []} of TemporalHelpers.CalendarEras[calendarId]) { if (era === eraName || aliases.includes(eraName)) { diff --git a/test/staging/Intl402/Temporal/old/japanese-era.js b/test/staging/Intl402/Temporal/old/japanese-era.js index 60155fd77d..9dd26a9d0f 100644 --- a/test/staging/Intl402/Temporal/old/japanese-era.js +++ b/test/staging/Intl402/Temporal/old/japanese-era.js @@ -69,8 +69,8 @@ date = Temporal.PlainDate.from({ }); assert.sameValue(`${date}`, "1000-01-01[u-ca=japanese]"); assert.sameValue( - TemporalHelpers.canonicalizeEraInCalendar(date, date.era), - TemporalHelpers.canonicalizeEraInCalendar(date, "ce"), + TemporalHelpers.canonicalizeCalendarEra(date.calendarId, date.era), + TemporalHelpers.canonicalizeCalendarEra(date.calendarId, "ce"), ); assert.sameValue(date.eraYear, 1000); @@ -83,7 +83,7 @@ date = Temporal.PlainDate.from({ }); assert.sameValue(`${date}`, "0000-01-01[u-ca=japanese]"); assert.sameValue( - TemporalHelpers.canonicalizeEraInCalendar(date, date.era), - TemporalHelpers.canonicalizeEraInCalendar(date, "bce"), + TemporalHelpers.canonicalizeCalendarEra(date.calendarId, date.era), + TemporalHelpers.canonicalizeCalendarEra(date.calendarId, "bce"), ); assert.sameValue(date.eraYear, 1); From 3a615a0c0e21ece3739b9b570723672a33ef02c9 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 29 Jul 2024 20:28:59 +0200 Subject: [PATCH 38/90] Adds property descriptor tests for explicit resource management objects These are all the prop-desc.js tests from @rbuckton's PR #3866 to make reviewing easier. --- .../AsyncDisposableStack/prop-desc.js | 22 ++++++++++++++++ .../prototype/adopt/prop-desc.js | 24 +++++++++++++++++ .../prototype/defer/prop-desc.js | 24 +++++++++++++++++ .../prototype/disposeAsync/prop-desc.js | 24 +++++++++++++++++ .../prototype/move/prop-desc.js | 24 +++++++++++++++++ .../prototype/prop-desc.js | 18 +++++++++++++ .../prototype/use/prop-desc.js | 24 +++++++++++++++++ .../Symbol.asyncDispose/prop-desc.js | 23 ++++++++++++++++ test/built-ins/DisposableStack/prop-desc.js | 22 ++++++++++++++++ .../prototype/adopt/prop-desc.js | 24 +++++++++++++++++ .../prototype/defer/prop-desc.js | 24 +++++++++++++++++ .../prototype/dispose/prop-desc.js | 24 +++++++++++++++++ .../prototype/move/prop-desc.js | 24 +++++++++++++++++ .../DisposableStack/prototype/prop-desc.js | 18 +++++++++++++ .../prototype/use/prop-desc.js | 24 +++++++++++++++++ .../prototype/Symbol.dispose/prop-desc.js | 23 ++++++++++++++++ .../NativeErrors/SuppressedError/prop-desc.js | 26 +++++++++++++++++++ .../SuppressedError/prototype/prop-desc.js | 24 +++++++++++++++++ .../Symbol/asyncDispose/prop-desc.js | 17 ++++++++++++ test/built-ins/Symbol/dispose/prop-desc.js | 17 ++++++++++++ 20 files changed, 450 insertions(+) create mode 100644 test/built-ins/AsyncDisposableStack/prop-desc.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/adopt/prop-desc.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/defer/prop-desc.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/disposeAsync/prop-desc.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/move/prop-desc.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/prop-desc.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/use/prop-desc.js create mode 100644 test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/prop-desc.js create mode 100644 test/built-ins/DisposableStack/prop-desc.js create mode 100644 test/built-ins/DisposableStack/prototype/adopt/prop-desc.js create mode 100644 test/built-ins/DisposableStack/prototype/defer/prop-desc.js create mode 100644 test/built-ins/DisposableStack/prototype/dispose/prop-desc.js create mode 100644 test/built-ins/DisposableStack/prototype/move/prop-desc.js create mode 100644 test/built-ins/DisposableStack/prototype/prop-desc.js create mode 100644 test/built-ins/DisposableStack/prototype/use/prop-desc.js create mode 100644 test/built-ins/Iterator/prototype/Symbol.dispose/prop-desc.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/prop-desc.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/prototype/prop-desc.js create mode 100644 test/built-ins/Symbol/asyncDispose/prop-desc.js create mode 100644 test/built-ins/Symbol/dispose/prop-desc.js diff --git a/test/built-ins/AsyncDisposableStack/prop-desc.js b/test/built-ins/AsyncDisposableStack/prop-desc.js new file mode 100644 index 0000000000..bcea356ffd --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prop-desc.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack-constructor +description: > + Property descriptor of AsyncDisposableStack +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(this, 'AsyncDisposableStack', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/adopt/prop-desc.js b/test/built-ins/AsyncDisposableStack/prototype/adopt/prop-desc.js new file mode 100644 index 0000000000..1149943413 --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/adopt/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.adopt +description: > + Property descriptor of AsyncDisposableStack.prototype.adopt +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof AsyncDisposableStack.prototype.adopt, 'function'); + +verifyProperty(AsyncDisposableStack.prototype, 'adopt', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/defer/prop-desc.js b/test/built-ins/AsyncDisposableStack/prototype/defer/prop-desc.js new file mode 100644 index 0000000000..4669bb66fd --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/defer/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.defer +description: > + Property descriptor of AsyncDisposableStack.prototype.defer +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof AsyncDisposableStack.prototype.defer, 'function'); + +verifyProperty(AsyncDisposableStack.prototype, 'defer', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/prop-desc.js b/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/prop-desc.js new file mode 100644 index 0000000000..dbdc2af42d --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.disposeAsync +description: > + Property descriptor of AsyncDisposableStack.prototype.disposeAsync +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof AsyncDisposableStack.prototype.disposeAsync, 'function'); + +verifyProperty(AsyncDisposableStack.prototype, 'disposeAsync', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/move/prop-desc.js b/test/built-ins/AsyncDisposableStack/prototype/move/prop-desc.js new file mode 100644 index 0000000000..1b84f1bb5f --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/move/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.move +description: > + Property descriptor of AsyncDisposableStack.prototype.move +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof AsyncDisposableStack.prototype.move, 'function'); + +verifyProperty(AsyncDisposableStack.prototype, 'move', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/prop-desc.js b/test/built-ins/AsyncDisposableStack/prototype/prop-desc.js new file mode 100644 index 0000000000..e4f4a212cc --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/prop-desc.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: The property descriptor AsyncDisposableStack.prototype +esid: sec-properties-of-the-asyncdisposablestack-constructor +info: | + This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: false }. +features: [explicit-resource-management] +includes: [propertyHelper.js] +---*/ + +verifyProperty(AsyncDisposableStack, 'prototype', { + writable: false, + enumerable: false, + configurable: false +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/use/prop-desc.js b/test/built-ins/AsyncDisposableStack/prototype/use/prop-desc.js new file mode 100644 index 0000000000..7613715c5f --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/use/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.use +description: > + Property descriptor of AsyncDisposableStack.prototype.use +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof AsyncDisposableStack.prototype.use, 'function'); + +verifyProperty(AsyncDisposableStack.prototype, 'use', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/prop-desc.js b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/prop-desc.js new file mode 100644 index 0000000000..3523d8d851 --- /dev/null +++ b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/prop-desc.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%asynciteratorprototype%-@@asyncDispose +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. +features: [explicit-resource-management] +includes: [propertyHelper.js] +---*/ + +async function* generator() {} +const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(generator.prototype)) + +verifyProperty(AsyncIteratorPrototype, Symbol.asyncDispose, { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/DisposableStack/prop-desc.js b/test/built-ins/DisposableStack/prop-desc.js new file mode 100644 index 0000000000..ec66e902c9 --- /dev/null +++ b/test/built-ins/DisposableStack/prop-desc.js @@ -0,0 +1,22 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack-constructor +description: > + Property descriptor of DisposableStack +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(this, 'DisposableStack', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/adopt/prop-desc.js b/test/built-ins/DisposableStack/prototype/adopt/prop-desc.js new file mode 100644 index 0000000000..5fdd90d000 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/adopt/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.adopt +description: > + Property descriptor of DisposableStack.prototype.adopt +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof DisposableStack.prototype.adopt, 'function'); + +verifyProperty(DisposableStack.prototype, 'adopt', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/defer/prop-desc.js b/test/built-ins/DisposableStack/prototype/defer/prop-desc.js new file mode 100644 index 0000000000..ae9b9f38c2 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/defer/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.defer +description: > + Property descriptor of DisposableStack.prototype.defer +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof DisposableStack.prototype.defer, 'function'); + +verifyProperty(DisposableStack.prototype, 'defer', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/dispose/prop-desc.js b/test/built-ins/DisposableStack/prototype/dispose/prop-desc.js new file mode 100644 index 0000000000..200ad059f0 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/dispose/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.dispose +description: > + Property descriptor of DisposableStack.prototype.dispose +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof DisposableStack.prototype.dispose, 'function'); + +verifyProperty(DisposableStack.prototype, 'dispose', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/move/prop-desc.js b/test/built-ins/DisposableStack/prototype/move/prop-desc.js new file mode 100644 index 0000000000..b6088e6ddc --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/move/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.move +description: > + Property descriptor of DisposableStack.prototype.move +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof DisposableStack.prototype.move, 'function'); + +verifyProperty(DisposableStack.prototype, 'move', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/prop-desc.js b/test/built-ins/DisposableStack/prototype/prop-desc.js new file mode 100644 index 0000000000..12858c2225 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/prop-desc.js @@ -0,0 +1,18 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: The property descriptor DisposableStack.prototype +esid: sec-properties-of-the-disposablestack-constructor +info: | + This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: false }. +features: [explicit-resource-management] +includes: [propertyHelper.js] +---*/ + +verifyProperty(DisposableStack, 'prototype', { + writable: false, + enumerable: false, + configurable: false +}); diff --git a/test/built-ins/DisposableStack/prototype/use/prop-desc.js b/test/built-ins/DisposableStack/prototype/use/prop-desc.js new file mode 100644 index 0000000000..cf5c3a2592 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/use/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.use +description: > + Property descriptor of DisposableStack.prototype.use +info: | + 17 ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof DisposableStack.prototype.use, 'function'); + +verifyProperty(DisposableStack.prototype, 'use', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/Iterator/prototype/Symbol.dispose/prop-desc.js b/test/built-ins/Iterator/prototype/Symbol.dispose/prop-desc.js new file mode 100644 index 0000000000..1926548eb8 --- /dev/null +++ b/test/built-ins/Iterator/prototype/Symbol.dispose/prop-desc.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%iteratorprototype%-@@dispose +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. +features: [explicit-resource-management] +includes: [propertyHelper.js] +---*/ +const IteratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf([][Symbol.iterator]()) +); + +verifyProperty(IteratorPrototype, Symbol.dispose, { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/NativeErrors/SuppressedError/prop-desc.js b/test/built-ins/NativeErrors/SuppressedError/prop-desc.js new file mode 100644 index 0000000000..17d880f29e --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/prop-desc.js @@ -0,0 +1,26 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-suppressederror-objects +description: > + Property descriptor of SuppressedError +info: | + SuppressedError Objects + + ECMAScript Standard Built-in Objects: + + 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. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof SuppressedError, 'function'); + +verifyProperty(this, 'SuppressedError', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/NativeErrors/SuppressedError/prototype/prop-desc.js b/test/built-ins/NativeErrors/SuppressedError/prototype/prop-desc.js new file mode 100644 index 0000000000..178f226c32 --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/prototype/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-aggregate-error.prototype +description: > + Property descriptor of SuppressedError.prototype +info: | + SuppressedError.prototype + + The initial value of SuppressedError.prototype is the intrinsic object %AggregateErrorPrototype%. + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof SuppressedError.prototype, 'object'); + +verifyProperty(SuppressedError, 'prototype', { + enumerable: false, + writable: false, + configurable: false +}); diff --git a/test/built-ins/Symbol/asyncDispose/prop-desc.js b/test/built-ins/Symbol/asyncDispose/prop-desc.js new file mode 100644 index 0000000000..8445223679 --- /dev/null +++ b/test/built-ins/Symbol/asyncDispose/prop-desc.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: > + `Symbol.asyncDispose` property descriptor +info: | + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof Symbol.asyncDispose, 'symbol'); +verifyNotEnumerable(Symbol, 'asyncDispose'); +verifyNotWritable(Symbol, 'asyncDispose'); +verifyNotConfigurable(Symbol, 'asyncDispose'); diff --git a/test/built-ins/Symbol/dispose/prop-desc.js b/test/built-ins/Symbol/dispose/prop-desc.js new file mode 100644 index 0000000000..3a23a7a02f --- /dev/null +++ b/test/built-ins/Symbol/dispose/prop-desc.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: > + `Symbol.dispose` property descriptor +info: | + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +assert.sameValue(typeof Symbol.dispose, 'symbol'); +verifyNotEnumerable(Symbol, 'dispose'); +verifyNotWritable(Symbol, 'dispose'); +verifyNotConfigurable(Symbol, 'dispose'); From 8996664a422f406c529708c36f6b4b92d96a51bb Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Fri, 26 Jul 2024 17:36:41 +0200 Subject: [PATCH 39/90] Added expected esid's --- test/built-ins/Symbol/asyncDispose/prop-desc.js | 2 +- test/built-ins/Symbol/dispose/prop-desc.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/built-ins/Symbol/asyncDispose/prop-desc.js b/test/built-ins/Symbol/asyncDispose/prop-desc.js index 8445223679..87a14cd0d2 100644 --- a/test/built-ins/Symbol/asyncDispose/prop-desc.js +++ b/test/built-ins/Symbol/asyncDispose/prop-desc.js @@ -1,7 +1,7 @@ // Copyright (C) 2015 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -esid: pending +esid: sec-symbol.asyncdispose description: > `Symbol.asyncDispose` property descriptor info: | diff --git a/test/built-ins/Symbol/dispose/prop-desc.js b/test/built-ins/Symbol/dispose/prop-desc.js index 3a23a7a02f..ed1002a624 100644 --- a/test/built-ins/Symbol/dispose/prop-desc.js +++ b/test/built-ins/Symbol/dispose/prop-desc.js @@ -1,7 +1,7 @@ // Copyright (C) 2015 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -esid: pending +esid: sec-symbol.dispose description: > `Symbol.dispose` property descriptor info: | From 59657217f132959569df4df36907ffcd970063f2 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 29 Jul 2024 20:55:53 +0200 Subject: [PATCH 40/90] Adds .name property descriptor tests for explicit resource management These are all the name.js tests from @rbuckton's PR #3866 to make reviewing easier. --- test/built-ins/AsyncDisposableStack/name.js | 31 +++++++++++++++++ .../prototype/adopt/name.js | 31 +++++++++++++++++ .../prototype/defer/name.js | 31 +++++++++++++++++ .../prototype/disposeAsync/name.js | 31 +++++++++++++++++ .../prototype/disposed/name.js | 28 ++++++++++++++++ .../prototype/move/name.js | 31 +++++++++++++++++ .../prototype/use/name.js | 31 +++++++++++++++++ .../Symbol.asyncDispose/name.js | 33 +++++++++++++++++++ test/built-ins/DisposableStack/name.js | 31 +++++++++++++++++ .../DisposableStack/prototype/adopt/name.js | 31 +++++++++++++++++ .../DisposableStack/prototype/defer/name.js | 31 +++++++++++++++++ .../DisposableStack/prototype/dispose/name.js | 31 +++++++++++++++++ .../prototype/disposed/name.js | 28 ++++++++++++++++ .../DisposableStack/prototype/move/name.js | 31 +++++++++++++++++ .../DisposableStack/prototype/use/name.js | 31 +++++++++++++++++ .../Iterator/prototype/Symbol.dispose/name.js | 33 +++++++++++++++++++ .../NativeErrors/SuppressedError/name.js | 33 +++++++++++++++++++ .../SuppressedError/prototype/name.js | 24 ++++++++++++++ 18 files changed, 551 insertions(+) create mode 100644 test/built-ins/AsyncDisposableStack/name.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/adopt/name.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/defer/name.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/disposeAsync/name.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/disposed/name.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/move/name.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/use/name.js create mode 100644 test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/name.js create mode 100644 test/built-ins/DisposableStack/name.js create mode 100644 test/built-ins/DisposableStack/prototype/adopt/name.js create mode 100644 test/built-ins/DisposableStack/prototype/defer/name.js create mode 100644 test/built-ins/DisposableStack/prototype/dispose/name.js create mode 100644 test/built-ins/DisposableStack/prototype/disposed/name.js create mode 100644 test/built-ins/DisposableStack/prototype/move/name.js create mode 100644 test/built-ins/DisposableStack/prototype/use/name.js create mode 100644 test/built-ins/Iterator/prototype/Symbol.dispose/name.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/name.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/prototype/name.js diff --git a/test/built-ins/AsyncDisposableStack/name.js b/test/built-ins/AsyncDisposableStack/name.js new file mode 100644 index 0000000000..521b3b1f5f --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack +description: AsyncDisposableStack.name property descriptor +info: | + AsyncDisposableStack ( ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack, 'name', { + value: 'AsyncDisposableStack', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/adopt/name.js b/test/built-ins/AsyncDisposableStack/prototype/adopt/name.js new file mode 100644 index 0000000000..4d1be41006 --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/adopt/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.adopt +description: AsyncDisposableStack.prototype.adopt.name property descriptor +info: | + AsyncDisposableStack.prototype.adopt.name value and property descriptor + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack.prototype.adopt, 'name', { + value: 'adopt', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/defer/name.js b/test/built-ins/AsyncDisposableStack/prototype/defer/name.js new file mode 100644 index 0000000000..a060306579 --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/defer/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.defer +description: AsyncDisposableStack.prototype.defer.name property descriptor +info: | + AsyncDisposableStack.prototype.defer.name value and property descriptor + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack.prototype.defer, 'name', { + value: 'defer', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/name.js b/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/name.js new file mode 100644 index 0000000000..87351ecdf3 --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.disposeAsync +description: AsyncDisposableStack.prototype.disposeAsync.name property descriptor +info: | + AsyncDisposableStack.prototype.disposeAsync.name value and property descriptor + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack.prototype.disposeAsync, 'name', { + value: 'disposeAsync', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/disposed/name.js b/test/built-ins/AsyncDisposableStack/prototype/disposed/name.js new file mode 100644 index 0000000000..71866de702 --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/disposed/name.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-get-asyncdisposablestack.prototype.disposed +description: > + AsyncDisposableStack.prototype.disposed.name value and descriptor. +info: | + get AsyncDisposableStack.prototype.size + + 17 ECMAScript Standard Built-in Objects + + Functions that are specified as get or set accessor functions of built-in + properties have "get " or "set " prepended to the property name string. + +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +var descriptor = Object.getOwnPropertyDescriptor(AsyncDisposableStack.prototype, 'disposed'); + +assert.sameValue(descriptor.get.name, + 'get disposed', + 'The value of `descriptor.get.name` is `get disposed`' +); + +verifyNotEnumerable(descriptor.get, 'name'); +verifyNotWritable(descriptor.get, 'name'); +verifyConfigurable(descriptor.get, 'name'); diff --git a/test/built-ins/AsyncDisposableStack/prototype/move/name.js b/test/built-ins/AsyncDisposableStack/prototype/move/name.js new file mode 100644 index 0000000000..4b0759da4e --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/move/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.move +description: AsyncDisposableStack.prototype.move.name property descriptor +info: | + AsyncDisposableStack.prototype.move.name value and property descriptor + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack.prototype.move, 'name', { + value: 'move', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/use/name.js b/test/built-ins/AsyncDisposableStack/prototype/use/name.js new file mode 100644 index 0000000000..ff27a8cde0 --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/use/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.use +description: AsyncDisposableStack.prototype.use.name property descriptor +info: | + AsyncDisposableStack.prototype.use.name value and property descriptor + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack.prototype.use, 'name', { + value: 'use', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/name.js b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/name.js new file mode 100644 index 0000000000..5ea13ac63f --- /dev/null +++ b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/name.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%asynciteratorprototype%-@@asyncDispose +description: Descriptor for `name` property +info: | + The value of the name property of this function is "[Symbol.asyncDispose]". + + ES6 Section 17: ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + [...] + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [explicit-resource-management] +includes: [propertyHelper.js] +---*/ + +async function* generator() {} +const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(generator.prototype)) + +verifyProperty(AsyncIteratorPrototype[Symbol.asyncDispose], 'name', { + value: '[Symbol.asyncDispose]', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/DisposableStack/name.js b/test/built-ins/DisposableStack/name.js new file mode 100644 index 0000000000..075b2d51ee --- /dev/null +++ b/test/built-ins/DisposableStack/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack +description: DisposableStack.name property descriptor +info: | + DisposableStack ( ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack, 'name', { + value: 'DisposableStack', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/adopt/name.js b/test/built-ins/DisposableStack/prototype/adopt/name.js new file mode 100644 index 0000000000..e81a624860 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/adopt/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.adopt +description: DisposableStack.prototype.adopt.name property descriptor +info: | + DisposableStack.prototype.adopt.name value and property descriptor + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack.prototype.adopt, 'name', { + value: 'adopt', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/defer/name.js b/test/built-ins/DisposableStack/prototype/defer/name.js new file mode 100644 index 0000000000..808c66793d --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/defer/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.defer +description: DisposableStack.prototype.defer.name property descriptor +info: | + DisposableStack.prototype.defer.name value and property descriptor + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack.prototype.defer, 'name', { + value: 'defer', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/dispose/name.js b/test/built-ins/DisposableStack/prototype/dispose/name.js new file mode 100644 index 0000000000..cac48a362b --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/dispose/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.dispose +description: DisposableStack.prototype.dispose.name property descriptor +info: | + DisposableStack.prototype.dispose.name value and property descriptor + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack.prototype.dispose, 'name', { + value: 'dispose', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/disposed/name.js b/test/built-ins/DisposableStack/prototype/disposed/name.js new file mode 100644 index 0000000000..c20b505705 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/disposed/name.js @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-get-disposablestack.prototype.disposed +description: > + DisposableStack.prototype.disposed.name value and descriptor. +info: | + get DisposableStack.prototype.size + + 17 ECMAScript Standard Built-in Objects + + Functions that are specified as get or set accessor functions of built-in + properties have "get " or "set " prepended to the property name string. + +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +var descriptor = Object.getOwnPropertyDescriptor(DisposableStack.prototype, 'disposed'); + +assert.sameValue(descriptor.get.name, + 'get disposed', + 'The value of `descriptor.get.name` is `get disposed`' +); + +verifyNotEnumerable(descriptor.get, 'name'); +verifyNotWritable(descriptor.get, 'name'); +verifyConfigurable(descriptor.get, 'name'); diff --git a/test/built-ins/DisposableStack/prototype/move/name.js b/test/built-ins/DisposableStack/prototype/move/name.js new file mode 100644 index 0000000000..a3b9844e04 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/move/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.move +description: DisposableStack.prototype.move.name property descriptor +info: | + DisposableStack.prototype.move.name value and property descriptor + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack.prototype.move, 'name', { + value: 'move', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/use/name.js b/test/built-ins/DisposableStack/prototype/use/name.js new file mode 100644 index 0000000000..d2b8327197 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/use/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.use +description: DisposableStack.prototype.use.name property descriptor +info: | + DisposableStack.prototype.use.name value and property descriptor + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack.prototype.use, 'name', { + value: 'use', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/Iterator/prototype/Symbol.dispose/name.js b/test/built-ins/Iterator/prototype/Symbol.dispose/name.js new file mode 100644 index 0000000000..a6d17ef8ee --- /dev/null +++ b/test/built-ins/Iterator/prototype/Symbol.dispose/name.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%iteratorprototype%-@@dispose +description: Descriptor for `name` property +info: | + The value of the name property of this function is "[Symbol.dispose]". + + ES6 Section 17: ECMAScript Standard Built-in Objects + + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value is a + String. Unless otherwise specified, this value is the name that is given to + the function in this specification. + + [...] + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +features: [explicit-resource-management] +includes: [propertyHelper.js] +---*/ +const IteratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf([][Symbol.iterator]()) +); + +verifyProperty(IteratorPrototype[Symbol.dispose], 'name', { + value: '[Symbol.dispose]', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/NativeErrors/SuppressedError/name.js b/test/built-ins/NativeErrors/SuppressedError/name.js new file mode 100644 index 0000000000..7af84ad00a --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/name.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-properties-of-the-suppressederror-constructor +description: SuppressedError.name property descriptor +info: | + Properties of the SuppressedError Constructor + + - has a name property whose value is the String value "SuppressedError". + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. Unless otherwise specified, this value is the name that + is given to the function in this specification. For functions that + are specified as properties of objects, the name value is the + property name string used to access the function. [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(SuppressedError, 'name', { + value: 'SuppressedError', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/NativeErrors/SuppressedError/prototype/name.js b/test/built-ins/NativeErrors/SuppressedError/prototype/name.js new file mode 100644 index 0000000000..ec90505f2a --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/prototype/name.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-aggregate-error.prototype.name +description: > + The `SuppressedError.prototype.name` property descriptor. +info: | + The initial value of SuppressedError.prototype.name is "SuppressedError". + + 17 ECMAScript Standard Built-in Objects: + + Every other data property described (...) has the attributes { [[Writable]]: true, + [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(SuppressedError.prototype, 'name', { + value: 'SuppressedError', + enumerable: false, + writable: true, + configurable: true +}); From c916d81d852a17b5a0b531d42f99672f85c11c0f Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 29 Jul 2024 21:02:03 +0200 Subject: [PATCH 41/90] Adds .length property descriptor tests for explicit resource management These are all the length.js tests from @rbuckton's PR #3866 to make reviewing easier. --- test/built-ins/AsyncDisposableStack/length.js | 32 +++++++++++++++++++ .../prototype/adopt/length.js | 32 +++++++++++++++++++ .../prototype/defer/length.js | 32 +++++++++++++++++++ .../prototype/disposeAsync/length.js | 32 +++++++++++++++++++ .../prototype/disposed/length.js | 23 +++++++++++++ .../prototype/move/length.js | 32 +++++++++++++++++++ .../prototype/use/length.js | 32 +++++++++++++++++++ .../Symbol.asyncDispose/length.js | 30 +++++++++++++++++ test/built-ins/DisposableStack/length.js | 32 +++++++++++++++++++ .../DisposableStack/prototype/adopt/length.js | 32 +++++++++++++++++++ .../DisposableStack/prototype/defer/length.js | 32 +++++++++++++++++++ .../prototype/dispose/length.js | 32 +++++++++++++++++++ .../prototype/disposed/length.js | 23 +++++++++++++ .../DisposableStack/prototype/move/length.js | 32 +++++++++++++++++++ .../DisposableStack/prototype/use/length.js | 32 +++++++++++++++++++ .../prototype/Symbol.dispose/length.js | 30 +++++++++++++++++ .../NativeErrors/SuppressedError/length.js | 32 +++++++++++++++++++ 17 files changed, 522 insertions(+) create mode 100644 test/built-ins/AsyncDisposableStack/length.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/adopt/length.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/defer/length.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/disposeAsync/length.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/disposed/length.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/move/length.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/use/length.js create mode 100644 test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/length.js create mode 100644 test/built-ins/DisposableStack/length.js create mode 100644 test/built-ins/DisposableStack/prototype/adopt/length.js create mode 100644 test/built-ins/DisposableStack/prototype/defer/length.js create mode 100644 test/built-ins/DisposableStack/prototype/dispose/length.js create mode 100644 test/built-ins/DisposableStack/prototype/disposed/length.js create mode 100644 test/built-ins/DisposableStack/prototype/move/length.js create mode 100644 test/built-ins/DisposableStack/prototype/use/length.js create mode 100644 test/built-ins/Iterator/prototype/Symbol.dispose/length.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/length.js diff --git a/test/built-ins/AsyncDisposableStack/length.js b/test/built-ins/AsyncDisposableStack/length.js new file mode 100644 index 0000000000..f90ee3ea3d --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack +description: AsyncDisposableStack.length property descriptor +info: | + AsyncDisposableStack ( ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack, 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/adopt/length.js b/test/built-ins/AsyncDisposableStack/prototype/adopt/length.js new file mode 100644 index 0000000000..34a25af15a --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/adopt/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.adopt +description: AsyncDisposableStack.prototype.adopt.length property descriptor +info: | + AsyncDisposableStack.prototype.adopt ( value, onDisposeAsync ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack.prototype.adopt, 'length', { + value: 2, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/defer/length.js b/test/built-ins/AsyncDisposableStack/prototype/defer/length.js new file mode 100644 index 0000000000..96a62e3bc8 --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/defer/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.defer +description: AsyncDisposableStack.prototype.defer.length property descriptor +info: | + AsyncDisposableStack.prototype.defer ( ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack.prototype.defer, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/length.js b/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/length.js new file mode 100644 index 0000000000..2dc5102e26 --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.disposeAsync +description: AsyncDisposableStack.prototype.disposeAsync.length property descriptor +info: | + AsyncDisposableStack.prototype.disposeAsync ( ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack.prototype.disposeAsync, 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js b/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js new file mode 100644 index 0000000000..3f30906c3c --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-get-asyncdisposablestack.prototype.disposed +description: > + Map.prototype.size.length value and descriptor. +info: | + get Map.prototype.size + + 17 ECMAScript Standard Built-in Objects +includes: [propertyHelper.js] +---*/ + +var descriptor = Object.getOwnPropertyDescriptor(Map.prototype, 'size'); + +assert.sameValue( + descriptor.get.length, 0, + 'The value of `Map.prototype.size.length` is `0`' +); + +verifyNotEnumerable(descriptor.get, 'length'); +verifyNotWritable(descriptor.get, 'length'); +verifyConfigurable(descriptor.get, 'length'); diff --git a/test/built-ins/AsyncDisposableStack/prototype/move/length.js b/test/built-ins/AsyncDisposableStack/prototype/move/length.js new file mode 100644 index 0000000000..f6919ea1f3 --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/move/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.move +description: AsyncDisposableStack.prototype.move.length property descriptor +info: | + AsyncDisposableStack.prototype.move ( ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack.prototype.move, 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncDisposableStack/prototype/use/length.js b/test/built-ins/AsyncDisposableStack/prototype/use/length.js new file mode 100644 index 0000000000..5634b9d349 --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/use/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.use +description: AsyncDisposableStack.prototype.use.length property descriptor +info: | + AsyncDisposableStack.prototype.use ( value ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(AsyncDisposableStack.prototype.use, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/length.js b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/length.js new file mode 100644 index 0000000000..a9c34d30ed --- /dev/null +++ b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/length.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%asynciteratorprototype%-@@asyncDispose +description: Length of %AsyncIteratorPrototype%[ @@asyncDispose ] +info: | + ES6 Section 17: + Every built-in Function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this value + is equal to the largest number of named arguments shown in the subclause + headings for the function description, including optional parameters. + + [...] + + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +features: [explicit-resource-management] +includes: [propertyHelper.js] +---*/ + +async function* generator() {} +const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(generator.prototype)) + +verifyProperty(AsyncIteratorPrototype[Symbol.asyncDispose], 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/DisposableStack/length.js b/test/built-ins/DisposableStack/length.js new file mode 100644 index 0000000000..7d0def4fb1 --- /dev/null +++ b/test/built-ins/DisposableStack/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack +description: DisposableStack.length property descriptor +info: | + DisposableStack ( ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack, 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/adopt/length.js b/test/built-ins/DisposableStack/prototype/adopt/length.js new file mode 100644 index 0000000000..f2dd3c63ec --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/adopt/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.adopt +description: DisposableStack.prototype.adopt.length property descriptor +info: | + DisposableStack.prototype.adopt ( ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack.prototype.adopt, 'length', { + value: 2, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/defer/length.js b/test/built-ins/DisposableStack/prototype/defer/length.js new file mode 100644 index 0000000000..6b3e90e774 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/defer/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.defer +description: DisposableStack.prototype.defer.length property descriptor +info: | + DisposableStack.prototype.defer ( ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack.prototype.defer, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/dispose/length.js b/test/built-ins/DisposableStack/prototype/dispose/length.js new file mode 100644 index 0000000000..326223f36f --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/dispose/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.dispose +description: DisposableStack.prototype.dispose.length property descriptor +info: | + DisposableStack.prototype.dispose ( ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack.prototype.dispose, 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/disposed/length.js b/test/built-ins/DisposableStack/prototype/disposed/length.js new file mode 100644 index 0000000000..3e1d77f3df --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/disposed/length.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-get-disposablestack.prototype.disposed +description: > + Map.prototype.size.length value and descriptor. +info: | + get Map.prototype.size + + 17 ECMAScript Standard Built-in Objects +includes: [propertyHelper.js] +---*/ + +var descriptor = Object.getOwnPropertyDescriptor(Map.prototype, 'size'); + +assert.sameValue( + descriptor.get.length, 0, + 'The value of `Map.prototype.size.length` is `0`' +); + +verifyNotEnumerable(descriptor.get, 'length'); +verifyNotWritable(descriptor.get, 'length'); +verifyConfigurable(descriptor.get, 'length'); diff --git a/test/built-ins/DisposableStack/prototype/move/length.js b/test/built-ins/DisposableStack/prototype/move/length.js new file mode 100644 index 0000000000..7091a70b6e --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/move/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.move +description: DisposableStack.prototype.move.length property descriptor +info: | + DisposableStack.prototype.move ( ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack.prototype.move, 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/use/length.js b/test/built-ins/DisposableStack/prototype/use/length.js new file mode 100644 index 0000000000..969531f743 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/use/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.use +description: DisposableStack.prototype.use.length property descriptor +info: | + DisposableStack.prototype.use ( value ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(DisposableStack.prototype.use, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/Iterator/prototype/Symbol.dispose/length.js b/test/built-ins/Iterator/prototype/Symbol.dispose/length.js new file mode 100644 index 0000000000..4a31d3b38e --- /dev/null +++ b/test/built-ins/Iterator/prototype/Symbol.dispose/length.js @@ -0,0 +1,30 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-%iteratorprototype%-@@dispose +description: Length of %IteratorPrototype%[ @@dispose ] +info: | + ES6 Section 17: + Every built-in Function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this value + is equal to the largest number of named arguments shown in the subclause + headings for the function description, including optional parameters. + + [...] + + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +features: [explicit-resource-management] +includes: [propertyHelper.js] +---*/ +const IteratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf([][Symbol.iterator]()) +); + +verifyProperty(IteratorPrototype[Symbol.dispose], 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/NativeErrors/SuppressedError/length.js b/test/built-ins/NativeErrors/SuppressedError/length.js new file mode 100644 index 0000000000..6e8fc344be --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-properties-of-the-suppressederror-constructors +description: SuppressedError.length property descriptor +info: | + SuppressedError ( error, suppressed, message ) + + 17 ECMAScript Standard Built-in Objects + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in + function object has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [explicit-resource-management] +---*/ + +verifyProperty(SuppressedError, 'length', { + value: 3, + writable: false, + enumerable: false, + configurable: true +}); From cb8324fdbaebabab8f78279fa8df071c70fe5027 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 29 Jul 2024 21:02:38 +0200 Subject: [PATCH 42/90] Adds [is/not]-a-constructor.js tests from @rbuckton's PR #3866 to make reviewing easier. --- .../AsyncDisposableStack/is-a-constructor.js | 23 +++++++++++++ .../prototype/adopt/not-a-constructor.js | 32 +++++++++++++++++++ .../prototype/defer/not-a-constructor.js | 32 +++++++++++++++++++ .../disposeAsync/not-a-constructor.js | 32 +++++++++++++++++++ .../prototype/move/not-a-constructor.js | 32 +++++++++++++++++++ .../prototype/use/not-a-constructor.js | 32 +++++++++++++++++++ .../DisposableStack/is-a-constructor.js | 23 +++++++++++++ .../prototype/adopt/not-a-constructor.js | 32 +++++++++++++++++++ .../prototype/defer/not-a-constructor.js | 32 +++++++++++++++++++ .../prototype/dispose/not-a-constructor.js | 32 +++++++++++++++++++ .../prototype/move/not-a-constructor.js | 32 +++++++++++++++++++ .../prototype/use/not-a-constructor.js | 32 +++++++++++++++++++ .../SuppressedError/is-a-constructor.js | 24 ++++++++++++++ 13 files changed, 390 insertions(+) create mode 100644 test/built-ins/AsyncDisposableStack/is-a-constructor.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/adopt/not-a-constructor.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/defer/not-a-constructor.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/disposeAsync/not-a-constructor.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/move/not-a-constructor.js create mode 100644 test/built-ins/AsyncDisposableStack/prototype/use/not-a-constructor.js create mode 100644 test/built-ins/DisposableStack/is-a-constructor.js create mode 100644 test/built-ins/DisposableStack/prototype/adopt/not-a-constructor.js create mode 100644 test/built-ins/DisposableStack/prototype/defer/not-a-constructor.js create mode 100644 test/built-ins/DisposableStack/prototype/dispose/not-a-constructor.js create mode 100644 test/built-ins/DisposableStack/prototype/move/not-a-constructor.js create mode 100644 test/built-ins/DisposableStack/prototype/use/not-a-constructor.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/is-a-constructor.js diff --git a/test/built-ins/AsyncDisposableStack/is-a-constructor.js b/test/built-ins/AsyncDisposableStack/is-a-constructor.js new file mode 100644 index 0000000000..7c34ccfd7a --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/is-a-constructor.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: > + The AsyncDisposableStack constructor implements [[Construct]] +info: | + IsConstructor ( argument ) + + The abstract operation IsConstructor takes argument argument (an ECMAScript language value). + It determines if argument is a function object with a [[Construct]] internal method. + It performs the following steps when called: + + If Type(argument) is not Object, return false. + If argument has a [[Construct]] internal method, return true. + Return false. +includes: [isConstructor.js] +features: [explicit-resource-management, Reflect.construct] +---*/ + +assert.sameValue(isConstructor(AsyncDisposableStack), true, 'isConstructor(AsyncDisposableStack) must return true'); +new AsyncDisposableStack(); diff --git a/test/built-ins/AsyncDisposableStack/prototype/adopt/not-a-constructor.js b/test/built-ins/AsyncDisposableStack/prototype/adopt/not-a-constructor.js new file mode 100644 index 0000000000..4624f8651a --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/adopt/not-a-constructor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.adopt +description: > + AsyncDisposableStack.prototype.adopt does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, explicit-resource-management, arrow-function] +---*/ + +assert.sameValue( + isConstructor(AsyncDisposableStack.prototype.adopt), + false, + 'isConstructor(AsyncDisposableStack.prototype.adopt) must return false' +); + +assert.throws(TypeError, () => { + let stack = new AsyncDisposableStack({}); new stack.adopt(); +}, '`let stack = new AsyncDisposableStack({}); new stack.adopt()` throws TypeError'); diff --git a/test/built-ins/AsyncDisposableStack/prototype/defer/not-a-constructor.js b/test/built-ins/AsyncDisposableStack/prototype/defer/not-a-constructor.js new file mode 100644 index 0000000000..e1f2c8539e --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/defer/not-a-constructor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.defer +description: > + AsyncDisposableStack.prototype.defer does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, explicit-resource-management, arrow-function] +---*/ + +assert.sameValue( + isConstructor(AsyncDisposableStack.prototype.defer), + false, + 'isConstructor(AsyncDisposableStack.prototype.defer) must return false' +); + +assert.throws(TypeError, () => { + let stack = new AsyncDisposableStack({}); new stack.defer(); +}, '`let stack = new AsyncDisposableStack({}); new stack.defer()` throws TypeError'); diff --git a/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/not-a-constructor.js b/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/not-a-constructor.js new file mode 100644 index 0000000000..8b56fb29cf --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/disposeAsync/not-a-constructor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.disposeAsync +description: > + AsyncDisposableStack.prototype.disposeAsync does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, explicit-resource-management, arrow-function] +---*/ + +assert.sameValue( + isConstructor(AsyncDisposableStack.prototype.disposeAsync), + false, + 'isConstructor(AsyncDisposableStack.prototype.disposeAsync) must return false' +); + +assert.throws(TypeError, () => { + let stack = new AsyncDisposableStack({}); new stack.disposeAsync(); +}, '`let stack = new AsyncDisposableStack({}); new stack.disposeAsync()` throws TypeError'); diff --git a/test/built-ins/AsyncDisposableStack/prototype/move/not-a-constructor.js b/test/built-ins/AsyncDisposableStack/prototype/move/not-a-constructor.js new file mode 100644 index 0000000000..5d7b0d97fd --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/move/not-a-constructor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.move +description: > + AsyncDisposableStack.prototype.move does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, explicit-resource-management, arrow-function] +---*/ + +assert.sameValue( + isConstructor(AsyncDisposableStack.prototype.move), + false, + 'isConstructor(AsyncDisposableStack.prototype.move) must return false' +); + +assert.throws(TypeError, () => { + let stack = new AsyncDisposableStack({}); new stack.move(); +}, '`let stack = new AsyncDisposableStack({}); new stack.move()` throws TypeError'); diff --git a/test/built-ins/AsyncDisposableStack/prototype/use/not-a-constructor.js b/test/built-ins/AsyncDisposableStack/prototype/use/not-a-constructor.js new file mode 100644 index 0000000000..e407a9aa81 --- /dev/null +++ b/test/built-ins/AsyncDisposableStack/prototype/use/not-a-constructor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-asyncdisposablestack.prototype.use +description: > + AsyncDisposableStack.prototype.use does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, explicit-resource-management, arrow-function] +---*/ + +assert.sameValue( + isConstructor(AsyncDisposableStack.prototype.use), + false, + 'isConstructor(AsyncDisposableStack.prototype.use) must return false' +); + +assert.throws(TypeError, () => { + let stack = new AsyncDisposableStack({}); new stack.use(); +}, '`let stack = new AsyncDisposableStack({}); new stack.use()` throws TypeError'); diff --git a/test/built-ins/DisposableStack/is-a-constructor.js b/test/built-ins/DisposableStack/is-a-constructor.js new file mode 100644 index 0000000000..01b4ec9c90 --- /dev/null +++ b/test/built-ins/DisposableStack/is-a-constructor.js @@ -0,0 +1,23 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: > + The DisposableStack constructor implements [[Construct]] +info: | + IsConstructor ( argument ) + + The abstract operation IsConstructor takes argument argument (an ECMAScript language value). + It determines if argument is a function object with a [[Construct]] internal method. + It performs the following steps when called: + + If Type(argument) is not Object, return false. + If argument has a [[Construct]] internal method, return true. + Return false. +includes: [isConstructor.js] +features: [explicit-resource-management, Reflect.construct] +---*/ + +assert.sameValue(isConstructor(DisposableStack), true, 'isConstructor(DisposableStack) must return true'); +new DisposableStack(); diff --git a/test/built-ins/DisposableStack/prototype/adopt/not-a-constructor.js b/test/built-ins/DisposableStack/prototype/adopt/not-a-constructor.js new file mode 100644 index 0000000000..f958f5028d --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/adopt/not-a-constructor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.adopt +description: > + DisposableStack.prototype.adopt does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, explicit-resource-management, arrow-function] +---*/ + +assert.sameValue( + isConstructor(DisposableStack.prototype.adopt), + false, + 'isConstructor(DisposableStack.prototype.adopt) must return false' +); + +assert.throws(TypeError, () => { + let stack = new DisposableStack({}); new stack.adopt(); +}, '`let stack = new DisposableStack({}); new stack.adopt()` throws TypeError'); diff --git a/test/built-ins/DisposableStack/prototype/defer/not-a-constructor.js b/test/built-ins/DisposableStack/prototype/defer/not-a-constructor.js new file mode 100644 index 0000000000..cbb41f3356 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/defer/not-a-constructor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.defer +description: > + DisposableStack.prototype.defer does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, explicit-resource-management, arrow-function] +---*/ + +assert.sameValue( + isConstructor(DisposableStack.prototype.defer), + false, + 'isConstructor(DisposableStack.prototype.defer) must return false' +); + +assert.throws(TypeError, () => { + let stack = new DisposableStack({}); new stack.defer(); +}, '`let stack = new DisposableStack({}); new stack.defer()` throws TypeError'); diff --git a/test/built-ins/DisposableStack/prototype/dispose/not-a-constructor.js b/test/built-ins/DisposableStack/prototype/dispose/not-a-constructor.js new file mode 100644 index 0000000000..c71599ad36 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/dispose/not-a-constructor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.dispose +description: > + DisposableStack.prototype.dispose does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, explicit-resource-management, arrow-function] +---*/ + +assert.sameValue( + isConstructor(DisposableStack.prototype.dispose), + false, + 'isConstructor(DisposableStack.prototype.dispose) must return false' +); + +assert.throws(TypeError, () => { + let stack = new DisposableStack({}); new stack.dispose(); +}, '`let stack = new DisposableStack({}); new stack.dispose()` throws TypeError'); diff --git a/test/built-ins/DisposableStack/prototype/move/not-a-constructor.js b/test/built-ins/DisposableStack/prototype/move/not-a-constructor.js new file mode 100644 index 0000000000..93490d98d4 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/move/not-a-constructor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.move +description: > + DisposableStack.prototype.move does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, explicit-resource-management, arrow-function] +---*/ + +assert.sameValue( + isConstructor(DisposableStack.prototype.move), + false, + 'isConstructor(DisposableStack.prototype.move) must return false' +); + +assert.throws(TypeError, () => { + let stack = new DisposableStack({}); new stack.move(); +}, '`let stack = new DisposableStack({}); new stack.move()` throws TypeError'); diff --git a/test/built-ins/DisposableStack/prototype/use/not-a-constructor.js b/test/built-ins/DisposableStack/prototype/use/not-a-constructor.js new file mode 100644 index 0000000000..67dbdae415 --- /dev/null +++ b/test/built-ins/DisposableStack/prototype/use/not-a-constructor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-disposablestack.prototype.use +description: > + DisposableStack.prototype.use does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, explicit-resource-management, arrow-function] +---*/ + +assert.sameValue( + isConstructor(DisposableStack.prototype.use), + false, + 'isConstructor(DisposableStack.prototype.use) must return false' +); + +assert.throws(TypeError, () => { + let stack = new DisposableStack({}); new stack.use(); +}, '`let stack = new DisposableStack({}); new stack.use()` throws TypeError'); diff --git a/test/built-ins/NativeErrors/SuppressedError/is-a-constructor.js b/test/built-ins/NativeErrors/SuppressedError/is-a-constructor.js new file mode 100644 index 0000000000..5afd11d1e1 --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/is-a-constructor.js @@ -0,0 +1,24 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: > + The SuppressedError constructor implements [[Construct]] +info: | + IsConstructor ( argument ) + + The abstract operation IsConstructor takes argument argument (an ECMAScript language value). + It determines if argument is a function object with a [[Construct]] internal method. + It performs the following steps when called: + + If Type(argument) is not Object, return false. + If argument has a [[Construct]] internal method, return true. + Return false. +includes: [isConstructor.js] +features: [Reflect.construct, explicit-resource-management] +---*/ + +assert.sameValue(isConstructor(SuppressedError), true, 'isConstructor(SuppressedError) must return true'); +new SuppressedError(); + From 435a89b7025a32524c640a33cc5d1c95ae51019f Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Mon, 29 Jul 2024 23:38:33 +0200 Subject: [PATCH 43/90] Address review comments and fixes some more descriptions - Fixes to two tests testing Map.prototype.size - Description fixes --- .../AsyncDisposableStack/prototype/defer/length.js | 2 +- .../AsyncDisposableStack/prototype/disposed/length.js | 8 ++++---- .../AsyncIteratorPrototype/Symbol.asyncDispose/length.js | 2 ++ .../AsyncIteratorPrototype/Symbol.asyncDispose/name.js | 2 +- .../Symbol.asyncDispose/prop-desc.js | 2 +- test/built-ins/DisposableStack/prototype/adopt/length.js | 4 ++-- test/built-ins/DisposableStack/prototype/defer/length.js | 2 +- .../DisposableStack/prototype/disposed/length.js | 8 ++++---- test/built-ins/DisposableStack/prototype/disposed/name.js | 2 +- .../built-ins/Iterator/prototype/Symbol.dispose/length.js | 2 ++ test/built-ins/Iterator/prototype/Symbol.dispose/name.js | 2 +- .../Iterator/prototype/Symbol.dispose/prop-desc.js | 2 +- 12 files changed, 21 insertions(+), 17 deletions(-) diff --git a/test/built-ins/AsyncDisposableStack/prototype/defer/length.js b/test/built-ins/AsyncDisposableStack/prototype/defer/length.js index 96a62e3bc8..edd6bab721 100644 --- a/test/built-ins/AsyncDisposableStack/prototype/defer/length.js +++ b/test/built-ins/AsyncDisposableStack/prototype/defer/length.js @@ -5,7 +5,7 @@ esid: sec-asyncdisposablestack.prototype.defer description: AsyncDisposableStack.prototype.defer.length property descriptor info: | - AsyncDisposableStack.prototype.defer ( ) + AsyncDisposableStack.prototype.defer ( onDisposeAsync ) 17 ECMAScript Standard Built-in Objects diff --git a/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js b/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js index 3f30906c3c..97f092faaa 100644 --- a/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js +++ b/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js @@ -3,19 +3,19 @@ /*--- esid: sec-get-asyncdisposablestack.prototype.disposed description: > - Map.prototype.size.length value and descriptor. + AsyncDisposableStack.prototype.disposed.length value and descriptor. info: | - get Map.prototype.size + get AsyncDisposableStack.prototype.disposed 17 ECMAScript Standard Built-in Objects includes: [propertyHelper.js] ---*/ -var descriptor = Object.getOwnPropertyDescriptor(Map.prototype, 'size'); +var descriptor = Object.getOwnPropertyDescriptor(AsyncDisposableStack.prototype, 'disposed'); assert.sameValue( descriptor.get.length, 0, - 'The value of `Map.prototype.size.length` is `0`' + 'The value of `AsyncDisposableStack.prototype.disposed` is `0`' ); verifyNotEnumerable(descriptor.get, 'length'); diff --git a/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/length.js b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/length.js index a9c34d30ed..c46eedba5c 100644 --- a/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/length.js +++ b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/length.js @@ -4,6 +4,8 @@ esid: sec-%asynciteratorprototype%-@@asyncDispose description: Length of %AsyncIteratorPrototype%[ @@asyncDispose ] info: | + %AsyncIteratorPrototype%[ @@asyncDispose ] () + ES6 Section 17: Every built-in Function object, including constructors, has a length property whose value is an integer. Unless otherwise specified, this value diff --git a/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/name.js b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/name.js index 5ea13ac63f..91ddae7294 100644 --- a/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/name.js +++ b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/name.js @@ -2,7 +2,7 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-%asynciteratorprototype%-@@asyncDispose -description: Descriptor for `name` property +description: Descriptor for `name` property of %AsyncIteratorPrototype%[ @@asyncDispose ] info: | The value of the name property of this function is "[Symbol.asyncDispose]". diff --git a/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/prop-desc.js b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/prop-desc.js index 3523d8d851..702e4cc949 100644 --- a/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/prop-desc.js +++ b/test/built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/prop-desc.js @@ -2,7 +2,7 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-%asynciteratorprototype%-@@asyncDispose -description: Property descriptor +description: Property descriptor of %AsyncIteratorPrototype%[ @@asyncDispose ] info: | ES6 Section 17 diff --git a/test/built-ins/DisposableStack/prototype/adopt/length.js b/test/built-ins/DisposableStack/prototype/adopt/length.js index f2dd3c63ec..9ac6ee535a 100644 --- a/test/built-ins/DisposableStack/prototype/adopt/length.js +++ b/test/built-ins/DisposableStack/prototype/adopt/length.js @@ -3,9 +3,9 @@ /*--- esid: sec-disposablestack.prototype.adopt -description: DisposableStack.prototype.adopt.length property descriptor +description: DisposableStack.prototype.adopt.length value and property descriptor info: | - DisposableStack.prototype.adopt ( ) + DisposableStack.prototype.adopt ( value, onDispose ) 17 ECMAScript Standard Built-in Objects diff --git a/test/built-ins/DisposableStack/prototype/defer/length.js b/test/built-ins/DisposableStack/prototype/defer/length.js index 6b3e90e774..28488c4037 100644 --- a/test/built-ins/DisposableStack/prototype/defer/length.js +++ b/test/built-ins/DisposableStack/prototype/defer/length.js @@ -5,7 +5,7 @@ esid: sec-disposablestack.prototype.defer description: DisposableStack.prototype.defer.length property descriptor info: | - DisposableStack.prototype.defer ( ) + DisposableStack.prototype.defer ( onDispose ) 17 ECMAScript Standard Built-in Objects diff --git a/test/built-ins/DisposableStack/prototype/disposed/length.js b/test/built-ins/DisposableStack/prototype/disposed/length.js index 3e1d77f3df..cbe73ba489 100644 --- a/test/built-ins/DisposableStack/prototype/disposed/length.js +++ b/test/built-ins/DisposableStack/prototype/disposed/length.js @@ -3,19 +3,19 @@ /*--- esid: sec-get-disposablestack.prototype.disposed description: > - Map.prototype.size.length value and descriptor. + DisposableStack.prototype.disposed.length value and descriptor. info: | - get Map.prototype.size + get DisposableStack.prototype.disposed 17 ECMAScript Standard Built-in Objects includes: [propertyHelper.js] ---*/ -var descriptor = Object.getOwnPropertyDescriptor(Map.prototype, 'size'); +var descriptor = Object.getOwnPropertyDescriptor(DisposableStack.prototype, 'disposed'); assert.sameValue( descriptor.get.length, 0, - 'The value of `Map.prototype.size.length` is `0`' + 'The value of `DisposableStack.prototype.disposed.length` is `0`' ); verifyNotEnumerable(descriptor.get, 'length'); diff --git a/test/built-ins/DisposableStack/prototype/disposed/name.js b/test/built-ins/DisposableStack/prototype/disposed/name.js index c20b505705..b6638f23b2 100644 --- a/test/built-ins/DisposableStack/prototype/disposed/name.js +++ b/test/built-ins/DisposableStack/prototype/disposed/name.js @@ -5,7 +5,7 @@ esid: sec-get-disposablestack.prototype.disposed description: > DisposableStack.prototype.disposed.name value and descriptor. info: | - get DisposableStack.prototype.size + get DisposableStack.prototype.disposed 17 ECMAScript Standard Built-in Objects diff --git a/test/built-ins/Iterator/prototype/Symbol.dispose/length.js b/test/built-ins/Iterator/prototype/Symbol.dispose/length.js index 4a31d3b38e..3054345184 100644 --- a/test/built-ins/Iterator/prototype/Symbol.dispose/length.js +++ b/test/built-ins/Iterator/prototype/Symbol.dispose/length.js @@ -4,6 +4,8 @@ esid: sec-%iteratorprototype%-@@dispose description: Length of %IteratorPrototype%[ @@dispose ] info: | + %IteratorPrototype% [ @@dispose ] ( ) + ES6 Section 17: Every built-in Function object, including constructors, has a length property whose value is an integer. Unless otherwise specified, this value diff --git a/test/built-ins/Iterator/prototype/Symbol.dispose/name.js b/test/built-ins/Iterator/prototype/Symbol.dispose/name.js index a6d17ef8ee..6e0c0d70fd 100644 --- a/test/built-ins/Iterator/prototype/Symbol.dispose/name.js +++ b/test/built-ins/Iterator/prototype/Symbol.dispose/name.js @@ -2,7 +2,7 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-%iteratorprototype%-@@dispose -description: Descriptor for `name` property +description: Descriptor for `name` property of %IteratorPrototype%[ @@dispose ] info: | The value of the name property of this function is "[Symbol.dispose]". diff --git a/test/built-ins/Iterator/prototype/Symbol.dispose/prop-desc.js b/test/built-ins/Iterator/prototype/Symbol.dispose/prop-desc.js index 1926548eb8..8889012af6 100644 --- a/test/built-ins/Iterator/prototype/Symbol.dispose/prop-desc.js +++ b/test/built-ins/Iterator/prototype/Symbol.dispose/prop-desc.js @@ -2,7 +2,7 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-%iteratorprototype%-@@dispose -description: Property descriptor +description: Property descriptor of %IteratorPrototype%[ @@dispose ] info: | ES6 Section 17 From e612296c413dfc8723a6fb65b39f55921a57aae7 Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Tue, 30 Jul 2024 01:15:58 +0200 Subject: [PATCH 44/90] Changed two files to use verifyProperty. --- .../prototype/disposed/length.js | 14 ++++++-------- .../DisposableStack/prototype/disposed/length.js | 14 ++++++-------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js b/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js index 97f092faaa..2741f01e43 100644 --- a/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js +++ b/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js @@ -13,11 +13,9 @@ includes: [propertyHelper.js] var descriptor = Object.getOwnPropertyDescriptor(AsyncDisposableStack.prototype, 'disposed'); -assert.sameValue( - descriptor.get.length, 0, - 'The value of `AsyncDisposableStack.prototype.disposed` is `0`' -); - -verifyNotEnumerable(descriptor.get, 'length'); -verifyNotWritable(descriptor.get, 'length'); -verifyConfigurable(descriptor.get, 'length'); +verifyProperty(descriptor.get, 'length', { + value: 0; + enumerable: false, + writable: false, + configurable: true +}); diff --git a/test/built-ins/DisposableStack/prototype/disposed/length.js b/test/built-ins/DisposableStack/prototype/disposed/length.js index cbe73ba489..21d6afc6a5 100644 --- a/test/built-ins/DisposableStack/prototype/disposed/length.js +++ b/test/built-ins/DisposableStack/prototype/disposed/length.js @@ -13,11 +13,9 @@ includes: [propertyHelper.js] var descriptor = Object.getOwnPropertyDescriptor(DisposableStack.prototype, 'disposed'); -assert.sameValue( - descriptor.get.length, 0, - 'The value of `DisposableStack.prototype.disposed.length` is `0`' -); - -verifyNotEnumerable(descriptor.get, 'length'); -verifyNotWritable(descriptor.get, 'length'); -verifyConfigurable(descriptor.get, 'length'); +verifyProperty(descriptor.get, 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true +}); From 6add1a22cdd8295080cd60b679d96857edd719fc Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Tue, 30 Jul 2024 01:24:47 +0200 Subject: [PATCH 45/90] adds features: [explicit-resource-management] flag --- test/built-ins/AsyncDisposableStack/prototype/disposed/length.js | 1 + test/built-ins/DisposableStack/prototype/disposed/length.js | 1 + 2 files changed, 2 insertions(+) diff --git a/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js b/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js index 2741f01e43..d333127f6e 100644 --- a/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js +++ b/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js @@ -9,6 +9,7 @@ info: | 17 ECMAScript Standard Built-in Objects includes: [propertyHelper.js] +features: [explicit-resource-management] ---*/ var descriptor = Object.getOwnPropertyDescriptor(AsyncDisposableStack.prototype, 'disposed'); diff --git a/test/built-ins/DisposableStack/prototype/disposed/length.js b/test/built-ins/DisposableStack/prototype/disposed/length.js index 21d6afc6a5..a3a687d967 100644 --- a/test/built-ins/DisposableStack/prototype/disposed/length.js +++ b/test/built-ins/DisposableStack/prototype/disposed/length.js @@ -9,6 +9,7 @@ info: | 17 ECMAScript Standard Built-in Objects includes: [propertyHelper.js] +features: [explicit-resource-management] ---*/ var descriptor = Object.getOwnPropertyDescriptor(DisposableStack.prototype, 'disposed'); From 1842afcbce564d8866934194cb54af6f43f76169 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Tue, 30 Jul 2024 02:33:50 +0200 Subject: [PATCH 46/90] RAB: Integrate staging tests for the .reduce method (#4156) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while adjusting usage of CollectValuesAndResize and applying review changes from PRs for previously tested methods. * Added missing 'shrink' test for Array.prototype.reduce * Deleted accidental files * Fix accidental call of .map instead of .reduce Addresses review comments * fix copyright in new file not in origin PR --- .../resizable-buffer-grow-mid-iteration.js | 86 +++++++++++ .../resizable-buffer-shrink-mid-iteration.js | 79 ++++++++++ .../prototype/reduce/resizable-buffer.js | 126 +++++++++++++++ .../resizable-buffer-grow-mid-iteration.js | 84 ++++++++++ .../resizable-buffer-shrink-mid-iteration.js | 83 ++++++++++ .../prototype/reduce/resizable-buffer.js | 145 ++++++++++++++++++ 6 files changed, 603 insertions(+) create mode 100644 test/built-ins/Array/prototype/reduce/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/reduce/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/reduce/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/reduce/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/reduce/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/reduce/resizable-buffer.js diff --git a/test/built-ins/Array/prototype/reduce/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/reduce/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..c7f224f6a2 --- /dev/null +++ b/test/built-ins/Array/prototype/reduce/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,86 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.reduce +description: > + Array.p.reduce behaves correctly when the resizable buffer is grown + mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset +// before calling this. +function ResizeMidIteration(acc, n) { + // Returns true by default. + return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +// Test for reduce. + +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduce.call(fixedLength, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduce.call(fixedLengthWithOffset, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduce.call(lengthTracking, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduce.call(lengthTrackingWithOffset, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 4, + 6 + ]); +} diff --git a/test/built-ins/Array/prototype/reduce/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/Array/prototype/reduce/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..c4e66aecd5 --- /dev/null +++ b/test/built-ins/Array/prototype/reduce/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,79 @@ +// Copyright 2024 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%array%.prototype.reduce +description: > + Array.p.reduce behaves correctly when the backing resizable buffer is shrunk + mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset +// before calling this. +function ResizeMidIteration(acc, n) { + // Returns true by default. + return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduce.call(fixedLength, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 0, + 2 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduce.call(fixedLengthWithOffset, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 4 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduce.call(lengthTracking, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 0, + 2, + 4 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + Array.prototype.reduce.call(lengthTrackingWithOffset, ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 4 + ]); +} diff --git a/test/built-ins/Array/prototype/reduce/resizable-buffer.js b/test/built-ins/Array/prototype/reduce/resizable-buffer.js new file mode 100644 index 0000000000..c03585e3cd --- /dev/null +++ b/test/built-ins/Array/prototype/reduce/resizable-buffer.js @@ -0,0 +1,126 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.reduce +description: > + Array.p.reduce behaves correctly on TypedArrays backed by resizable buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + function ReduceCollecting(array) { + const reduceValues = []; + Array.prototype.reduce.call(array, (acc, n) => { + reduceValues.push(n); + }, 'initial value'); + return ToNumbers(reduceValues); + } + assert.compareArray(ReduceCollecting(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceCollecting(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(ReduceCollecting(lengthTracking), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceCollecting(lengthTrackingWithOffset), [ + 4, + 6 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.compareArray(ReduceCollecting(fixedLength), []); + assert.compareArray(ReduceCollecting(fixedLengthWithOffset), []); + + assert.compareArray(ReduceCollecting(lengthTracking), [ + 0, + 2, + 4 + ]); + assert.compareArray(ReduceCollecting(lengthTrackingWithOffset), [4]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.compareArray(ReduceCollecting(fixedLength), []); + assert.compareArray(ReduceCollecting(fixedLengthWithOffset), []); + + assert.compareArray(ReduceCollecting(lengthTracking), [0]); + + // Shrink to zero. + rab.resize(0); + assert.compareArray(ReduceCollecting(fixedLength), []); + assert.compareArray(ReduceCollecting(fixedLengthWithOffset), []); + assert.compareArray(ReduceCollecting(lengthTrackingWithOffset), []); + + assert.compareArray(ReduceCollecting(lengthTracking), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.compareArray(ReduceCollecting(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceCollecting(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(ReduceCollecting(lengthTracking), [ + 0, + 2, + 4, + 6, + 8, + 10 + ]); + assert.compareArray(ReduceCollecting(lengthTrackingWithOffset), [ + 4, + 6, + 8, + 10 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..46b7beeb2b --- /dev/null +++ b/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,84 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.reduce +description: > + TypedArray.p.reduce behaves correctly on TypedArrays backed by resizable + buffers that are grown mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset +// before calling this. +function ResizeMidIteration(n) { + // Returns true by default. + return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + fixedLength.reduce(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + fixedLengthWithOffset.reduce(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + lengthTracking.reduce(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.reduce(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 4, + 6 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..e9de100daa --- /dev/null +++ b/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,83 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.reduce +description: > + TypedArray.p.reduce behaves correctly on TypedArrays backed by resizable + buffers that are shrunk mid-iteration. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset +// before calling this. +function ResizeMidIteration(n) { + return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLength.reduce(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 0, + 2, + undefined, + undefined + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLengthWithOffset.reduce(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 4, + undefined + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + lengthTracking.reduce(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 0, + 2, + 4, + undefined + ]); +} +for (let ctor of ctors) { + values = []; + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.reduce(ResizeMidIteration, 'initial value'); + assert.compareArray(values, [ + 4, + undefined + ]); +} diff --git a/test/built-ins/TypedArray/prototype/reduce/resizable-buffer.js b/test/built-ins/TypedArray/prototype/reduce/resizable-buffer.js new file mode 100644 index 0000000000..4956887d17 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/reduce/resizable-buffer.js @@ -0,0 +1,145 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.reduce +description: > + TypedArray.p.reduce behaves correctly on TypedArrays backed by resizable + buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + function ReduceCollecting(array) { + const reduceValues = []; + array.reduce((acc, n) => { + reduceValues.push(n); + }, 'initial value'); + return ToNumbers(reduceValues); + } + assert.compareArray(ReduceCollecting(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceCollecting(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(ReduceCollecting(lengthTracking), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceCollecting(lengthTrackingWithOffset), [ + 4, + 6 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + ReduceCollecting(fixedLength); + }); + assert.throws(TypeError, () => { + ReduceCollecting(fixedLengthWithOffset); + }); + + assert.compareArray(ReduceCollecting(lengthTracking), [ + 0, + 2, + 4 + ]); + assert.compareArray(ReduceCollecting(lengthTrackingWithOffset), [4]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + ReduceCollecting(fixedLength); + }); + assert.throws(TypeError, () => { + ReduceCollecting(fixedLengthWithOffset); + }); + assert.throws(TypeError, () => { + ReduceCollecting(lengthTrackingWithOffset); + }); + + assert.compareArray(ReduceCollecting(lengthTracking), [0]); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + ReduceCollecting(fixedLength); + }); + assert.throws(TypeError, () => { + ReduceCollecting(fixedLengthWithOffset); + }); + assert.throws(TypeError, () => { + ReduceCollecting(lengthTrackingWithOffset); + }); + + assert.compareArray(ReduceCollecting(lengthTracking), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.compareArray(ReduceCollecting(fixedLength), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ReduceCollecting(fixedLengthWithOffset), [ + 4, + 6 + ]); + assert.compareArray(ReduceCollecting(lengthTracking), [ + 0, + 2, + 4, + 6, + 8, + 10 + ]); + assert.compareArray(ReduceCollecting(lengthTrackingWithOffset), [ + 4, + 6, + 8, + 10 + ]); +} From 616dcadff406451eb249c6170253c5ff7486a3ea Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Tue, 30 Jul 2024 14:24:39 +0900 Subject: [PATCH 47/90] Fix escaped `a` --- test/built-ins/RegExp/escape/initial-char-escape.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/built-ins/RegExp/escape/initial-char-escape.js b/test/built-ins/RegExp/escape/initial-char-escape.js index 5d6ce26318..e51159a424 100644 --- a/test/built-ins/RegExp/escape/initial-char-escape.js +++ b/test/built-ins/RegExp/escape/initial-char-escape.js @@ -102,7 +102,7 @@ assert.sameValue(RegExp.escape('8+8'), '\\x38\\+8', 'Initial decimal digit 8 wit assert.sameValue(RegExp.escape('9+9'), '\\x39\\+9', 'Initial decimal digit 9 with special character is escaped'); assert.sameValue(RegExp.escape('0+0'), '\\x30\\+0', 'Initial decimal digit 0 with special character is escaped'); -assert.sameValue(RegExp.escape('a*a'), '\\x62\\*a', 'Initial ASCII letter a with special character is escaped'); +assert.sameValue(RegExp.escape('a*a'), '\\x61\\*a', 'Initial ASCII letter a with special character is escaped'); assert.sameValue(RegExp.escape('b*b'), '\\x62\\*b', 'Initial ASCII letter b with special character is escaped'); assert.sameValue(RegExp.escape('c*c'), '\\x63\\*c', 'Initial ASCII letter c with special character is escaped'); assert.sameValue(RegExp.escape('d*d'), '\\x64\\*d', 'Initial ASCII letter d with special character is escaped'); From 5492929d555b793f3dc45ac9109e5b93d9053dce Mon Sep 17 00:00:00 2001 From: Lucas Mirelmann Date: Thu, 1 Aug 2024 11:03:53 +0200 Subject: [PATCH 48/90] Fix typo Fix typo in an ObjectLiteral --- .../built-ins/AsyncDisposableStack/prototype/disposed/length.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js b/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js index d333127f6e..abf73d92f1 100644 --- a/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js +++ b/test/built-ins/AsyncDisposableStack/prototype/disposed/length.js @@ -15,7 +15,7 @@ features: [explicit-resource-management] var descriptor = Object.getOwnPropertyDescriptor(AsyncDisposableStack.prototype, 'disposed'); verifyProperty(descriptor.get, 'length', { - value: 0; + value: 0, enumerable: false, writable: false, configurable: true From 8ca5bdd44cf682409d355a068068bec83752160b Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 19 May 2024 12:43:11 -0400 Subject: [PATCH 49/90] CONTRIBUTING.md: Improve asyncHelpers documentation * Only mention `$DONE` after `asyncTest`. * Document that `asyncTest` is not intended to be called multiple times per file. --- CONTRIBUTING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2c8e529a4f..74118d65de 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -209,8 +209,9 @@ This key is for boolean properties associated with the test. - **raw** - execute the test without any modification (no harness files will be included); necessary to test the behavior of directive prologue; implies `noStrict` -- **async** - defer interpretation of test results until after the invocation - of the global `$DONE` function +- **async** - defer interpretation of test results until settlement of an + `asyncTest` callback promise or manual invocation of `$DONE`; refer to + [Writing Asynchronous Tests](#writing-asynchronous-tests) for details - **generated** - informative flag used to denote test files that were created procedurally using the project's test generation tool; refer to [Procedurally-generated tests](#procedurally-generated-tests) @@ -346,7 +347,7 @@ Consumers that violate the spec by throwing exceptions for parsing errors at run An asynchronous test is any test that include the `async` frontmatter flag. -For most asynchronous tests, the `asyncHelpers.js` harness file includes an `asyncTest` method that precludes needing to interact with the test runner via the `$DONE` function. `asyncTest` takes an async function and will ensure that `$DONE` is called properly if the async function returns or throws an exception. For example, a test written using `asyncTest` might look like: +Most asynchronous tests should include the `asyncHelpers.js` harness file and call its `asyncTest` function **exactly once**, with a callback returning a promise that indicates test failure via rejection and otherwise fulfills upon test conclusion (such as an async function). ```js /*--- From 1b34a1c4847ef7b01a3899faed70729159b6002f Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 19 May 2024 12:43:58 -0400 Subject: [PATCH 50/90] harness/asyncHelpers.js: Add doc comments --- harness/asyncHelpers.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/harness/asyncHelpers.js b/harness/asyncHelpers.js index c8e58457fc..e7eac06a68 100644 --- a/harness/asyncHelpers.js +++ b/harness/asyncHelpers.js @@ -6,6 +6,14 @@ description: | defines: [asyncTest] ---*/ +/** + * Defines the **sole** asynchronous test of a file. + * @see {@link ../docs/rfcs/async-helpers.md} for background. + * + * @param {Function} testFunc a callback whose returned promise indicates test results + * (fulfillment for success, rejection for failure) + * @returns {void} + */ function asyncTest(testFunc) { if (!Object.hasOwn(globalThis, "$DONE")) { throw new Test262Error("asyncTest called without async flag"); @@ -28,6 +36,18 @@ function asyncTest(testFunc) { } } +/** + * Asserts that a callback asynchronously throws an instance of a particular + * error (i.e., returns a promise whose rejection value is an object referencing + * the constructor). + * + * @param {Function} expectedErrorConstructor the expected constructor of the + * rejection value + * @param {Function} func the callback + * @param {string} [message] the prefix to use for failure messages + * @returns {Promise} fulfills if the expected error is thrown, + * otherwise rejects + */ assert.throwsAsync = function (expectedErrorConstructor, func, message) { return new Promise(function (resolve) { var innerThenable; From b22b500f241a226b4c9e6b899638ec6bb5109269 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 19 May 2024 13:18:45 -0400 Subject: [PATCH 51/90] harness/asyncHelpers.js: Refactor assert.throwsAsync to fail fast --- harness/asyncHelpers.js | 43 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/harness/asyncHelpers.js b/harness/asyncHelpers.js index e7eac06a68..210cc4201f 100644 --- a/harness/asyncHelpers.js +++ b/harness/asyncHelpers.js @@ -56,32 +56,31 @@ assert.throwsAsync = function (expectedErrorConstructor, func, message) { } else { message += " "; } - if (typeof func === "function") { - try { - innerThenable = func(); - if ( - innerThenable === null || - typeof innerThenable !== "object" || - typeof innerThenable.then !== "function" - ) { - message += - "Expected to obtain an inner promise that would reject with a" + - expectedErrorConstructor.name + - " but result was not a thenable"; - throw new Test262Error(message); - } - } catch (thrown) { - message += - "Expected a " + - expectedErrorConstructor.name + - " to be thrown asynchronously but an exception was thrown synchronously while obtaining the inner promise"; - throw new Test262Error(message); - } - } else { + if (typeof func !== "function") { message += "assert.throwsAsync called with an argument that is not a function"; throw new Test262Error(message); } + try { + innerThenable = func(); + if ( + innerThenable === null || + typeof innerThenable !== "object" || + typeof innerThenable.then !== "function" + ) { + message += + "Expected to obtain an inner promise that would reject with a" + + expectedErrorConstructor.name + + " but result was not a thenable"; + throw new Test262Error(message); + } + } catch (thrown) { + message += + "Expected a " + + expectedErrorConstructor.name + + " to be thrown asynchronously but an exception was thrown synchronously while obtaining the inner promise"; + throw new Test262Error(message); + } try { resolve(innerThenable.then( From 0631e2111b23894103669bc7167023c12c20a3f4 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 19 May 2024 13:26:31 -0400 Subject: [PATCH 52/90] harness/asyncHelpers.js: Isolate assert.throwsAsync failure conditions --- harness/asyncHelpers.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/harness/asyncHelpers.js b/harness/asyncHelpers.js index 210cc4201f..cd610bd734 100644 --- a/harness/asyncHelpers.js +++ b/harness/asyncHelpers.js @@ -63,17 +63,6 @@ assert.throwsAsync = function (expectedErrorConstructor, func, message) { } try { innerThenable = func(); - if ( - innerThenable === null || - typeof innerThenable !== "object" || - typeof innerThenable.then !== "function" - ) { - message += - "Expected to obtain an inner promise that would reject with a" + - expectedErrorConstructor.name + - " but result was not a thenable"; - throw new Test262Error(message); - } } catch (thrown) { message += "Expected a " + @@ -81,6 +70,17 @@ assert.throwsAsync = function (expectedErrorConstructor, func, message) { " to be thrown asynchronously but an exception was thrown synchronously while obtaining the inner promise"; throw new Test262Error(message); } + if ( + innerThenable === null || + typeof innerThenable !== "object" || + typeof innerThenable.then !== "function" + ) { + message += + "Expected to obtain an inner promise that would reject with a" + + expectedErrorConstructor.name + + " but result was not a thenable"; + throw new Test262Error(message); + } try { resolve(innerThenable.then( From b87eaf9ac3e50b517cfef1de98e260a4f09fb353 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 19 May 2024 13:26:31 -0400 Subject: [PATCH 53/90] harness/asyncHelpers.js: Fix an assert.throwsAsync failure message typo --- harness/asyncHelpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/harness/asyncHelpers.js b/harness/asyncHelpers.js index cd610bd734..fa4665b621 100644 --- a/harness/asyncHelpers.js +++ b/harness/asyncHelpers.js @@ -76,7 +76,7 @@ assert.throwsAsync = function (expectedErrorConstructor, func, message) { typeof innerThenable.then !== "function" ) { message += - "Expected to obtain an inner promise that would reject with a" + + "Expected to obtain an inner promise that would reject with a " + expectedErrorConstructor.name + " but result was not a thenable"; throw new Test262Error(message); From 0b61e98564e3e7a84c0effc9641f4b9f9ba1683a Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 19 May 2024 13:33:08 -0400 Subject: [PATCH 54/90] harness/asyncHelpers.js: Clean up assert.throwsAsync failure messages * Remove mention of an "inner" promise/thenable. --- harness/asyncHelpers.js | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/harness/asyncHelpers.js b/harness/asyncHelpers.js index fa4665b621..abd71ce8a4 100644 --- a/harness/asyncHelpers.js +++ b/harness/asyncHelpers.js @@ -67,7 +67,7 @@ assert.throwsAsync = function (expectedErrorConstructor, func, message) { message += "Expected a " + expectedErrorConstructor.name + - " to be thrown asynchronously but an exception was thrown synchronously while obtaining the inner promise"; + " to be thrown asynchronously but the function threw synchronously"; throw new Test262Error(message); } if ( @@ -76,7 +76,7 @@ assert.throwsAsync = function (expectedErrorConstructor, func, message) { typeof innerThenable.then !== "function" ) { message += - "Expected to obtain an inner promise that would reject with a " + + "Expected to obtain a promise that would reject with a " + expectedErrorConstructor.name + " but result was not a thenable"; throw new Test262Error(message); @@ -113,19 +113,10 @@ assert.throwsAsync = function (expectedErrorConstructor, func, message) { } )); } catch (thrown) { - if (typeof thrown !== "object" || thrown === null) { - message += - "Expected a " + - expectedErrorConstructor.name + - " to be thrown asynchronously but innerThenable synchronously threw a value that was not an object "; - } else { - message += - "Expected a " + - expectedErrorConstructor.name + - " to be thrown asynchronously but a " + - thrown.constructor.name + - " was thrown synchronously"; - } + message += + "Expected a " + + expectedErrorConstructor.name + + " to be thrown asynchronously but .then threw synchronously"; throw new Test262Error(message); } }); From fa3d0246e74da7844843ebfb4c71453c616b923a Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 19 May 2024 13:41:38 -0400 Subject: [PATCH 55/90] harness/asyncHelpers.js: Reduce the size of assert.throwsAsync --- harness/asyncHelpers.js | 64 ++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/harness/asyncHelpers.js b/harness/asyncHelpers.js index abd71ce8a4..1bec9a0f2e 100644 --- a/harness/asyncHelpers.js +++ b/harness/asyncHelpers.js @@ -50,74 +50,60 @@ function asyncTest(testFunc) { */ assert.throwsAsync = function (expectedErrorConstructor, func, message) { return new Promise(function (resolve) { + var expectedName = expectedErrorConstructor.name; + var fail = function (detail) { + if (message === undefined) { + throw new Test262Error(detail); + } + throw new Test262Error(message + " " + detail); + }; var innerThenable; - if (message === undefined) { - message = ""; - } else { - message += " "; - } if (typeof func !== "function") { - message += - "assert.throwsAsync called with an argument that is not a function"; - throw new Test262Error(message); + fail("assert.throwsAsync called with an argument that is not a function"); } try { innerThenable = func(); } catch (thrown) { - message += - "Expected a " + - expectedErrorConstructor.name + - " to be thrown asynchronously but the function threw synchronously"; - throw new Test262Error(message); + fail("Expected a " + + expectedName + + " to be thrown asynchronously but the function threw synchronously"); } if ( innerThenable === null || typeof innerThenable !== "object" || typeof innerThenable.then !== "function" ) { - message += - "Expected to obtain a promise that would reject with a " + - expectedErrorConstructor.name + - " but result was not a thenable"; - throw new Test262Error(message); + fail("Expected to obtain a promise that would reject with a " + + expectedName + + " but result was not a thenable"); } try { resolve(innerThenable.then( function () { - message += - "Expected a " + - expectedErrorConstructor.name + - " to be thrown asynchronously but no exception was thrown at all"; - throw new Test262Error(message); + fail("Expected a " + + expectedName + + " to be thrown asynchronously but no exception was thrown at all"); }, function (thrown) { - var expectedName, actualName; + var actualName; if (typeof thrown !== "object" || thrown === null) { - message += "Thrown value was not an object!"; - throw new Test262Error(message); + fail("Thrown value was not an object!"); } else if (thrown.constructor !== expectedErrorConstructor) { - expectedName = expectedErrorConstructor.name; actualName = thrown.constructor.name; if (expectedName === actualName) { - message += - "Expected a " + + fail("Expected a " + expectedName + - " but got a different error constructor with the same name"; - } else { - message += - "Expected a " + expectedName + " but got a " + actualName; + " but got a different error constructor with the same name"); } - throw new Test262Error(message); + fail("Expected a " + expectedName + " but got a " + actualName); } } )); } catch (thrown) { - message += - "Expected a " + - expectedErrorConstructor.name + - " to be thrown asynchronously but .then threw synchronously"; - throw new Test262Error(message); + fail("Expected a " + + expectedName + + " to be thrown asynchronously but .then threw synchronously"); } }); }; From f83c1b938757f8ef213aa00594f0460b2b8cfbb6 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 19 May 2024 13:51:39 -0400 Subject: [PATCH 56/90] harness/asyncHelpers.js: Further reduce the size of assert.throwsAsync --- harness/asyncHelpers.js | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/harness/asyncHelpers.js b/harness/asyncHelpers.js index 1bec9a0f2e..b2efdf8061 100644 --- a/harness/asyncHelpers.js +++ b/harness/asyncHelpers.js @@ -51,59 +51,47 @@ function asyncTest(testFunc) { assert.throwsAsync = function (expectedErrorConstructor, func, message) { return new Promise(function (resolve) { var expectedName = expectedErrorConstructor.name; + var expectation = "Expected a " + expectedName + " to be thrown asynchronously"; var fail = function (detail) { if (message === undefined) { throw new Test262Error(detail); } throw new Test262Error(message + " " + detail); }; - var innerThenable; + var res; if (typeof func !== "function") { fail("assert.throwsAsync called with an argument that is not a function"); } try { - innerThenable = func(); + res = func(); } catch (thrown) { - fail("Expected a " + - expectedName + - " to be thrown asynchronously but the function threw synchronously"); + fail(expectation + " but the function threw synchronously"); } - if ( - innerThenable === null || - typeof innerThenable !== "object" || - typeof innerThenable.then !== "function" - ) { - fail("Expected to obtain a promise that would reject with a " + - expectedName + - " but result was not a thenable"); + if (res === null || typeof res !== "object" || typeof res.then !== "function") { + fail(expectation + " but result was not a thenable"); } try { - resolve(innerThenable.then( + resolve(res.then( function () { - fail("Expected a " + - expectedName + - " to be thrown asynchronously but no exception was thrown at all"); + fail(expectation + " but no exception was thrown at all"); }, function (thrown) { var actualName; - if (typeof thrown !== "object" || thrown === null) { - fail("Thrown value was not an object!"); + if (thrown === null || typeof thrown !== "object") { + fail(expectation + " but thrown value was not an object"); } else if (thrown.constructor !== expectedErrorConstructor) { actualName = thrown.constructor.name; if (expectedName === actualName) { - fail("Expected a " + - expectedName + + fail(expectation + " but got a different error constructor with the same name"); } - fail("Expected a " + expectedName + " but got a " + actualName); + fail(expectation + " but got a " + actualName); } } )); } catch (thrown) { - fail("Expected a " + - expectedName + - " to be thrown asynchronously but .then threw synchronously"); + fail(expectation + " but .then threw synchronously"); } }); }; From feb400c68598138b4e5a056c69b94bc1108d8a51 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Thu, 1 Aug 2024 12:42:01 -0400 Subject: [PATCH 57/90] harness/asyncHelpers.js: Update throwsAsync to not succeed on a bad thenable Fixes #4186 --- harness/asyncHelpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/harness/asyncHelpers.js b/harness/asyncHelpers.js index b2efdf8061..2d55fafebc 100644 --- a/harness/asyncHelpers.js +++ b/harness/asyncHelpers.js @@ -72,7 +72,7 @@ assert.throwsAsync = function (expectedErrorConstructor, func, message) { } try { - resolve(res.then( + resolve(Promise.resolve(res).then( function () { fail(expectation + " but no exception was thrown at all"); }, From ea37a19a4a67fc00e3023b9868288095be8311fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A8le?= Date: Mon, 5 Aug 2024 22:02:50 +0200 Subject: [PATCH 58/90] Add tests for nullable quantifiers in RegExps (#4185) * Add tests for nullable quantifiers in RegExps The JavaScript semantics for a quantifier matching the empty string are different from other regex languages. This adds a test that documents this JavaScript-specific behavior. This is part of my work at the SYSTEMF lab at EPFL. * Update nullable-quantifier.js --- test/built-ins/RegExp/nullable-quantifier.js | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/built-ins/RegExp/nullable-quantifier.js diff --git a/test/built-ins/RegExp/nullable-quantifier.js b/test/built-ins/RegExp/nullable-quantifier.js new file mode 100644 index 0000000000..04b4eda241 --- /dev/null +++ b/test/built-ins/RegExp/nullable-quantifier.js @@ -0,0 +1,21 @@ +// Copyright (C) 2024 Aurèle Barrière. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-runtime-semantics-repeatmatcher-abstract-operation +description: JavaScript nullable quantifiers have special semantics, optional iterations are not allowed to match the empty string. Point 2.b below shows that after each optional (min=0) iteration of a quantifier, if the iteration matched the empty string (y.[[EndIndex]] = x.[[EndIndex]]), then the iteration is discarded. In particular, for (a?b??)* on "ab", it is possible to do two iterations of the star, one matching "a" and the other matching "b". +info: | + RepeatMatcher ( m, min, max, greedy, x, c, parenIndex, parenCount ) + + 2. Let d be a new MatcherContinuation with parameters (y) that captures m, min, max, greedy, x, c, parenIndex, and parenCount and performs the following steps when called: + + b. If min = 0 and y.[[EndIndex]] = x.[[EndIndex]], return failure. +author: Aurèle Barrière +---*/ + +let input = "ab"; +let regex = /(a?b??)*/; +let match = regex.exec(input); +let expected = "ab"; + +assert.sameValue(match[0], expected, "The regex is expected to match the whole string"); From c0942e0883ed7b7b9155af52bd04d0de5f86eac7 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Mon, 5 Aug 2024 23:09:41 +0200 Subject: [PATCH 59/90] RAB: Integrate staging tests for the .set method (#4173) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, and renaming helper function. --- .../set/target-grow-mid-iteration.js | 113 ++++ .../set/target-grow-source-length-getter.js | 64 +++ .../set/target-shrink-mid-iteration.js | 99 ++++ .../set/target-shrink-source-length-getter.js | 147 +++++ .../set/this-backed-by-resizable-buffer.js | 525 ++++++++++++++++++ ...rray-arg-src-backed-by-resizable-buffer.js | 229 ++++++++ 6 files changed, 1177 insertions(+) create mode 100644 test/built-ins/TypedArray/prototype/set/target-grow-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/set/target-grow-source-length-getter.js create mode 100644 test/built-ins/TypedArray/prototype/set/target-shrink-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/set/target-shrink-source-length-getter.js create mode 100644 test/built-ins/TypedArray/prototype/set/this-backed-by-resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/set/typedarray-arg-src-backed-by-resizable-buffer.js diff --git a/test/built-ins/TypedArray/prototype/set/target-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/set/target-grow-mid-iteration.js new file mode 100644 index 0000000000..acc32ebe09 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/set/target-grow-mid-iteration.js @@ -0,0 +1,113 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.set +description: > + TypedArray.p.set behaves correctly on TypedArrays backed by resizable buffers + that are grown mid-iteration due to a Proxy source. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Resizing will happen when we're calling Get for the `resizeAt`:th data +// element, but we haven't yet written it to the target. +function CreateSourceProxy(length, rab, resizeAt, resizeTo) { + let requestedIndices = []; + return new Proxy({}, { + get(target, prop, receiver) { + if (prop == 'length') { + return length; + } + requestedIndices.push(prop); + if (requestedIndices.length == resizeAt) { + rab.resize(resizeTo); + } + return true; // Can be converted to both BigInt and Number. + } + }); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + const resizeAt = 2; + const resizeTo = 6 * ctor.BYTES_PER_ELEMENT; + fixedLength.set(CreateSourceProxy(4, rab, resizeAt, resizeTo)); + assert.compareArray(ToNumbers(fixedLength), [ + 1, + 1, + 1, + 1 + ]); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 1, + 1, + 1, + 1, + 0, + 0 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const resizeAt = 1; + const resizeTo = 6 * ctor.BYTES_PER_ELEMENT; + fixedLengthWithOffset.set(CreateSourceProxy(2, rab, resizeAt, resizeTo)); + assert.compareArray(ToNumbers(fixedLengthWithOffset), [ + 1, + 1 + ]); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 1, + 1, + 0, + 0 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + const resizeAt = 2; + const resizeTo = 6 * ctor.BYTES_PER_ELEMENT; + lengthTracking.set(CreateSourceProxy(2, rab, resizeAt, resizeTo)); + assert.compareArray(ToNumbers(lengthTracking), [ + 1, + 1, + 4, + 6, + 0, + 0 + ]); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 1, + 1, + 4, + 6, + 0, + 0 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const resizeAt = 1; + const resizeTo = 6 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.set(CreateSourceProxy(2, rab, resizeAt, resizeTo)); + assert.compareArray(ToNumbers(lengthTrackingWithOffset), [ + 1, + 1, + 0, + 0 + ]); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 1, + 1, + 0, + 0 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/set/target-grow-source-length-getter.js b/test/built-ins/TypedArray/prototype/set/target-grow-source-length-getter.js new file mode 100644 index 0000000000..e78e0713db --- /dev/null +++ b/test/built-ins/TypedArray/prototype/set/target-grow-source-length-getter.js @@ -0,0 +1,64 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.set +description: > + TypedArray.p.set behaves correctly on TypedArrays backed by a + resizable buffer is grown due to the source's length getter +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset +function CreateSourceProxy(length, rab, resizeTo) { + return new Proxy({}, { + get(target, prop, receiver) { + if (prop == 'length') { + rab.resize(resizeTo); + return length; + } + return true; // Can be converted to both BigInt and Number. + } + }); +} + +// Test that we still throw for lengthTracking TAs if the source length is +// too large, even though we resized in the length getter (we check against +// the original length). +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + const resizeTo = 6 * ctor.BYTES_PER_ELEMENT; + assert.throws(RangeError, () => { + lengthTracking.set(CreateSourceProxy(6, rab, resizeTo)); + }); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 4, + 6, + 0, + 0 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 6 * ctor.BYTES_PER_ELEMENT; + assert.throws(RangeError, () => { + lengthTrackingWithOffset.set(CreateSourceProxy(4, rab, resizeTo)); + }); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 4, + 6, + 0, + 0 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/set/target-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/set/target-shrink-mid-iteration.js new file mode 100644 index 0000000000..ba95c5bac9 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/set/target-shrink-mid-iteration.js @@ -0,0 +1,99 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.set +description: > + TypedArray.p.set behaves correctly on TypedArrays backed by resizable buffers + that are shrunk mid-iteration due to a Proxy source. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +// Resizing will happen when we're calling Get for the `resizeAt`:th data +// element, but we haven't yet written it to the target. +function CreateSourceProxy(length, rab, resizeAt, resizeTo) { + let requestedIndices = []; + return new Proxy({}, { + get(target, prop, receiver) { + if (prop == 'length') { + return length; + } + requestedIndices.push(prop); + if (requestedIndices.length == resizeAt) { + rab.resize(resizeTo); + } + return true; // Can be converted to both BigInt and Number. + } + }); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + const resizeAt = 2; + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLength.set(CreateSourceProxy(4, rab, resizeAt, resizeTo)); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 1, + 2, + 4 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const resizeAt = 2; + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLengthWithOffset.set(CreateSourceProxy(2, rab, resizeAt, resizeTo)); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 1 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + const resizeAt = 2; + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + lengthTracking.set(CreateSourceProxy(2, rab, resizeAt, resizeTo)); + assert.compareArray(ToNumbers(lengthTracking), [ + 1, + 1, + 4 + ]); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 1, + 1, + 4 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const resizeAt = 2; + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.set(CreateSourceProxy(2, rab, resizeAt, resizeTo)); + assert.compareArray(ToNumbers(lengthTrackingWithOffset), [1]); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 1 + ]); +} + +// Length-tracking TA goes OOB because of the offset. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const resizeAt = 1; + const resizeTo = 1 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.set(CreateSourceProxy(2, rab, resizeAt, resizeTo)); + assert.compareArray(ToNumbers(new ctor(rab)), [0]); +} diff --git a/test/built-ins/TypedArray/prototype/set/target-shrink-source-length-getter.js b/test/built-ins/TypedArray/prototype/set/target-shrink-source-length-getter.js new file mode 100644 index 0000000000..f3e15e225e --- /dev/null +++ b/test/built-ins/TypedArray/prototype/set/target-shrink-source-length-getter.js @@ -0,0 +1,147 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.set +description: > + TypedArray.p.set behaves correctly on TypedArrays backed by resizable buffers + that are shrunk due to the source's length getter. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +function CreateSourceProxy(length, rab, resizeTo) { + return new Proxy({}, { + get(target, prop, receiver) { + if (prop == 'length') { + rab.resize(resizeTo); + return length; + } + return true; // Can be converted to both BigInt and Number. + } + }); +} + +// Tests where the length getter returns a non-zero value -> these are nop if +// the TA went OOB. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLength.set(CreateSourceProxy(1, rab, resizeTo)); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 4 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLengthWithOffset.set(CreateSourceProxy(1, rab, resizeTo)); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 4 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + lengthTracking.set(CreateSourceProxy(1, rab, resizeTo)); + assert.compareArray(ToNumbers(lengthTracking), [ + 1, + 2, + 4 + ]); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 1, + 2, + 4 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.set(CreateSourceProxy(1, rab, resizeTo)); + assert.compareArray(ToNumbers(lengthTrackingWithOffset), [1]); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 1 + ]); +} + +// Length-tracking TA goes OOB because of the offset. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 1 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.set(CreateSourceProxy(1, rab, resizeTo)); + assert.compareArray(ToNumbers(new ctor(rab)), [0]); +} + +// Tests where the length getter returns a zero -> these don't throw even if +// the TA went OOB. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLength.set(CreateSourceProxy(0, rab, resizeTo)); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 4 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + fixedLengthWithOffset.set(CreateSourceProxy(0, rab, resizeTo)); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 4 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + lengthTracking.set(CreateSourceProxy(0, rab, resizeTo)); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 4 + ]); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.set(CreateSourceProxy(0, rab, resizeTo)); + assert.compareArray(ToNumbers(new ctor(rab)), [ + 0, + 2, + 4 + ]); +} + +// Length-tracking TA goes OOB because of the offset. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 1 * ctor.BYTES_PER_ELEMENT; + lengthTrackingWithOffset.set(CreateSourceProxy(0, rab, resizeTo)); + assert.compareArray(ToNumbers(new ctor(rab)), [0]); +} diff --git a/test/built-ins/TypedArray/prototype/set/this-backed-by-resizable-buffer.js b/test/built-ins/TypedArray/prototype/set/this-backed-by-resizable-buffer.js new file mode 100644 index 0000000000..e35300c95e --- /dev/null +++ b/test/built-ins/TypedArray/prototype/set/this-backed-by-resizable-buffer.js @@ -0,0 +1,525 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.set +description: > + TypedArray.p.set behaves correctly on TypedArrays backed by resizable buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function SetNumOrBigInt(target, source, offset) { + if (target instanceof BigInt64Array || target instanceof BigUint64Array) { + const bigIntSource = []; + for (const s of source) { + bigIntSource.push(BigInt(s)); + } + source = bigIntSource; + } + if (offset == undefined) { + return target.set(source); + } + return target.set(source, offset); +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taFull = new ctor(rab); + + // Orig. array: [0, 0, 0, 0] + // [0, 0, 0, 0] << fixedLength + // [0, 0] << fixedLengthWithOffset + // [0, 0, 0, 0, ...] << lengthTracking + // [0, 0, ...] << lengthTrackingWithOffset + + // For making sure we're not calling the source length or element getters + // if the target is OOB. + const throwingProxy = new Proxy({}, { + get(target, prop, receiver) { + throw new Error('Called getter for ' + prop); + } + }); + SetNumOrBigInt(fixedLength, [ + 1, + 2 + ]); + assert.compareArray(ToNumbers(taFull), [ + 1, + 2, + 0, + 0 + ]); + SetNumOrBigInt(fixedLength, [ + 3, + 4 + ], 1); + assert.compareArray(ToNumbers(taFull), [ + 1, + 3, + 4, + 0 + ]); + assert.throws(RangeError, () => { + SetNumOrBigInt(fixedLength, [ + 0, + 0, + 0, + 0, + 0 + ]); + }); + assert.throws(RangeError, () => { + SetNumOrBigInt(fixedLength, [ + 0, + 0, + 0, + 0 + ], 1); + }); + assert.compareArray(ToNumbers(taFull), [ + 1, + 3, + 4, + 0 + ]); + SetNumOrBigInt(fixedLengthWithOffset, [ + 5, + 6 + ]); + assert.compareArray(ToNumbers(taFull), [ + 1, + 3, + 5, + 6 + ]); + SetNumOrBigInt(fixedLengthWithOffset, [7], 1); + assert.compareArray(ToNumbers(taFull), [ + 1, + 3, + 5, + 7 + ]); + assert.throws(RangeError, () => { + SetNumOrBigInt(fixedLengthWithOffset, [ + 0, + 0, + 0 + ]); + }); + assert.throws(RangeError, () => { + SetNumOrBigInt(fixedLengthWithOffset, [ + 0, + 0 + ], 1); + }); + assert.compareArray(ToNumbers(taFull), [ + 1, + 3, + 5, + 7 + ]); + SetNumOrBigInt(lengthTracking, [ + 8, + 9 + ]); + assert.compareArray(ToNumbers(taFull), [ + 8, + 9, + 5, + 7 + ]); + SetNumOrBigInt(lengthTracking, [ + 10, + 11 + ], 1); + assert.compareArray(ToNumbers(taFull), [ + 8, + 10, + 11, + 7 + ]); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTracking, [ + 0, + 0, + 0, + 0, + 0 + ]); + }); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTracking, [ + 0, + 0, + 0, + 0 + ], 1); + }); + assert.compareArray(ToNumbers(taFull), [ + 8, + 10, + 11, + 7 + ]); + SetNumOrBigInt(lengthTrackingWithOffset, [ + 12, + 13 + ]); + assert.compareArray(ToNumbers(taFull), [ + 8, + 10, + 12, + 13 + ]); + SetNumOrBigInt(lengthTrackingWithOffset, [14], 1); + assert.compareArray(ToNumbers(taFull), [ + 8, + 10, + 12, + 14 + ]); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTrackingWithOffset, [ + 0, + 0, + 0 + ]); + }); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTrackingWithOffset, [ + 0, + 0 + ], 1); + }); + assert.compareArray(ToNumbers(taFull), [ + 8, + 10, + 12, + 14 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [8, 10, 12] + // [8, 10, 12, ...] << lengthTracking + // [12, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + SetNumOrBigInt(fixedLength, throwingProxy); + }); + assert.throws(TypeError, () => { + SetNumOrBigInt(fixedLengthWithOffset, throwingProxy); + }); + assert.compareArray(ToNumbers(taFull), [ + 8, + 10, + 12 + ]); + SetNumOrBigInt(lengthTracking, [ + 15, + 16 + ]); + assert.compareArray(ToNumbers(taFull), [ + 15, + 16, + 12 + ]); + SetNumOrBigInt(lengthTracking, [ + 17, + 18 + ], 1); + assert.compareArray(ToNumbers(taFull), [ + 15, + 17, + 18 + ]); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTracking, [ + 0, + 0, + 0, + 0 + ]); + }); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTracking, [ + 0, + 0, + 0 + ], 1); + }); + assert.compareArray(ToNumbers(taFull), [ + 15, + 17, + 18 + ]); + SetNumOrBigInt(lengthTrackingWithOffset, [19]); + assert.compareArray(ToNumbers(taFull), [ + 15, + 17, + 19 + ]); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTrackingWithOffset, [ + 0, + 0 + ]); + }); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTrackingWithOffset, [0], 1); + }); + assert.compareArray(ToNumbers(taFull), [ + 15, + 17, + 19 + ]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + SetNumOrBigInt(fixedLength, throwingProxy); + }); + assert.throws(TypeError, () => { + SetNumOrBigInt(fixedLengthWithOffset, throwingProxy); + }); + assert.throws(TypeError, () => { + SetNumOrBigInt(lengthTrackingWithOffset, throwingProxy); + }); + assert.compareArray(ToNumbers(taFull), [15]); + SetNumOrBigInt(lengthTracking, [20]); + assert.compareArray(ToNumbers(taFull), [20]); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + SetNumOrBigInt(fixedLength, throwingProxy); + }); + assert.throws(TypeError, () => { + SetNumOrBigInt(fixedLengthWithOffset, throwingProxy); + }); + assert.throws(TypeError, () => { + SetNumOrBigInt(lengthTrackingWithOffset, throwingProxy); + }); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTracking, [0]); + }); + assert.compareArray(ToNumbers(taFull), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 0, 0, 0, 0, 0] + // [0, 0, 0, 0] << fixedLength + // [0, 0] << fixedLengthWithOffset + // [0, 0, 0, 0, 0, 0, ...] << lengthTracking + // [0, 0, 0, 0, ...] << lengthTrackingWithOffset + SetNumOrBigInt(fixedLength, [ + 21, + 22 + ]); + assert.compareArray(ToNumbers(taFull), [ + 21, + 22, + 0, + 0, + 0, + 0 + ]); + SetNumOrBigInt(fixedLength, [ + 23, + 24 + ], 1); + assert.compareArray(ToNumbers(taFull), [ + 21, + 23, + 24, + 0, + 0, + 0 + ]); + assert.throws(RangeError, () => { + SetNumOrBigInt(fixedLength, [ + 0, + 0, + 0, + 0, + 0 + ]); + }); + assert.throws(RangeError, () => { + SetNumOrBigInt(fixedLength, [ + 0, + 0, + 0, + 0 + ], 1); + }); + assert.compareArray(ToNumbers(taFull), [ + 21, + 23, + 24, + 0, + 0, + 0 + ]); + SetNumOrBigInt(fixedLengthWithOffset, [ + 25, + 26 + ]); + assert.compareArray(ToNumbers(taFull), [ + 21, + 23, + 25, + 26, + 0, + 0 + ]); + SetNumOrBigInt(fixedLengthWithOffset, [27], 1); + assert.compareArray(ToNumbers(taFull), [ + 21, + 23, + 25, + 27, + 0, + 0 + ]); + assert.throws(RangeError, () => { + SetNumOrBigInt(fixedLengthWithOffset, [ + 0, + 0, + 0 + ]); + }); + assert.throws(RangeError, () => { + SetNumOrBigInt(fixedLengthWithOffset, [ + 0, + 0 + ], 1); + }); + assert.compareArray(ToNumbers(taFull), [ + 21, + 23, + 25, + 27, + 0, + 0 + ]); + SetNumOrBigInt(lengthTracking, [ + 28, + 29, + 30, + 31, + 32, + 33 + ]); + assert.compareArray(ToNumbers(taFull), [ + 28, + 29, + 30, + 31, + 32, + 33 + ]); + SetNumOrBigInt(lengthTracking, [ + 34, + 35, + 36, + 37, + 38 + ], 1); + assert.compareArray(ToNumbers(taFull), [ + 28, + 34, + 35, + 36, + 37, + 38 + ]); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTracking, [ + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ]); + }); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTracking, [ + 0, + 0, + 0, + 0, + 0, + 0 + ], 1); + }); + assert.compareArray(ToNumbers(taFull), [ + 28, + 34, + 35, + 36, + 37, + 38 + ]); + SetNumOrBigInt(lengthTrackingWithOffset, [ + 39, + 40, + 41, + 42 + ]); + assert.compareArray(ToNumbers(taFull), [ + 28, + 34, + 39, + 40, + 41, + 42 + ]); + SetNumOrBigInt(lengthTrackingWithOffset, [ + 43, + 44, + 45 + ], 1); + assert.compareArray(ToNumbers(taFull), [ + 28, + 34, + 39, + 43, + 44, + 45 + ]); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTrackingWithOffset, [ + 0, + 0, + 0, + 0, + 0 + ]); + }); + assert.throws(RangeError, () => { + SetNumOrBigInt(lengthTrackingWithOffset, [ + 0, + 0, + 0, + 0 + ], 1); + }); + assert.compareArray(ToNumbers(taFull), [ + 28, + 34, + 39, + 43, + 44, + 45 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/set/typedarray-arg-src-backed-by-resizable-buffer.js b/test/built-ins/TypedArray/prototype/set/typedarray-arg-src-backed-by-resizable-buffer.js new file mode 100644 index 0000000000..79aba4fb70 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/set/typedarray-arg-src-backed-by-resizable-buffer.js @@ -0,0 +1,229 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.set +description: > + TypedArray.p.set behaves correctly on TypedArrays backed by resizable buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function IsBigIntTypedArray(ta) { + return ta instanceof BigInt64Array || ta instanceof BigUint64Array; +} + +function SetNumOrBigInt(target, source, offset) { + if (IsBigIntTypedArray(target)) { + const bigIntSource = []; + for (const s of source) { + bigIntSource.push(BigInt(s)); + } + source = bigIntSource; + } + if (offset == undefined) { + return target.set(source); + } + return target.set(source, offset); +} + +for (let targetIsResizable of [ + false, + true + ]) { + for (let targetCtor of ctors) { + for (let sourceCtor of ctors) { + const rab = CreateResizableArrayBuffer(4 * sourceCtor.BYTES_PER_ELEMENT, 8 * sourceCtor.BYTES_PER_ELEMENT); + const fixedLength = new sourceCtor(rab, 0, 4); + const fixedLengthWithOffset = new sourceCtor(rab, 2 * sourceCtor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new sourceCtor(rab, 0); + const lengthTrackingWithOffset = new sourceCtor(rab, 2 * sourceCtor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taFull = new sourceCtor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taFull, i, i + 1); + } + + // Orig. array: [1, 2, 3, 4] + // [1, 2, 3, 4] << fixedLength + // [3, 4] << fixedLengthWithOffset + // [1, 2, 3, 4, ...] << lengthTracking + // [3, 4, ...] << lengthTrackingWithOffset + + const targetAb = targetIsResizable ? new ArrayBuffer(6 * targetCtor.BYTES_PER_ELEMENT) : new ArrayBuffer(6 * targetCtor.BYTES_PER_ELEMENT, { maxByteLength: 8 * targetCtor.BYTES_PER_ELEMENT }); + const target = new targetCtor(targetAb); + if (IsBigIntTypedArray(target) != IsBigIntTypedArray(taFull)) { + // Can't mix BigInt and non-BigInt types. + continue; + } + SetNumOrBigInt(target, fixedLength); + assert.compareArray(ToNumbers(target), [ + 1, + 2, + 3, + 4, + 0, + 0 + ]); + SetNumOrBigInt(target, fixedLengthWithOffset); + assert.compareArray(ToNumbers(target), [ + 3, + 4, + 3, + 4, + 0, + 0 + ]); + SetNumOrBigInt(target, lengthTracking, 1); + assert.compareArray(ToNumbers(target), [ + 3, + 1, + 2, + 3, + 4, + 0 + ]); + SetNumOrBigInt(target, lengthTrackingWithOffset, 1); + assert.compareArray(ToNumbers(target), [ + 3, + 3, + 4, + 3, + 4, + 0 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * sourceCtor.BYTES_PER_ELEMENT); + + // Orig. array: [1, 2, 3] + // [1, 2, 3, ...] << lengthTracking + // [3, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + SetNumOrBigInt(target, fixedLength); + }); + assert.throws(TypeError, () => { + SetNumOrBigInt(target, fixedLengthWithOffset); + }); + assert.compareArray(ToNumbers(target), [ + 3, + 3, + 4, + 3, + 4, + 0 + ]); + SetNumOrBigInt(target, lengthTracking); + assert.compareArray(ToNumbers(target), [ + 1, + 2, + 3, + 3, + 4, + 0 + ]); + SetNumOrBigInt(target, lengthTrackingWithOffset); + assert.compareArray(ToNumbers(target), [ + 3, + 2, + 3, + 3, + 4, + 0 + ]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * sourceCtor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + SetNumOrBigInt(target, fixedLength); + }); + assert.throws(TypeError, () => { + SetNumOrBigInt(target, fixedLengthWithOffset); + }); + assert.throws(TypeError, () => { + SetNumOrBigInt(target, lengthTrackingWithOffset); + }); + SetNumOrBigInt(target, lengthTracking, 3); + assert.compareArray(ToNumbers(target), [ + 3, + 2, + 3, + 1, + 4, + 0 + ]); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + SetNumOrBigInt(target, fixedLength); + }); + assert.throws(TypeError, () => { + SetNumOrBigInt(target, fixedLengthWithOffset); + }); + assert.throws(TypeError, () => { + SetNumOrBigInt(target, lengthTrackingWithOffset); + }); + SetNumOrBigInt(target, lengthTracking, 4); + assert.compareArray(ToNumbers(target), [ + 3, + 2, + 3, + 1, + 4, + 0 + ]); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * sourceCtor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taFull, i, i + 1); + } + + // Orig. array: [1, 2, 3, 4, 5, 6] + // [1, 2, 3, 4] << fixedLength + // [3, 4] << fixedLengthWithOffset + // [1, 2, 3, 4, 5, 6, ...] << lengthTracking + // [3, 4, 5, 6, ...] << lengthTrackingWithOffset + + SetNumOrBigInt(target, fixedLength); + assert.compareArray(ToNumbers(target), [ + 1, + 2, + 3, + 4, + 4, + 0 + ]); + SetNumOrBigInt(target, fixedLengthWithOffset); + assert.compareArray(ToNumbers(target), [ + 3, + 4, + 3, + 4, + 4, + 0 + ]); + SetNumOrBigInt(target, lengthTracking, 0); + assert.compareArray(ToNumbers(target), [ + 1, + 2, + 3, + 4, + 5, + 6 + ]); + SetNumOrBigInt(target, lengthTrackingWithOffset, 1); + assert.compareArray(ToNumbers(target), [ + 1, + 3, + 4, + 5, + 6, + 6 + ]); + } + } +} From ef72bd1c4450258049bb0521037aa629f274869a Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Tue, 6 Aug 2024 02:22:10 +0200 Subject: [PATCH 60/90] RAB: Integrate staging tests for the .sort method (#4176) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while applying review changes from PRs for previously tested methods. * Renamed test files * Some minor documentation fixes and removing onlyStrict flag --- .../Array/prototype/sort/comparefn-grow.js | 69 ++++++ .../sort/comparefn-resizable-buffer.js | 191 ++++++++++++++++ .../Array/prototype/sort/comparefn-shrink.js | 71 ++++++ .../resizable-buffer-default-comparator.js | 173 +++++++++++++++ .../prototype/sort/comparefn-grow.js | 71 ++++++ .../sort/comparefn-resizable-buffer.js | 206 ++++++++++++++++++ .../prototype/sort/comparefn-shrink.js | 73 +++++++ .../resizable-buffer-default-comparator.js | 182 ++++++++++++++++ 8 files changed, 1036 insertions(+) create mode 100644 test/built-ins/Array/prototype/sort/comparefn-grow.js create mode 100644 test/built-ins/Array/prototype/sort/comparefn-resizable-buffer.js create mode 100644 test/built-ins/Array/prototype/sort/comparefn-shrink.js create mode 100644 test/built-ins/Array/prototype/sort/resizable-buffer-default-comparator.js create mode 100644 test/built-ins/TypedArray/prototype/sort/comparefn-grow.js create mode 100644 test/built-ins/TypedArray/prototype/sort/comparefn-resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/sort/comparefn-shrink.js create mode 100644 test/built-ins/TypedArray/prototype/sort/resizable-buffer-default-comparator.js diff --git a/test/built-ins/Array/prototype/sort/comparefn-grow.js b/test/built-ins/Array/prototype/sort/comparefn-grow.js new file mode 100644 index 0000000000..640cdda2ae --- /dev/null +++ b/test/built-ins/Array/prototype/sort/comparefn-grow.js @@ -0,0 +1,69 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.sort +description: > + Array.p.sort behaves correctly on TypedArrays backed by resizable buffers which + are grown by the comparison callback. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function ResizeAndCompare(rab, resizeTo) { + return (a, b) => { + rab.resize(resizeTo); + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; + } +} + +function WriteUnsortedData(taFull) { + for (let i = 0; i < taFull.length; ++i) { + WriteToTypedArray(taFull, i, 10 - i); + } +} + +// Fixed length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 6 * ctor.BYTES_PER_ELEMENT; + const fixedLength = new ctor(rab, 0, 4); + const taFull = new ctor(rab, 0); + WriteUnsortedData(taFull); + Array.prototype.sort.call(fixedLength, ResizeAndCompare(rab, resizeTo)); + // Growing doesn't affect the sorting. + assert.compareArray(ToNumbers(taFull), [ + 7, + 8, + 9, + 10, + 0, + 0 + ]); +} + +// Length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 6 * ctor.BYTES_PER_ELEMENT; + const lengthTracking = new ctor(rab, 0); + const taFull = new ctor(rab, 0); + WriteUnsortedData(taFull); + Array.prototype.sort.call(lengthTracking, ResizeAndCompare(rab, resizeTo)); + // Growing doesn't affect the sorting. Only the elements that were part of + // the original TA are sorted. + assert.compareArray(ToNumbers(taFull), [ + 7, + 8, + 9, + 10, + 0, + 0 + ]); +} diff --git a/test/built-ins/Array/prototype/sort/comparefn-resizable-buffer.js b/test/built-ins/Array/prototype/sort/comparefn-resizable-buffer.js new file mode 100644 index 0000000000..b575811e80 --- /dev/null +++ b/test/built-ins/Array/prototype/sort/comparefn-resizable-buffer.js @@ -0,0 +1,191 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.sort +description: > + Array.p.sort behaves correctly on TypedArrays backed by resizable buffers and + is passed a user-provided comparison callback. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taFull = new ctor(rab, 0); + function WriteUnsortedData() { + // Write some data into the array. + for (let i = 0; i < taFull.length; ++i) { + WriteToTypedArray(taFull, i, 10 - i); + } + } + function OddBeforeEvenComparison(a, b) { + // Sort all odd numbers before even numbers. + a = Number(a); + b = Number(b); + if (a % 2 == 1 && b % 2 == 0) { + return -1; + } + if (a % 2 == 0 && b % 2 == 1) { + return 1; + } + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; + } + // Orig. array: [10, 9, 8, 7] + // [10, 9, 8, 7] << fixedLength + // [8, 7] << fixedLengthWithOffset + // [10, 9, 8, 7, ...] << lengthTracking + // [8, 7, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + Array.prototype.sort.call(fixedLength, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 7, + 9, + 8, + 10 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(fixedLengthWithOffset, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 7, + 8 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(lengthTracking, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 7, + 9, + 8, + 10 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(lengthTrackingWithOffset, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 7, + 8 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [10, 9, 8] + // [10, 9, 8, ...] << lengthTracking + // [8, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + Array.prototype.sort.call(fixedLength, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 8 + ]); + Array.prototype.sort.call(fixedLengthWithOffset, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 8 + ]); + + WriteUnsortedData(); + Array.prototype.sort.call(lengthTracking, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 9, + 8, + 10 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(lengthTrackingWithOffset, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 8 + ]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + WriteUnsortedData(); + Array.prototype.sort.call(fixedLength, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [10]); + Array.prototype.sort.call(fixedLengthWithOffset, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [10]); + Array.prototype.sort.call(lengthTrackingWithOffset, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [10]); + + WriteUnsortedData(); + Array.prototype.sort.call(lengthTracking, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [10]); + + // Shrink to zero. + rab.resize(0); + Array.prototype.sort.call(fixedLength, OddBeforeEvenComparison); + Array.prototype.sort.call(fixedLengthWithOffset, OddBeforeEvenComparison); + Array.prototype.sort.call(lengthTrackingWithOffset, OddBeforeEvenComparison); + + Array.prototype.sort.call(lengthTracking, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [10, 9, 8, 7, 6, 5] + // [10, 9, 8, 7] << fixedLength + // [8, 7] << fixedLengthWithOffset + // [10, 9, 8, 7, 6, 5, ...] << lengthTracking + // [8, 7, 6, 5, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + Array.prototype.sort.call(fixedLength, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 7, + 9, + 8, + 10, + 6, + 5 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(fixedLengthWithOffset, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 7, + 8, + 6, + 5 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(lengthTracking, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 5, + 7, + 9, + 6, + 8, + 10 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(lengthTrackingWithOffset, OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 5, + 7, + 6, + 8 + ]); +} diff --git a/test/built-ins/Array/prototype/sort/comparefn-shrink.js b/test/built-ins/Array/prototype/sort/comparefn-shrink.js new file mode 100644 index 0000000000..c9c26f01c6 --- /dev/null +++ b/test/built-ins/Array/prototype/sort/comparefn-shrink.js @@ -0,0 +1,71 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.sort +description: > + Array.p.sort behaves correctly on TypedArrays backed by resizable buffers and + is shrunk by the comparison callback. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer, Array.prototype.includes] +---*/ + +function ResizeAndCompare(rab, resizeTo) { + return (a, b) => { + rab.resize(resizeTo); + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; + } +} + +function WriteUnsortedData(taFull) { + for (let i = 0; i < taFull.length; ++i) { + WriteToTypedArray(taFull, i, 10 - i); + } +} + +// Fixed length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 2 * ctor.BYTES_PER_ELEMENT; + const fixedLength = new ctor(rab, 0, 4); + const taFull = new ctor(rab, 0); + WriteUnsortedData(taFull); + Array.prototype.sort.call(fixedLength, ResizeAndCompare(rab, resizeTo)); + // The data is unchanged. + assert.compareArray(ToNumbers(taFull), [ + 10, + 9 + ]); +} + +// Length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 2 * ctor.BYTES_PER_ELEMENT; + const lengthTracking = new ctor(rab, 0); + const taFull = new ctor(rab, 0); + WriteUnsortedData(taFull); + Array.prototype.sort.call(lengthTracking, ResizeAndCompare(rab, resizeTo)); + // The sort result is implementation defined, but it contains 2 elements out + // of the 4 original ones. + const newData = ToNumbers(taFull); + assert.sameValue(newData.length, 2); + assert([ + 10, + 9, + 8, + 7 + ].includes(newData[0])); + assert([ + 10, + 9, + 8, + 7 + ].includes(newData[1])); +} diff --git a/test/built-ins/Array/prototype/sort/resizable-buffer-default-comparator.js b/test/built-ins/Array/prototype/sort/resizable-buffer-default-comparator.js new file mode 100644 index 0000000000..38b1c065da --- /dev/null +++ b/test/built-ins/Array/prototype/sort/resizable-buffer-default-comparator.js @@ -0,0 +1,173 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.sort +description: > + Array.p.sort behaves correctly on TypedArrays backed by resizable buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] + +---*/ + +// The default comparison function for Array.prototype.sort is the string sort. + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taFull = new ctor(rab, 0); + function WriteUnsortedData() { + // Write some data into the array. + for (let i = 0; i < taFull.length; ++i) { + WriteToTypedArray(taFull, i, 10 - 2 * i); + } + } + // Orig. array: [10, 8, 6, 4] + // [10, 8, 6, 4] << fixedLength + // [6, 4] << fixedLengthWithOffset + // [10, 8, 6, 4, ...] << lengthTracking + // [6, 4, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + Array.prototype.sort.call(fixedLength); + assert.compareArray(ToNumbers(taFull), [ + 10, + 4, + 6, + 8 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(fixedLengthWithOffset); + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 4, + 6 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(lengthTracking); + assert.compareArray(ToNumbers(taFull), [ + 10, + 4, + 6, + 8 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(lengthTrackingWithOffset); + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 4, + 6 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [10, 8, 6] + // [10, 8, 6, ...] << lengthTracking + // [6, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + Array.prototype.sort.call(fixedLength); // OOB -> NOOP + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 6 + ]); + Array.prototype.sort.call(fixedLengthWithOffset); // OOB -> NOOP + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 6 + ]); + Array.prototype.sort.call(lengthTracking); + assert.compareArray(ToNumbers(taFull), [ + 10, + 6, + 8 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(lengthTrackingWithOffset); + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 6 + ]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + WriteUnsortedData(); + Array.prototype.sort.call(fixedLength); // OOB -> NOOP + assert.compareArray(ToNumbers(taFull), [10]); + Array.prototype.sort.call(fixedLengthWithOffset); // OOB -> NOOP + assert.compareArray(ToNumbers(taFull), [10]); + Array.prototype.sort.call(lengthTrackingWithOffset); // OOB -> NOOP + assert.compareArray(ToNumbers(taFull), [10]); + Array.prototype.sort.call(lengthTracking); + assert.compareArray(ToNumbers(taFull), [10]); + + // Shrink to zero. + rab.resize(0); + Array.prototype.sort.call(fixedLength); // OOB -> NOOP + assert.compareArray(ToNumbers(taFull), []); + Array.prototype.sort.call(fixedLengthWithOffset); // OOB -> NOOP + assert.compareArray(ToNumbers(taFull), []); + Array.prototype.sort.call(lengthTrackingWithOffset); // OOB -> NOOP + assert.compareArray(ToNumbers(taFull), []); + Array.prototype.sort.call(lengthTracking); + assert.compareArray(ToNumbers(taFull), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [10, 8, 6, 4, 2, 0] + // [10, 8, 6, 4] << fixedLength + // [6, 4] << fixedLengthWithOffset + // [10, 8, 6, 4, 2, 0, ...] << lengthTracking + // [6, 4, 2, 0, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + Array.prototype.sort.call(fixedLength); + assert.compareArray(ToNumbers(taFull), [ + 10, + 4, + 6, + 8, + 2, + 0 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(fixedLengthWithOffset); + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 4, + 6, + 2, + 0 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(lengthTracking); + assert.compareArray(ToNumbers(taFull), [ + 0, + 10, + 2, + 4, + 6, + 8 + ]); + WriteUnsortedData(); + Array.prototype.sort.call(lengthTrackingWithOffset); + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 0, + 2, + 4, + 6 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/sort/comparefn-grow.js b/test/built-ins/TypedArray/prototype/sort/comparefn-grow.js new file mode 100644 index 0000000000..11f09bf467 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/sort/comparefn-grow.js @@ -0,0 +1,71 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.sort +description: > + TypedArray.p.sort behaves correctly on TypedArrays backed by resizable buffers + which are grown by the comparison callback. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Returns a function that resizes rab to size resizeTo and then compares its +// arguments. Such a result function is to be used as an argument to .sort. +function ResizeAndCompare(rab, resizeTo) { + return (a, b) => { + rab.resize(resizeTo); + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; + } +} + +function WriteUnsortedData(taFull) { + for (let i = 0; i < taFull.length; ++i) { + WriteToTypedArray(taFull, i, 10 - i); + } +} + +// Fixed length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 6 * ctor.BYTES_PER_ELEMENT; + const fixedLength = new ctor(rab, 0, 4); + const taFull = new ctor(rab, 0); + WriteUnsortedData(taFull); + fixedLength.sort(ResizeAndCompare(rab, resizeTo)); + // Growing doesn't affect the sorting. + assert.compareArray(ToNumbers(taFull), [ + 7, + 8, + 9, + 10, + 0, + 0 + ]); +} + +// Length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 6 * ctor.BYTES_PER_ELEMENT; + const lengthTracking = new ctor(rab, 0); + const taFull = new ctor(rab, 0); + WriteUnsortedData(taFull); + lengthTracking.sort(ResizeAndCompare(rab, resizeTo)); + // Growing doesn't affect the sorting. Only the elements that were part of + // the original TA are sorted. + assert.compareArray(ToNumbers(taFull), [ + 7, + 8, + 9, + 10, + 0, + 0 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/sort/comparefn-resizable-buffer.js b/test/built-ins/TypedArray/prototype/sort/comparefn-resizable-buffer.js new file mode 100644 index 0000000000..c3c8c93371 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/sort/comparefn-resizable-buffer.js @@ -0,0 +1,206 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.sort +description: > + TypedArray.p.sort behaves correctly on TypedArrays backed by resizable buffers + and passed a user-provided comparison callback. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taFull = new ctor(rab, 0); + function WriteUnsortedData() { + // Write some data into the array. + for (let i = 0; i < taFull.length; ++i) { + WriteToTypedArray(taFull, i, 10 - i); + } + } + function OddBeforeEvenComparison(a, b) { + // Sort all odd numbers before even numbers. + a = Number(a); + b = Number(b); + if (a % 2 == 1 && b % 2 == 0) { + return -1; + } + if (a % 2 == 0 && b % 2 == 1) { + return 1; + } + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; + } + // Orig. array: [10, 9, 8, 7] + // [10, 9, 8, 7] << fixedLength + // [8, 7] << fixedLengthWithOffset + // [10, 9, 8, 7, ...] << lengthTracking + // [8, 7, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + fixedLength.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 7, + 9, + 8, + 10 + ]); + WriteUnsortedData(); + fixedLengthWithOffset.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 7, + 8 + ]); + WriteUnsortedData(); + lengthTracking.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 7, + 9, + 8, + 10 + ]); + WriteUnsortedData(); + lengthTrackingWithOffset.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 7, + 8 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [10, 9, 8] + // [10, 9, 8, ...] << lengthTracking + // [8, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + assert.throws(TypeError, () => { + fixedLength.sort(OddBeforeEvenComparison); + }); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 8 + ]); + assert.throws(TypeError, () => { + fixedLengthWithOffset.sort(OddBeforeEvenComparison); + }); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 8 + ]); + WriteUnsortedData(); + lengthTracking.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 9, + 8, + 10 + ]); + WriteUnsortedData(); + lengthTrackingWithOffset.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 8 + ]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + WriteUnsortedData(); + assert.throws(TypeError, () => { + fixedLength.sort(OddBeforeEvenComparison); + }); + assert.compareArray(ToNumbers(taFull), [10]); + assert.throws(TypeError, () => { + fixedLengthWithOffset.sort(OddBeforeEvenComparison); + }); + assert.compareArray(ToNumbers(taFull), [10]); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.sort(OddBeforeEvenComparison); + }); + assert.compareArray(ToNumbers(taFull), [10]); + + WriteUnsortedData(); + lengthTracking.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [10]); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + fixedLength.sort(OddBeforeEvenComparison); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.sort(OddBeforeEvenComparison); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.sort(OddBeforeEvenComparison); + }); + + lengthTracking.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [10, 9, 8, 7, 6, 5] + // [10, 9, 8, 7] << fixedLength + // [8, 7] << fixedLengthWithOffset + // [10, 9, 8, 7, 6, 5, ...] << lengthTracking + // [8, 7, 6, 5, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + fixedLength.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 7, + 9, + 8, + 10, + 6, + 5 + ]); + WriteUnsortedData(); + fixedLengthWithOffset.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 7, + 8, + 6, + 5 + ]); + WriteUnsortedData(); + lengthTracking.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 5, + 7, + 9, + 6, + 8, + 10 + ]); + WriteUnsortedData(); + lengthTrackingWithOffset.sort(OddBeforeEvenComparison); + assert.compareArray(ToNumbers(taFull), [ + 10, + 9, + 5, + 7, + 6, + 8 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/sort/comparefn-shrink.js b/test/built-ins/TypedArray/prototype/sort/comparefn-shrink.js new file mode 100644 index 0000000000..b057179066 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/sort/comparefn-shrink.js @@ -0,0 +1,73 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.sort +description: > + TypedArray.p.sort behaves correctly on TypedArrays backed by a + resizable buffer and is shrunk by the comparison callback +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer, Array.prototype.includes] +---*/ + +// Returns a function that resizes rab to size resizeTo and then compares its +// arguments. Such a result function is to be used as an argument to .sort. +function ResizeAndCompare(rab, resizeTo) { + return (a, b) => { + rab.resize(resizeTo); + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; + } +} + +function WriteUnsortedData(taFull) { + for (let i = 0; i < taFull.length; ++i) { + WriteToTypedArray(taFull, i, 10 - i); + } +} + +// Fixed length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 2 * ctor.BYTES_PER_ELEMENT; + const fixedLength = new ctor(rab, 0, 4); + const taFull = new ctor(rab, 0); + WriteUnsortedData(taFull); + fixedLength.sort(ResizeAndCompare(rab, resizeTo)); + // The data is unchanged. + assert.compareArray(ToNumbers(taFull), [ + 10, + 9 + ]); +} + +// Length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const resizeTo = 2 * ctor.BYTES_PER_ELEMENT; + const lengthTracking = new ctor(rab, 0); + const taFull = new ctor(rab, 0); + WriteUnsortedData(taFull); + lengthTracking.sort(ResizeAndCompare(rab, resizeTo)); + // The sort result is implementation defined, but it contains 2 elements out + // of the 4 original ones. + const newData = ToNumbers(taFull); + assert.sameValue(newData.length, 2); + assert([ + 10, + 9, + 8, + 7 + ].includes(newData[0])); + assert([ + 10, + 9, + 8, + 7 + ].includes(newData[1])); +} diff --git a/test/built-ins/TypedArray/prototype/sort/resizable-buffer-default-comparator.js b/test/built-ins/TypedArray/prototype/sort/resizable-buffer-default-comparator.js new file mode 100644 index 0000000000..f3386199bd --- /dev/null +++ b/test/built-ins/TypedArray/prototype/sort/resizable-buffer-default-comparator.js @@ -0,0 +1,182 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.sort +description: > + TypedArray.p.sort behaves correctly on TypedArrays backed by resizable buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// This test cannot be reused between TypedArray.protoype.sort and +// Array.prototype.sort, since the default sorting functions differ. + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taFull = new ctor(rab, 0); + function WriteUnsortedData() { + // Write some data into the array. + for (let i = 0; i < taFull.length; ++i) { + WriteToTypedArray(taFull, i, 10 - 2 * i); + } + } + // Orig. array: [10, 8, 6, 4] + // [10, 8, 6, 4] << fixedLength + // [6, 4] << fixedLengthWithOffset + // [10, 8, 6, 4, ...] << lengthTracking + // [6, 4, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + fixedLength.sort(); + assert.compareArray(ToNumbers(taFull), [ + 4, + 6, + 8, + 10 + ]); + WriteUnsortedData(); + fixedLengthWithOffset.sort(); + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 4, + 6 + ]); + WriteUnsortedData(); + lengthTracking.sort(); + assert.compareArray(ToNumbers(taFull), [ + 4, + 6, + 8, + 10 + ]); + WriteUnsortedData(); + lengthTrackingWithOffset.sort(); + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 4, + 6 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [10, 8, 6] + // [10, 8, 6, ...] << lengthTracking + // [6, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + assert.throws(TypeError, () => { + fixedLength.sort(); + }); + WriteUnsortedData(); + assert.throws(TypeError, () => { + fixedLengthWithOffset.sort(); + }); + WriteUnsortedData(); + lengthTracking.sort(); + assert.compareArray(ToNumbers(taFull), [ + 6, + 8, + 10 + ]); + WriteUnsortedData(); + lengthTrackingWithOffset.sort(); + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 6 + ]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + WriteUnsortedData(); + assert.throws(TypeError, () => { + fixedLength.sort(); + }); + WriteUnsortedData(); + assert.throws(TypeError, () => { + fixedLengthWithOffset.sort(); + }); + WriteUnsortedData(); + lengthTracking.sort(); + assert.compareArray(ToNumbers(taFull), [10]); + WriteUnsortedData(); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.sort(); + }); + + // Shrink to zero. + rab.resize(0); + WriteUnsortedData(); + assert.throws(TypeError, () => { + fixedLength.sort(); + }); + WriteUnsortedData(); + assert.throws(TypeError, () => { + fixedLengthWithOffset.sort(); + }); + WriteUnsortedData(); + lengthTracking.sort(); + assert.compareArray(ToNumbers(taFull), []); + WriteUnsortedData(); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.sort(); + }); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [10, 8, 6, 4, 2, 0] + // [10, 8, 6, 4] << fixedLength + // [6, 4] << fixedLengthWithOffset + // [10, 8, 6, 4, 2, 0, ...] << lengthTracking + // [6, 4, 2, 0, ...] << lengthTrackingWithOffset + + WriteUnsortedData(); + fixedLength.sort(); + assert.compareArray(ToNumbers(taFull), [ + 4, + 6, + 8, + 10, + 2, + 0 + ]); + WriteUnsortedData(); + fixedLengthWithOffset.sort(); + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 4, + 6, + 2, + 0 + ]); + WriteUnsortedData(); + lengthTracking.sort(); + assert.compareArray(ToNumbers(taFull), [ + 0, + 2, + 4, + 6, + 8, + 10 + ]); + WriteUnsortedData(); + lengthTrackingWithOffset.sort(); + assert.compareArray(ToNumbers(taFull), [ + 10, + 8, + 0, + 2, + 4, + 6 + ]); +} From dc36c7eae9ea419d2ab007741318933ececee0f2 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Tue, 6 Aug 2024 02:26:21 +0200 Subject: [PATCH 61/90] RAB: Integrate staging tests for the .values method (#4179) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while applying review changes from PRs for previously tested methods. * Removes unnecessary .from calls, as suggested in previous PR review comment: https://github.com/tc39/test262/pull/4138#discussion_r1676183221 --- .../resizable-buffer-grow-mid-iteration.js | 60 +++++++ .../resizable-buffer-shrink-mid-iteration.js | 52 ++++++ .../prototype/values/resizable-buffer.js | 156 ++++++++++++++++++ .../resizable-buffer-grow-mid-iteration.js | 60 +++++++ .../resizable-buffer-shrink-mid-iteration.js | 52 ++++++ .../prototype/values/resizable-buffer.js | 149 +++++++++++++++++ 6 files changed, 529 insertions(+) create mode 100644 test/built-ins/Array/prototype/values/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/values/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/values/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/values/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/values/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/values/resizable-buffer.js diff --git a/test/built-ins/Array/prototype/values/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/values/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..0d1965f983 --- /dev/null +++ b/test/built-ins/Array/prototype/values/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,60 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.values +description: > + Array.p.values behaves correctly on TypedArrays backed by resizable buffers and + resized mid-iteration. +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + // The fixed length array is not affected by resizing. + TestIterationAndResize(Array.prototype.values.call(fixedLength), [ + 0, + 2, + 4, + 6 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + // The fixed length array is not affected by resizing. + TestIterationAndResize(Array.prototype.values.call(fixedLengthWithOffset), [ + 4, + 6 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + TestIterationAndResize(Array.prototype.values.call(lengthTracking), [ + 0, + 2, + 4, + 6, + 0, + 0 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + TestIterationAndResize(Array.prototype.values.call(lengthTrackingWithOffset), [ + 4, + 6, + 0, + 0 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/Array/prototype/values/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/Array/prototype/values/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..79fe5d4bf9 --- /dev/null +++ b/test/built-ins/Array/prototype/values/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,52 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.values +description: > + Array.p.values behaves correctly on TypedArrays backed by resizable buffers + that are shrunk mid-iteration. +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + + // The fixed length array goes out of bounds when the RAB is resized. + assert.throws(TypeError, () => { + TestIterationAndResize(Array.prototype.values.call(fixedLength), null, rab, 2, 3 * ctor.BYTES_PER_ELEMENT); + }); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + assert.throws(TypeError, () => { + TestIterationAndResize(Array.prototype.values.call(fixedLengthWithOffset), null, rab, 2, 3 * ctor.BYTES_PER_ELEMENT); + }); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + TestIterationAndResize(Array.prototype.values.call(lengthTracking), [ + 0, + 2, + 4 + ], rab, 2, 3 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // The fixed length array goes out of bounds when the RAB is resized. + TestIterationAndResize(Array.prototype.values.call(lengthTrackingWithOffset), [ + 4, + 6 + ], rab, 2, 3 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/Array/prototype/values/resizable-buffer.js b/test/built-ins/Array/prototype/values/resizable-buffer.js new file mode 100644 index 0000000000..c4b7f77868 --- /dev/null +++ b/test/built-ins/Array/prototype/values/resizable-buffer.js @@ -0,0 +1,156 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.values +description: > + Array.p.values behaves correctly on TypedArrays backed by resizable buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function IteratorToNumbers(iterator) { + const result = []; + for (let value of iterator) { + result.push(Number(value)); + } + return result; +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(fixedLength)), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(fixedLengthWithOffset)), [ + 4, + 6 + ]); + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(lengthTracking)), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(lengthTrackingWithOffset)), [ + 4, + 6 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + // TypedArray.prototype.{entries, keys, values} throw right away when + // called. Array.prototype.{entries, keys, values} don't throw, but when + // we try to iterate the returned ArrayIterator, that throws. + Array.prototype.values.call(fixedLength); + Array.prototype.values.call(fixedLengthWithOffset); + + assert.throws(TypeError, () => { + Array.from(Array.prototype.values.call(fixedLength)); + }); + assert.throws(TypeError, () => { + Array.from(Array.prototype.values.call(fixedLengthWithOffset)); + }); + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(lengthTracking)), [ + 0, + 2, + 4 + ]); + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(lengthTrackingWithOffset)), [4]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + Array.prototype.values.call(fixedLength); + Array.prototype.values.call(fixedLengthWithOffset); + Array.prototype.values.call(lengthTrackingWithOffset); + + assert.throws(TypeError, () => { + Array.from(Array.prototype.values.call(fixedLength)); + }); + assert.throws(TypeError, () => { + Array.from(Array.prototype.values.call(fixedLengthWithOffset)); + }); + assert.throws(TypeError, () => { + Array.from(Array.prototype.values.call(lengthTrackingWithOffset)); + }); + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(lengthTracking)), [0]); + + // Shrink to zero. + rab.resize(0); + Array.prototype.values.call(fixedLength); + Array.prototype.values.call(fixedLengthWithOffset); + Array.prototype.values.call(lengthTrackingWithOffset); + + assert.throws(TypeError, () => { + Array.from(Array.prototype.values.call(fixedLength)); + }); + assert.throws(TypeError, () => { + Array.from(Array.prototype.values.call(fixedLengthWithOffset)); + }); + assert.throws(TypeError, () => { + Array.from(Array.prototype.values.call(lengthTrackingWithOffset)); + }); + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(lengthTracking)), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(fixedLength)), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(fixedLengthWithOffset)), [ + 4, + 6 + ]); + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(lengthTracking)), [ + 0, + 2, + 4, + 6, + 8, + 10 + ]); + assert.compareArray(IteratorToNumbers(Array.prototype.values.call(lengthTrackingWithOffset)), [ + 4, + 6, + 8, + 10 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/values/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/values/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..3ea3141139 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/values/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,60 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.values +description: > + TypedArray.p.values behaves correctly on TypedArrays backed by resizable + buffers and resized mid-iteration. +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset + +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + // The fixed length array is not affected by resizing. + TestIterationAndResize(fixedLength.values(), [ + 0, + 2, + 4, + 6 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + // The fixed length array is not affected by resizing. + TestIterationAndResize(fixedLengthWithOffset.values(), [ + 4, + 6 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + TestIterationAndResize(lengthTracking.values(), [ + 0, + 2, + 4, + 6, + 0, + 0 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + TestIterationAndResize(lengthTrackingWithOffset.values(), [ + 4, + 6, + 0, + 0 + ], rab, 2, 6 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/TypedArray/prototype/values/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/values/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..4547734d1a --- /dev/null +++ b/test/built-ins/TypedArray/prototype/values/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,52 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.values +description: > + TypedArray.p.values behaves correctly on TypedArrays backed by resizable + buffers that are shrunk mid-iteration. +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + + // The fixed length array goes out of bounds when the RAB is resized. + assert.throws(TypeError, () => { + TestIterationAndResize(fixedLength.values(), null, rab, 2, 3 * ctor.BYTES_PER_ELEMENT); + }); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + assert.throws(TypeError, () => { + TestIterationAndResize(fixedLengthWithOffset.values(), null, rab, 2, 3 * ctor.BYTES_PER_ELEMENT); + }); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + TestIterationAndResize(lengthTracking.values(), [ + 0, + 2, + 4 + ], rab, 2, 3 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // The fixed length array goes out of bounds when the RAB is resized. + TestIterationAndResize(lengthTrackingWithOffset.values(), [ + 4, + 6 + ], rab, 2, 3 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/TypedArray/prototype/values/resizable-buffer.js b/test/built-ins/TypedArray/prototype/values/resizable-buffer.js new file mode 100644 index 0000000000..e7eb2347ac --- /dev/null +++ b/test/built-ins/TypedArray/prototype/values/resizable-buffer.js @@ -0,0 +1,149 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.values +description: > + TypedArray.p.values behaves correctly on TypedArrays backed by resizable + buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function IteratorToNumbers(iterator) { + let result = []; + for (let value of iterator) { + result.push(Number(value)); + } + return result; +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert.compareArray(IteratorToNumbers(fixedLength.values()), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(IteratorToNumbers(fixedLengthWithOffset.values()), [ + 4, + 6 + ]); + assert.compareArray(IteratorToNumbers(lengthTracking.values()), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(IteratorToNumbers(lengthTrackingWithOffset.values()), [ + 4, + 6 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + // TypedArray.prototype.{entries, keys, values} throw right away when + // called. Array.prototype.{entries, keys, values} don't throw, but when + // we try to iterate the returned ArrayIterator, that throws. + assert.throws(TypeError, () => { + fixedLength.values(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.values(); + }); + + assert.compareArray(IteratorToNumbers(lengthTracking.values()), [ + 0, + 2, + 4 + ]); + assert.compareArray(IteratorToNumbers(lengthTrackingWithOffset.values()), [4]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + fixedLength.values(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.values(); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.values(); + }); + + assert.compareArray(IteratorToNumbers(lengthTracking.values()), [0]); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + fixedLength.values(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.values(); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.values(); + }); + + assert.compareArray(IteratorToNumbers(lengthTracking.values()), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.compareArray(IteratorToNumbers(fixedLength.values()), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(IteratorToNumbers(fixedLengthWithOffset.values()), [ + 4, + 6 + ]); + assert.compareArray(IteratorToNumbers(lengthTracking.values()), [ + 0, + 2, + 4, + 6, + 8, + 10 + ]); + assert.compareArray(IteratorToNumbers(lengthTrackingWithOffset.values()), [ + 4, + 6, + 8, + 10 + ]); +} From 5dc04b733275cf64e3022867359e27bc99d9262c Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Tue, 30 Jul 2024 13:08:18 +0300 Subject: [PATCH 62/90] Fix TypedArray.reduce tests against RAB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * reduce callback has call signature «accumulator, kValue, 𝔽(k), O » --- .../prototype/reduce/resizable-buffer-grow-mid-iteration.js | 2 +- .../prototype/reduce/resizable-buffer-shrink-mid-iteration.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-grow-mid-iteration.js index 46b7beeb2b..d5aec2c57a 100644 --- a/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-grow-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-grow-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset // before calling this. -function ResizeMidIteration(n) { +function ResizeMidIteration(acc, n) { // Returns true by default. return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); } diff --git a/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-shrink-mid-iteration.js index e9de100daa..0838d691b7 100644 --- a/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-shrink-mid-iteration.js +++ b/test/built-ins/TypedArray/prototype/reduce/resizable-buffer-shrink-mid-iteration.js @@ -19,7 +19,7 @@ let resizeTo; // resizeTo. To be called by a method of the view being collected. // Note that rab, values, resizeAfter, and resizeTo may need to be reset // before calling this. -function ResizeMidIteration(n) { +function ResizeMidIteration(acc, n) { return CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); } From bcb42e339dbac06f2f9902046b1fbf62562e0cd3 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Fri, 9 Aug 2024 18:05:04 +0200 Subject: [PATCH 63/90] RAB: Integrate staging tests for the .some method (#4175) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while applying review changes from PRs for previously tested methods. * Address review comments. --- .../resizable-buffer-grow-mid-iteration.js | 84 +++++++++++++ .../resizable-buffer-shrink-mid-iteration.js | 74 +++++++++++ .../Array/prototype/some/resizable-buffer.js | 99 +++++++++++++++ .../resizable-buffer-grow-mid-iteration.js | 84 +++++++++++++ .../resizable-buffer-shrink-mid-iteration.js | 83 +++++++++++++ .../prototype/some/resizable-buffer.js | 115 ++++++++++++++++++ 6 files changed, 539 insertions(+) create mode 100644 test/built-ins/Array/prototype/some/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/some/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/Array/prototype/some/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/some/resizable-buffer-grow-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/some/resizable-buffer-shrink-mid-iteration.js create mode 100644 test/built-ins/TypedArray/prototype/some/resizable-buffer.js diff --git a/test/built-ins/Array/prototype/some/resizable-buffer-grow-mid-iteration.js b/test/built-ins/Array/prototype/some/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..cb653c938e --- /dev/null +++ b/test/built-ins/Array/prototype/some/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,84 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.some +description: > + Array.p.some behaves correctly on TypedArrays backed by resizable buffers that + are grown mid-iteration. +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset +// before calling this. +function ResizeMidIteration(n) { + CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); + return false; +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + values = []; + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + assert(!Array.prototype.some.call(fixedLength, ResizeMidIteration)); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + values = []; + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + assert(!Array.prototype.some.call(fixedLengthWithOffset, ResizeMidIteration)); + assert.compareArray(values, [ + 4, + 6 + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + values = []; + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + assert(!Array.prototype.some.call(lengthTracking, ResizeMidIteration)); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + values = []; + rab = rab; + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + assert(!Array.prototype.some.call(lengthTrackingWithOffset, ResizeMidIteration)); + assert.compareArray(values, [ + 4, + 6 + ]); +} diff --git a/test/built-ins/Array/prototype/some/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/Array/prototype/some/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..3619404e44 --- /dev/null +++ b/test/built-ins/Array/prototype/some/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,74 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.some +description: > + Array.p.some behaves correctly on TypedArrays backed by resizable buffers that + are shrunk mid-iteration. +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Collects the view of the resizable array buffer rab into values, with an +// iteration during which, after resizeAfter steps, rab is resized to length +// resizeTo. To be called by a method of the view being collected. +// Note that rab, values, resizeAfter, and resizeTo may need to be reset +// before calling this. +function ResizeMidIteration(n) { + CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); + return false; +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + values = []; + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert(!Array.prototype.some.call(fixedLength, ResizeMidIteration)); + assert.compareArray(values, [ + 0, + 2 + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + values = []; + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert(!Array.prototype.some.call(fixedLengthWithOffset, ResizeMidIteration)); + assert.compareArray(values, [4]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + values = []; + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert(!Array.prototype.some.call(lengthTracking, ResizeMidIteration)); + assert.compareArray(values, [ + 0, + 2, + 4 + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + values = []; + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert(!Array.prototype.some.call(lengthTrackingWithOffset, ResizeMidIteration)); + assert.compareArray(values, [4]); +} diff --git a/test/built-ins/Array/prototype/some/resizable-buffer.js b/test/built-ins/Array/prototype/some/resizable-buffer.js new file mode 100644 index 0000000000..0bd06bc97e --- /dev/null +++ b/test/built-ins/Array/prototype/some/resizable-buffer.js @@ -0,0 +1,99 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.some +description: > + Array.p.some behaves correctly on TypedArrays backed by resizable buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + function div3(n) { + return Number(n) % 3 == 0; + } + function over10(n) { + return Number(n) > 10; + } + assert(Array.prototype.some.call(fixedLength, div3)); + assert(!Array.prototype.some.call(fixedLength, over10)); + assert(Array.prototype.some.call(fixedLengthWithOffset, div3)); + assert(!Array.prototype.some.call(fixedLengthWithOffset, over10)); + assert(Array.prototype.some.call(lengthTracking, div3)); + assert(!Array.prototype.some.call(lengthTracking, over10)); + assert(Array.prototype.some.call(lengthTrackingWithOffset, div3)); + assert(!Array.prototype.some.call(lengthTrackingWithOffset, over10)); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert(!Array.prototype.some.call(fixedLength, div3)); + assert(!Array.prototype.some.call(fixedLengthWithOffset, div3)); + + assert(Array.prototype.some.call(lengthTracking, div3)); + assert(!Array.prototype.some.call(lengthTracking, over10)); + assert(!Array.prototype.some.call(lengthTrackingWithOffset, div3)); + assert(!Array.prototype.some.call(lengthTrackingWithOffset, over10)); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert(!Array.prototype.some.call(fixedLength, div3)); + assert(!Array.prototype.some.call(fixedLengthWithOffset, div3)); + assert(!Array.prototype.some.call(lengthTrackingWithOffset, div3)); + + assert(Array.prototype.some.call(lengthTracking, div3)); + assert(!Array.prototype.some.call(lengthTracking, over10)); + + // Shrink to zero. + rab.resize(0); + assert(!Array.prototype.some.call(fixedLength, div3)); + assert(!Array.prototype.some.call(fixedLengthWithOffset, div3)); + assert(!Array.prototype.some.call(lengthTrackingWithOffset, div3)); + + assert(!Array.prototype.some.call(lengthTracking, div3)); + assert(!Array.prototype.some.call(lengthTracking, over10)); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert(Array.prototype.some.call(fixedLength, div3)); + assert(!Array.prototype.some.call(fixedLength, over10)); + assert(Array.prototype.some.call(fixedLengthWithOffset, div3)); + assert(!Array.prototype.some.call(fixedLengthWithOffset, over10)); + assert(Array.prototype.some.call(lengthTracking, div3)); + assert(!Array.prototype.some.call(lengthTracking, over10)); + assert(Array.prototype.some.call(lengthTrackingWithOffset, div3)); + assert(!Array.prototype.some.call(lengthTrackingWithOffset, over10)); +} diff --git a/test/built-ins/TypedArray/prototype/some/resizable-buffer-grow-mid-iteration.js b/test/built-ins/TypedArray/prototype/some/resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..6ea12d9e4e --- /dev/null +++ b/test/built-ins/TypedArray/prototype/some/resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,84 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.some +description: > + TypedArray.p.some behaves correctly on TypedArrays backed by resizable buffers + which are grown mid-iteration. +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Below the argument array should be a view of the resizable array buffer rab. +// This array gets collected into values via reduce and CollectValuesAndResize. +// The latter performs an during which, after resizeAfter steps, rab is resized +// to length resizeTo. Note that rab, values, resizeAfter, and resizeTo may need +// to be reset before calling this. +function ResizeMidIteration(n) { + CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); + return false; +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + values = []; + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + assert(!fixedLength.some(ResizeMidIteration)); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + values = []; + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + assert(!fixedLengthWithOffset.some(ResizeMidIteration)); + assert.compareArray(values, [ + 4, + 6 + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + values = []; + resizeAfter = 2; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + assert(!lengthTracking.some(ResizeMidIteration)); + assert.compareArray(values, [ + 0, + 2, + 4, + 6 + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + values = []; + rab = rab; + resizeAfter = 1; + resizeTo = 5 * ctor.BYTES_PER_ELEMENT; + assert(!lengthTrackingWithOffset.some(ResizeMidIteration)); + assert.compareArray(values, [ + 4, + 6 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/some/resizable-buffer-shrink-mid-iteration.js b/test/built-ins/TypedArray/prototype/some/resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..2182324dbb --- /dev/null +++ b/test/built-ins/TypedArray/prototype/some/resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,83 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.some +description: > + TypedArray.p.some behaves correctly on TypedArrays backed by resizable buffers + which are shrunk mid-iteration. +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +let values; +let rab; +let resizeAfter; +let resizeTo; +// Below the argument array should be a view of the resizable array buffer rab. +// This array gets collected into values via reduce and CollectValuesAndResize. +// The latter performs an during which, after resizeAfter steps, rab is resized +// to length resizeTo. Note that rab, values, resizeAfter, and resizeTo may need +// to be reset before calling this. +function ResizeMidIteration(n) { + CollectValuesAndResize(n, values, rab, resizeAfter, resizeTo); + return false; +} + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [4, 6] << fixedLengthWithOffset +// [0, 2, 4, 6, ...] << lengthTracking +// [4, 6, ...] << lengthTrackingWithOffset +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + values = []; + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert(!fixedLength.some(ResizeMidIteration)); + assert.compareArray(values, [ + 0, + 2, + undefined, + undefined + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + values = []; + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert(!fixedLengthWithOffset.some(ResizeMidIteration)); + assert.compareArray(values, [ + 4, + undefined + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + values = []; + resizeAfter = 2; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert(!lengthTracking.some(ResizeMidIteration)); + assert.compareArray(values, [ + 0, + 2, + 4, + undefined + ]); +} +for (let ctor of ctors) { + rab = CreateRabForTest(ctor); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + values = []; + resizeAfter = 1; + resizeTo = 3 * ctor.BYTES_PER_ELEMENT; + assert(!lengthTrackingWithOffset.some(ResizeMidIteration)); + assert.compareArray(values, [ + 4, + undefined + ]); +} diff --git a/test/built-ins/TypedArray/prototype/some/resizable-buffer.js b/test/built-ins/TypedArray/prototype/some/resizable-buffer.js new file mode 100644 index 0000000000..6a4c08b55d --- /dev/null +++ b/test/built-ins/TypedArray/prototype/some/resizable-buffer.js @@ -0,0 +1,115 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.some +description: > + TypedArray.p.some behaves correctly on TypedArrays backed by resizable buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + function div3(n) { + return Number(n) % 3 == 0; + } + function over10(n) { + return Number(n) > 10; + } + assert(fixedLength.some(div3)); + assert(!fixedLength.some(over10)); + assert(fixedLengthWithOffset.some(div3)); + assert(!fixedLengthWithOffset.some(over10)); + assert(lengthTracking.some(div3)); + assert(!lengthTracking.some(over10)); + assert(lengthTrackingWithOffset.some(div3)); + assert(!lengthTrackingWithOffset.some(over10)); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + fixedLength.some(div3); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.some(div3); + }); + + assert(lengthTracking.some(div3)); + assert(!lengthTracking.some(over10)); + assert(!lengthTrackingWithOffset.some(div3)); + assert(!lengthTrackingWithOffset.some(over10)); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + fixedLength.some(div3); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.some(div3); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.some(div3); + }); + + assert(lengthTracking.some(div3)); + assert(!lengthTracking.some(over10)); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + fixedLength.some(div3); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.some(div3); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.some(div3); + }); + + assert(!lengthTracking.some(div3)); + assert(!lengthTracking.some(over10)); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert(fixedLength.some(div3)); + assert(!fixedLength.some(over10)); + assert(fixedLengthWithOffset.some(div3)); + assert(!fixedLengthWithOffset.some(over10)); + assert(lengthTracking.some(div3)); + assert(!lengthTracking.some(over10)); + assert(lengthTrackingWithOffset.some(div3)); + assert(!lengthTrackingWithOffset.some(over10)); +} From 2020cfbe66f213209fa1fedff62d6e656139f757 Mon Sep 17 00:00:00 2001 From: Luis Fernando Pardo Sixtos Date: Tue, 13 Aug 2024 10:19:32 -0700 Subject: [PATCH 64/90] [decorators] Support private auto-accessors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support for the accessor keywords for private class fields as part of the decorators proposal. Changes to AST: - Add an AUTO_ACCESSOR value to the ClassLiteralProperty::Kind enum. - Add an AutoAccessorInfo class to be used in ClassLiteralProperty objects of kind AUTO_ACCESSOR to hold the information about the generated getters/setters and backing storage. - Add AutoAccessorGetterBody and AutoAccessorSetterBody statements to implement the logic of generated getters and setters. Changes to Parser: - Add logic to parse the "accessor" keyword and throw when used on non field class properties. - Add preparser logic to mock the function scopes and variable declarations required for the generated getters/setters. - Add parser logic to synthetically create statements for the generated setters/getters.  Changes to the Bytecode Generator: - Add logic to BuildClassLiteral to build auto accessor storage private names. - Add logic to set the generated getters/setters in the accessor pair. - Add logic to initialize the accessor storage in BuildClassProperty. - Add AutoAccessorGetterBody and AutoAccessorSetterBody visitors. Tests: - Add parsing-unittests for parsing converage. - Add test262 tests for functionality coverage. - Add test-debug test for devtools support coverage. Bug: 42202709 Change-Id: Ibb9bee3bbd0c09341108856f969e0c22bbb8b9cc Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5547688 Reviewed-by: Seth Brenith Commit-Queue: Luis Pardo Reviewed-by: Shu-yu Guo Cr-Commit-Position: refs/heads/main@{#95612} --- .../decorators/private-auto-accessor.js | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 test/staging/decorators/private-auto-accessor.js diff --git a/test/staging/decorators/private-auto-accessor.js b/test/staging/decorators/private-auto-accessor.js new file mode 100644 index 0000000000..7edbd2566c --- /dev/null +++ b/test/staging/decorators/private-auto-accessor.js @@ -0,0 +1,106 @@ +// Copyright 2024 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/*--- +description: Test private auto-accessors. +features: [decorators] +---*/ + +(function TestUninitializedPrivateAccessor() { + class C { + accessor #x; + assertFieldIsUndefined() { + assert.sameValue(this.#x, undefined); + } + assertFieldMatchesValue(value) { + assert.sameValue(this.#x, value); + } + setField(value) { + this.#x = value; + } + } + let c = new C(); + c.assertFieldIsUndefined(); + c.setField(42); + c.assertFieldMatchesValue(42); +})(); + +(function TestInitializedPrivateAccessor() { + class C { + accessor #x = 5; + assertFieldMatchesValue(value) { + assert.sameValue(this.#x, value); + } + setField(value) { + this.#x = value; + } + } + let c = new C(); + c.assertFieldMatchesValue(5); + c.setField(42); + c.assertFieldMatchesValue(42); +})(); + +(function TestInitializedMultiplePrivateAccessor() { + class C { + accessor #x = 5; + accessor #y = 42; + assertFieldsMatcheValues(value_x, value_y) { + assert.sameValue(this.#x, value_x); + assert.sameValue(this.#y, value_y); + } + } + let c = new C(); + c.assertFieldsMatcheValues(5, 42); +})(); + +(function TestThrowOnDuplicatedName() { + // Auto-accessors will instantiate private getter and setter with the same + // name, which shouldn't collide with other private variables. + let assertThrowsSyntaxError = (code_string) => { + assert.throws(SyntaxError, () => {eval(code_string)}); + }; + assertThrowsSyntaxError('class C { accessor #x = 5; accessor #x = 42; }'); + assertThrowsSyntaxError('class C { accessor #x = 5; #x = 42; }'); + assertThrowsSyntaxError('class C { accessor #x = 5; get #x() {}; }'); + assertThrowsSyntaxError('class C { accessor #x = 5; set #x(value) {}; }'); + assertThrowsSyntaxError('class C { accessor #x = 5; #x() {}; }'); + assertThrowsSyntaxError('class C { accessor #x = 5; static #x = 42; }'); + assertThrowsSyntaxError('class C { static accessor #x = 5; #x = 42; }'); + assertThrowsSyntaxError( + 'class C { static accessor #x = 5; static #x = 42; }'); +})(); + +(function TestUninitializedStaticPrivateAccessor() { + class C { + static #x; + static assertFieldIsUndefined() { + assert.sameValue(C.#x, undefined); + } + static assertFieldMatchesValue(value) { + assert.sameValue(C.#x, value); + } + static setField(value) { + C.#x = value; + } + } + C.assertFieldIsUndefined(); + C.setField(42); + C.assertFieldMatchesValue(42); +})(); + +(function TestInitializedStaticPrivateAccessor() { + class C { + static accessor #x = 5; + static assertFieldMatchesValue(value) { + assert.sameValue(C.#x, value); + } + static setField(value) { + C.#x = value; + } + } + C.assertFieldMatchesValue(5); + C.setField(42); + C.assertFieldMatchesValue(42); +})(); From 7608bfb14651788ba58a666062f994be38ad4cb1 Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Tue, 13 Aug 2024 17:27:55 +0100 Subject: [PATCH 65/90] Update INTERPRETING.md fixing `$262.AbstractModuleSource` position --- INTERPRETING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INTERPRETING.md b/INTERPRETING.md index da75456dc6..fb942deef4 100644 --- a/INTERPRETING.md +++ b/INTERPRETING.md @@ -42,6 +42,7 @@ properties of the global scope prior to test execution. the test runner. This is used as a communication mechanism for asynchronous tests (via the `async` flag, described below). - **`$262`** An ordinary object with the following properties: + - **`AbstractModuleSource`** - a reference to the `%AbstractModuleSource%` constructor which does not appear as a property of the global object. - **`createRealm`** - a function which creates a new [ECMAScript Realm](https://tc39.github.io/ecma262/#sec-code-realms), defines this API on the new realm's global object, and returns the `$262` @@ -107,7 +108,6 @@ properties of the global scope prior to test execution. - **`sleep`** - a function that takes a millisecond argument and sleeps the execution for approximately that duration. - **`monotonicNow`** - a function that returns a value that conforms to [`DOMHighResTimeStamp`][] and is produced in such a way that its semantics conform to **[Monotonic Clock][]**. - - **`AbstractModuleSource`** - a reference to the `%AbstractModuleSource%` constructor which does not appear as a property of the global object. In addition, consumers may choose to override any of [the functions defined by test harness files](https://github.com/tc39/test262/blob/HEAD/CONTRIBUTING.md#test-environment) as they see fit. See [the documentation on handling errors and negative test cases](https://github.com/tc39/test262/blob/HEAD/CONTRIBUTING.md#handling-errors-and-negative-test-cases) for a useful example of this. From 12307f5c20a4c4211e69823939fd1872212894c5 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Wed, 14 Aug 2024 02:03:51 +0200 Subject: [PATCH 66/90] RAB: Integrate staging tests for the .slice method (#4174) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while applying review changes from PRs for previously tested methods. * Add coerced-start-shrink test for Array.p.slice * Renames files to add more tests for the end argument of .slice. * Tests for the 'end' argument of .slice and test file for Array.p.slice parallel to TypedArray.p.slice resizable-buffer.js --- .../prototype/slice/coerced-start-end-grow.js | 56 +++++++ .../slice/coerced-start-end-shrink.js | 95 ++++++++++++ .../Array/prototype/slice/resizable-buffer.js | 124 +++++++++++++++ .../prototype/slice/coerced-start-end-grow.js | 55 +++++++ .../slice/coerced-start-end-shrink.js | 86 +++++++++++ .../prototype/slice/resizable-buffer.js | 144 ++++++++++++++++++ .../prototype/slice/speciesctor-resize.js | 129 ++++++++++++++++ 7 files changed, 689 insertions(+) create mode 100644 test/built-ins/Array/prototype/slice/coerced-start-end-grow.js create mode 100644 test/built-ins/Array/prototype/slice/coerced-start-end-shrink.js create mode 100644 test/built-ins/Array/prototype/slice/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/slice/coerced-start-end-grow.js create mode 100644 test/built-ins/TypedArray/prototype/slice/coerced-start-end-shrink.js create mode 100644 test/built-ins/TypedArray/prototype/slice/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/slice/speciesctor-resize.js diff --git a/test/built-ins/Array/prototype/slice/coerced-start-end-grow.js b/test/built-ins/Array/prototype/slice/coerced-start-end-grow.js new file mode 100644 index 0000000000..2d718b803d --- /dev/null +++ b/test/built-ins/Array/prototype/slice/coerced-start-end-grow.js @@ -0,0 +1,56 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.slice +description: > + Array.p.slice behaves correctly on TypedArrays backed by resizable buffers that + are grown by argument coercion. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// The start argument grows the resizable array buffer rab. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i + 1); + } + const evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTracking, evil)), [ + 1, + 2, + 3, + 4 + ]); + assert.sameValue(rab.byteLength, 6 * ctor.BYTES_PER_ELEMENT); +} + +// The end argument grows the resizable array buffer rab. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i + 1); + } + + const evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 5; + } + }; + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTracking,4,evil)), [ + ]); + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTracking,3,evil)), [ + 4, + 0 + ]); + assert.sameValue(rab.byteLength, 6 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/Array/prototype/slice/coerced-start-end-shrink.js b/test/built-ins/Array/prototype/slice/coerced-start-end-shrink.js new file mode 100644 index 0000000000..b6656b3be3 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/coerced-start-end-shrink.js @@ -0,0 +1,95 @@ +// Copyright 2023 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.slice +description: > + Array.p.slice behaves correctly on TypedArrays backed by resizable buffers that + are shrunk by argument coercion. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// The start argument shrinks the resizable array buffer rab. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLength, evil)), [ + undefined, + undefined, + undefined, + undefined + ]); + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLength, evil)), [ + ]); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i + 1); + } + const evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTracking, evil)), [ + 1, + 2, + undefined, + undefined + ]); + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTracking, evil)), [ + 1, + 2 + ]); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); +} + +// The end argument shrinks the resizable array buffer rab. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 3; + } + }; + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLength, 2, evil)), [ + undefined + ]); + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLength, 2, evil)), [ + ]); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i + 1); + } + const evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 3; + } + }; + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTracking, 1, evil)), [ + 2, + undefined + ]); + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTracking, 1, evil)), [ + 2 + ]); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/Array/prototype/slice/resizable-buffer.js b/test/built-ins/Array/prototype/slice/resizable-buffer.js new file mode 100644 index 0000000000..606a520101 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/resizable-buffer.js @@ -0,0 +1,124 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.slice +description: > + Array.p.slice behaves correctly on TypedArrays backed by resizable buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, i); + } + const fixedLengthSlice = Array.prototype.slice.call(fixedLength); + assert.compareArray(ToNumbers(fixedLengthSlice), [ + 0, + 1, + 2, + 3 + ]); + const fixedLengthWithOffsetSlice = Array.prototype.slice.call(fixedLengthWithOffset); + assert.compareArray(ToNumbers(fixedLengthWithOffsetSlice), [ + 2, + 3 + ]); + const lengthTrackingSlice = Array.prototype.slice.call(lengthTracking); + assert.compareArray(ToNumbers(lengthTrackingSlice), [ + 0, + 1, + 2, + 3 + ]); + const lengthTrackingWithOffsetSlice = Array.prototype.slice.call(lengthTrackingWithOffset); + assert.compareArray(ToNumbers(lengthTrackingWithOffsetSlice), [ + 2, + 3 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLength)), []); + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLengthWithOffset)), []); + + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTracking)), [ + 0, + 1, + 2 + ]); + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTrackingWithOffset)), [2]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLength)), []); + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLengthWithOffset)), []); + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTracking)), [0]); + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTrackingWithOffset)), []); + + // Shrink to zero. + rab.resize(0); + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLength)), []); + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLengthWithOffset)), []); + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTracking)), []); + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTrackingWithOffset)), []); + + // Verify that the previously created slices aren't affected by the + // shrinking. + assert.compareArray(ToNumbers(fixedLengthSlice), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(ToNumbers(fixedLengthWithOffsetSlice), [ + 2, + 3 + ]); + assert.compareArray(ToNumbers(lengthTrackingSlice), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(ToNumbers(lengthTrackingWithOffsetSlice), [ + 2, + 3 + ]); + + // Grow so that all TAs are back in-bounds. New memory is zeroed. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLength)), [ + 0, + 0, + 0, + 0 + ]); + assert.compareArray(ToNumbers(Array.prototype.slice.call(fixedLengthWithOffset)), [ + 0, + 0 + ]); + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTracking)), [ + 0, + 0, + 0, + 0, + 0, + 0 + ]); + assert.compareArray(ToNumbers(Array.prototype.slice.call(lengthTrackingWithOffset)), [ + 0, + 0, + 0, + 0 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/slice/coerced-start-end-grow.js b/test/built-ins/TypedArray/prototype/slice/coerced-start-end-grow.js new file mode 100644 index 0000000000..4a927dd8aa --- /dev/null +++ b/test/built-ins/TypedArray/prototype/slice/coerced-start-end-grow.js @@ -0,0 +1,55 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.slice +description: > + TypedArray.p.slice behaves correctly on TypedArrays backed by resizable buffers + that is grown by argument coercion. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// The start argument grows the resizable array buffer rab. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i + 1); + } + const evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.compareArray(ToNumbers(lengthTracking.slice(evil)), [ + 1, + 2, + 3, + 4 + ]); + assert.sameValue(rab.byteLength, 6 * ctor.BYTES_PER_ELEMENT); +} + +// The end argument grows the resizable array buffer rab. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i + 1); + } + const evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 5; + } + }; + assert.compareArray(ToNumbers(lengthTracking.slice(4,evil)), [ + ]); + assert.compareArray(ToNumbers(lengthTracking.slice(3,evil)), [ + 4, + 0 + ]); + assert.sameValue(rab.byteLength, 6 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/TypedArray/prototype/slice/coerced-start-end-shrink.js b/test/built-ins/TypedArray/prototype/slice/coerced-start-end-shrink.js new file mode 100644 index 0000000000..1359f8ba34 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/slice/coerced-start-end-shrink.js @@ -0,0 +1,86 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.slice +description: > + TypedArray.p.slice behaves correctly on TypedArrays backed by resizable buffers + that are shrunk by argument coercion. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// The start argument shrinks the resizable array buffer rab. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.throws(TypeError, () => { + fixedLength.slice(evil); + }); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i + 1); + } + const evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.compareArray(ToNumbers(lengthTracking.slice(evil)), [ + 1, + 2, + 0, + 0 + ]); + assert.compareArray(ToNumbers(lengthTracking.slice(evil)), [ + 1, + 2 + ]); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); +} + +// The end argument shrinks the resizable array buffer rab. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 5; + } + }; + assert.throws(TypeError, () => { + fixedLength.slice(1, evil); + }); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(lengthTracking, i, i + 1); + } + const evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 5; + } + }; + assert.compareArray(ToNumbers(lengthTracking.slice(1,evil)), [ + 2, + 0, + 0 + ]); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); +} diff --git a/test/built-ins/TypedArray/prototype/slice/resizable-buffer.js b/test/built-ins/TypedArray/prototype/slice/resizable-buffer.js new file mode 100644 index 0000000000..db072bf3d5 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/slice/resizable-buffer.js @@ -0,0 +1,144 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.slice +description: > + TypedArray.p.slice behaves correctly on TypedArrays backed by resizable + buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, i); + } + const fixedLengthSlice = fixedLength.slice(); + assert.compareArray(ToNumbers(fixedLengthSlice), [ + 0, + 1, + 2, + 3 + ]); + assert(!fixedLengthSlice.buffer.resizable); + const fixedLengthWithOffsetSlice = fixedLengthWithOffset.slice(); + assert.compareArray(ToNumbers(fixedLengthWithOffsetSlice), [ + 2, + 3 + ]); + assert(!fixedLengthWithOffsetSlice.buffer.resizable); + const lengthTrackingSlice = lengthTracking.slice(); + assert.compareArray(ToNumbers(lengthTrackingSlice), [ + 0, + 1, + 2, + 3 + ]); + assert(!lengthTrackingSlice.buffer.resizable); + const lengthTrackingWithOffsetSlice = lengthTrackingWithOffset.slice(); + assert.compareArray(ToNumbers(lengthTrackingWithOffsetSlice), [ + 2, + 3 + ]); + assert(!lengthTrackingWithOffsetSlice.buffer.resizable); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + fixedLength.slice(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.slice(); + }); + assert.compareArray(ToNumbers(lengthTracking.slice()), [ + 0, + 1, + 2 + ]); + assert.compareArray(ToNumbers(lengthTrackingWithOffset.slice()), [2]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + fixedLength.slice(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.slice(); + }); + assert.compareArray(ToNumbers(lengthTracking.slice()), [0]); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.slice(); + }); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + fixedLength.slice(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.slice(); + }); + assert.compareArray(ToNumbers(lengthTracking.slice()), []); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.slice(); + }); + + // Verify that the previously created slices aren't affected by the + // shrinking. + assert.compareArray(ToNumbers(fixedLengthSlice), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(ToNumbers(fixedLengthWithOffsetSlice), [ + 2, + 3 + ]); + assert.compareArray(ToNumbers(lengthTrackingSlice), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(ToNumbers(lengthTrackingWithOffsetSlice), [ + 2, + 3 + ]); + + // Grow so that all TAs are back in-bounds. New memory is zeroed. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + assert.compareArray(ToNumbers(fixedLength.slice()), [ + 0, + 0, + 0, + 0 + ]); + assert.compareArray(ToNumbers(fixedLengthWithOffset.slice()), [ + 0, + 0 + ]); + assert.compareArray(ToNumbers(lengthTracking.slice()), [ + 0, + 0, + 0, + 0, + 0, + 0 + ]); + assert.compareArray(ToNumbers(lengthTrackingWithOffset.slice()), [ + 0, + 0, + 0, + 0 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/slice/speciesctor-resize.js b/test/built-ins/TypedArray/prototype/slice/speciesctor-resize.js new file mode 100644 index 0000000000..280d8a3c13 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/slice/speciesctor-resize.js @@ -0,0 +1,129 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.slice +description: > + TypedArray.p.slice behaves correctly on TypedArrays backed by resizable buffers + which the species constructor resizes. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// The corresponding test for Array.prototype.slice is not possible, since it +// doesn't call the species constructor if the "original array" is not an Array. + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + let resizeWhenConstructorCalled = false; + class MyArray extends ctor { + constructor(...params) { + super(...params); + if (resizeWhenConstructorCalled) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + } + } + ; + const fixedLength = new MyArray(rab, 0, 4); + resizeWhenConstructorCalled = true; + assert.throws(TypeError, () => { + fixedLength.slice(); + }); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 1); + } + let resizeWhenConstructorCalled = false; + class MyArray extends ctor { + constructor(...params) { + super(...params); + if (resizeWhenConstructorCalled) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + } + } + ; + const lengthTracking = new MyArray(rab); + resizeWhenConstructorCalled = true; + const a = lengthTracking.slice(); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); + // The length of the resulting TypedArray is determined before + // TypedArraySpeciesCreate is called, and it doesn't change. + assert.sameValue(a.length, 4); + assert.compareArray(ToNumbers(a), [ + 1, + 1, + 0, + 0 + ]); +} + +// Test that the (start, end) parameters are computed based on the original +// length. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 1); + } + let resizeWhenConstructorCalled = false; + class MyArray extends ctor { + constructor(...params) { + super(...params); + if (resizeWhenConstructorCalled) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + } + } + ; + const lengthTracking = new MyArray(rab); + resizeWhenConstructorCalled = true; + const a = lengthTracking.slice(-3, -1); + assert.sameValue(rab.byteLength, 2 * ctor.BYTES_PER_ELEMENT); + // The length of the resulting TypedArray is determined before + // TypedArraySpeciesCreate is called, and it doesn't change. + assert.sameValue(a.length, 2); + assert.compareArray(ToNumbers(a), [ + 1, + 0 + ]); +} + +// Test where the buffer gets resized "between elements". +{ + const rab = CreateResizableArrayBuffer(8, 16); + const taWrite = new Uint8Array(rab); + for (let i = 0; i < 8; ++i) { + WriteToTypedArray(taWrite, i, 255); + } + let resizeWhenConstructorCalled = false; + class MyArray extends Uint16Array { + constructor(...params) { + super(...params); + if (resizeWhenConstructorCalled) { + rab.resize(5); + } + } + } + ; + const lengthTracking = new MyArray(rab); + assert.compareArray(ToNumbers(lengthTracking), [ + 65535, + 65535, + 65535, + 65535 + ]); + resizeWhenConstructorCalled = true; + const a = lengthTracking.slice(); + assert.sameValue(rab.byteLength, 5); + assert.sameValue(a.length, 4); + assert.sameValue(a[0], 65535); + assert.sameValue(a[1], 65535); + assert.sameValue(a[2], 0); + assert.sameValue(a[3], 0); +} From 984df1f3dbb7081902cd6f16636cb32da74481af Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Fri, 5 Jul 2024 16:44:44 +0100 Subject: [PATCH 67/90] Remove unused harness/timer.js --- harness/timer.js | 30 ------------------------------ test/harness/timer.js | 18 ------------------ 2 files changed, 48 deletions(-) delete mode 100644 harness/timer.js delete mode 100644 test/harness/timer.js diff --git a/harness/timer.js b/harness/timer.js deleted file mode 100644 index 3ca7714caf..0000000000 --- a/harness/timer.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2017 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: | - Used in website/scripts/sth.js -defines: [setTimeout] ----*/ -//setTimeout is not available, hence this script was loaded -if (Promise === undefined && this.setTimeout === undefined) { - if(/\$DONE()/.test(code)) - throw new Test262Error("Async test capability is not supported in your test environment"); -} - -if (Promise !== undefined && this.setTimeout === undefined) { - (function(that) { - that.setTimeout = function(callback, delay) { - var p = Promise.resolve(); - var start = Date.now(); - var end = start + delay; - function check(){ - var timeLeft = end - Date.now(); - if(timeLeft > 0) - p.then(check); - else - callback(); - } - p.then(check); - } - })(this); -} diff --git a/test/harness/timer.js b/test/harness/timer.js deleted file mode 100644 index 911963dcf6..0000000000 --- a/test/harness/timer.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2017 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - Including timer.js will expose: - - setTimeout() - -includes: [timer.js,fnGlobalObject.js] ----*/ - -var gO = fnGlobalObject(); - -assert(typeof setTimeout === "function"); -assert(typeof gO.setTimeout === "function"); -assert.sameValue(gO.setTimeout, setTimeout); - -// TODO: assert semantics From b1d0933df5f0ccbf0fc4985469e356c89fc6d2a2 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Wed, 14 Aug 2024 21:30:54 +0200 Subject: [PATCH 68/90] RAB: Integrate staging tests for the .toLocaleString method (#4178) * Import relevant files from #3888 * Removing parts in resizableArrayBufferUtils.js and adding it in includes, while applying review changes from PRs for previously tested methods. * Apply suggestions from code review * Address review: get implementation dependent toLocaleString separator. * Apply suggestions from code review --- .../toLocaleString/resizable-buffer.js | 88 ++++++++++++++ .../user-provided-tolocalestring-grow.js | 81 +++++++++++++ .../user-provided-tolocalestring-shrink.js | 82 +++++++++++++ .../toLocaleString/resizable-buffer.js | 114 ++++++++++++++++++ .../user-provided-tolocalestring-grow.js | 82 +++++++++++++ .../user-provided-tolocalestring-shrink.js | 83 +++++++++++++ 6 files changed, 530 insertions(+) create mode 100644 test/built-ins/Array/prototype/toLocaleString/resizable-buffer.js create mode 100644 test/built-ins/Array/prototype/toLocaleString/user-provided-tolocalestring-grow.js create mode 100644 test/built-ins/Array/prototype/toLocaleString/user-provided-tolocalestring-shrink.js create mode 100644 test/built-ins/TypedArray/prototype/toLocaleString/resizable-buffer.js create mode 100644 test/built-ins/TypedArray/prototype/toLocaleString/user-provided-tolocalestring-grow.js create mode 100644 test/built-ins/TypedArray/prototype/toLocaleString/user-provided-tolocalestring-shrink.js diff --git a/test/built-ins/Array/prototype/toLocaleString/resizable-buffer.js b/test/built-ins/Array/prototype/toLocaleString/resizable-buffer.js new file mode 100644 index 0000000000..c8768f47fe --- /dev/null +++ b/test/built-ins/Array/prototype/toLocaleString/resizable-buffer.js @@ -0,0 +1,88 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.tolocalestring +description: > + Array.p.toLocaleString behaves correctly on TypedArrays backed by resizable + buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taWrite = new ctor(rab); + + // toLocaleString separator is implementation dependent. + function listToString(list) { + const comma = ['',''].toLocaleString(); + return list.join(comma); + } + + // Write some data into the array. + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert.sameValue(Array.prototype.toLocaleString.call(fixedLength), listToString([0,2,4,6])); + assert.sameValue(Array.prototype.toLocaleString.call(fixedLengthWithOffset), listToString([4,6])); + assert.sameValue(Array.prototype.toLocaleString.call(lengthTracking), listToString([0,2,4,6])); + assert.sameValue(Array.prototype.toLocaleString.call(lengthTrackingWithOffset), listToString([4,6])); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.sameValue(Array.prototype.toLocaleString.call(fixedLength), listToString([])); + assert.sameValue(Array.prototype.toLocaleString.call(fixedLengthWithOffset), listToString([])); + + assert.sameValue(Array.prototype.toLocaleString.call(lengthTracking), listToString([0,2,4])); + assert.sameValue(Array.prototype.toLocaleString.call(lengthTrackingWithOffset), listToString([4])); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.sameValue(Array.prototype.toLocaleString.call(fixedLength), listToString([])); + assert.sameValue(Array.prototype.toLocaleString.call(fixedLengthWithOffset), listToString([])); + assert.sameValue(Array.prototype.toLocaleString.call(lengthTrackingWithOffset), listToString([])); + + assert.sameValue(Array.prototype.toLocaleString.call(lengthTracking), listToString([0])); + + // Shrink to zero. + rab.resize(0); + assert.sameValue(Array.prototype.toLocaleString.call(fixedLength), listToString([])); + assert.sameValue(Array.prototype.toLocaleString.call(fixedLengthWithOffset), listToString([])); + assert.sameValue(Array.prototype.toLocaleString.call(lengthTrackingWithOffset), listToString([])); + + assert.sameValue(Array.prototype.toLocaleString.call(lengthTracking), listToString([])); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.sameValue(Array.prototype.toLocaleString.call(fixedLength), listToString([0,2,4,6])); + assert.sameValue(Array.prototype.toLocaleString.call(fixedLengthWithOffset), listToString([4,6])); + assert.sameValue(Array.prototype.toLocaleString.call(lengthTracking), listToString([0,2,4,6,8,10])); + assert.sameValue(Array.prototype.toLocaleString.call(lengthTrackingWithOffset), listToString([4,6,8,10])); +} diff --git a/test/built-ins/Array/prototype/toLocaleString/user-provided-tolocalestring-grow.js b/test/built-ins/Array/prototype/toLocaleString/user-provided-tolocalestring-grow.js new file mode 100644 index 0000000000..201e31ca75 --- /dev/null +++ b/test/built-ins/Array/prototype/toLocaleString/user-provided-tolocalestring-grow.js @@ -0,0 +1,81 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.tolocalestring +description: > + Array.p.toLocaleString behaves correctly when {Number,BigInt}.prototype.toLocaleString + is replaced with a user-provided function that grows the array. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const oldNumberPrototypeToLocaleString = Number.prototype.toLocaleString; +const oldBigIntPrototypeToLocaleString = BigInt.prototype.toLocaleString; + +// toLocaleString separator is implementation dependent. +function listToString(list) { + const comma = ['',''].toLocaleString(); + const len = list.length; + let result = ''; + if (len > 1) { + for (let i=0; i < len - 1 ; i++) { + result += list[i] + comma; + } + } + if (len > 0) { + result += list[len-1]; + } + return result; +} + +// Growing + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let resizeAfter = 2; + Number.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + } + return oldNumberPrototypeToLocaleString.call(this); + }; + BigInt.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + } + return oldBigIntPrototypeToLocaleString.call(this); + }; + + // We iterate 4 elements since it was the starting length. Resizing doesn't + // affect the TA. + assert.sameValue(Array.prototype.toLocaleString.call(fixedLength), listToString([0,0,0,0])); +} + +// Growing + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let resizeAfter = 2; + Number.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + } + return oldNumberPrototypeToLocaleString.call(this); + }; + BigInt.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + } + return oldBigIntPrototypeToLocaleString.call(this); + }; + + // We iterate 4 elements since it was the starting length. + assert.sameValue(Array.prototype.toLocaleString.call(lengthTracking), listToString([0,0,0,0])); +} +Number.prototype.toLocaleString = oldNumberPrototypeToLocaleString; +BigInt.prototype.toLocaleString = oldBigIntPrototypeToLocaleString; diff --git a/test/built-ins/Array/prototype/toLocaleString/user-provided-tolocalestring-shrink.js b/test/built-ins/Array/prototype/toLocaleString/user-provided-tolocalestring-shrink.js new file mode 100644 index 0000000000..d9e622148a --- /dev/null +++ b/test/built-ins/Array/prototype/toLocaleString/user-provided-tolocalestring-shrink.js @@ -0,0 +1,82 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-array.prototype.tolocalestring +description: > + Array.p.toLocaleString behaves correctly when {Number,BigInt}.prototype.toLocaleString + is replaced with a user-provided function that shrinks the array. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const oldNumberPrototypeToLocaleString = Number.prototype.toLocaleString; +const oldBigIntPrototypeToLocaleString = BigInt.prototype.toLocaleString; + +// toLocaleString separator is implementation dependent. +function listToString(list) { + const comma = ['',''].toLocaleString(); + const len = list.length; + let result = ''; + if (len > 1) { + for (let i=0; i < len - 1 ; i++) { + result += list[i] + comma; + } + } + if (len > 0) { + result += list[len-1]; + } + return result; +} + +// Shrinking + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let resizeAfter = 2; + Number.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + return oldNumberPrototypeToLocaleString.call(this); + }; + BigInt.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + return oldBigIntPrototypeToLocaleString.call(this); + }; + + // We iterate 4 elements, since it was the starting length. The TA goes + // OOB after 2 elements. + assert.sameValue(Array.prototype.toLocaleString.call(fixedLength),listToString([0,0,'',''])); +} + +// Shrinking + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let resizeAfter = 2; + Number.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + return oldNumberPrototypeToLocaleString.call(this); + }; + BigInt.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + return oldBigIntPrototypeToLocaleString.call(this); + }; + + // We iterate 4 elements, since it was the starting length. Elements beyond + // the new length are converted to the empty string. + assert.sameValue(Array.prototype.toLocaleString.call(lengthTracking),listToString([0,0,'',''])); +} +Number.prototype.toLocaleString = oldNumberPrototypeToLocaleString; +BigInt.prototype.toLocaleString = oldBigIntPrototypeToLocaleString; diff --git a/test/built-ins/TypedArray/prototype/toLocaleString/resizable-buffer.js b/test/built-ins/TypedArray/prototype/toLocaleString/resizable-buffer.js new file mode 100644 index 0000000000..d31c5f5a5b --- /dev/null +++ b/test/built-ins/TypedArray/prototype/toLocaleString/resizable-buffer.js @@ -0,0 +1,114 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.tolocalestring +description: > + TypedArray.p.toLocaleString behaves correctly on TypedArrays backed by + resizable buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taWrite = new ctor(rab); + + // toLocaleString separator is implementation dependent. + function listToString(list) { + const comma = ['',''].toLocaleString(); + const len = list.length; + let result = ''; + if (len > 1) { + for (let i=0; i < len - 1 ; i++) { + result += list[i] + comma; + } + } + if (len > 0) { + result += list[len-1]; + } + return result; + } + + // Write some data into the array. + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert.sameValue(fixedLength.toLocaleString(),listToString([0,2,4,6])); + assert.sameValue(fixedLengthWithOffset.toLocaleString(),listToString([4,6])); + assert.sameValue(lengthTracking.toLocaleString(),listToString([0,2,4,6])); + assert.sameValue(lengthTrackingWithOffset.toLocaleString(),listToString([4,6])); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + fixedLength.toLocaleString(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.toLocaleString(); + }); + + assert.sameValue(lengthTracking.toLocaleString(),listToString([0,2,4])); + assert.sameValue(lengthTrackingWithOffset.toLocaleString(),listToString([4])); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + fixedLength.toLocaleString(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.toLocaleString(); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.toLocaleString(); + }); + + assert.sameValue(lengthTracking.toLocaleString(),listToString([0])); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + fixedLength.toLocaleString(); + }); + assert.throws(TypeError, () => { + fixedLengthWithOffset.toLocaleString(); + }); + assert.throws(TypeError, () => { + lengthTrackingWithOffset.toLocaleString(); + }); + + assert.sameValue(lengthTracking.toLocaleString(),listToString([])); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.sameValue(fixedLength.toLocaleString(),listToString([0,2,4,6])); + assert.sameValue(fixedLengthWithOffset.toLocaleString(),listToString([4,6])); + assert.sameValue(lengthTracking.toLocaleString(),listToString([0,2,4,6,8,10])); + assert.sameValue(lengthTrackingWithOffset.toLocaleString(),listToString([4,6,8,10])); +} diff --git a/test/built-ins/TypedArray/prototype/toLocaleString/user-provided-tolocalestring-grow.js b/test/built-ins/TypedArray/prototype/toLocaleString/user-provided-tolocalestring-grow.js new file mode 100644 index 0000000000..a12255d8e7 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/toLocaleString/user-provided-tolocalestring-grow.js @@ -0,0 +1,82 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.tolocalestring +description: > + TypedArray.p.toLocaleString behaves correctly when {Number,BigInt}. + prototype.toLocaleString is replaced with a user-provided function + that grows the underlying resizable buffer. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const oldNumberPrototypeToLocaleString = Number.prototype.toLocaleString; +const oldBigIntPrototypeToLocaleString = BigInt.prototype.toLocaleString; + +// toLocaleString separator is implementation dependent. +function listToString(list) { + const comma = ['',''].toLocaleString(); + const len = list.length; + let result = ''; + if (len > 1) { + for (let i=0; i < len - 1 ; i++) { + result += list[i] + comma; + } + } + if (len > 0) { + result += list[len-1]; + } + return result; +} + +// Growing + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let resizeAfter = 2; + Number.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + } + return oldNumberPrototypeToLocaleString.call(this); + }; + BigInt.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + } + return oldBigIntPrototypeToLocaleString.call(this); + }; + + // We iterate 4 elements since it was the starting length. Resizing doesn't + // affect the TA. + assert.sameValue(fixedLength.toLocaleString(), listToString([0,0,0,0])); +} + +// Growing + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let resizeAfter = 2; + Number.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + } + return oldNumberPrototypeToLocaleString.call(this); + }; + BigInt.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + } + return oldBigIntPrototypeToLocaleString.call(this); + }; + + // We iterate 4 elements since it was the starting length. + assert.sameValue(lengthTracking.toLocaleString(), listToString([0,0,0,0])); +} +Number.prototype.toLocaleString = oldNumberPrototypeToLocaleString; +BigInt.prototype.toLocaleString = oldBigIntPrototypeToLocaleString; diff --git a/test/built-ins/TypedArray/prototype/toLocaleString/user-provided-tolocalestring-shrink.js b/test/built-ins/TypedArray/prototype/toLocaleString/user-provided-tolocalestring-shrink.js new file mode 100644 index 0000000000..c0235a8f4d --- /dev/null +++ b/test/built-ins/TypedArray/prototype/toLocaleString/user-provided-tolocalestring-shrink.js @@ -0,0 +1,83 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.tolocalestring +description: > + TypedArray.p.toLocaleString behaves correctly when {Number,BigInt}. + prototype.toLocaleString is replaced with a user-provided function + that shrinks the underlying resizable buffer. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const oldNumberPrototypeToLocaleString = Number.prototype.toLocaleString; +const oldBigIntPrototypeToLocaleString = BigInt.prototype.toLocaleString; + +// toLocaleString separator is implementation dependent. +function listToString(list) { + const comma = ['',''].toLocaleString(); + const len = list.length; + let result = ''; + if (len > 1) { + for (let i=0; i < len - 1 ; i++) { + result += list[i] + comma; + } + } + if (len > 0) { + result += list[len-1]; + } + return result; +} + +// Shrinking + fixed-length TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + let resizeAfter = 2; + Number.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + return oldNumberPrototypeToLocaleString.call(this); + }; + BigInt.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + return oldBigIntPrototypeToLocaleString.call(this); + }; + + // We iterate 4 elements, since it was the starting length. The TA goes + // OOB after 2 elements. + assert.sameValue(fixedLength.toLocaleString(), listToString([0,0,'',''])); +} + +// Shrinking + length-tracking TA. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let resizeAfter = 2; + Number.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + return oldNumberPrototypeToLocaleString.call(this); + }; + BigInt.prototype.toLocaleString = function () { + --resizeAfter; + if (resizeAfter == 0) { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + } + return oldBigIntPrototypeToLocaleString.call(this); + }; + + // We iterate 4 elements, since it was the starting length. Elements beyond + // the new length are converted to the empty string. + assert.sameValue(lengthTracking.toLocaleString(), listToString([0,0,'',''])); +} +Number.prototype.toLocaleString = oldNumberPrototypeToLocaleString; +BigInt.prototype.toLocaleString = oldBigIntPrototypeToLocaleString; From cb4a6c8074671c00df8cbc17a620c0f9462b312a Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Wed, 14 Aug 2024 12:44:13 -0700 Subject: [PATCH 69/90] Temporal: Add a test for a coverage gap in Duration.prototype.round See https://github.com/tc39/proposal-temporal/issues/2919; this adds test coverage that would have caught an unintentional normative change. --- .../prototype/round/end-of-month-round-up.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/built-ins/Temporal/Duration/prototype/round/end-of-month-round-up.js diff --git a/test/built-ins/Temporal/Duration/prototype/round/end-of-month-round-up.js b/test/built-ins/Temporal/Duration/prototype/round/end-of-month-round-up.js new file mode 100644 index 0000000000..babcf9bb15 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/round/end-of-month-round-up.js @@ -0,0 +1,21 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: Correctly handle special case where rounding value is at upper bound +info: | + sec-temporal-nudgetocalendarunit: + 1. If _progress_ = 1, then + 1. Let _roundedUnit_ be abs(_r2_). + 1. Else, + 1. Let _roundedUnit_ be ApplyUnsignedRoundingMode(abs(_total_), abs(_r1_), + abs(_r2_), _unsignedRoundingMode_). +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const instance = new Temporal.Duration(0, 11); +const relativeTo = new Temporal.PlainDate(2023, 5, 31); +const result = instance.round({ relativeTo, smallestUnit: "months", roundingMode: "ceil" }); +TemporalHelpers.assertDuration(result, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0); From 224c5c3cb99bccf55ef36fca0b173bbb50ad6cc5 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Fri, 16 Aug 2024 00:13:34 +0200 Subject: [PATCH 70/90] RAB: Integrate staging tests for the .subarray method (#4177) * Import relevant files from #3888 * Adds resizableArrayBufferUtils.js to includes and removes its content from each test * renamed tests to indicate the end argument is tested too * Adds more tests for the 'end' argument of .subarray --- .../subarray/coerced-begin-end-grow.js | 106 ++++++++++ .../subarray/coerced-begin-end-shrink.js | 192 ++++++++++++++++++ .../prototype/subarray/resizable-buffer.js | 172 ++++++++++++++++ 3 files changed, 470 insertions(+) create mode 100644 test/built-ins/TypedArray/prototype/subarray/coerced-begin-end-grow.js create mode 100644 test/built-ins/TypedArray/prototype/subarray/coerced-begin-end-shrink.js create mode 100644 test/built-ins/TypedArray/prototype/subarray/resizable-buffer.js diff --git a/test/built-ins/TypedArray/prototype/subarray/coerced-begin-end-grow.js b/test/built-ins/TypedArray/prototype/subarray/coerced-begin-end-grow.js new file mode 100644 index 0000000000..b306821d66 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/subarray/coerced-begin-end-grow.js @@ -0,0 +1,106 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.subarray +description: > + TypedArray.p.subarray behaves correctly on TypedArrays backed by resizable + buffers that are grown by argument coercion. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [0, 2, 4, 6, ...] << lengthTracking + +// Growing a fixed length TA back in bounds. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + // Make `fixedLength` OOB. + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + const evil = { + valueOf: () => { + rab.resize(4 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + // The length computation is done before parameter conversion. At that + // point, the length is 0, since the TA is OOB. + assert.compareArray(ToNumbers(fixedLength.subarray(evil, 1)), []); +} + +// As above but with the second parameter conversion growing the buffer. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + // Make `fixedLength` OOB. + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + const evil = { + valueOf: () => { + rab.resize(4 * ctor.BYTES_PER_ELEMENT); + return 1; + } + }; + // The length computation is done before parameter conversion. At that + // point, the length is 0, since the TA is OOB. + assert.compareArray(ToNumbers(fixedLength.subarray(0, evil)), []); +} + + +// Growing + fixed-length TA. Growing won't affect anything. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + const evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.compareArray(ToNumbers(fixedLength.subarray(evil)), [ + 0, + 2, + 4, + 6 + ]); +} + +// As above but with the second parameter conversion growing the buffer. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + const evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 4; + } + }; + assert.compareArray(ToNumbers(fixedLength.subarray(0, evil)), [ + 0, + 2, + 4, + 6 + ]); +} + +// Growing + length-tracking TA. The length computation is done with the +// original length. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab, 0); + const evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.compareArray( + ToNumbers(lengthTracking.subarray(evil, lengthTracking.length)), [ + 0, + 2, + 4, + 6 + ]); +} diff --git a/test/built-ins/TypedArray/prototype/subarray/coerced-begin-end-shrink.js b/test/built-ins/TypedArray/prototype/subarray/coerced-begin-end-shrink.js new file mode 100644 index 0000000000..7505222a49 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/subarray/coerced-begin-end-shrink.js @@ -0,0 +1,192 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.subarray +description: > + TypedArray.p.subarray behaves correctly on TypedArrays backed by resizable + buffers that are shrunk by argument coercion. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// Orig. array: [0, 2, 4, 6] +// [0, 2, 4, 6] << fixedLength +// [0, 2, 4, 6, ...] << lengthTracking + + +// Fixed-length TA + first parameter conversion shrinks. The old length is +// used in the length computation, and the subarray construction fails. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.throws(RangeError, () => { + fixedLength.subarray(evil); + }); +} + +// Like the previous test, but now we construct a smaller subarray and it +// succeeds. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.compareArray(ToNumbers(fixedLength.subarray(evil, 1)), [0]); +} + +// As above but with the second parameter conversion shrinking the buffer. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 1; + } + }; + assert.compareArray(ToNumbers(fixedLength.subarray(0,evil)), [0]); +} + +// Fixed-length TA + second parameter conversion shrinks. The old length is +// used in the length computation, and the subarray construction fails. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 3; + } + }; + assert.throws(RangeError, () => { + fixedLength.subarray(0, evil); + }); +} + +// Like the previous test, but now we construct a smaller subarray and it +// succeeds. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 1; + } + }; + assert.compareArray(ToNumbers(fixedLength.subarray(0, evil)), [0]); +} + +// Shrinking + fixed-length TA, subarray construction succeeds even though the +// TA goes OOB. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + const evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.compareArray(ToNumbers(fixedLength.subarray(evil, 1)), [0]); +} + +// As above but with the second parameter conversion shrinking the buffer. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const fixedLength = new ctor(rab, 0, 4); + const evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 1; + } + }; + assert.compareArray(ToNumbers(fixedLength.subarray(0,evil)), [0]); +} + +// Length-tracking TA + first parameter conversion shrinks. The old length is +// used in the length computation, and the subarray construction fails. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.throws(RangeError, () => { + lengthTracking.subarray(evil, lengthTracking.length); + }); +} + +// Like the previous test, but now we construct a smaller subarray and it +// succeeds. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.compareArray(ToNumbers(lengthTracking.subarray(evil, 1)), [0]); +} + +// As above but with the second parameter conversion shrinking the buffer. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 1; + } + }; + assert.compareArray(ToNumbers(lengthTracking.subarray(0,evil)), [0]); +} + +// Length-tracking TA + first parameter conversion shrinks. The second +// parameter is negative -> the relative index is not recomputed, and the +// subarray construction fails. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.throws(RangeError, () => { + lengthTracking.subarray(evil, -1); + }); +} + +// Length-tracking TA + second parameter conversion shrinks. The second +// parameter is too large -> the subarray construction fails. +for (let ctor of ctors) { + const rab = CreateRabForTest(ctor); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 3; + } + }; + assert.throws(RangeError, () => { + lengthTracking.subarray(0, evil); + }); +} diff --git a/test/built-ins/TypedArray/prototype/subarray/resizable-buffer.js b/test/built-ins/TypedArray/prototype/subarray/resizable-buffer.js new file mode 100644 index 0000000000..d740f26b52 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/subarray/resizable-buffer.js @@ -0,0 +1,172 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype.subarray +description: > + TypedArray.p.subarray behaves correctly on TypedArrays backed by resizable + buffers. +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + const fixedLengthSubFull = fixedLength.subarray(0); + assert.compareArray(ToNumbers(fixedLengthSubFull), [ + 0, + 2, + 4, + 6 + ]); + const fixedLengthWithOffsetSubFull = fixedLengthWithOffset.subarray(0); + assert.compareArray(ToNumbers(fixedLengthWithOffsetSubFull), [ + 4, + 6 + ]); + const lengthTrackingSubFull = lengthTracking.subarray(0); + assert.compareArray(ToNumbers(lengthTrackingSubFull), [ + 0, + 2, + 4, + 6 + ]); + const lengthTrackingWithOffsetSubFull = lengthTrackingWithOffset.subarray(0); + assert.compareArray(ToNumbers(lengthTrackingWithOffsetSubFull), [ + 4, + 6 + ]); + + // Relative offsets + assert.compareArray(ToNumbers(fixedLength.subarray(-2)), [ + 4, + 6 + ]); + assert.compareArray(ToNumbers(fixedLengthWithOffset.subarray(-1)), [6]); + assert.compareArray(ToNumbers(lengthTracking.subarray(-2)), [ + 4, + 6 + ]); + assert.compareArray(ToNumbers(lengthTrackingWithOffset.subarray(-1)), [6]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + // We can create subarrays of OOB arrays (which have length 0), as long as + // the new arrays are not OOB. + assert.compareArray(ToNumbers(fixedLength.subarray(0)), []); + assert.compareArray(ToNumbers(fixedLengthWithOffset.subarray(0)), []); + assert.compareArray(ToNumbers(lengthTracking.subarray(0)), [ + 0, + 2, + 4 + ]); + assert.compareArray(ToNumbers(lengthTrackingWithOffset.subarray(0)), [4]); + + // Also the previously created subarrays are OOB. + assert.sameValue(fixedLengthSubFull.length, 0); + assert.sameValue(fixedLengthWithOffsetSubFull.length, 0); + + // Relative offsets + assert.compareArray(ToNumbers(lengthTracking.subarray(-2)), [ + 2, + 4 + ]); + assert.compareArray(ToNumbers(lengthTrackingWithOffset.subarray(-1)), [4]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.compareArray(ToNumbers(fixedLength.subarray(0)), []); + assert.compareArray(ToNumbers(lengthTracking.subarray(0)), [0]); + + // Even the 0-length subarray of fixedLengthWithOffset would be OOB -> + // this throws. + assert.throws(RangeError, () => { + fixedLengthWithOffset.subarray(0); + }); + + // Also the previously created subarrays are OOB. + assert.sameValue(fixedLengthSubFull.length, 0); + assert.sameValue(fixedLengthWithOffsetSubFull.length, 0); + assert.sameValue(lengthTrackingWithOffsetSubFull.length, 0); + + // Shrink to zero. + rab.resize(0); + assert.compareArray(ToNumbers(fixedLength.subarray(0)), []); + assert.compareArray(ToNumbers(lengthTracking.subarray(0)), []); + assert.throws(RangeError, () => { + fixedLengthWithOffset.subarray(0); + }); + assert.throws(RangeError, () => { + lengthTrackingWithOffset.subarray(0); + }); + + // Also the previously created subarrays are OOB. + assert.sameValue(fixedLengthSubFull.length, 0); + assert.sameValue(fixedLengthWithOffsetSubFull.length, 0); + assert.sameValue(lengthTrackingWithOffsetSubFull.length, 0); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert.compareArray(ToNumbers(fixedLength.subarray(0)), [ + 0, + 2, + 4, + 6 + ]); + assert.compareArray(ToNumbers(fixedLengthWithOffset.subarray(0)), [ + 4, + 6 + ]); + assert.compareArray(ToNumbers(lengthTracking.subarray(0)), [ + 0, + 2, + 4, + 6, + 8, + 10 + ]); + assert.compareArray(ToNumbers(lengthTrackingWithOffset.subarray(0)), [ + 4, + 6, + 8, + 10 + ]); + + // Also the previously created subarrays are no longer OOB. + assert.sameValue(fixedLengthSubFull.length, 4); + assert.sameValue(fixedLengthWithOffsetSubFull.length, 2); + // Subarrays of length-tracking TAs are also length-tracking. + assert.sameValue(lengthTrackingSubFull.length, 6); + assert.sameValue(lengthTrackingWithOffsetSubFull.length, 4); +} From efa4272ffbc8d597898207283d424137fe6f94ed Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 16 Aug 2024 14:56:25 +0200 Subject: [PATCH 71/90] Revert "Revert "Add valid index prototype chain [[Set]] tests"" This reverts commit bd65623af6ce11c11ddecec89432c47c75a2c6f6. --- .../key-is-valid-index-prototype-chain-set.js | 87 +++++++++++++++++++ .../key-is-valid-index-prototype-chain-set.js | 87 +++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-valid-index-prototype-chain-set.js create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/key-is-valid-index-prototype-chain-set.js diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-valid-index-prototype-chain-set.js b/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-valid-index-prototype-chain-set.js new file mode 100644 index 0000000000..15b80e4f97 --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-valid-index-prototype-chain-set.js @@ -0,0 +1,87 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-integer-indexed-exotic-objects-set-p-v-receiver +description: > + If receiver is altered, OrdinarySet result is returned for valid indices. + Value is not coerced. +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 2. If Type(P) is String, then + a. Let numericIndex be ! CanonicalNumericIndexString(P). + b. If numericIndex is not undefined, then + [...] + 3. Return ? OrdinarySet(O, P, V, Receiver). +includes: [testBigIntTypedArray.js] +features: [BigInt, TypedArray, Proxy] +---*/ + +var valueOfCalls = 0; +var value = { + valueOf: function() { + ++valueOfCalls; + return 2n; + }, +}; + +testWithBigIntTypedArrayConstructors(function(TA) { + var target, receiver; + + Object.defineProperty(TA.prototype, 0, { + get: function() { throw new Test262Error("0 getter should be unreachable!"); }, + set: function(_v) { throw new Test262Error("0 setter should be unreachable!"); }, + configurable: true, + }); + + + target = new TA([0n]); + receiver = Object.create(target); + receiver[0] = value; + assert.sameValue(target[0], 0n, "target[0] should remain unchanged (receiver: empty object)"); + assert.sameValue(receiver[0], value, "receiver[0] should be updated (receiver: empty object)"); + + + var proxyTrapCalls = 0; + target = new TA([0n]); + receiver = new Proxy(Object.create(target), { + defineProperty(_target, key, desc) { + ++proxyTrapCalls; + Object.defineProperty(_target, key, desc); + return true; + }, + }); + receiver[0] = value; + assert.sameValue(target[0], 0n, "target[0] should remain unchanged (receiver: proxy of an empty object)"); + assert.sameValue(receiver[0], value, "receiver[0] should be created (receiver: proxy of an empty object)"); + assert.sameValue(proxyTrapCalls, 1, "Proxy's [[DefineOwnProperty]] exotic method should be called"); + + + target = new TA([0n]); + receiver = Object.preventExtensions(Object.create(target)); + assert.throws(TypeError, function() { "use strict"; receiver[0] = value; }, + "setting receiver[0] should throw in strict mode (receiver: non-extensible empty object)"); + assert.sameValue(target[0], 0n, "target[0] should remain unchanged (receiver: non-extensible empty object)"); + assert(!receiver.hasOwnProperty(0), "receiver[0] should not be created (receiver: non-extensible empty object)"); + + + target = new TA([0n]); + receiver = Object.setPrototypeOf([], target); + receiver[0] = value; + assert.sameValue(target[0], 0n, "target[0] should remain unchanged (receiver: regular array)"); + assert.sameValue(receiver[0], value, "receiver[0] should be created (receiver: regular array)"); + assert.sameValue(receiver.length, 1, "Array's [[DefineOwnProperty]] exotic method should be called"); + + + target = new TA([0n]); + receiver = Object.setPrototypeOf(new String(""), target); + receiver[0] = value; + assert.sameValue(target[0], 0n, "target[0] should remain unchanged (receiver: empty String object)"); + assert.sameValue(receiver[0], value, "receiver[0] should be created (receiver: empty String object)"); + + + assert(delete TA.prototype[0]); +}); + +assert.sameValue(valueOfCalls, 0, "value should not be coerced"); diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/key-is-valid-index-prototype-chain-set.js b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-valid-index-prototype-chain-set.js new file mode 100644 index 0000000000..3816549054 --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-valid-index-prototype-chain-set.js @@ -0,0 +1,87 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-integer-indexed-exotic-objects-set-p-v-receiver +description: > + If receiver is altered, OrdinarySet result is returned for valid indices. + Value is not coerced. +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 2. If Type(P) is String, then + a. Let numericIndex be ! CanonicalNumericIndexString(P). + b. If numericIndex is not undefined, then + [...] + 3. Return ? OrdinarySet(O, P, V, Receiver). +includes: [testTypedArray.js] +features: [TypedArray, Proxy] +---*/ + +var valueOfCalls = 0; +var value = { + valueOf: function() { + ++valueOfCalls; + return 2.3; + }, +}; + +testWithTypedArrayConstructors(function(TA) { + var target, receiver; + + Object.defineProperty(TA.prototype, 0, { + get: function() { throw new Test262Error("0 getter should be unreachable!"); }, + set: function(_v) { throw new Test262Error("0 setter should be unreachable!"); }, + configurable: true, + }); + + + target = new TA([0]); + receiver = Object.create(target); + receiver[0] = value; + assert.sameValue(target[0], 0, "target[0] should remain unchanged (receiver: empty object)"); + assert.sameValue(receiver[0], value, "receiver[0] should be updated (receiver: empty object)"); + + + var proxyTrapCalls = 0; + target = new TA([0]); + receiver = new Proxy(Object.create(target), { + defineProperty(_target, key, desc) { + ++proxyTrapCalls; + Object.defineProperty(_target, key, desc); + return true; + }, + }); + receiver[0] = value; + assert.sameValue(target[0], 0, "target[0] should remain unchanged (receiver: proxy of an empty object)"); + assert.sameValue(receiver[0], value, "receiver[0] should be created (receiver: proxy of an empty object)"); + assert.sameValue(proxyTrapCalls, 1, "Proxy's [[DefineOwnProperty]] exotic method should be called"); + + + target = new TA([0]); + receiver = Object.preventExtensions(Object.create(target)); + assert.throws(TypeError, function() { "use strict"; receiver[0] = value; }, + "setting receiver[0] should throw in strict mode (receiver: non-extensible empty object)"); + assert.sameValue(target[0], 0, "target[0] should remain unchanged (receiver: non-extensible empty object)"); + assert(!receiver.hasOwnProperty(0), "receiver[0] should not be created (receiver: non-extensible empty object)"); + + + target = new TA([0]); + receiver = Object.setPrototypeOf([], target); + receiver[0] = value; + assert.sameValue(target[0], 0, "target[0] should remain unchanged (receiver: regular array)"); + assert.sameValue(receiver[0], value, "receiver[0] should be created (receiver: regular array)"); + assert.sameValue(receiver.length, 1, "Array's [[DefineOwnProperty]] exotic method should be called"); + + + target = new TA([0]); + receiver = Object.setPrototypeOf(new String(""), target); + receiver[0] = value; + assert.sameValue(target[0], 0, "target[0] should remain unchanged (receiver: empty String object)"); + assert.sameValue(receiver[0], value, "receiver[0] should be created (receiver: empty String object)"); + + + assert(delete TA.prototype[0]); +}); + +assert.sameValue(valueOfCalls, 0, "value should not be coerced"); From 44685c14d75fde3e003c0c06b4160420e467ba46 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 16 Aug 2024 14:56:25 +0200 Subject: [PATCH 72/90] Revert "Revert "Add valid index Reflect.set tests"" This reverts commit b90326d9a4ead2086d3fa86aab750802a9d1bce4. --- .../BigInt/key-is-valid-index-reflect-set.js | 87 ++++++++++++++++++ .../Set/key-is-valid-index-reflect-set.js | 89 +++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-valid-index-reflect-set.js create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/key-is-valid-index-reflect-set.js diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-valid-index-reflect-set.js b/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-valid-index-reflect-set.js new file mode 100644 index 0000000000..0a0cae6a3c --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-valid-index-reflect-set.js @@ -0,0 +1,87 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-integer-indexed-exotic-objects-set-p-v-receiver +description: > + If receiver is altered, OrdinarySet result is returned for valid indices. + Value is not coerced. +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 2. If Type(P) is String, then + a. Let numericIndex be ! CanonicalNumericIndexString(P). + b. If numericIndex is not undefined, then + [...] + 3. Return ? OrdinarySet(O, P, V, Receiver). +includes: [testBigIntTypedArray.js] +features: [BigInt, TypedArray, Reflect] +---*/ + +var valueOfCalls = 0; +var value = { + valueOf: function() { + ++valueOfCalls; + return 2n; + }, +}; + +testWithBigIntTypedArrayConstructors(function(TA) { + var target, receiver; + + Object.defineProperty(TA.prototype, 0, { + get: function() { throw new Test262Error("0 getter should be unreachable!"); }, + set: function(_v) { throw new Test262Error("0 setter should be unreachable!"); }, + configurable: true, + }); + + + target = new TA([0n]); + receiver = {}; + assert(Reflect.set(target, 0, value, receiver), "Reflect.set should succeed (receiver: empty object)"); + assert.sameValue(target[0], 0n, "target[0] should remain unchanged (receiver: empty object)"); + assert.sameValue(receiver[0], value, "receiver[0] should be created (receiver: empty object)"); + + + target = new TA([0n]); + receiver = new TA([1n]); + assert(Reflect.set(target, 0, Object(2n), receiver), "Reflect.set should succeed (receiver: another typed array of the same length)"); + assert.sameValue(target[0], 0n, "target[0] should remain unchanged (receiver: another typed array of the same length)"); + assert.sameValue(receiver[0], 2n, "receiver[0] should be updated (receiver: another typed array of the same length)"); + + + target = new TA([0n, 0n]); + receiver = new TA([1n]); + assert(!Reflect.set(target, 1, value, receiver), "Reflect.set should fail (receiver: another typed array of shorter length)"); + assert.sameValue(target[1], 0n, "target[1] should remain unchanged (receiver: another typed array of shorter length)"); + assert(!receiver.hasOwnProperty(1), "receiver[1] should not be created (receiver: another typed array of shorter length)"); + + + target = new TA([0n]); + receiver = Object.preventExtensions({}); + assert(!Reflect.set(target, 0, value, receiver), "Reflect.set should fail (receiver: non-extensible empty object)"); + assert.sameValue(target[0], 0n, "target[0] should remain unchanged (receiver: non-extensible empty object)"); + assert(!receiver.hasOwnProperty(0), "receiver[0] should not be created (receiver: non-extensible empty object)"); + + + target = new TA([0n]); + receiver = { + get 0() { return 1n; }, + set 0(_v) { throw new Test262Error("0 setter should be unreachable!"); }, + }; + assert(!Reflect.set(target, 0, value, receiver), "Reflect.set should fail (receiver: plain object with 0 accessor)"); + assert.sameValue(target[0], 0n, "target[0] should remain unchanged (receiver: plain object with 0 accessor)"); + assert.sameValue(receiver[0], 1n, "receiver[0] should remain unchanged (receiver: plain object with 0 accessor)"); + + + target = new TA([0n]); + receiver = Object.defineProperty({}, 0, { value: 1n, writable: false, configurable: true }); + assert(!Reflect.set(target, 0, value, receiver), "Reflect.set should fail (receiver: plain object with non-writable 0)"); + assert.sameValue(target[0], 0n, "target[0] should remain unchanged (receiver: plain object with non-writable 0)"); + assert.sameValue(receiver[0], 1n, "receiver[0] should remain unchanged (receiver: plain object with non-writable 0)"); + + + assert(delete TA.prototype[0]); +}); + +assert.sameValue(valueOfCalls, 0, "value should not be coerced"); diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/key-is-valid-index-reflect-set.js b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-valid-index-reflect-set.js new file mode 100644 index 0000000000..67d2be655c --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-valid-index-reflect-set.js @@ -0,0 +1,89 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-integer-indexed-exotic-objects-set-p-v-receiver +description: > + If receiver is altered, OrdinarySet result is returned for valid indices. + Value is not coerced. +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 2. If Type(P) is String, then + a. Let numericIndex be ! CanonicalNumericIndexString(P). + b. If numericIndex is not undefined, then + [...] + 3. Return ? OrdinarySet(O, P, V, Receiver). +includes: [testTypedArray.js] +features: [TypedArray, Reflect] +---*/ + +var valueOfCalls = 0; +var value = { + valueOf: function() { + ++valueOfCalls; + return 2.3; + }, +}; + +testWithTypedArrayConstructors(function(TA) { + function coerceValue(value) { return new TA([value])[0]; } + + var target, receiver; + + Object.defineProperty(TA.prototype, 0, { + get: function() { throw new Test262Error("0 getter should be unreachable!"); }, + set: function(_v) { throw new Test262Error("0 setter should be unreachable!"); }, + configurable: true, + }); + + + target = new TA([0]); + receiver = {}; + assert(Reflect.set(target, 0, value, receiver), "Reflect.set should succeed (receiver: empty object)"); + assert.sameValue(target[0], 0, "target[0] should remain unchanged (receiver: empty object)"); + assert.sameValue(receiver[0], value, "receiver[0] should be created (receiver: empty object)"); + + + target = new TA([0]); + receiver = new TA([1]); + assert(Reflect.set(target, 0, new Number(2.3), receiver), "Reflect.set should succeed (receiver: another typed array of the same length)"); + assert.sameValue(target[0], 0, "target[0] should remain unchanged (receiver: another typed array of the same length)"); + assert.sameValue(receiver[0], coerceValue(new Number(2.3)), "receiver[0] should be updated (receiver: another typed array of the same length)"); + + + target = new TA([0, 0]); + receiver = new TA([1]); + assert(!Reflect.set(target, 1, value, receiver), "Reflect.set should fail (receiver: another typed array of shorter length)"); + assert.sameValue(target[1], 0, "target[1] should remain unchanged (receiver: another typed array of shorter length)"); + assert(!receiver.hasOwnProperty(1), "receiver[1] should not be created (receiver: another typed array of shorter length)"); + + + target = new TA([0]); + receiver = Object.preventExtensions({}); + assert(!Reflect.set(target, 0, value, receiver), "Reflect.set should fail (receiver: non-extensible empty object)"); + assert.sameValue(target[0], 0, "target[0] should remain unchanged (receiver: non-extensible empty object)"); + assert(!receiver.hasOwnProperty(0), "receiver[0] should not be created (receiver: non-extensible empty object)"); + + + target = new TA([0]); + receiver = { + get 0() { return 1; }, + set 0(_v) { throw new Test262Error("0 setter should be unreachable!"); }, + }; + assert(!Reflect.set(target, 0, value, receiver), "Reflect.set should fail (receiver: plain object with 0 accessor)"); + assert.sameValue(target[0], 0, "target[0] should remain unchanged (receiver: plain object with 0 accessor)"); + assert.sameValue(receiver[0], 1, "receiver[0] should remain unchanged (receiver: plain object with 0 accessor)"); + + + target = new TA([0]); + receiver = Object.defineProperty({}, 0, { value: 1, writable: false, configurable: true }); + assert(!Reflect.set(target, 0, value, receiver), "Reflect.set should fail (receiver: plain object with non-writable 0)"); + assert.sameValue(target[0], 0, "target[0] should remain unchanged (receiver: plain object with non-writable 0)"); + assert.sameValue(receiver[0], 1, "receiver[0] should remain unchanged (receiver: plain object with non-writable 0)"); + + + assert(delete TA.prototype[0]); +}); + +assert.sameValue(valueOfCalls, 0, "value should not be coerced"); From 79faa2252a0ff343d97db23962bec4c0152168eb Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 16 Aug 2024 14:56:25 +0200 Subject: [PATCH 73/90] Revert "Revert "Add invalid index prototype chain [[Set]] tests"" This reverts commit 3d77404e4f2e73b604f0ae7a42ae7a5d5f1d47e6. --- ...nical-invalid-index-prototype-chain-set.js | 89 +++++++++++++++++++ ...nical-invalid-index-prototype-chain-set.js | 89 +++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-prototype-chain-set.js create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-prototype-chain-set.js b/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-prototype-chain-set.js new file mode 100644 index 0000000000..a329672afd --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-prototype-chain-set.js @@ -0,0 +1,89 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-integer-indexed-exotic-objects-set-p-v-receiver +description: > + If receiver is altered, `true` is returned for canonical numeric strings that are invalid indices. + Value is not coerced. +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 2. If Type(P) is String, then + a. Let numericIndex be ! CanonicalNumericIndexString(P). + b. If numericIndex is not undefined, then + i. If ! SameValue(O, Receiver) is true + [...] + ii. 1. Else if ! IsValidIntegerIndex(_O_, _numericIndex_) is *false*, return *true*. +includes: [testBigIntTypedArray.js] +features: [BigInt, TypedArray, Proxy] +---*/ + +var valueOfCalls = 0; +var value = { + valueOf: function() { + ++valueOfCalls; + return 2n; + }, +}; + +testWithBigIntTypedArrayConstructors(function(TA) { + var target, receiver; + + [1, 1.5, -1].forEach(function(key) { + Object.defineProperty(TA.prototype, key, { + get: function() { throw new Test262Error(key + " getter should be unreachable!"); }, + set: function(_v) { throw new Test262Error(key + " setter should be unreachable!"); }, + configurable: true, + }); + + + target = new TA([0n]); + receiver = Object.create(target); + receiver[key] = value; + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: empty object)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: empty object)"); + + + var proxyTrapCalls = 0; + target = new TA([0n]); + receiver = new Proxy(Object.create(target), { + defineProperty(_target, key, desc) { + ++proxyTrapCalls; + Object.defineProperty(_target, key, desc); + return true; + }, + }); + receiver[key] = value; + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: proxy of an empty object)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: proxy of an empty object)"); + assert.sameValue(proxyTrapCalls, 0, "Proxy's [[DefineOwnProperty]] exotic method should not be called (key: " + key + ")"); + + + target = new TA([0n]); + receiver = Object.preventExtensions(Object.create(target)); + receiver[key] = value; + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: non-extensible empty object)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: non-extensible empty object)"); + + + assert(delete TA.prototype[key]); + }); + + + target = new TA([0n]); + receiver = Object.setPrototypeOf([], target); + receiver[1] = value; + assert(!target.hasOwnProperty(1), "target[1] should not be created (receiver: regular array)"); + assert(!receiver.hasOwnProperty(1), "receiver[1] should not be created (receiver: regular array)"); + assert.sameValue(receiver.length, 0, "Array's [[DefineOwnProperty]] exotic method should not be called"); + + + target = new TA([0n]); + receiver = Object.setPrototypeOf(new String(""), target); + receiver[1] = value; + assert(!target.hasOwnProperty(1), "target[1] should not be created (receiver: empty String object)"); + assert(!receiver.hasOwnProperty(1), "receiver[1] should remain unchanged (receiver: empty String object)"); +}); + +assert.sameValue(valueOfCalls, 0, "value should not be coerced"); diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js new file mode 100644 index 0000000000..3771fe645e --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js @@ -0,0 +1,89 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-integer-indexed-exotic-objects-set-p-v-receiver +description: > + If receiver is altered, `true` is returned for canonical numeric strings that are invalid indices. + Value is not coerced. +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 2. If Type(P) is String, then + a. Let numericIndex be ! CanonicalNumericIndexString(P). + b. If numericIndex is not undefined, then + i. If ! SameValue(O, Receiver) is true + [...] + ii. 1. Else if ! IsValidIntegerIndex(_O_, _numericIndex_) is *false*, return *true*. +includes: [testTypedArray.js] +features: [TypedArray, Proxy] +---*/ + +var valueOfCalls = 0; +var value = { + valueOf: function() { + ++valueOfCalls; + return 2.3; + }, +}; + +testWithTypedArrayConstructors(function(TA) { + var target, receiver; + + [1, 1.5, -1].forEach(function(key) { + Object.defineProperty(TA.prototype, key, { + get: function() { throw new Test262Error(key + " getter should be unreachable!"); }, + set: function(_v) { throw new Test262Error(key + " setter should be unreachable!"); }, + configurable: true, + }); + + + target = new TA([0]); + receiver = Object.create(target); + receiver[key] = value; + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: empty object)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: empty object)"); + + + var proxyTrapCalls = 0; + target = new TA([0]); + receiver = new Proxy(Object.create(target), { + defineProperty(_target, key, desc) { + ++proxyTrapCalls; + Object.defineProperty(_target, key, desc); + return true; + }, + }); + receiver[key] = value; + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: proxy of an empty object)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: proxy of an empty object)"); + assert.sameValue(proxyTrapCalls, 0, "Proxy's [[DefineOwnProperty]] exotic method should not be called (key: " + key + ")"); + + + target = new TA([0]); + receiver = Object.preventExtensions(Object.create(target)); + receiver[key] = value; + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: non-extensible empty object)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: non-extensible empty object)"); + + + assert(delete TA.prototype[key]); + }); + + + target = new TA([0]); + receiver = Object.setPrototypeOf([], target); + receiver[1] = value; + assert(!target.hasOwnProperty(1), "target[1] should not be created (receiver: regular array)"); + assert(!receiver.hasOwnProperty(1), "receiver[1] should not be created (receiver: regular array)"); + assert.sameValue(receiver.length, 0, "Array's [[DefineOwnProperty]] exotic method should not be called"); + + + target = new TA([0]); + receiver = Object.setPrototypeOf(new String(""), target); + receiver[1] = value; + assert(!target.hasOwnProperty(1), "target[1] should not be created (receiver: empty String object)"); + assert(!receiver.hasOwnProperty(1), "receiver[1] should remain unchanged (receiver: empty String object)"); +}); + +assert.sameValue(valueOfCalls, 0, "value should not be coerced"); From 941813e1f0e64ae9a5c4c5c8075f49ff89b0c642 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 16 Aug 2024 14:56:25 +0200 Subject: [PATCH 74/90] Revert "Revert "Add invalid index Reflect.set tests"" This reverts commit b11068129241c61c8ea9a027d54dba3d03b46571. --- ...-is-canonical-invalid-index-reflect-set.js | 91 +++++++++++++++++++ ...-is-canonical-invalid-index-reflect-set.js | 91 +++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-reflect-set.js create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-reflect-set.js b/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-reflect-set.js new file mode 100644 index 0000000000..7be2b2356c --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-reflect-set.js @@ -0,0 +1,91 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-integer-indexed-exotic-objects-set-p-v-receiver +description: > + If receiver is altered, `true` is returned for canonical numeric strings that are invalid indices. + Value is not coerced. +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 2. If Type(P) is String, then + a. Let numericIndex be ! CanonicalNumericIndexString(P). + b. If numericIndex is not undefined, then + i. If ! SameValue(O, Receiver) is true + [...] + ii. 1. Else if ! IsValidIntegerIndex(_O_, _numericIndex_) is *false*, return *true*. +includes: [testBigIntTypedArray.js] +features: [BigInt, TypedArray, Reflect] +---*/ + +var valueOfCalls = 0; +var value = { + valueOf: function() { + ++valueOfCalls; + return 2n; + }, +}; + +testWithBigIntTypedArrayConstructors(function(TA) { + var target, receiver; + + [1, 1.5, -1].forEach(function(key) { + Object.defineProperty(TA.prototype, key, { + get: function() { throw new Test262Error(key + " getter should be unreachable!"); }, + set: function(_v) { throw new Test262Error(key + " setter should be unreachable!"); }, + configurable: true, + }); + + + target = new TA([0n]); + receiver = {}; + assert(Reflect.set(target, key, value, receiver), "Reflect.set should succeed (key: " + key + ", receiver: empty object)"); + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: empty object)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: empty object)"); + + + target = new TA([0n]); + receiver = new TA([1n]); + assert(Reflect.set(target, key, value, receiver), "Reflect.set should succeed (key: " + key + ", receiver: another typed array of the same length)"); + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: another typed array of the same length)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: another typed array of the same length)"); + + + target = new TA([0n]); + receiver = Object.defineProperty({}, key, { + get: function() { return 1n; }, + set: function(_v) { throw new Test262Error(key + " setter should be unreachable!"); }, + configurable: true, + }); + assert(Reflect.set(target, key, value, receiver), "Reflect.set should succeed (receiver: plain object with " + key + " accessor)"); + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: plain object with " + key + " accessor)"); + assert.sameValue(receiver[key], 1n, "receiver[" + key + "] should remain unchanged (receiver: plain object with " + key + " accessor)"); + + + target = new TA([0n]); + receiver = Object.defineProperty({}, key, { value: 1n, writable: false, configurable: true }); + assert(Reflect.set(target, key, value, receiver), "Reflect.set should succeed (receiver: plain object with non-writable " + key + ")"); + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: plain object with non-writable " + key + ")"); + assert.sameValue(receiver[key], 1n, "receiver[" + key + "] should remain unchanged (receiver: plain object with non-writable " + key + ")"); + + + target = new TA([0n]); + receiver = Object.preventExtensions({}); + assert(Reflect.set(target, key, value, receiver), "Reflect.set should fail (key: " + key + ", receiver: non-extensible empty object)"); + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: non-extensible empty object)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: non-extensible empty object)"); + + + assert(delete TA.prototype[key]); + }); + + + target = new TA([0n]); + receiver = new TA([1n, 1n]); + assert(Reflect.set(target, 1, value, receiver), "Reflect.set should succeed (receiver: another typed array of greater length)"); + assert(!target.hasOwnProperty(1), "target[1] should not be created (receiver: another typed array of greater length)"); + assert.sameValue(receiver[1], 1n, "receiver[1] should remain unchanged (receiver: another typed array of greater length)"); +}); + +assert.sameValue(valueOfCalls, 0, "value should not be coerced"); diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js new file mode 100644 index 0000000000..fa319037de --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js @@ -0,0 +1,91 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-integer-indexed-exotic-objects-set-p-v-receiver +description: > + If receiver is altered, `true` is returned for canonical numeric strings that are invalid indices. + Value is not coerced. +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 2. If Type(P) is String, then + a. Let numericIndex be ! CanonicalNumericIndexString(P). + b. If numericIndex is not undefined, then + i. If ! SameValue(O, Receiver) is true + [...] + ii. 1. Else if ! IsValidIntegerIndex(_O_, _numericIndex_) is *false*, return *true*. +includes: [testTypedArray.js] +features: [TypedArray, Reflect] +---*/ + +var valueOfCalls = 0; +var value = { + valueOf: function() { + ++valueOfCalls; + return 2.3; + }, +}; + +testWithTypedArrayConstructors(function(TA) { + var target, receiver; + + [1, 1.5, -1].forEach(function(key) { + Object.defineProperty(TA.prototype, key, { + get: function() { throw new Test262Error(key + " getter should be unreachable!"); }, + set: function(_v) { throw new Test262Error(key + " setter should be unreachable!"); }, + configurable: true, + }); + + + target = new TA([0]); + receiver = {}; + assert(Reflect.set(target, key, value, receiver), "Reflect.set should succeed (key: " + key + ", receiver: empty object)"); + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: empty object)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: empty object)"); + + + target = new TA([0]); + receiver = new TA([1]); + assert(Reflect.set(target, key, value, receiver), "Reflect.set should succeed (key: " + key + ", receiver: another typed array of the same length)"); + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: another typed array of the same length)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: another typed array of the same length)"); + + + target = new TA([0]); + receiver = Object.defineProperty({}, key, { + get: function() { return 1; }, + set: function(_v) { throw new Test262Error(key + " setter should be unreachable!"); }, + configurable: true, + }); + assert(Reflect.set(target, key, value, receiver), "Reflect.set should succeed (receiver: plain object with " + key + " accessor)"); + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: plain object with " + key + " accessor)"); + assert.sameValue(receiver[key], 1, "receiver[" + key + "] should remain unchanged (receiver: plain object with " + key + " accessor)"); + + + target = new TA([0]); + receiver = Object.defineProperty({}, key, { value: 1, writable: false, configurable: true }); + assert(Reflect.set(target, key, value, receiver), "Reflect.set should succeed (receiver: plain object with non-writable " + key + ")"); + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: plain object with non-writable " + key + ")"); + assert.sameValue(receiver[key], 1, "receiver[" + key + "] should remain unchanged (receiver: plain object with non-writable " + key + ")"); + + + target = new TA([0]); + receiver = Object.preventExtensions({}); + assert(Reflect.set(target, key, value, receiver), "Reflect.set should fail (key: " + key + ", receiver: non-extensible empty object)"); + assert(!target.hasOwnProperty(key), "target[" + key + "] should not be created (receiver: non-extensible empty object)"); + assert(!receiver.hasOwnProperty(key), "receiver[" + key + "] should not be created (receiver: non-extensible empty object)"); + + + assert(delete TA.prototype[key]); + }); + + + target = new TA([0]); + receiver = new TA([1, 1]); + assert(Reflect.set(target, 1, value, receiver), "Reflect.set should succeed (receiver: another typed array of greater length)"); + assert(!target.hasOwnProperty(1), "target[1] should not be created (receiver: another typed array of greater length)"); + assert.sameValue(receiver[1], 1, "receiver[1] should remain unchanged (receiver: another typed array of greater length)"); +}); + +assert.sameValue(valueOfCalls, 0, "value should not be coerced"); From dde3050bdbfb8f425084077b6293563932d57ebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Juli=C3=A1n=20Espina?= Date: Mon, 19 Aug 2024 16:33:17 +0000 Subject: [PATCH 75/90] Fix test regression in asyncHelpers.js (#4197) --- harness/asyncHelpers.js | 54 +++++++++++-------- ...cHelpers-throwsAsync-func-never-settles.js | 37 +++++++++++++ 2 files changed, 68 insertions(+), 23 deletions(-) create mode 100644 test/harness/asyncHelpers-throwsAsync-func-never-settles.js diff --git a/harness/asyncHelpers.js b/harness/asyncHelpers.js index 2d55fafebc..4763838afc 100644 --- a/harness/asyncHelpers.js +++ b/harness/asyncHelpers.js @@ -3,7 +3,7 @@ /*--- description: | A collection of assertion and wrapper functions for testing asynchronous built-ins. -defines: [asyncTest] +defines: [asyncTest, assert.throwsAsync] ---*/ /** @@ -50,18 +50,21 @@ function asyncTest(testFunc) { */ assert.throwsAsync = function (expectedErrorConstructor, func, message) { return new Promise(function (resolve) { - var expectedName = expectedErrorConstructor.name; - var expectation = "Expected a " + expectedName + " to be thrown asynchronously"; var fail = function (detail) { if (message === undefined) { throw new Test262Error(detail); } throw new Test262Error(message + " " + detail); }; - var res; + if (typeof expectedErrorConstructor !== "function") { + fail("assert.throwsAsync called with an argument that is not an error constructor"); + } if (typeof func !== "function") { fail("assert.throwsAsync called with an argument that is not a function"); } + var expectedName = expectedErrorConstructor.name; + var expectation = "Expected a " + expectedName + " to be thrown asynchronously"; + var res; try { res = func(); } catch (thrown) { @@ -70,28 +73,33 @@ assert.throwsAsync = function (expectedErrorConstructor, func, message) { if (res === null || typeof res !== "object" || typeof res.then !== "function") { fail(expectation + " but result was not a thenable"); } - + var onResFulfilled, onResRejected; + var resSettlementP = new Promise(function (onFulfilled, onRejected) { + onResFulfilled = onFulfilled; + onResRejected = onRejected; + }); try { - resolve(Promise.resolve(res).then( - function () { - fail(expectation + " but no exception was thrown at all"); - }, - function (thrown) { - var actualName; - if (thrown === null || typeof thrown !== "object") { - fail(expectation + " but thrown value was not an object"); - } else if (thrown.constructor !== expectedErrorConstructor) { - actualName = thrown.constructor.name; - if (expectedName === actualName) { - fail(expectation + - " but got a different error constructor with the same name"); - } - fail(expectation + " but got a " + actualName); - } - } - )); + res.then(onResFulfilled, onResRejected) } catch (thrown) { fail(expectation + " but .then threw synchronously"); } + resolve(resSettlementP.then( + function () { + fail(expectation + " but no exception was thrown at all"); + }, + function (thrown) { + var actualName; + if (thrown === null || typeof thrown !== "object") { + fail(expectation + " but thrown value was not an object"); + } else if (thrown.constructor !== expectedErrorConstructor) { + actualName = thrown.constructor.name; + if (expectedName === actualName) { + fail(expectation + + " but got a different error constructor with the same name"); + } + fail(expectation + " but got a " + actualName); + } + } + )); }); }; diff --git a/test/harness/asyncHelpers-throwsAsync-func-never-settles.js b/test/harness/asyncHelpers-throwsAsync-func-never-settles.js new file mode 100644 index 0000000000..60f73766d1 --- /dev/null +++ b/test/harness/asyncHelpers-throwsAsync-func-never-settles.js @@ -0,0 +1,37 @@ +// Copyright (C) 2024 Julián Espina. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + assert.throwsAsync returns a promise that never settles if func returns a thenable that never settles. +flags: [async] +includes: [asyncHelpers.js] +---*/ + +var realDone = $DONE; +var doneCalls = 0 +globalThis.$DONE = function () { + doneCalls++; +} + +function delay() { + var later = Promise.resolve(); + for (var i = 0; i < 100; i++) { + later = later.then(); + } + return later; +} + +(async function () { + // Spy on the promise returned by an invocation of assert.throwsAsync + // with a function that returns a thenable which never settles. + var neverSettlingThenable = { then: function () { } }; + const p = assert.throwsAsync(TypeError, function () { return neverSettlingThenable }); + assert(p instanceof Promise, "assert.throwsAsync should return a promise"); + p.then($DONE, $DONE); +})() + // Give it a long time to try. + .then(delay, delay) + .then(function () { + assert.sameValue(doneCalls, 0, "$DONE should not have been called") + }) + .then(realDone, realDone); From 5e57a7942841edecfeea9432dc4db7f98715104c Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 20 Aug 2024 11:32:18 +0200 Subject: [PATCH 76/90] update es-meta version to v0.4.2 --- .github/workflows/esmeta-test262.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/esmeta-test262.yml b/.github/workflows/esmeta-test262.yml index 642665a238..2c605d0177 100644 --- a/.github/workflows/esmeta-test262.yml +++ b/.github/workflows/esmeta-test262.yml @@ -21,7 +21,7 @@ jobs: - name: download esmeta run: | mkdir -p "${ESMETA_HOME}" - git clone --branch v0.4.1 --depth 1 https://github.com/es-meta/esmeta.git "${ESMETA_HOME}" + git clone --branch v0.4.2 --depth 1 https://github.com/es-meta/esmeta.git "${ESMETA_HOME}" cd "${ESMETA_HOME}" && git submodule update --init --depth 1 - name: build esmeta working-directory: ${{ env.ESMETA_HOME }} From 22967c5b7b9ac9f3ed3ebe11559d3ada08d81046 Mon Sep 17 00:00:00 2001 From: Michael Ficarra Date: Mon, 5 Aug 2024 18:00:00 -0600 Subject: [PATCH 77/90] Math.sqrt: add a test with exact input-output expectations --- test/built-ins/Math/sqrt/results.js | 1021 +++++++++++++++++++++++++++ 1 file changed, 1021 insertions(+) create mode 100644 test/built-ins/Math/sqrt/results.js diff --git a/test/built-ins/Math/sqrt/results.js b/test/built-ins/Math/sqrt/results.js new file mode 100644 index 0000000000..a644d1bc01 --- /dev/null +++ b/test/built-ins/Math/sqrt/results.js @@ -0,0 +1,1021 @@ +// Copyright 2024 Michael Ficarra. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 20.2.2.32 +description: > + Math.sqrt returns the best possible Number for the square root, not an approximation. +info: | + Math.sqrt ( x ) + + Return 𝔽(the square root of ℝ(_n_)). +---*/ + +// 1000 random non-negative finite doubles, with progressively larger magnitude exponents, and their square roots +const examples = [ + [2.6364218206773287, 1.6237061990019404], + [6.093135406384165, 2.4684277194976088], + [0.5577847536359243, 0.7468498869491274], + [18.826149681104784, 4.33891111698601], + [51.0071358534849, 7.141928020743761], + [0.09916483871835496, 0.31490449142296295], + [0.05495461478727153, 0.23442400642270309], + [0.025188429959113877, 0.15870863227661525], + [0.00812479431693535, 0.09013764095501585], + [1724.98994093245, 41.53299821747101], + [0.0029825902870519953, 0.05461309629614489], + [7267.933822887094, 85.25217781902755], + [0.0008860138193399767, 0.02976598426627241], + [25136.0059901805, 158.54338835214952], + [0.00017917048388385395, 0.013385457925818375], + [112728.51764979148, 335.7506778098765], + [0.00004969153203848829, 0.007049222087470949], + [0.00001941546662946677, 0.004406298517970244], + [933382.27260725, 966.1171112278521], + [0.000005294364184376967, 0.002300948540140993], + [3130866.954533674, 1769.42560016907], + [9.72044333465995e-7, 0.0009859230869930955], + [16080744.632595163, 4010.0803773235225], + [4.4205797932006607e-7, 0.0006648744086818698], + [1.756023173880081e-7, 0.00041904930185839484], + [111405072.76243196, 10554.860148880798], + [3.0892296725681764e-8, 0.00017576204574845436], + [1.8639944384971586e-8, 0.00013652818165115797], + [642938223.9516982, 25356.226532189252], + [6.7141406880308e-9, 0.00008193986019045187], + [3768749884.450741, 61390.144847937445], + [1.8258753524207704e-9, 0.00004273026272351681], + [8682620259.345915, 93180.5787669615], + [3.2719931235745735e-10, 0.000018088651479794103], + [1.7288819479897516e-10, 0.000013148695555034163], + [131195381256.19533, 362209.02978279727], + [5.1535438181624584e-11, 0.000007178818717701721], + [2.8633714112951604e-11, 0.000005351047945304883], + [1075736798229.0712, 1037177.3224618204], + [1769289622560.063, 1330146.4665818058], + [2.584443592924671e-12, 0.0000016076204753997976], + [1.6505683161263436e-12, 0.0000012847444555733034], + [9895708558925.95, 3145744.515838174], + [18685414632224.207, 4322662.909853625], + [1.6121069579556452e-13, 4.0151051766493555e-7], + [81368179193918.36, 9020431.20886792], + [4.853388692504837e-14, 2.203040783214155e-7], + [1.5241670622374688e-14, 1.2345716108178857e-7], + [975630473715166.6, 31235084.019659154], + [4.469656075594871e-15, 6.685548650331454e-8], + [3075560259258901, 55457733.989578955], + [7307054298634085, 85481309.64505683], + [7.428035353751654e-16, 2.7254422308593617e-8], + [2.3245002467788256e-16, 1.5246311838535985e-8], + [38651061189498650, 196598731.4035842], + [8.626254925032578e-17, 9.287763414855364e-9], + [245261483562121020, 495238814.6764357], + [2.359419496918105e-17, 4.857385610509119e-9], + [1.2379295553316081e-17, 3.5184223102572665e-9], + [4.115087182801168e-18, 2.0285677663812883e-9], + [2.978665174163489e-18, 1.7258809849359512e-9], + [8483294251614005000, 2912609526.114684], + [4.523188214083293e-19, 6.725465198841856e-10], + [24378912475850270000, 4937500630.46581], + [1.9581825550381185e-19, 4.425135653331001e-10], + [96034813220780460000, 9799735364.834116], + [2.920538955165126e-20, 1.7089584416144022e-10], + [1.750634688256351e-20, 1.3231155233978442e-10], + [754994936573400200000, 27477171189.432877], + [1.8632934465655627e21, 43165882900.336494], + [4.2056655125676105e21, 64851102631.8567], + [7.037373863164293e21, 83889056873.7323], + [5.016081426480113e-22, 2.239661007045511e-11], + [3.1360853670074786e-22, 1.7708995925821087e-11], + [1.4460461763569206e-22, 1.2025166012812133e-11], + [1.1138491594465553e23, 333743787874.2547], + [3.32077706603068e-23, 5.762618385795367e-12], + [4.50259352006827e23, 671013674977.5127], + [1.2030527277267097e-23, 3.4685050493356783e-12], + [3.9898456768622155e-24, 1.9974598060692525e-12], + [2.099099422079296e-24, 1.448826912394747e-12], + [1.2947577980725777e-24, 1.1378742452804605e-12], + [4.523588897224216e-25, 6.725763077320086e-13], + [2.6439027364270637e-25, 5.141889474139894e-13], + [6.161406847244829e25, 7849462941657.11], + [1.1262097160333162e26, 10612302841670.682], + [2.8903531131865582e26, 17001038536473.465], + [5.520139379052935e26, 23494976865391.75], + [1.164692380222816e27, 34127589721848.45], + [4.279137256127335e-27, 6.541511489042371e-14], + [3.4013217683189986e27, 58320851916951.61], + [8.3233105280907e-28, 2.88501482285459e-14], + [4.892374771987226e-28, 2.211871328081095e-14], + [2.644502650010035e-28, 1.6261926853881846e-14], + [7.787526091150166e28, 279061392728377.34], + [8.992269683411683e28, 299871133712661.4], + [3.987026745804168e-29, 6.314290732777647e-15], + [2.1265718826609917e-29, 4.611476859598226e-15], + [9.318934400304718e29, 965346279855302.4], + [3.478110095369478e-30, 1.8649691942146063e-15], + [3.0336290098099214e-30, 1.7417316124506442e-15], + [1.187505107289765e-30, 1.0897270792679079e-15], + [6.121852606868157e-31, 7.824226867153174e-16], + [3.330016415530198e31, 5770629441863511], + [1.1972007699823333e-31, 3.4600589156578435e-16], + [9.491784329862492e31, 9742578883366812], + [3.2090013924080404e-32, 1.7913685808364622e-16], + [5.953924050511395e32, 24400664028897644], + [7.943918556616615e32, 28184957968066256], + [1.5494270953537593e33, 39362762801329880], + [2.709475968421315e-33, 5.20526269118218e-17], + [5.895348228542645e33, 76781171054775180], + [5.837257350750867e-34, 2.4160416699119384e-17], + [3.637594352139908e34, 190724784759084400], + [1.4131093499710667e-34, 1.1887427602181503e-17], + [9.862394293586106e34, 314044491968671600], + [3.1845200900520636e-35, 5.64315522562694e-18], + [4.8782336780412935e35, 698443532294579600], + [1.110815576633264e-35, 3.33289000213518e-18], + [5.491170564095181e-36, 2.343324681749241e-18], + [1.508770843596759e-36, 1.228320334276348e-18], + [1.1699721732111957e-36, 1.0816525196250392e-18], + [6.612965083691836e-37, 8.132013947166985e-19], + [2.3376769318234387e-37, 4.834952876526759e-19], + [8.442517993381293e37, 9188317579068158000], + [1.3847550294555677e38, 11767561469801497000], + [3.723438694436284e-38, 1.9296213862922134e-19], + [1.882723158337299e-38, 1.3721235944102482e-19], + [7.125389733783852e-39, 8.441202363279683e-20], + [2.6849968016192544e39, 51816954769836240000], + [2.906000639202325e39, 53907333816488500000], + [9.295880368156956e-40, 3.0489146213295245e-20], + [1.4927361896539553e40, 122177583445325800000], + [2.3049623126773745e-40, 1.5182102333594564e-20], + [6.612130780424898e40, 257140638181227560000], + [7.787983839518702e-41, 8.824955433042539e-21], + [3.362042923738955e-41, 5.7983126198394606e-21], + [1.94114615866614e-41, 4.405844026592567e-21], + [9.468800250495811e41, 973077604844331600000], + [4.6047974907521363e-42, 2.1458791882937252e-21], + [3.17089316421976e42, 1.780700189313114e21], + [1.3918013247929126e-42, 1.1797462967913536e-21], + [1.200207317308855e43, 3.464400838974692e21], + [2.0319091746754344e-43, 4.507670323654376e-22], + [7.4327616786354335e43, 8.621346576165137e21], + [1.7268671846659664e44, 1.3141031864606243e22], + [2.0484061765160574e44, 1.4312254107987523e22], + [6.5456923007084346e44, 2.5584550613032926e22], + [9.328456638771375e44, 3.0542522225204937e22], + [3.760974008764618e-45, 6.132678051850283e-23], + [1.4122172352163547e-45, 3.757947891092098e-23], + [1.3300600995467618e-45, 3.646998902586566e-23], + [4.429527186753373e-46, 2.1046441948114111e-23], + [4.183050428910713e46, 2.045250700748129e23], + [1.2337655524558335e-46, 1.1107499954786557e-23], + [5.97546732989559e-47, 7.730114701539421e-24], + [3.1005119225635093e-47, 5.568224063885638e-24], + [5.6296556417084825e47, 7.50310311918241e23], + [1.3620262837869847e48, 1.1670588176210249e24], + [3.1130476432230247e-48, 1.7643830772321027e-24], + [4.870459456344632e48, 2.2069117463878415e24], + [9.858220813082454e48, 3.139780376568153e24], + [5.556962829131254e-49, 7.454503893037587e-25], + [2.589637950003785e49, 5.088848543633211e24], + [8.499087188535236e49, 9.219049402479215e24], + [1.141437146870446e50, 1.068380618913712e25], + [3.9388099652794106e-50, 1.9846435360737734e-25], + [1.710592494534373e-50, 1.3078962093890987e-25], + [8.869444860439435e-51, 9.417773017247462e-26], + [1.8157478720946456e51, 4.261159316541269e25], + [2.3728034589514474e-51, 4.8711430475315003e-26], + [1.1950714257640223e52, 1.0931932243496674e26], + [1.4016634209157064e52, 1.1839186715799807e26], + [2.8011285784075223e52, 1.6736572463941123e26], + [8.153815667314413e52, 2.8554886915052584e26], + [1.0637264599470274e53, 3.261481963689248e26], + [2.1530551611602513e-53, 4.640102543220625e-27], + [1.919404771488337e-53, 4.381101198886345e-27], + [1.398778231958682e54, 1.182699552700804e27], + [2.9296586655033626e54, 1.7116245690873226e27], + [1.7224158129622894e-54, 1.3124084017417328e-27], + [7.730559269102998e54, 2.7803883306299135e27], + [3.2899966756320666e-55, 5.73584926199431e-28], + [2.642441513471452e55, 5.140468376978359e27], + [6.830315646013029e55, 8.264572370070353e27], + [1.5249399316387194e56, 1.2348845823147682e28], + [3.1014249013844634e56, 1.7610862844802533e28], + [1.076148310797754e-56, 1.0373756845028486e-28], + [9.62492113199095e-57, 9.810668240232645e-29], + [4.1188883231917496e-57, 6.417856591722621e-29], + [1.6307004169851293e-57, 4.038193181343767e-29], + [1.1505235690700644e-57, 3.391936864197305e-29], + [4.772620584318082e-58, 2.1846328259728412e-29], + [2.1569523804262153e-58, 1.4686566584556838e-29], + [1.1647751060992745e-58, 1.0792474721301295e-29], + [7.5475260834017815e-59, 8.687649902822846e-30], + [3.0845980569349766e-59, 5.5539157870235815e-30], + [6.53471003867459e59, 8.083755339367088e29], + [8.868322438087189e59, 9.417177091935347e29], + [3.9544754004744846e-60, 1.9885862818782806e-30], + [2.18763082689505e-60, 1.4790641726764427e-30], + [6.432581762266233e-61, 8.020337749911929e-31], + [5.1761509221555365e-61, 7.194547186693222e-31], + [2.0987471033469038e-61, 4.581208468676037e-31], + [1.4083531117605594e-61, 3.7528031013637783e-31], + [2.0146258988532675e62, 1.4193751790324034e31], + [3.688455065160669e-62, 1.920535098653672e-31], + [6.448285106075812e62, 2.5393473779843142e31], + [8.904845547242042e-63, 9.436548917502649e-32], + [4.1290721987804467e-63, 6.425785709763785e-32], + [1.4682044892502313e-63, 3.8317156591404733e-32], + [1.0644526030301698e64, 1.031723123241003e32], + [4.4912608966110374e-64, 2.119259516107227e-32], + [2.504689501975298e-64, 1.5826210860390108e-32], + [5.746518613638574e64, 2.397189732507332e32], + [1.5276919882932144e65, 3.9085700560348335e32], + [3.9087997083184305e65, 6.25203943391149e32], + [7.512464344555431e65, 8.667447343108253e32], + [1.6420921069710679e66, 1.2814414176898871e33], + [1.9598989681860843e66, 1.3999639167443153e33], + [4.324485009209941e66, 2.0795396147248413e33], + [1.1478971583074518e-66, 1.0713996258667687e-33], + [2.0059262296399578e67, 4.478756780223679e33], + [1.94168179703729e-67, 4.406451857262587e-34], + [6.834230205628381e67, 8.266940308015041e33], + [6.158434038093654e-68, 2.481619237129994e-34], + [3.6938289932502024e68, 1.9219336599503643e34], + [1.264905179588931e-68, 1.124680034315952e-34], + [5.918784590915353e-69, 7.693363757756001e-35], + [3.0447177466729825e-69, 5.517896108729289e-35], + [4.447622918769664e69, 6.6690500963553e34], + [1.3357828040249557e70, 1.1557607036168672e35], + [2.947814701158749e-70, 1.7169201207856902e-35], + [5.479903009207335e70, 2.3409192658456498e35], + [1.131553461291788e-70, 1.0637450170467489e-35], + [4.790550608827023e-71, 6.921380360034422e-36], + [2.54391755369521e-71, 5.043726354289267e-36], + [7.495246645844719e71, 8.65750925257647e35], + [5.147631150891665e-72, 2.2688391637336624e-36], + [1.7842682854052505e72, 1.3357650562150704e36], + [5.393978612912003e72, 2.3224940501348984e36], + [1.0425513888847234e-72, 1.0210540577681102e-36], + [1.977350004555512e73, 4.4467403843214323e36], + [4.473107873130231e73, 6.688129688582774e36], + [7.812063748904077e73, 8.838587980500096e36], + [1.6975310044313772e74, 1.3028933204339398e37], + [3.2300906331893816e74, 1.797245290212046e37], + [5.559975934650521e74, 2.357960121514043e37], + [1.7823914887221356e75, 4.22183785657637e37], + [2.8066889548237318e75, 5.297819320082304e37], + [1.4324209107939194e-75, 3.7847336904912073e-38], + [5.75982981787146e-76, 2.3999645451280026e-38], + [2.84709401114082e76, 1.6873334024847668e38], + [4.5903215370624054e76, 2.1425035675728538e38], + [7.998760572609657e76, 2.8282080143811305e38], + [1.954729464018061e77, 4.421232253589559e38], + [3.1001981692242718e-77, 5.567942321202934e-39], + [5.446357966558231e77, 7.379944421578141e38], + [1.4347678702696647e78, 1.1978179620750662e39], + [3.191631668127788e-78, 1.786513830936606e-39], + [1.5003212059742984e-78, 1.2248759961621823e-39], + [9.461315908907407e-79, 9.726929581788595e-40], + [2.0626210170940118e79, 4.541608764627367e39], + [3.159471179501996e79, 5.620917344617331e39], + [1.3398724719445527e-79, 3.6604268493504317e-40], + [1.668072418684072e80, 1.2915387793961403e40], + [2.981112023363782e80, 1.7265897090402751e40], + [6.730415699386019e80, 2.59430447314613e40], + [1.146987159199044e81, 3.386719886850762e40], + [2.8388438747706336e-81, 5.328080212206488e-41], + [1.885863173736937e-81, 4.342652615322733e-41], + [8.168904869785256e81, 9.038199416800482e40], + [4.345402328538356e-82, 2.0845628626976822e-41], + [5.289561444406141e82, 2.2999046598513908e41], + [9.392344048036107e82, 3.064693140925549e41], + [1.2370130058650805e83, 3.517119568432498e41], + [2.2766481688304407e-83, 4.771423444665586e-42], + [6.272692440835879e83, 7.920033106519112e41], + [1.1372198484272548e84, 1.0664051052143622e42], + [3.091574311219671e84, 1.7582873232835614e42], + [1.3746815221495492e-84, 1.172468132679754e-42], + [1.4290753385479132e85, 3.780311281558588e42], + [4.544362100405665e-85, 6.741188397015518e-43], + [4.0560995194055724e85, 6.368751462732372e42], + [9.69623186841726e85, 9.8469446370015e42], + [2.1751510974085668e86, 1.4748393463047313e43], + [3.3647408154590466e86, 1.8343229855887013e43], + [1.1151391703566532e-86, 1.0560015011147728e-43], + [7.056575060080249e-87, 8.400342290692832e-44], + [2.142176308138171e-87, 4.628365054895919e-44], + [5.114917830494906e87, 7.15186537240104e43], + [8.165944247869666e-88, 2.8576116334921487e-44], + [2.875018702470018e88, 1.6955880108298766e44], + [2.1594319452794002e-88, 1.469500576821731e-44], + [7.527119560918543e-89, 8.675897395035595e-45], + [1.8374445944027442e89, 4.286542422982355e44], + [1.6767324851823106e-89, 4.0947924064380976e-45], + [7.417835243305932e89, 8.612685552895759e44], + [1.3811213798299968e90, 1.1752112064773705e45], + [3.6689238512159455e-90, 1.915443512927475e-45], + [6.065346263910295e90, 2.4627923712546895e45], + [1.3352594509051504e91, 3.6541202099891987e45], + [2.3510251243523464e91, 4.8487370771700403e45], + [1.4208669421331486e-91, 3.769438873536947e-46], + [1.2351207183001675e92, 1.1113598509484529e46], + [2.0458875580594228e92, 1.430345258341294e46], + [2.501775831168855e-92, 1.5817002975181028e-46], + [9.833334799593875e-93, 9.916317259746118e-47], + [1.443674272924411e93, 3.79957138757046e46], + [2.520868275101921e93, 5.020824907424996e46], + [6.448541902391714e93, 8.030281378875658e46], + [8.535272996692151e93, 9.2386541209703e46], + [1.9719051461783734e94, 1.404245400981742e47], + [4.792547889064161e94, 2.1891888655536694e47], + [1.2199529487370906e95, 3.4927824849782594e47], + [3.547959660180053e-95, 5.956475182673099e-48], + [3.985044064860309e95, 6.312720542571411e47], + [7.649929455714116e95, 8.746387514690918e47], + [1.6129741510041275e96, 1.270029192973188e48], + [3.0931163460970288e-96, 1.758725773421493e-48], + [1.6813486411690822e-96, 1.2966682849399387e-48], + [1.3180348897262367e97, 3.6304750236384175e48], + [3.1039403407959814e97, 5.571301769601052e48], + [1.5240410485097617e-97, 3.903896833306128e-49], + [6.971288070729216e-98, 2.6403196910088777e-49], + [5.735539804827279e-98, 2.394898704502401e-49], + [2.8535834407877993e98, 1.6892552917743958e49], + [9.871697492391928e-99, 9.935641646311489e-50], + [2.0088993541036913e99, 4.482074691595056e49], + [1.946317951646461e-99, 4.411709364460063e-50], + [9.390677962280974e-100, 3.064421309526641e-50], + [6.786330632385783e-100, 2.605058661985519e-50], + [2.9404933734963053e100, 1.7147866845460123e50], + [1.8531326172506335e-100, 1.3612981367983405e-50], + [1.119927915234845e101, 3.3465324071863475e50], + [3.884226801915178e-101, 6.232356538192578e-51], + [2.7269202968149374e-101, 5.2219922412954017e-51], + [8.254209708878875e101, 9.085268135216965e50], + [6.972532168924607e-102, 2.6405552766273625e-51], + [2.708617885299807e102, 1.6457879223338004e51], + [5.236877514456369e102, 2.2884224947453146e51], + [1.161433356069375e103, 3.4079808627241074e51], + [3.003819106806815e-103, 5.480710817774292e-52], + [4.439008636160038e103, 6.66258856313373e51], + [9.002276106267622e-104, 3.0003793270631003e-52], + [3.3960782967394955e-104, 1.842845163528259e-52], + [5.4149724334913127e104, 2.3270093324890885e52], + [9.152523378515453e104, 3.0253137653002956e52], + [1.9679279323943353e105, 4.436133375355542e52], + [2.888390108400342e105, 5.374374483044834e52], + [1.2821795498726208e-105, 3.580753481981999e-53], + [1.3003917169373775e106, 1.1403471914015386e53], + [4.2557699836238334e-106, 2.0629517647351412e-53], + [4.966486115455959e106, 2.2285614452951392e53], + [7.561962584675896e-107, 8.695954567887241e-54], + [1.8228493744993866e107, 4.2694840139054115e53], + [5.309397876047218e107, 7.286561518334432e53], + [8.787211807544319e107, 9.374012912058698e53], + [2.171532430163008e108, 1.4736120351581714e54], + [2.9516158424420328e-108, 1.7180267292571535e-54], + [8.472579233576034e108, 2.9107695260147333e54], + [1.2438387282560994e109, 3.526809788259213e54], + [2.58582397072793e109, 5.0850997735815666e54], + [7.142650627467428e109, 8.451420370249861e54], + [8.209521882901238e-110, 2.86522632315516e-55], + [3.345752216918009e-110, 1.8291397477825496e-55], + [2.299685403238757e-110, 1.5164713657826703e-55], + [6.295539155198952e110, 2.5090913006901425e55], + [5.43310320934929e-111, 7.370958695684904e-56], + [3.3217325941458126e111, 5.763447400771358e55], + [9.080493504293825e-112, 3.013385721127288e-56], + [4.972949414619484e-112, 2.2300110794835716e-56], + [2.1721331872931473e-112, 1.4738158593573172e-56], + [1.0727716873786853e-112, 1.0357469224567772e-56], + [1.1873055200390316e113, 3.445729995282613e56], + [2.3754165580184708e113, 4.8738245331756365e56], + [1.609299549103162e-113, 4.011607594348134e-57], + [8.969303837674172e-114, 2.9948796032018e-57], + [5.132332826100722e-114, 2.265465255990637e-57], + [3.724784734670678e114, 1.9299701382847035e57], + [1.5646836489831724e-114, 1.2508731546336633e-57], + [5.020232827545436e-115, 7.085360137315136e-58], + [3.3172031575574013e115, 5.759516609540597e57], + [1.6097392763493938e-115, 4.0121556255327306e-58], + [1.1375940996735337e116, 1.0665805640801512e58], + [3.2011962048050223e-116, 1.7891887001669283e-58], + [2.4028349243070718e-116, 1.5501080363339427e-58], + [1.230286517507037e117, 3.5075440375097745e58], + [5.7063306788576066e-117, 7.554025866289847e-59], + [3.81746944369302e117, 6.178567345018601e58], + [1.3262966997768381e-117, 3.6418356632017843e-59], + [6.215118914740789e-118, 2.4930140221709124e-59], + [3.3962400369703565e-118, 1.8428890462994121e-59], + [8.041976479629169e118, 2.8358378796449504e59], + [9.604637524630492e118, 3.099134963926304e59], + [3.2018333305125866e119, 5.658474468010425e59], + [3.974461700498037e119, 6.304333192731835e59], + [7.949516952470846e-120, 2.819488775021253e-60], + [2.2910901954456233e120, 1.5136347628954693e60], + [4.3047561134490487e120, 2.0747906191828246e60], + [8.443162099771256e-121, 9.188668075282324e-61], + [1.6803623278269906e121, 4.0992222772460026e60], + [3.466137788532709e-121, 5.887391432997053e-61], + [4.828680085021368e121, 6.94887047297715e60], + [1.488585954642875e122, 1.2200762085389892e61], + [2.085558231663234e122, 1.4441461946988726e61], + [4.810979496264978e122, 2.1933945145059924e61], + [9.271443477547573e-123, 9.62883351063231e-62], + [2.430333473853147e123, 4.9298412488163825e61], + [2.993319649043068e123, 5.471123878183592e61], + [1.1123330255382685e-123, 3.3351657013381934e-62], + [2.0685437908296826e124, 1.4382433002902125e62], + [3.2908617460684498e-124, 1.8140732471618807e-62], + [6.257641579642928e124, 2.501527849064033e62], + [1.3046045199205295e125, 3.6119309516109654e62], + [1.941505366402168e125, 4.40625165690995e62], + [6.765208720831414e125, 8.225088887563108e62], + [6.251642730647003e-126, 2.5003285245437254e-63], + [3.0641830188726155e-126, 1.750480796487815e-63], + [2.3196894914652613e-126, 1.5230526883418253e-63], + [8.220375952756892e126, 2.8671198009076794e63], + [2.09533707026623e127, 4.5774851941499824e63], + [4.1547513406756876e127, 6.445736064000517e63], + [1.436629465086068e-127, 3.7902895207174713e-64], + [5.85938717595173e-128, 2.4206171064321038e-64], + [2.471985659713248e-128, 1.5722549601490363e-64], + [5.819519862953747e128, 2.4123681027060831e64], + [9.218870861176231e128, 3.0362593534110736e64], + [5.620988360142958e-129, 7.497325096421362e-65], + [2.6361099341571754e-129, 5.1343061207500816e-65], + [8.255185333945022e129, 9.085805046304385e64], + [4.097861906979064e-130, 2.0243176398428837e-65], + [4.412087305581445e130, 2.100496918726958e65], + [6.23803731967102e130, 2.4976063179914924e65], + [1.299767257814368e131, 3.605228505676676e65], + [2.549273557804692e-131, 5.049033132991595e-66], + [1.637101885409647e-131, 4.046111572126561e-66], + [1.3221246389874849e132, 1.1498367879779655e66], + [3.612840396282678e-132, 1.9007473257334018e-66], + [1.70281157328564e-132, 1.3049182247503634e-66], + [8.912245931850124e-133, 9.440469231902683e-67], + [1.5427361520965407e133, 3.927768007528628e66], + [4.3098017678179273e133, 6.564908047960708e66], + [5.502730671085936e133, 7.418039276713177e66], + [1.1386671763785346e134, 1.0670834908190336e67], + [2.236312809103837e134, 1.495430643361248e67], + [6.236366484285548e134, 2.4972718082510657e67], + [5.743247779152324e-135, 7.578421853626469e-68], + [3.7844822222579143e-135, 6.15181454715429e-68], + [4.2707239060150784e135, 6.535077586391058e67], + [8.865447213092549e-136, 2.9774900861451325e-68], + [1.767098824964197e136, 1.329322694067997e68], + [3.135905087942047e-136, 1.7708486914307633e-68], + [5.117868324041611e136, 2.262270612469165e68], + [8.382019173328589e-137, 9.155336789724663e-69], + [2.6767187228501482e-137, 5.173701501681507e-69], + [5.72089957920286e137, 7.563662855523678e68], + [9.560405120961301e-138, 3.091990478795383e-69], + [1.6090135834811053e138, 1.2684689919273176e69], + [1.8358925481123047e-138, 1.3549511238831844e-69], + [9.201073744514271e138, 3.0333271739979303e69], + [1.3138614811165913e139, 3.624722721970042e69], + [2.764863859467541e-139, 5.258197276127571e-70], + [1.1469353514275982e-139, 3.3866433993374596e-70], + [1.2456670985142225e140, 1.1160945741800837e70], + [3.4128588296281774e-140, 1.8473924406114087e-70], + [1.784835945015018e-140, 1.3359775241429093e-70], + [9.357407295518402e140, 3.058987952823352e70], + [5.048358544655811e-141, 7.105180183961425e-71], + [4.4161437611876514e141, 6.645407257036736e70], + [9.379659653552042e-142, 3.062623002191429e-71], + [2.333480160468471e142, 1.527573291357397e71], + [2.4739236141094746e-142, 1.5728711371595178e-71], + [5.784299275618662e142, 2.4050570212821695e71], + [5.233592582491059e-143, 7.23435731941066e-72], + [3.9415846715456154e-143, 6.278204099538032e-72], + [1.1868816058647257e-143, 3.445114810662666e-72], + [6.577826324246065e-144, 2.564727339162209e-72], + [3.0725285828553693e144, 1.7528629675064075e72], + [4.0585639406710166e144, 2.0145877843050216e72], + [7.10962244957678e144, 2.6663875280192824e72], + [6.338440095951786e-145, 7.961432092250605e-73], + [2.56909001448098e145, 5.0686191556290556e72], + [1.110572217652152e-145, 3.3325248951090406e-73], + [1.5958927229227292e146, 1.2632864769808665e73], + [2.240196093605432e146, 1.4967284635515662e73], + [1.6192150761553748e-146, 1.2724838215692076e-73], + [5.479215508511587e-147, 7.402172322036003e-74], + [2.0747066085163763e147, 4.554894739196918e73], + [1.4523662643826972e-147, 3.810992343711408e-74], + [9.021039579731393e-148, 3.0035045496438647e-74], + [1.6374048701078094e148, 1.2796112183424343e74], + [2.878063529808568e-148, 1.696485640908454e-74], + [6.770526584989555e148, 2.602023555809892e74], + [6.443503565916299e-149, 8.027143679987483e-75], + [2.833320640745976e-149, 5.322894551600638e-75], + [6.097769380912148e149, 7.808821537794386e74], + [1.1834867852330407e150, 1.08788178826242e75], + [2.462709399587796e-150, 1.5693022014856783e-75], + [1.9879288113628234e-150, 1.4099392935026754e-75], + [9.478052690900818e-151, 9.735529102673782e-76], + [4.05005514259216e-151, 6.364004354643513e-76], + [4.5346562200806216e151, 6.733985610380098e75], + [8.142463934449162e151, 9.023560236652251e75], + [1.1660827207891676e152, 1.0798531014861085e76], + [2.435729824085869e-152, 1.5606824866339307e-76], + [1.583997049543372e-152, 1.2585694456577961e-76], + [6.60974084990108e-153, 8.130031272941747e-77], + [3.273811472025356e-153, 5.721723055186572e-77], + [1.2653205989779825e-153, 3.557134519494564e-77], + [7.710625323033553e153, 8.781016639907677e76], + [5.083379212603646e-154, 2.254635050868243e-77], + [1.9920577485201303e-154, 1.4114027591442955e-77], + [7.861241441904935e154, 2.803790548865042e77], + [1.6728236347700093e155, 4.090016668389029e77], + [3.251820444921185e155, 5.70247353779146e77], + [4.440892237648901e155, 6.664001979027993e77], + [1.1681842368440651e156, 1.0808257199216094e78], + [1.7915485035054454e156, 1.3384873938537655e78], + [6.646174087313228e156, 2.5780174722668633e78], + [7.032837066076427e156, 2.6519496726137974e78], + [2.4094941590204663e157, 4.908659856845315e78], + [1.905174102120031e-157, 4.364830010573185e-79], + [1.0178435770051598e-157, 3.190366087152319e-79], + [1.7180009240411648e158, 1.3107253427172165e79], + [2.6929244128629224e-158, 1.6410132275100413e-79], + [8.485212227840385e158, 2.9129387614298355e79], + [5.41881199646115e-159, 7.361258042251439e-80], + [2.7472768415354795e159, 5.241447168040025e79], + [4.799301551799175e159, 6.927699150366719e79], + [1.1374786077016586e160, 1.066526421473776e80], + [4.3816782112557046e-160, 2.0932458554254215e-80], + [2.3517038127806393e-160, 1.5335265934377009e-80], + [1.237208646167306e-160, 1.1122988115462976e-80], + [5.7767171821779034e-161, 7.6004718157348e-81], + [2.0612249668487447e-161, 4.540071548829099e-81], + [6.711421209045612e161, 8.192326415033529e80], + [7.808511908558749e-162, 2.7943714693216343e-81], + [3.4473128106975573e162, 1.8566940541450435e81], + [1.8369041700619853e-162, 1.3553243781700326e-81], + [1.260738215622096e163, 3.550687561053628e81], + [4.993183184923244e-163, 7.066245951651588e-82], + [1.8680839626659697e-163, 4.322133689123891e-82], + [1.1211916206658371e164, 1.0588633626043716e82], + [1.8155531144088822e164, 1.3474246229043323e82], + [1.963483009831839e-164, 1.4012433799421995e-82], + [7.742158677595007e164, 2.7824734819212578e82], + [8.524310818712796e-165, 9.232719436175236e-83], + [3.6811311730063326e165, 6.067232625346034e82], + [1.2546946077241453e-165, 3.542166861857506e-83], + [1.0803027221133152e166, 1.0393761215812663e83], + [1.9445301455466088e166, 1.3944641069409455e83], + [2.1307013933368853e-166, 1.4596922255519776e-83], + [6.228420706812873e166, 2.495680409590313e83], + [2.2496095146137002e167, 4.743004864654579e83], + [3.1351722345912756e-167, 5.599260874964905e-84], + [5.193151860234628e167, 7.206352655979741e83], + [5.13033154406953e-168, 2.2650235195400354e-84], + [3.5533385843503496e168, 1.8850301282341218e84], + [1.5884445082387458e-168, 1.2603350777625552e-84], + [7.914791185532489e-169, 8.896511218186873e-85], + [2.9993932318039227e169, 5.47667164599442e84], + [1.6626831066640226e-169, 4.0776011411907645e-85], + [8.355521887396055e-170, 2.8905919614148334e-85], + [3.905302516244791e-170, 1.9761838265315275e-85], + [2.0604906035449972e-170, 1.4354409091094614e-85], + [5.560844553380822e170, 2.3581443029171946e85], + [4.314951945149526e-171, 6.56882938212702e-86], + [2.8204375498860285e-171, 5.310779180013069e-86], + [1.5205372644544306e-171, 3.899406704172355e-86], + [1.2639861342741105e172, 1.1242713792826493e86], + [3.267362329351932e-172, 1.807584667270646e-86], + [4.9318723152088004e172, 2.2207819152741678e86], + [9.851995727572769e-173, 9.925722002742556e-87], + [1.341334816546909e173, 3.662423810193065e86], + [3.0549427174435646e173, 5.527153623198441e86], + [7.276217164805913e173, 8.530074539419871e86], + [1.163454185954185e174, 1.0786353350202213e87], + [2.86877797094319e174, 1.6937467257365222e87], + [7.223700701025096e174, 2.687694309445383e87], + [9.652804348451466e174, 3.106896256467452e87], + [1.881537005213637e175, 4.337668734716423e87], + [4.5425564549011394e175, 6.739849000460722e87], + [6.40966011070583e175, 8.006035292643814e87], + [5.185011052471997e-176, 2.2770619342635363e-88], + [2.749158746457103e-176, 1.6580587282895328e-88], + [5.11714070126712e176, 2.2621097898349495e88], + [1.2048028177393118e177, 3.4710269629308725e88], + [2.221500865954068e177, 4.713280031945978e88], + [1.0311112869226584e-177, 3.211092161434577e-89], + [1.1094139445051383e178, 1.0532872089345519e89], + [2.490487124239358e-178, 1.57812772747942e-89], + [2.330135386790282e-178, 1.5264780990208416e-89], + [6.750127466470132e178, 2.598100742171121e89], + [5.9812615013650325e-179, 7.733861584852054e-90], + [3.0495885975809073e-179, 5.522308029783297e-90], + [7.559930703547839e179, 8.694786198376496e89], + [1.8861963610062518e180, 1.3733886416474588e90], + [4.123445043401793e180, 2.0306267612246702e90], + [1.2995584883700009e-180, 1.1399817929993448e-90], + [7.508262971805556e-181, 8.665023353578198e-91], + [2.8581459679089006e-181, 5.34616308010605e-91], + [2.010774000939296e-181, 4.4841654752465326e-91], + [7.055998721396565e181, 8.399999238926492e90], + [4.7712328879494584e-182, 2.1843151988551146e-91], + [2.641251438357198e-182, 1.62519273883352e-91], + [9.978590503605425e182, 3.1588907077652157e91], + [1.805969017437007e183, 4.2496694194219475e91], + [3.311401730637796e183, 5.754478022060555e91], + [6.1836920680944595e183, 7.863645508346914e91], + [1.4451878655158245e184, 1.2021596672305325e92], + [3.012040084411346e-184, 1.735523000254202e-92], + [1.601953307742924e-184, 1.2656829412388096e-92], + [9.580089286745693e184, 3.095171931693891e92], + [4.669187498473844e-185, 6.8331453215000805e-93], + [4.144610141860627e185, 6.437864662961335e92], + [9.492697652515747e185, 9.743047599450465e92], + [6.05640687564016e-186, 2.460976813308114e-93], + [3.3900197014146888e-186, 1.8412006141142493e-93], + [1.1088203277756655e-186, 1.0530053787971197e-93], + [5.446058191563198e-187, 7.379741317663647e-94], + [3.4818280071502916e-187, 5.900701659252305e-94], + [4.83733978937074e187, 6.955098697625174e93], + [7.102790120358866e187, 8.427805242385984e93], + [1.70224544101063e188, 1.3047012842067067e94], + [3.587555480751102e188, 1.8940843383416436e94], + [1.111578363088116e189, 3.3340341376298413e94], + [4.831202505642164e-189, 6.950685222078586e-95], + [4.39742526156247e189, 6.631308514586295e94], + [6.600035403065669e189, 8.124060193687433e94], + [1.3115415331164787e190, 1.1452255381000193e95], + [4.082081721360552e-190, 2.0204162247815552e-95], + [1.2912499941463614e-190, 1.1363318151606781e-95], + [1.3706120747889848e191, 3.702177838501258e95], + [4.8269484074059805e-191, 6.947624347506117e-96], + [3.492057097322307e191, 5.909362992169551e95], + [1.2855154679277422e-191, 3.5854085791269903e-96], + [6.804598198429846e-192, 2.6085624773867015e-96], + [3.044118876083912e-192, 1.7447403463220285e-96], + [1.6633732162998678e-192, 1.2897182701271886e-96], + [5.92061069636697e-193, 7.694550471838475e-97], + [3.417479980242522e193, 5.845921638409569e96], + [1.7967018876867518e-193, 4.2387520423902503e-97], + [1.3497017505311573e194, 1.1617666506365025e97], + [2.772095891650699e-194, 1.6649612282725082e-97], + [1.929589035259489e-194, 1.3890964816237528e-97], + [1.190348587338919e-194, 1.0910309745093945e-97], + [6.688968337750512e-195, 8.178611335520544e-98], + [3.0025634753608016e195, 5.479565197495876e97], + [1.0389120965689685e-195, 3.2232159353182783e-98], + [4.790853668250854e-196, 2.1888018796252104e-98], + [2.0328636857920928e196, 1.425785287409045e98], + [7.39313791205219e196, 2.7190325323637063e98], + [1.0520367544930053e-196, 1.0256884295403772e-98], + [3.7249037335101477e-197, 6.103198942775951e-99], + [1.4647096086784373e-197, 3.827152477597982e-99], + [8.710278890747314e197, 9.332887490346872e98], + [1.9895606316593648e198, 1.4105178593904315e99], + [3.337969037792304e-198, 1.8270109572173628e-99], + [8.764480026910918e198, 2.9604864510601834e99], + [4.882878087920101e-199, 6.987759360424557e-100], + [2.9226901340764247e-199, 5.406191019633347e-100], + [1.6113055482971697e-199, 4.014107059231442e-100], + [1.394294883676362e200, 1.180802643830188e100], + [3.43448576367021e-200, 1.8532365644110873e-100], + [1.343973340598184e-200, 1.1592986416787454e-100], + [1.0734811999880925e-200, 1.0360893783781844e-100], + [1.8076042552476152e201, 4.2515929429422276e100], + [3.885559777670769e201, 6.233425845929964e100], + [1.4626690461917114e-201, 3.824485646713439e-101], + [7.932134017217473e-202, 2.816404448444412e-101], + [2.2191420551232144e202, 1.489678507303913e101], + [7.464395046342848e202, 2.732104508678767e101], + [5.794039047818522e-203, 7.61185854296999e-102], + [2.828625409058378e-203, 5.318482310827383e-102], + [2.3327529102932513e-203, 4.829858083104773e-102], + [7.593036024779165e203, 8.713802857982939e101], + [1.894697070646319e204, 1.376479956500028e102], + [2.728232221942395e204, 1.651736123581002e102], + [6.0915439225658e204, 2.4681053305249756e102], + [4.206419733866126e-205, 6.485691739410782e-103], + [3.5864263971120897e205, 5.988677981918956e102], + [4.305257846248795e205, 6.561446369702944e102], + [1.3002967826868136e206, 1.1403055654897128e103], + [2.1373652233536096e206, 1.4619730583542262e103], + [4.840419963714771e206, 2.2000954442284478e103], + [1.0701181890744888e207, 3.2712660990425233e103], + [5.158083681752355e-207, 7.181980006761613e-104], + [3.1029727382874974e-207, 5.5704333209253094e-104], + [1.274831055377559e-207, 3.570477636644093e-104], + [1.3489686157315508e208, 1.1614510819365364e104], + [2.6307645245628207e208, 1.621963169915649e104], + [5.550183956658152e208, 2.3558828401807574e104], + [6.286081390232014e-209, 7.928481185089622e-105], + [1.9643885770481934e209, 4.432142345467024e104], + [6.454330742797223e209, 8.03388495237343e104], + [7.721811800325596e-210, 2.7788148193655502e-105], + [1.8207023725207008e210, 1.3493340477882786e105], + [3.218033715400385e210, 1.793887877042594e105], + [1.5182930144642057e-210, 1.2321903320770724e-105], + [1.658390863592661e211, 4.0723345437140364e105], + [2.3535094105232726e211, 4.851298187622848e105], + [1.742926489493158e-211, 4.174837109987835e-106], + [1.3058146787525189e212, 1.1427224854497783e106], + [3.52712070015826e-212, 1.878063018154146e-106], + [5.9645421531910525e212, 2.4422412151937514e106], + [7.663654818804923e-213, 8.754230302433745e-107], + [3.720293489637861e-213, 6.099420865654264e-107], + [2.8220309837206994e-213, 5.312279156558604e-107], + [8.366565616612615e-214, 2.892501619120137e-107], + [1.6998855564459006e214, 1.3037965932022911e107], + [2.183583955369743e214, 1.477695488038636e107], + [5.491510206105432e214, 2.3433971507419378e107], + [1.2243259828922321e215, 3.499036985932318e107], + [2.5079076905528487e215, 5.007901447265959e107], + [1.5526912646129438e-215, 3.940420364140029e-108], + [5.984306608120332e-216, 2.4462842451604704e-108], + [4.720225715614302e-216, 2.1726080446353644e-108], + [4.034622111402736e216, 2.0086368789312658e108], + [1.1275867337969803e-216, 1.0618788696442643e-108], + [5.963731360409445e-217, 7.722519899883357e-109], + [3.0055039546043495e217, 5.48224767281117e108], + [6.560742304146522e217, 8.099840926923517e108], + [1.1135721656144034e218, 1.055259288333632e109], + [2.6056709456206447e-218, 1.6142090774186114e-109], + [5.366173850389301e218, 2.3165003454325884e109], + [5.867216543541286e-219, 7.659775808430222e-110], + [1.5526576580419578e219, 3.9403777205262416e109], + [3.384048562478265e219, 5.817257569059724e109], + [7.994346698689276e-220, 2.827427576205848e-110], + [5.056795334717539e-220, 2.248731939275453e-110], + [3.277143910889988e220, 1.8102883502055654e110], + [8.323920791290883e220, 2.8851205852253184e110], + [7.345976724953095e-221, 8.570867356897489e-111], + [3.3397269591736347e221, 5.7790370817062894e110], + [2.1951148131975832e-221, 4.685205239045119e-111], + [9.83176320579265e221, 9.915524799924938e110], + [4.188876382334804e-222, 2.046674469068006e-111], + [1.5593712958067274e-222, 1.2487478912121242e-111], + [8.651349400967479e-223, 9.30126303303346e-112], + [1.9994770517608634e223, 4.471551242869597e111], + [2.599110284403816e-223, 5.098147001022839e-112], + [1.4067506928660039e-223, 3.7506675310749736e-112], + [1.4481336677122486e224, 1.2033842560513448e112], + [1.9628488748790776e224, 1.401017085862652e112], + [1.613780409522561e-224, 1.2703465706343923e-112], + [7.583018780057219e224, 2.753728160159826e112], + [5.324383114632452e-225, 7.296837064531763e-113], + [4.819180723659685e225, 6.9420319241989125e112], + [1.0751674764144168e226, 1.0369028288197583e113], + [1.4222458161267847e226, 1.1925794800040728e113], + [2.4296291089302997e226, 1.5587267589062235e113], + [9.10364186556454e-227, 9.541300679448552e-114], + [7.664339137733834e-227, 8.754621144135156e-114], + [3.078940893781277e-227, 5.548820499692955e-114], + [1.7070782807027268e-227, 4.131680385391308e-114], + [9.620445845911016e-228, 3.1016843562669328e-114], + [2.739707225998974e228, 1.6552060977409955e114], + [2.105544610440993e-228, 1.4510494858691046e-114], + [1.0901656892505088e-228, 1.044109998635445e-114], + [2.1783998058035627e229, 4.6673330776831886e114], + [2.7334296403019473e229, 5.22822115092882e114], + [7.906784117899939e229, 8.892009962826143e114], + [1.2763298709108703e230, 1.1297477023259973e115], + [3.7395189017675573e230, 1.9337835715941837e115], + [4.662457923757396e230, 2.159272545038582e115], + [8.065462200139888e230, 2.839975739357625e115], + [2.7784108705151504e231, 5.271063337235809e115], + [5.762773217325168e231, 7.591293181879599e115], + [1.0807699610815717e-231, 3.287506594794255e-116], + [5.1187539345449674e-232, 2.2624663388755573e-116], + [2.2776012171256968e-232, 1.5091723616359056e-116], + [5.760671142152797e232, 2.4001398172091554e116], + [6.109982493590774e-233, 7.816637700182076e-117], + [2.7776845455513406e233, 5.2703743183490685e116], + [6.1461076150762305e233, 7.839711483898008e116], + [6.684307446140772e-234, 2.5854027628477486e-117], + [2.133225887264769e234, 1.460556704570134e117], + [1.2587230854515603e-234, 1.1219282889077894e-117], + [6.94302784909868e-235, 8.332483332775818e-118], + [2.115442757878419e235, 4.5993942621593325e117], + [2.6814031611038588e-235, 5.178226685945546e-118], + [1.4644892248261278e-235, 3.8268645453244457e-118], + [4.965498778069491e-236, 2.2283399152888436e-118], + [4.0062724232429093e236, 2.001567491553285e118], + [1.0070033023400693e-236, 1.003495541763923e-118], + [8.49169358153587e236, 2.914051060214263e118], + [2.4744875263587095e237, 4.974422103479669e118], + [5.211096062451675e237, 7.218792185990448e118], + [9.021973557613818e237, 9.498407002026086e118], + [1.955698867623561e238, 1.398463037632229e119], + [3.1870358496382564e238, 1.7852271143017787e119], + [1.1767391497682072e-238, 1.0847760827784723e-119], + [4.4017246051207265e-239, 6.634549423375129e-120], + [3.269537309371882e239, 5.71798680426239e119], + [7.930808198257907e239, 8.905508519033546e119], + [1.4486518290238644e240, 1.2035995301693435e120], + [2.8991415762931794e240, 1.702686576059487e120], + [1.6817917282383117e-240, 1.2968391296680987e-120], + [1.0670902139648442e-240, 1.0330005875917226e-120], + [3.392635344432064e-241, 5.824633331319718e-121], + [5.058549388122564e241, 7.112347986510899e120], + [1.1134390902629017e-241, 3.336823474897798e-121], + [6.7759154382504495e-242, 2.603058861848969e-121], + [2.3950894906446155e-242, 1.547607666899016e-121], + [1.7440131843329147e-242, 1.3206109133022167e-121], + [1.2495592926661218e243, 3.5349105966998966e121], + [3.782275124743448e-243, 6.150020426586767e-122], + [1.8975316610917503e-243, 4.3560666444531706e-122], + [9.071570348531914e243, 9.524479171341557e121], + [2.4768707198353443e244, 1.573807713742484e122], + [1.55066206748012e-244, 1.2452558241100982e-122], + [9.772649676191643e244, 3.1261237461418002e122], + [5.325183733004515e-245, 7.297385650357609e-123], + [2.458620835671438e-245, 4.958448180299395e-123], + [1.0286760303875382e-245, 3.207297975535697e-123], + [1.027203508067744e246, 1.0135104873989929e123], + [2.4430828477738524e246, 1.563036419209051e123], + [4.0785834590031695e246, 2.019550311084913e123], + [5.755379386024469e-247, 7.58642167693338e-124], + [1.6868902308558232e247, 4.1071769268632965e123], + [2.3567688475284907e-247, 4.854656370463816e-124], + [9.859407940096723e247, 9.929455141193158e123], + [1.8386051560036232e248, 1.3559517528303221e124], + [2.1964082707846216e-248, 1.48202843116609e-124], + [5.598771249322913e248, 2.3661722780311056e124], + [8.670911616466196e-249, 9.311772987173922e-125], + [2.5833259747972307e249, 5.082642988443346e124], + [1.4071068008571067e-249, 3.7511422271850834e-125], + [9.55443868847519e-250, 3.0910255075743373e-125], + [2.5382793668679673e250, 1.59319784297744e125], + [1.5554641250664774e-250, 1.247182474646945e-125], + [8.61840455427426e-251, 9.283536262801078e-126], + [4.059388356440167e-251, 6.371332950364599e-126], + [3.7314447147512766e251, 6.1085552422412265e125], + [1.5210973593336573e-251, 3.9001248176611696e-126], + [9.756602885865253e251, 9.877551764412704e125], + [2.2009398161443592e252, 1.483556475549333e126], + [1.978437998183238e-252, 1.4065695852616883e-126], + [1.0564351500100374e253, 3.2502848336877146e126], + [3.6131821393046605e-253, 6.010975078391742e-127], + [1.657707740565561e-253, 4.0714957209428095e-127], + [6.959133905107306e-254, 2.6380170403367953e-127], + [1.2833488995008763e254, 1.1328499015760545e127], + [2.68978130196551e254, 1.6400552740580147e127], + [6.644336716912607e254, 2.577661094269882e127], + [1.2949675889582017e255, 3.5985658100946296e127], + [2.907391109101237e255, 5.392022912693562e127], + [1.49263741115478e-255, 3.863466592523844e-128], + [8.603678754036722e-256, 2.9332028150192274e-128], + [2.7210277398978328e256, 1.6495538002435182e128], + [1.4399522364166417e-256, 1.1999800983419023e-128], + [7.183134232594344e256, 2.680136980192308e128], + [5.2719329627496335e-257, 7.260807780646472e-129], + [4.340847884131169e257, 6.588511124777106e128], + [1.4718196694482473e-257, 3.836430201956302e-129], + [6.623656994793045e-258, 2.573646633629614e-129], + [3.120658943705647e258, 1.766538690124178e129], + [4.04000638809245e258, 2.0099767133209403e129], + [8.023454180088804e258, 2.832570242745765e129], + [4.004851762548488e-259, 6.328389813016016e-130], + [5.801938865318406e259, 7.617045926944649e129], + [8.689808547636416e259, 9.32191426029891e129], + [2.1927090421968508e260, 1.4807798763478826e130], + [3.303438678181491e260, 1.8175364310465667e130], + [1.2874125055248046e-260, 1.1346420164636971e-130], + [1.587189482040237e261, 3.9839546709773654e130], + [2.9535217379352106e-261, 5.434631301141974e-131], + [5.035444923640649e261, 7.09608689605803e130], + [1.1592636133551025e262, 1.076691048237656e131], + [3.098400364216125e262, 1.7602273615121784e131], + [2.268479071515142e-262, 1.5061470949130906e-131], + [9.677233455330007e262, 3.11082520488214e131], + [2.1735445747919434e263, 4.6621288858116565e131], + [2.8565577802327522e-263, 5.344677520891931e-132], + [1.0849558012731932e-263, 3.2938667266196323e-132], + [6.291151023577279e-264, 2.508216701877507e-132], + [3.0168484729305057e264, 1.7369077329928916e132], + [1.383677885909719e-264, 1.1762983830260581e-132], + [9.412846028260774e264, 3.0680361843141246e132], + [2.2645222175441895e265, 4.758699630722861e132], + [4.7259317591760604e265, 6.874541264096144e132], + [1.1701821045843852e-265, 3.420792458750436e-133], + [4.778529516934361e-266, 2.1859847933904668e-133], + [3.9044132595607796e266, 1.9759588203099728e133], + [1.1997692490875455e-266, 1.0953397870467161e-133], + [1.5527737081534268e267, 3.940524975372478e133], + [3.2344371605411528e267, 5.687211232705493e133], + [5.673793622551648e267, 7.532458843267349e133], + [1.0432719139857164e268, 1.0214068307906094e134], + [2.6396070789187234e268, 1.6246867633235409e134], + [6.1645455350787286e268, 2.4828502844671744e134], + [7.57335196315868e-269, 8.70250076883575e-135], + [2.6411315435684497e269, 5.139194045342567e134], + [4.366168809024183e269, 6.6076991525221415e134], + [7.550788368437509e269, 8.689527241707405e134], + [1.9822642738282828e270, 1.4079290727264221e135], + [3.536521323110423e-270, 1.8805640970491866e-135], + [1.6057482754260527e-270, 1.2671812322734474e-135], + [1.262544295346429e271, 3.553229932535227e135], + [2.3010769290058998e271, 4.7969541680173473e135], + [3.7062783835457044e271, 6.087921142348762e135], + [6.94237193723016e-272, 2.6348381235343777e-136], + [5.510587017365919e-272, 2.3474639544337885e-136], + [4.259902098903556e272, 2.0639530273006594e136], + [7.895718756015192e-273, 8.88578570302885e-137], + [1.810050052625588e273, 4.254468301239989e136], + [2.416242194745764e-273, 4.91552865391482e-137], + [7.060772991181245e273, 8.402840585885969e136], + [7.625987987080336e-274, 2.7615191447969967e-137], + [2.881851068004715e-274, 1.697601563384269e-137], + [6.42722295033941e274, 2.5351968267452944e137], + [7.056728511863852e274, 2.6564503593825826e137], + [3.040091767513743e-275, 5.513702719147762e-138], + [2.2283448684906393e-275, 4.720534788019933e-138], + [1.0072841238605406e-275, 3.1737739740891136e-138], + [1.6046782981249131e276, 1.2667589739666e138], + [4.307671534205205e276, 2.075493082186786e138], + [5.842932421290422e276, 2.4172158408570846e138], + [5.705890005196658e-277, 7.553734179329227e-139], + [3.4712871927451646e-277, 5.891763057646806e-139], + [4.823430519741443e277, 6.945092166228929e138], + [7.136419113470423e277, 8.447732899109928e138], + [4.08963991290667e-278, 2.022285813851907e-139], + [2.595217100722346e-278, 1.6109677528499278e-139], + [7.93017940128612e278, 2.8160574215179135e139], + [1.1381236275635708e279, 3.3736087911368307e139], + [3.422488386655499e279, 5.850203745730143e139], + [1.2079372735258513e-279, 3.475539200650528e-140], + [1.1898249394367005e280, 1.090790969634742e140], + [3.8411962793995745e-280, 1.9598970073449203e-140], + [5.529110560059116e280, 2.3514060814880778e140], + [6.582939661533738e-281, 8.113531698054639e-141], + [2.800873919861212e-281, 5.292328334354561e-141], + [2.43156480510695e-281, 4.9310899455464713e-141], + [9.052455275105984e281, 9.514439171651676e140], + [1.8875044651665902e282, 1.3738647914429536e141], + [2.7174477010643608e-282, 1.6484682893717916e-141], + [8.986807408557548e282, 2.9978004284070593e141], + [8.055540602950735e-283, 8.975266348666615e-142], + [3.3644682898381725e283, 5.800403684088007e141], + [5.278122844502319e283, 7.265069059893594e141], + [9.083181777796106e-284, 3.0138317434448966e-142], + [2.9476442971654457e-284, 1.7168704951642235e-142], + [1.7646609632018615e-284, 1.3284054212482956e-142], + [1.1308465452883921e-284, 1.0634126881358864e-142], + [6.086715970811502e-285, 7.801740812672196e-143], + [3.538741008808386e285, 5.948731805022299e142], + [1.003022139565505e-285, 3.1670524775657015e-143], + [1.0806559149307645e286, 1.0395460138593023e143], + [2.4479547408340165e-286, 1.5645941137668953e-143], + [7.356097331454571e286, 2.71221262652001e143], + [9.958473995393397e286, 3.1557049918193235e143], + [2.9012650444171675e287, 5.386339243323955e143], + [1.4262134993751524e-287, 3.7765241947790463e-144], + [9.560856866769819e287, 9.777963421270209e143], + [5.360153478949893e-288, 2.3152005267254698e-144], + [2.985471533025146e-288, 1.7278517103690196e-144], + [1.3678899290477521e-288, 1.1695682660912754e-144], + [4.918892186481433e-289, 7.013481436833945e-145], + [3.3538002972446483e-289, 5.7912004776597474e-145], + [1.5019152605051456e-289, 3.875455148115052e-145], + [1.2806299811228752e290, 1.1316492306023431e145], + [1.925405008294064e290, 1.3875896397328947e145], + [1.9668724315129337e-290, 1.4024522920630612e-145], + [1.1746025155475246e291, 3.427247460495849e145], + [6.215282046104887e-291, 7.883706010566913e-146], + [3.064717337940106e-291, 5.53598892515159e-146], + [1.1859264944087496e-291, 3.4437283493457344e-146], + [1.5530285678267847e292, 1.2462056683496448e146], + [2.566318941170117e292, 1.6019734520803138e146], + [7.6196505926992395e292, 2.7603714591879187e146], + [8.866804451319227e-293, 9.416371090456889e-147], + [3.541785235884867e-293, 5.951289974354188e-147], + [6.135161510116648e293, 7.832727181586658e146], + [1.2461504700719871e294, 1.1163110991439559e147], + [3.9085284121159114e-294, 1.9769998513191426e-147], + [1.6225440935468405e-294, 1.2737912283992382e-147], + [1.0547409643958778e-294, 1.027005824908446e-147], + [5.353607023922659e-295, 7.316834714494143e-148], + [2.7552376817847925e-295, 5.249035798872773e-148], + [4.7000955374089e295, 6.855724277863646e147], + [9.357622017220938e295, 9.673480251295775e147], + [1.8104389901117752e296, 1.345525544206343e148], + [1.6168227993124728e-296, 1.271543471263359e-148], + [1.209584855930238e-296, 1.0998112819617e-148], + [1.3948114861279186e297, 3.7347175075605365e148], + [2.653442227639427e297, 5.151157372512925e148], + [1.40998731625735e-297, 3.754979781912747e-149], + [2.092459027978939e298, 1.446533452077393e149], + [2.7568763180772853e298, 1.6603843886514006e149], + [7.122994738351322e298, 2.6688939166537367e149], + [9.68872464921942e298, 3.1126716256649077e149], + [2.2939424654665187e299, 4.789511943263655e149], + [6.636893002415853e299, 8.1467128355035645e149], + [6.905542849360564e299, 8.30995959638828e149], + [1.3415205933077406e300, 1.1582403003296598e150], + [3.296046200672238e300, 1.8155016388514327e150], + [5.821518575208046e300, 2.412782330673044e150], + [5.621832682768831e-301, 7.497888157854071e-151], +]; + +for (let i = 0; i < examples.length; ++i) { + const example = examples[i]; + assert.sameValue(Math.sqrt(example[0]), example[1], "Math.sqrt(" + example[0] + ") is " + example[1]); +} From b70b75793d936c165c492401a84c0c94e5f3eed2 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Tue, 20 Aug 2024 15:03:14 -0400 Subject: [PATCH 78/90] Test `await` in ConditionalExpression --- .../syntax-await-in-ConditionalExpression.js | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 test/language/expressions/await/syntax-await-in-ConditionalExpression.js diff --git a/test/language/expressions/await/syntax-await-in-ConditionalExpression.js b/test/language/expressions/await/syntax-await-in-ConditionalExpression.js new file mode 100644 index 0000000000..b676e49b3f --- /dev/null +++ b/test/language/expressions/await/syntax-await-in-ConditionalExpression.js @@ -0,0 +1,73 @@ +// Copyright (C) 2024 Richard Gibson. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: prod-ConditionalExpression +description: > + await binds more tightly than conditional operators +info: | + ConditionalExpression[In, Yield, Await] : + ShortCircuitExpression[?In, ?Yield, ?Await] + ShortCircuitExpression[?In, ?Yield, ?Await] `?` AssignmentExpression[+In, ?Yield, ?Await] `:` AssignmentExpression[?In, ?Yield, ?Await] + + ShortCircuitExpression[In, Yield, Await] : + LogicalORExpression[?In, ?Yield, ?Await] + CoalesceExpression[?In, ?Yield, ?Await] + + LogicalORExpression[In, Yield, Await] : + LogicalANDExpression[?In, ?Yield, ?Await] + LogicalORExpression[?In, ?Yield, ?Await] `||` LogicalANDExpression[?In, ?Yield, ?Await] + + LogicalANDExpression[In, Yield, Await] : + BitwiseORExpression[?In, ?Yield, ?Await] + LogicalANDExpression[?In, ?Yield, ?Await] `&&` BitwiseORExpression[?In, ?Yield, ?Await] + + BitwiseORExpression[In, Yield, Await] : + BitwiseXORExpression[?In, ?Yield, ?Await] + + BitwiseXORExpression[In, Yield, Await] : + BitwiseANDExpression[?In, ?Yield, ?Await] + + BitwiseANDExpression[In, Yield, Await] : + EqualityExpression[?In, ?Yield, ?Await] + + EqualityExpression[In, Yield, Await] : + RelationalExpression[?In, ?Yield, ?Await] + + RelationalExpression[In, Yield, Await] : + ShiftExpression[?Yield, ?Await] + + ShiftExpression[Yield, Await] : + AdditiveExpression[?Yield, ?Await] + + AdditiveExpression[Yield, Await] : + MultiplicativeExpression[?Yield, ?Await] + + MultiplicativeExpression[Yield, Await] : + ExponentiationExpression[?Yield, ?Await] + + ExponentiationExpression[Yield, Await] : + UnaryExpression[?Yield, ?Await] + + UnaryExpression[Yield, Await] : + UpdateExpression[?Yield, ?Await] + [+Await] AwaitExpression[?Yield] + + AwaitExpression[Yield] : + `await` UnaryExpression[?Yield, +Await] +flags: [async] +includes: [asyncHelpers.js] +---*/ + +async function foo() { + let x = 'initial value'; + let shouldNotBeAwaited = { + then: function(onFulfilled) { + x = 'unexpected then() call'; + Promise.resolve().then(onFulfilled); + } + }; + // This must parse like `(await false) || shouldNotBeAwaited`. + await false || shouldNotBeAwaited; + assert.sameValue(x, 'initial value'); +} +asyncTest(foo); From 2e1843d0a514fa1547e6d8766798200b2d1f958e Mon Sep 17 00:00:00 2001 From: Luis Fernando Pardo Sixtos Date: Thu, 22 Aug 2024 10:24:24 -0700 Subject: [PATCH 79/90] [decorators] Support public auto-accessors Add support for the accessor keywords for public class fields as part of the decorators proposal. Changes to the parser: - Minor cleanup of reused code. - Support declaration of public auto-accessors. Changes to the bytecode generator: - Add logic to create the accessor storage private name for public members. - Add the generated getter and setter to the arguments list passed to Runtime::kDefineClass Changes to class boilerplate: - Add logic to add a template AccessorPair to the descriptors lists for each auto accessor property. The template AccessorPair object is initialized with consecutive indices corresponding to the positions in the Runtime::kDefineClass arguments. Add tests. Bug: 42202709 Change-Id: I2253eddb734e950d8faf83fff1763e32b7f53a73 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5745256 Reviewed-by: Shu-yu Guo Reviewed-by: Seth Brenith Commit-Queue: Luis Pardo Cr-Commit-Position: refs/heads/main@{#95784} --- .../decorators/public-auto-accessor.js | 509 ++++++++++++++++++ 1 file changed, 509 insertions(+) create mode 100644 test/staging/decorators/public-auto-accessor.js diff --git a/test/staging/decorators/public-auto-accessor.js b/test/staging/decorators/public-auto-accessor.js new file mode 100644 index 0000000000..db29b61449 --- /dev/null +++ b/test/staging/decorators/public-auto-accessor.js @@ -0,0 +1,509 @@ +// Copyright 2024 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/*--- +description: Test public auto-accessors. +features: [decorators] +---*/ + +(function TestPublicAutoAccessor() { + let name = 'x3'; + let symbol = Symbol(); + class C { + accessor x0; + accessor x1 = 1; + accessor 'x2' = 2; + accessor [name] = 3; + accessor [symbol] = 4; + accessor 1 = 5; + } + let c = new C(); + assert.sameValue(c.x0, undefined); + assert.sameValue(c.x1, 1); + assert.sameValue(c.x2, 2); + assert.sameValue(c.x3, 3); + assert.sameValue(c[symbol], 4); + assert.sameValue(c[1], 5); + c.x0 = 42; + c.x1 = 43; + c.x2 = 44; + c.x3 = 45; + c[symbol] = 46; + c[1] = 47; + assert.sameValue(c.x0, 42); + assert.sameValue(c.x1, 43); + assert.sameValue(c.x2, 44); + assert.sameValue(c.x3, 45); + assert.sameValue(c[symbol], 46); + assert.sameValue(c[1], 47); +})(); + +(function TestRedeclaredPublicAutoaccessor() { + let name = 'y'; + let symbol = Symbol(); + class C { + accessor x = 0; + accessor x = 1; + accessor y = 2; + accessor [name] = 3; + accessor [symbol] = 4; + accessor [symbol] = 5; + accessor 1 = 6; + accessor 1 = 7; + } + let c = new C(); + // Latest values should override previous ones. + assert.sameValue(c.x, 1); + assert.sameValue(c.y, 3); + assert.sameValue(c[symbol], 5); +})(); + +(function TestDerivedPublicAutoAccessor() { + let name = 'x3'; + let symbol = Symbol(); + let name2 = 'y3'; + let symbol2 = Symbol(); + class C { + accessor x0; + accessor x1 = 1; + accessor 'x2' = 2; + accessor [name] = 3; + accessor [symbol] = 4; + accessor 1 = 5; + + accessor y0 = 7; + accessor y1 = 8; + accessor 'y2' = 9; + accessor [name2] = 10; + accessor [symbol2] = 11; + accessor 2 = 12; + } + class D extends C { + accessor y0; + accessor y1 = 13; + accessor 'y2' = 14; + accessor [name2] = 15; + accessor [symbol2] = 16; + accessor 2 = 17; + } + + // Test inherited accessors. + let d = new D(); + assert.sameValue(d.x0, undefined); + assert.sameValue(d.x1, 1); + assert.sameValue(d.x2, 2); + assert.sameValue(d.x3, 3); + assert.sameValue(d[symbol], 4); + assert.sameValue(d[1], 5); + + // Test overridden accessors. + assert.sameValue(d.y0, undefined); + assert.sameValue(d.y1, 13); + assert.sameValue(d.y2, 14); + assert.sameValue(d.y3, 15); + assert.sameValue(d[symbol2], 16); + assert.sameValue(d[2], 17); + d.y0 = 42; + d.y1 = 43; + d.y2 = 44; + d.y3 = 45; + d[symbol2] = 46; + d[2] = 47; + assert.sameValue(d.y0, 42); + assert.sameValue(d.y1, 43); + assert.sameValue(d.y2, 44); + assert.sameValue(d.y3, 45); + assert.sameValue(d[symbol2], 46); + assert.sameValue(d[2], 47); + + // Test base class accessors. + let c = new C(); + assert.sameValue(c.y0, 7); + assert.sameValue(c.y1, 8); + assert.sameValue(c.y2, 9); + assert.sameValue(c.y3, 10); + assert.sameValue(c[symbol2], 11); + assert.sameValue(c[2], 12); + c.y0 = 48; + c.y1 = 49; + c.y2 = 50; + c.y3 = 51; + c[symbol2] = 52; + c[2] = 53; + assert.sameValue(c.y0, 48); + assert.sameValue(c.y1, 49); + assert.sameValue(c.y2, 50); + assert.sameValue(c.y3, 51); + assert.sameValue(c[symbol2], 52); + assert.sameValue(c[2], 53); +})(); + +(function TestAccessorsInPrototype() { + const name = 'x2'; + class C { + accessor x0 = 0; + accessor x1 = 2; + accessor [name] = 4; + accessor 1 = 6; + } + + const assertIsAccessorDescriptor = (key, value) => { + let c = new C(); + assert.sameValue( + Object.getOwnPropertyDescriptor(C.prototype, key).get.call(c), value); + value++; + Object.getOwnPropertyDescriptor(C.prototype, key).set.call(c, value); + assert.sameValue( + Object.getOwnPropertyDescriptor(C.prototype, key).get.call(c), value); + }; + + assertIsAccessorDescriptor('x0', 0); + assertIsAccessorDescriptor('x1', 2); + assertIsAccessorDescriptor('x2', 4); + assertIsAccessorDescriptor(1, 6); +})(); + +(function TestPublicStaticAutoAccessor() { + let name = 'x3'; + let symbol = Symbol(); + class C { + static accessor x0; + static accessor x1 = 1; + static accessor 'x2' = 2; + static accessor [name] = 3; + static accessor [symbol] = 4; + static accessor 1 = 5; + } + assert.sameValue(C.x0, undefined); + assert.sameValue(C.x1, 1); + assert.sameValue(C.x2, 2); + assert.sameValue(C.x3, 3); + assert.sameValue(C[symbol], 4); + assert.sameValue(C[1], 5); + C.x0 = 42; + C.x1 = 43; + C.x2 = 44; + C.x3 = 45; + C[symbol] = 46; + C[1] = 47; + assert.sameValue(C.x0, 42); + assert.sameValue(C.x1, 43); + assert.sameValue(C.x2, 44); + assert.sameValue(C.x3, 45); + assert.sameValue(C[symbol], 46); + assert.sameValue(C[1], 47); +})(); + +(function TestRedeclaredPublicAutoaccessor() { + let name = 'y'; + let symbol = Symbol(); + class C { + static accessor x = 0; + static accessor x = 1; + static accessor y = 2; + static accessor [name] = 3; + static accessor [symbol] = 4; + static accessor [symbol] = 5; + static accessor 1 = 6; + static accessor 1 = 7; + } + // Latest values should override previous ones. + assert.sameValue(C.x, 1); + assert.sameValue(C.y, 3); + assert.sameValue(C[symbol], 5); + assert.sameValue(C[1], 7); +})(); + +(function TestDerivedPublicStaticAutoAccessor() { + let name = 'x3'; + let symbol = Symbol(); + let name2 = 'y3'; + let symbol2 = Symbol(); + class C { + static accessor x0; + static accessor x1 = 1; + static accessor 'x2' = 2; + static accessor [name] = 3; + static accessor [symbol] = 4; + static accessor 1 = 5; + + static accessor y0 = 6; + static accessor y1 = 7; + static accessor 'y2' = 8; + static accessor [name2] = 9; + static accessor [symbol2] = 10; + static accessor 2 = 11; + } + class D extends C { + static accessor y0; + static accessor y1 = 12; + static accessor 'y2' = 13; + static accessor [name2] = 14; + static accessor [symbol2] = 15; + static accessor 2 = 16; + } + let assertThrowsTypeError = (code_string) => { + assert.throws(TypeError, () => {eval(code_string)}); + }; + // Calling the accessor on the derived class passes such class as the receiver + // to the generated getter/setter, which doesn't contain the static private + // "accessor storage" variable and hence throws a TypeError. + assertThrowsTypeError('D.x0'); + assertThrowsTypeError('D.x1'); + assertThrowsTypeError('D.x2'); + assertThrowsTypeError('D.x3'); + assertThrowsTypeError('D[symbol]'); + assertThrowsTypeError('D.x0 = 0'); + assertThrowsTypeError('D.x1 = 0'); + assertThrowsTypeError('D.x2 = 0'); + assertThrowsTypeError('D.x3 = 0'); + assertThrowsTypeError('D[symbol] = 0'); + assertThrowsTypeError('D[1]'); + + // Test overridden accessors. + assert.sameValue(D.y0, undefined); + assert.sameValue(D.y1, 12); + assert.sameValue(D.y2, 13); + assert.sameValue(D.y3, 14); + assert.sameValue(D[symbol2], 15); + assert.sameValue(D[2], 16); + + D.y0 = 42; + D.y1 = 43; + D.y2 = 44; + D.y3 = 45; + D[symbol2] = 46; + D[2] = 47; + assert.sameValue(D.y0, 42); + assert.sameValue(D.y1, 43); + assert.sameValue(D.y2, 44); + assert.sameValue(D.y3, 45); + assert.sameValue(D[symbol2], 46); + assert.sameValue(D[2], 47); + + // Test base class accessors. + assert.sameValue(C.y0, 6); + assert.sameValue(C.y1, 7); + assert.sameValue(C.y2, 8); + assert.sameValue(C.y3, 9); + assert.sameValue(C[symbol2], 10); + assert.sameValue(C[2], 11); + C.y0 = 48; + C.y1 = 49; + C.y2 = 50; + C.y3 = 51; + C[symbol2] = 52; + C[2] = 53; + assert.sameValue(C.y0, 48); + assert.sameValue(C.y1, 49); + assert.sameValue(C.y2, 50); + assert.sameValue(C.y3, 51); + assert.sameValue(C[symbol2], 52); + assert.sameValue(C[2], 53); +})(); + +(function TestStaticAccessorsInPrototype() { + const name = 'x2'; + class C { + static accessor x0 = 0; + static accessor x1 = 2; + static accessor [name] = 4; + static accessor 1 = 6; + } + + const assertIsAccessorDescriptor = (key, value) => { + assert.sameValue( + Object.getOwnPropertyDescriptor(C.prototype.constructor, key) + .get.call(C), + value); + value++; + Object.getOwnPropertyDescriptor(C.prototype.constructor, key) + .set.call(C, value); + assert.sameValue( + Object.getOwnPropertyDescriptor(C.prototype.constructor, key) + .get.call(C), + value); + }; + + assertIsAccessorDescriptor('x0', 0); + assertIsAccessorDescriptor('x1', 2); + assertIsAccessorDescriptor('x2', 4); + assertIsAccessorDescriptor(1, 6); +})(); + +(function TestPublicAutoAccessorLiteralNameOverrides() { +// Auto-accessors are override by getter/setter. +class A { + #x = 1; + accessor x = 2; + get x () {return this.#x}; + set x (v) {this.#x = v}; + xValue() {return this.#x}; +} +const a = new A(); +assert.sameValue(a.x, 1); // Read from #x. +a.x = 3; // Set #x to 3. +assert.sameValue(a.x, 3); // Read from #x. +assert.sameValue(a.xValue(), 3); // Read from #x. + +// Auto-accessor getter overrides user-defined getter. +// User-defined setter overrides auto-accessor setter. +class B { + #x = 1; + get x () {return this.#x}; + accessor x = 2; + set x (v) {this.#x = v}; + xValue() {return this.#x}; +} +const b = new B(); +assert.sameValue(b.x, 2); // Read from accessor backing storage. +b.x = 3; // Set #x to 3. +assert.sameValue(b.x, 2); // Read from accessor backing storage. +assert.sameValue(b.xValue(), 3); // Read from #x. + +// Auto-accessor overrdes user-defined getter and setter. +class C { + #x = 1; + get x () {return this.#x}; + set x (v) {this.#x = v}; + accessor x = 2; + xValue() {return this.#x}; +} +const c = new C(); // Read from accessor backing storage. +assert.sameValue(c.x, 2); +c.x = 3; // Set accessor backing storage. +assert.sameValue(c.x, 3); // Read from accessor backing storage. +assert.sameValue(c.xValue(), 1); // Read from #x. +})(); + +(function TestStaticPublicAutoAccessorLiteralNameOverrides() { + // Auto-accessors are override by getter/setter. + class A { + static #x = 1; + static accessor x = 2; + static get x () {return this.#x}; + static set x (v) {this.#x = v}; + static xValue() {return this.#x}; + } + assert.sameValue(A.x, 1); + A.x = 3; + assert.sameValue(A.x, 3); + assert.sameValue(A.xValue(), 3); + + // Auto-accessor getter overrides user-defined getter. + // User-defined setter overrides auto-accessor setter. + class B { + static #x = 1; + static get x () {return this.#x}; + static accessor x = 2; + static set x (v) {this.#x = v}; + static xValue() {return this.#x}; + } + assert.sameValue(B.x, 2); + B.x = 3; // Set #x to 3. + assert.sameValue(B.x, 2); // Read from accessor backing storage. + assert.sameValue(B.xValue(),3); // Read from #x. + + // Auto-accessor overrdes user-defined getter and setter. + class C { + static #x = 1; + static get x () {return this.#x}; + static set x (v) {this.#x = v}; + static accessor x = 2; + static xValue() {return this.#x}; + } + assert.sameValue(C.x, 2); + C.x = 3; // Set accessor backing storage. + assert.sameValue(C.x, 3); // Read from accessor backing storage. + assert.sameValue(C.xValue(), 1); // Read from #x. +})(); + +(function TestPublicAutoAccessorComputedNameOverrides() { + let name = 'x'; + // Auto-accessors are override by getter/setter. + class A { + #x = 1; + accessor [name] = 2; + get x () {return this.#x}; + set x (v) {this.#x = v}; + xValue() {return this.#x}; + } + const a = new A(); + assert.sameValue(a.x, 1); // Read from #x. + a.x = 3; // Set #x to 3. + assert.sameValue(a.x, 3); // Read from #x. + assert.sameValue(a.xValue(), 3); // Read from #x. + + // Auto-accessor getter overrides user-defined getter. + // User-defined setter overrides auto-accessor setter. + class B { + #x = 1; + get x () {return this.#x}; + accessor [name] = 2; + set x (v) {this.#x = v}; + xValue() {return this.#x}; + } + const b = new B(); + assert.sameValue(b.x, 2); // Read from accessor backing storage. + b.x = 3; // Set #x to 3. + assert.sameValue(b.x, 2); // Read from accessor backing storage. + assert.sameValue(b.xValue(), 3); // Read from #x. + + // Auto-accessor overrdes user-defined getter and setter. + class C { + #x = 1; + get x () {return this.#x}; + set x (v) {this.#x = v}; + accessor [name] = 2; + xValue() {return this.#x}; + } + const c = new C(); // Read from accessor backing storage. + assert.sameValue(c.x, 2); + c.x = 3; // Set accessor backing storage. + assert.sameValue(c.x, 3); // Read from accessor backing storage. + assert.sameValue(c.xValue(), 1); // Read from #x. +})(); + +(function TestStaticPublicAutoAccessorComputedNameOverrides() { + let name = 'x'; + // Auto-accessors are override by getter/setter. + class A { + static #x = 1; + static accessor [name] = 2; + static get x () {return this.#x}; + static set x (v) {this.#x = v}; + static xValue() {return this.#x}; + } + assert.sameValue(A.x, 1); + A.x = 3; + assert.sameValue(A.x, 3); + assert.sameValue(A.xValue(), 3); + + // Auto-accessor getter overrides user-defined getter. + // User-defined setter overrides auto-accessor setter. + class B { + static #x = 1; + static get x () {return this.#x}; + static accessor [name] = 2; + static set x (v) {this.#x = v}; + static xValue() {return this.#x}; + } + assert.sameValue(B.x, 2); + B.x = 3; // Set #x to 3. + assert.sameValue(B.x, 2); // Read from accessor backing storage. + assert.sameValue(B.xValue(), 3); // Read from #x. + + // Auto-accessor overrdes user-defined getter and setter. + class C { + static #x = 1; + static get x () {return this.#x}; + static set x (v) {this.#x = v}; + static accessor [name] = 2; + static xValue() {return this.#x}; + } + assert.sameValue(C.x, 2); + C.x = 3; // Set accessor backing storage. + assert.sameValue(C.x, 3); // Read from accessor backing storage. + assert.sameValue(C.xValue(), 1); // Read from #x. +})(); From cfd81e1698b872f39d52b6e5f12986385f509c5e Mon Sep 17 00:00:00 2001 From: Jonatan Klemets Date: Thu, 22 Aug 2024 16:07:27 +0300 Subject: [PATCH 80/90] Remove import-assertions test files --- ...mport-assertions-trailing-comma-first.case | 14 ---- ...port-assertions-trailing-comma-second.case | 14 ---- .../2nd-param-assert-enumeration-abrupt.js | 43 ----------- ...2nd-param-assert-enumeration-enumerable.js | 60 ---------------- .../2nd-param-assert-enumeration.js | 58 --------------- .../2nd-param-assert-non-object.js | 47 ------------ .../2nd-param-assert-undefined.js | 36 ---------- .../2nd-param-assert-value-abrupt.js | 34 --------- .../2nd-param-assert-value-non-string.js | 47 ------------ .../import-assertions/2nd-param-await-expr.js | 21 ------ .../2nd-param-await-ident.js | 21 ------ .../2nd-param-evaluation-abrupt-return.js | 30 -------- .../2nd-param-evaluation-abrupt-throw.js | 29 -------- .../2nd-param-evaluation-sequence.js | 25 ------- .../2nd-param-get-assert-error.js | 36 ---------- .../import-assertions/2nd-param-in.js | 22 ------ .../import-assertions/2nd-param-non-object.js | 40 ----------- .../2nd-param-trailing-comma-fulfill.js | 20 ------ .../2nd-param-trailing-comma-reject.js | 24 ------- .../import-assertions/2nd-param-yield-expr.js | 31 -------- .../2nd-param-yield-ident-invalid.js | 19 ----- .../2nd-param-yield-ident-valid.js | 21 ------ .../import-assertions/2nd-param_FIXTURE.js | 3 - .../import-assertions/2nd-param_FIXTURE.json | 1 - .../import-assertions/README.md | 2 - .../trailing-comma-fulfill.js | 20 ------ .../trailing-comma-reject.js | 24 ------- .../import/import-assertions/README.md | 2 - .../json-extensibility-array.js | 20 ------ .../json-extensibility-object.js | 20 ------ .../json-idempotency-indirect_FIXTURE.js | 6 -- .../import-assertions/json-idempotency.js | 21 ------ .../json-idempotency_FIXTURE.json | 1 - .../import/import-assertions/json-invalid.js | 23 ------ .../json-invalid_FIXTURE.json | 3 - .../import-assertions/json-named-bindings.js | 20 ------ .../json-named-bindings_FIXTURE.json | 3 - .../import-assertions/json-value-array.js | 47 ------------ .../json-value-array_FIXTURE.json | 10 --- .../import-assertions/json-value-boolean.js | 20 ------ .../json-value-boolean_FIXTURE.json | 1 - .../import-assertions/json-value-null.js | 20 ------ .../json-value-null_FIXTURE.json | 1 - .../import-assertions/json-value-number.js | 20 ------ .../json-value-number_FIXTURE.json | 1 - .../import-assertions/json-value-object.js | 67 ----------------- .../json-value-object_FIXTURE.json | 10 --- .../import-assertions/json-value-string.js | 20 ------ .../json-value-string_FIXTURE.json | 1 - .../import-assertions/json-via-namespace.js | 13 ---- .../json-via-namespace_FIXTURE.json | 1 - .../module-code/import-assertions/README.md | 2 - .../early-dup-assert-key-export.js | 23 ------ .../early-dup-assert-key-import-nobinding.js | 24 ------- ...early-dup-assert-key-import-withbinding.js | 24 ------- .../eval-gtbndng-indirect-faux-assertion.js | 47 ------------ .../import-assertion-1_FIXTURE.js | 3 - .../import-assertion-2_FIXTURE.js | 3 - .../import-assertion-3_FIXTURE.js | 3 - .../import-assertion-empty.js | 29 -------- .../import-assertion-key-identifiername.js | 37 ---------- .../import-assertion-key-string-double.js | 37 ---------- .../import-assertion-key-string-single.js | 37 ---------- .../import-assertion-many.js | 35 --------- .../import-assertion-newlines.js | 71 ------------------- .../import-assertion-trlng-comma.js | 35 --------- .../import-assertion-value-string-double.js | 35 --------- .../import-assertion-value-string-single.js | 35 --------- 68 files changed, 1573 deletions(-) delete mode 100644 src/dynamic-import/import-assertions-trailing-comma-first.case delete mode 100644 src/dynamic-import/import-assertions-trailing-comma-second.case delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration-abrupt.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration-enumerable.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-non-object.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-undefined.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-value-abrupt.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-value-non-string.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-await-expr.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-await-ident.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-abrupt-return.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-abrupt-throw.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-sequence.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-get-assert-error.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-in.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-non-object.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-trailing-comma-fulfill.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-trailing-comma-reject.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-expr.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-ident-invalid.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-ident-valid.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param_FIXTURE.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/2nd-param_FIXTURE.json delete mode 100644 test/language/expressions/dynamic-import/import-assertions/README.md delete mode 100644 test/language/expressions/dynamic-import/import-assertions/trailing-comma-fulfill.js delete mode 100644 test/language/expressions/dynamic-import/import-assertions/trailing-comma-reject.js delete mode 100644 test/language/import/import-assertions/README.md delete mode 100644 test/language/import/import-assertions/json-extensibility-array.js delete mode 100644 test/language/import/import-assertions/json-extensibility-object.js delete mode 100644 test/language/import/import-assertions/json-idempotency-indirect_FIXTURE.js delete mode 100644 test/language/import/import-assertions/json-idempotency.js delete mode 100644 test/language/import/import-assertions/json-idempotency_FIXTURE.json delete mode 100644 test/language/import/import-assertions/json-invalid.js delete mode 100644 test/language/import/import-assertions/json-invalid_FIXTURE.json delete mode 100644 test/language/import/import-assertions/json-named-bindings.js delete mode 100644 test/language/import/import-assertions/json-named-bindings_FIXTURE.json delete mode 100644 test/language/import/import-assertions/json-value-array.js delete mode 100644 test/language/import/import-assertions/json-value-array_FIXTURE.json delete mode 100644 test/language/import/import-assertions/json-value-boolean.js delete mode 100644 test/language/import/import-assertions/json-value-boolean_FIXTURE.json delete mode 100644 test/language/import/import-assertions/json-value-null.js delete mode 100644 test/language/import/import-assertions/json-value-null_FIXTURE.json delete mode 100644 test/language/import/import-assertions/json-value-number.js delete mode 100644 test/language/import/import-assertions/json-value-number_FIXTURE.json delete mode 100644 test/language/import/import-assertions/json-value-object.js delete mode 100644 test/language/import/import-assertions/json-value-object_FIXTURE.json delete mode 100644 test/language/import/import-assertions/json-value-string.js delete mode 100644 test/language/import/import-assertions/json-value-string_FIXTURE.json delete mode 100644 test/language/import/import-assertions/json-via-namespace.js delete mode 100644 test/language/import/import-assertions/json-via-namespace_FIXTURE.json delete mode 100644 test/language/module-code/import-assertions/README.md delete mode 100644 test/language/module-code/import-assertions/early-dup-assert-key-export.js delete mode 100644 test/language/module-code/import-assertions/early-dup-assert-key-import-nobinding.js delete mode 100644 test/language/module-code/import-assertions/early-dup-assert-key-import-withbinding.js delete mode 100644 test/language/module-code/import-assertions/eval-gtbndng-indirect-faux-assertion.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-1_FIXTURE.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-2_FIXTURE.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-3_FIXTURE.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-empty.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-key-identifiername.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-key-string-double.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-key-string-single.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-many.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-newlines.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-trlng-comma.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-value-string-double.js delete mode 100644 test/language/module-code/import-assertions/import-assertion-value-string-single.js diff --git a/src/dynamic-import/import-assertions-trailing-comma-first.case b/src/dynamic-import/import-assertions-trailing-comma-first.case deleted file mode 100644 index dc33458cc8..0000000000 --- a/src/dynamic-import/import-assertions-trailing-comma-first.case +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2018 Leo Balter. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -desc: ImportCall trailing comma following first parameter -template: syntax/valid -info: | - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [import-assertions] ----*/ - -//- import -import('./empty_FIXTURE.js',) diff --git a/src/dynamic-import/import-assertions-trailing-comma-second.case b/src/dynamic-import/import-assertions-trailing-comma-second.case deleted file mode 100644 index f82af0a93a..0000000000 --- a/src/dynamic-import/import-assertions-trailing-comma-second.case +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2021 V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -desc: ImportCall trailing comma following second parameter -template: syntax/valid -info: | - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [import-assertions] ----*/ - -//- import -import('./empty_FIXTURE.js', {},) diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration-abrupt.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration-abrupt.js deleted file mode 100644 index 282c7613aa..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration-abrupt.js +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: Reports abrupt completions produced by attributes enumeration -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - [...] - 6. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 7. Let specifierString be ToString(specifier). - 8. IfAbruptRejectPromise(specifierString, promiseCapability). - 9. Let assertions be a new empty List. - 10. If options is not undefined, then - a. If Type(options) is not Object, - [...] - b. Let assertionsObj be Get(options, "assert"). - c. IfAbruptRejectPromise(assertionsObj, promiseCapability). - d. If assertionsObj is not undefined, - i. If Type(assertionsObj) is not Object, - [...] - ii. Let keys be EnumerableOwnPropertyNames(assertionsObj, key). - iii. IfAbruptRejectPromise(keys, promiseCapability). - [...] -features: [dynamic-import, import-assertions, Proxy] -flags: [async] ----*/ - -var thrown = new Test262Error(); -var options = { - assert: new Proxy({}, { - ownKeys: function() { - throw thrown; - }, - }) -}; - -import('./2nd-param_FIXTURE.js', options) - .then(function() { - throw new Test262Error('Expected promise to be rejected, but promise was fulfilled.'); - }, function(error) { - assert.sameValue(error, thrown); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration-enumerable.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration-enumerable.js deleted file mode 100644 index 151bb1738d..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration-enumerable.js +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - Follows the semantics of the EnumerableOwnPropertyNames abstract operation - during attributes enumeration -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - [...] - 6. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 7. Let specifierString be ToString(specifier). - 8. IfAbruptRejectPromise(specifierString, promiseCapability). - 9. Let assertions be a new empty List. - 10. If options is not undefined, then - a. If Type(options) is not Object, - [...] - b. Let assertionsObj be Get(options, "assert"). - c. IfAbruptRejectPromise(assertionsObj, promiseCapability). - d. If assertionsObj is not undefined, - i. If Type(assertionsObj) is not Object, - [...] - ii. Let keys be EnumerableOwnPropertyNames(assertionsObj, key). - [...] -features: [dynamic-import, import-assertions, json-modules, Symbol, Proxy] -includes: [compareArray.js] -flags: [async] ----*/ - -var symbol = Symbol(''); -var target = { - type: "json" -}; -var descriptors = { - type: {configurable: true, enumerable: true} -}; -var log = []; - -var options = { - assert: new Proxy({}, { - ownKeys: function() { - return ["type"]; - }, - get(_, name) { - log.push(name); - return "json"; - }, - getOwnPropertyDescriptor(target, name) { - return {configurable: true, enumerable: true, value: "json"}; - }, - }) -}; - -import('./2nd-param_FIXTURE.json', options) - .then(function(module) { - assert.sameValue(module.default, 262); - }) - .then($DONE, $DONE); - -assert.compareArray(log, ['type']); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration.js deleted file mode 100644 index cfa9d28a8f..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration.js +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - Follows the semantics of the EnumerableOwnPropertyNames abstract operation - during attributes enumeration -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - [...] - 6. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 7. Let specifierString be ToString(specifier). - 8. IfAbruptRejectPromise(specifierString, promiseCapability). - 9. Let assertions be a new empty List. - 10. If options is not undefined, then - a. If Type(options) is not Object, - [...] - b. Let assertionsObj be Get(options, "assert"). - c. IfAbruptRejectPromise(assertionsObj, promiseCapability). - d. If assertionsObj is not undefined, - i. If Type(assertionsObj) is not Object, - [...] - ii. Let keys be EnumerableOwnPropertyNames(assertionsObj, key). - [...] -features: [dynamic-import, import-assertions, Symbol, Proxy] -flags: [async] ----*/ - -var symbol = Symbol(''); -var target = { - [symbol]: '', - unreported: '', - nonEnumerable: '' -}; -var descriptors = { - [symbol]: {configurable: true, enumerable: true}, - nonEnumerable: {configurable: true, enumerable: false} -}; - -var options = { - assert: new Proxy({}, { - ownKeys: function() { - return [symbol, 'nonEnumerable', 'absent']; - }, - get() { - throw new Error("Should not be called"); - }, - getOwnPropertyDescriptor(target, name) { - return descriptors[name]; - } - }) -}; - -import('./2nd-param_FIXTURE.js', options) - .then(function(module) { - assert.sameValue(module.default, 262); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-non-object.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-non-object.js deleted file mode 100644 index d685ee83d3..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-non-object.js +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - Rejects promise when the `assert` property of the second argument is neither - undefined nor an object -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - [...] - 6. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 7. Let specifierString be ToString(specifier). - 8. IfAbruptRejectPromise(specifierString, promiseCapability). - 9. Let assertions be a new empty List. - 10. If options is not undefined, then - a. If Type(options) is not Object, - [...] - b. Let assertionsObj be Get(options, "assert"). - c. IfAbruptRejectPromise(assertionsObj, promiseCapability). - d. If assertionsObj is not undefined, - i. If Type(assertionsObj) is not Object, - 1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a - newly created TypeError object »). - 2. Return promiseCapability.[[Promise]]. - [...] -features: [dynamic-import, import-assertions, Symbol, BigInt] -flags: [async] ----*/ - -function test(promise, valueType) { - return promise.then(function() { - throw new Test262Error('Promise for ' + valueType + ' was not rejected.'); - }, function(error) { - assert.sameValue(error.constructor, TypeError, valueType); - }); -} - -Promise.all([ - test(import('./2nd-param_FIXTURE.js', {assert:null}), 'null'), - test(import('./2nd-param_FIXTURE.js', {assert:false}), 'boolean'), - test(import('./2nd-param_FIXTURE.js', {assert:23}), 'number'), - test(import('./2nd-param_FIXTURE.js', {assert:''}), 'string'), - test(import('./2nd-param_FIXTURE.js', {assert:Symbol('')}), 'symbol'), - test(import('./2nd-param_FIXTURE.js', {assert:23n}), 'bigint') - ]) - .then(function() {}) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-undefined.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-undefined.js deleted file mode 100644 index bdd4003d38..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-undefined.js +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: Accepts undefined for the `assert` property of the second argument -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - [...] - 6. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 7. Let specifierString be ToString(specifier). - 8. IfAbruptRejectPromise(specifierString, promiseCapability). - 9. Let assertions be a new empty List. - 10. If options is not undefined, then - a. If Type(options) is not Object, - [...] - b. Let assertionsObj be Get(options, "assert"). - c. IfAbruptRejectPromise(assertionsObj, promiseCapability). - d. If assertionsObj is not undefined, - i. If Type(assertionsObj) is not Object, - 1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a - newly created TypeError object »). - 2. Return promiseCapability.[[Promise]]. - [...] -features: [dynamic-import, import-assertions, Symbol, BigInt] -flags: [async] ----*/ - -Promise.all([ - import('./2nd-param_FIXTURE.js', {}), - import('./2nd-param_FIXTURE.js', {assert:undefined}), - ]) - .then(function(values) { - assert.sameValue(values[0].default, 262); - assert.sameValue(values[1].default, 262); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-value-abrupt.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-value-abrupt.js deleted file mode 100644 index e840a71950..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-value-abrupt.js +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - Rejects promise when retrieving a value of the `assert` object produces an - abrupt completion -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - [...] - 10. If options is not undefined, then - [...] - d. If assertionsObj is not undefined, - [...] - ii. Let keys be EnumerableOwnPropertyNames(assertionsObj, key). - iii. IfAbruptRejectPromise(keys, promiseCapability). - iv. Let supportedAssertions be ! HostGetSupportedImportAssertions(). - v. For each String key of keys, - 1. Let value be Get(assertionsObj, key). - 2. IfAbruptRejectPromise(value, promiseCapability). - [...] -features: [dynamic-import, import-assertions] -flags: [async] ----*/ - -var thrown = new Test262Error(); - -import('./2nd-param_FIXTURE.js', {assert:{get ''() { throw thrown; }}}) - .then(function() { - throw new Test262Error('Expected promise to be rejected, but it was fulfilled'); - }, function(error) { - assert.sameValue(error, thrown); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-value-non-string.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-value-non-string.js deleted file mode 100644 index aa71b1c282..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-assert-value-non-string.js +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - Rejects promise when any property of the `assert` object is not a string -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - [...] - 10. If options is not undefined, then - [...] - d. If assertionsObj is not undefined, - [...] - ii. Let keys be EnumerableOwnPropertyNames(assertionsObj, key). - iii. IfAbruptRejectPromise(keys, promiseCapability). - iv. Let supportedAssertions be ! HostGetSupportedImportAssertions(). - v. For each String key of keys, - 1. Let value be Get(assertionsObj, key). - 2. IfAbruptRejectPromise(value, promiseCapability). - 3. If Type(value) is not String, then - a. Perform ! Call(promiseCapability.[[Reject]], undefined, « a - newly created TypeError object »). - b. Return promiseCapability.[[Promise]]. - [...] -features: [dynamic-import, import-assertions, Symbol, BigInt] -flags: [async] ----*/ - -function test(promise, valueType) { - return promise.then(function() { - throw new Test262Error('Promise for ' + valueType + ' was not rejected.'); - }, function(error) { - assert.sameValue(error.constructor, TypeError, valueType); - }); -} - -Promise.all([ - test(import('./2nd-param_FIXTURE.js', {assert:{'': undefined}}), 'undefined'), - test(import('./2nd-param_FIXTURE.js', {assert:{'': null}}), 'null'), - test(import('./2nd-param_FIXTURE.js', {assert:{'': false}}), 'boolean'), - test(import('./2nd-param_FIXTURE.js', {assert:{'': 23}}), 'number'), - test(import('./2nd-param_FIXTURE.js', {assert:{'': Symbol('')}}), 'symbol'), - test(import('./2nd-param_FIXTURE.js', {assert:{'': 23n}}), 'bigint'), - test(import('./2nd-param_FIXTURE.js', {assert:{'': {}}}), 'object') - ]) - .then(function() {}) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-await-expr.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-await-expr.js deleted file mode 100644 index 966ab94369..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-await-expr.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - ImportCall parameter list forwards the Await production parameter - AwaitExpression -esid: sec-import-call-runtime-semantics-evaluation -info: | - ImportCall[Yield, Await]: - import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [dynamic-import, import-assertions, async-functions] -flags: [async] ----*/ - -(async function () { - return import('./2nd-param_FIXTURE.js', await undefined); -}()) - .then(function(module) { - assert.sameValue(module.default, 262); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-await-ident.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-await-ident.js deleted file mode 100644 index d13ca53b20..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-await-ident.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - ImportCall parameter list forwards the Await production parameter - IdentifierReference -esid: sec-import-call-runtime-semantics-evaluation -info: | - ImportCall[Yield, Await]: - import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [dynamic-import, import-assertions, async-functions] -flags: [async] ----*/ - -function await() {} - -import('./2nd-param_FIXTURE.js', await(undefined)) - .then(function(module) { - assert.sameValue(module.default, 262); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-abrupt-return.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-abrupt-return.js deleted file mode 100644 index 6da4a5482b..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-abrupt-return.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: Forwards "return" completion when evaluating second parameter -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Let specifierRef be the result of evaluating specifierExpression. - 3. Let specifier be ? GetValue(specifierRef). - 4. If optionsExpression is present, then - a. Let optionsRef be the result of evaluating optionsExpression. - b. Let options be ? GetValue(optionsRef). - [...] -features: [dynamic-import, import-assertions] ----*/ - -var beforeCount = 0; -var afterCount = 0; -var iter = function*() { - beforeCount += 1, import('', yield), afterCount += 1; -}(); - -iter.next(); -var result = iter.return(595); - -assert.sameValue(result.done, true); -assert.sameValue(result.value, 595); -assert.sameValue(beforeCount, 1); -assert.sameValue(afterCount, 0); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-abrupt-throw.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-abrupt-throw.js deleted file mode 100644 index e5e6619096..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-abrupt-throw.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: Forwards "throw" completion when evaluating second parameter -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Let specifierRef be the result of evaluating specifierExpression. - 3. Let specifier be ? GetValue(specifierRef). - 4. If optionsExpression is present, then - a. Let optionsRef be the result of evaluating optionsExpression. - b. Let options be ? GetValue(optionsRef). - [...] -features: [dynamic-import, import-assertions] ----*/ - -var beforeCount = 0; -var afterCount = 0; -function throwError() { - throw new Test262Error(); -} - -assert.throws(Test262Error, function() { - beforeCount += 1, import('', throwError()), afterCount += 1; -}); - -assert.sameValue(beforeCount, 1); -assert.sameValue(afterCount, 0); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-sequence.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-sequence.js deleted file mode 100644 index 9795c4bada..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-evaluation-sequence.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: Evaluates parameters in correct sequence -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Let specifierRef be the result of evaluating specifierExpression. - 3. Let specifier be ? GetValue(specifierRef). - 4. If optionsExpression is present, then - a. Let optionsRef be the result of evaluating optionsExpression. - b. Let options be ? GetValue(optionsRef). - [...] -features: [dynamic-import, import-assertions] ----*/ - -var log = []; - -import(log.push('first'), (log.push('second'), undefined)) - .then(null, function() {}); - -assert.sameValue(log.length, 2); -assert.sameValue(log[0], 'first'); -assert.sameValue(log[1], 'second'); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-get-assert-error.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-get-assert-error.js deleted file mode 100644 index d7bb7d8c04..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-get-assert-error.js +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: Rejects promise when accessing "assert" property throws an error -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - [...] - 6. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 7. Let specifierString be ToString(specifier). - 8. IfAbruptRejectPromise(specifierString, promiseCapability). - 9. Let assertions be a new empty List. - 10. If options is not undefined, then - a. If Type(options) is not Object, - [...] - b. Let assertionsObj be Get(options, "assert"). - c. IfAbruptRejectPromise(assertionsObj, promiseCapability). - [...] -features: [dynamic-import, import-assertions] -flags: [async] ----*/ - -var thrown = new Test262Error(); -var options = { - get assert() { - throw thrown; - } -}; - -import('./2nd-param_FIXTURE.js', options) - .then(function() { - throw new Test262Error('Expected an error, but observed no error'); - }, function(caught) { - assert.sameValue(thrown, caught); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-in.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-in.js deleted file mode 100644 index 6d8ac2b0eb..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-in.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: ImportCall parameter list enables the Yield production parameter -esid: sec-import-call-runtime-semantics-evaluation -info: | - ImportCall[Yield, Await]: - import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [dynamic-import, import-assertions] -flags: [async] ----*/ - -var promise; - -for (promise = import('./2nd-param_FIXTURE.js', 'test262' in {} || undefined); false; ) ; - -promise - .then(function(module) { - assert.sameValue(module.default, 262); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-non-object.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-non-object.js deleted file mode 100644 index 28b6e573d1..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-non-object.js +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - Rejects promise when the second argument is neither undefined nor an object -esid: sec-import-call-runtime-semantics-evaluation -info: | - 2.1.1.1 EvaluateImportCall ( specifierExpression [ , optionsExpression ] ) - [...] - 6. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 7. Let specifierString be ToString(specifier). - 8. IfAbruptRejectPromise(specifierString, promiseCapability). - 9. Let assertions be a new empty List. - 10. If options is not undefined, then - a. If Type(options) is not Object, - i. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »). - ii. Return promiseCapability.[[Promise]]. - [...] -features: [dynamic-import, import-assertions, Symbol, BigInt] -flags: [async] ----*/ - -function test(promise, valueType) { - return promise.then(function() { - throw new Test262Error('Promise for ' + valueType + ' was not rejected.'); - }, function(error) { - assert.sameValue(error.constructor, TypeError, valueType); - }); -} - -Promise.all([ - test(import('./2nd-param_FIXTURE.js', null), 'null'), - test(import('./2nd-param_FIXTURE.js', false), 'boolean'), - test(import('./2nd-param_FIXTURE.js', 23), 'number'), - test(import('./2nd-param_FIXTURE.js', ''), 'string'), - test(import('./2nd-param_FIXTURE.js', Symbol('')), 'symbol'), - test(import('./2nd-param_FIXTURE.js', 23n), 'bigint') - ]) - .then(function() {}) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-trailing-comma-fulfill.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-trailing-comma-fulfill.js deleted file mode 100644 index c806f3e683..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-trailing-comma-fulfill.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - ImportCall parameter list supports an optional trailing comma (fulfillment - semantics) -esid: sec-import-call-runtime-semantics-evaluation -info: | - ImportCall[Yield, Await]: - import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [dynamic-import, import-assertions] -flags: [async] ----*/ - -import('./2nd-param_FIXTURE.js', {},) - .then(function(module) { - assert.sameValue(module.default, 262); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-trailing-comma-reject.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-trailing-comma-reject.js deleted file mode 100644 index 3970c745b6..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-trailing-comma-reject.js +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - ImportCall parameter list supports an optional trailing comma (rejection - semantics) -esid: sec-import-call-runtime-semantics-evaluation -info: | - ImportCall[Yield, Await]: - import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [dynamic-import, import-assertions] -flags: [async] ----*/ - -var thrown = new Test262Error(); - -import({toString: function() { throw thrown; } }, {},) - .then(function() { - throw new Test262Error('Expected promise to be rejected, but it was fulfilled.'); - }, function(caught) { - assert.sameValue(thrown, caught); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-expr.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-expr.js deleted file mode 100644 index b1482ac9e8..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-expr.js +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - ImportCall parameter list forwards the Yield production parameter - YieldExpression -esid: sec-import-call-runtime-semantics-evaluation -info: | - ImportCall[Yield, Await]: - import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [dynamic-import, import-assertions] -flags: [async] ----*/ - -var promise; - -var iter = (function * () { - promise = import('./2nd-param_FIXTURE.js', yield); -}()); - -iter.next(); - -assert.sameValue(promise, undefined); - -iter.next(); - -promise - .then(function(module) { - assert.sameValue(module.default, 262); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-ident-invalid.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-ident-invalid.js deleted file mode 100644 index 56971e8031..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-ident-invalid.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - ImportCall parameter list forwards the Yield production parameter - invalid IdentifierReference -esid: sec-import-call-runtime-semantics-evaluation -info: | - ImportCall[Yield, Await]: - import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [dynamic-import, import-assertions] -flags: [onlyStrict] -negative: - phase: parse - type: SyntaxError ----*/ -$DONOTEVALUATE(); - -import('./empty_FIXTURE.js', yield); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-ident-valid.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-ident-valid.js deleted file mode 100644 index 39a8fe7d6e..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param-yield-ident-valid.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - ImportCall parameter list forwards the Yield production parameter - valid IdentifierReference -esid: sec-import-call-runtime-semantics-evaluation -info: | - ImportCall[Yield, Await]: - import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [dynamic-import, import-assertions] -flags: [async, noStrict] ----*/ - -var yield; - -import('./2nd-param_FIXTURE.js', yield) - .then(function(module) { - assert.sameValue(module.default, 262); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param_FIXTURE.js b/test/language/expressions/dynamic-import/import-assertions/2nd-param_FIXTURE.js deleted file mode 100644 index fc9f2fa021..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param_FIXTURE.js +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -export default 262; diff --git a/test/language/expressions/dynamic-import/import-assertions/2nd-param_FIXTURE.json b/test/language/expressions/dynamic-import/import-assertions/2nd-param_FIXTURE.json deleted file mode 100644 index 5484d82917..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/2nd-param_FIXTURE.json +++ /dev/null @@ -1 +0,0 @@ -262 diff --git a/test/language/expressions/dynamic-import/import-assertions/README.md b/test/language/expressions/dynamic-import/import-assertions/README.md deleted file mode 100644 index d80cf27f8e..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/README.md +++ /dev/null @@ -1,2 +0,0 @@ -Make sure to keep the tests in this folder aligned -with the tests in the import-attributes folder. diff --git a/test/language/expressions/dynamic-import/import-assertions/trailing-comma-fulfill.js b/test/language/expressions/dynamic-import/import-assertions/trailing-comma-fulfill.js deleted file mode 100644 index 0d3689b37e..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/trailing-comma-fulfill.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - ImportCall parameter list supports an optional trailing comma (fulfillment - semantics) -esid: sec-import-call-runtime-semantics-evaluation -info: | - ImportCall[Yield, Await]: - import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [dynamic-import, import-assertions] -flags: [async] ----*/ - -import('./2nd-param_FIXTURE.js',) - .then(function(module) { - assert.sameValue(module.default, 262); - }) - .then($DONE, $DONE); diff --git a/test/language/expressions/dynamic-import/import-assertions/trailing-comma-reject.js b/test/language/expressions/dynamic-import/import-assertions/trailing-comma-reject.js deleted file mode 100644 index d257eccc32..0000000000 --- a/test/language/expressions/dynamic-import/import-assertions/trailing-comma-reject.js +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - ImportCall parameter list supports an optional trailing comma (rejection - semantics) -esid: sec-import-call-runtime-semantics-evaluation -info: | - ImportCall[Yield, Await]: - import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) -features: [dynamic-import, import-assertions] -flags: [async] ----*/ - -var thrown = new Test262Error(); - -import({toString: function() { throw thrown; } },) - .then(function() { - throw new Test262Error('Expected promise to be rejected, but it was fulfilled.'); - }, function(caught) { - assert.sameValue(thrown, caught); - }) - .then($DONE, $DONE); diff --git a/test/language/import/import-assertions/README.md b/test/language/import/import-assertions/README.md deleted file mode 100644 index d80cf27f8e..0000000000 --- a/test/language/import/import-assertions/README.md +++ /dev/null @@ -1,2 +0,0 @@ -Make sure to keep the tests in this folder aligned -with the tests in the import-attributes folder. diff --git a/test/language/import/import-assertions/json-extensibility-array.js b/test/language/import/import-assertions/json-extensibility-array.js deleted file mode 100644 index 4dc80018b9..0000000000 --- a/test/language/import/import-assertions/json-extensibility-array.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: Creates extensible arrays -flags: [module] -includes: [propertyHelper.js] -features: [import-assertions, json-modules] ----*/ - -import value from './json-value-array_FIXTURE.json' assert { type: 'json' }; - -value.test262property = 'test262 value'; - -verifyProperty(value, 'test262property', { - value: 'test262 value', - writable: true, - enumerable: true, - configurable: true -}); diff --git a/test/language/import/import-assertions/json-extensibility-object.js b/test/language/import/import-assertions/json-extensibility-object.js deleted file mode 100644 index fb4c8ed2c4..0000000000 --- a/test/language/import/import-assertions/json-extensibility-object.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: Creates extensible objects -flags: [module] -includes: [propertyHelper.js] -features: [import-assertions, json-modules] ----*/ - -import value from './json-value-object_FIXTURE.json' assert { type: 'json' }; - -value.test262property = 'test262 value'; - -verifyProperty(value, 'test262property', { - value: 'test262 value', - writable: true, - enumerable: true, - configurable: true -}); diff --git a/test/language/import/import-assertions/json-idempotency-indirect_FIXTURE.js b/test/language/import/import-assertions/json-idempotency-indirect_FIXTURE.js deleted file mode 100644 index 61c440b333..0000000000 --- a/test/language/import/import-assertions/json-idempotency-indirect_FIXTURE.js +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -import value from './json-idempotency_FIXTURE.json' assert { type: 'json' }; - -globalThis.viaSecondModule = value; diff --git a/test/language/import/import-assertions/json-idempotency.js b/test/language/import/import-assertions/json-idempotency.js deleted file mode 100644 index 54832a1cad..0000000000 --- a/test/language/import/import-assertions/json-idempotency.js +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: The same object representation is returned to all import sites -flags: [module, async] -features: [import-assertions, json-modules, globalThis, dynamic-import] ----*/ - -import viaStaticImport1 from './json-idempotency_FIXTURE.json' assert { type: 'json' }; -import {default as viaStaticImport2} from './json-idempotency_FIXTURE.json' assert { type: 'json' }; -import './json-idempotency-indirect_FIXTURE.js'; - -assert.sameValue(viaStaticImport1, viaStaticImport2); -assert.sameValue(globalThis.viaSecondModule, viaStaticImport1); - -import('./json-idempotency_FIXTURE.json', { assert: { type: 'json' } }) - .then(function(viaDynamicImport) { - assert.sameValue(viaDynamicImport.default, viaStaticImport1); - }) - .then($DONE, $DONE); diff --git a/test/language/import/import-assertions/json-idempotency_FIXTURE.json b/test/language/import/import-assertions/json-idempotency_FIXTURE.json deleted file mode 100644 index 0967ef424b..0000000000 --- a/test/language/import/import-assertions/json-idempotency_FIXTURE.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/test/language/import/import-assertions/json-invalid.js b/test/language/import/import-assertions/json-invalid.js deleted file mode 100644 index 855d8566f7..0000000000 --- a/test/language/import/import-assertions/json-invalid.js +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: Does not define -info: | - # 1.4 ParseJSONModule ( source ) - - The abstract operation ParseJSONModule takes a single argument source which - is a String representing the contents of a module. - - 1. Let json be ? Call(%JSON.parse%, undefined, « source »). - 2. Return CreateDefaultExportSyntheticModule(json). -flags: [module] -features: [import-assertions, json-modules] -negative: - phase: parse - type: SyntaxError ----*/ - -$DONOTEVALUATE(); - -import value from './json-invalid_FIXTURE.json' assert { type: 'json' }; diff --git a/test/language/import/import-assertions/json-invalid_FIXTURE.json b/test/language/import/import-assertions/json-invalid_FIXTURE.json deleted file mode 100644 index 64809bccc4..0000000000 --- a/test/language/import/import-assertions/json-invalid_FIXTURE.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - notJson: 0 -} diff --git a/test/language/import/import-assertions/json-named-bindings.js b/test/language/import/import-assertions/json-named-bindings.js deleted file mode 100644 index 7900fe38f8..0000000000 --- a/test/language/import/import-assertions/json-named-bindings.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: Does not define named bindings -info: | - In the early design of JSON modules, contributors considered allowing the - properties of object values in JSON modules to be imported directly by name. - This was ultimately rejected, so attempting to import in this way should - produce a SyntaxError. -flags: [module] -features: [import-assertions, json-modules] -negative: - phase: parse - type: SyntaxError ----*/ - -$DONOTEVALUATE(); - -import {name} from './json-named-bindings_FIXTURE.json' assert { type: 'json' }; diff --git a/test/language/import/import-assertions/json-named-bindings_FIXTURE.json b/test/language/import/import-assertions/json-named-bindings_FIXTURE.json deleted file mode 100644 index ead2bb7c66..0000000000 --- a/test/language/import/import-assertions/json-named-bindings_FIXTURE.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": 0 -} diff --git a/test/language/import/import-assertions/json-value-array.js b/test/language/import/import-assertions/json-value-array.js deleted file mode 100644 index 90d64b96d9..0000000000 --- a/test/language/import/import-assertions/json-value-array.js +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: Correctly parses the JSON representation of an array -info: | - # 1.4 ParseJSONModule ( source ) - - The abstract operation ParseJSONModule takes a single argument source which - is a String representing the contents of a module. - - 1. Let json be ? Call(%JSON.parse%, undefined, « source »). - 2. Return CreateDefaultExportSyntheticModule(json). - - To more fully verify parsing correctness, the source text of the imported - module record includes non-printable characters (specifically, all four forms - of JSON's so-called "whitespace" token) both before and after the "value." -flags: [module] -features: [import-assertions, json-modules] ----*/ - -import value from './json-value-array_FIXTURE.json' assert { type: 'json' }; - -assert(Array.isArray(value), 'the exported value is an array'); -assert.sameValue( - Object.getPrototypeOf(value), - Array.prototype, - 'the exported value is not a subclass of Array' -); -assert.sameValue(Object.getOwnPropertyNames(value).length, 7); -assert.sameValue(value.length, 6); - -assert.sameValue(value[0], -1.2345); -assert.sameValue(value[1], true); -assert.sameValue(value[2], 'a string value'); -assert.sameValue(value[3], null); - -assert.sameValue(Object.getPrototypeOf(value[4]), Object.prototype); -assert.sameValue(Object.getOwnPropertyNames(value[4]).length, 0); - -assert(Array.isArray(value[5]), 'the fifth element is an array'); -assert.sameValue( - Object.getPrototypeOf(value[5]), - Array.prototype, - 'the fifth element is not a subclass of Array' -); -assert.sameValue(Object.getOwnPropertyNames(value[5]).length, 1); diff --git a/test/language/import/import-assertions/json-value-array_FIXTURE.json b/test/language/import/import-assertions/json-value-array_FIXTURE.json deleted file mode 100644 index 9520048793..0000000000 --- a/test/language/import/import-assertions/json-value-array_FIXTURE.json +++ /dev/null @@ -1,10 +0,0 @@ - - [ - -1234.500e-003, - true, - "a string value", - null, - {}, - [] -] - diff --git a/test/language/import/import-assertions/json-value-boolean.js b/test/language/import/import-assertions/json-value-boolean.js deleted file mode 100644 index 0ab3fd371e..0000000000 --- a/test/language/import/import-assertions/json-value-boolean.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: Correctly parses the JSON representation of a boolean -info: | - # 1.4 ParseJSONModule ( source ) - - The abstract operation ParseJSONModule takes a single argument source which - is a String representing the contents of a module. - - 1. Let json be ? Call(%JSON.parse%, undefined, « source »). - 2. Return CreateDefaultExportSyntheticModule(json). -flags: [module] -features: [import-assertions, json-modules] ----*/ - -import value from './json-value-boolean_FIXTURE.json' assert { type: 'json' }; - -assert.sameValue(value, true); diff --git a/test/language/import/import-assertions/json-value-boolean_FIXTURE.json b/test/language/import/import-assertions/json-value-boolean_FIXTURE.json deleted file mode 100644 index 27ba77ddaf..0000000000 --- a/test/language/import/import-assertions/json-value-boolean_FIXTURE.json +++ /dev/null @@ -1 +0,0 @@ -true diff --git a/test/language/import/import-assertions/json-value-null.js b/test/language/import/import-assertions/json-value-null.js deleted file mode 100644 index cb651b33b0..0000000000 --- a/test/language/import/import-assertions/json-value-null.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: Correctly parses the JSON representation of null -info: | - # 1.4 ParseJSONModule ( source ) - - The abstract operation ParseJSONModule takes a single argument source which - is a String representing the contents of a module. - - 1. Let json be ? Call(%JSON.parse%, undefined, « source »). - 2. Return CreateDefaultExportSyntheticModule(json). -flags: [module] -features: [import-assertions, json-modules] ----*/ - -import value from './json-value-null_FIXTURE.json' assert { type: 'json' }; - -assert.sameValue(value, null); diff --git a/test/language/import/import-assertions/json-value-null_FIXTURE.json b/test/language/import/import-assertions/json-value-null_FIXTURE.json deleted file mode 100644 index 19765bd501..0000000000 --- a/test/language/import/import-assertions/json-value-null_FIXTURE.json +++ /dev/null @@ -1 +0,0 @@ -null diff --git a/test/language/import/import-assertions/json-value-number.js b/test/language/import/import-assertions/json-value-number.js deleted file mode 100644 index da4cada9d2..0000000000 --- a/test/language/import/import-assertions/json-value-number.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: Correctly parses the JSON representation of a number -info: | - # 1.4 ParseJSONModule ( source ) - - The abstract operation ParseJSONModule takes a single argument source which - is a String representing the contents of a module. - - 1. Let json be ? Call(%JSON.parse%, undefined, « source »). - 2. Return CreateDefaultExportSyntheticModule(json). -flags: [module] -features: [import-assertions, json-modules] ----*/ - -import value from './json-value-number_FIXTURE.json' assert { type: 'json' }; - -assert.sameValue(value, -1.2345); diff --git a/test/language/import/import-assertions/json-value-number_FIXTURE.json b/test/language/import/import-assertions/json-value-number_FIXTURE.json deleted file mode 100644 index 859603baed..0000000000 --- a/test/language/import/import-assertions/json-value-number_FIXTURE.json +++ /dev/null @@ -1 +0,0 @@ --1234.500e-003 diff --git a/test/language/import/import-assertions/json-value-object.js b/test/language/import/import-assertions/json-value-object.js deleted file mode 100644 index 815ab9f896..0000000000 --- a/test/language/import/import-assertions/json-value-object.js +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: Correctly parses the JSON representation of an ordinary object -info: | - # 1.4 ParseJSONModule ( source ) - - The abstract operation ParseJSONModule takes a single argument source which - is a String representing the contents of a module. - - 1. Let json be ? Call(%JSON.parse%, undefined, « source »). - 2. Return CreateDefaultExportSyntheticModule(json). - - To more fully verify parsing correctness, the source text of the imported - module record includes non-printable characters (specifically, all four forms - of JSON's so-called "whitespace" token) both before and after the "value." -flags: [module] -includes: [propertyHelper.js] -features: [import-assertions, json-modules] ----*/ - -import value from './json-value-object_FIXTURE.json' assert { type: 'json' }; - -assert.sameValue(Object.getPrototypeOf(value), Object.prototype); -assert.sameValue(Object.getOwnPropertyNames(value).length, 6); - -verifyProperty(value, 'number', { - value: -1.2345, - writable: true, - enumerable: true, - configurable: true -}); - -verifyProperty(value, 'boolean', { - value: true, - writable: true, - enumerable: true, - configurable: true -}); - -verifyProperty(value, 'string', { - value: 'a string value', - writable: true, - enumerable: true, - configurable: true -}); - -verifyProperty(value, 'null', { - value: null, - writable: true, - enumerable: true, - configurable: true -}); - -assert.sameValue(Object.getPrototypeOf(value.object), Object.prototype); -assert.sameValue(Object.getOwnPropertyNames(value.object).length, 0); - -assert( - Array.isArray(value.array), 'the value of the "array" property is an array' -); -assert.sameValue( - Object.getPrototypeOf(value.array), - Array.prototype, - 'the value of the "array" property is not a subclass of Array' -); -assert.sameValue(Object.getOwnPropertyNames(value.array).length, 1); diff --git a/test/language/import/import-assertions/json-value-object_FIXTURE.json b/test/language/import/import-assertions/json-value-object_FIXTURE.json deleted file mode 100644 index 814ec45e4d..0000000000 --- a/test/language/import/import-assertions/json-value-object_FIXTURE.json +++ /dev/null @@ -1,10 +0,0 @@ - - { - "number": -1234.500e-003, - "boolean": true, - "string": "a string value", - "null": null, - "object": {}, - "array": [] -} - diff --git a/test/language/import/import-assertions/json-value-string.js b/test/language/import/import-assertions/json-value-string.js deleted file mode 100644 index ce0ebcf323..0000000000 --- a/test/language/import/import-assertions/json-value-string.js +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: Correctly parses the JSON representation of a string -info: | - # 1.4 ParseJSONModule ( source ) - - The abstract operation ParseJSONModule takes a single argument source which - is a String representing the contents of a module. - - 1. Let json be ? Call(%JSON.parse%, undefined, « source »). - 2. Return CreateDefaultExportSyntheticModule(json). -flags: [module] -features: [import-assertions, json-modules] ----*/ - -import value from './json-value-string_FIXTURE.json' assert { type: 'json' }; - -assert.sameValue(value, 'a string value'); diff --git a/test/language/import/import-assertions/json-value-string_FIXTURE.json b/test/language/import/import-assertions/json-value-string_FIXTURE.json deleted file mode 100644 index d98e333143..0000000000 --- a/test/language/import/import-assertions/json-value-string_FIXTURE.json +++ /dev/null @@ -1 +0,0 @@ -"a string value" diff --git a/test/language/import/import-assertions/json-via-namespace.js b/test/language/import/import-assertions/json-via-namespace.js deleted file mode 100644 index f0eedb379b..0000000000 --- a/test/language/import/import-assertions/json-via-namespace.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-parse-json-module -description: May be imported via a module namespace object -flags: [module] -features: [import-assertions, json-modules] ----*/ - -import * as ns from './json-via-namespace_FIXTURE.json' assert { type: 'json' }; - -assert.sameValue(Object.getOwnPropertyNames(ns).length, 1); -assert.sameValue(ns.default, 262); diff --git a/test/language/import/import-assertions/json-via-namespace_FIXTURE.json b/test/language/import/import-assertions/json-via-namespace_FIXTURE.json deleted file mode 100644 index 5484d82917..0000000000 --- a/test/language/import/import-assertions/json-via-namespace_FIXTURE.json +++ /dev/null @@ -1 +0,0 @@ -262 diff --git a/test/language/module-code/import-assertions/README.md b/test/language/module-code/import-assertions/README.md deleted file mode 100644 index d80cf27f8e..0000000000 --- a/test/language/module-code/import-assertions/README.md +++ /dev/null @@ -1,2 +0,0 @@ -Make sure to keep the tests in this folder aligned -with the tests in the import-attributes folder. diff --git a/test/language/module-code/import-assertions/early-dup-assert-key-export.js b/test/language/module-code/import-assertions/early-dup-assert-key-export.js deleted file mode 100644 index 9f44e359a0..0000000000 --- a/test/language/module-code/import-assertions/early-dup-assert-key-export.js +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: WithClause may not have duplicate keys (export declaration) -esid: sec-modules -info: | - WithClause: AttributesKeyword { WithEntries,opt } - - - It is a Syntax Error if WithClauseToAttributes of WithClause has two - entries a and b such that a.[[Key]] is b.[[Key]]. -features: [import-assertions] -flags: [module] -negative: - phase: parse - type: SyntaxError ----*/ - -$DONOTEVALUATE(); - -export * from './import-assertion-3_FIXTURE.js' assert { - type: 'json', - 'typ\u0065': '' -}; diff --git a/test/language/module-code/import-assertions/early-dup-assert-key-import-nobinding.js b/test/language/module-code/import-assertions/early-dup-assert-key-import-nobinding.js deleted file mode 100644 index 7c48699630..0000000000 --- a/test/language/module-code/import-assertions/early-dup-assert-key-import-nobinding.js +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - WithClause may not have duplicate keys (import declaration without binding) -esid: sec-modules -info: | - WithClause: AttributesKeyword { WithEntries,opt } - - - It is a Syntax Error if WithClauseToAttributes of WithClause has two - entries a and b such that a.[[Key]] is b.[[Key]]. -features: [import-assertions] -flags: [module] -negative: - phase: parse - type: SyntaxError ----*/ - -$DONOTEVALUATE(); - -import './import-assertion-2_FIXTURE.js' assert { - type: 'json', - 'typ\u0065': '' -}; diff --git a/test/language/module-code/import-assertions/early-dup-assert-key-import-withbinding.js b/test/language/module-code/import-assertions/early-dup-assert-key-import-withbinding.js deleted file mode 100644 index 0874455882..0000000000 --- a/test/language/module-code/import-assertions/early-dup-assert-key-import-withbinding.js +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - WithClause may not have duplicate keys (import declaration with binding) -esid: sec-modules -info: | - WithClause: AttributesKeyword { WithEntries,opt } - - - It is a Syntax Error if WithClauseToAttributes of WithClause has two - entries a and b such that a.[[Key]] is b.[[Key]]. -features: [import-assertions] -flags: [module] -negative: - phase: parse - type: SyntaxError ----*/ - -$DONOTEVALUATE(); - -import x from './import-assertion-1_FIXTURE.js' assert { - type: 'json', - 'typ\u0065': '' -}; diff --git a/test/language/module-code/import-assertions/eval-gtbndng-indirect-faux-assertion.js b/test/language/module-code/import-assertions/eval-gtbndng-indirect-faux-assertion.js deleted file mode 100644 index 46b6069510..0000000000 --- a/test/language/module-code/import-assertions/eval-gtbndng-indirect-faux-assertion.js +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - `assert` AttributesKeyword in WithClause in ImportDeclaration may not - be preceded by a line terminator -esid: sec-modules -info: | - ImportDeclaration: - import ModuleSpecifier[no LineTerminator here] WithClause; - - WithClause: - AttributesKeyword {} - AttributesKeyword { WithEntries ,opt } - - AttributesKeyword: - with - [no LineTerminator here] assert - - The restriction LineTerminator could be verified more simply with a negative - syntax test. This test is designed to parse successfully in order to verify - the restriction more precisely. -features: [import-assertions, globalThis] -flags: [module, raw] ----*/ - -var callCount = 0; - -// Define a property on the global "this" value so that the effect of the -// expected IdentifierReference can be observed. -Object.defineProperty(globalThis, 'assert', { - get: function() { - callCount += 1; - } -}); - -import * as x from './import-assertion-1_FIXTURE.js' -assert -{ type: 'json' }; - -if (x.default !== 262.1) { - throw 'module value incorrectly imported - first declaration'; -} - -if (callCount !== 1) { - throw 'IdentifierReference not recognized - first declaration'; -} diff --git a/test/language/module-code/import-assertions/import-assertion-1_FIXTURE.js b/test/language/module-code/import-assertions/import-assertion-1_FIXTURE.js deleted file mode 100644 index 3e4b8af7ff..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-1_FIXTURE.js +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -export default 262.1; diff --git a/test/language/module-code/import-assertions/import-assertion-2_FIXTURE.js b/test/language/module-code/import-assertions/import-assertion-2_FIXTURE.js deleted file mode 100644 index a717e7ac57..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-2_FIXTURE.js +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -export default 262.2; diff --git a/test/language/module-code/import-assertions/import-assertion-3_FIXTURE.js b/test/language/module-code/import-assertions/import-assertion-3_FIXTURE.js deleted file mode 100644 index 376f79094d..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-3_FIXTURE.js +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -export default 262.3; diff --git a/test/language/module-code/import-assertions/import-assertion-empty.js b/test/language/module-code/import-assertions/import-assertion-empty.js deleted file mode 100644 index 11ba46ac7c..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-empty.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: WithClause in ImportDeclaration may be empty -esid: sec-modules -info: | - ImportDeclaration: - import ModuleSpecifier[no LineTerminator here] WithClause; - - WithClause: - assert {} - assert {WithEntries ,opt} - - WithEntries: - AttributeKey : StringLiteral - AttributeKey : StringLiteral , WithEntries - - AttributeKey: - IdentifierName - StringLiteral -features: [import-assertions, globalThis] -flags: [module] ----*/ - -import x from './import-assertion-1_FIXTURE.js' assert {}; -import './import-assertion-2_FIXTURE.js' assert {}; -export * from './import-assertion-3_FIXTURE.js' assert {}; - -assert.sameValue(x, 262.1); diff --git a/test/language/module-code/import-assertions/import-assertion-key-identifiername.js b/test/language/module-code/import-assertions/import-assertion-key-identifiername.js deleted file mode 100644 index 43cdf8b1e2..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-key-identifiername.js +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - WithClause in ImportDeclaration may use any valid IdentifierName as a key -esid: sec-modules -info: | - ImportDeclaration: - import ModuleSpecifier[no LineTerminator here] WithClause; - - WithClause: - assert {} - assert {WithEntries ,opt} - - WithEntries: - AttributeKey : StringLiteral - AttributeKey : StringLiteral , WithEntries - - AttributeKey: - IdentifierName - StringLiteral -negative: - phase: resolution - type: SyntaxError -features: [import-assertions] -flags: [module] ----*/ - -$DONOTEVALUATE(); - -import "../resources/ensure-linking-error_FIXTURE.js"; - -import x from './import-assertion-1_FIXTURE.js' assert {if:''}; -import './import-assertion-2_FIXTURE.js' assert {if:''}; -export * from './import-assertion-3_FIXTURE.js' assert {if:''}; - -assert.sameValue(x, 262.1); diff --git a/test/language/module-code/import-assertions/import-assertion-key-string-double.js b/test/language/module-code/import-assertions/import-assertion-key-string-double.js deleted file mode 100644 index 2aaf7c4776..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-key-string-double.js +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - WithClause in ImportDeclaration may use a string literal as a key (delimited with U+0022) -esid: sec-modules -info: | - ImportDeclaration: - import ModuleSpecifier[no LineTerminator here] WithClause; - - WithClause: - assert {} - assert {WithEntries ,opt} - - WithEntries: - AttributeKey : StringLiteral - AttributeKey : StringLiteral , WithEntries - - AttributeKey: - IdentifierName - StringLiteral -negative: - phase: resolution - type: SyntaxError -features: [import-assertions, globalThis] -flags: [module] ----*/ - -$DONOTEVALUATE(); - -import "../resources/ensure-linking-error_FIXTURE.js"; - -import x from './import-assertion-1_FIXTURE.js' assert {"test262\u0078":''}; -import './import-assertion-2_FIXTURE.js' assert {"test262\u0078":''}; -export * from './import-assertion-3_FIXTURE.js' assert {"test262\u0078":''}; - -assert.sameValue(x, 262.1); diff --git a/test/language/module-code/import-assertions/import-assertion-key-string-single.js b/test/language/module-code/import-assertions/import-assertion-key-string-single.js deleted file mode 100644 index d4cb0abb7a..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-key-string-single.js +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - WithClause in ImportDeclaration may use a string literal as a key (delimited with U+0027) -esid: sec-modules -info: | - ImportDeclaration: - import ModuleSpecifier[no LineTerminator here] WithClause; - - WithClause: - assert {} - assert {WithEntries ,opt} - - WithEntries: - AttributeKey : StringLiteral - AttributeKey : StringLiteral , WithEntries - - AttributeKey: - IdentifierName - StringLiteral -negative: - phase: resolution - type: SyntaxError -features: [import-assertions, globalThis] -flags: [module] ----*/ - -$DONOTEVALUATE(); - -import "../resources/ensure-linking-error_FIXTURE.js"; - -import x from './import-assertion-1_FIXTURE.js' assert {'test262\u0078':''}; -import './import-assertion-2_FIXTURE.js' assert {'test262\u0078':''}; -export * from './import-assertion-3_FIXTURE.js' assert {'test262\u0078':''}; - -assert.sameValue(x, 262.1); diff --git a/test/language/module-code/import-assertions/import-assertion-many.js b/test/language/module-code/import-assertions/import-assertion-many.js deleted file mode 100644 index b970515c4f..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-many.js +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - WithClause in ImportDeclaration may contain multiple WithEntries -esid: sec-modules -info: | - ImportDeclaration: - import ModuleSpecifier[no LineTerminator here] WithClause; - - WithClause: - assert {} - assert {WithEntries ,opt} - - WithEntries: - AttributeKey : StringLiteral - AttributeKey : StringLiteral , WithEntries - - AttributeKey: - IdentifierName - StringLiteral -negative: - phase: resolution - type: SyntaxError -features: [import-assertions, globalThis] -flags: [module] ----*/ - -$DONOTEVALUATE(); - -import "../resources/ensure-linking-error_FIXTURE.js"; - -import x from './import-assertion-1_FIXTURE.js' assert {test262_1:'',test262_2:'',test262_3:'',test262_4:''}; -import './import-assertion-2_FIXTURE.js' assert {test262_1:'',test262_2:'',test262_3:'',test262_4:''}; -export * from './import-assertion-3_FIXTURE.js' assert {test262_1:'',test262_2:'',test262_3:'',test262_4:''}; diff --git a/test/language/module-code/import-assertions/import-assertion-newlines.js b/test/language/module-code/import-assertions/import-assertion-newlines.js deleted file mode 100644 index b7896d9adf..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-newlines.js +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - WithClause in ImportDeclaration may include line terminators -esid: sec-modules -info: | - ImportDeclaration: - import ModuleSpecifier[no LineTerminator here] WithClause; - - WithClause: - assert {} - assert {WithEntries ,opt} - - WithEntries: - AttributeKey : StringLiteral - AttributeKey : StringLiteral , WithEntries - - AttributeKey: - IdentifierName - StringLiteral - - This test uses all four LineFeed characters in order to completely verify the - grammar. -negative: - phase: resolution - type: SyntaxError -features: [import-assertions, globalThis] -flags: [module] ----*/ - -$DONOTEVALUATE(); - -import "../resources/ensure-linking-error_FIXTURE.js"; - -import x from './import-assertion-1_FIXTURE.js' assert - -

{ - -

test262 - -

: - -

'' - -

}; -import './import-assertion-2_FIXTURE.js' assert - -

{ - -

test262 - -

: - -

'' - -

}; -export * from './import-assertion-3_FIXTURE.js' assert - -

{ - -

test262 - -

: - -

'' - -

}; - -assert.sameValue(x, 262.1); -assert.sameValue(globalThis.test262, 262.2); diff --git a/test/language/module-code/import-assertions/import-assertion-trlng-comma.js b/test/language/module-code/import-assertions/import-assertion-trlng-comma.js deleted file mode 100644 index 89d0733df7..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-trlng-comma.js +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - WithClause in ImportDeclaration may contain a trailing comma -esid: sec-modules -info: | - ImportDeclaration: - import ModuleSpecifier[no LineTerminator here] WithClause; - - WithClause: - assert {} - assert {WithEntries ,opt} - - WithEntries: - AttributeKey : StringLiteral - AttributeKey : StringLiteral , WithEntries - - AttributeKey: - IdentifierName - StringLiteral -negative: - phase: resolution - type: SyntaxError -features: [import-assertions, globalThis] -flags: [module] ----*/ - -$DONOTEVALUATE(); - -import "../resources/ensure-linking-error_FIXTURE.js"; - -import x from './import-assertion-1_FIXTURE.js' assert {test262:'',}; -import './import-assertion-2_FIXTURE.js' assert {test262:'',}; -export * from './import-assertion-3_FIXTURE.js' assert {test262:'',}; diff --git a/test/language/module-code/import-assertions/import-assertion-value-string-double.js b/test/language/module-code/import-assertions/import-assertion-value-string-double.js deleted file mode 100644 index 0ce091ae30..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-value-string-double.js +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - WithClause in ImportDeclaration may use a string literal as a value (delimited with U+0022) -esid: sec-modules -info: | - ImportDeclaration: - import ModuleSpecifier[no LineTerminator here] WithClause; - - WithClause: - assert {} - assert {WithEntries ,opt} - - WithEntries: - AttributeKey : StringLiteral - AttributeKey : StringLiteral , WithEntries - - AttributeKey: - IdentifierName - StringLiteral -negative: - phase: resolution - type: SyntaxError -features: [import-assertions, globalThis] -flags: [module] ----*/ - -$DONOTEVALUATE(); - -import "../resources/ensure-linking-error_FIXTURE.js"; - -import x from './import-assertion-1_FIXTURE.js' assert {test262:"\u0078"}; -import './import-assertion-2_FIXTURE.js' assert {test262:"\u0078"}; -export * from './import-assertion-3_FIXTURE.js' assert {test262:"\u0078"}; diff --git a/test/language/module-code/import-assertions/import-assertion-value-string-single.js b/test/language/module-code/import-assertions/import-assertion-value-string-single.js deleted file mode 100644 index c12e13c9ac..0000000000 --- a/test/language/module-code/import-assertions/import-assertion-value-string-single.js +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2021 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -description: > - WithClause in ImportDeclaration may use a string literal as a value (delimited with U+0027) -esid: sec-modules -info: | - ImportDeclaration: - import ModuleSpecifier[no LineTerminator here] WithClause; - - WithClause: - assert {} - assert {WithEntries ,opt} - - WithEntries: - AttributeKey : StringLiteral - AttributeKey : StringLiteral , WithEntries - - AttributeKey: - IdentifierName - StringLiteral -features: [import-assertions, globalThis] -negative: - phase: resolution - type: SyntaxError -flags: [module] ----*/ - -$DONOTEVALUATE(); - -import "../resources/ensure-linking-error_FIXTURE.js"; - -import x from './import-assertion-1_FIXTURE.js' assert {test262:'\u0078'}; -import './import-assertion-2_FIXTURE.js' assert {test262:'\u0078'}; -export * from './import-assertion-3_FIXTURE.js' assert {test262:'\u0078'}; From 3b56bf655fc55f5b7aa83505c4e87b2ab8661370 Mon Sep 17 00:00:00 2001 From: Jonatan Klemets Date: Tue, 20 Aug 2024 20:27:54 +0300 Subject: [PATCH 81/90] Remove generated import-assertions test files Generated by running `./make.py clean` and `./make.py` --- ...-import-assertions-trailing-comma-first.js | 30 ---------------- ...import-assertions-trailing-comma-second.js | 30 ---------------- ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 30 ---------------- ...import-assertions-trailing-comma-second.js | 30 ---------------- ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 33 ------------------ ...import-assertions-trailing-comma-second.js | 33 ------------------ ...-import-assertions-trailing-comma-first.js | 33 ------------------ ...import-assertions-trailing-comma-second.js | 33 ------------------ ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 34 ------------------- ...import-assertions-trailing-comma-second.js | 34 ------------------- ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 30 ---------------- ...import-assertions-trailing-comma-second.js | 30 ---------------- ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 34 ------------------- ...import-assertions-trailing-comma-second.js | 34 ------------------- ...-import-assertions-trailing-comma-first.js | 33 ------------------ ...import-assertions-trailing-comma-second.js | 33 ------------------ ...-import-assertions-trailing-comma-first.js | 32 ----------------- ...import-assertions-trailing-comma-second.js | 32 ----------------- ...-import-assertions-trailing-comma-first.js | 20 ----------- ...import-assertions-trailing-comma-second.js | 20 ----------- 42 files changed, 1322 deletions(-) delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-arrow-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-arrow-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-function-await-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-function-await-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-function-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-function-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-block-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-block-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-block-labeled-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-block-labeled-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-do-while-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-do-while-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-else-braceless-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-else-braceless-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-else-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-else-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-function-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-function-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-function-return-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-function-return-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-if-braceless-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-if-braceless-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-if-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-if-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-while-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-while-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-with-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/nested-with-import-assertions-trailing-comma-second.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/top-level-import-assertions-trailing-comma-first.js delete mode 100644 test/language/expressions/dynamic-import/syntax/valid/top-level-import-assertions-trailing-comma-second.js diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-import-assertions-trailing-comma-first.js deleted file mode 100644 index 97edda186e..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,30 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-arrow-assignment-expression.template -/*--- -description: ImportCall trailing comma following first parameter (nested arrow syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -let f = () => import('./empty_FIXTURE.js',); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-import-assertions-trailing-comma-second.js deleted file mode 100644 index 87ad272769..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,30 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-arrow-assignment-expression.template -/*--- -description: ImportCall trailing comma following second parameter (nested arrow syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -let f = () => import('./empty_FIXTURE.js', {},); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-import-assertions-trailing-comma-first.js deleted file mode 100644 index e8988d36a0..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-arrow.template -/*--- -description: ImportCall trailing comma following first parameter (nested arrow syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -let f = () => { - import('./empty_FIXTURE.js',); -}; diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-import-assertions-trailing-comma-second.js deleted file mode 100644 index 7b69e7d07b..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-arrow-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-arrow.template -/*--- -description: ImportCall trailing comma following second parameter (nested arrow syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -let f = () => { - import('./empty_FIXTURE.js', {},); -}; diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-import-assertions-trailing-comma-first.js deleted file mode 100644 index f463609051..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-async-arrow-fn-await.template -/*--- -description: ImportCall trailing comma following first parameter (nested in async arrow function) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -(async () => { - await import('./empty_FIXTURE.js',) -}); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-import-assertions-trailing-comma-second.js deleted file mode 100644 index d81c466193..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-async-arrow-fn-await.template -/*--- -description: ImportCall trailing comma following second parameter (nested in async arrow function) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -(async () => { - await import('./empty_FIXTURE.js', {},) -}); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-import-assertions-trailing-comma-first.js deleted file mode 100644 index b79a7a4f26..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,30 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-async-arrow-fn-return-await.template -/*--- -description: ImportCall trailing comma following first parameter (nested in async arrow function, returned) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -(async () => await import('./empty_FIXTURE.js',)); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-import-assertions-trailing-comma-second.js deleted file mode 100644 index 03ac8acfca..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,30 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-async-arrow-fn-return-await.template -/*--- -description: ImportCall trailing comma following second parameter (nested in async arrow function, returned) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -(async () => await import('./empty_FIXTURE.js', {},)); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-await-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-await-import-assertions-trailing-comma-first.js deleted file mode 100644 index f16cb9a0cf..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-await-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-async-function-await.template -/*--- -description: ImportCall trailing comma following first parameter (nested arrow syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -async function f() { - await import('./empty_FIXTURE.js',); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-await-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-await-import-assertions-trailing-comma-second.js deleted file mode 100644 index d581669f6e..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-await-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-async-function-await.template -/*--- -description: ImportCall trailing comma following second parameter (nested arrow syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -async function f() { - await import('./empty_FIXTURE.js', {},); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-import-assertions-trailing-comma-first.js deleted file mode 100644 index 3a46430e8a..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,33 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-async-function.template -/*--- -description: ImportCall trailing comma following first parameter (nested arrow syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -async function f() { - import('./empty_FIXTURE.js',); -} - diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-import-assertions-trailing-comma-second.js deleted file mode 100644 index bb50554b3d..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,33 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-async-function.template -/*--- -description: ImportCall trailing comma following second parameter (nested arrow syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -async function f() { - import('./empty_FIXTURE.js', {},); -} - diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-import-assertions-trailing-comma-first.js deleted file mode 100644 index 3b93f33995..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,33 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-async-function-return-await.template -/*--- -description: ImportCall trailing comma following first parameter (nested arrow syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -async function f() { - return await import('./empty_FIXTURE.js',); -} - diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-import-assertions-trailing-comma-second.js deleted file mode 100644 index c22b3f4003..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,33 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-async-function-return-await.template -/*--- -description: ImportCall trailing comma following second parameter (nested arrow syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -async function f() { - return await import('./empty_FIXTURE.js', {},); -} - diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-import-assertions-trailing-comma-first.js deleted file mode 100644 index 209ffac56e..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-async-generator-await.template -/*--- -description: ImportCall trailing comma following first parameter (nested in async generator, awaited) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import, async-iteration] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -async function * f() { - await import('./empty_FIXTURE.js',) -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-import-assertions-trailing-comma-second.js deleted file mode 100644 index f1e1d7f58c..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-async-generator-await.template -/*--- -description: ImportCall trailing comma following second parameter (nested in async generator, awaited) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import, async-iteration] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -async function * f() { - await import('./empty_FIXTURE.js', {},) -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-block-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-block-import-assertions-trailing-comma-first.js deleted file mode 100644 index 057b2fbcbb..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-block-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-block.template -/*--- -description: ImportCall trailing comma following first parameter (nested block syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -{ - import('./empty_FIXTURE.js',); -}; diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-block-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-block-import-assertions-trailing-comma-second.js deleted file mode 100644 index 735e291804..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-block-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-block.template -/*--- -description: ImportCall trailing comma following second parameter (nested block syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -{ - import('./empty_FIXTURE.js', {},); -}; diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-block-labeled-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-block-labeled-import-assertions-trailing-comma-first.js deleted file mode 100644 index 4c08b8ea88..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-block-labeled-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-block-labeled.template -/*--- -description: ImportCall trailing comma following first parameter (nested block syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -label: { - import('./empty_FIXTURE.js',); -}; diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-block-labeled-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-block-labeled-import-assertions-trailing-comma-second.js deleted file mode 100644 index 593aacdff0..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-block-labeled-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-block-labeled.template -/*--- -description: ImportCall trailing comma following second parameter (nested block syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -label: { - import('./empty_FIXTURE.js', {},); -}; diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-do-while-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-do-while-import-assertions-trailing-comma-first.js deleted file mode 100644 index 858e6fbb09..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-do-while-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-do-while.template -/*--- -description: ImportCall trailing comma following first parameter (nested do while syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -do { - import('./empty_FIXTURE.js',); -} while (false); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-do-while-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-do-while-import-assertions-trailing-comma-second.js deleted file mode 100644 index 0b9224b991..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-do-while-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-do-while.template -/*--- -description: ImportCall trailing comma following second parameter (nested do while syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -do { - import('./empty_FIXTURE.js', {},); -} while (false); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-else-braceless-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-else-braceless-import-assertions-trailing-comma-first.js deleted file mode 100644 index 573a952270..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-else-braceless-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-else-braceless.template -/*--- -description: ImportCall trailing comma following first parameter (nested else syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -if (false) { - -} else import('./empty_FIXTURE.js',); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-else-braceless-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-else-braceless-import-assertions-trailing-comma-second.js deleted file mode 100644 index 68c1cd659a..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-else-braceless-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-else-braceless.template -/*--- -description: ImportCall trailing comma following second parameter (nested else syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -if (false) { - -} else import('./empty_FIXTURE.js', {},); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-else-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-else-import-assertions-trailing-comma-first.js deleted file mode 100644 index 81c97b0605..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-else-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,34 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-else.template -/*--- -description: ImportCall trailing comma following first parameter (nested else syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -if (false) { - -} else { - import('./empty_FIXTURE.js',); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-else-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-else-import-assertions-trailing-comma-second.js deleted file mode 100644 index 15229fa8a9..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-else-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,34 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-else.template -/*--- -description: ImportCall trailing comma following second parameter (nested else syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -if (false) { - -} else { - import('./empty_FIXTURE.js', {},); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-function-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-function-import-assertions-trailing-comma-first.js deleted file mode 100644 index 0fb0c2b373..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-function-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-function.template -/*--- -description: ImportCall trailing comma following first parameter (nested function syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -function fn() { - import('./empty_FIXTURE.js',); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-function-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-function-import-assertions-trailing-comma-second.js deleted file mode 100644 index 094989828a..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-function-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-function.template -/*--- -description: ImportCall trailing comma following second parameter (nested function syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -function fn() { - import('./empty_FIXTURE.js', {},); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-function-return-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-function-return-import-assertions-trailing-comma-first.js deleted file mode 100644 index 1605ee7cf7..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-function-return-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-function-return.template -/*--- -description: ImportCall trailing comma following first parameter (nested function syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -function fn() { - return import('./empty_FIXTURE.js',); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-function-return-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-function-return-import-assertions-trailing-comma-second.js deleted file mode 100644 index c05be79184..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-function-return-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-function-return.template -/*--- -description: ImportCall trailing comma following second parameter (nested function syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -function fn() { - return import('./empty_FIXTURE.js', {},); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-if-braceless-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-if-braceless-import-assertions-trailing-comma-first.js deleted file mode 100644 index ab784e5436..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-if-braceless-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,30 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-if-braceless.template -/*--- -description: ImportCall trailing comma following first parameter (nested if syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -if (true) import('./empty_FIXTURE.js',); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-if-braceless-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-if-braceless-import-assertions-trailing-comma-second.js deleted file mode 100644 index 9aea3d51a8..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-if-braceless-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,30 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-if-braceless.template -/*--- -description: ImportCall trailing comma following second parameter (nested if syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -if (true) import('./empty_FIXTURE.js', {},); diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-if-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-if-import-assertions-trailing-comma-first.js deleted file mode 100644 index b672403732..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-if-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-if.template -/*--- -description: ImportCall trailing comma following first parameter (nested if syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -if (true) { - import('./empty_FIXTURE.js',); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-if-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-if-import-assertions-trailing-comma-second.js deleted file mode 100644 index 1042adbb0e..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-if-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-if.template -/*--- -description: ImportCall trailing comma following second parameter (nested if syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -if (true) { - import('./empty_FIXTURE.js', {},); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-while-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-while-import-assertions-trailing-comma-first.js deleted file mode 100644 index 9732eef234..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-while-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,34 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-while.template -/*--- -description: ImportCall trailing comma following first parameter (nested while syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -let x = 0; -while (!x) { - x++; - import('./empty_FIXTURE.js',); -}; diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-while-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-while-import-assertions-trailing-comma-second.js deleted file mode 100644 index 7d1e6d9972..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-while-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,34 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-while.template -/*--- -description: ImportCall trailing comma following second parameter (nested while syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -let x = 0; -while (!x) { - x++; - import('./empty_FIXTURE.js', {},); -}; diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-assertions-trailing-comma-first.js deleted file mode 100644 index 66c1bb0b3c..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,33 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-with-expression.template -/*--- -description: ImportCall trailing comma following first parameter (nested with syntax in the expression position) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated, noStrict] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -with (import('./empty_FIXTURE.js',)) { - assert.sameValue(then, Promise.prototype.then); - assert.sameValue(constructor, Promise); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-assertions-trailing-comma-second.js deleted file mode 100644 index 988a5b9f0a..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-with-expression-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,33 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-with-expression.template -/*--- -description: ImportCall trailing comma following second parameter (nested with syntax in the expression position) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated, noStrict] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -with (import('./empty_FIXTURE.js', {},)) { - assert.sameValue(then, Promise.prototype.then); - assert.sameValue(constructor, Promise); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-with-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/nested-with-import-assertions-trailing-comma-first.js deleted file mode 100644 index 234bfcd81b..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-with-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/nested-with.template -/*--- -description: ImportCall trailing comma following first parameter (nested with syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated, noStrict] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -with ({}) { - import('./empty_FIXTURE.js',); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/nested-with-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/nested-with-import-assertions-trailing-comma-second.js deleted file mode 100644 index 2e341ed033..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/nested-with-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,32 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/nested-with.template -/*--- -description: ImportCall trailing comma following second parameter (nested with syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated, noStrict] -info: | - ImportCall : - import( AssignmentExpression ) - - 1. Let referencingScriptOrModule be ! GetActiveScriptOrModule(). - 2. Assert: referencingScriptOrModule is a Script Record or Module Record (i.e. is not null). - 3. Let argRef be the result of evaluating AssignmentExpression. - 4. Let specifier be ? GetValue(argRef). - 5. Let promiseCapability be ! NewPromiseCapability(%Promise%). - 6. Let specifierString be ToString(specifier). - 7. IfAbruptRejectPromise(specifierString, promiseCapability). - 8. Perform ! HostImportModuleDynamically(referencingScriptOrModule, specifierString, promiseCapability). - 9. Return promiseCapability.[[Promise]]. - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -with ({}) { - import('./empty_FIXTURE.js', {},); -} diff --git a/test/language/expressions/dynamic-import/syntax/valid/top-level-import-assertions-trailing-comma-first.js b/test/language/expressions/dynamic-import/syntax/valid/top-level-import-assertions-trailing-comma-first.js deleted file mode 100644 index d1cdc577c7..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/top-level-import-assertions-trailing-comma-first.js +++ /dev/null @@ -1,20 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-first.case -// - src/dynamic-import/syntax/valid/top-level.template -/*--- -description: ImportCall trailing comma following first parameter (top level syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -import('./empty_FIXTURE.js',); diff --git a/test/language/expressions/dynamic-import/syntax/valid/top-level-import-assertions-trailing-comma-second.js b/test/language/expressions/dynamic-import/syntax/valid/top-level-import-assertions-trailing-comma-second.js deleted file mode 100644 index 583b5c4ab6..0000000000 --- a/test/language/expressions/dynamic-import/syntax/valid/top-level-import-assertions-trailing-comma-second.js +++ /dev/null @@ -1,20 +0,0 @@ -// This file was procedurally generated from the following sources: -// - src/dynamic-import/import-assertions-trailing-comma-second.case -// - src/dynamic-import/syntax/valid/top-level.template -/*--- -description: ImportCall trailing comma following second parameter (top level syntax) -esid: sec-import-call-runtime-semantics-evaluation -features: [import-assertions, dynamic-import] -flags: [generated] -info: | - ImportCall : - import( AssignmentExpression ) - - - ImportCall : - import( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - import( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) - ----*/ - -import('./empty_FIXTURE.js', {},); From 3b4d9f53b553358986600754418453ca8abcb154 Mon Sep 17 00:00:00 2001 From: Jonatan Klemets Date: Tue, 20 Aug 2024 20:33:00 +0300 Subject: [PATCH 82/90] Remove README about keeping import-assertions tests in sync --- .../expressions/dynamic-import/import-attributes/README.md | 2 -- test/language/import/import-attributes/README.md | 2 -- test/language/module-code/import-attributes/README.md | 2 -- 3 files changed, 6 deletions(-) delete mode 100644 test/language/expressions/dynamic-import/import-attributes/README.md delete mode 100644 test/language/import/import-attributes/README.md delete mode 100644 test/language/module-code/import-attributes/README.md diff --git a/test/language/expressions/dynamic-import/import-attributes/README.md b/test/language/expressions/dynamic-import/import-attributes/README.md deleted file mode 100644 index bf4a0de27f..0000000000 --- a/test/language/expressions/dynamic-import/import-attributes/README.md +++ /dev/null @@ -1,2 +0,0 @@ -Make sure to keep the tests in this folder aligned -with the tests in the import-assertions folder. diff --git a/test/language/import/import-attributes/README.md b/test/language/import/import-attributes/README.md deleted file mode 100644 index bf4a0de27f..0000000000 --- a/test/language/import/import-attributes/README.md +++ /dev/null @@ -1,2 +0,0 @@ -Make sure to keep the tests in this folder aligned -with the tests in the import-assertions folder. diff --git a/test/language/module-code/import-attributes/README.md b/test/language/module-code/import-attributes/README.md deleted file mode 100644 index bf4a0de27f..0000000000 --- a/test/language/module-code/import-attributes/README.md +++ /dev/null @@ -1,2 +0,0 @@ -Make sure to keep the tests in this folder aligned -with the tests in the import-assertions folder. From 0661aecf7df80ea5f2882b0325415fce97e260a5 Mon Sep 17 00:00:00 2001 From: Jonatan Klemets Date: Thu, 22 Aug 2024 16:03:21 +0300 Subject: [PATCH 83/90] Replace reference to import-assertions in rfcs/async-helpers.md --- rfcs/async-helpers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/async-helpers.md b/rfcs/async-helpers.md index d5020c1c87..b5f3fe6f7d 100644 --- a/rfcs/async-helpers.md +++ b/rfcs/async-helpers.md @@ -194,7 +194,7 @@ f(); Tests written like this will correctly pass if the import Promise is rejected, and will correctly fail if the import succeeds (due to the imported module object being passed to `$DONE`.) However, at a first glance, it's not immediately clear that the test is correct in the case of the import succeeding; in fact in an earlier draft of this RFC I thought the test was incorrect. -Others, such as [`test/language/expressions/dynamic-import/import-assertions/2nd-param-non-object.js`](https://github.com/tc39/test262/blob/main/test/language/expressions/dynamic-import/import-assertions/2nd-param-non-object.js), use a pattern more like what is proposed in this RFC. However, this pattern doesn't format the messages as helpfully in all the edge cases that `assert.throws()` does, such as: +Others, such as [`test/language/expressions/dynamic-import/import-attributes/2nd-param-non-object.js`](https://github.com/tc39/test262/blob/main/test/language/expressions/dynamic-import/import-attributes/2nd-param-non-object.js), use a pattern more like what is proposed in this RFC. However, this pattern doesn't format the messages as helpfully in all the edge cases that `assert.throws()` does, such as: - the Promise being rejected with a primitive value; - the error constructor being a different object with the same name, such as a different iframe's TypeError; From b3d690e47b28a53fb94f8b62964ea8ac5aec85dd Mon Sep 17 00:00:00 2001 From: Jonatan Klemets Date: Thu, 22 Aug 2024 16:08:17 +0300 Subject: [PATCH 84/90] Remove import-assertions from features.txt --- features.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/features.txt b/features.txt index 566686c661..335651e62a 100644 --- a/features.txt +++ b/features.txt @@ -31,12 +31,6 @@ legacy-regexp # https://github.com/tc39/proposal-import-attributes/ import-attributes -# Import Assertions (Normative Optional, Deprecated) -# This feature should not be implemented, but if it is it must -# respect the specified behavior -# https://github.com/tc39/proposal-import-attributes/ -import-assertions - # JSON modules # https://github.com/tc39/proposal-json-modules json-modules From ea11e0e78739b2be9fd2f49787955b9c2bf54bcc Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 30 Jul 2024 14:36:13 -0700 Subject: [PATCH 85/90] Temporal: Further coverage and tweaks for removing Calendar/TimeZone objs Tweak some tests to provide coverage of new execution paths in the spec, such as calling GetOptionsObject inside ToTemporal___; add a few new tests for things that weren't covered before, such as rounding a PlainDateTime at the edge of the range; and tweak the tests verifying when the properties of the options bag are read, which I made a mistake in #4119. See: https://github.com/tc39/proposal-temporal/pull/2925 --- .../Duration/compare/options-wrong-type.js | 4 +-- .../compare/relativeto-string-invalid.js | 7 ++-- ...ervable-get-overflow-argument-primitive.js | 14 ++++---- ...le-get-overflow-argument-string-invalid.js | 10 ++---- .../PlainDate/from/options-wrong-type.js | 8 +++++ .../PlainDate/from/order-of-operations.js | 27 +++++++++++++-- .../prototype/with/options-wrong-type.js | 2 ++ .../prototype/with/order-of-operations.js | 8 ++--- ...ervable-get-overflow-argument-primitive.js | 7 +++- ...le-get-overflow-argument-string-invalid.js | 10 ++---- .../PlainDateTime/from/options-wrong-type.js | 8 +++++ .../PlainDateTime/from/order-of-operations.js | 27 +++++++++++++-- .../toString/rounding-edge-of-range.js | 22 ++++++++++++ .../prototype/with/options-wrong-type.js | 2 ++ .../prototype/with/order-of-operations.js | 8 ++--- ...ervable-get-overflow-argument-primitive.js | 9 +++-- ...le-get-overflow-argument-string-invalid.js | 10 ++---- .../PlainMonthDay/from/options-wrong-type.js | 4 +++ .../PlainMonthDay/from/order-of-operations.js | 17 ++++++++-- .../prototype/with/options-wrong-type.js | 2 ++ .../prototype/with/order-of-operations.js | 8 ++--- ...le-get-overflow-argument-string-invalid.js | 10 ++---- .../PlainTime/from/options-wrong-type.js | 8 +++++ .../PlainTime/from/order-of-operations.js | 28 +++++++++++++-- .../prototype/with/options-wrong-type.js | 2 ++ .../prototype/with/order-of-operations.js | 8 ++--- ...ervable-get-overflow-argument-primitive.js | 14 ++++---- ...le-get-overflow-argument-string-invalid.js | 10 ++---- .../PlainYearMonth/from/options-wrong-type.js | 4 +++ .../from/order-of-operations.js | 19 +++++++++-- .../prototype/with/options-wrong-type.js | 2 ++ .../prototype/with/order-of-operations.js | 8 ++--- ...ervable-get-overflow-argument-primitive.js | 7 +++- ...le-get-overflow-argument-string-invalid.js | 16 ++------- .../ZonedDateTime/from/options-wrong-type.js | 4 +++ .../ZonedDateTime/from/order-of-operations.js | 20 +++++++++-- .../prototype/with/options-wrong-type.js | 2 ++ .../prototype/with/non-iso-calendar-fields.js | 34 +++++++++++++++++++ .../prototype/with/non-iso-calendar-fields.js | 34 +++++++++++++++++++ .../prototype/with/non-iso-calendar-fields.js | 18 ++++++++++ .../prototype/with/non-iso-calendar-fields.js | 25 ++++++++++++++ .../prototype/with/non-iso-calendar-fields.js | 34 +++++++++++++++++++ 42 files changed, 409 insertions(+), 112 deletions(-) create mode 100644 test/built-ins/Temporal/PlainDateTime/prototype/toString/rounding-edge-of-range.js create mode 100644 test/intl402/Temporal/PlainDate/prototype/with/non-iso-calendar-fields.js create mode 100644 test/intl402/Temporal/PlainDateTime/prototype/with/non-iso-calendar-fields.js create mode 100644 test/intl402/Temporal/PlainMonthDay/prototype/with/non-iso-calendar-fields.js create mode 100644 test/intl402/Temporal/PlainYearMonth/prototype/with/non-iso-calendar-fields.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/with/non-iso-calendar-fields.js diff --git a/test/built-ins/Temporal/Duration/compare/options-wrong-type.js b/test/built-ins/Temporal/Duration/compare/options-wrong-type.js index 427dd9fee8..8c47ace345 100644 --- a/test/built-ins/Temporal/Duration/compare/options-wrong-type.js +++ b/test/built-ins/Temporal/Duration/compare/options-wrong-type.js @@ -3,7 +3,7 @@ /*--- esid: sec-temporal.duration.compare -description: TypeError thrown when options argument is a primitive +description: TypeError thrown when options argument is a primitive, before early return features: [BigInt, Symbol, Temporal] ---*/ @@ -17,6 +17,6 @@ const badOptions = [ ]; for (const value of badOptions) { - assert.throws(TypeError, () => Temporal.Duration.compare({ hours: 1 }, { minutes: 60 }, value), + assert.throws(TypeError, () => Temporal.Duration.compare({ hours: 1 }, { hours: 1 }, value), `TypeError on wrong options type ${typeof value}`); }; diff --git a/test/built-ins/Temporal/Duration/compare/relativeto-string-invalid.js b/test/built-ins/Temporal/Duration/compare/relativeto-string-invalid.js index e4e2377dc6..50e7ba05dc 100644 --- a/test/built-ins/Temporal/Duration/compare/relativeto-string-invalid.js +++ b/test/built-ins/Temporal/Duration/compare/relativeto-string-invalid.js @@ -3,12 +3,11 @@ /*--- esid: sec-temporal.duration.compare -description: RangeError thrown if relativeTo is a string with the wrong format +description: RangeError thrown if relativeTo is a string with the wrong format, before early return features: [Temporal] ---*/ ['bad string', '15:30:45.123456', 'iso8601', 'UTC', 'P1YT1H'].forEach((relativeTo) => { - const duration1 = new Temporal.Duration(0, 0, 0, 31); - const duration2 = new Temporal.Duration(0, 1); - assert.throws(RangeError, () => Temporal.Duration.compare(duration1, duration2, { relativeTo })); + const duration = new Temporal.Duration(0, 1); + assert.throws(RangeError, () => Temporal.Duration.compare(duration, duration, { relativeTo })); }); diff --git a/test/built-ins/Temporal/PlainDate/from/observable-get-overflow-argument-primitive.js b/test/built-ins/Temporal/PlainDate/from/observable-get-overflow-argument-primitive.js index d17e3269ed..dc3186a716 100644 --- a/test/built-ins/Temporal/PlainDate/from/observable-get-overflow-argument-primitive.js +++ b/test/built-ins/Temporal/PlainDate/from/observable-get-overflow-argument-primitive.js @@ -15,18 +15,18 @@ const expected = [ ]; let actual = []; -const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); +const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "reject" }, "options"); const result = Temporal.PlainDate.from("2021-05-17", options); assert.compareArray(actual, expected, "Successful call"); TemporalHelpers.assertPlainDate(result, 2021, 5, "M05", 17); actual.splice(0); // empty it for the next check -const failureExpected = [ - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", -]; assert.throws(TypeError, () => Temporal.PlainDate.from(7, options)); -assert.compareArray(actual, failureExpected, "Failing call"); +assert.compareArray(actual, [], "Failing call before options is processed"); + +actual.splice(0); + +assert.throws(RangeError, () => Temporal.PlainDate.from({ year: 2021, month: 2, day: 29 }, options)); +assert.compareArray(actual, expected, "Failing call after options is processed"); diff --git a/test/built-ins/Temporal/PlainDate/from/observable-get-overflow-argument-string-invalid.js b/test/built-ins/Temporal/PlainDate/from/observable-get-overflow-argument-string-invalid.js index b5fc45c02a..9323980870 100644 --- a/test/built-ins/Temporal/PlainDate/from/observable-get-overflow-argument-string-invalid.js +++ b/test/built-ins/Temporal/PlainDate/from/observable-get-overflow-argument-string-invalid.js @@ -3,19 +3,13 @@ /*--- esid: sec-temporal.plaindate.from -description: overflow property is extracted with ISO-invalid string argument. +description: overflow property is not extracted with ISO-invalid string argument. includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", -]; - let actual = []; const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); assert.throws(RangeError, () => Temporal.PlainDate.from("2020-13-34", options)); -assert.compareArray(actual, expected); +assert.compareArray(actual, [], "options read after ISO string parsing"); diff --git a/test/built-ins/Temporal/PlainDate/from/options-wrong-type.js b/test/built-ins/Temporal/PlainDate/from/options-wrong-type.js index 7340817660..b2396debee 100644 --- a/test/built-ins/Temporal/PlainDate/from/options-wrong-type.js +++ b/test/built-ins/Temporal/PlainDate/from/options-wrong-type.js @@ -19,4 +19,12 @@ const badOptions = [ for (const value of badOptions) { assert.throws(TypeError, () => Temporal.PlainDate.from({ year: 1976, month: 11, day: 18 }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(TypeError, () => Temporal.PlainDate.from(new Temporal.PlainDate(1976, 11, 18), value), + "TypeError thrown before cloning PlainDate instance"); + assert.throws(TypeError, () => Temporal.PlainDate.from(new Temporal.ZonedDateTime(0n, "UTC"), value), + "TypeError thrown before converting ZonedDateTime instance"); + assert.throws(TypeError, () => Temporal.PlainDate.from(new Temporal.PlainDateTime(1976, 11, 18), value), + "TypeError thrown before converting PlainDateTime instance"); + assert.throws(RangeError, () => Temporal.PlainDate.from("1976-11-18Z", value), + "Invalid string processed before throwing TypeError"); }; diff --git a/test/built-ins/Temporal/PlainDate/from/order-of-operations.js b/test/built-ins/Temporal/PlainDate/from/order-of-operations.js index 257bfda34a..add927f243 100644 --- a/test/built-ins/Temporal/PlainDate/from/order-of-operations.js +++ b/test/built-ins/Temporal/PlainDate/from/order-of-operations.js @@ -8,10 +8,13 @@ includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ +const expectedOptionsReading = [ "get options.overflow", "get options.overflow.toString", "call options.overflow.toString", +]; + +const expected = [ "get fields.calendar", "get fields.day", "get fields.day.valueOf", @@ -25,7 +28,7 @@ const expected = [ "get fields.year", "get fields.year.valueOf", "call fields.year.valueOf", -]; +].concat(expectedOptionsReading); const actual = []; const fields = TemporalHelpers.propertyBagObserver(actual, { @@ -43,3 +46,23 @@ const options = TemporalHelpers.propertyBagObserver(actual, { const result = Temporal.PlainDate.from(fields, options); assert.compareArray(actual, expected, "order of operations"); + +actual.splice(0); // clear for next test + +Temporal.PlainDate.from(new Temporal.PlainDate(2000, 5, 2), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a PlainDate instance"); + +actual.splice(0); + +Temporal.PlainDate.from(new Temporal.PlainDateTime(2000, 5, 2), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a PlainDateTime instance"); + +actual.splice(0); + +Temporal.PlainDate.from(new Temporal.ZonedDateTime(0n, "UTC"), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a ZonedDateTime instance"); + +actual.splice(0); + +Temporal.PlainDate.from("2001-05-02", options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string"); diff --git a/test/built-ins/Temporal/PlainDate/prototype/with/options-wrong-type.js b/test/built-ins/Temporal/PlainDate/prototype/with/options-wrong-type.js index 0fdb1c24e6..39904e1afe 100644 --- a/test/built-ins/Temporal/PlainDate/prototype/with/options-wrong-type.js +++ b/test/built-ins/Temporal/PlainDate/prototype/with/options-wrong-type.js @@ -20,4 +20,6 @@ const instance = new Temporal.PlainDate(2000, 5, 2); for (const value of badOptions) { assert.throws(TypeError, () => instance.with({ day: 5 }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(RangeError, () => instance.with({ day: -1 }, value), + "Partial date processed before throwing TypeError"); }; diff --git a/test/built-ins/Temporal/PlainDate/prototype/with/order-of-operations.js b/test/built-ins/Temporal/PlainDate/prototype/with/order-of-operations.js index 3e3d1b1df5..049cc01230 100644 --- a/test/built-ins/Temporal/PlainDate/prototype/with/order-of-operations.js +++ b/test/built-ins/Temporal/PlainDate/prototype/with/order-of-operations.js @@ -12,10 +12,6 @@ const expected = [ // RejectObjectWithCalendarOrTimeZone "get fields.calendar", "get fields.timeZone", - // GetTemporalOverflowOption - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", // PrepareTemporalFields on argument "get fields.day", "get fields.day.valueOf", @@ -29,6 +25,10 @@ const expected = [ "get fields.year", "get fields.year.valueOf", "call fields.year.valueOf", + // GetTemporalOverflowOption + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", ]; const actual = []; diff --git a/test/built-ins/Temporal/PlainDateTime/from/observable-get-overflow-argument-primitive.js b/test/built-ins/Temporal/PlainDateTime/from/observable-get-overflow-argument-primitive.js index 252511ed7a..eb61369b15 100644 --- a/test/built-ins/Temporal/PlainDateTime/from/observable-get-overflow-argument-primitive.js +++ b/test/built-ins/Temporal/PlainDateTime/from/observable-get-overflow-argument-primitive.js @@ -24,4 +24,9 @@ TemporalHelpers.assertPlainDateTime(result, 2021, 5, "M05", 17, 12, 34, 56, 0, 0 actual.splice(0); // empty it for the next check assert.throws(TypeError, () => Temporal.PlainDateTime.from(7, options)); -assert.compareArray(actual, expected, "Failing call"); +assert.compareArray(actual, [], "Failing call before options is processed"); + +actual.splice(0); + +assert.throws(RangeError, () => Temporal.PlainDateTime.from({ year: 2021, month: 2, day: 29 }, options)); +assert.compareArray(actual, expected, "Failing call after options is processed"); diff --git a/test/built-ins/Temporal/PlainDateTime/from/observable-get-overflow-argument-string-invalid.js b/test/built-ins/Temporal/PlainDateTime/from/observable-get-overflow-argument-string-invalid.js index 1fd76087a5..d9539a75a0 100644 --- a/test/built-ins/Temporal/PlainDateTime/from/observable-get-overflow-argument-string-invalid.js +++ b/test/built-ins/Temporal/PlainDateTime/from/observable-get-overflow-argument-string-invalid.js @@ -3,19 +3,13 @@ /*--- esid: sec-temporal.plaindatetime.from -description: overflow property is extracted with ISO-invalid string argument. +description: overflow property is not extracted with ISO-invalid string argument. includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", -]; - let actual = []; const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "reject" }, "options"); assert.throws(RangeError, () => Temporal.PlainDateTime.from("2020-13-34T25:60:60", options)); -assert.compareArray(actual, expected); +assert.compareArray(actual, [], "options read after string parsing"); diff --git a/test/built-ins/Temporal/PlainDateTime/from/options-wrong-type.js b/test/built-ins/Temporal/PlainDateTime/from/options-wrong-type.js index df34d81b64..04f0400a7a 100644 --- a/test/built-ins/Temporal/PlainDateTime/from/options-wrong-type.js +++ b/test/built-ins/Temporal/PlainDateTime/from/options-wrong-type.js @@ -19,4 +19,12 @@ const badOptions = [ for (const value of badOptions) { assert.throws(TypeError, () => Temporal.PlainDateTime.from({ year: 1976, month: 11, day: 18 }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(TypeError, () => Temporal.PlainDateTime.from(new Temporal.PlainDateTime(1976, 11, 18), value), + "TypeError thrown before cloning PlainDateTime instance"); + assert.throws(TypeError, () => Temporal.PlainDateTime.from(new Temporal.ZonedDateTime(0n, "UTC"), value), + "TypeError thrown before converting ZonedDateTime instance"); + assert.throws(TypeError, () => Temporal.PlainDateTime.from(new Temporal.PlainDate(1976, 11, 18), value), + "TypeError thrown before converting PlainDate instance"); + assert.throws(RangeError, () => Temporal.PlainDateTime.from("1976-11-18T12:34Z", value), + "Invalid string processed before throwing TypeError"); }; diff --git a/test/built-ins/Temporal/PlainDateTime/from/order-of-operations.js b/test/built-ins/Temporal/PlainDateTime/from/order-of-operations.js index f19ffb3522..1b0faad3f0 100644 --- a/test/built-ins/Temporal/PlainDateTime/from/order-of-operations.js +++ b/test/built-ins/Temporal/PlainDateTime/from/order-of-operations.js @@ -8,11 +8,14 @@ includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ +const expectedOptionsReading = [ // GetTemporalOverflowOption "get options.overflow", "get options.overflow.toString", "call options.overflow.toString", +]; + +const expected = [ // GetTemporalCalendarSlotValueWithISODefault "get fields.calendar", // PrepareTemporalFields @@ -46,7 +49,7 @@ const expected = [ "get fields.year", "get fields.year.valueOf", "call fields.year.valueOf", -]; +].concat(expectedOptionsReading); const actual = []; const fields = TemporalHelpers.propertyBagObserver(actual, { @@ -70,3 +73,23 @@ const options = TemporalHelpers.propertyBagObserver(actual, { Temporal.PlainDateTime.from(fields, options); assert.compareArray(actual, expected, "order of operations"); + +actual.splice(0); // clear for next test + +Temporal.PlainDateTime.from(new Temporal.PlainDateTime(2000, 5, 2), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a PlainDateTime instance"); + +actual.splice(0); + +Temporal.PlainDateTime.from(new Temporal.PlainDate(2000, 5, 2), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a PlainDate instance"); + +actual.splice(0); + +Temporal.PlainDateTime.from(new Temporal.ZonedDateTime(0n, "UTC"), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a ZonedDateTime instance"); + +actual.splice(0); + +Temporal.PlainDateTime.from("2001-05-02", options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string"); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/toString/rounding-edge-of-range.js b/test/built-ins/Temporal/PlainDateTime/prototype/toString/rounding-edge-of-range.js new file mode 100644 index 0000000000..f8a4c2870c --- /dev/null +++ b/test/built-ins/Temporal/PlainDateTime/prototype/toString/rounding-edge-of-range.js @@ -0,0 +1,22 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.tostring +description: Rounding can cause RangeError at edge of representable range +features: [Temporal] +---*/ + +const start = new Temporal.PlainDateTime(-271821, 4, 19, 0, 0, 0, 1); +assert.throws( + RangeError, + () => start.toString({ smallestUnit: "second" }), + "Rounding down can go out of range" +); + +const end = new Temporal.PlainDateTime(275760, 9, 13, 23, 59, 59, 999); +assert.throws( + RangeError, + () => end.toString({ smallestUnit: "second", roundingMode: "halfExpand" }), + "Rounding up can go out of range" +); diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/with/options-wrong-type.js b/test/built-ins/Temporal/PlainDateTime/prototype/with/options-wrong-type.js index 5c29d95e5e..3694064eb4 100644 --- a/test/built-ins/Temporal/PlainDateTime/prototype/with/options-wrong-type.js +++ b/test/built-ins/Temporal/PlainDateTime/prototype/with/options-wrong-type.js @@ -20,4 +20,6 @@ const instance = new Temporal.PlainDateTime(2000, 5, 2); for (const value of badOptions) { assert.throws(TypeError, () => instance.with({ day: 5 }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(RangeError, () => instance.with({ day: -1 }, value), + "Partial datetime processed before throwing TypeError"); }; diff --git a/test/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js b/test/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js index 9cf38b9cda..8fb29c7628 100644 --- a/test/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js +++ b/test/built-ins/Temporal/PlainDateTime/prototype/with/order-of-operations.js @@ -12,10 +12,6 @@ const expected = [ // RejectObjectWithCalendarOrTimeZone "get fields.calendar", "get fields.timeZone", - // CopyDataProperties - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", // PrepareTemporalFields on argument "get fields.day", "get fields.day.valueOf", @@ -47,6 +43,10 @@ const expected = [ "get fields.year", "get fields.year.valueOf", "call fields.year.valueOf", + // GetTemporalOverflowOption + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", ]; const actual = []; diff --git a/test/built-ins/Temporal/PlainMonthDay/from/observable-get-overflow-argument-primitive.js b/test/built-ins/Temporal/PlainMonthDay/from/observable-get-overflow-argument-primitive.js index 281311983d..f1a025b806 100644 --- a/test/built-ins/Temporal/PlainMonthDay/from/observable-get-overflow-argument-primitive.js +++ b/test/built-ins/Temporal/PlainMonthDay/from/observable-get-overflow-argument-primitive.js @@ -17,7 +17,7 @@ const expected = [ ]; let actual = []; -const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); +const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "reject" }, "options"); const result = Temporal.PlainMonthDay.from("05-17", options); assert.compareArray(actual, expected, "Successful call"); @@ -26,4 +26,9 @@ TemporalHelpers.assertPlainMonthDay(result, "M05", 17); actual.splice(0); // empty it for the next check assert.throws(TypeError, () => Temporal.PlainMonthDay.from(7, options)); -assert.compareArray(actual, expected, "Failing call"); +assert.compareArray(actual, [], "Failing call before options is processed"); + +actual.splice(0); + +assert.throws(RangeError, () => Temporal.PlainMonthDay.from({ monthCode: "M02", day: 30 }, options)); +assert.compareArray(actual, expected, "Failing call after options is processed"); diff --git a/test/built-ins/Temporal/PlainMonthDay/from/observable-get-overflow-argument-string-invalid.js b/test/built-ins/Temporal/PlainMonthDay/from/observable-get-overflow-argument-string-invalid.js index fa3f1256b5..603c7b1409 100644 --- a/test/built-ins/Temporal/PlainMonthDay/from/observable-get-overflow-argument-string-invalid.js +++ b/test/built-ins/Temporal/PlainMonthDay/from/observable-get-overflow-argument-string-invalid.js @@ -3,19 +3,13 @@ /*--- esid: sec-temporal.plainmonthday.from -description: overflow property is extracted with ISO-invalid string argument. +description: overflow property is not extracted with ISO-invalid string argument. includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", -]; - let actual = []; const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); assert.throws(RangeError, () => Temporal.PlainMonthDay.from("13-34", options)); -assert.compareArray(actual, expected); +assert.compareArray(actual, [], "options read after string parsing"); diff --git a/test/built-ins/Temporal/PlainMonthDay/from/options-wrong-type.js b/test/built-ins/Temporal/PlainMonthDay/from/options-wrong-type.js index c4c559bc6a..1d3090f2a4 100644 --- a/test/built-ins/Temporal/PlainMonthDay/from/options-wrong-type.js +++ b/test/built-ins/Temporal/PlainMonthDay/from/options-wrong-type.js @@ -19,4 +19,8 @@ const badOptions = [ for (const value of badOptions) { assert.throws(TypeError, () => Temporal.PlainMonthDay.from({ monthCode: "M12", day: 15 }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(TypeError, () => Temporal.PlainMonthDay.from(new Temporal.PlainMonthDay(12, 15), value), + "TypeError thrown before cloning PlainMonthDay instance"); + assert.throws(RangeError, () => Temporal.PlainMonthDay.from("1976-11-18Z", value), + "Invalid string string processed before throwing TypeError"); }; diff --git a/test/built-ins/Temporal/PlainMonthDay/from/order-of-operations.js b/test/built-ins/Temporal/PlainMonthDay/from/order-of-operations.js index 8bea4600cb..bbb6e91074 100644 --- a/test/built-ins/Temporal/PlainMonthDay/from/order-of-operations.js +++ b/test/built-ins/Temporal/PlainMonthDay/from/order-of-operations.js @@ -8,10 +8,13 @@ includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ +const expectedOptionsReading = [ "get options.overflow", "get options.overflow.toString", "call options.overflow.toString", +]; + +const expected = [ "get fields.calendar", // PrepareTemporalFields "get fields.day", @@ -26,7 +29,7 @@ const expected = [ "get fields.year", "get fields.year.valueOf", "call fields.year.valueOf", -]; +].concat(expectedOptionsReading); const actual = []; const fields = TemporalHelpers.propertyBagObserver(actual, { @@ -44,3 +47,13 @@ const options = TemporalHelpers.propertyBagObserver(actual, { Temporal.PlainMonthDay.from(fields, options); assert.compareArray(actual, expected, "order of operations"); + +actual.splice(0); // clear for next test + +Temporal.PlainMonthDay.from(new Temporal.PlainMonthDay(5, 2), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a PlainMonthDay instance"); + +actual.splice(0); + +Temporal.PlainMonthDay.from("05-02", options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string"); diff --git a/test/built-ins/Temporal/PlainMonthDay/prototype/with/options-wrong-type.js b/test/built-ins/Temporal/PlainMonthDay/prototype/with/options-wrong-type.js index 5dbd34864b..0a92ad371e 100644 --- a/test/built-ins/Temporal/PlainMonthDay/prototype/with/options-wrong-type.js +++ b/test/built-ins/Temporal/PlainMonthDay/prototype/with/options-wrong-type.js @@ -20,4 +20,6 @@ const instance = new Temporal.PlainMonthDay(5, 2); for (const value of badOptions) { assert.throws(TypeError, () => instance.with({ day: 5 }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(RangeError, () => instance.with({ day: -1 }, value), + "Partial date processed before throwing TypeError"); }; diff --git a/test/built-ins/Temporal/PlainMonthDay/prototype/with/order-of-operations.js b/test/built-ins/Temporal/PlainMonthDay/prototype/with/order-of-operations.js index d133168362..ed52124edd 100644 --- a/test/built-ins/Temporal/PlainMonthDay/prototype/with/order-of-operations.js +++ b/test/built-ins/Temporal/PlainMonthDay/prototype/with/order-of-operations.js @@ -12,10 +12,6 @@ const expected = [ // RejectObjectWithCalendarOrTimeZone "get fields.calendar", "get fields.timeZone", - // GetTemporalOverflowOption - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", // PrepareTemporalFields on argument "get fields.day", "get fields.day.valueOf", @@ -29,6 +25,10 @@ const expected = [ "get fields.year", "get fields.year.valueOf", "call fields.year.valueOf", + // GetTemporalOverflowOption + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", ]; const actual = []; diff --git a/test/built-ins/Temporal/PlainTime/from/observable-get-overflow-argument-string-invalid.js b/test/built-ins/Temporal/PlainTime/from/observable-get-overflow-argument-string-invalid.js index 5f6d1ce1e1..69d21f42b7 100644 --- a/test/built-ins/Temporal/PlainTime/from/observable-get-overflow-argument-string-invalid.js +++ b/test/built-ins/Temporal/PlainTime/from/observable-get-overflow-argument-string-invalid.js @@ -3,17 +3,11 @@ /*--- esid: sec-temporal.plaintime.from -description: overflow property is extracted with ISO-invalid string argument. +description: overflow property is not extracted with ISO-invalid string argument. includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ - "get overflow", - "get overflow.toString", - "call overflow.toString", -]; - let actual = []; const object = { get overflow() { @@ -23,4 +17,4 @@ const object = { }; assert.throws(RangeError, () => Temporal.PlainTime.from("24:60", object)); -assert.compareArray(actual, expected); +assert.compareArray(actual, [], "options read after ISO string parsing"); diff --git a/test/built-ins/Temporal/PlainTime/from/options-wrong-type.js b/test/built-ins/Temporal/PlainTime/from/options-wrong-type.js index 587674dd12..c720cda26f 100644 --- a/test/built-ins/Temporal/PlainTime/from/options-wrong-type.js +++ b/test/built-ins/Temporal/PlainTime/from/options-wrong-type.js @@ -19,4 +19,12 @@ const badOptions = [ for (const value of badOptions) { assert.throws(TypeError, () => Temporal.PlainTime.from({ hour: 12, minute: 34 }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(TypeError, () => Temporal.PlainTime.from(new Temporal.PlainTime(12, 34), value), + "TypeError thrown before cloning PlainTime instance"); + assert.throws(TypeError, () => Temporal.PlainTime.from(new Temporal.ZonedDateTime(0n, "UTC"), value), + "TypeError thrown before converting ZonedDateTime instance"); + assert.throws(TypeError, () => Temporal.PlainTime.from(new Temporal.PlainDateTime(1976, 11, 18), value), + "TypeError thrown before converting PlainDateTime instance"); + assert.throws(RangeError, () => Temporal.PlainTime.from("T99:99", value), + "Invalid string processed before throwing TypeError"); }; diff --git a/test/built-ins/Temporal/PlainTime/from/order-of-operations.js b/test/built-ins/Temporal/PlainTime/from/order-of-operations.js index 96d1e89628..07818fd5fa 100644 --- a/test/built-ins/Temporal/PlainTime/from/order-of-operations.js +++ b/test/built-ins/Temporal/PlainTime/from/order-of-operations.js @@ -8,10 +8,14 @@ includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ +const expectedOptionsReading = [ + // GetTemporalOverflowOption "get options.overflow", "get options.overflow.toString", "call options.overflow.toString", +]; + +const expected = [ // ToTemporalTimeRecord "get fields.hour", "get fields.hour.valueOf", @@ -31,7 +35,7 @@ const expected = [ "get fields.second", "get fields.second.valueOf", "call fields.second.valueOf", -]; +].concat(expectedOptionsReading); const actual = []; const fields = TemporalHelpers.propertyBagObserver(actual, { @@ -50,3 +54,23 @@ const options = TemporalHelpers.propertyBagObserver(actual, { const result = Temporal.PlainTime.from(fields, options); assert.compareArray(actual, expected, "order of operations"); + +actual.splice(0); // clear for next test + +Temporal.PlainTime.from(new Temporal.PlainTime(12, 34), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a PlainTime instance"); + +actual.splice(0); + +Temporal.PlainTime.from(new Temporal.PlainDateTime(2000, 5, 2), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a PlainDateTime instance"); + +actual.splice(0); + +Temporal.PlainTime.from(new Temporal.ZonedDateTime(0n, "UTC"), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when converting a ZonedDateTime instance"); + +actual.splice(0); + +Temporal.PlainTime.from("12:34", options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string"); diff --git a/test/built-ins/Temporal/PlainTime/prototype/with/options-wrong-type.js b/test/built-ins/Temporal/PlainTime/prototype/with/options-wrong-type.js index d45bbc8986..19f963bc42 100644 --- a/test/built-ins/Temporal/PlainTime/prototype/with/options-wrong-type.js +++ b/test/built-ins/Temporal/PlainTime/prototype/with/options-wrong-type.js @@ -20,4 +20,6 @@ const instance = new Temporal.PlainTime(); for (const value of badOptions) { assert.throws(TypeError, () => instance.with({ minute: 45 }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(RangeError, () => instance.with({ minute: Infinity }, value), + "Partial time processed before throwing TypeError"); }; diff --git a/test/built-ins/Temporal/PlainTime/prototype/with/order-of-operations.js b/test/built-ins/Temporal/PlainTime/prototype/with/order-of-operations.js index 36e2854676..b70f40e2fe 100644 --- a/test/built-ins/Temporal/PlainTime/prototype/with/order-of-operations.js +++ b/test/built-ins/Temporal/PlainTime/prototype/with/order-of-operations.js @@ -13,10 +13,6 @@ const expected = [ // RejectObjectWithCalendarOrTimeZone "get fields.calendar", "get fields.timeZone", - // ToTemporalOverflow - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", // ToTemporalTimeRecord "get fields.hour", "get fields.hour.valueOf", @@ -36,6 +32,10 @@ const expected = [ "get fields.second", "get fields.second.valueOf", "call fields.second.valueOf", + // GetTemporalOverflowOption + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", ]; const actual = []; diff --git a/test/built-ins/Temporal/PlainYearMonth/from/observable-get-overflow-argument-primitive.js b/test/built-ins/Temporal/PlainYearMonth/from/observable-get-overflow-argument-primitive.js index 1714a0a460..2dced50ea4 100644 --- a/test/built-ins/Temporal/PlainYearMonth/from/observable-get-overflow-argument-primitive.js +++ b/test/built-ins/Temporal/PlainYearMonth/from/observable-get-overflow-argument-primitive.js @@ -15,18 +15,18 @@ const expected = [ ]; let actual = []; -const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); +const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "reject" }, "options"); const result = Temporal.PlainYearMonth.from("2021-05", options); assert.compareArray(actual, expected, "Successful call"); TemporalHelpers.assertPlainYearMonth(result, 2021, 5, "M05"); actual.splice(0); // empty it for the next check -const failureExpected = [ - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", -]; assert.throws(TypeError, () => Temporal.PlainYearMonth.from(7, options)); -assert.compareArray(actual, failureExpected, "Failing call"); +assert.compareArray(actual, [], "Failing call before options is processed"); + +actual.splice(0); + +assert.throws(RangeError, () => Temporal.PlainYearMonth.from({ year: 2021, month: 13 }, options)); +assert.compareArray(actual, expected, "Failing call after options is processed"); diff --git a/test/built-ins/Temporal/PlainYearMonth/from/observable-get-overflow-argument-string-invalid.js b/test/built-ins/Temporal/PlainYearMonth/from/observable-get-overflow-argument-string-invalid.js index 774824f76b..aa2323323a 100644 --- a/test/built-ins/Temporal/PlainYearMonth/from/observable-get-overflow-argument-string-invalid.js +++ b/test/built-ins/Temporal/PlainYearMonth/from/observable-get-overflow-argument-string-invalid.js @@ -3,19 +3,13 @@ /*--- esid: sec-temporal.plainyearmonth.from -description: overflow property is extracted with ISO-invalid string argument. +description: overflow property is not extracted with ISO-invalid string argument. includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", -]; - let actual = []; const options = TemporalHelpers.propertyBagObserver(actual, { overflow: "constrain" }, "options"); assert.throws(RangeError, () => Temporal.PlainYearMonth.from("2020-13", options)); -assert.compareArray(actual, expected); +assert.compareArray(actual, [], "options read after string parsing"); diff --git a/test/built-ins/Temporal/PlainYearMonth/from/options-wrong-type.js b/test/built-ins/Temporal/PlainYearMonth/from/options-wrong-type.js index eb85b8180b..71d4f234b4 100644 --- a/test/built-ins/Temporal/PlainYearMonth/from/options-wrong-type.js +++ b/test/built-ins/Temporal/PlainYearMonth/from/options-wrong-type.js @@ -19,4 +19,8 @@ const badOptions = [ for (const value of badOptions) { assert.throws(TypeError, () => Temporal.PlainYearMonth.from({ year: 2021, monthCode: "M01" }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(TypeError, () => Temporal.PlainYearMonth.from(new Temporal.PlainYearMonth(2021, 1), value), + "TypeError thrown before cloning PlainYearMonth instance"); + assert.throws(RangeError, () => Temporal.PlainYearMonth.from("1976-11-18Z", value), + "Invalid string string processed before throwing TypeError"); }; diff --git a/test/built-ins/Temporal/PlainYearMonth/from/order-of-operations.js b/test/built-ins/Temporal/PlainYearMonth/from/order-of-operations.js index 92451a2f5a..4fb65bdbab 100644 --- a/test/built-ins/Temporal/PlainYearMonth/from/order-of-operations.js +++ b/test/built-ins/Temporal/PlainYearMonth/from/order-of-operations.js @@ -8,11 +8,14 @@ includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ - // CopyDataProperties +const expectedOptionsReading = [ + // GetTemporalOverflowOption "get options.overflow", "get options.overflow.toString", "call options.overflow.toString", +]; + +const expected = [ // GetTemporalCalendarSlotValueWithISODefault "get fields.calendar", // PrepareTemporalFields @@ -25,7 +28,7 @@ const expected = [ "get fields.year", "get fields.year.valueOf", "call fields.year.valueOf", -]; +].concat(expectedOptionsReading); const actual = []; const fields = TemporalHelpers.propertyBagObserver(actual, { @@ -42,3 +45,13 @@ const options = TemporalHelpers.propertyBagObserver(actual, { Temporal.PlainYearMonth.from(fields, options); assert.compareArray(actual, expected, "order of operations"); + +actual.splice(0); // clear for next test + +Temporal.PlainYearMonth.from(new Temporal.PlainYearMonth(2000, 5), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a PlainYearMonth instance"); + +actual.splice(0); + +Temporal.PlainYearMonth.from("2000-05", options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string"); diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/with/options-wrong-type.js b/test/built-ins/Temporal/PlainYearMonth/prototype/with/options-wrong-type.js index 8b6b6e1af3..381daf6e38 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/with/options-wrong-type.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/with/options-wrong-type.js @@ -20,4 +20,6 @@ const instance = new Temporal.PlainYearMonth(2019, 10); for (const value of badOptions) { assert.throws(TypeError, () => instance.with({ year: 2020 }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(RangeError, () => instance.with({ month: -1 }, value), + "Partial date processed before throwing TypeError"); }; diff --git a/test/built-ins/Temporal/PlainYearMonth/prototype/with/order-of-operations.js b/test/built-ins/Temporal/PlainYearMonth/prototype/with/order-of-operations.js index cc8c6b6e61..7c81ce7ef0 100644 --- a/test/built-ins/Temporal/PlainYearMonth/prototype/with/order-of-operations.js +++ b/test/built-ins/Temporal/PlainYearMonth/prototype/with/order-of-operations.js @@ -12,10 +12,6 @@ const expected = [ // RejectObjectWithCalendarOrTimeZone "get fields.calendar", "get fields.timeZone", - // CopyDataProperties - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", // PrepareTemporalFields on argument "get fields.month", "get fields.month.valueOf", @@ -26,6 +22,10 @@ const expected = [ "get fields.year", "get fields.year.valueOf", "call fields.year.valueOf", + // GetTemporalOverflowOption + "get options.overflow", + "get options.overflow.toString", + "call options.overflow.toString", ]; const actual = []; diff --git a/test/built-ins/Temporal/ZonedDateTime/from/observable-get-overflow-argument-primitive.js b/test/built-ins/Temporal/ZonedDateTime/from/observable-get-overflow-argument-primitive.js index bbce75342f..c99a9cf77e 100644 --- a/test/built-ins/Temporal/ZonedDateTime/from/observable-get-overflow-argument-primitive.js +++ b/test/built-ins/Temporal/ZonedDateTime/from/observable-get-overflow-argument-primitive.js @@ -34,4 +34,9 @@ assert.sameValue(result.epochNanoseconds, 1_000_000_000_000_000_000n); actual.splice(0); // empty it for the next check assert.throws(TypeError, () => Temporal.ZonedDateTime.from(7, options)); -assert.compareArray(actual, expected, "Failing call"); +assert.compareArray(actual, [], "Failing call before options is processed"); + +actual.splice(0); + +assert.throws(RangeError, () => Temporal.ZonedDateTime.from({ year: 2021, month: 2, day: 29, timeZone: "UTC" }, options)); +assert.compareArray(actual, expected, "Failing call after options is processed"); diff --git a/test/built-ins/Temporal/ZonedDateTime/from/observable-get-overflow-argument-string-invalid.js b/test/built-ins/Temporal/ZonedDateTime/from/observable-get-overflow-argument-string-invalid.js index 2b395b1890..54e98a0439 100644 --- a/test/built-ins/Temporal/ZonedDateTime/from/observable-get-overflow-argument-string-invalid.js +++ b/test/built-ins/Temporal/ZonedDateTime/from/observable-get-overflow-argument-string-invalid.js @@ -3,23 +3,11 @@ /*--- esid: sec-temporal.zoneddatetime.from -description: options properties are extracted with ISO-invalid string argument. +description: options properties are not extracted with ISO-invalid string argument. includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ - "get options.disambiguation", - "get options.disambiguation.toString", - "call options.disambiguation.toString", - "get options.offset", - "get options.offset.toString", - "call options.offset.toString", - "get options.overflow", - "get options.overflow.toString", - "call options.overflow.toString", -]; - let actual = []; const options = TemporalHelpers.propertyBagObserver(actual, { disambiguation: "compatible", @@ -28,4 +16,4 @@ const options = TemporalHelpers.propertyBagObserver(actual, { }, "options"); assert.throws(RangeError, () => Temporal.ZonedDateTime.from("2020-13-34T25:60:60+99:99[UTC]", options)); -assert.compareArray(actual, expected); +assert.compareArray(actual, [], "options read after string parsing"); diff --git a/test/built-ins/Temporal/ZonedDateTime/from/options-wrong-type.js b/test/built-ins/Temporal/ZonedDateTime/from/options-wrong-type.js index 91fb3bab63..dcfc965938 100644 --- a/test/built-ins/Temporal/ZonedDateTime/from/options-wrong-type.js +++ b/test/built-ins/Temporal/ZonedDateTime/from/options-wrong-type.js @@ -19,4 +19,8 @@ const badOptions = [ for (const value of badOptions) { assert.throws(TypeError, () => Temporal.ZonedDateTime.from({ year: 1976, month: 11, day: 18, timeZone: "UTC" }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(TypeError, () => Temporal.ZonedDateTime.from(new Temporal.ZonedDateTime(0n, "UTC"), value), + "TypeError thrown before cloning ZonedDateTime instance"); + assert.throws(RangeError, () => Temporal.ZonedDateTime.from("1976-11-18Z", value), + "Invalid string string processed before throwing TypeError"); }; diff --git a/test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js b/test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js index ae18e7d83c..461ef86338 100644 --- a/test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js +++ b/test/built-ins/Temporal/ZonedDateTime/from/order-of-operations.js @@ -8,7 +8,7 @@ includes: [compareArray.js, temporalHelpers.js] features: [Temporal] ---*/ -const expected = [ +const expectedOptionsReading = [ // GetTemporalDisambiguationOption "get options.disambiguation", "get options.disambiguation.toString", @@ -21,6 +21,9 @@ const expected = [ "get options.overflow", "get options.overflow.toString", "call options.overflow.toString", +]; + +const expected = [ // ToTemporalCalendar "get item.calendar", // PrepareTemporalFields @@ -58,7 +61,7 @@ const expected = [ "get item.year", "get item.year.valueOf", "call item.year.valueOf", -]; +].concat(expectedOptionsReading); const actual = []; const from = TemporalHelpers.propertyBagObserver(actual, { @@ -86,5 +89,16 @@ function createOptionsObserver({ overflow = "constrain", disambiguation = "compa }, "options"); } -Temporal.ZonedDateTime.from(from, createOptionsObserver()); +const options = createOptionsObserver(); +Temporal.ZonedDateTime.from(from, options); assert.compareArray(actual, expected, "order of operations"); + +actual.splice(0); // clear for next test + +Temporal.ZonedDateTime.from(new Temporal.ZonedDateTime(0n, "UTC"), options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when cloning a ZonedDateTime instance"); + +actual.splice(0); + +Temporal.ZonedDateTime.from("2001-05-02T06:54:32.987654321+00:00[UTC]", options); +assert.compareArray(actual, expectedOptionsReading, "order of operations when parsing a string"); diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/with/options-wrong-type.js b/test/built-ins/Temporal/ZonedDateTime/prototype/with/options-wrong-type.js index 5f4d25d930..ea029a44a6 100644 --- a/test/built-ins/Temporal/ZonedDateTime/prototype/with/options-wrong-type.js +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/with/options-wrong-type.js @@ -20,4 +20,6 @@ const instance = new Temporal.ZonedDateTime(0n, "UTC"); for (const value of badOptions) { assert.throws(TypeError, () => instance.with({ day: 5 }, value), `TypeError on wrong options type ${typeof value}`); + assert.throws(RangeError, () => instance.with({ day: -1 }, value), + "Partial datetime processed before throwing TypeError"); }; diff --git a/test/intl402/Temporal/PlainDate/prototype/with/non-iso-calendar-fields.js b/test/intl402/Temporal/PlainDate/prototype/with/non-iso-calendar-fields.js new file mode 100644 index 0000000000..cf49113365 --- /dev/null +++ b/test/intl402/Temporal/PlainDate/prototype/with/non-iso-calendar-fields.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindate.prototype.with +description: Properties passed to with() are calendar fields, not ISO date +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDate(2024, 8, 8, "hebrew"); + +const resultYear = instance.with({ year: 5783 }); +assert.sameValue(resultYear.year, 5783, "year is changed"); +assert.sameValue(resultYear.month, 11, "month is changed because year has different number of months"); +assert.sameValue(resultYear.monthCode, "M11", "month code is not changed"); +assert.sameValue(resultYear.day, 4, "day is not changed"); + +const resultMonth = instance.with({ month: 13 }); +assert.sameValue(resultMonth.year, 5784, "year is not changed"); +assert.sameValue(resultMonth.month, 13, "month is changed"); +assert.sameValue(resultMonth.monthCode, "M12", "month code is changed"); +assert.sameValue(resultMonth.day, 4, "day is not changed"); + +const resultMonthCode = instance.with({ monthCode: "M10" }); +assert.sameValue(resultMonthCode.year, 5784, "year is not changed"); +assert.sameValue(resultMonthCode.month, 11, "month is changed"); +assert.sameValue(resultMonthCode.monthCode, "M10", "month code is changed"); +assert.sameValue(resultMonthCode.day, 4, "day is not changed"); + +const resultDay = instance.with({ day: 24 }); +assert.sameValue(resultDay.year, 5784, "year is not changed"); +assert.sameValue(resultDay.month, 12, "month is not changed"); +assert.sameValue(resultDay.monthCode, "M11", "month code is not changed"); +assert.sameValue(resultDay.day, 24, "day is changed"); diff --git a/test/intl402/Temporal/PlainDateTime/prototype/with/non-iso-calendar-fields.js b/test/intl402/Temporal/PlainDateTime/prototype/with/non-iso-calendar-fields.js new file mode 100644 index 0000000000..5fb04a09ea --- /dev/null +++ b/test/intl402/Temporal/PlainDateTime/prototype/with/non-iso-calendar-fields.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plaindatetime.prototype.with +description: Properties passed to with() are calendar fields, not ISO date +features: [Temporal] +---*/ + +const instance = new Temporal.PlainDateTime(2024, 8, 8, 12, 34, 56, 987, 654, 321, "hebrew"); + +const resultYear = instance.with({ year: 5783 }); +assert.sameValue(resultYear.year, 5783, "year is changed"); +assert.sameValue(resultYear.month, 11, "month is changed because year has different number of months"); +assert.sameValue(resultYear.monthCode, "M11", "month code is not changed"); +assert.sameValue(resultYear.day, 4, "day is not changed"); + +const resultMonth = instance.with({ month: 13 }); +assert.sameValue(resultMonth.year, 5784, "year is not changed"); +assert.sameValue(resultMonth.month, 13, "month is changed"); +assert.sameValue(resultMonth.monthCode, "M12", "month code is changed"); +assert.sameValue(resultMonth.day, 4, "day is not changed"); + +const resultMonthCode = instance.with({ monthCode: "M10" }); +assert.sameValue(resultMonthCode.year, 5784, "year is not changed"); +assert.sameValue(resultMonthCode.month, 11, "month is changed"); +assert.sameValue(resultMonthCode.monthCode, "M10", "month code is changed"); +assert.sameValue(resultMonthCode.day, 4, "day is not changed"); + +const resultDay = instance.with({ day: 24 }); +assert.sameValue(resultDay.year, 5784, "year is not changed"); +assert.sameValue(resultDay.month, 12, "month is not changed"); +assert.sameValue(resultDay.monthCode, "M11", "month code is not changed"); +assert.sameValue(resultDay.day, 24, "day is changed"); diff --git a/test/intl402/Temporal/PlainMonthDay/prototype/with/non-iso-calendar-fields.js b/test/intl402/Temporal/PlainMonthDay/prototype/with/non-iso-calendar-fields.js new file mode 100644 index 0000000000..81085e4a20 --- /dev/null +++ b/test/intl402/Temporal/PlainMonthDay/prototype/with/non-iso-calendar-fields.js @@ -0,0 +1,18 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainmonthday.prototype.with +description: Properties passed to with() are calendar fields, not ISO date +features: [Temporal] +---*/ + +const instance = Temporal.PlainMonthDay.from({ calendar: "hebrew", monthCode: "M11", day: 4 }); + +const resultMonthCode = instance.with({ monthCode: "M10" }); +assert.sameValue(resultMonthCode.monthCode, "M10", "month code is changed"); +assert.sameValue(resultMonthCode.day, 4, "day is not changed"); + +const resultDay = instance.with({ day: 24 }); +assert.sameValue(resultDay.monthCode, "M11", "month code is not changed"); +assert.sameValue(resultDay.day, 24, "day is changed"); diff --git a/test/intl402/Temporal/PlainYearMonth/prototype/with/non-iso-calendar-fields.js b/test/intl402/Temporal/PlainYearMonth/prototype/with/non-iso-calendar-fields.js new file mode 100644 index 0000000000..a16ebdf116 --- /dev/null +++ b/test/intl402/Temporal/PlainYearMonth/prototype/with/non-iso-calendar-fields.js @@ -0,0 +1,25 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.plainyearmonth.prototype.with +description: Properties passed to with() are calendar fields, not ISO date +features: [Temporal] +---*/ + +const instance = Temporal.PlainYearMonth.from({ calendar: "hebrew", year: 5784, monthCode: "M11" }); + +const resultYear = instance.with({ year: 5783 }); +assert.sameValue(resultYear.year, 5783, "year is changed"); +assert.sameValue(resultYear.month, 11, "month is changed because year has different number of months"); +assert.sameValue(resultYear.monthCode, "M11", "month code is not changed"); + +const resultMonth = instance.with({ month: 13 }); +assert.sameValue(resultMonth.year, 5784, "year is not changed"); +assert.sameValue(resultMonth.month, 13, "month is changed"); +assert.sameValue(resultMonth.monthCode, "M12", "month code is changed"); + +const resultMonthCode = instance.with({ monthCode: "M10" }); +assert.sameValue(resultMonthCode.year, 5784, "year is not changed"); +assert.sameValue(resultMonthCode.month, 11, "month is changed"); +assert.sameValue(resultMonthCode.monthCode, "M10", "month code is changed"); diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/with/non-iso-calendar-fields.js b/test/intl402/Temporal/ZonedDateTime/prototype/with/non-iso-calendar-fields.js new file mode 100644 index 0000000000..c77abef13c --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/with/non-iso-calendar-fields.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.with +description: Properties passed to with() are calendar fields, not ISO date +features: [Temporal] +---*/ + +const instance = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", "hebrew"); + +const resultYear = instance.with({ year: 5762 }); +assert.sameValue(resultYear.year, 5762, "year is changed"); +assert.sameValue(resultYear.month, 12, "month is not changed"); +assert.sameValue(resultYear.monthCode, "M12", "month code is not changed"); +assert.sameValue(resultYear.day, 21, "day is not changed"); + +const resultMonth = instance.with({ month: 11 }); +assert.sameValue(resultMonth.year, 5761, "year is not changed"); +assert.sameValue(resultMonth.month, 11, "month is changed"); +assert.sameValue(resultMonth.monthCode, "M11", "month code is changed"); +assert.sameValue(resultMonth.day, 21, "day is not changed"); + +const resultMonthCode = instance.with({ monthCode: "M11" }); +assert.sameValue(resultMonthCode.year, 5761, "year is not changed"); +assert.sameValue(resultMonthCode.month, 11, "month is changed"); +assert.sameValue(resultMonthCode.monthCode, "M11", "month code is changed"); +assert.sameValue(resultMonthCode.day, 21, "day is not changed"); + +const resultDay = instance.with({ day: 24 }); +assert.sameValue(resultDay.year, 5761, "year is not changed"); +assert.sameValue(resultDay.month, 12, "month is not changed"); +assert.sameValue(resultDay.monthCode, "M12", "month code is not changed"); +assert.sameValue(resultDay.day, 24, "day is changed"); From b9ed8c920cec2654bbc39dd331da76656bc33f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Tue, 27 Aug 2024 10:48:28 +0200 Subject: [PATCH 86/90] Add more tests for typed array indices in typed array set --- ...s-in-bounds-receiver-is-not-typed-array.js | 36 +++++++++++++++++ ...is-out-of-bounds-receiver-is-not-object.js | 34 ++++++++++++++++ ...t-of-bounds-receiver-is-not-typed-array.js | 34 ++++++++++++++++ .../key-is-out-of-bounds-receiver-is-proto.js | 40 +++++++++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/key-is-in-bounds-receiver-is-not-typed-array.js create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-object.js create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-typed-array.js create mode 100644 test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-proto.js diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/key-is-in-bounds-receiver-is-not-typed-array.js b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-in-bounds-receiver-is-not-typed-array.js new file mode 100644 index 0000000000..e1f5b0f82e --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-in-bounds-receiver-is-not-typed-array.js @@ -0,0 +1,36 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-typedarray-set +description: > + Receiver is not the typed array object. +info: | + 10.4.5.5 [[Set]] ( P, V, Receiver ) + ... + i. If SameValue(O, Receiver) is true, then + ... + ii. If IsValidIntegerIndex(O, numericIndex) is false, return true. + 2. Return ? OrdinarySet(O, P, V, Receiver). + +features: [TypedArray, Reflect.set] +---*/ + +let receiver = {}; + +let typedArray = new Int32Array(10); + +let valueOfCalled = 0; + +let value = { + valueOf() { + valueOfCalled++; + return 1; + } +}; + +assert(Reflect.set(typedArray, 0, value, receiver), "[[Set]] succeeeds"); + +assert.sameValue(valueOfCalled, 0, "valueOf is not called"); + +assert.sameValue(receiver[0], value, "value assigned to receiver[0]"); diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-object.js b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-object.js new file mode 100644 index 0000000000..7236a3d1d9 --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-object.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-typedarray-set +description: > + Receiver is not an object. +info: | + 10.4.5.5 [[Set]] ( P, V, Receiver ) + ... + i. If SameValue(O, Receiver) is true, then + 1. Perform ? TypedArraySetElement(O, numericIndex, V). + 2. Return true. + ii. If IsValidIntegerIndex(O, numericIndex) is false, return true. + +features: [TypedArray, Reflect.set] +---*/ + +let receiver = "not an object"; + +let typedArray = new Int32Array(10); + +let valueOfCalled = 0; + +let value = { + valueOf() { + valueOfCalled++; + return 1; + } +}; + +assert(Reflect.set(typedArray, 100, value, receiver), "[[Set]] succeeeds"); + +assert.sameValue(valueOfCalled, 0, "valueOf is not called"); diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-typed-array.js b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-typed-array.js new file mode 100644 index 0000000000..2e772bdabc --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-typed-array.js @@ -0,0 +1,34 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-typedarray-set +description: > + Receiver is not the typed array object. +info: | + 10.4.5.5 [[Set]] ( P, V, Receiver ) + ... + i. If SameValue(O, Receiver) is true, then + 1. Perform ? TypedArraySetElement(O, numericIndex, V). + 2. Return true. + ii. If IsValidIntegerIndex(O, numericIndex) is false, return true. + +features: [TypedArray, Reflect.set] +---*/ + +let receiver = {}; + +let typedArray = new Int32Array(10); + +let valueOfCalled = 0; + +let value = { + valueOf() { + valueOfCalled++; + return 1; + } +}; + +assert(Reflect.set(typedArray, 100, value, receiver), "[[Set]] succeeeds"); + +assert.sameValue(valueOfCalled, 0, "valueOf is not called"); diff --git a/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-proto.js b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-proto.js new file mode 100644 index 0000000000..228982d33b --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-proto.js @@ -0,0 +1,40 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-typedarray-set +description: > + Receiver is an object in the prototype chain. +info: | + 10.4.5.5 [[Set]] ( P, V, Receiver ) + ... + i. If SameValue(O, Receiver) is true, then + 1. Perform ? TypedArraySetElement(O, numericIndex, V). + 2. Return true. + ii. If IsValidIntegerIndex(O, numericIndex) is false, return true. + + 10.4.5.16 TypedArraySetElement ( O, index, value ) + 1. If O.[[ContentType]] is bigint, let numValue be ? ToBigInt(value). + 2. Otherwise, let numValue be ? ToNumber(value). + ... + +features: [TypedArray, Reflect.set] +---*/ + +let receiver = new Int32Array(10); + +// |receiver| is in the prototype chain of |obj|. +let obj = Object.create(receiver); + +let valueOfCalled = 0; + +let value = { + valueOf() { + valueOfCalled++; + return 1; + } +}; + +assert(Reflect.set(obj, 100, value, receiver), "[[Set]] succeeeds"); + +assert.sameValue(valueOfCalled, 1, "valueOf is called exactly once"); From 18c8c85746c5caceafb9c976fc5a1d30aaf8f89c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Tue, 27 Aug 2024 10:49:03 +0200 Subject: [PATCH 87/90] Add more tests for deleted bindings in object environments --- ...-deleted-in-get-unscopables-strict-mode.js | 42 ++++++++++++++++++ ...ding-binding-deleted-in-get-unscopables.js | 39 ++++++++++++++++ ...-deleted-in-get-unscopables-strict-mode.js | 40 +++++++++++++++++ ...ding-binding-deleted-in-get-unscopables.js | 44 +++++++++++++++++++ ...-typed-array-in-proto-chain-strict-mode.js | 36 +++++++++++++++ ...deleted-with-typed-array-in-proto-chain.js | 33 ++++++++++++++ 6 files changed, 234 insertions(+) create mode 100644 test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js create mode 100644 test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables.js create mode 100644 test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js create mode 100644 test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables.js create mode 100644 test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain-strict-mode.js create mode 100644 test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain.js diff --git a/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js b/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js new file mode 100644 index 0000000000..68d3810aba --- /dev/null +++ b/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js @@ -0,0 +1,42 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-getbindingvalue-n-s +description: > + Binding deleted when retrieving unscopables. +info: | + 9.1.1.2.6 GetBindingValue ( N, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let value be ? HasProperty(bindingObject, N). + 3. If value is false, then + a. If S is false, return undefined; otherwise throw a ReferenceError exception. + ... + +flags: [noStrict] +features: [Symbol.unscopables] +---*/ + +var unscopablesCalled = 0; + +var env = { + binding: 0, + get [Symbol.unscopables]() { + unscopablesCalled++; + delete env.binding; + return null; + } +}; + +var result = null; +with (env) { + assert.throws(ReferenceError, function() { + "use strict"; + result = binding; + }); +} + +assert.sameValue(unscopablesCalled, 1, "get [Symbol.unscopables] called once"); + +assert.sameValue(result, null, "result not modified"); diff --git a/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables.js b/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables.js new file mode 100644 index 0000000000..7ebb6877ba --- /dev/null +++ b/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables.js @@ -0,0 +1,39 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-getbindingvalue-n-s +description: > + Binding deleted when retrieving unscopables. +info: | + 9.1.1.2.6 GetBindingValue ( N, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let value be ? HasProperty(bindingObject, N). + 3. If value is false, then + a. If S is false, return undefined; otherwise throw a ReferenceError exception. + ... + +flags: [noStrict] +features: [Symbol.unscopables] +---*/ + +var unscopablesCalled = 0; + +var env = { + binding: 0, + get [Symbol.unscopables]() { + unscopablesCalled++; + delete env.binding; + return null; + } +}; + +var result = null; +with (env) { + result = binding; +} + +assert.sameValue(unscopablesCalled, 1, "get [Symbol.unscopables] called once"); + +assert.sameValue(result, undefined, "result set to undefined"); diff --git a/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js b/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js new file mode 100644 index 0000000000..d966990ae4 --- /dev/null +++ b/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js @@ -0,0 +1,40 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-setmutablebinding-n-v-s +description: > + Binding deleted when retrieving unscopables. +info: | + 9.1.1.2.5 SetMutableBinding ( N, V, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let stillExists be ? HasProperty(bindingObject, N). + 3. If stillExists is false and S is true, throw a ReferenceError exception. + ... + +flags: [noStrict] +features: [Symbol.unscopables] +---*/ + +var unscopablesCalled = 0; + +var env = { + binding: 0, + get [Symbol.unscopables]() { + unscopablesCalled++; + delete env.binding; + return null; + } +}; + +with (env) { + assert.throws(ReferenceError, function() { + "use strict"; + binding = 123; + }); +} + +assert.sameValue(unscopablesCalled, 1, "get [Symbol.unscopables] called once"); + +assert.sameValue(Object.getOwnPropertyDescriptor(env, "binding"), undefined, "binding deleted"); diff --git a/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables.js b/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables.js new file mode 100644 index 0000000000..ec40c10db2 --- /dev/null +++ b/test/language/statements/with/set-mutable-binding-binding-deleted-in-get-unscopables.js @@ -0,0 +1,44 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-setmutablebinding-n-v-s +description: > + Binding deleted when retrieving unscopables. +info: | + 9.1.1.2.5 SetMutableBinding ( N, V, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let stillExists be ? HasProperty(bindingObject, N). + 3. If stillExists is false and S is true, throw a ReferenceError exception. + 4. Perform ? Set(bindingObject, N, V, S). + ... + +flags: [noStrict] +features: [Symbol.unscopables] +includes: [propertyHelper.js] +---*/ + +var unscopablesCalled = 0; + +var env = { + binding: 0, + get [Symbol.unscopables]() { + unscopablesCalled++; + delete env.binding; + return null; + } +}; + +with (env) { + binding = 123; +} + +assert.sameValue(unscopablesCalled, 1, "get [Symbol.unscopables] called once"); + +verifyProperty(env, "binding", { + value: 123, + writable: true, + enumerable: true, + configurable: true, +}); diff --git a/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain-strict-mode.js b/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain-strict-mode.js new file mode 100644 index 0000000000..75c732657f --- /dev/null +++ b/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain-strict-mode.js @@ -0,0 +1,36 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-setmutablebinding-n-v-s +description: > + Typed Array index binding deleted from object. +info: | + 9.1.1.2.5 SetMutableBinding ( N, V, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let stillExists be ? HasProperty(bindingObject, N). + 3. If stillExists is false and S is true, throw a ReferenceError exception. + ... + +flags: [noStrict] +features: [TypedArray] +---*/ + +var typedArray = new Int32Array(10); + +var env = Object.create(typedArray); + +Object.defineProperty(env, "NaN", { + configurable: true, + value: 100, +}); + +with (env) { + assert.throws(ReferenceError, function() { + "use strict"; + NaN = (delete env.NaN, 0); + }); +} + +assert.sameValue(Object.getOwnPropertyDescriptor(env, "NaN"), undefined); diff --git a/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain.js b/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain.js new file mode 100644 index 0000000000..a351998209 --- /dev/null +++ b/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain.js @@ -0,0 +1,33 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object-environment-records-setmutablebinding-n-v-s +description: > + Typed Array index binding deleted from object. +info: | + 9.1.1.2.5 SetMutableBinding ( N, V, S ) + + 1. Let bindingObject be envRec.[[BindingObject]]. + 2. Let stillExists be ? HasProperty(bindingObject, N). + 3. If stillExists is false and S is true, throw a ReferenceError exception. + 4. Perform ? Set(bindingObject, N, V, S). + +flags: [noStrict] +features: [TypedArray] +---*/ + +var typedArray = new Int32Array(10); + +var env = Object.create(typedArray); + +Object.defineProperty(env, "NaN", { + configurable: true, + value: 100, +}); + +with (env) { + NaN = (delete env.NaN, 0); +} + +assert.sameValue(Object.getOwnPropertyDescriptor(env, "NaN"), undefined); From a4443793b9c26ac8c11294682dd8d6c52634f2f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Tue, 27 Aug 2024 11:00:08 +0200 Subject: [PATCH 88/90] Add coverage when array buffer is resized in SetTypedArrayFromArrayLike --- ...g-value-conversion-resizes-array-buffer.js | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 test/built-ins/TypedArray/prototype/set/array-arg-value-conversion-resizes-array-buffer.js diff --git a/test/built-ins/TypedArray/prototype/set/array-arg-value-conversion-resizes-array-buffer.js b/test/built-ins/TypedArray/prototype/set/array-arg-value-conversion-resizes-array-buffer.js new file mode 100644 index 0000000000..d61c28813b --- /dev/null +++ b/test/built-ins/TypedArray/prototype/set/array-arg-value-conversion-resizes-array-buffer.js @@ -0,0 +1,66 @@ +// Copyright (C) 2024 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-settypedarrayfromarraylike +description: > + Value conversion shrinks and then grows the array buffer. +info: | + 23.2.3.26.2 SetTypedArrayFromArrayLike ( target, targetOffset, source ) + ... + 9. Repeat, while k < srcLength, + a. Let Pk be ! ToString(𝔽(k)). + b. Let value be ? Get(src, Pk). + c. Let targetIndex be 𝔽(targetOffset + k). + d. Perform ? TypedArraySetElement(target, targetIndex, value). + e. Set k to k + 1. + +features: [resizable-arraybuffer] +includes: [compareArray.js] +---*/ + +var rab = new ArrayBuffer(5, {maxByteLength: 10}); +var typedArray = new Int8Array(rab); + +var log = []; + +var growNumber = 0 + +var grow = { + valueOf() { + log.push("grow"); + rab.resize(rab.byteLength + 1); + return --growNumber; + } +}; + +var shrinkNumber = 0 + +var shrink = { + valueOf() { + log.push("shrink"); + rab.resize(rab.byteLength - 1); + return ++shrinkNumber; + } +}; + +var array = { + get length() { + return 5; + }, + 0: shrink, + 1: shrink, + 2: shrink, + 3: grow, + 4: grow, +} + +typedArray.set(array); + +assert.compareArray(log, [ + "shrink", "shrink", "shrink", "grow", "grow", +]); + +assert.compareArray(typedArray, [ + 1, 2, 0, 0 +]); From 3acb672d118bceca7aeed032fffc9f5144159f68 Mon Sep 17 00:00:00 2001 From: Ioanna M Dimitriou H <9728696+ioannad@users.noreply.github.com> Date: Tue, 27 Aug 2024 17:18:44 +0200 Subject: [PATCH 89/90] RAB: Integrate helper to rest of the tests (#4198) Co-authored-by: Philip Chimento --- .../prototype/apply/resizable-buffer.js | 99 ++++++++ .../typedarray-backed-by-resizable-buffer.js | 216 ++++++++++++++++++ .../Object/defineProperty/coerced-P-grow.js | 62 +++++ .../Object/defineProperty/coerced-P-shrink.js | 50 ++++ .../typedarray-backed-by-resizable-buffer.js | 214 +++++++++++++++++ .../typedarray-backed-by-resizable-buffer.js | 53 +++++ .../out-of-bounds-behaves-like-detached.js | 21 ++ .../TypedArray/out-of-bounds-get-and-set.js | 63 +++++ .../built-ins/TypedArray/out-of-bounds-has.js | 41 ++++ ...resizable-and-fixed-have-same-prototype.js | 19 ++ .../resizable-buffer-length-tracking-1.js | 58 +++++ .../resizable-buffer-length-tracking-2.js | 78 +++++++ .../buffer-arg/resizable-out-of-bounds.js | 36 +++ .../src-typedarray-resizable-buffer.js | 150 ++++++++++++ .../typedarray-backed-by-resizable-buffer.js | 199 ++++++++++++++++ .../statements/for-in/resizable-buffer.js | 21 ++ ...ked-by-resizable-buffer-grow-before-end.js | 57 +++++ ...-by-resizable-buffer-grow-mid-iteration.js | 71 ++++++ ...y-resizable-buffer-shrink-mid-iteration.js | 86 +++++++ ...ble-buffer-shrink-to-zero-mid-iteration.js | 58 +++++ .../typedarray-backed-by-resizable-buffer.js | 70 ++++++ 21 files changed, 1722 insertions(+) create mode 100644 test/built-ins/Function/prototype/apply/resizable-buffer.js create mode 100644 test/built-ins/Object/defineProperties/typedarray-backed-by-resizable-buffer.js create mode 100644 test/built-ins/Object/defineProperty/coerced-P-grow.js create mode 100644 test/built-ins/Object/defineProperty/coerced-P-shrink.js create mode 100644 test/built-ins/Object/defineProperty/typedarray-backed-by-resizable-buffer.js create mode 100644 test/built-ins/Object/freeze/typedarray-backed-by-resizable-buffer.js create mode 100644 test/built-ins/TypedArray/out-of-bounds-behaves-like-detached.js create mode 100644 test/built-ins/TypedArray/out-of-bounds-get-and-set.js create mode 100644 test/built-ins/TypedArray/out-of-bounds-has.js create mode 100644 test/built-ins/TypedArray/prototype/resizable-and-fixed-have-same-prototype.js create mode 100644 test/built-ins/TypedArray/resizable-buffer-length-tracking-1.js create mode 100644 test/built-ins/TypedArray/resizable-buffer-length-tracking-2.js create mode 100644 test/built-ins/TypedArrayConstructors/ctors/buffer-arg/resizable-out-of-bounds.js create mode 100644 test/built-ins/TypedArrayConstructors/ctors/typedarray-arg/src-typedarray-resizable-buffer.js create mode 100644 test/language/destructuring/binding/typedarray-backed-by-resizable-buffer.js create mode 100644 test/language/statements/for-in/resizable-buffer.js create mode 100644 test/language/statements/for-of/typedarray-backed-by-resizable-buffer-grow-before-end.js create mode 100644 test/language/statements/for-of/typedarray-backed-by-resizable-buffer-grow-mid-iteration.js create mode 100644 test/language/statements/for-of/typedarray-backed-by-resizable-buffer-shrink-mid-iteration.js create mode 100644 test/language/statements/for-of/typedarray-backed-by-resizable-buffer-shrink-to-zero-mid-iteration.js create mode 100644 test/language/statements/for-of/typedarray-backed-by-resizable-buffer.js diff --git a/test/built-ins/Function/prototype/apply/resizable-buffer.js b/test/built-ins/Function/prototype/apply/resizable-buffer.js new file mode 100644 index 0000000000..2e93f387cb --- /dev/null +++ b/test/built-ins/Function/prototype/apply/resizable-buffer.js @@ -0,0 +1,99 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-function.prototype.apply +description: > + Function.p.apply behaves correctly when the argument array is a + TypedArray backed by resizable buffer +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, i); + } + function func(...args) { + return [...args]; + } + assert.compareArray(ToNumbers(func.apply(null, fixedLength)), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(ToNumbers(func.apply(null, fixedLengthWithOffset)), [ + 2, + 3 + ]); + assert.compareArray(ToNumbers(func.apply(null, lengthTracking)), [ + 0, + 1, + 2, + 3 + ]); + assert.compareArray(ToNumbers(func.apply(null, lengthTrackingWithOffset)), [ + 2, + 3 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + assert.compareArray(ToNumbers(func.apply(null, fixedLength)), []); + assert.compareArray(ToNumbers(func.apply(null, fixedLengthWithOffset)), []); + assert.compareArray(ToNumbers(func.apply(null, lengthTracking)), [ + 0, + 1, + 2 + ]); + assert.compareArray(ToNumbers(func.apply(null, lengthTrackingWithOffset)), [2]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.compareArray(ToNumbers(func.apply(null, fixedLength)), []); + assert.compareArray(ToNumbers(func.apply(null, fixedLengthWithOffset)), []); + assert.compareArray(ToNumbers(func.apply(null, lengthTracking)), [0]); + assert.compareArray(ToNumbers(func.apply(null, lengthTrackingWithOffset)), []); + + // Shrink to zero. + rab.resize(0); + assert.compareArray(ToNumbers(func.apply(null, fixedLength)), []); + assert.compareArray(ToNumbers(func.apply(null, fixedLengthWithOffset)), []); + assert.compareArray(ToNumbers(func.apply(null, lengthTracking)), []); + assert.compareArray(ToNumbers(func.apply(null, lengthTrackingWithOffset)), []); + + // Grow so that all TAs are back in-bounds. New memory is zeroed. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + assert.compareArray(ToNumbers(func.apply(null, fixedLength)), [ + 0, + 0, + 0, + 0 + ]); + assert.compareArray(ToNumbers(func.apply(null, fixedLengthWithOffset)), [ + 0, + 0 + ]); + assert.compareArray(ToNumbers(func.apply(null, lengthTracking)), [ + 0, + 0, + 0, + 0, + 0, + 0 + ]); + assert.compareArray(ToNumbers(func.apply(null, lengthTrackingWithOffset)), [ + 0, + 0, + 0, + 0 + ]); +} diff --git a/test/built-ins/Object/defineProperties/typedarray-backed-by-resizable-buffer.js b/test/built-ins/Object/defineProperties/typedarray-backed-by-resizable-buffer.js new file mode 100644 index 0000000000..46901a0874 --- /dev/null +++ b/test/built-ins/Object/defineProperties/typedarray-backed-by-resizable-buffer.js @@ -0,0 +1,216 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.defineproperties +description: > + Object.defineProperties behaves correctly on TypedArrays backed by + resizable buffers +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, value) { + if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) { + return BigInt(value); + } else { + return value; + } +} + +function DefinePropertiesMayNeedBigInt(ta, index, value) { + const values = {}; + values[index] = { value: MayNeedBigInt(ta, value) }; + Object.defineProperties(ta, values); +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taFull = new ctor(rab, 0); + + // Orig. array: [0, 0, 0, 0] + // [0, 0, 0, 0] << fixedLength + // [0, 0] << fixedLengthWithOffset + // [0, 0, 0, 0, ...] << lengthTracking + // [0, 0, ...] << lengthTrackingWithOffset + + DefinePropertiesMayNeedBigInt(fixedLength, 0, 1); + assert.compareArray(ToNumbers(taFull), [ + 1, + 0, + 0, + 0 + ]); + DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 0, 2); + assert.compareArray(ToNumbers(taFull), [ + 1, + 0, + 2, + 0 + ]); + DefinePropertiesMayNeedBigInt(lengthTracking, 1, 3); + assert.compareArray(ToNumbers(taFull), [ + 1, + 3, + 2, + 0 + ]); + DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 1, 4); + assert.compareArray(ToNumbers(taFull), [ + 1, + 3, + 2, + 4 + ]); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(fixedLength, 4, 8); + }); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 2, 8); + }); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(lengthTracking, 4, 8); + }); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 2, 8); + }); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [1, 3, 2] + // [1, 3, 2, ...] << lengthTracking + // [2, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(fixedLength, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 0, 8); + }); + assert.compareArray(ToNumbers(taFull), [ + 1, + 3, + 2 + ]); + DefinePropertiesMayNeedBigInt(lengthTracking, 0, 5); + assert.compareArray(ToNumbers(taFull), [ + 5, + 3, + 2 + ]); + DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 0, 6); + assert.compareArray(ToNumbers(taFull), [ + 5, + 3, + 6 + ]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(fixedLength, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 0, 8); + }); + assert.compareArray(ToNumbers(taFull), [5]); + DefinePropertiesMayNeedBigInt(lengthTracking, 0, 7); + assert.compareArray(ToNumbers(taFull), [7]); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(fixedLength, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(lengthTracking, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 0, 8); + }); + assert.compareArray(ToNumbers(taFull), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + DefinePropertiesMayNeedBigInt(fixedLength, 0, 9); + assert.compareArray(ToNumbers(taFull), [ + 9, + 0, + 0, + 0, + 0, + 0 + ]); + DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 0, 10); + assert.compareArray(ToNumbers(taFull), [ + 9, + 0, + 10, + 0, + 0, + 0 + ]); + DefinePropertiesMayNeedBigInt(lengthTracking, 1, 11); + assert.compareArray(ToNumbers(taFull), [ + 9, + 11, + 10, + 0, + 0, + 0 + ]); + DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 2, 12); + assert.compareArray(ToNumbers(taFull), [ + 9, + 11, + 10, + 0, + 12, + 0 + ]); + + // Trying to define properties out of the fixed-length bounds throws. + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(fixedLength, 5, 13); + }); + assert.throws(TypeError, () => { + DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 3, 13); + }); + assert.compareArray(ToNumbers(taFull), [ + 9, + 11, + 10, + 0, + 12, + 0 + ]); + DefinePropertiesMayNeedBigInt(lengthTracking, 4, 14); + assert.compareArray(ToNumbers(taFull), [ + 9, + 11, + 10, + 0, + 14, + 0 + ]); + DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 3, 15); + assert.compareArray(ToNumbers(taFull), [ + 9, + 11, + 10, + 0, + 14, + 15 + ]); +} diff --git a/test/built-ins/Object/defineProperty/coerced-P-grow.js b/test/built-ins/Object/defineProperty/coerced-P-grow.js new file mode 100644 index 0000000000..106de77d25 --- /dev/null +++ b/test/built-ins/Object/defineProperty/coerced-P-grow.js @@ -0,0 +1,62 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.defineproperty +description: > + Object.defineProperty behaves correctly when the object is a + TypedArray backed by a resizable buffer that's grown during argument + coercion +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, value) { + if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) { + return BigInt(value); + } else { + return value; + } +} + +// Fixed length. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + // Make fixedLength go OOB. + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + const evil = { + toString: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + Object.defineProperty(fixedLength, evil, { value: MayNeedBigInt(fixedLength, 8) }); + assert.compareArray(ToNumbers(fixedLength), [ + 8, + 0, + 0, + 0 + ]); +} + +// Length tracking. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab, 0); + const evil = { + toString: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 4; // Index valid after resize. + } + }; + Object.defineProperty(lengthTracking, evil, { value: MayNeedBigInt(lengthTracking, 8) }); + assert.compareArray(ToNumbers(lengthTracking), [ + 0, + 0, + 0, + 0, + 8, + 0 + ]); +} diff --git a/test/built-ins/Object/defineProperty/coerced-P-shrink.js b/test/built-ins/Object/defineProperty/coerced-P-shrink.js new file mode 100644 index 0000000000..bcc3019d5a --- /dev/null +++ b/test/built-ins/Object/defineProperty/coerced-P-shrink.js @@ -0,0 +1,50 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.defineproperty +description: > + Object.defineProperty behaves correctly when the object is a + TypedArray backed by a resizable buffer that's shrunk during argument + coercion +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, value) { + if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) { + return BigInt(value); + } else { + return value; + } +} + +// Fixed length. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const evil = { + toString: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert.throws(TypeError, () => { + Object.defineProperty(fixedLength, evil, { value: MayNeedBigInt(fixedLength, 8) }); + }); +} + +// Length tracking. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab, 0); + const evil = { + toString: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 3; // Index too large after resize. + } + }; + assert.throws(TypeError, () => { + Object.defineProperty(lengthTracking, evil, { value: MayNeedBigInt(lengthTracking, 8) }); + }); +} diff --git a/test/built-ins/Object/defineProperty/typedarray-backed-by-resizable-buffer.js b/test/built-ins/Object/defineProperty/typedarray-backed-by-resizable-buffer.js new file mode 100644 index 0000000000..155fd50445 --- /dev/null +++ b/test/built-ins/Object/defineProperty/typedarray-backed-by-resizable-buffer.js @@ -0,0 +1,214 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.defineproperty +description: > + Object.defineProperty behaves correctly on TypedArrays backed by + resizable buffers +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, value) { + if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) { + return BigInt(value); + } else { + return value; + } +} + +function DefinePropertyMayNeedBigInt(ta, index, value) { + Object.defineProperty(ta, index, { value: MayNeedBigInt(ta, value) }); +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + const taFull = new ctor(rab, 0); + + // Orig. array: [0, 0, 0, 0] + // [0, 0, 0, 0] << fixedLength + // [0, 0] << fixedLengthWithOffset + // [0, 0, 0, 0, ...] << lengthTracking + // [0, 0, ...] << lengthTrackingWithOffset + + DefinePropertyMayNeedBigInt(fixedLength, 0, 1); + assert.compareArray(ToNumbers(taFull), [ + 1, + 0, + 0, + 0 + ]); + DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 0, 2); + assert.compareArray(ToNumbers(taFull), [ + 1, + 0, + 2, + 0 + ]); + DefinePropertyMayNeedBigInt(lengthTracking, 1, 3); + assert.compareArray(ToNumbers(taFull), [ + 1, + 3, + 2, + 0 + ]); + DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 1, 4); + assert.compareArray(ToNumbers(taFull), [ + 1, + 3, + 2, + 4 + ]); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(fixedLength, 4, 8); + }); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 2, 8); + }); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(lengthTracking, 4, 8); + }); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 2, 8); + }); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [1, 3, 2] + // [1, 3, 2, ...] << lengthTracking + // [2, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(fixedLength, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 0, 8); + }); + assert.compareArray(ToNumbers(taFull), [ + 1, + 3, + 2 + ]); + DefinePropertyMayNeedBigInt(lengthTracking, 0, 5); + assert.compareArray(ToNumbers(taFull), [ + 5, + 3, + 2 + ]); + DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 0, 6); + assert.compareArray(ToNumbers(taFull), [ + 5, + 3, + 6 + ]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(fixedLength, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 0, 8); + }); + assert.compareArray(ToNumbers(taFull), [5]); + DefinePropertyMayNeedBigInt(lengthTracking, 0, 7); + assert.compareArray(ToNumbers(taFull), [7]); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(fixedLength, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(lengthTracking, 0, 8); + }); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 0, 8); + }); + assert.compareArray(ToNumbers(taFull), []); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + DefinePropertyMayNeedBigInt(fixedLength, 0, 9); + assert.compareArray(ToNumbers(taFull), [ + 9, + 0, + 0, + 0, + 0, + 0 + ]); + DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 0, 10); + assert.compareArray(ToNumbers(taFull), [ + 9, + 0, + 10, + 0, + 0, + 0 + ]); + DefinePropertyMayNeedBigInt(lengthTracking, 1, 11); + assert.compareArray(ToNumbers(taFull), [ + 9, + 11, + 10, + 0, + 0, + 0 + ]); + DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 2, 12); + assert.compareArray(ToNumbers(taFull), [ + 9, + 11, + 10, + 0, + 12, + 0 + ]); + + // Trying to define properties out of the fixed-length bounds throws. + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(fixedLength, 5, 13); + }); + assert.throws(TypeError, () => { + DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 3, 13); + }); + assert.compareArray(ToNumbers(taFull), [ + 9, + 11, + 10, + 0, + 12, + 0 + ]); + DefinePropertyMayNeedBigInt(lengthTracking, 4, 14); + assert.compareArray(ToNumbers(taFull), [ + 9, + 11, + 10, + 0, + 14, + 0 + ]); + DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 3, 15); + assert.compareArray(ToNumbers(taFull), [ + 9, + 11, + 10, + 0, + 14, + 15 + ]); +} diff --git a/test/built-ins/Object/freeze/typedarray-backed-by-resizable-buffer.js b/test/built-ins/Object/freeze/typedarray-backed-by-resizable-buffer.js new file mode 100644 index 0000000000..ced1de4672 --- /dev/null +++ b/test/built-ins/Object/freeze/typedarray-backed-by-resizable-buffer.js @@ -0,0 +1,53 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-object.freeze +description: > + Object.freeze throws on non-0-length TypedArrays backed by resizable + buffers but do not throw on 0-length ones +features: [resizable-arraybuffer] +includes: [resizableArrayBufferUtils.js] +---*/ + +// Freezing non-OOB non-zero-length TAs throws. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + Object.freeze(fixedLength); + }); + assert.throws(TypeError, () => { + Object.freeze(fixedLengthWithOffset); + }); + assert.throws(TypeError, () => { + Object.freeze(lengthTracking); + }); + assert.throws(TypeError, () => { + Object.freeze(lengthTrackingWithOffset); + }); +} +// Freezing zero-length TAs doesn't throw. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 0); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 0); + const lengthTrackingWithOffset = new ctor(rab, 4 * ctor.BYTES_PER_ELEMENT); + Object.freeze(fixedLength); + Object.freeze(fixedLengthWithOffset); + Object.freeze(lengthTrackingWithOffset); +} +// If the buffer has been resized to make length-tracking TAs zero-length, +// freezing them also doesn't throw. +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + Object.freeze(lengthTrackingWithOffset); + rab.resize(0 * ctor.BYTES_PER_ELEMENT); + Object.freeze(lengthTracking); +} diff --git a/test/built-ins/TypedArray/out-of-bounds-behaves-like-detached.js b/test/built-ins/TypedArray/out-of-bounds-behaves-like-detached.js new file mode 100644 index 0000000000..7aa51819d2 --- /dev/null +++ b/test/built-ins/TypedArray/out-of-bounds-behaves-like-detached.js @@ -0,0 +1,21 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-isvalidintegerindex +description: > + TypedArrays backed by resizable buffers that are out-of-bounds behave + as if they were detached +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const rab = CreateResizableArrayBuffer(16, 40); +const i8a = new Int8Array(rab, 0, 4); +i8a.__proto__ = { 2: 'wrong value' }; +i8a[2] = 10; +assert.sameValue(i8a[2], 10); +assert(2 in i8a); +rab.resize(0); +assert.sameValue(i8a[2], undefined); +assert(!(2 in i8a)); diff --git a/test/built-ins/TypedArray/out-of-bounds-get-and-set.js b/test/built-ins/TypedArray/out-of-bounds-get-and-set.js new file mode 100644 index 0000000000..5e3b59c49a --- /dev/null +++ b/test/built-ins/TypedArray/out-of-bounds-get-and-set.js @@ -0,0 +1,63 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-isvalidintegerindex +description: > + Getting and setting in-bounds and out-of-bounds indices on TypedArrays backed + by resizable buffers. +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function MayNeedBigInt(ta, num) { + if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) { + return BigInt(num); + } else { + return num; + } +} + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 40 * ctor.BYTES_PER_ELEMENT); + const array = new ctor(rab, 0, 4); + // Initial values + for (let i = 0; i < 4; ++i) { + assert.sameValue(Convert(array[i]), 0); + } + // Within-bounds write + for (let i = 0; i < 4; ++i) { + array[i] = MayNeedBigInt(array, i); + } + // Within-bounds read + for (let i = 0; i < 4; ++i) { + assert.sameValue(Convert(array[i]), i, `${ctor} array fails within-bounds read`); + } + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + // OOB read. If the RAB isn't large enough to fit the entire TypedArray, + // the length of the TypedArray is treated as 0. + for (let i = 0; i < 4; ++i) { + assert.sameValue(array[i], undefined); + } + // OOB write (has no effect) + for (let i = 0; i < 4; ++i) { + array[i] = MayNeedBigInt(array, 10); + } + rab.resize(4 * ctor.BYTES_PER_ELEMENT); + // Within-bounds read + for (let i = 0; i < 2; ++i) { + assert.sameValue(array[i], MayNeedBigInt(array, i)); + } + // The shrunk-and-regrown part got zeroed. + for (let i = 2; i < 4; ++i) { + assert.sameValue(array[i], MayNeedBigInt(array, 0)); + } + rab.resize(40 * ctor.BYTES_PER_ELEMENT); + // Within-bounds read + for (let i = 0; i < 2; ++i) { + assert.sameValue(array[i], MayNeedBigInt(array, i)); + } + for (let i = 2; i < 4; ++i) { + assert.sameValue(array[i], MayNeedBigInt(array, 0)); + } +} diff --git a/test/built-ins/TypedArray/out-of-bounds-has.js b/test/built-ins/TypedArray/out-of-bounds-has.js new file mode 100644 index 0000000000..513532ffd7 --- /dev/null +++ b/test/built-ins/TypedArray/out-of-bounds-has.js @@ -0,0 +1,41 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-isvalidintegerindex +description: > + In-bound indices are testable with `in` on TypedArrays backed by resizable buffers. +info: | + IsValidIntegerIndex ( O, index ) + ... + 6. Let length be IntegerIndexedObjectLength(O, getBufferByteLength). + 7. If length is out-of-bounds or ℝ(index) < 0 or ℝ(index) ≥ length, return false. + ... +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 40 * ctor.BYTES_PER_ELEMENT); + const array = new ctor(rab, 0, 4); + // Within-bounds read + for (let i = 0; i < 4; ++i) { + assert(i in array); + } + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + // OOB read. If the RAB isn't large enough to fit the entire TypedArray, + // the length of the TypedArray is treated as 0. + for (let i = 0; i < 4; ++i) { + assert(!(i in array)); + } + rab.resize(4 * ctor.BYTES_PER_ELEMENT); + // Within-bounds read + for (let i = 0; i < 4; ++i) { + assert(i in array); + } + rab.resize(40 * ctor.BYTES_PER_ELEMENT); + // Within-bounds read + for (let i = 0; i < 4; ++i) { + assert(i in array); + } +} diff --git a/test/built-ins/TypedArray/prototype/resizable-and-fixed-have-same-prototype.js b/test/built-ins/TypedArray/prototype/resizable-and-fixed-have-same-prototype.js new file mode 100644 index 0000000000..fcf535b221 --- /dev/null +++ b/test/built-ins/TypedArray/prototype/resizable-and-fixed-have-same-prototype.js @@ -0,0 +1,19 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-%typedarray%.prototype +description: > + TypedArrays that are backed by resizable buffers have the same prototypes + as those backed by fixed-length buffers +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const rab = CreateResizableArrayBuffer(40, 80); +const ab = new ArrayBuffer(80); +for (let ctor of ctors) { + const ta_rab = new ctor(rab, 0, 3); + const ta_ab = new ctor(ab, 0, 3); + assert.sameValue(ta_ab.__proto__, ta_rab.__proto__); +} diff --git a/test/built-ins/TypedArray/resizable-buffer-length-tracking-1.js b/test/built-ins/TypedArray/resizable-buffer-length-tracking-1.js new file mode 100644 index 0000000000..3a887cbdc3 --- /dev/null +++ b/test/built-ins/TypedArray/resizable-buffer-length-tracking-1.js @@ -0,0 +1,58 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-arraybuffer-length +description: > + Basic functionality of length-tracking TypedArrays backed by resizable + buffers +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const rab = CreateResizableArrayBuffer(16, 40); +let tas = []; +for (let ctor of ctors) { + tas.push(new ctor(rab)); +} +for (let ta of tas) { + assert.sameValue(ta.length, 16 / ta.BYTES_PER_ELEMENT); + assert.sameValue(ta.byteLength, 16); +} +rab.resize(40); +for (let ta of tas) { + assert.sameValue(ta.length, 40 / ta.BYTES_PER_ELEMENT); + assert.sameValue(ta.byteLength, 40); +} +// Resize to a number which is not a multiple of all byte_lengths. +rab.resize(19); +for (let ta of tas) { + const expected_length = Math.floor(19 / ta.BYTES_PER_ELEMENT); + assert.sameValue(ta.length, expected_length); + assert.sameValue(ta.byteLength, expected_length * ta.BYTES_PER_ELEMENT); +} +rab.resize(1); +for (let ta of tas) { + if (ta.BYTES_PER_ELEMENT == 1) { + assert.sameValue(ta.length, 1); + assert.sameValue(ta.byteLength, 1); + } else { + assert.sameValue(ta.length, 0); + assert.sameValue(ta.byteLength, 0); + } +} +rab.resize(0); +for (let ta of tas) { + assert.sameValue(ta.length, 0); + assert.sameValue(ta.byteLength, 0); +} +rab.resize(8); +for (let ta of tas) { + assert.sameValue(ta.length, 8 / ta.BYTES_PER_ELEMENT); + assert.sameValue(ta.byteLength, 8); +} +rab.resize(40); +for (let ta of tas) { + assert.sameValue(ta.length, 40 / ta.BYTES_PER_ELEMENT); + assert.sameValue(ta.byteLength, 40); +} diff --git a/test/built-ins/TypedArray/resizable-buffer-length-tracking-2.js b/test/built-ins/TypedArray/resizable-buffer-length-tracking-2.js new file mode 100644 index 0000000000..aa76518aaf --- /dev/null +++ b/test/built-ins/TypedArray/resizable-buffer-length-tracking-2.js @@ -0,0 +1,78 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-arraybuffer-length +description: > + Length-tracking TypedArrays backed by resizable buffers with offsets + behave correctly +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +// length-tracking-1 but with offsets. + +const rab = CreateResizableArrayBuffer(16, 40); +const offset = 8; +let tas = []; +for (let ctor of ctors) { + tas.push(new ctor(rab, offset)); +} +for (let ta of tas) { + assert.sameValue(ta.length, (16 - offset) / ta.BYTES_PER_ELEMENT); + assert.sameValue(ta.byteLength, 16 - offset); + assert.sameValue(ta.byteOffset, offset); +} +rab.resize(40); +for (let ta of tas) { + assert.sameValue(ta.length, (40 - offset) / ta.BYTES_PER_ELEMENT); + assert.sameValue(ta.byteLength, 40 - offset); + assert.sameValue(ta.byteOffset, offset); +} +// Resize to a number which is not a multiple of all byte_lengths. +rab.resize(20); +for (let ta of tas) { + const expected_length = Math.floor((20 - offset) / ta.BYTES_PER_ELEMENT); + assert.sameValue(ta.length, expected_length); + assert.sameValue(ta.byteLength, expected_length * ta.BYTES_PER_ELEMENT); + assert.sameValue(ta.byteOffset, offset); +} +// Resize so that all TypedArrays go out of bounds (because of the offset). +rab.resize(7); +for (let ta of tas) { + assert.sameValue(ta.length, 0); + assert.sameValue(ta.byteLength, 0); + assert.sameValue(ta.byteOffset, 0); +} +rab.resize(0); +for (let ta of tas) { + assert.sameValue(ta.length, 0); + assert.sameValue(ta.byteLength, 0); + assert.sameValue(ta.byteOffset, 0); +} +rab.resize(8); +for (let ta of tas) { + assert.sameValue(ta.length, 0); + assert.sameValue(ta.byteLength, 0); + assert.sameValue(ta.byteOffset, offset); +} +// Resize so that the TypedArrays which have element size > 1 go out of bounds +// (because less than 1 full element would fit). +rab.resize(offset + 1); +for (let ta of tas) { + if (ta.BYTES_PER_ELEMENT == 1) { + assert.sameValue(ta.length, 1); + assert.sameValue(ta.byteLength, 1); + assert.sameValue(ta.byteOffset, offset); + } else { + assert.sameValue(ta.length, 0); + assert.sameValue(ta.byteLength, 0); + assert.sameValue(ta.byteOffset, offset); + } +} +rab.resize(40); +for (let ta of tas) { + assert.sameValue(ta.length, (40 - offset) / ta.BYTES_PER_ELEMENT); + assert.sameValue(ta.byteLength, 40 - offset); + assert.sameValue(ta.byteOffset, offset); +} diff --git a/test/built-ins/TypedArrayConstructors/ctors/buffer-arg/resizable-out-of-bounds.js b/test/built-ins/TypedArrayConstructors/ctors/buffer-arg/resizable-out-of-bounds.js new file mode 100644 index 0000000000..4f19aabef3 --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/ctors/buffer-arg/resizable-out-of-bounds.js @@ -0,0 +1,36 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializetypedarrayfromarraybuffer +description: > + Creating a TypedArray from a resizable buffer with invalid bounds + throw RangedError +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +const rab = CreateResizableArrayBuffer(40, 80); +for (let ctor of ctors) { + // Length too big. + assert.throws(RangeError, () => { + new ctor(rab, 0, 40 / ctor.BYTES_PER_ELEMENT + 1); + }); + // Offset too close to the end. + assert.throws(RangeError, () => { + new ctor(rab, 40 - ctor.BYTES_PER_ELEMENT, 2); + }); + // Offset beyond end. + assert.throws(RangeError, () => { + new ctor(rab, 40, 1); + }); + if (ctor.BYTES_PER_ELEMENT > 1) { + // Offset not a multiple of the byte size. + assert.throws(RangeError, () => { + new ctor(rab, 1, 1); + }); + assert.throws(RangeError, () => { + new ctor(rab, 1); + }); + } +} diff --git a/test/built-ins/TypedArrayConstructors/ctors/typedarray-arg/src-typedarray-resizable-buffer.js b/test/built-ins/TypedArrayConstructors/ctors/typedarray-arg/src-typedarray-resizable-buffer.js new file mode 100644 index 0000000000..924d3e8943 --- /dev/null +++ b/test/built-ins/TypedArrayConstructors/ctors/typedarray-arg/src-typedarray-resizable-buffer.js @@ -0,0 +1,150 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializetypedarrayfromtypedarray +description: > + Initializing a TypedArray from another TypedArray that is backed by a + resizable buffer +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +function IsBigIntTypedArray(ta) { + return ta instanceof BigInt64Array || ta instanceof BigUint64Array; +} + +function AllBigIntMatchedCtorCombinations(test) { + for (let targetCtor of ctors) { + for (let sourceCtor of ctors) { + if (IsBigIntTypedArray(new targetCtor()) != IsBigIntTypedArray(new sourceCtor())) { + continue; + } + test(targetCtor, sourceCtor); + } + } +} + +AllBigIntMatchedCtorCombinations((targetCtor, sourceCtor) => { + const rab = CreateResizableArrayBuffer(4 * sourceCtor.BYTES_PER_ELEMENT, 8 * sourceCtor.BYTES_PER_ELEMENT); + const fixedLength = new sourceCtor(rab, 0, 4); + const fixedLengthWithOffset = new sourceCtor(rab, 2 * sourceCtor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new sourceCtor(rab, 0); + const lengthTrackingWithOffset = new sourceCtor(rab, 2 * sourceCtor.BYTES_PER_ELEMENT); + + // Write some data into the array. + const taFull = new sourceCtor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taFull, i, i + 1); + } + + // Orig. array: [1, 2, 3, 4] + // [1, 2, 3, 4] << fixedLength + // [3, 4] << fixedLengthWithOffset + // [1, 2, 3, 4, ...] << lengthTracking + // [3, 4, ...] << lengthTrackingWithOffset + + assert.compareArray(ToNumbers(new targetCtor(fixedLength)), [ + 1, + 2, + 3, + 4 + ]); + assert.compareArray(ToNumbers(new targetCtor(fixedLengthWithOffset)), [ + 3, + 4 + ]); + assert.compareArray(ToNumbers(new targetCtor(lengthTracking)), [ + 1, + 2, + 3, + 4 + ]); + assert.compareArray(ToNumbers(new targetCtor(lengthTrackingWithOffset)), [ + 3, + 4 + ]); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * sourceCtor.BYTES_PER_ELEMENT); + + // Orig. array: [1, 2, 3] + // [1, 2, 3, ...] << lengthTracking + // [3, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + new targetCtor(fixedLength); + }); + assert.throws(TypeError, () => { + new targetCtor(fixedLengthWithOffset); + }); + assert.compareArray(ToNumbers(new targetCtor(lengthTracking)), [ + 1, + 2, + 3 + ]); + assert.compareArray(ToNumbers(new targetCtor(lengthTrackingWithOffset)), [3]); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * sourceCtor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + new targetCtor(fixedLength); + }); + assert.throws(TypeError, () => { + new targetCtor(fixedLengthWithOffset); + }); + assert.compareArray(ToNumbers(new targetCtor(lengthTracking)), [1]); + assert.throws(TypeError, () => { + new targetCtor(lengthTrackingWithOffset); + }); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + new targetCtor(fixedLength); + }); + assert.throws(TypeError, () => { + new targetCtor(fixedLengthWithOffset); + }); + assert.compareArray(ToNumbers(new targetCtor(lengthTracking)), []); + assert.throws(TypeError, () => { + new targetCtor(lengthTrackingWithOffset); + }); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * sourceCtor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taFull, i, i + 1); + } + + // Orig. array: [1, 2, 3, 4, 5, 6] + // [1, 2, 3, 4] << fixedLength + // [3, 4] << fixedLengthWithOffset + // [1, 2, 3, 4, 5, 6, ...] << lengthTracking + // [3, 4, 5, 6, ...] << lengthTrackingWithOffset + + assert.compareArray(ToNumbers(new targetCtor(fixedLength)), [ + 1, + 2, + 3, + 4 + ]); + assert.compareArray(ToNumbers(new targetCtor(fixedLengthWithOffset)), [ + 3, + 4 + ]); + assert.compareArray(ToNumbers(new targetCtor(lengthTracking)), [ + 1, + 2, + 3, + 4, + 5, + 6 + ]); + assert.compareArray(ToNumbers(new targetCtor(lengthTrackingWithOffset)), [ + 3, + 4, + 5, + 6 + ]); +}); diff --git a/test/language/destructuring/binding/typedarray-backed-by-resizable-buffer.js b/test/language/destructuring/binding/typedarray-backed-by-resizable-buffer.js new file mode 100644 index 0000000000..13e4df0221 --- /dev/null +++ b/test/language/destructuring/binding/typedarray-backed-by-resizable-buffer.js @@ -0,0 +1,199 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-arraybuffer-length +description: > + Destructuring assignment on TypedArrays backed by resizable buffer +includes: [compareArray.js, resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const fixedLength = new ctor(rab, 0, 4); + const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2); + const lengthTracking = new ctor(rab, 0); + const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT); + + // Write some data into the array. + let ta_write = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(ta_write, i, i); + } + { + let [a, b, c, d, e] = fixedLength; + assert.compareArray(ToNumbers([ + a, + b, + c, + d + ]), [ + 0, + 1, + 2, + 3 + ]); + assert.sameValue(e, undefined); + } + { + let [a, b, c] = fixedLengthWithOffset; + assert.compareArray(ToNumbers([ + a, + b + ]), [ + 2, + 3 + ]); + assert.sameValue(c, undefined); + } + { + let [a, b, c, d, e] = lengthTracking; + assert.compareArray(ToNumbers([ + a, + b, + c, + d + ]), [ + 0, + 1, + 2, + 3 + ]); + assert.sameValue(e, undefined); + } + { + let [a, b, c] = lengthTrackingWithOffset; + assert.compareArray(ToNumbers([ + a, + b + ]), [ + 2, + 3 + ]); + assert.sameValue(c, undefined); + } + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + let [a, b, c] = fixedLength; + }); + assert.throws(TypeError, () => { + let [a, b, c] = fixedLengthWithOffset; + }); + { + let [a, b, c, d] = lengthTracking; + assert.compareArray(ToNumbers([ + a, + b, + c + ]), [ + 0, + 1, + 2 + ]); + assert.sameValue(d, undefined); + } + { + let [a, b] = lengthTrackingWithOffset; + assert.compareArray(ToNumbers([a]), [2]); + assert.sameValue(b, undefined); + } + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + let [a, b, c] = fixedLength; + }); + assert.throws(TypeError, () => { + let [a, b, c] = fixedLengthWithOffset; + }); + assert.throws(TypeError, () => { + let [a, b, c] = lengthTrackingWithOffset; + }); + { + let [a, b] = lengthTracking; + assert.compareArray(ToNumbers([a]), [0]); + assert.sameValue(b, undefined); + } + + // Shrink to 0. + rab.resize(0); + assert.throws(TypeError, () => { + let [a, b, c] = fixedLength; + }); + assert.throws(TypeError, () => { + let [a, b, c] = fixedLengthWithOffset; + }); + assert.throws(TypeError, () => { + let [a, b, c] = lengthTrackingWithOffset; + }); + { + let [a] = lengthTracking; + assert.sameValue(a, undefined); + } + + // Grow so that all TAs are back in-bounds. The new memory is zeroed. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + { + let [a, b, c, d, e] = fixedLength; + assert.compareArray(ToNumbers([ + a, + b, + c, + d + ]), [ + 0, + 0, + 0, + 0 + ]); + assert.sameValue(e, undefined); + } + { + let [a, b, c] = fixedLengthWithOffset; + assert.compareArray(ToNumbers([ + a, + b + ]), [ + 0, + 0 + ]); + assert.sameValue(c, undefined); + } + { + let [a, b, c, d, e, f, g] = lengthTracking; + assert.compareArray(ToNumbers([ + a, + b, + c, + d, + e, + f + ]), [ + 0, + 0, + 0, + 0, + 0, + 0 + ]); + assert.sameValue(g, undefined); + } + { + let [a, b, c, d, e] = lengthTrackingWithOffset; + assert.compareArray(ToNumbers([ + a, + b, + c, + d + ]), [ + 0, + 0, + 0, + 0 + ]); + assert.sameValue(e, undefined); + } +} diff --git a/test/language/statements/for-in/resizable-buffer.js b/test/language/statements/for-in/resizable-buffer.js new file mode 100644 index 0000000000..b062415401 --- /dev/null +++ b/test/language/statements/for-in/resizable-buffer.js @@ -0,0 +1,21 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-arraybuffer-length +description: > + Indices of TypedArrays backed by resizable buffers are enumerable with + for-in +includes: [resizableArrayBufferUtils.js] +features: [resizable-arraybuffer] +---*/ + +let rab = CreateResizableArrayBuffer(100, 200); +for (let ctor of ctors) { + const ta = new ctor(rab, 0, 3); + let keys = ''; + for (const key in ta) { + keys += key; + } + assert.sameValue(keys, '012'); +} diff --git a/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-grow-before-end.js b/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-grow-before-end.js new file mode 100644 index 0000000000..e8b56e2510 --- /dev/null +++ b/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-grow-before-end.js @@ -0,0 +1,57 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-arraybuffer-length +description: > + TypedArrays backed by resizable buffers are iterable with for-of and behave + correctly when the buffer is grown during iteration +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +function CreateRab(buffer_byte_length, ctor) { + const rab = CreateResizableArrayBuffer(buffer_byte_length, 2 * buffer_byte_length); + let ta_write = new ctor(rab); + for (let i = 0; i < buffer_byte_length / ctor.BYTES_PER_ELEMENT; ++i) { + WriteToTypedArray(ta_write, i, i % 128); + } + return rab; +} + +// We need to recreate the RAB between all TA tests, since we grow it. +for (let ctor of ctors) { + const no_elements = 10; + const offset = 2; + const buffer_byte_length = no_elements * ctor.BYTES_PER_ELEMENT; + const byte_offset = offset * ctor.BYTES_PER_ELEMENT; + + // Create various different styles of TypedArrays with the RAB as the + // backing store and iterate them. + + let rab = CreateRab(buffer_byte_length, ctor); + const length_tracking_ta = new ctor(rab); + { + let expected = []; + for (let i = 0; i < no_elements; ++i) { + expected.push(i % 128); + } + // After resizing, the new memory contains zeros. + for (let i = 0; i < no_elements; ++i) { + expected.push(0); + } + TestIterationAndResize(length_tracking_ta, expected, rab, no_elements, buffer_byte_length * 2); + } + rab = CreateRab(buffer_byte_length, ctor); + const length_tracking_ta_with_offset = new ctor(rab, byte_offset); + { + let expected = []; + for (let i = offset; i < no_elements; ++i) { + expected.push(i % 128); + } + for (let i = 0; i < no_elements; ++i) { + expected.push(0); + } + TestIterationAndResize(length_tracking_ta_with_offset, expected, rab, no_elements - offset, buffer_byte_length * 2); + } +} diff --git a/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-grow-mid-iteration.js b/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-grow-mid-iteration.js new file mode 100644 index 0000000000..243c67dd9e --- /dev/null +++ b/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-grow-mid-iteration.js @@ -0,0 +1,71 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-arraybuffer-length +description: > + TypedArrays backed by resizable buffers are iterable with for-of and behave + correctly when the buffer is grown during iteration +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +function CreateRab(buffer_byte_length, ctor) { + const rab = CreateResizableArrayBuffer(buffer_byte_length, 2 * buffer_byte_length); + let ta_write = new ctor(rab); + for (let i = 0; i < buffer_byte_length / ctor.BYTES_PER_ELEMENT; ++i) { + WriteToTypedArray(ta_write, i, i % 128); + } + return rab; +} + +for (let ctor of ctors) { + const no_elements = 10; + const offset = 2; + const buffer_byte_length = no_elements * ctor.BYTES_PER_ELEMENT; + const byte_offset = offset * ctor.BYTES_PER_ELEMENT; + + // Create various different styles of TypedArrays with the RAB as the + // backing store and iterate them. + + // Fixed-length TAs aren't affected by resizing. + let rab = CreateRab(buffer_byte_length, ctor); + const ta = new ctor(rab, 0, 3); + TestIterationAndResize(ta, [ + 0, + 1, + 2 + ], rab, 2, buffer_byte_length * 2); + rab = CreateRab(buffer_byte_length, ctor); + const ta_with_offset = new ctor(rab, byte_offset, 3); + TestIterationAndResize(ta_with_offset, [ + 2, + 3, + 4 + ], rab, 2, buffer_byte_length * 2); + rab = CreateRab(buffer_byte_length, ctor); + const length_tracking_ta = new ctor(rab); + { + let expected = []; + for (let i = 0; i < no_elements; ++i) { + expected.push(i % 128); + } + for (let i = 0; i < no_elements; ++i) { + // After resizing, the new memory contains zeros. + expected.push(0); + } + TestIterationAndResize(length_tracking_ta, expected, rab, 2, buffer_byte_length * 2); + } + rab = CreateRab(buffer_byte_length, ctor); + const length_tracking_ta_with_offset = new ctor(rab, byte_offset); + { + let expected = []; + for (let i = offset; i < no_elements; ++i) { + expected.push(i % 128); + } + for (let i = 0; i < no_elements; ++i) { + expected.push(0); + } + TestIterationAndResize(length_tracking_ta_with_offset, expected, rab, 2, buffer_byte_length * 2); + } +} diff --git a/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-shrink-mid-iteration.js b/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-shrink-mid-iteration.js new file mode 100644 index 0000000000..53cf49f967 --- /dev/null +++ b/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-shrink-mid-iteration.js @@ -0,0 +1,86 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-arraybuffer-length +description: > + TypedArrays backed by resizable buffers are iterable with for-of and behave + correctly when the buffer is shrunk during iteration +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +function CreateRab(buffer_byte_length, ctor) { + const rab = CreateResizableArrayBuffer(buffer_byte_length, 2 * buffer_byte_length); + let ta_write = new ctor(rab); + for (let i = 0; i < buffer_byte_length / ctor.BYTES_PER_ELEMENT; ++i) { + WriteToTypedArray(ta_write, i, i % 128); + } + return rab; +} + +for (let ctor of ctors) { + const no_elements = 10; + const offset = 2; + const buffer_byte_length = no_elements * ctor.BYTES_PER_ELEMENT; + const byte_offset = offset * ctor.BYTES_PER_ELEMENT; + + // Create various different styles of TypedArrays with the RAB as the + // backing store and iterate them. + + // Fixed-length TAs aren't affected by shrinking if they stay in-bounds. + // They appear detached after shrinking out of bounds. + let rab = CreateRab(buffer_byte_length, ctor); + const ta1 = new ctor(rab, 0, 3); + TestIterationAndResize(ta1, [ + 0, + 1, + 2 + ], rab, 2, buffer_byte_length / 2); + rab = CreateRab(buffer_byte_length, ctor); + const ta2 = new ctor(rab, 0, 3); + assert.throws(TypeError, () => { + TestIterationAndResize(ta2, null, rab, 2, 1); + }); + rab = CreateRab(buffer_byte_length, ctor); + const ta_with_offset1 = new ctor(rab, byte_offset, 3); + TestIterationAndResize(ta_with_offset1, [ + 2, + 3, + 4 + ], rab, 2, buffer_byte_length / 2); + rab = CreateRab(buffer_byte_length, ctor); + const ta_with_offset2 = new ctor(rab, byte_offset, 3); + assert.throws(TypeError, () => { + TestIterationAndResize(ta_with_offset2, null, rab, 2, 0); + }); + + // Length-tracking TA with offset 0 doesn't throw, but its length gracefully + // reduces too. + rab = CreateRab(buffer_byte_length, ctor); + const length_tracking_ta = new ctor(rab); + TestIterationAndResize(length_tracking_ta, [ + 0, + 1, + 2, + 3, + 4 + ], rab, 2, buffer_byte_length / 2); + + // Length-tracking TA appears detached when the buffer is resized beyond the + // offset. + rab = CreateRab(buffer_byte_length, ctor); + const length_tracking_ta_with_offset = new ctor(rab, byte_offset); + assert.throws(TypeError, () => { + TestIterationAndResize(length_tracking_ta_with_offset, null, rab, 2, byte_offset / 2); + }); + + // Length-tracking TA reduces its length gracefully when the buffer is + // resized to barely cover the offset. + rab = CreateRab(buffer_byte_length, ctor); + const length_tracking_ta_with_offset2 = new ctor(rab, byte_offset); + TestIterationAndResize(length_tracking_ta_with_offset2, [ + 2, + 3 + ], rab, 2, byte_offset); +} diff --git a/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-shrink-to-zero-mid-iteration.js b/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-shrink-to-zero-mid-iteration.js new file mode 100644 index 0000000000..05393f707d --- /dev/null +++ b/test/language/statements/for-of/typedarray-backed-by-resizable-buffer-shrink-to-zero-mid-iteration.js @@ -0,0 +1,58 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-arraybuffer-length +description: > + TypedArrays backed by resizable buffers are iterable with for-of and behave + correctly when the buffer is shrunk during iteration +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +function CreateRab(buffer_byte_length, ctor) { + const rab = CreateResizableArrayBuffer(buffer_byte_length, 2 * buffer_byte_length); + let ta_write = new ctor(rab); + for (let i = 0; i < buffer_byte_length / ctor.BYTES_PER_ELEMENT; ++i) { + WriteToTypedArray(ta_write, i, i % 128); + } + return rab; +} + +for (let ctor of ctors) { + const no_elements = 10; + const offset = 2; + const buffer_byte_length = no_elements * ctor.BYTES_PER_ELEMENT; + const byte_offset = offset * ctor.BYTES_PER_ELEMENT; + + // Create various different styles of TypedArrays with the RAB as the + // backing store and iterate them. + + // Fixed-length TAs appear detached after shrinking out of bounds. + let rab = CreateRab(buffer_byte_length, ctor); + const ta = new ctor(rab, 0, 3); + assert.throws(TypeError, () => { + TestIterationAndResize(ta, null, rab, 2, 0); + }); + rab = CreateRab(buffer_byte_length, ctor); + const ta_with_offset = new ctor(rab, byte_offset, 3); + assert.throws(TypeError, () => { + TestIterationAndResize(ta_with_offset, null, rab, 2, 0); + }); + + // Length-tracking TA with offset 0 doesn't throw, but its length gracefully + // goes to zero too. + rab = CreateRab(buffer_byte_length, ctor); + const length_tracking_ta = new ctor(rab); + TestIterationAndResize(length_tracking_ta, [ + 0, + 1 + ], rab, 2, 0); + + // Length-tracking TA which is resized beyond the offset appars detached. + rab = CreateRab(buffer_byte_length, ctor); + const length_tracking_ta_with_offset = new ctor(rab, byte_offset); + assert.throws(TypeError, () => { + TestIterationAndResize(length_tracking_ta_with_offset, null, rab, 2, 0); + }); +} diff --git a/test/language/statements/for-of/typedarray-backed-by-resizable-buffer.js b/test/language/statements/for-of/typedarray-backed-by-resizable-buffer.js new file mode 100644 index 0000000000..fcdfab5cee --- /dev/null +++ b/test/language/statements/for-of/typedarray-backed-by-resizable-buffer.js @@ -0,0 +1,70 @@ +// Copyright 2023 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-arraybuffer-length +description: > + TypedArrays backed by resizable buffers are iterable with for-of +features: [resizable-arraybuffer] +includes: [compareArray.js, resizableArrayBufferUtils.js] +---*/ + +function CollectValues(ta) { + let values = []; + for (const value of ta) { + values.push(Number(value)); + } + return values; +} +for (let ctor of ctors) { + const no_elements = 10; + const offset = 2; + const buffer_byte_length = no_elements * ctor.BYTES_PER_ELEMENT; + // We can use the same RAB for all the TAs below, since we won't modify it + // after writing the initial values. + const rab = CreateResizableArrayBuffer(buffer_byte_length, 2 * buffer_byte_length); + const byte_offset = offset * ctor.BYTES_PER_ELEMENT; + + // Write some data into the array. + let ta_write = new ctor(rab); + for (let i = 0; i < no_elements; ++i) { + WriteToTypedArray(ta_write, i, i % 128); + } + + // Create various different styles of TypedArrays with the RAB as the + // backing store and iterate them. + const ta = new ctor(rab, 0, 3); + assert.compareArray(CollectValues(ta), [ + 0, + 1, + 2 + ]); + const empty_ta = new ctor(rab, 0, 0); + assert.compareArray(CollectValues(empty_ta), []); + const ta_with_offset = new ctor(rab, byte_offset, 3); + assert.compareArray(CollectValues(ta_with_offset), [ + 2, + 3, + 4 + ]); + const empty_ta_with_offset = new ctor(rab, byte_offset, 0); + assert.compareArray(CollectValues(empty_ta_with_offset), []); + const length_tracking_ta = new ctor(rab); + { + let expected = []; + for (let i = 0; i < no_elements; ++i) { + expected.push(i % 128); + } + assert.compareArray(CollectValues(length_tracking_ta), expected); + } + const length_tracking_ta_with_offset = new ctor(rab, byte_offset); + { + let expected = []; + for (let i = offset; i < no_elements; ++i) { + expected.push(i % 128); + } + assert.compareArray(CollectValues(length_tracking_ta_with_offset), expected); + } + const empty_length_tracking_ta_with_offset = new ctor(rab, buffer_byte_length); + assert.compareArray(CollectValues(empty_length_tracking_ta_with_offset), []); +} From b69e9d5e722291dcb6ada5582c71887133626c63 Mon Sep 17 00:00:00 2001 From: Rezvan Mahdavi Hezaveh Date: Tue, 27 Aug 2024 11:24:40 -0700 Subject: [PATCH 90/90] [explicit-resource-management] Add AsyncDisposableStack builtins This CL adds builtin methods for developer exposed AsyncDisposableStack object. Bug: 42203814 Change-Id: I1f16a3bcb80c71a4f33e4ae028f1737c3502dabe Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5715141 Reviewed-by: Shu-yu Guo Commit-Queue: Rezvan Mahdavi Hezaveh Cr-Commit-Position: refs/heads/main@{#95838} --- ...able-stack-adopt-and-defer-not-callable.js | 26 +++++++++ ...isposable-stack-adopt-on-disposed-stack.js | 22 ++++++++ .../async-disposable-stack-adopt.js | 35 ++++++++++++ ...sable-stack-async-dispose-symbol-throws.js | 29 ++++++++++ ...posable-stack-constructor-and-prototype.js | 21 +++++++ ...isposable-stack-defer-on-disposed-stack.js | 21 +++++++ .../async-disposable-stack-defer.js | 31 ++++++++++ ...posable-stack-dispose-on-disposed-stack.js | 41 ++++++++++++++ ...ync-disposable-stack-dispose-sync-calls.js | 39 +++++++++++++ ...e-stack-dispose-throws-suppressed-error.js | 56 +++++++++++++++++++ .../async-disposable-stack-dispose.js | 29 ++++++++++ .../async-disposable-stack-disposed-getter.js | 41 ++++++++++++++ ...disposable-stack-move-on-disposed-stack.js | 22 ++++++++ .../async-disposable-stack-move.js | 28 ++++++++++ ...-disposable-stack-use-on-disposed-stack.js | 27 +++++++++ .../async-disposable-stack-use.js | 56 +++++++++++++++++++ 16 files changed, 524 insertions(+) create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-adopt-and-defer-not-callable.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-adopt-on-disposed-stack.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-adopt.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-async-dispose-symbol-throws.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-constructor-and-prototype.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-defer-on-disposed-stack.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-defer.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-dispose-on-disposed-stack.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-dispose-sync-calls.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-dispose-throws-suppressed-error.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-dispose.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-disposed-getter.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-move-on-disposed-stack.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-move.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-use-on-disposed-stack.js create mode 100644 test/staging/explicit-resource-management/async-disposable-stack-use.js diff --git a/test/staging/explicit-resource-management/async-disposable-stack-adopt-and-defer-not-callable.js b/test/staging/explicit-resource-management/async-disposable-stack-adopt-and-defer-not-callable.js new file mode 100644 index 0000000000..e1050cad16 --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-adopt-and-defer-not-callable.js @@ -0,0 +1,26 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test developer exposed DisposableStack protype methods adopt() and defer(). +features: [explicit-resource-management] +---*/ + +// adopt() method when onDispose is not callable-------- +function TestAsyncDisposableStackAdoptWithNonCallableOnDispose() { + let stack = new AsyncDisposableStack(); + stack.adopt(42, 43); +}; +assert.throws( + TypeError, () => TestAsyncDisposableStackAdoptWithNonCallableOnDispose(), + 'onDispose is not callable'); + +// defer() method when onDispose is not callable-------- +function TestAsyncDisposableStackDeferWithNonCallableOnDispose() { + let stack = new AsyncDisposableStack(); + stack.defer(42); +}; +assert.throws( + TypeError, () => TestAsyncDisposableStackDeferWithNonCallableOnDispose(), + 'onDispose is not callable'); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-adopt-on-disposed-stack.js b/test/staging/explicit-resource-management/async-disposable-stack-adopt-on-disposed-stack.js new file mode 100644 index 0000000000..31c07ba0ef --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-adopt-on-disposed-stack.js @@ -0,0 +1,22 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Test adopt() on a disposed stack. +includes: [asyncHelpers.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +asyncTest(async function() { + async function TestAsyncDisposableStackAdoptOnDisposedStack() { + let stack = new AsyncDisposableStack(); + await stack.disposeAsync(); + stack.adopt(42, function(v) { + return v + }); + }; + await assert.throwsAsync( + ReferenceError, () => TestAsyncDisposableStackAdoptOnDisposedStack(), + 'Cannot add values to a disposed stack!'); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-adopt.js b/test/staging/explicit-resource-management/async-disposable-stack-adopt.js new file mode 100644 index 0000000000..2844a4eb5f --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-adopt.js @@ -0,0 +1,35 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test developer exposed AsyncDisposableStack protype methods adopt(). +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +asyncTest(async function() { + let valuesNormal = []; + + async function TestAsyncDisposableStackAdopt() { + let stack = new AsyncDisposableStack(); + stack.adopt(42, function(v) { + valuesNormal.push(v) + }); + const disposable = { + value: 1, + [Symbol.asyncDispose]() { + valuesNormal.push(43); + } + }; + stack.use(disposable); + stack.adopt(44, function(v) { + valuesNormal.push(v) + }); + await stack.disposeAsync(); + }; + + await TestAsyncDisposableStackAdopt(); + assert.compareArray(valuesNormal, [44, 43, 42]); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-async-dispose-symbol-throws.js b/test/staging/explicit-resource-management/async-disposable-stack-async-dispose-symbol-throws.js new file mode 100644 index 0000000000..432c384dc0 --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-async-dispose-symbol-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Exposed AsyncDisposableStack protype methods disposeAsync() throws. +includes: [asyncHelpers.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +asyncTest(async function() { + async function TestAsyncDisposableStackUseDisposeMethodThrows() { + { + let stack = new AsyncDisposableStack(); + const disposable = { + value: 1, + [Symbol.asyncDispose]() { + throw new Test262Error('Symbol.asyncDispose is throwing!'); + } + }; + stack.use(disposable); + await stack.disposeAsync(); + } + }; + await assert.throwsAsync( + Test262Error, () => TestAsyncDisposableStackUseDisposeMethodThrows(), + 'Symbol.asyncDisposeispose is throwing!'); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-constructor-and-prototype.js b/test/staging/explicit-resource-management/async-disposable-stack-constructor-and-prototype.js new file mode 100644 index 0000000000..82869db064 --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-constructor-and-prototype.js @@ -0,0 +1,21 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Test AsyncDisposableStack constructor and prototype. +includes: [propertyHelper.js] +features: [globalThis, explicit-resource-management] +---*/ + +// constructor -------- +assert.sameValue( + typeof AsyncDisposableStack, 'function', + 'The value of `typeof AsyncDisposableStack` is "function"'); + +// prototype -------- +verifyProperty(AsyncDisposableStack, 'prototype', { + value: AsyncDisposableStack.prototype, + writable: false, + enumerable: false, + configurable: false, +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-defer-on-disposed-stack.js b/test/staging/explicit-resource-management/async-disposable-stack-defer-on-disposed-stack.js new file mode 100644 index 0000000000..ecf337dc31 --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-defer-on-disposed-stack.js @@ -0,0 +1,21 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Test defer() on disposed stack. +includes: [asyncHelpers.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +asyncTest(async function() { + async function TestAsyncDisposableStackDeferOnDisposedStack() { + let stack = new AsyncDisposableStack(); + await stack.disposeAsync(); + stack.defer(() => {}); + }; + + await assert.throwsAsync( + ReferenceError, () => TestAsyncDisposableStackDeferOnDisposedStack(), + 'Cannot add values to a disposed stack!'); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-defer.js b/test/staging/explicit-resource-management/async-disposable-stack-defer.js new file mode 100644 index 0000000000..6bda41081d --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-defer.js @@ -0,0 +1,31 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test developer exposed AsyncDisposableStack protype method defer(). +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +asyncTest(async function() { + let deferValuesNormal = []; + + async function TestAsyncDisposableStackDefer() { + let stack = new AsyncDisposableStack(); + stack.defer(() => deferValuesNormal.push(42)); + const disposable = { + value: 1, + [Symbol.asyncDispose]() { + deferValuesNormal.push(43); + } + }; + stack.use(disposable); + stack.defer(() => deferValuesNormal.push(44)); + await stack.disposeAsync(); + }; + + await TestAsyncDisposableStackDefer(); + assert.compareArray(deferValuesNormal, [44, 43, 42]); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-dispose-on-disposed-stack.js b/test/staging/explicit-resource-management/async-disposable-stack-dispose-on-disposed-stack.js new file mode 100644 index 0000000000..1286c4eefa --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-dispose-on-disposed-stack.js @@ -0,0 +1,41 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Call disposeAsync() on a disposed AsyncDisposableStack. +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +asyncTest(async function() { + let valuesNormal = []; + + async function TestAsyncDisposableStackUseDisposingTwice() { + let stack = new AsyncDisposableStack(); + const firstDisposable = { + value: 1, + [Symbol.asyncDispose]() { + valuesNormal.push(42); + } + }; + const secondDisposable = { + value: 2, + [Symbol.asyncDispose]() { + valuesNormal.push(43); + } + }; + stack.use(firstDisposable); + stack.use(secondDisposable); + let newStack = stack.move(); + await newStack.disposeAsync(); + assert.sameValue(newStack.disposed, true, 'disposed should be true'); + // stack is already disposed, so the next line should do nothing. + await newStack.disposeAsync(); + }; + + await TestAsyncDisposableStackUseDisposingTwice(); + + assert.compareArray(valuesNormal, [43, 42]); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-dispose-sync-calls.js b/test/staging/explicit-resource-management/async-disposable-stack-dispose-sync-calls.js new file mode 100644 index 0000000000..9b2ea4c077 --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-dispose-sync-calls.js @@ -0,0 +1,39 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Call disposeAsync() twice without await. +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +asyncTest(async function() { + let valuesNormal = []; + + async function TestAsyncDisposableStackUseDisposingTwiceWithoutAwait() { + let stack = new AsyncDisposableStack(); + const firstDisposable = { + value: 1, + [Symbol.asyncDispose]() { + valuesNormal.push(42); + } + }; + const secondDisposable = { + value: 2, + [Symbol.asyncDispose]() { + valuesNormal.push(43); + } + }; + stack.use(firstDisposable); + stack.use(secondDisposable); + stack.disposeAsync(); + assert.sameValue(stack.disposed, true, 'disposed should be true'); + stack.disposeAsync(); + }; + + await TestAsyncDisposableStackUseDisposingTwiceWithoutAwait(); + + assert.compareArray(valuesNormal, [43, 42]); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-dispose-throws-suppressed-error.js b/test/staging/explicit-resource-management/async-disposable-stack-dispose-throws-suppressed-error.js new file mode 100644 index 0000000000..f200ff319b --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-dispose-throws-suppressed-error.js @@ -0,0 +1,56 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: disposeAsync() throws a suppressed error. +includes: [asyncHelpers.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +asyncTest(async function() { + let firstDisposeError = + new Test262Error('The first Symbol.asyncDispose is throwing!'); + let secondDisposeError = + new Test262Error('The second Symbol.asyncDispose is throwing!'); + + async function TestAsyncDisposableStackUseTwoDisposeMethodsThrow() { + { + let stack = new AsyncDisposableStack(); + const firstDisposable = { + value: 1, + [Symbol.asyncDispose]() { + throw firstDisposeError; + } + }; + const secondDisposable = { + value: 1, + [Symbol.asyncDispose]() { + throw secondDisposeError; + } + }; + stack.use(firstDisposable); + stack.use(secondDisposable); + await stack.disposeAsync(); + } + }; + + await assert.throwsAsync( + SuppressedError, + () => TestAsyncDisposableStackUseTwoDisposeMethodsThrow(), + 'An error was suppressed during disposal'); + + async function RunTestAsyncDisposableStackUseTwoDisposeMethodsThrow() { + try { + await TestAsyncDisposableStackUseTwoDisposeMethodsThrow(); + } catch (error) { + assert( + error instanceof SuppressedError, + 'error is an instanceof SuppressedError'); + assert.sameValue(error.error, firstDisposeError, 'error.error'); + assert.sameValue( + error.suppressed, secondDisposeError, 'error.suppressed'); + } + } + await RunTestAsyncDisposableStackUseTwoDisposeMethodsThrow(); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-dispose.js b/test/staging/explicit-resource-management/async-disposable-stack-dispose.js new file mode 100644 index 0000000000..28785011fc --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-dispose.js @@ -0,0 +1,29 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test developer exposed AsyncDisposableStack protype methods disposeAsync(). +includes: [asyncHelpers.js, compareArray.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +asyncTest(async function() { + let valuesNormal = []; + + async function TestAsyncDisposableStackUse() { + let stack = new AsyncDisposableStack(); + const disposable = { + value: 1, + [Symbol.asyncDispose]() { + valuesNormal.push(42); + } + }; + stack.use(disposable); + await stack.disposeAsync(); + }; + + await TestAsyncDisposableStackUse(); + assert.compareArray(valuesNormal, [42]); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-disposed-getter.js b/test/staging/explicit-resource-management/async-disposable-stack-disposed-getter.js new file mode 100644 index 0000000000..f13a8821f0 --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-disposed-getter.js @@ -0,0 +1,41 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Test `disposed` accessor property of AsyncDisposableStack. +includes: [asyncHelpers.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +asyncTest(async function() { + // disposed should be true -------- + async function TestDisposableStackDisposedTrue() { + let stack = new AsyncDisposableStack(); + const disposable = { + value: 1, + [Symbol.asyncDispose]() { + return 42; + } + }; + stack.use(disposable); + stack.dispose(); + assert.sameValue(stack.disposed, true, 'disposed should be true'); + }; + + TestDisposableStackDisposedTrue(); + + // disposed should be false -------- + async function TestDisposableStackDisposedFalse() { + let stack = new AsyncDisposableStack(); + const disposable = { + value: 1, + [Symbol.asyncDispose]() { + return 42; + } + }; + stack.use(disposable); + assert.sameValue(stack.disposed, false, 'disposed should be false'); + }; + TestDisposableStackDisposedFalse(); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-move-on-disposed-stack.js b/test/staging/explicit-resource-management/async-disposable-stack-move-on-disposed-stack.js new file mode 100644 index 0000000000..8671ed72d6 --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-move-on-disposed-stack.js @@ -0,0 +1,22 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Test move() on a disposed-stack. +includes: [asyncHelpers.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +// move() method on disposed stack -------- +asyncTest(async function() { + async function TestAsyncDisposableStackMoveOnDisposedStack() { + let stack = new AsyncDisposableStack(); + await stack.disposeAsync(); + let newStack = stack.move(); + }; + + await assert.throwsAsync( + ReferenceError, () => TestAsyncDisposableStackMoveOnDisposedStack(), + 'Cannot move elements from a disposed stack!'); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-move.js b/test/staging/explicit-resource-management/async-disposable-stack-move.js new file mode 100644 index 0000000000..99ebad349c --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-move.js @@ -0,0 +1,28 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Test developer exposed AsyncDisposableStack protype method move. +features: [explicit-resource-management] +---*/ + +// Two stacks should not be the same -------- +(function TestAsyncDisposableStackMoveNotSameObjects() { + let stack = new AsyncDisposableStack(); + const firstDisposable = { + value: 1, + [Symbol.asyncDispose]() { + return 42; + } + }; + const secondDisposable = { + value: 2, + [Symbol.asyncDispose]() { + return 43; + } + }; + stack.use(firstDisposable); + stack.use(secondDisposable); + let newStack = stack.move(); + assert.notSameValue(stack, newStack); +})(); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-use-on-disposed-stack.js b/test/staging/explicit-resource-management/async-disposable-stack-use-on-disposed-stack.js new file mode 100644 index 0000000000..f2d8c3d264 --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-use-on-disposed-stack.js @@ -0,0 +1,27 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Test use() on a disposed stack. +includes: [asyncHelpers.js] +flags: [async] +features: [explicit-resource-management] +---*/ + +asyncTest(async function() { + async function TestAsyncDisposableStackUseOnDisposedStack() { + let stack = new AsyncDisposableStack(); + const disposable = { + value: 1, + [Symbol.asyncDispose]() { + return 42; + } + }; + await stack.disposeAsync(); + stack.use(disposable); + }; + + await assert.throwsAsync( + ReferenceError, () => TestAsyncDisposableStackUseOnDisposedStack(), + 'Cannot add values to a disposed stack!'); +}); diff --git a/test/staging/explicit-resource-management/async-disposable-stack-use.js b/test/staging/explicit-resource-management/async-disposable-stack-use.js new file mode 100644 index 0000000000..9b26884a96 --- /dev/null +++ b/test/staging/explicit-resource-management/async-disposable-stack-use.js @@ -0,0 +1,56 @@ +// Copyright (C) 2024 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test developer exposed AsyncDisposableStack protype methods use(). +features: [explicit-resource-management] +---*/ + +// use() method on a non object -------- +function TestAsyncDisposableStackUseWithNonObject() { + let stack = new AsyncDisposableStack(); + stack.use(42); +}; +assert.throws( + TypeError, () => TestAsyncDisposableStackUseWithNonObject(), + 'use() is called on non-object'); + +// use() method with null [symbol.asyncDispose] -------- +function TestAsyncDisposableStackUseWithNullDispose() { + let stack = new AsyncDisposableStack(); + const disposable = { + value: 1, + [Symbol.asyncDispose]: null, + }; + stack.use(disposable); +}; +assert.throws( + TypeError, () => TestAsyncDisposableStackUseWithNullDispose(), + 'symbol.asyncDispose is null'); + +// use() method with undefined [symbol.asyncDispose] -------- +function TestAsyncDisposableStackUseWithUndefinedDispose() { + let stack = new AsyncDisposableStack(); + const disposable = { + value: 1, + [Symbol.asyncDispose]: undefined, + }; + stack.use(disposable); +}; +assert.throws( + TypeError, () => TestAsyncDisposableStackUseWithUndefinedDispose(), + 'symbol.asyncDispose is undefined'); + +// use() method when [symbol.asyncDispose] is not callable-------- +function TestAsyncDisposableStackUseWithNonCallableDispose() { + let stack = new AsyncDisposableStack(); + const disposable = { + value: 1, + [Symbol.asyncDispose]: 42, + }; + stack.use(disposable); +}; +assert.throws( + TypeError, () => TestAsyncDisposableStackUseWithNonCallableDispose(), + 'symbol.asyncDispose is not callable');