diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/tests/test262/built-ins/Atomics/waitAsync | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/built-ins/Atomics/waitAsync')
104 files changed, 6690 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bad-range.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bad-range.js new file mode 100644 index 0000000000..251bb9384f --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bad-range.js @@ -0,0 +1,36 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Test range checking of Atomics.waitAsync on arrays that allow atomic operations +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + ... + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + ... + +includes: [testAtomics.js] +features: [Atomics.waitAsync, Atomics, SharedArrayBuffer, ArrayBuffer, DataView, Symbol, TypedArray] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 8) +); + +testWithAtomicsOutOfBoundsIndices(function(IdxGen) { + assert.throws(RangeError, function() { + Atomics.waitAsync(i32a, IdxGen(i32a), 0, 0); + }, '`Atomics.waitAsync(i32a, IdxGen(i32a), 0, 0)` throws a RangeError exception'); +}); + + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/bad-range.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/bad-range.js new file mode 100644 index 0000000000..a2214e5b2b --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/bad-range.js @@ -0,0 +1,31 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Test range checking of Atomics.waitAsync on arrays that allow atomic operations +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + ... + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + ... + +includes: [testAtomics.js] +features: [Atomics.waitAsync, Atomics, SharedArrayBuffer, ArrayBuffer, DataView, Symbol, TypedArray, BigInt] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 8)); + +testWithAtomicsOutOfBoundsIndices(function(IdxGen) { + assert.throws(RangeError, function() { + Atomics.waitAsync(i64a, IdxGen(i64a), 0n, 0); + }, '`Atomics.waitAsync(i64a, IdxGen(i64a), 0n, 0)` throws a RangeError exception'); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/browser.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/browser.js diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/false-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/false-for-timeout-agent.js new file mode 100644 index 0000000000..37bb338b35 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/false-for-timeout-agent.js @@ -0,0 +1,96 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf() { + return false; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]() { + return false; + } + }; + + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, false).value); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, valueOf).value); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value); + $262.agent.report(Atomics.waitAsync(i64a, 0, 0n, false).value); + $262.agent.report(Atomics.waitAsync(i64a, 0, 0n, valueOf).value); + $262.agent.report(Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/false-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/false-for-timeout.js new file mode 100644 index 0000000000..78e5cb927c --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/false-for-timeout.js @@ -0,0 +1,61 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, computed-property-names, Symbol, Symbol.toPrimitive, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +const valueOf = { + valueOf() { + return false; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return false; + } +}; + +assert.sameValue( + Atomics.waitAsync(i64a, 0, 0n, false).value, + 'timed-out', + 'The value of Atomics.waitAsync(i64a, 0, 0n, false).value is "timed-out"' +); + +assert.sameValue( + Atomics.waitAsync(i64a, 0, 0n, valueOf).value, + 'timed-out', + 'The value of Atomics.waitAsync(i64a, 0, 0n, valueOf).value is "timed-out"' +); + +assert.sameValue( + Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value, + 'timed-out', + 'The value of Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value is "timed-out"' +); + +Promise.all([ + Atomics.waitAsync(i64a, 0, 0n, false).value, + Atomics.waitAsync(i64a, 0, 0n, valueOf).value, + Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value +]).then(outcomes => { + assert.sameValue(outcomes[0], 'timed-out', 'The value of outcomes[0] is "timed-out"'); + assert.sameValue(outcomes[1], 'timed-out', 'The value of outcomes[1] is "timed-out"'); + assert.sameValue(outcomes[2], 'timed-out', 'The value of outcomes[2] is "timed-out"'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/good-views.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/good-views.js new file mode 100644 index 0000000000..8a084276ad --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/good-views.js @@ -0,0 +1,71 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Test Atomics.waitAsync on arrays that allow atomic operations +flags: [async] +includes: [atomicsHelper.js, asyncHelpers.js] +features: [Atomics.waitAsync, Atomics, BigInt] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +$262.agent.start(` + (async () => { + var sab = new SharedArrayBuffer(2048); + var good_indices = [ (view) => 0/-1, // -0 + (view) => '-0', + (view) => view.length - 1, + (view) => ({ valueOf: () => 0 }), + (view) => ({ toString: () => '0', valueOf: false }) // non-callable valueOf triggers invocation of toString + ]; + + var view = new BigInt64Array(sab, 32, 20); + + view[0] = 0n; + $262.agent.report("A " + (await Atomics.waitAsync(view, 0, 0n, 0).value)) + $262.agent.report("B " + (await Atomics.waitAsync(view, 0, 37n, 0).value)); + + const results = []; + // In-bounds boundary cases for indexing + for ( let IdxGen of good_indices ) { + let Idx = IdxGen(view); + view.fill(0n); + // Atomics.store() computes an index from Idx in the same way as other + // Atomics operations, not quite like view[Idx]. + Atomics.store(view, Idx, 37n); + results.push(await Atomics.waitAsync(view, Idx, 0n).value); + } + $262.agent.report("C " + results.join(",")); + + $262.agent.leaving(); + })(); +`); + + +asyncTest(async () => { + const outcomes = []; + + for (let i = 0; i < 3; i++) { + outcomes.push(await $262.agent.getReportAsync()); + } + + assert.sameValue( + outcomes[0], + 'A timed-out', + 'The value of outcomes[0] is "A timed-out"' + ); + + assert.sameValue( + outcomes[1], + 'B not-equal', + 'The value of outcomes[1] is "B not-equal"' + ); + assert.sameValue( + outcomes[2], + 'C not-equal,not-equal,not-equal,not-equal,not-equal', + 'The value of outcomes[2] is "C not-equal,not-equal,not-equal,not-equal,not-equal"' + ); +}); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/nan-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/nan-for-timeout-agent.js new file mode 100644 index 0000000000..70f79c11e0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/nan-for-timeout-agent.js @@ -0,0 +1,50 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + NaN timeout arg should result in an infinite timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, NaN).value); // NaN => +Infinity + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 1, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 1' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'ok', + '(await $262.agent.getReportAsync()) resolves to the value "ok"' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/negative-index-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/negative-index-throws.js new file mode 100644 index 0000000000..0618a9aa71 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/negative-index-throws.js @@ -0,0 +1,46 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a RangeError is index < 0 +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(RangeError, function() { + Atomics.waitAsync(i64a, -Infinity, poisoned, poisoned); +}, '`Atomics.waitAsync(i64a, -Infinity, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i64a, -7.999, poisoned, poisoned); +}, '`Atomics.waitAsync(i64a, -7.999, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i64a, -1, poisoned, poisoned); +}, '`Atomics.waitAsync(i64a, -1, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i64a, -300, poisoned, poisoned); +}, '`Atomics.waitAsync(i64a, -300, poisoned, poisoned)` throws a RangeError exception'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/negative-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/negative-timeout-agent.js new file mode 100644 index 0000000000..9ef681c34b --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/negative-timeout-agent.js @@ -0,0 +1,49 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Test that Atomics.waitAsync times out with a negative timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + var i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, -5).value); // -5 => 0 + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/negative-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/negative-timeout.js new file mode 100644 index 0000000000..2f0f64af62 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/negative-timeout.js @@ -0,0 +1,25 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Test that Atomics.waitAsync times out with a negative timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, destructuring-binding, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +Promise.all([Atomics.waitAsync(i64a, 0, 0n, -1).value]).then(([outcome]) => { + assert.sameValue(outcome, 'timed-out', 'The value of `outcome` is "timed-out"'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-no-operation.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-no-operation.js new file mode 100644 index 0000000000..a87317a889 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-no-operation.js @@ -0,0 +1,61 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Test that Atomics.waitAsync returns the right result when it timed out and that + the time to time out is reasonable. +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i64a, 0, 0n, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + const lapse = await $262.agent.getReportAsync(); + assert(lapse >= TIMEOUT, 'The result of evaluating `(lapse >= TIMEOUT)` is true'); + const result = await $262.agent.getReportAsync(); + assert.sameValue(result, 'timed-out', 'The value of `result` is "timed-out"'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-add.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-add.js new file mode 100644 index 0000000000..e15da5a1e2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-add.js @@ -0,0 +1,61 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to Add operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i64a, 0, 0n, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + Atomics.add(i64a, 0, 1n); + const lapse = await $262.agent.getReportAsync(); + assert(lapse >= TIMEOUT, 'The result of evaluating `(lapse >= TIMEOUT)` is true'); + const result = await $262.agent.getReportAsync(); + assert.sameValue(result, 'timed-out', 'The value of `result` is "timed-out"'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-and.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-and.js new file mode 100644 index 0000000000..02ed9ef726 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-and.js @@ -0,0 +1,61 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to And operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i64a, 0, 0n, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + Atomics.and(i64a, 0, 1n); + const lapse = await $262.agent.getReportAsync(); + assert(lapse >= TIMEOUT, 'The result of evaluating `(lapse >= TIMEOUT)` is true'); + const result = await $262.agent.getReportAsync(); + assert.sameValue(result, 'timed-out', 'The value of `result` is "timed-out"'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-compareExchange.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-compareExchange.js new file mode 100644 index 0000000000..36308c49b6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-compareExchange.js @@ -0,0 +1,61 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to compareExchange operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i64a, 0, 0n, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + Atomics.compareExchange(i64a, 0, 0n, 1n); + const lapse = await $262.agent.getReportAsync(); + assert(lapse >= TIMEOUT, 'The result of evaluating `(lapse >= TIMEOUT)` is true'); + const result = await $262.agent.getReportAsync(); + assert.sameValue(result, 'timed-out', 'The value of `result` is "timed-out"'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-exchange.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-exchange.js new file mode 100644 index 0000000000..93e73140bb --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-exchange.js @@ -0,0 +1,61 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to exchange operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i64a, 0, 0n, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + Atomics.exchange(i64a, 0, 1n); + const lapse = await $262.agent.getReportAsync(); + assert(lapse >= TIMEOUT, 'The result of evaluating `(lapse >= TIMEOUT)` is true'); + const result = await $262.agent.getReportAsync(); + assert.sameValue(result, 'timed-out', 'The value of `result` is "timed-out"'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-or.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-or.js new file mode 100644 index 0000000000..321f100417 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-or.js @@ -0,0 +1,61 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to Or operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i64a, 0, 0n, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + Atomics.or(i64a, 0, 1n); + const lapse = await $262.agent.getReportAsync(); + assert(lapse >= TIMEOUT, 'The result of evaluating `(lapse >= TIMEOUT)` is true'); + const result = await $262.agent.getReportAsync(); + assert.sameValue(result, 'timed-out', 'The value of `result` is "timed-out"'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-store.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-store.js new file mode 100644 index 0000000000..74b2a930b2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-store.js @@ -0,0 +1,61 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to Store operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i64a, 0, 0n, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + Atomics.store(i64a, 0, 0b1010n); + const lapse = await $262.agent.getReportAsync(); + assert(lapse >= TIMEOUT, 'The result of evaluating `(lapse >= TIMEOUT)` is true'); + const result = await $262.agent.getReportAsync(); + assert.sameValue(result, 'timed-out', 'The value of `result` is "timed-out"'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-sub.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-sub.js new file mode 100644 index 0000000000..9359795e8b --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-sub.js @@ -0,0 +1,61 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to Sub operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i64a, 0, 0n, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + Atomics.sub(i64a, 0, 1n); + const lapse = await $262.agent.getReportAsync(); + assert(lapse >= TIMEOUT, 'The result of evaluating `(lapse >= TIMEOUT)` is true'); + const result = await $262.agent.getReportAsync(); + assert.sameValue(result, 'timed-out', 'The value of `result` is "timed-out"'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-xor.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-xor.js new file mode 100644 index 0000000000..dfc8d00b07 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/no-spurious-wakeup-on-xor.js @@ -0,0 +1,61 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to xor operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i64a, 0, 0n, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + Atomics.xor(i64a, 0, 1n); + const lapse = await $262.agent.getReportAsync(); + assert(lapse >= TIMEOUT, 'The result of evaluating `(lapse >= TIMEOUT)` is true'); + const result = await $262.agent.getReportAsync(); + assert.sameValue(result, 'timed-out', 'The value of `result` is "timed-out"'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/non-bigint64-typedarray-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/non-bigint64-typedarray-throws.js new file mode 100644 index 0000000000..a4e3dd79f7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/non-bigint64-typedarray-throws.js @@ -0,0 +1,38 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if typedArray arg is not an BigInt64Array +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 5. If waitable is true, then + a. If typeName is not "Int32Array" or "BigInt64Array", throw a TypeError exception. + +features: [Atomics.waitAsync, Float32Array, Float64Array, Int8Array, TypedArray, Uint16Array, Uint8Array, Uint8ClampedArray, arrow-function, SharedArrayBuffer, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, () => { + const view = new BigUint64Array(new SharedArrayBuffer(BigUint64Array.BYTES_PER_ELEMENT * 8)); + Atomics.waitAsync(view, poisoned, poisoned, poisoned); +}, '`const view = new BigUint64Array(new SharedArrayBuffer(BigUint64Array.BYTES_PER_ELEMENT * 8)); Atomics.waitAsync(view, poisoned, poisoned, poisoned)` throws a TypeError exception'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/non-shared-bufferdata-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/non-shared-bufferdata-throws.js new file mode 100644 index 0000000000..def8fe86ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/non-shared-bufferdata-throws.js @@ -0,0 +1,41 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if typedArray.buffer is not a SharedArrayBuffer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 5. If waitable is true, then + a. If typeName is not "BigInt64Array" or "BigInt64Array", throw a TypeError exception. + +features: [Atomics.waitAsync, ArrayBuffer, Atomics, TypedArray, BigInt, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array(new ArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, () => { + Atomics.waitAsync(i64a, 0, 0n, 0); +}, '`Atomics.waitAsync(i64a, 0, 0n, 0)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(i64a, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(i64a, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/not-a-typedarray-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/not-a-typedarray-throws.js new file mode 100644 index 0000000000..8fc491f329 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/not-a-typedarray-throws.js @@ -0,0 +1,44 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if the typedArray arg is not a TypedArray object +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 2. Perform ? RequireInternalSlot(typedArray, [[TypedArrayName]]). + + RequireInternalSlot ( O, internalSlot ) + + 1. If Type(O) is not Object, throw a TypeError exception. + 2. If O does not have an internalSlot internal slot, throw a TypeError exception. + +features: [Atomics.waitAsync, arrow-function, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, () => { + Atomics.waitAsync({}, 0, 0n, 0); +}, '`Atomics.waitAsync({}, 0, 0n, 0)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync({}, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync({}, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/not-an-object-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/not-an-object-throws.js new file mode 100644 index 0000000000..3f4caa0d05 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/not-an-object-throws.js @@ -0,0 +1,64 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if typedArray arg is not an Object +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 2. Perform ? RequireInternalSlot(typedArray, [[TypedArrayName]]). + + RequireInternalSlot ( O, internalSlot ) + + 1. If Type(O) is not Object, throw a TypeError exception. + 2. If O does not have an internalSlot internal slot, throw a TypeError exception. + +features: [Atomics.waitAsync, Symbol, arrow-function, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, () => { + Atomics.waitAsync(null, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(null, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(undefined, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(undefined, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(true, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(true, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(false, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(false, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync('***string***', poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync("***string***", poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(Number.NEGATIVE_INFINITY, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(Number.NEGATIVE_INFINITY, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(Symbol('***symbol***'), poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(Symbol("***symbol***"), poisoned, poisoned, poisoned)` throws a TypeError exception'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/null-bufferdata-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/null-bufferdata-throws.js new file mode 100644 index 0000000000..96e8e987b4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/null-bufferdata-throws.js @@ -0,0 +1,51 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + A null value for bufferData throws a TypeError +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 2. Perform ? RequireInternalSlot(typedArray, [[TypedArrayName]]). + + RequireInternalSlot ( O, internalSlot ) + + 1. If Type(O) is not Object, throw a TypeError exception. + 2. If O does not have an internalSlot internal slot, throw a TypeError exception. + +includes: [detachArrayBuffer.js] +features: [Atomics.waitAsync, ArrayBuffer, Atomics, TypedArray, BigInt] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array( + new ArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +try { + $DETACHBUFFER(i64a.buffer); // Detaching a non-shared ArrayBuffer sets the [[ArrayBufferData]] value to null +} catch (error) { + throw new Test262Error(`An unexpected error occurred when detaching ArrayBuffer: ${error.message}`); +} + +assert.throws(TypeError, function() { + Atomics.waitAsync(i64a, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(i64a, poisoned, poisoned, poisoned)` throws a TypeError exception'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/null-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/null-for-timeout-agent.js new file mode 100644 index 0000000000..298f98d34f --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/null-for-timeout-agent.js @@ -0,0 +1,98 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + null timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Null -> Return +0. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf() { + return null; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]() { + return null; + } + }; + + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, null).value); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, valueOf).value); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value); + $262.agent.report(Atomics.waitAsync(i64a, 0, 0n, null).value); + $262.agent.report(Atomics.waitAsync(i64a, 0, 0n, valueOf).value); + $262.agent.report(Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/null-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/null-for-timeout.js new file mode 100644 index 0000000000..9f50139d06 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/null-for-timeout.js @@ -0,0 +1,54 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + null timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Null -> Return +0. + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics, BigInt, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +const valueOf = { + valueOf() { + return null; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return null; + } +}; + +assert.sameValue( + Atomics.waitAsync(i64a, 0, 0n, null).value, + 'timed-out', + 'The value of Atomics.waitAsync(i64a, 0, 0n, null).value is "timed-out"' +); + +assert.sameValue( + Atomics.waitAsync(i64a, 0, 0n, valueOf).value, + 'timed-out', + 'The value of Atomics.waitAsync(i64a, 0, 0n, valueOf).value is "timed-out"' +); + +assert.sameValue( + Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value, + 'timed-out', + 'The value of Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value is "timed-out"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/object-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/object-for-timeout-agent.js new file mode 100644 index 0000000000..be0fece5ee --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/object-for-timeout-agent.js @@ -0,0 +1,107 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Object valueOf, toString, toPrimitive Zero timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Object -> Apply the following steps: + + Let primValue be ? ToPrimitive(argument, hint Number). + Return ? ToNumber(primValue). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf() { + return 0; + } + }; + + const toString = { + toString() { + return "0"; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]() { + return 0; + } + }; + + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, valueOf).value); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, toString).value); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value); + $262.agent.report(Atomics.waitAsync(i64a, 0, 0n, valueOf).value); + $262.agent.report(Atomics.waitAsync(i64a, 0, 0n, toString).value); + $262.agent.report(Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/object-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/object-for-timeout.js new file mode 100644 index 0000000000..d46f27436b --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/object-for-timeout.js @@ -0,0 +1,72 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Object valueOf, toString, toPrimitive Zero timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Object -> Apply the following steps: + + Let primValue be ? ToPrimitive(argument, hint Number). + Return ? ToNumber(primValue). + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics, BigInt, arrow-function] +flags: [async] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +const valueOf = { + valueOf() { + return 0; + } +}; + +const toString = { + toString() { + return '0'; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return 0; + } +}; + +assert.sameValue( + Atomics.waitAsync(i64a, 0, 0n, valueOf).value, + 'timed-out', + 'The value of Atomics.waitAsync(i64a, 0, 0n, valueOf).value is "timed-out"' +); + +assert.sameValue( + Atomics.waitAsync(i64a, 0, 0n, toString).value, + 'timed-out', + 'The value of Atomics.waitAsync(i64a, 0, 0n, toString).value is "timed-out"' +); + +assert.sameValue( + Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value, + 'timed-out', + 'The value of Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value is "timed-out"' +); + +Promise.all([ + Atomics.waitAsync(i64a, 0, 0n, valueOf).value, + Atomics.waitAsync(i64a, 0, 0n, toString).value, + Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value +]).then(outcomes => { + assert.sameValue(outcomes[0], 'timed-out', 'The value of outcomes[0] is "timed-out"'); + assert.sameValue(outcomes[1], 'timed-out', 'The value of outcomes[1] is "timed-out"'); + assert.sameValue(outcomes[2], 'timed-out', 'The value of outcomes[2] is "timed-out"'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/out-of-range-index-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/out-of-range-index-throws.js new file mode 100644 index 0000000000..e129569ae1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/out-of-range-index-throws.js @@ -0,0 +1,49 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a RangeError if value of index arg is out of range +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + + ... + 2.Let accessIndex be ? ToIndex(requestIndex). + ... + 5. If accessIndex ≥ length, throw a RangeError exception. +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(RangeError, function() { + Atomics.waitAsync(i64a, Infinity, poisoned, poisoned); +}, '`Atomics.waitAsync(i64a, Infinity, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i64a, -1, poisoned, poisoned); +}, '`Atomics.waitAsync(i64a, -1, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i64a, 4, poisoned, poisoned); +}, '`Atomics.waitAsync(i64a, 4, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i64a, 200, poisoned, poisoned); +}, '`Atomics.waitAsync(i64a, 200, poisoned, poisoned)` throws a RangeError exception'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/poisoned-object-for-timeout-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/poisoned-object-for-timeout-throws-agent.js new file mode 100644 index 0000000000..abb3e8d0d1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/poisoned-object-for-timeout-throws-agent.js @@ -0,0 +1,86 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Let primValue be ? ToPrimitive(argument, hint Number). + Return ? ToNumber(primValue). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; + +$262.agent.start(` + const poisonedValueOf = { + valueOf() { + throw new Error('should not evaluate this code'); + } + }; + + const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Error('passing a poisoned object using @@ToPrimitive'); + } + }; + + $262.agent.receiveBroadcast(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + let status1 = ''; + let status2 = ''; + + try { + Atomics.waitAsync(i64a, 0, 0n, poisonedValueOf); + } catch (error) { + status1 = 'poisonedValueOf'; + } + try { + Atomics.waitAsync(i64a, 0, 0n, poisonedToPrimitive); + } catch (error) { + status2 = 'poisonedToPrimitive'; + } + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'poisonedValueOf', + '(await $262.agent.getReportAsync()) resolves to the value "poisonedValueOf"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'poisonedToPrimitive', + '(await $262.agent.getReportAsync()) resolves to the value "poisonedToPrimitive"' + ); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/poisoned-object-for-timeout-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/poisoned-object-for-timeout-throws.js new file mode 100644 index 0000000000..a7878a5ba7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/poisoned-object-for-timeout-throws.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Let primValue be ? ToPrimitive(argument, hint Number). + Return ? ToNumber(primValue). + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics, BigInt] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +const poisonedValueOf = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Test262Error('passing a poisoned object using @@ToPrimitive'); + } +}; + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i64a, 0, 0n, poisonedValueOf); +}, '`Atomics.waitAsync(i64a, 0, 0n, poisonedValueOf)` throws a Test262Error exception'); + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i64a, 0, 0n, poisonedToPrimitive); +}, '`Atomics.waitAsync(i64a, 0, 0n, poisonedToPrimitive)` throws a Test262Error exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/shell.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/shell.js diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-index-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-index-throws-agent.js new file mode 100644 index 0000000000..41cbde0555 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-index-throws-agent.js @@ -0,0 +1,98 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + + ValidateAtomicAccess( typedArray, requestIndex ) + + 2. Let accessIndex be ? ToIndex(requestIndex). + + ToIndex ( value ) + + 2. Else, + a. Let integerIndex be ? ToInteger(value). + + ToInteger(value) + + 1. Let number be ? ToNumber(argument). + + Symbol --> Throw a TypeError exception. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; + +$262.agent.start(` + const poisonedValueOf = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } + }; + + const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Test262Error('should not evaluate this code'); + } + }; + + $262.agent.receiveBroadcast(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + let status1 = ''; + let status2 = ''; + + try { + Atomics.waitAsync(i64a, Symbol('1'), poisonedValueOf, poisonedValueOf); + } catch (error) { + status1 = 'A ' + error.name; + } + try { + Atomics.waitAsync(i64a, Symbol('2'), poisonedToPrimitive, poisonedToPrimitive); + } catch (error) { + status2 = 'B ' + error.name; + } + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'A TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "A TypeError"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'B TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "B TypeError"' + ); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-index-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-index-throws.js new file mode 100644 index 0000000000..aaa9ae80e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-index-throws.js @@ -0,0 +1,71 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + + ValidateAtomicAccess( typedArray, requestIndex ) + + 2. Let accessIndex be ? ToIndex(requestIndex). + + ToIndex ( value ) + + 2. Else, + a. Let integerIndex be ? ToInteger(value). + + ToInteger(value) + + 1. Let number be ? ToNumber(argument). + + Symbol --> Throw a TypeError exception. + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics, BigInt] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +const poisonedValueOf = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i64a, poisonedValueOf, poisonedValueOf, poisonedValueOf); +}, '`Atomics.waitAsync(i64a, poisonedValueOf, poisonedValueOf, poisonedValueOf)` throws a Test262Error exception'); + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i64a, poisonedToPrimitive, poisonedToPrimitive, poisonedToPrimitive); +}, '`Atomics.waitAsync(i64a, poisonedToPrimitive, poisonedToPrimitive, poisonedToPrimitive)` throws a Test262Error exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i64a, Symbol('1'), poisonedValueOf, poisonedValueOf); +}, '`Atomics.waitAsync(i64a, Symbol("1"), poisonedValueOf, poisonedValueOf)` throws a TypeError exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i64a, Symbol('2'), poisonedToPrimitive, poisonedToPrimitive); +}, '`Atomics.waitAsync(i64a, Symbol("2"), poisonedToPrimitive, poisonedToPrimitive)` throws a TypeError exception'); + + + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-timeout-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-timeout-throws-agent.js new file mode 100644 index 0000000000..2ef1e36e59 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-timeout-throws-agent.js @@ -0,0 +1,73 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Symbol --> Throw a TypeError exception. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + let status1 = ''; + let status2 = ''; + + try { + Atomics.waitAsync(i64a, 0, 0n, Symbol('1')); + } catch (error) { + status1 = 'A ' + error.name; + } + try { + Atomics.waitAsync(i64a, 0, 0n, Symbol('2')); + } catch (error) { + status2 = 'B ' + error.name; + } + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'A TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "A TypeError"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'B TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "B TypeError"' + ); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-timeout-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-timeout-throws.js new file mode 100644 index 0000000000..55dbafc489 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-timeout-throws.js @@ -0,0 +1,52 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Symbol --> Throw a TypeError exception. + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics, BigInt] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +const poisonedValueOf = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Test262Error('passing a poisoned object using @@ToPrimitive'); + } +}; + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i64a, 0, 0n, poisonedValueOf); +}, '`Atomics.waitAsync(i64a, 0, 0n, poisonedValueOf)` throws a Test262Error exception'); + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i64a, 0, 0n, poisonedToPrimitive); +}, '`Atomics.waitAsync(i64a, 0, 0n, poisonedToPrimitive)` throws a Test262Error exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i64a, 0, 0n, Symbol('foo')); +}, '`Atomics.waitAsync(i64a, 0, 0n, Symbol("foo"))` throws a TypeError exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i64a, 0, 0n, Symbol('foo')); +}, '`Atomics.waitAsync(i64a, 0, 0n, Symbol("foo"))` throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-value-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-value-throws-agent.js new file mode 100644 index 0000000000..70bcc8d273 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-value-throws-agent.js @@ -0,0 +1,89 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if value arg is a Symbol +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 5. Otherwise, let v be ? ToInt32(value). + + ToInt32(value) + + 1.Let number be ? ToNumber(argument). + + Symbol --> Throw a TypeError exception. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; + +$262.agent.start(` + const poisonedValueOf = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } + }; + + const poisonedToPrimitive = { + [Symbol.toPrimitive]: function() { + throw new Test262Error("passing a poisoned object using @@ToPrimitive"); + } + }; + + $262.agent.receiveBroadcast(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + let status1 = ""; + let status2 = ""; + + try { + Atomics.waitAsync(i64a, 0, Symbol("1"), poisonedValueOf); + } catch (error) { + status1 = 'A ' + error.name; + } + try { + Atomics.waitAsync(i64a, 0, Symbol("2"), poisonedToPrimitive); + } catch (error) { + status2 = 'B ' + error.name; + } + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'A TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "A TypeError"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'B TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "B TypeError"' + ); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-value-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-value-throws.js new file mode 100644 index 0000000000..552928e077 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/symbol-for-value-throws.js @@ -0,0 +1,60 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if value arg is a Symbol +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 5. Otherwise, let v be ? ToInt32(value). + + ToInt32(value) + + 1.Let number be ? ToNumber(argument). + + Symbol --> Throw a TypeError exception. + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics, BigInt] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +const poisonedValueOf = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Test262Error("passing a poisoned object using @@ToPrimitive"); + } +}; + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i64a, 0, poisonedValueOf, poisonedValueOf); +}, '`Atomics.waitAsync(i64a, 0, poisonedValueOf, poisonedValueOf)` throws a Test262Error exception'); + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i64a, 0, poisonedToPrimitive, poisonedToPrimitive); +}, '`Atomics.waitAsync(i64a, 0, poisonedToPrimitive, poisonedToPrimitive)` throws a Test262Error exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i64a, 0, Symbol("foo"), poisonedValueOf); +}, '`Atomics.waitAsync(i64a, 0, Symbol("foo"), poisonedValueOf)` throws a TypeError exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i64a, 0, Symbol("foo"), poisonedToPrimitive); +}, '`Atomics.waitAsync(i64a, 0, Symbol("foo"), poisonedToPrimitive)` throws a TypeError exception'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/true-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/true-for-timeout-agent.js new file mode 100644 index 0000000000..af48ef70d9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/true-for-timeout-agent.js @@ -0,0 +1,75 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + True timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf() { + return true; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]() { + return true; + } + }; + + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, true).value); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, valueOf).value); + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/true-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/true-for-timeout.js new file mode 100644 index 0000000000..884acd3219 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/true-for-timeout.js @@ -0,0 +1,65 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Boolean -> If argument is true, return 1. If argument is false, return +0. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, computed-property-names, Symbol, Symbol.toPrimitive, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +const valueOf = { + valueOf() { + return true; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return true; + } +}; + +let outcomes = []; +let lifespan = 1000; +let start = $262.agent.monotonicNow(); + +(function wait() { + let elapsed = $262.agent.monotonicNow() - start; + + if (elapsed > lifespan) { + $DONE('Test timed out'); + return; + } + + if (outcomes.length) { + assert.sameValue(outcomes[0], 'timed-out', 'The value of outcomes[0] is "timed-out"'); + assert.sameValue(outcomes[1], 'timed-out', 'The value of outcomes[1] is "timed-out"'); + assert.sameValue(outcomes[2], 'timed-out', 'The value of outcomes[2] is "timed-out"'); + $DONE(); + return; + } + + $262.agent.setTimeout(wait, 0); +})(); + +Promise.all([ + Atomics.waitAsync(i64a, 0, 0n, true).value, + Atomics.waitAsync(i64a, 0, 0n, valueOf).value, + Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value +]).then(results => outcomes = results, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/undefined-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/undefined-for-timeout-agent.js new file mode 100644 index 0000000000..9ccc4e03c8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/undefined-for-timeout-agent.js @@ -0,0 +1,82 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Undefined timeout arg is coerced to zero +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + ... + Undefined Return NaN. + + 5.If q is NaN, let t be +∞, else let t be max(q, 0) + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const WAIT_INDEX = 0; +const RUNNING = 1; +const NUMAGENT = 2; +const NOTIFYCOUNT = 2; + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + var i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + // undefined => NaN => +Infinity + $262.agent.report("A " + (await Atomics.waitAsync(i64a, 0, 0n, undefined).value)); + $262.agent.leaving(); + }); +`); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + var i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + // undefined timeout arg => NaN => +Infinity + $262.agent.report("B " + (await Atomics.waitAsync(i64a, 0, 0n).value)); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, BigInt(NUMAGENT)).then(async (agentCount) => { + + assert.sameValue( + agentCount, + BigInt(NUMAGENT), + 'The value of `agentCount` must return the same value returned by BigInt(NUMAGENT)' + ); + + assert.sameValue( + Atomics.notify(i64a, WAIT_INDEX, NOTIFYCOUNT), + NOTIFYCOUNT, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0, 2) must return the value of NOTIFYCOUNT' + ); + + const reports = [ + await $262.agent.getReportAsync(), + await $262.agent.getReportAsync(), + ]; + + reports.sort(); + assert.sameValue(reports[0], 'A ok', 'The value of reports[0] is "A ok"'); + assert.sameValue(reports[1], 'B ok', 'The value of reports[1] is "B ok"'); +}).then($DONE, $DONE); + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/undefined-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/undefined-for-timeout.js new file mode 100644 index 0000000000..0b9deb11d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/undefined-for-timeout.js @@ -0,0 +1,51 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Undefined timeout arg is coerced to zero +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + ... + Undefined Return NaN. + + 5.If q is NaN, let t be +∞, else let t be max(q, 0) + +flags: [async] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, computed-property-names, Symbol, Symbol.toPrimitive, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +const valueOf = { + valueOf() { + return undefined; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return undefined; + } +}; + +Promise.all([ + Atomics.waitAsync(i64a, 0, 0n).value, + Atomics.waitAsync(i64a, 0, 0n, undefined).value, + Atomics.waitAsync(i64a, 0, 0n, valueOf).value, + Atomics.waitAsync(i64a, 0, 0n, toPrimitive).value +]).then(outcomes => { + assert.sameValue(outcomes[0], 'ok', 'The value of outcomes[0] is "ok"'); + assert.sameValue(outcomes[1], 'ok', 'The value of outcomes[1] is "ok"'); + assert.sameValue(outcomes[2], 'ok', 'The value of outcomes[2] is "ok"'); + assert.sameValue(outcomes[3], 'ok', 'The value of outcomes[3] is "ok"'); +}).then($DONE, $DONE); + +Atomics.notify(i64a, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/undefined-index-defaults-to-zero-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/undefined-index-defaults-to-zero-agent.js new file mode 100644 index 0000000000..0eb729af68 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/undefined-index-defaults-to-zero-agent.js @@ -0,0 +1,84 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Undefined index arg is coerced to zero +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + ... + 2.Let accessIndex be ? ToIndex(requestIndex). + + 9.If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception. + ... + 3.If bufferData is a Data Block, return false + + If value is undefined, then + Let index be 0. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const WAIT_INDEX = 0; +const RUNNING = 1; +const NUMAGENT = 2; +const NOTIFYCOUNT = 2; + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + var i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + $262.agent.report("A " + (await Atomics.waitAsync(i64a, undefined, 0n).value)); + $262.agent.leaving(); + }); +`); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + var i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + $262.agent.report("B " + (await Atomics.waitAsync(i64a, undefined, 0n).value)); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, BigInt(NUMAGENT)).then(async (agentCount) => { + + assert.sameValue( + agentCount, + BigInt(NUMAGENT), + 'The value of `agentCount` must return the same value returned by BigInt(NUMAGENT)' + ); + + assert.sameValue( + Atomics.notify(i64a, WAIT_INDEX, NOTIFYCOUNT), + NOTIFYCOUNT, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0, 2) must return the value of NOTIFYCOUNT' + ); + + const reports = [ + await $262.agent.getReportAsync(), + await $262.agent.getReportAsync(), + ]; + + reports.sort(); + assert.sameValue(reports[0], 'A ok', 'The value of reports[0] is "A ok"'); + assert.sameValue(reports[1], 'B ok', 'The value of reports[1] is "B ok"'); +}).then($DONE, $DONE); + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/value-not-equal-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/value-not-equal-agent.js new file mode 100644 index 0000000000..6c0922fcf8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/value-not-equal-agent.js @@ -0,0 +1,63 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Returns "not-equal" when value arg does not match an index in the typedArray +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 16. Let w be ! AtomicLoad(typedArray, i). + 17. If v is not equal to w, then + a. Perform LeaveCriticalSection(WL). + b. If mode is sync, then + i. Return the String "not-equal". + c. Perform ! Call(capability.[[Resolve]], undefined, « "not-equal" »). + d. Return promiseCapability.[[Promise]]. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; +const value = 42n; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + $262.agent.report(Atomics.store(i64a, 0, 42n)); + $262.agent.report(Atomics.waitAsync(i64a, 0, 0n).value); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + await $262.agent.getReportAsync(), + value.toString(), + '(await $262.agent.getReportAsync()) must return the same value returned by value.toString()' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'not-equal', + '(await $262.agent.getReportAsync()) resolves to the value "not-equal"' + ); + + assert.sameValue( + Atomics.notify(i64a, 0, 1), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0, 1) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/value-not-equal.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/value-not-equal.js new file mode 100644 index 0000000000..adc2bc69a2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/value-not-equal.js @@ -0,0 +1,44 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Returns "not-equal" when value arg does not match an index in the typedArray +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 16. Let w be ! AtomicLoad(typedArray, i). + 17. If v is not equal to w, then + a. Perform LeaveCriticalSection(WL). + b. If mode is sync, then + i. Return the String "not-equal". + c. Perform ! Call(capability.[[Resolve]], undefined, « "not-equal" »). + d. Return promiseCapability.[[Promise]]. + +flags: [async] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, BigInt, computed-property-names, Symbol, Symbol.toPrimitive, Atomics, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +const valueOf = { + valueOf() { + return undefined; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return undefined; + } +}; + +Promise.all([Atomics.store(i64a, 0, 42n), Atomics.waitAsync(i64a, 0, 0n).value]).then(outcomes => { + assert.sameValue(outcomes[0], 42n, 'The value of outcomes[0] is 42n'); + assert.sameValue(outcomes[1], 'not-equal', 'The value of outcomes[1] is "not-equal"'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/waiterlist-block-indexedposition-wake.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/waiterlist-block-indexedposition-wake.js new file mode 100644 index 0000000000..bde4046ecd --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/waiterlist-block-indexedposition-wake.js @@ -0,0 +1,90 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Get the correct WaiterList +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 11. Let indexedPosition be (i × 4) + offset. + 12. Let WL be GetWaiterList(block, indexedPosition). + + GetWaiterList( block, i ) + + ... + 4. Return the WaiterList that is referenced by the pair (block, i). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const NUMAGENT = 2; +const RUNNING = 4; + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + // Wait on index 0 + $262.agent.report(await Atomics.waitAsync(i64a, 0, 0n, Infinity).value); + $262.agent.leaving(); + }); +`); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + // Wait on index 2 + $262.agent.report(await Atomics.waitAsync(i64a, 2, 0n, Infinity).value); + $262.agent.leaving(); + }); +`); + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 5) +); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, BigInt(NUMAGENT)).then(async (agentCount) => { + + assert.sameValue( + agentCount, + BigInt(NUMAGENT), + 'The value of `agentCount` must return the same value returned by BigInt(NUMAGENT)' + ); + + // Notify index 1, notifies nothing + assert.sameValue(Atomics.notify(i64a, 1), 0, 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 5)), 1) must return 0'); + + // Notify index 3, notifies nothing + assert.sameValue(Atomics.notify(i64a, 3), 0, 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 5)), 3) must return 0'); + + // Notify index 2, notifies 1 + assert.sameValue(Atomics.notify(i64a, 2), 1, 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 5)), 2) must return 1'); + assert.sameValue( + await $262.agent.getReportAsync(), + 'ok', + '(await $262.agent.getReportAsync()) resolves to the value "ok"' + ); + + // Notify index 0, notifies 1 + assert.sameValue(Atomics.notify(i64a, 0), 1, 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 5)), 0) must return 1'); + assert.sameValue( + await $262.agent.getReportAsync(), + 'ok', + '(await $262.agent.getReportAsync()) resolves to the value "ok"' + ); + +}).then($DONE, $DONE); + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/was-woken-before-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/was-woken-before-timeout.js new file mode 100644 index 0000000000..ba8807b68d --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/bigint/was-woken-before-timeout.js @@ -0,0 +1,53 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Test that Atomics.waitAsync returns the right result when it was awoken before + a timeout +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, BigInt, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.huge; +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i64a, 0, 0n, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i64a, RUNNING, 1n).then(async agentCount => { + assert.sameValue(agentCount, 1n, 'The value of `agentCount` is 1n'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 1, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 1' + ); + + const lapse = await $262.agent.getReportAsync(); + assert(lapse < TIMEOUT, 'The result of evaluating `(lapse < TIMEOUT)` is true'); + const result = await $262.agent.getReportAsync(); + assert.sameValue(result, 'ok', 'The value of `result` is "ok"'); + assert.sameValue(result, 'ok', 'The value of `result` is "ok"'); + + assert.sameValue( + Atomics.notify(i64a, 0), + 0, + 'Atomics.notify(new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)), 0) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/browser.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/browser.js diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/descriptor.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/descriptor.js new file mode 100644 index 0000000000..3d08175e3c --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/descriptor.js @@ -0,0 +1,24 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: Atomics.waitAsync property descriptor +info: | + ES 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. +includes: [propertyHelper.js] +features: [Atomics.waitAsync, Atomics] +---*/ + +verifyProperty(Atomics, 'waitAsync', { + configurable: true, + writable: true, + enumerable: false, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/false-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/false-for-timeout-agent.js new file mode 100644 index 0000000000..05f0311793 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/false-for-timeout-agent.js @@ -0,0 +1,94 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf() { + return false; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]() { + return false; + } + }; + + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, false).value); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, valueOf).value); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, toPrimitive).value); + $262.agent.report(Atomics.waitAsync(i32a, 0, 0, false).value); + $262.agent.report(Atomics.waitAsync(i32a, 0, 0, valueOf).value); + $262.agent.report(Atomics.waitAsync(i32a, 0, 0, toPrimitive).value); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); + +}).then($DONE, $DONE); + + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/false-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/false-for-timeout.js new file mode 100644 index 0000000000..cfb66b3dd3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/false-for-timeout.js @@ -0,0 +1,64 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, computed-property-names, Symbol, Symbol.toPrimitive, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const valueOf = { + valueOf() { + return false; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return false; + } +}; + +assert.sameValue( + Atomics.waitAsync(i32a, 0, 0, false).value, + 'timed-out', + 'The value of Atomics.waitAsync(i32a, 0, 0, false).value is "timed-out"' +); + +assert.sameValue( + Atomics.waitAsync(i32a, 0, 0, valueOf).value, + 'timed-out', + 'The value of Atomics.waitAsync(i32a, 0, 0, valueOf).value is "timed-out"' +); + +assert.sameValue( + Atomics.waitAsync(i32a, 0, 0, toPrimitive).value, + 'timed-out', + 'The value of Atomics.waitAsync(i32a, 0, 0, toPrimitive).value is "timed-out"' +); + +Promise.all([ + Atomics.waitAsync(i32a, 0, 0, false).value, + Atomics.waitAsync(i32a, 0, 0, valueOf).value, + Atomics.waitAsync(i32a, 0, 0, toPrimitive).value, + ]).then(outcomes => { + assert.sameValue(outcomes[0], 'timed-out', 'The value of outcomes[0] is "timed-out"'); + assert.sameValue(outcomes[1], 'timed-out', 'The value of outcomes[1] is "timed-out"'); + assert.sameValue(outcomes[2], 'timed-out', 'The value of outcomes[2] is "timed-out"'); + }).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/good-views.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/good-views.js new file mode 100644 index 0000000000..343b706a41 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/good-views.js @@ -0,0 +1,70 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Test Atomics.waitAsync on arrays that allow atomic operations +flags: [async] +includes: [atomicsHelper.js, asyncHelpers.js] +features: [Atomics.waitAsync, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +$262.agent.start(` + (async () => { + var sab = new SharedArrayBuffer(1024); + var good_indices = [ (view) => 0/-1, // -0 + (view) => '-0', + (view) => view.length - 1, + (view) => ({ valueOf: () => 0 }), + (view) => ({ toString: () => '0', valueOf: false }) // non-callable valueOf triggers invocation of toString + ]; + + var view = new Int32Array(sab, 32, 20); + + view[0] = 0; + $262.agent.report("A " + (await Atomics.waitAsync(view, 0, 0, 0).value)) + $262.agent.report("B " + (await Atomics.waitAsync(view, 0, 37, 0).value)); + + const results = []; + // In-bounds boundary cases for indexing + for ( let IdxGen of good_indices ) { + let Idx = IdxGen(view); + view.fill(0); + // Atomics.store() computes an index from Idx in the same way as other + // Atomics operations, not quite like view[Idx]. + Atomics.store(view, Idx, 37); + results.push(await Atomics.waitAsync(view, Idx, 0).value); + } + $262.agent.report("C " + results.join(",")); + $262.agent.leaving(); + })(); +`); + + +asyncTest(async () => { + const outcomes = []; + + for (let i = 0; i < 3; i++) { + outcomes.push(await $262.agent.getReportAsync()); + } + + assert.sameValue( + outcomes[0], + 'A timed-out', + 'The value of outcomes[0] is "A timed-out"' + ); + + assert.sameValue( + outcomes[1], + 'B not-equal', + 'The value of outcomes[1] is "B not-equal"' + ); + assert.sameValue( + outcomes[2], + 'C not-equal,not-equal,not-equal,not-equal,not-equal', + 'The value of outcomes[2] is "C not-equal,not-equal,not-equal,not-equal,not-equal"' + ); +}); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/implicit-infinity-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/implicit-infinity-for-timeout.js new file mode 100644 index 0000000000..2c4baf0a85 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/implicit-infinity-for-timeout.js @@ -0,0 +1,39 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Undefined timeout arg is coerced to zero +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + ... + Undefined Return NaN. + + 5.If q is NaN, let t be +∞, else let t be max(q, 0) + +flags: [async] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, computed-property-names, Symbol, Symbol.toPrimitive, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +let {async, value} = Atomics.waitAsync(i32a, 0, 0); + +value.then(result => { + + assert.sameValue(result, "ok", 'The value of `result` is "ok"'); + +}, $DONE).then($DONE, $DONE); + +Atomics.notify(i32a, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/is-function.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/is-function.js new file mode 100644 index 0000000000..96a8a74f60 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/is-function.js @@ -0,0 +1,13 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: Atomics.waitAsync is callable +features: [Atomics.waitAsync, Atomics] +---*/ + +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/length.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/length.js new file mode 100644 index 0000000000..b02c6027b3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/length.js @@ -0,0 +1,34 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Atomics.waitAsync.length is 4. +info: | + Atomics.waitAsync ( ia, index, expect, timeout ) + + 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, including optional + parameters. However, rest parameters 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: [Atomics.waitAsync, Atomics] +---*/ + +verifyProperty(Atomics.waitAsync, 'length', { + value: 4, + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/name.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/name.js new file mode 100644 index 0000000000..6a558f8464 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/name.js @@ -0,0 +1,20 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Atomics.waitAsync.name is "waitAsync". +includes: [propertyHelper.js] +features: [Atomics.waitAsync, Atomics] +---*/ + +verifyProperty(Atomics.waitAsync, 'name', { + value: 'waitAsync', + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/nan-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/nan-for-timeout-agent.js new file mode 100644 index 0000000000..3aac20d767 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/nan-for-timeout-agent.js @@ -0,0 +1,54 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + NaN timeout arg should result in an infinite timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, NaN).value); // NaN => +Infinity + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + assert.sameValue(Atomics.notify(i32a, 0), 1, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 1'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'ok', + '(await $262.agent.getReportAsync()) resolves to the value "ok"' + ); + +}).then($DONE, $DONE); + + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/negative-index-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/negative-index-throws.js new file mode 100644 index 0000000000..4d6c2b2526 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/negative-index-throws.js @@ -0,0 +1,45 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a RangeError is index < 0 +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(RangeError, function() { + Atomics.waitAsync(i32a, -Infinity, poisoned, poisoned); +}, '`Atomics.waitAsync(i32a, -Infinity, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i32a, -7.999, poisoned, poisoned); +}, '`Atomics.waitAsync(i32a, -7.999, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i32a, -1, poisoned, poisoned); +}, '`Atomics.waitAsync(i32a, -1, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i32a, -300, poisoned, poisoned); +}, '`Atomics.waitAsync(i32a, -300, poisoned, poisoned)` throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/negative-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/negative-timeout-agent.js new file mode 100644 index 0000000000..317bcdf268 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/negative-timeout-agent.js @@ -0,0 +1,52 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Test that Atomics.waitAsync times out with a negative timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + var i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, -5).value); // -5 => 0 + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); + +}).then($DONE, $DONE); + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/negative-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/negative-timeout.js new file mode 100644 index 0000000000..f2d611acee --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/negative-timeout.js @@ -0,0 +1,34 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Test that Atomics.waitAsync times out with a negative timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, destructuring-binding, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +Promise.all([ + Atomics.waitAsync(i32a, 0, 0, -1).value, + ]).then(([outcome]) => { + assert.sameValue( + outcome, + 'timed-out', + 'The value of `outcome` is "timed-out"' + ); + }).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-no-operation.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-no-operation.js new file mode 100644 index 0000000000..30462d4816 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-no-operation.js @@ -0,0 +1,73 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Test that Atomics.waitAsync returns the right result when it timed out and that + the time to time out is reasonable. +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + const lapse = await $262.agent.getReportAsync(); + + assert( + lapse >= TIMEOUT, + 'The result of evaluating `(lapse >= TIMEOUT)` is true' + ); + + const result = await $262.agent.getReportAsync(); + + assert.sameValue( + result, + 'timed-out', + 'The value of `result` is "timed-out"' + ); + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-add.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-add.js new file mode 100644 index 0000000000..57cd10a192 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-add.js @@ -0,0 +1,74 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to Add operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + Atomics.add(i32a, 0, 1); + + const lapse = await $262.agent.getReportAsync(); + + assert( + lapse >= TIMEOUT, + 'The result of evaluating `(lapse >= TIMEOUT)` is true' + ); + + const result = await $262.agent.getReportAsync(); + + assert.sameValue( + result, + 'timed-out', + 'The value of `result` is "timed-out"' + ); + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-and.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-and.js new file mode 100644 index 0000000000..339ab3a329 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-and.js @@ -0,0 +1,74 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to And operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + Atomics.and(i32a, 0, 1); + + const lapse = await $262.agent.getReportAsync(); + + assert( + lapse >= TIMEOUT, + 'The result of evaluating `(lapse >= TIMEOUT)` is true' + ); + + const result = await $262.agent.getReportAsync(); + + assert.sameValue( + result, + 'timed-out', + 'The value of `result` is "timed-out"' + ); + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-compareExchange.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-compareExchange.js new file mode 100644 index 0000000000..3802faddc4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-compareExchange.js @@ -0,0 +1,74 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to compareExchange operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + Atomics.compareExchange(i32a, 0, 0, 1); + + const lapse = await $262.agent.getReportAsync(); + + assert( + lapse >= TIMEOUT, + 'The result of evaluating `(lapse >= TIMEOUT)` is true' + ); + + const result = await $262.agent.getReportAsync(); + + assert.sameValue( + result, + 'timed-out', + 'The value of `result` is "timed-out"' + ); + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-exchange.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-exchange.js new file mode 100644 index 0000000000..e68a1821f6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-exchange.js @@ -0,0 +1,74 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to exchange operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + Atomics.exchange(i32a, 0, 1); + + const lapse = await $262.agent.getReportAsync(); + + assert( + lapse >= TIMEOUT, + 'The result of evaluating `(lapse >= TIMEOUT)` is true' + ); + + const result = await $262.agent.getReportAsync(); + + assert.sameValue( + result, + 'timed-out', + 'The value of `result` is "timed-out"' + ); + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-or.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-or.js new file mode 100644 index 0000000000..bec800415d --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-or.js @@ -0,0 +1,74 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to Or operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + Atomics.or(i32a, 0, 1); + + const lapse = await $262.agent.getReportAsync(); + + assert( + lapse >= TIMEOUT, + 'The result of evaluating `(lapse >= TIMEOUT)` is true' + ); + + const result = await $262.agent.getReportAsync(); + + assert.sameValue( + result, + 'timed-out', + 'The value of `result` is "timed-out"' + ); + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-store.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-store.js new file mode 100644 index 0000000000..b60ce4f767 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-store.js @@ -0,0 +1,74 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to Store operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + Atomics.store(i32a, 0, 0b1010); + + const lapse = await $262.agent.getReportAsync(); + + assert( + lapse >= TIMEOUT, + 'The result of evaluating `(lapse >= TIMEOUT)` is true' + ); + + const result = await $262.agent.getReportAsync(); + + assert.sameValue( + result, + 'timed-out', + 'The value of `result` is "timed-out"' + ); + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-sub.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-sub.js new file mode 100644 index 0000000000..c60beab60e --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-sub.js @@ -0,0 +1,74 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to Sub operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + Atomics.sub(i32a, 0, 1); + + const lapse = await $262.agent.getReportAsync(); + + assert( + lapse >= TIMEOUT, + 'The result of evaluating `(lapse >= TIMEOUT)` is true' + ); + + const result = await $262.agent.getReportAsync(); + + assert.sameValue( + result, + 'timed-out', + 'The value of `result` is "timed-out"' + ); + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-xor.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-xor.js new file mode 100644 index 0000000000..f00bfadda5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/no-spurious-wakeup-on-xor.js @@ -0,0 +1,74 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Waiter does not spuriously notify on index which is subject to xor operation +info: | + AddWaiter ( WL, waiterRecord ) + + 5. Append waiterRecord as the last element of WL.[[Waiters]] + 6. If waiterRecord.[[Timeout]] is finite, then in parallel, + a. Wait waiterRecord.[[Timeout]] milliseconds. + b. Perform TriggerTimeout(WL, waiterRecord). + + TriggerTimeout( WL, waiterRecord ) + + 3. If waiterRecord is in WL.[[Waiters]], then + a. Set waiterRecord.[[Result]] to "timed-out". + b. Perform RemoveWaiter(WL, waiterRecord). + c. Perform NotifyWaiter(WL, waiterRecord). + 4. Perform LeaveCriticalSection(WL). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + Atomics.xor(i32a, 0, 1); + + const lapse = await $262.agent.getReportAsync(); + + assert( + lapse >= TIMEOUT, + 'The result of evaluating `(lapse >= TIMEOUT)` is true' + ); + + const result = await $262.agent.getReportAsync(); + + assert.sameValue( + result, + 'timed-out', + 'The value of `result` is "timed-out"' + ); + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/non-int32-typedarray-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/non-int32-typedarray-throws.js new file mode 100644 index 0000000000..13ee2c67aa --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/non-int32-typedarray-throws.js @@ -0,0 +1,88 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if typedArray arg is not an Int32Array +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 5. If waitable is true, then + a. If typeName is not "Int32Array" or "BigInt64Array", throw a TypeError exception. + +features: [Atomics.waitAsync, Float32Array, Float64Array, Int8Array, TypedArray, Uint16Array, Uint8Array, Uint8ClampedArray, arrow-function, SharedArrayBuffer, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, () => { + const view = new Float64Array( + new SharedArrayBuffer(Float64Array.BYTES_PER_ELEMENT * 8) + ); + Atomics.waitAsync(view, poisoned, poisoned, poisoned); +}, '`const view = new Float64Array( new SharedArrayBuffer(Float64Array.BYTES_PER_ELEMENT * 8) ); Atomics.waitAsync(view, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + const view = new Float32Array( + new SharedArrayBuffer(Float32Array.BYTES_PER_ELEMENT * 4) + ); + Atomics.waitAsync(view, poisoned, poisoned, poisoned); +}, '`const view = new Float32Array( new SharedArrayBuffer(Float32Array.BYTES_PER_ELEMENT * 4) ); Atomics.waitAsync(view, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + const view = new Int16Array( + new SharedArrayBuffer(Int16Array.BYTES_PER_ELEMENT * 2) + ); + Atomics.waitAsync(view, poisoned, poisoned, poisoned); +}, '`const view = new Int16Array( new SharedArrayBuffer(Int16Array.BYTES_PER_ELEMENT * 2) ); Atomics.waitAsync(view, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + const view = new Int8Array( + new SharedArrayBuffer(Int8Array.BYTES_PER_ELEMENT) + ); + Atomics.waitAsync(view, poisoned, poisoned, poisoned); +}, '`const view = new Int8Array( new SharedArrayBuffer(Int8Array.BYTES_PER_ELEMENT) ); Atomics.waitAsync(view, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + const view = new Uint32Array( + new SharedArrayBuffer(Uint32Array.BYTES_PER_ELEMENT * 4) + ); + Atomics.waitAsync(view, poisoned, poisoned, poisoned); +}, '`const view = new Uint32Array( new SharedArrayBuffer(Uint32Array.BYTES_PER_ELEMENT * 4) ); Atomics.waitAsync(view, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + const view = new Uint16Array( + new SharedArrayBuffer(Uint16Array.BYTES_PER_ELEMENT * 2) + ); + Atomics.waitAsync(view, poisoned, poisoned, poisoned); +}, '`const view = new Uint16Array( new SharedArrayBuffer(Uint16Array.BYTES_PER_ELEMENT * 2) ); Atomics.waitAsync(view, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + const view = new Uint8Array( + new SharedArrayBuffer(Uint8Array.BYTES_PER_ELEMENT) + ); + Atomics.waitAsync(view, poisoned, poisoned, poisoned); +}, '`const view = new Uint8Array( new SharedArrayBuffer(Uint8Array.BYTES_PER_ELEMENT) ); Atomics.waitAsync(view, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + const view = new Uint8ClampedArray( + new SharedArrayBuffer(Uint8ClampedArray.BYTES_PER_ELEMENT) + ); + Atomics.waitAsync(view, poisoned, poisoned, poisoned); +}, '`const view = new Uint8ClampedArray( new SharedArrayBuffer(Uint8ClampedArray.BYTES_PER_ELEMENT) ); Atomics.waitAsync(view, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/non-shared-bufferdata-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/non-shared-bufferdata-throws.js new file mode 100644 index 0000000000..889bfd676e --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/non-shared-bufferdata-throws.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if typedArray.buffer is not a SharedArrayBuffer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 5. If waitable is true, then + a. If typeName is not "Int32Array" or "BigInt64Array", throw a TypeError exception. + +features: [Atomics.waitAsync, ArrayBuffer, Atomics, TypedArray, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new ArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, () => { + Atomics.waitAsync(i32a, 0, 0, 0); +}, '`Atomics.waitAsync(i32a, 0, 0, 0)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(i32a, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(i32a, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/not-a-typedarray-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/not-a-typedarray-throws.js new file mode 100644 index 0000000000..25be13fbbd --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/not-a-typedarray-throws.js @@ -0,0 +1,43 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if the typedArray arg is not a TypedArray object +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 2. Perform ? RequireInternalSlot(typedArray, [[TypedArrayName]]). + + RequireInternalSlot ( O, internalSlot ) + + 1. If Type(O) is not Object, throw a TypeError exception. + 2. If O does not have an internalSlot internal slot, throw a TypeError exception. + +features: [Atomics.waitAsync, arrow-function, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, () => { + Atomics.waitAsync({}, 0, 0, 0); +}, '`Atomics.waitAsync({}, 0, 0, 0)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync({}, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync({}, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/not-an-object-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/not-an-object-throws.js new file mode 100644 index 0000000000..9ea6b9f392 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/not-an-object-throws.js @@ -0,0 +1,63 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if typedArray arg is not an Object +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 2. Perform ? RequireInternalSlot(typedArray, [[TypedArrayName]]). + + RequireInternalSlot ( O, internalSlot ) + + 1. If Type(O) is not Object, throw a TypeError exception. + 2. If O does not have an internalSlot internal slot, throw a TypeError exception. + +features: [Atomics.waitAsync, Symbol, arrow-function, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, () => { + Atomics.waitAsync(null, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(null, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(undefined, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(undefined, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(true, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(true, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(false, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(false, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync('***string***', poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync("***string***", poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(Number.NEGATIVE_INFINITY, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(Number.NEGATIVE_INFINITY, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +assert.throws(TypeError, () => { + Atomics.waitAsync(Symbol('***symbol***'), poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(Symbol("***symbol***"), poisoned, poisoned, poisoned)` throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/null-bufferdata-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/null-bufferdata-throws.js new file mode 100644 index 0000000000..e5a8412140 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/null-bufferdata-throws.js @@ -0,0 +1,50 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + A null value for bufferData throws a TypeError +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 2. Perform ? RequireInternalSlot(typedArray, [[TypedArrayName]]). + + RequireInternalSlot ( O, internalSlot ) + + 1. If Type(O) is not Object, throw a TypeError exception. + 2. If O does not have an internalSlot internal slot, throw a TypeError exception. + +includes: [detachArrayBuffer.js] +features: [Atomics.waitAsync, ArrayBuffer, Atomics, TypedArray] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new ArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +try { + $DETACHBUFFER(i32a.buffer); // Detaching a non-shared ArrayBuffer sets the [[ArrayBufferData]] value to null +} catch (error) { + throw new Test262Error(`An unexpected error occurred when detaching ArrayBuffer: ${error.message}`); +} + +assert.throws(TypeError, function() { + Atomics.waitAsync(i32a, poisoned, poisoned, poisoned); +}, '`Atomics.waitAsync(i32a, poisoned, poisoned, poisoned)` throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/null-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/null-for-timeout-agent.js new file mode 100644 index 0000000000..09f8191896 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/null-for-timeout-agent.js @@ -0,0 +1,95 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + null timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Null -> Return +0. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf() { + return null; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]() { + return null; + } + }; + + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, null).value); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, valueOf).value); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, toPrimitive).value); + $262.agent.report(Atomics.waitAsync(i32a, 0, 0, null).value); + $262.agent.report(Atomics.waitAsync(i32a, 0, 0, valueOf).value); + $262.agent.report(Atomics.waitAsync(i32a, 0, 0, toPrimitive).value); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); + +}).then($DONE, $DONE); + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/null-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/null-for-timeout.js new file mode 100644 index 0000000000..6567c2c7d8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/null-for-timeout.js @@ -0,0 +1,56 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + null timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Null -> Return +0. + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const valueOf = { + valueOf() { + return null; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return null; + } +}; + +assert.sameValue( + Atomics.waitAsync(i32a, 0, 0, null).value, + 'timed-out', + 'The value of Atomics.waitAsync(i32a, 0, 0, null).value is "timed-out"' +); +assert.sameValue( + Atomics.waitAsync(i32a, 0, 0, valueOf).value, + 'timed-out', + 'The value of Atomics.waitAsync(i32a, 0, 0, valueOf).value is "timed-out"' +); +assert.sameValue( + Atomics.waitAsync(i32a, 0, 0, toPrimitive).value, + 'timed-out', + 'The value of Atomics.waitAsync(i32a, 0, 0, toPrimitive).value is "timed-out"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/object-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/object-for-timeout-agent.js new file mode 100644 index 0000000000..ae681bf391 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/object-for-timeout-agent.js @@ -0,0 +1,105 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Object valueOf, toString, toPrimitive Zero timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Object -> Apply the following steps: + + Let primValue be ? ToPrimitive(argument, hint Number). + Return ? ToNumber(primValue). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf() { + return 0; + } + }; + + const toString = { + toString() { + return "0"; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]() { + return 0; + } + }; + + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, valueOf).value); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, toString).value); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, toPrimitive).value); + $262.agent.report(Atomics.waitAsync(i32a, 0, 0, valueOf).value); + $262.agent.report(Atomics.waitAsync(i32a, 0, 0, toString).value); + $262.agent.report(Atomics.waitAsync(i32a, 0, 0, toPrimitive).value); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); + +}).then($DONE, $DONE); + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/object-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/object-for-timeout.js new file mode 100644 index 0000000000..cd1dc8f596 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/object-for-timeout.js @@ -0,0 +1,73 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Object valueOf, toString, toPrimitive Zero timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Object -> Apply the following steps: + + Let primValue be ? ToPrimitive(argument, hint Number). + Return ? ToNumber(primValue). + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics, arrow-function] +flags: [async] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const valueOf = { + valueOf() { + return 0; + } +}; + +const toString = { + toString() { + return "0"; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return 0; + } +}; + +assert.sameValue( + Atomics.waitAsync(i32a, 0, 0, valueOf).value, + 'timed-out', + 'The value of Atomics.waitAsync(i32a, 0, 0, valueOf).value is "timed-out"' +); +assert.sameValue( + Atomics.waitAsync(i32a, 0, 0, toString).value, + 'timed-out', + 'The value of Atomics.waitAsync(i32a, 0, 0, toString).value is "timed-out"' +); +assert.sameValue( + Atomics.waitAsync(i32a, 0, 0, toPrimitive).value, + 'timed-out', + 'The value of Atomics.waitAsync(i32a, 0, 0, toPrimitive).value is "timed-out"' +); + +Promise.all([ + Atomics.waitAsync(i32a, 0, 0, valueOf).value, + Atomics.waitAsync(i32a, 0, 0, toString).value, + Atomics.waitAsync(i32a, 0, 0, toPrimitive).value, + ]).then(outcomes => { + assert.sameValue(outcomes[0], "timed-out", 'The value of outcomes[0] is "timed-out"'); + assert.sameValue(outcomes[1], "timed-out", 'The value of outcomes[1] is "timed-out"'); + assert.sameValue(outcomes[2], "timed-out", 'The value of outcomes[2] is "timed-out"'); + }).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/out-of-range-index-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/out-of-range-index-throws.js new file mode 100644 index 0000000000..72ae3b0fb4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/out-of-range-index-throws.js @@ -0,0 +1,48 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a RangeError if value of index arg is out of range +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + + ... + 2.Let accessIndex be ? ToIndex(requestIndex). + ... + 5. If accessIndex ≥ length, throw a RangeError exception. +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(RangeError, function() { + Atomics.waitAsync(i32a, Infinity, poisoned, poisoned); +}, '`Atomics.waitAsync(i32a, Infinity, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i32a, -1, poisoned, poisoned); +}, '`Atomics.waitAsync(i32a, -1, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i32a, 4, poisoned, poisoned); +}, '`Atomics.waitAsync(i32a, 4, poisoned, poisoned)` throws a RangeError exception'); +assert.throws(RangeError, function() { + Atomics.waitAsync(i32a, 200, poisoned, poisoned); +}, '`Atomics.waitAsync(i32a, 200, poisoned, poisoned)` throws a RangeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/poisoned-object-for-timeout-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/poisoned-object-for-timeout-throws-agent.js new file mode 100644 index 0000000000..b2e606d77f --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/poisoned-object-for-timeout-throws-agent.js @@ -0,0 +1,89 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Let primValue be ? ToPrimitive(argument, hint Number). + Return ? ToNumber(primValue). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; + +$262.agent.start(` + const poisonedValueOf = { + valueOf() { + throw new Error('should not evaluate this code'); + } + }; + + const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Error('passing a poisoned object using @@ToPrimitive'); + } + }; + + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + let status1 = ''; + let status2 = ''; + + try { + Atomics.waitAsync(i32a, 0, 0, poisonedValueOf); + } catch (error) { + status1 = 'poisonedValueOf'; + } + try { + Atomics.waitAsync(i32a, 0, 0, poisonedToPrimitive); + } catch (error) { + status2 = 'poisonedToPrimitive'; + } + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'poisonedValueOf', + '(await $262.agent.getReportAsync()) resolves to the value "poisonedValueOf"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'poisonedToPrimitive', + '(await $262.agent.getReportAsync()) resolves to the value "poisonedToPrimitive"' + ); + + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); + +}).then($DONE, $DONE); + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/poisoned-object-for-timeout-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/poisoned-object-for-timeout-throws.js new file mode 100644 index 0000000000..3a084108e5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/poisoned-object-for-timeout-throws.js @@ -0,0 +1,49 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Let primValue be ? ToPrimitive(argument, hint Number). + Return ? ToNumber(primValue). + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisonedValueOf = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Test262Error('passing a poisoned object using @@ToPrimitive'); + } +}; + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i32a, 0, 0, poisonedValueOf); +}, '`Atomics.waitAsync(i32a, 0, 0, poisonedValueOf)` throws a Test262Error exception'); + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i32a, 0, 0, poisonedToPrimitive); +}, '`Atomics.waitAsync(i32a, 0, 0, poisonedToPrimitive)` throws a Test262Error exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-promise-resolves-to-ok.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-promise-resolves-to-ok.js new file mode 100644 index 0000000000..41fb6ae31c --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-promise-resolves-to-ok.js @@ -0,0 +1,52 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Atomics.waitAsync returns a result object containing a property named "value" whose value is a promise that resolves to "ok" and async is true. +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + ... + 13. Let promiseCapability be undefined. + 14. If mode is async, then + a. Set promiseCapability to ! NewPromiseCapability(%Promise%). + + ... + Perform ! CreateDataPropertyOrThrow(_resultObject_, *"async"*, *true*). + Perform ! CreateDataPropertyOrThrow(_resultObject_, *"value"*, _promiseCapability_.[[Promise]]). + Return _resultObject_. + +flags: [async] +features: [Atomics.waitAsync, TypedArray, SharedArrayBuffer, destructuring-binding, Atomics, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 8) +); + +let {async, value} = Atomics.waitAsync(i32a, 0, 0, 1000); +assert.sameValue(async, true, 'The value of `async` is true'); +assert(value instanceof Promise, 'The result of evaluating `(value instanceof Promise)` is true'); +assert.sameValue( + Object.getPrototypeOf(value), + Promise.prototype, + 'Object.getPrototypeOf(value) must return the value of Promise.prototype' +); + +value.then(outcome => { + assert.sameValue(outcome, "ok", 'The value of `outcome` is "ok"'); +}).then(() => $DONE(), $DONE); + +Atomics.add(i32a, 0, 1); +Atomics.notify(i32a, 0, 1); + + + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-promise-resolves-to-timed-out.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-promise-resolves-to-timed-out.js new file mode 100644 index 0000000000..9cd01f3200 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-promise-resolves-to-timed-out.js @@ -0,0 +1,57 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Atomics.waitAsync returns a result object containing a promise that resolves to "timed-out" and async is true. +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + ... + 13. Let promiseCapability be undefined. + 14. If mode is async, then + a. Set promiseCapability to ! NewPromiseCapability(%Promise%). + + ... + Perform ! CreateDataPropertyOrThrow(_resultObject_, *"async"*, *true*). + Perform ! CreateDataPropertyOrThrow(_resultObject_, *"value"*, _promiseCapability_.[[Promise]]). + Return _resultObject_. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, TypedArray, SharedArrayBuffer, destructuring-binding, Atomics, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 8) +); + +let {async, value} = Atomics.waitAsync(i32a, 0, 0, 1); +let outcome = null; +let lifespan = 1000; +let start = $262.agent.monotonicNow(); + +function wait() { + let elapsed = $262.agent.monotonicNow() - start; + if (elapsed > lifespan) { + $DONE("Test timed out"); + return; + } + if (outcome === "timed-out") { + $DONE(); + return; + } + + $262.agent.setTimeout(wait, 0); +} + +wait(); + +value.then(result => (outcome = result), $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-string-not-equal.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-string-not-equal.js new file mode 100644 index 0000000000..f981109bb7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-string-not-equal.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Atomics.waitAsync returns a result object containing a string "not-equal" and async is false. +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + ... + 13. Let promiseCapability be undefined. + 14. If mode is async, then + a. Set promiseCapability to ! NewPromiseCapability(%Promise%). + + ... + Perform ! CreateDataPropertyOrThrow(_resultObject_, *"async"*, *true*). + Perform ! CreateDataPropertyOrThrow(_resultObject_, *"value"*, _promiseCapability_.[[Promise]]). + Return _resultObject_. + +features: [Atomics.waitAsync, TypedArray, SharedArrayBuffer, destructuring-binding, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 8) +); + +let {async, value} = Atomics.waitAsync(i32a, 0, 1); + +assert.sameValue(async, false, 'The value of `async` is false'); +assert.sameValue(value, "not-equal", 'The value of `value` is "not-equal"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-string-timed-out.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-string-timed-out.js new file mode 100644 index 0000000000..85fed2b5ad --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/returns-result-object-value-is-string-timed-out.js @@ -0,0 +1,39 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Atomics.waitAsync returns a result object containing a string "not-equal" and async is false. +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + ... + 13. Let promiseCapability be undefined. + 14. If mode is async, then + a. Set promiseCapability to ! NewPromiseCapability(%Promise%). + + ... + Perform ! CreateDataPropertyOrThrow(_resultObject_, *"async"*, *true*). + Perform ! CreateDataPropertyOrThrow(_resultObject_, *"value"*, _promiseCapability_.[[Promise]]). + Return _resultObject_. + +features: [Atomics.waitAsync, TypedArray, SharedArrayBuffer, destructuring-binding, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 8) +); + +let {async, value} = Atomics.waitAsync(i32a, 0, 0, 0); + +assert.sameValue(async, false, 'The value of `async` is false'); +assert.sameValue(value, "timed-out", 'The value of `value` is "timed-out"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/shell.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/shell.js new file mode 100644 index 0000000000..409797a047 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/shell.js @@ -0,0 +1,457 @@ +// GENERATED, DO NOT EDIT +// file: asyncHelpers.js +// Copyright (C) 2022 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + A collection of assertion and wrapper functions for testing asynchronous built-ins. +defines: [asyncTest] +---*/ + +function asyncTest(testFunc) { + if (!Object.hasOwn(globalThis, "$DONE")) { + throw new Test262Error("asyncTest called without async flag"); + } + if (typeof testFunc !== "function") { + $DONE(new Test262Error("asyncTest called with non-function argument")); + return; + } + try { + testFunc().then( + function () { + $DONE(); + }, + function (error) { + $DONE(error); + } + ); + } catch (syncError) { + $DONE(syncError); + } +} + +assert.throwsAsync = async function (expectedErrorConstructor, func, message) { + var innerThenable; + if (message === undefined) { + 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 { + message += + "assert.throwsAsync called with an argument that is not a function"; + throw new Test262Error(message); + } + + try { + return innerThenable.then( + function () { + message += + "Expected a " + + expectedErrorConstructor.name + + " to be thrown asynchronously but no exception was thrown at all"; + throw new Test262Error(message); + }, + function (thrown) { + var expectedName, actualName; + if (typeof thrown !== "object" || thrown === null) { + message += "Thrown value was not an object!"; + throw new Test262Error(message); + } else if (thrown.constructor !== expectedErrorConstructor) { + expectedName = expectedErrorConstructor.name; + actualName = thrown.constructor.name; + if (expectedName === actualName) { + message += + "Expected a " + + expectedName + + " but got a different error constructor with the same name"; + } else { + message += + "Expected a " + expectedName + " but got a " + actualName; + } + throw new Test262Error(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"; + } + throw new Test262Error(message); + } +}; + +// file: atomicsHelper.js +// Copyright (C) 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: > + Collection of functions used to interact with Atomics.* operations across agent boundaries. +defines: + - $262.agent.getReportAsync + - $262.agent.getReport + - $262.agent.safeBroadcastAsync + - $262.agent.safeBroadcast + - $262.agent.setTimeout + - $262.agent.tryYield + - $262.agent.trySleep +---*/ + +/** + * @return {String} A report sent from an agent. + */ +{ + // This is only necessary because the original + // $262.agent.getReport API was insufficient. + // + // All runtimes currently have their own + // $262.agent.getReport which is wrong, so we + // will pave over it with a corrected version. + // + // Binding $262.agent is necessary to prevent + // breaking SpiderMonkey's $262.agent.getReport + let getReport = $262.agent.getReport.bind($262.agent); + + $262.agent.getReport = function() { + var r; + while ((r = getReport()) == null) { + $262.agent.sleep(1); + } + return r; + }; + + if (this.setTimeout === undefined) { + (function(that) { + that.setTimeout = function(callback, delay) { + let p = Promise.resolve(); + let start = Date.now(); + let end = start + delay; + function check() { + if ((end - Date.now()) > 0) { + p.then(check); + } + else { + callback(); + } + } + p.then(check); + } + })(this); + } + + $262.agent.setTimeout = setTimeout; + + $262.agent.getReportAsync = function() { + return new Promise(function(resolve) { + (function loop() { + let result = getReport(); + if (!result) { + setTimeout(loop, 1000); + } else { + resolve(result); + } + })(); + }); + }; +} + +/** + * + * Share a given Int32Array or BigInt64Array to all running agents. Ensure that the + * provided TypedArray is a "shared typed array". + * + * NOTE: Migrating all tests to this API is necessary to prevent tests from hanging + * indefinitely when a SAB is sent to a worker but the code in the worker attempts to + * create a non-sharable TypedArray (something that is not Int32Array or BigInt64Array). + * When that scenario occurs, an exception is thrown and the agent worker can no + * longer communicate with any other threads that control the SAB. If the main + * thread happens to be spinning in the $262.agent.waitUntil() while loop, it will never + * meet its termination condition and the test will hang indefinitely. + * + * Because we've defined $262.agent.broadcast(SAB) in + * https://github.com/tc39/test262/blob/HEAD/INTERPRETING.md, there are host implementations + * that assume compatibility, which must be maintained. + * + * + * $262.agent.safeBroadcast(TA) should not be included in + * https://github.com/tc39/test262/blob/HEAD/INTERPRETING.md + * + * + * @param {(Int32Array|BigInt64Array)} typedArray An Int32Array or BigInt64Array with a SharedArrayBuffer + */ +$262.agent.safeBroadcast = function(typedArray) { + let Constructor = Object.getPrototypeOf(typedArray).constructor; + let temp = new Constructor( + new SharedArrayBuffer(Constructor.BYTES_PER_ELEMENT) + ); + try { + // This will never actually wait, but that's fine because we only + // want to ensure that this typedArray CAN be waited on and is shareable. + Atomics.wait(temp, 0, Constructor === Int32Array ? 1 : BigInt(1)); + } catch (error) { + throw new Test262Error(`${Constructor.name} cannot be used as a shared typed array. (${error})`); + } + + $262.agent.broadcast(typedArray.buffer); +}; + +$262.agent.safeBroadcastAsync = async function(ta, index, expected) { + await $262.agent.broadcast(ta.buffer); + await $262.agent.waitUntil(ta, index, expected); + await $262.agent.tryYield(); + return await Atomics.load(ta, index); +}; + + +/** + * With a given Int32Array or BigInt64Array, wait until the expected number of agents have + * reported themselves by calling: + * + * Atomics.add(typedArray, index, 1); + * + * @param {(Int32Array|BigInt64Array)} typedArray An Int32Array or BigInt64Array with a SharedArrayBuffer + * @param {number} index The index of which all agents will report. + * @param {number} expected The number of agents that are expected to report as active. + */ +$262.agent.waitUntil = function(typedArray, index, expected) { + + var agents = 0; + while ((agents = Atomics.load(typedArray, index)) !== expected) { + /* nothing */ + } + assert.sameValue(agents, expected, "Reporting number of 'agents' equals the value of 'expected'"); +}; + +/** + * Timeout values used throughout the Atomics tests. All timeouts are specified in milliseconds. + * + * @property {number} yield Used for `$262.agent.tryYield`. Must not be used in other functions. + * @property {number} small Used when agents will always timeout and `Atomics.wake` is not part + * of the test semantics. Must be larger than `$262.agent.timeouts.yield`. + * @property {number} long Used when some agents may timeout and `Atomics.wake` is called on some + * agents. The agents are required to wait and this needs to be observable + * by the main thread. + * @property {number} huge Used when `Atomics.wake` is called on all waiting agents. The waiting + * must not timeout. The agents are required to wait and this needs to be + * observable by the main thread. All waiting agents must be woken by the + * main thread. + * + * Usage for `$262.agent.timeouts.small`: + * const WAIT_INDEX = 0; + * const RUNNING = 1; + * const TIMEOUT = $262.agent.timeouts.small; + * const i32a = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 2)); + * + * $262.agent.start(` + * $262.agent.receiveBroadcast(function(sab) { + * const i32a = new Int32Array(sab); + * Atomics.add(i32a, ${RUNNING}, 1); + * + * $262.agent.report(Atomics.wait(i32a, ${WAIT_INDEX}, 0, ${TIMEOUT})); + * + * $262.agent.leaving(); + * }); + * `); + * $262.agent.safeBroadcast(i32a.buffer); + * + * // Wait until the agent was started and then try to yield control to increase + * // the likelihood the agent has called `Atomics.wait` and is now waiting. + * $262.agent.waitUntil(i32a, RUNNING, 1); + * $262.agent.tryYield(); + * + * // The agent is expected to time out. + * assert.sameValue($262.agent.getReport(), "timed-out"); + * + * + * Usage for `$262.agent.timeouts.long`: + * const WAIT_INDEX = 0; + * const RUNNING = 1; + * const NUMAGENT = 2; + * const TIMEOUT = $262.agent.timeouts.long; + * const i32a = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 2)); + * + * for (let i = 0; i < NUMAGENT; i++) { + * $262.agent.start(` + * $262.agent.receiveBroadcast(function(sab) { + * const i32a = new Int32Array(sab); + * Atomics.add(i32a, ${RUNNING}, 1); + * + * $262.agent.report(Atomics.wait(i32a, ${WAIT_INDEX}, 0, ${TIMEOUT})); + * + * $262.agent.leaving(); + * }); + * `); + * } + * $262.agent.safeBroadcast(i32a.buffer); + * + * // Wait until the agents were started and then try to yield control to increase + * // the likelihood the agents have called `Atomics.wait` and are now waiting. + * $262.agent.waitUntil(i32a, RUNNING, NUMAGENT); + * $262.agent.tryYield(); + * + * // Wake exactly one agent. + * assert.sameValue(Atomics.wake(i32a, WAIT_INDEX, 1), 1); + * + * // When it doesn't matter how many agents were woken at once, a while loop + * // can be used to make the test more resilient against intermittent failures + * // in case even though `tryYield` was called, the agents haven't started to + * // wait. + * // + * // // Repeat until exactly one agent was woken. + * // var woken = 0; + * // while ((woken = Atomics.wake(i32a, WAIT_INDEX, 1)) !== 0) ; + * // assert.sameValue(woken, 1); + * + * // One agent was woken and the other one timed out. + * const reports = [$262.agent.getReport(), $262.agent.getReport()]; + * assert(reports.includes("ok")); + * assert(reports.includes("timed-out")); + * + * + * Usage for `$262.agent.timeouts.huge`: + * const WAIT_INDEX = 0; + * const RUNNING = 1; + * const NUMAGENT = 2; + * const TIMEOUT = $262.agent.timeouts.huge; + * const i32a = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 2)); + * + * for (let i = 0; i < NUMAGENT; i++) { + * $262.agent.start(` + * $262.agent.receiveBroadcast(function(sab) { + * const i32a = new Int32Array(sab); + * Atomics.add(i32a, ${RUNNING}, 1); + * + * $262.agent.report(Atomics.wait(i32a, ${WAIT_INDEX}, 0, ${TIMEOUT})); + * + * $262.agent.leaving(); + * }); + * `); + * } + * $262.agent.safeBroadcast(i32a.buffer); + * + * // Wait until the agents were started and then try to yield control to increase + * // the likelihood the agents have called `Atomics.wait` and are now waiting. + * $262.agent.waitUntil(i32a, RUNNING, NUMAGENT); + * $262.agent.tryYield(); + * + * // Wake all agents. + * assert.sameValue(Atomics.wake(i32a, WAIT_INDEX), NUMAGENT); + * + * // When it doesn't matter how many agents were woken at once, a while loop + * // can be used to make the test more resilient against intermittent failures + * // in case even though `tryYield` was called, the agents haven't started to + * // wait. + * // + * // // Repeat until all agents were woken. + * // for (var wokenCount = 0; wokenCount < NUMAGENT; ) { + * // var woken = 0; + * // while ((woken = Atomics.wake(i32a, WAIT_INDEX)) !== 0) ; + * // // Maybe perform an action on the woken agents here. + * // wokenCount += woken; + * // } + * + * // All agents were woken and none timeout. + * for (var i = 0; i < NUMAGENT; i++) { + * assert($262.agent.getReport(), "ok"); + * } + */ +$262.agent.timeouts = { + yield: 100, + small: 200, + long: 1000, + huge: 10000, +}; + +/** + * Try to yield control to the agent threads. + * + * Usage: + * const VALUE = 0; + * const RUNNING = 1; + * const i32a = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 2)); + * + * $262.agent.start(` + * $262.agent.receiveBroadcast(function(sab) { + * const i32a = new Int32Array(sab); + * Atomics.add(i32a, ${RUNNING}, 1); + * + * Atomics.store(i32a, ${VALUE}, 1); + * + * $262.agent.leaving(); + * }); + * `); + * $262.agent.safeBroadcast(i32a.buffer); + * + * // Wait until agent was started and then try to yield control. + * $262.agent.waitUntil(i32a, RUNNING, 1); + * $262.agent.tryYield(); + * + * // Note: This result is not guaranteed, but should hold in practice most of the time. + * assert.sameValue(Atomics.load(i32a, VALUE), 1); + * + * The default implementation simply waits for `$262.agent.timeouts.yield` milliseconds. + */ +$262.agent.tryYield = function() { + $262.agent.sleep($262.agent.timeouts.yield); +}; + +/** + * Try to sleep the current agent for the given amount of milliseconds. It is acceptable, + * but not encouraged, to ignore this sleep request and directly continue execution. + * + * The default implementation calls `$262.agent.sleep(ms)`. + * + * @param {number} ms Time to sleep in milliseconds. + */ +$262.agent.trySleep = function(ms) { + $262.agent.sleep(ms); +}; + +// file: detachArrayBuffer.js +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + A function used in the process of asserting correctness of TypedArray objects. + + $262.detachArrayBuffer is defined by a host. +defines: [$DETACHBUFFER] +---*/ + +function $DETACHBUFFER(buffer) { + if (!$262 || typeof $262.detachArrayBuffer !== "function") { + throw new Test262Error("No method available to detach an ArrayBuffer"); + } + $262.detachArrayBuffer(buffer); +} diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-index-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-index-throws-agent.js new file mode 100644 index 0000000000..937bad77ae --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-index-throws-agent.js @@ -0,0 +1,100 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + + ValidateAtomicAccess( typedArray, requestIndex ) + + 2. Let accessIndex be ? ToIndex(requestIndex). + + ToIndex ( value ) + + 2. Else, + a. Let integerIndex be ? ToInteger(value). + + ToInteger(value) + + 1. Let number be ? ToNumber(argument). + + Symbol --> Throw a TypeError exception. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; + +$262.agent.start(` + const poisonedValueOf = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } + }; + + const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Test262Error('should not evaluate this code'); + } + }; + + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + let status1 = ''; + let status2 = ''; + + try { + Atomics.waitAsync(i32a, Symbol('1'), poisonedValueOf, poisonedValueOf); + } catch (error) { + status1 = 'A ' + error.name; + } + try { + Atomics.waitAsync(i32a, Symbol('2'), poisonedToPrimitive, poisonedToPrimitive); + } catch (error) { + status2 = 'B ' + error.name; + } + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'A TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "A TypeError"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'B TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "B TypeError"' + ); + + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); + +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-index-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-index-throws.js new file mode 100644 index 0000000000..58127afa98 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-index-throws.js @@ -0,0 +1,71 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + + ValidateAtomicAccess( typedArray, requestIndex ) + + 2. Let accessIndex be ? ToIndex(requestIndex). + + ToIndex ( value ) + + 2. Else, + a. Let integerIndex be ? ToInteger(value). + + ToInteger(value) + + 1. Let number be ? ToNumber(argument). + + Symbol --> Throw a TypeError exception. + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisonedValueOf = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i32a, poisonedValueOf, poisonedValueOf, poisonedValueOf); +}, '`Atomics.waitAsync(i32a, poisonedValueOf, poisonedValueOf, poisonedValueOf)` throws a Test262Error exception'); + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i32a, poisonedToPrimitive, poisonedToPrimitive, poisonedToPrimitive); +}, '`Atomics.waitAsync(i32a, poisonedToPrimitive, poisonedToPrimitive, poisonedToPrimitive)` throws a Test262Error exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i32a, Symbol('1'), poisonedValueOf, poisonedValueOf); +}, '`Atomics.waitAsync(i32a, Symbol("1"), poisonedValueOf, poisonedValueOf)` throws a TypeError exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i32a, Symbol('2'), poisonedToPrimitive, poisonedToPrimitive); +}, '`Atomics.waitAsync(i32a, Symbol("2"), poisonedToPrimitive, poisonedToPrimitive)` throws a TypeError exception'); + + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-timeout-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-timeout-throws-agent.js new file mode 100644 index 0000000000..dc5c01c221 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-timeout-throws-agent.js @@ -0,0 +1,77 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Symbol --> Throw a TypeError exception. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + let status1 = ''; + let status2 = ''; + + try { + Atomics.waitAsync(i32a, 0, 0, Symbol('1')); + } catch (error) { + status1 = 'A ' + error.name; + } + try { + Atomics.waitAsync(i32a, 0, 0, Symbol('2')); + } catch (error) { + status2 = 'B ' + error.name; + } + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'A TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "A TypeError"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'B TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "B TypeError"' + ); + + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); + +}).then($DONE, $DONE); + + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-timeout-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-timeout-throws.js new file mode 100644 index 0000000000..1659f517e3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-timeout-throws.js @@ -0,0 +1,55 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Symbol --> Throw a TypeError exception. + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisonedValueOf = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Test262Error('passing a poisoned object using @@ToPrimitive'); + } +}; + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i32a, 0, 0, poisonedValueOf); +}, '`Atomics.waitAsync(i32a, 0, 0, poisonedValueOf)` throws a Test262Error exception'); + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i32a, 0, 0, poisonedToPrimitive); +}, '`Atomics.waitAsync(i32a, 0, 0, poisonedToPrimitive)` throws a Test262Error exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i32a, 0, 0, Symbol("foo")); +}, '`Atomics.waitAsync(i32a, 0, 0, Symbol("foo"))` throws a TypeError exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i32a, 0, 0, Symbol("foo")); +}, '`Atomics.waitAsync(i32a, 0, 0, Symbol("foo"))` throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-value-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-value-throws-agent.js new file mode 100644 index 0000000000..4de2105353 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-value-throws-agent.js @@ -0,0 +1,93 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if value arg is a Symbol +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 5. Otherwise, let v be ? ToInt32(value). + + ToInt32(value) + + 1.Let number be ? ToNumber(argument). + + Symbol --> Throw a TypeError exception. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; + +$262.agent.start(` + const poisonedValueOf = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } + }; + + const poisonedToPrimitive = { + [Symbol.toPrimitive]: function() { + throw new Test262Error("passing a poisoned object using @@ToPrimitive"); + } + }; + + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + let status1 = ""; + let status2 = ""; + + try { + Atomics.waitAsync(i32a, 0, Symbol("1"), poisonedValueOf); + } catch (error) { + status1 = 'A ' + error.name; + } + try { + Atomics.waitAsync(i32a, 0, Symbol("2"), poisonedToPrimitive); + } catch (error) { + status2 = 'B ' + error.name; + } + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'A TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "A TypeError"' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'B TypeError', + '(await $262.agent.getReportAsync()) resolves to the value "B TypeError"' + ); + + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); + +}).then($DONE, $DONE); + + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-value-throws.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-value-throws.js new file mode 100644 index 0000000000..1d0c98ad8c --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/symbol-for-value-throws.js @@ -0,0 +1,59 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if value arg is a Symbol +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 5. Otherwise, let v be ? ToInt32(value). + + ToInt32(value) + + 1.Let number be ? ToNumber(argument). + + Symbol --> Throw a TypeError exception. + +features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisonedValueOf = { + valueOf() { + throw new Test262Error('should not evaluate this code'); + } +}; + +const poisonedToPrimitive = { + [Symbol.toPrimitive]() { + throw new Test262Error("passing a poisoned object using @@ToPrimitive"); + } +}; + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i32a, 0, poisonedValueOf, poisonedValueOf); +}, '`Atomics.waitAsync(i32a, 0, poisonedValueOf, poisonedValueOf)` throws a Test262Error exception'); + +assert.throws(Test262Error, function() { + Atomics.waitAsync(i32a, 0, poisonedToPrimitive, poisonedToPrimitive); +}, '`Atomics.waitAsync(i32a, 0, poisonedToPrimitive, poisonedToPrimitive)` throws a Test262Error exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i32a, 0, Symbol("foo"), poisonedValueOf); +}, '`Atomics.waitAsync(i32a, 0, Symbol("foo"), poisonedValueOf)` throws a TypeError exception'); + +assert.throws(TypeError, function() { + Atomics.waitAsync(i32a, 0, Symbol("foo"), poisonedToPrimitive); +}, '`Atomics.waitAsync(i32a, 0, Symbol("foo"), poisonedToPrimitive)` throws a TypeError exception'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/true-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/true-for-timeout-agent.js new file mode 100644 index 0000000000..240c3c07fa --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/true-for-timeout-agent.js @@ -0,0 +1,76 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + True timeout arg should result in an +0 timeout +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf() { + return true; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]() { + return true; + } + }; + + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, true).value); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, valueOf).value); + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, toPrimitive).value); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'timed-out', + '(await $262.agent.getReportAsync()) resolves to the value "timed-out"' + ); + + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); + +}).then($DONE, $DONE); + + diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/true-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/true-for-timeout.js new file mode 100644 index 0000000000..86a2be28fa --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/true-for-timeout.js @@ -0,0 +1,66 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + + Boolean -> If argument is true, return 1. If argument is false, return +0. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, computed-property-names, Symbol, Symbol.toPrimitive, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const valueOf = { + valueOf() { + return true; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return true; + } +}; + +let outcomes = []; +let lifespan = 1000; +let start = $262.agent.monotonicNow(); + +(function wait() { + let elapsed = $262.agent.monotonicNow() - start; + if (elapsed > lifespan) { + $DONE("Test timed out"); + return; + } + if (outcomes.length) { + assert.sameValue(outcomes[0], 'timed-out', 'The value of outcomes[0] is "timed-out"'); + assert.sameValue(outcomes[1], 'timed-out', 'The value of outcomes[1] is "timed-out"'); + assert.sameValue(outcomes[2], 'timed-out', 'The value of outcomes[2] is "timed-out"'); + $DONE(); + return; + } + + $262.agent.setTimeout(wait, 0); +})(); + +Promise.all([ + Atomics.waitAsync(i32a, 0, 0, true).value, + Atomics.waitAsync(i32a, 0, 0, valueOf).value, + Atomics.waitAsync(i32a, 0, 0, toPrimitive).value, + ]).then(results => (outcomes = results), $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/undefined-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/undefined-for-timeout-agent.js new file mode 100644 index 0000000000..b50ef05dce --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/undefined-for-timeout-agent.js @@ -0,0 +1,77 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Undefined timeout arg is coerced to zero +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + ... + Undefined Return NaN. + + 5.If q is NaN, let t be +∞, else let t be max(q, 0) + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const WAIT_INDEX = 0; +const RUNNING = 1; +const NUMAGENT = 2; +const NOTIFYCOUNT = 2; + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + var i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + // undefined => NaN => +Infinity + $262.agent.report("A " + (await Atomics.waitAsync(i32a, 0, 0, undefined).value)); + $262.agent.leaving(); + }); +`); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + var i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + // undefined timeout arg => NaN => +Infinity + $262.agent.report("B " + (await Atomics.waitAsync(i32a, 0, 0).value)); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, NUMAGENT).then(async (agentCount) => { + + assert.sameValue(agentCount, NUMAGENT, 'The value of `agentCount` is expected to equal the value of NUMAGENT'); + + assert.sameValue( + Atomics.notify(i32a, WAIT_INDEX, NOTIFYCOUNT), + NOTIFYCOUNT, + 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0, 2) must return the value of NOTIFYCOUNT' + ); + + const reports = [ + await $262.agent.getReportAsync(), + await $262.agent.getReportAsync(), + ]; + + reports.sort(); + assert.sameValue(reports[0], 'A ok', 'The value of reports[0] is "A ok"'); + assert.sameValue(reports[1], 'B ok', 'The value of reports[1] is "B ok"'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/undefined-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/undefined-for-timeout.js new file mode 100644 index 0000000000..89038c7ab5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/undefined-for-timeout.js @@ -0,0 +1,54 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Undefined timeout arg is coerced to zero +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 6. Let q be ? ToNumber(timeout). + ... + Undefined Return NaN. + + 5.If q is NaN, let t be +∞, else let t be max(q, 0) + +flags: [async] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, computed-property-names, Symbol, Symbol.toPrimitive, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const valueOf = { + valueOf() { + return undefined; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return undefined; + } +}; + +Promise.all([ + Atomics.waitAsync(i32a, 0, 0).value, + Atomics.waitAsync(i32a, 0, 0, undefined).value, + Atomics.waitAsync(i32a, 0, 0, valueOf).value, + Atomics.waitAsync(i32a, 0, 0, toPrimitive).value + ]).then(outcomes => { + assert.sameValue(outcomes[0], 'ok', 'The value of outcomes[0] is "ok"'); + assert.sameValue(outcomes[1], 'ok', 'The value of outcomes[1] is "ok"'); + assert.sameValue(outcomes[2], 'ok', 'The value of outcomes[2] is "ok"'); + assert.sameValue(outcomes[3], 'ok', 'The value of outcomes[3] is "ok"'); + }).then($DONE, $DONE); + +Atomics.notify(i32a, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/undefined-index-defaults-to-zero-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/undefined-index-defaults-to-zero-agent.js new file mode 100644 index 0000000000..294e871035 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/undefined-index-defaults-to-zero-agent.js @@ -0,0 +1,79 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Undefined index arg is coerced to zero +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 2. Let i be ? ValidateAtomicAccess(typedArray, index). + ... + 2.Let accessIndex be ? ToIndex(requestIndex). + + 9.If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception. + ... + 3.If bufferData is a Data Block, return false + + If value is undefined, then + Let index be 0. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const WAIT_INDEX = 0; +const RUNNING = 1; +const NUMAGENT = 2; +const NOTIFYCOUNT = 2; + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + var i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + $262.agent.report("A " + (await Atomics.waitAsync(i32a, undefined, 0).value)); + $262.agent.leaving(); + }); +`); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + var i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + $262.agent.report("B " + (await Atomics.waitAsync(i32a, undefined, 0).value)); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, NUMAGENT).then(async (agentCount) => { + + assert.sameValue(agentCount, NUMAGENT, 'The value of `agentCount` is expected to equal the value of NUMAGENT'); + + assert.sameValue( + Atomics.notify(i32a, WAIT_INDEX, NOTIFYCOUNT), + NOTIFYCOUNT, + 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0, 2) must return the value of NOTIFYCOUNT' + ); + + const reports = [ + await $262.agent.getReportAsync(), + await $262.agent.getReportAsync(), + ]; + + reports.sort(); + assert.sameValue(reports[0], 'A ok', 'The value of reports[0] is "A ok"'); + assert.sameValue(reports[1], 'B ok', 'The value of reports[1] is "B ok"'); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/validate-arraytype-before-index-coercion.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/validate-arraytype-before-index-coercion.js new file mode 100644 index 0000000000..97c45cc86d --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/validate-arraytype-before-index-coercion.js @@ -0,0 +1,53 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + TypedArray type is validated before `index` argument is coerced. +info: | + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 1. If waitable is not present, set waitable to false. + 2. Perform ? RequireInternalSlot(typedArray, [[TypedArrayName]]). + 3. Let typeName be typedArray.[[TypedArrayName]]. + 4. Let type be the Element Type value in Table 61 for typeName. + 5. If waitable is true, then + a. If typeName is not "Int32Array" or "BigInt64Array", throw a TypeError exception. + 6. Else, + a. If ! IsUnclampedIntegerElementType(type) is false and ! IsBigIntElementType(type) is false, throw a TypeError exception. + 7. Assert: typedArray has a [[ViewedArrayBuffer]] internal slot. + 8. Let buffer be typedArray.[[ViewedArrayBuffer]]. + 9. If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception. + 10. Return buffer. + +features: [Atomics.waitAsync, Atomics, TypedArray, SharedArrayBuffer] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const index = { + valueOf() { + throw new Test262Error(); + } +}; + +const nonSharedArrayTypes = [ + Int8Array, Uint8Array, Int16Array, Uint16Array, Uint32Array, + Uint8ClampedArray, Float32Array, Float64Array +]; + +for (const nonSharedArrayType of nonSharedArrayTypes) { + const typedArray = new nonSharedArrayType(new SharedArrayBuffer(8)); + assert.throws(TypeError, function() { + Atomics.waitAsync(typedArray, index, 0, 0); + }, '`Atomics.waitAsync(typedArray, index, 0, 0)` throws a TypeError exception'); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/validate-arraytype-before-timeout-coercion.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/validate-arraytype-before-timeout-coercion.js new file mode 100644 index 0000000000..68297a551c --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/validate-arraytype-before-timeout-coercion.js @@ -0,0 +1,53 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + TypedArray type is validated before `timeout` argument is coerced. +info: | + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 1. If waitable is not present, set waitable to false. + 2. Perform ? RequireInternalSlot(typedArray, [[TypedArrayName]]). + 3. Let typeName be typedArray.[[TypedArrayName]]. + 4. Let type be the Element Type value in Table 61 for typeName. + 5. If waitable is true, then + a. If typeName is not "Int32Array" or "BigInt64Array", throw a TypeError exception. + 6. Else, + a. If ! IsUnclampedIntegerElementType(type) is false and ! IsBigIntElementType(type) is false, throw a TypeError exception. + 7. Assert: typedArray has a [[ViewedArrayBuffer]] internal slot. + 8. Let buffer be typedArray.[[ViewedArrayBuffer]]. + 9. If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception. + 10. Return buffer. + +features: [Atomics.waitAsync, Atomics, TypedArray, SharedArrayBuffer] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const timeout = { + valueOf() { + throw new Test262Error(); + } +}; + +const nonSharedArrayTypes = [ + Int8Array, Uint8Array, Int16Array, Uint16Array, Uint32Array, + Uint8ClampedArray, Float32Array, Float64Array +]; + +for (const nonSharedArrayType of nonSharedArrayTypes) { + const typedArray = new nonSharedArrayType(new SharedArrayBuffer(8)); + assert.throws(TypeError, function() { + Atomics.waitAsync(typedArray, 0, 0, timeout); + }, '`Atomics.waitAsync(typedArray, 0, 0, timeout)` throws a TypeError exception'); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/validate-arraytype-before-value-coercion.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/validate-arraytype-before-value-coercion.js new file mode 100644 index 0000000000..575ff360e3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/validate-arraytype-before-value-coercion.js @@ -0,0 +1,53 @@ +// |reftest| skip -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.notify +description: > + TypedArray type is validated before `value` argument is coerced. +info: | + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + + ValidateSharedIntegerTypedArray ( typedArray [ , waitable ] ) + + 1. If waitable is not present, set waitable to false. + 2. Perform ? RequireInternalSlot(typedArray, [[TypedArrayName]]). + 3. Let typeName be typedArray.[[TypedArrayName]]. + 4. Let type be the Element Type value in Table 61 for typeName. + 5. If waitable is true, then + a. If typeName is not "Int32Array" or "BigInt64Array", throw a TypeError exception. + 6. Else, + a. If ! IsUnclampedIntegerElementType(type) is false and ! IsBigIntElementType(type) is false, throw a TypeError exception. + 7. Assert: typedArray has a [[ViewedArrayBuffer]] internal slot. + 8. Let buffer be typedArray.[[ViewedArrayBuffer]]. + 9. If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception. + 10. Return buffer. + +features: [Atomics.waitAsync, Atomics, TypedArray, SharedArrayBuffer] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const value = { + valueOf() { + throw new Test262Error(); + } +}; + +const nonSharedArrayTypes = [ + Int8Array, Uint8Array, Int16Array, Uint16Array, Uint32Array, + Uint8ClampedArray, Float32Array, Float64Array +]; + +for (const nonSharedArrayType of nonSharedArrayTypes) { + const typedArray = new nonSharedArrayType(new SharedArrayBuffer(8)); + assert.throws(TypeError, function() { + Atomics.waitAsync(typedArray, 0, value, 0); + }, '`Atomics.waitAsync(typedArray, 0, value, 0)` throws a TypeError exception'); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/value-not-equal-agent.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/value-not-equal-agent.js new file mode 100644 index 0000000000..852162a856 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/value-not-equal-agent.js @@ -0,0 +1,67 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Returns "not-equal" when value arg does not match an index in the typedArray +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 16. Let w be ! AtomicLoad(typedArray, i). + 17. If v is not equal to w, then + a. Perform LeaveCriticalSection(WL). + b. If mode is sync, then + i. Return the String "not-equal". + c. Perform ! Call(capability.[[Resolve]], undefined, « "not-equal" »). + d. Return promiseCapability.[[Promise]]. + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; +const value = 42; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + $262.agent.report(Atomics.store(i32a, 0, ${value})); + $262.agent.report(Atomics.waitAsync(i32a, 0, 0).value); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + + assert.sameValue( + await $262.agent.getReportAsync(), + '42', + '(await $262.agent.getReportAsync()) resolves to the value "42"' + ); + assert.sameValue( + await $262.agent.getReportAsync(), + 'not-equal', + '(await $262.agent.getReportAsync()) resolves to the value "not-equal"' + ); + assert.sameValue( + Atomics.notify(i32a, 0, 1), + 0, + 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0, 1) must return 0' + ); +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/value-not-equal.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/value-not-equal.js new file mode 100644 index 0000000000..324fc4fc90 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/value-not-equal.js @@ -0,0 +1,50 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Returns "not-equal" when value arg does not match an index in the typedArray +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 16. Let w be ! AtomicLoad(typedArray, i). + 17. If v is not equal to w, then + a. Perform LeaveCriticalSection(WL). + b. If mode is sync, then + i. Return the String "not-equal". + c. Perform ! Call(capability.[[Resolve]], undefined, « "not-equal" »). + d. Return promiseCapability.[[Promise]]. + +flags: [async] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, computed-property-names, Symbol, Symbol.toPrimitive, Atomics, arrow-function] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const valueOf = { + valueOf() { + return undefined; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]() { + return undefined; + } +}; + +Promise.all([ + Atomics.store(i32a, 0, 42), + Atomics.waitAsync(i32a, 0, 0).value, + ]).then(outcomes => { + assert.sameValue(outcomes[0], 42, 'The value of outcomes[0] is 42'); + assert.sameValue(outcomes[1], 'not-equal', 'The value of outcomes[1] is "not-equal"'); + }).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/waiterlist-block-indexedposition-wake.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/waiterlist-block-indexedposition-wake.js new file mode 100644 index 0000000000..eaef023ecd --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/waiterlist-block-indexedposition-wake.js @@ -0,0 +1,85 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.waitasync +description: > + Get the correct WaiterList +info: | + Atomics.waitAsync( typedArray, index, value, timeout ) + + 1. Return DoWait(async, typedArray, index, value, timeout). + + DoWait ( mode, typedArray, index, value, timeout ) + + 11. Let indexedPosition be (i × 4) + offset. + 12. Let WL be GetWaiterList(block, indexedPosition). + + GetWaiterList( block, i ) + + ... + 4. Return the WaiterList that is referenced by the pair (block, i). + +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const NUMAGENT = 2; +const RUNNING = 4; + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + // Wait on index 0 + $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, Infinity).value); + $262.agent.leaving(); + }); +`); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + // Wait on index 2 + $262.agent.report(await Atomics.waitAsync(i32a, 2, 0, Infinity).value); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 5) +); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, NUMAGENT).then(async (agentCount) => { + + assert.sameValue(agentCount, NUMAGENT, 'The value of `agentCount` is expected to equal the value of NUMAGENT'); + + // Notify index 1, notifies nothing + assert.sameValue(Atomics.notify(i32a, 1), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 5)), 1) must return 0'); + + // Notify index 3, notifies nothing + assert.sameValue(Atomics.notify(i32a, 3), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 5)), 3) must return 0'); + + // Notify index 2, notifies 1 + assert.sameValue(Atomics.notify(i32a, 2), 1, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 5)), 2) must return 1'); + assert.sameValue( + await $262.agent.getReportAsync(), + 'ok', + '(await $262.agent.getReportAsync()) resolves to the value "ok"' + ); + + // Notify index 0, notifies 1 + assert.sameValue(Atomics.notify(i32a, 0), 1, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 5)), 0) must return 1'); + assert.sameValue( + await $262.agent.getReportAsync(), + 'ok', + '(await $262.agent.getReportAsync()) resolves to the value "ok"' + ); + +}).then($DONE, $DONE); diff --git a/js/src/tests/test262/built-ins/Atomics/waitAsync/was-woken-before-timeout.js b/js/src/tests/test262/built-ins/Atomics/waitAsync/was-woken-before-timeout.js new file mode 100644 index 0000000000..e45f0ef896 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/waitAsync/was-woken-before-timeout.js @@ -0,0 +1,55 @@ +// |reftest| skip async -- Atomics.waitAsync is not supported +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.waitasync +description: > + Test that Atomics.waitAsync returns the right result when it was awoken before + a timeout +flags: [async] +includes: [atomicsHelper.js] +features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics, arrow-function, async-functions] +---*/ +assert.sameValue(typeof Atomics.waitAsync, 'function', 'The value of `typeof Atomics.waitAsync` is "function"'); + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.huge; + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.start(` + $262.agent.receiveBroadcast(async (sab) => { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = await Atomics.waitAsync(i32a, 0, 0, ${TIMEOUT}).value; + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcastAsync(i32a, RUNNING, 1).then(async (agentCount) => { + + assert.sameValue(agentCount, 1, 'The value of `agentCount` is 1'); + assert.sameValue(Atomics.notify(i32a, 0), 1, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 1'); + + let lapse = await $262.agent.getReportAsync(); + + assert( + lapse < TIMEOUT, + 'The result of evaluating `(lapse < TIMEOUT)` is true' + ); + + assert.sameValue( + await $262.agent.getReportAsync(), + 'ok', + '(await $262.agent.getReportAsync()) resolves to the value "ok"' + ); + assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)), 0) must return 0'); +}).then($DONE, $DONE); |