diff options
Diffstat (limited to 'js/src/tests/test262/built-ins/Atomics/wait')
80 files changed, 4502 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bad-range.js b/js/src/tests/test262/built-ins/Atomics/wait/bad-range.js new file mode 100644 index 0000000000..777d623b65 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bad-range.js @@ -0,0 +1,29 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Test range checking of Atomics.wait on arrays that allow atomic operations +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + ... + +includes: [testAtomics.js] +features: [ArrayBuffer, Atomics, DataView, SharedArrayBuffer, Symbol, TypedArray] +---*/ + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 8) +); + +testWithAtomicsOutOfBoundsIndices(function(IdxGen) { + assert.throws(RangeError, function() { + Atomics.wait(i32a, IdxGen(i32a), 0, 0); + }, '`Atomics.wait(i32a, IdxGen(i32a), 0, 0)` throws RangeError'); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/bad-range.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/bad-range.js new file mode 100644 index 0000000000..ad3310e9a0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/bad-range.js @@ -0,0 +1,29 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Test range checking of Atomics.wait on arrays that allow atomic operations +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + ... + +includes: [testAtomics.js] +features: [ArrayBuffer, Atomics, BigInt, DataView, SharedArrayBuffer, Symbol, TypedArray] +---*/ + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 8) +); + +testWithAtomicsOutOfBoundsIndices(function(IdxGen) { + assert.throws(RangeError, function() { + Atomics.wait(i64a, IdxGen(i64a), 0n, 0); + }, '`Atomics.wait(i64a, IdxGen(i64a), 0n, 0)` throws RangeError'); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/browser.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/browser.js diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/cannot-suspend-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/cannot-suspend-throws.js new file mode 100644 index 0000000000..5b54c68914 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/cannot-suspend-throws.js @@ -0,0 +1,27 @@ +// |reftest| skip-if(xulRuntime.shell||!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- shell can block main thread, Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.wait +description: > + Atomics.wait throws if agent cannot be suspended, CanBlock is false +info: | + Assuming [[CanBlock]] is false for the main host. + + Atomics.wait( typedArray, index, value, timeout ) + + ... (after args validation) + 6. Let B be AgentCanSuspend(). + 7. If B is false, throw a TypeError exception. + ... +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +flags: [CanBlockIsFalse] +---*/ + +const i64a = new BigInt64Array(new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4)); + +assert.throws(TypeError, function() { + Atomics.wait(i64a, 0, 0n, 0); +}, '`Atomics.wait(i64a, 0, 0n, 0)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/false-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/false-for-timeout-agent.js new file mode 100644 index 0000000000..1b401417e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/false-for-timeout-agent.js @@ -0,0 +1,78 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Boolean -> If argument is true, return 1. If argument is false, return +0. + +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf: function() { + return false; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]: function() { + return false; + } + }; + + $262.agent.receiveBroadcast(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const status1 = Atomics.wait(i64a, 0, 0n, false); + const status2 = Atomics.wait(i64a, 0, 0n, valueOf); + const status3 = Atomics.wait(i64a, 0, 0n, toPrimitive); + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.report(status3); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); + +assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/false-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/false-for-timeout.js new file mode 100644 index 0000000000..b58907c223 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/false-for-timeout.js @@ -0,0 +1,52 @@ +// |reftest| skip-if(!xulRuntime.shell||!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- browser cannot block main thread, Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Boolean -> If argument is true, return 1. If argument is false, return +0. + +features: [Atomics, BigInt, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +flags: [CanBlockIsTrue] +---*/ + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +const valueOf = { + valueOf: function() { + return false; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]: function() { + return false; + } +}; + +assert.sameValue( + Atomics.wait(i64a, 0, 0n, false), + "timed-out", + 'Atomics.wait(i64a, 0, 0n, false) returns "timed-out"' +); +assert.sameValue( + Atomics.wait(i64a, 0, 0n, valueOf), + "timed-out", + 'Atomics.wait(i64a, 0, 0n, valueOf) returns "timed-out"' +); +assert.sameValue( + Atomics.wait(i64a, 0, 0n, toPrimitive), + "timed-out", + 'Atomics.wait(i64a, 0, 0n, toPrimitive) returns "timed-out"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/nan-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/nan-for-timeout.js new file mode 100644 index 0000000000..00ae824330 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/nan-for-timeout.js @@ -0,0 +1,46 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + NaN timeout arg should result in an infinite timeout +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4.Let q be ? ToNumber(timeout). + ... + Undefined Return NaN. + 5.If q is NaN, let t be +∞, else let t be max(q, 0) + +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +const RUNNING = 1; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + $262.agent.report(Atomics.wait(i64a, 0, 0n, NaN)); // NaN => +Infinity + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue(Atomics.notify(i64a, 0), 1, 'Atomics.notify(i64a, 0) returns 1'); +assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/negative-index-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/negative-index-throws.js new file mode 100644 index 0000000000..ce31bf301e --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/negative-index-throws.js @@ -0,0 +1,42 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a RangeError is index < 0 +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 2.Let i be ? ValidateAtomicAccess(typedArray, index). + ... + 2.Let accessIndex be ? ToIndex(requestIndex). + ... + 2.b If integerIndex < 0, throw a RangeError exception +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 8) +); +const poisoned = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(RangeError, function() { + Atomics.wait(i64a, -Infinity, poisoned, poisoned); +}, '`Atomics.wait(i64a, -Infinity, poisoned, poisoned)` throws RangeError'); +assert.throws(RangeError, function() { + Atomics.wait(i64a, -7.999, poisoned, poisoned); +}, '`Atomics.wait(i64a, -7.999, poisoned, poisoned)` throws RangeError'); +assert.throws(RangeError, function() { + Atomics.wait(i64a, -1, poisoned, poisoned); +}, '`Atomics.wait(i64a, -1, poisoned, poisoned)` throws RangeError'); +assert.throws(RangeError, function() { + Atomics.wait(i64a, -300, poisoned, poisoned); +}, '`Atomics.wait(i64a, -300, poisoned, poisoned)` throws RangeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/negative-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/negative-timeout-agent.js new file mode 100644 index 0000000000..752fc7f8fc --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/negative-timeout-agent.js @@ -0,0 +1,42 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Test that Atomics.wait times out with a negative timeout +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +const RUNNING = 1; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + $262.agent.report(Atomics.wait(i64a, 0, 0n, -5)); // -5 => 0 + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/negative-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/negative-timeout.js new file mode 100644 index 0000000000..e38b9381cc --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/negative-timeout.js @@ -0,0 +1,23 @@ +// |reftest| skip-if(!xulRuntime.shell||!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- browser cannot block main thread, Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Test that Atomics.wait times out with a negative timeout +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +flags: [CanBlockIsTrue] +---*/ + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +assert.sameValue( + Atomics.wait(i64a, 0, 0n, -1), + "timed-out", + 'Atomics.wait(i64a, 0, 0n, -1) returns "timed-out"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-no-operation.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-no-operation.js new file mode 100644 index 0000000000..01202a1efe --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-no-operation.js @@ -0,0 +1,62 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Test that Atomics.wait returns the right result when it timed out and that + the time to time out is reasonable. + info: | + 17. Let awoken be Suspend(WL, W, t). + 18. If awoken is true, then + a. Assert: W is not on the list of waiters in WL. + 19. Else, + a.Perform RemoveWaiter(WL, W). +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i64a, 0, 0n, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +// NO OPERATION OCCURS HERE! + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-add.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-add.js new file mode 100644 index 0000000000..b822c523d6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-add.js @@ -0,0 +1,57 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to Add operation +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i64a, 0, 0n, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.add(i64a, 0, 1n); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0'); + + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-and.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-and.js new file mode 100644 index 0000000000..e3d168a11b --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-and.js @@ -0,0 +1,57 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously nofity on index which is subject to And operation +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i64a, 0, 0n, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.and(i64a, 0, 1n); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0'); + + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-compareExchange.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-compareExchange.js new file mode 100644 index 0000000000..0ebe25cd3d --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-compareExchange.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to compareExchange operation +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i64a, 0, 0n, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.compareExchange(i64a, 0, 0n, 1n); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-exchange.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-exchange.js new file mode 100644 index 0000000000..f668ee3611 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-exchange.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to exchange operation +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i64a, 0, 0n, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.exchange(i64a, 0, 1n); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-or.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-or.js new file mode 100644 index 0000000000..6eebfce7c1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-or.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to Or operation +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i64a, 0, 0n, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.or(i64a, 0, 1n); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-store.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-store.js new file mode 100644 index 0000000000..3b3630f721 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-store.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Demonstrates that Atomics.store(...) is causing a waiting +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i64a, 0, 0n, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.store(i64a, 0, 0x111111n); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-sub.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-sub.js new file mode 100644 index 0000000000..0703e2e57e --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-sub.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to Sub operation +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i64a, 0, 0n, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.sub(i64a, 0, 1n); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-xor.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-xor.js new file mode 100644 index 0000000000..1d6f636d65 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-xor.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to xor operation +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i64a, 0, 0n, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.xor(i64a, 0, 1n); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i64a, 0), 0, 'Atomics.notify(i64a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/non-bigint64-typedarray-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/non-bigint64-typedarray-throws.js new file mode 100644 index 0000000000..9db40a9a65 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/non-bigint64-typedarray-throws.js @@ -0,0 +1,44 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-validatesharedintegertypedarray +description: > + Throws a TypeError if typedArray arg is not a BigInt64Array +info: | + Atomics.wait( 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", + throw a TypeError exception. + +features: [Atomics, BigInt, SharedArrayBuffer] +---*/ + +const i64a = new BigUint64Array( + new SharedArrayBuffer(BigUint64Array.BYTES_PER_ELEMENT) +); + +const poisoned = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, function() { + Atomics.wait(i64a, 0, 0n, 0); +}, '`Atomics.wait(i64a, 0, 0n, 0)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait(i64a, poisoned, poisoned, poisoned); +}, '`Atomics.wait(i64a, poisoned, poisoned, poisoned)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/non-shared-bufferdata-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/non-shared-bufferdata-throws.js new file mode 100644 index 0000000000..ec45720916 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/non-shared-bufferdata-throws.js @@ -0,0 +1,34 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if typedArray.buffer is not a SharedArrayBuffer +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 1.Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + ... + 9.If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception. + ... + 4.If bufferData is a Data Block, return false. +features: [ArrayBuffer, Atomics, BigInt, TypedArray] +---*/ +const i64a = new BigInt64Array(new ArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT)); + +const poisoned = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, function() { + Atomics.wait(i64a, 0, 0n, 0); +}, '`Atomics.wait(i64a, 0, 0n, 0)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait(i64a, poisoned, poisoned, poisoned); +}, '`Atomics.wait(i64a, poisoned, poisoned, poisoned)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/null-bufferdata-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/null-bufferdata-throws.js new file mode 100644 index 0000000000..9499b9f0e6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/null-bufferdata-throws.js @@ -0,0 +1,48 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.wait +description: > + A null value for bufferData throws a TypeError +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 1.Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + ... + + ValidateSharedIntegerTypedArray(typedArray [ , onlyInt32 ] ) + + ... + 9.If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception. + + + IsSharedArrayBuffer( obj ) + + ... + 3.If bufferData is null, return false. + +includes: [detachArrayBuffer.js] +features: [ArrayBuffer, Atomics, BigInt, TypedArray] +---*/ + +const i64a = new BigInt64Array( + new ArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); +const poisoned = { + valueOf: function() { + 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.wait(i64a, poisoned, poisoned, poisoned); +}, '`Atomics.wait(i64a, poisoned, poisoned, poisoned)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/out-of-range-index-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/out-of-range-index-throws.js new file mode 100644 index 0000000000..7bb3c5ec75 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/out-of-range-index-throws.js @@ -0,0 +1,40 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a RangeError if value of index arg is out of range +info: | + Atomics.wait( 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, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(RangeError, function() { + Atomics.wait(i64a, Infinity, poisoned, poisoned); +}, '`Atomics.wait(i64a, Infinity, poisoned, poisoned)` throws RangeError'); +assert.throws(RangeError, function() { + Atomics.wait(i64a, 8, poisoned, poisoned); +}, '`Atomics.wait(i64a, 8, poisoned, poisoned)` throws RangeError'); +assert.throws(RangeError, function() { + Atomics.wait(i64a, 200, poisoned, poisoned); +}, '`Atomics.wait(i64a, 200, poisoned, poisoned)` throws RangeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/shell.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/shell.js diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/value-not-equal.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/value-not-equal.js new file mode 100644 index 0000000000..a97cd35bcf --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/value-not-equal.js @@ -0,0 +1,62 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Returns "not-equal" when value arg does not match an index in the typedArray +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 3.Let v be ? ToBigInt64(value). + ... + 14.If v is not equal to w, then + a.Perform LeaveCriticalSection(WL). + b. Return the String "not-equal". + +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; +const value = "42n"; + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +$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, ${value})); + $262.agent.report(Atomics.wait(i64a, 0, 0n)); + $262.agent.leaving(); + }); +`); + +// NB: We don't actually explicitly need to wait for the agent to start in this +// test case, we only do it for consistency with other test cases which do +// require the main agent to wait and yield control. + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + '42', + '$262.agent.getReport() returns "42"' +); +assert.sameValue( + $262.agent.getReport(), + 'not-equal', + '$262.agent.getReport() returns "not-equal"' +); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/waiterlist-block-indexedposition-wake.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/waiterlist-block-indexedposition-wake.js new file mode 100644 index 0000000000..e1da72ccb0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/waiterlist-block-indexedposition-wake.js @@ -0,0 +1,78 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Get the correct WaiterList +info: | + Atomics.wait( typedArray, index, value, timeout ) + + ... + 11. Let WL be GetWaiterList(block, indexedPosition). + ... + + + GetWaiterList( block, i ) + + ... + 4. Return the WaiterList that is referenced by the pair (block, i). + +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +var NUMAGENT = 2; +var RUNNING = 4; + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 5) +); + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + // Wait on index 0 + $262.agent.report(Atomics.wait(i64a, 0, 0n, Infinity)); + $262.agent.leaving(); + }); +`); + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + // Wait on index 2 + $262.agent.report(Atomics.wait(i64a, 2, 0n, Infinity)); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); + +// Wait until all agents started. +$262.agent.waitUntil(i64a, RUNNING, BigInt(NUMAGENT)); + +// Notify index 1, notifies nothing +assert.sameValue(Atomics.notify(i64a, 1), 0, 'Atomics.notify(i64a, 1) returns 0'); + +// Notify index 3, notifies nothing +assert.sameValue(Atomics.notify(i64a, 3), 0, 'Atomics.notify(i64a, 3) returns 0'); + +// Notify index 2, notifies 1 +var woken = 0; +while ((woken = Atomics.notify(i64a, 2)) === 0) ; +assert.sameValue(woken, 1, 'Atomics.notify(i64a, 2) returns 1'); +assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"'); + +// Notify index 0, notifies 1 +var woken = 0; +while ((woken = Atomics.notify(i64a, 0)) === 0) ; +assert.sameValue(woken, 1, 'Atomics.notify(i64a, 0) returns 1'); +assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/waiterlist-order-of-operations-is-fifo.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/waiterlist-order-of-operations-is-fifo.js new file mode 100644 index 0000000000..f75888e49f --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/waiterlist-order-of-operations-is-fifo.js @@ -0,0 +1,95 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + New waiters should be applied to the end of the list and woken by order they entered the list (FIFO) +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 16.Perform AddWaiter(WL, W). + ... + 3.Add W to the end of the list of waiters in WL. + +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +var WAIT_INDEX = 0; +var RUNNING = 1; +var LOCK_INDEX = 2; +var NUMAGENT = 3; + +const i64a = new BigInt64Array( + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 4) +); + +for (var i = 0; i < NUMAGENT; i++) { + var agentNum = i; + + $262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + // Synchronize workers before reporting the initial report. + while (Atomics.compareExchange(i64a, ${LOCK_INDEX}, 0n, 1n) !== 0n) ; + + // Report the agent number before waiting. + $262.agent.report(${agentNum}); + + // Wait until restarted by main thread. + var status = Atomics.wait(i64a, ${WAIT_INDEX}, 0n); + + // Report wait status. + $262.agent.report(status); + + // Report the agent number after waiting. + $262.agent.report(${agentNum}); + + $262.agent.leaving(); + }); + `); +} + +$262.agent.safeBroadcast(i64a); + +// Wait until all agents started. +$262.agent.waitUntil(i64a, RUNNING, BigInt(NUMAGENT)); + +// Agents may be started in any order. +const started = []; +for (var i = 0; i < NUMAGENT; i++) { + // Wait until an agent entered its critical section. + $262.agent.waitUntil(i64a, LOCK_INDEX, 1n); + + // Record the agent number. + started.push($262.agent.getReport()); + + // The agent may have been interrupted between reporting its initial report + // and the `Atomics.wait` call. Try to yield control to ensure the agent + // actually started to wait. + $262.agent.tryYield(); + + // Now continue with the next agent. + Atomics.store(i64a, LOCK_INDEX, 0n); +} + +// Agents must notify in the order they waited. +for (var i = 0; i < NUMAGENT; i++) { + var woken = 0; + while ((woken = Atomics.notify(i64a, WAIT_INDEX, 1)) === 0) ; + + assert.sameValue(woken, 1, + 'Atomics.notify(i64a, WAIT_INDEX, 1) returns 1, at index = ' + i); + + assert.sameValue($262.agent.getReport(), 'ok', + '$262.agent.getReport() returns "ok", at index = ' + i); + + assert.sameValue($262.agent.getReport(), started[i], + '$262.agent.getReport() returns the value of `started[' + i + ']`'); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/bigint/was-woken-before-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/bigint/was-woken-before-timeout.js new file mode 100644 index 0000000000..438d9363d4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/bigint/was-woken-before-timeout.js @@ -0,0 +1,64 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.wait +description: > + Test that Atomics.wait returns the right result when it was awoken before + a timeout +info: | + Atomics.wait( 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. +includes: [atomicsHelper.js] +features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i64a = new BigInt64Array(sab); + Atomics.add(i64a, ${RUNNING}, 1n); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i64a, 0, 0n, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i64a); +$262.agent.waitUntil(i64a, RUNNING, 1n); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue(Atomics.notify(i64a, 0), 1, 'Atomics.notify(i64a, 0) returns 1'); + +const lapse = $262.agent.getReport(); + +assert( + lapse < TIMEOUT, + 'The result of `(lapse < TIMEOUT)` is true' +); +assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/browser.js b/js/src/tests/test262/built-ins/Atomics/wait/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/browser.js diff --git a/js/src/tests/test262/built-ins/Atomics/wait/cannot-suspend-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/cannot-suspend-throws.js new file mode 100644 index 0000000000..696a86fda4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/cannot-suspend-throws.js @@ -0,0 +1,30 @@ +// |reftest| skip-if(xulRuntime.shell||!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- shell can block main thread, Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Atomics.wait throws if agent cannot be suspended, CanBlock is false +info: | + Assuming [[CanBlock]] is false for the main host. + + Atomics.wait( typedArray, index, value, timeout ) + + ... (after args validation) + 6. Let B be AgentCanSuspend(). + 7. If B is false, throw a TypeError exception. + ... +features: [Atomics, SharedArrayBuffer, TypedArray] +flags: [CanBlockIsFalse] +---*/ + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +assert.throws(TypeError, function() { + Atomics.wait(i32a, 0, 0, 0); +}, '`Atomics.wait(i32a, 0, 0, 0)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/descriptor.js b/js/src/tests/test262/built-ins/Atomics/wait/descriptor.js new file mode 100644 index 0000000000..36a7db4989 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/descriptor.js @@ -0,0 +1,18 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: Testing descriptor property of Atomics.wait +includes: [propertyHelper.js] +features: [Atomics] +---*/ + +verifyProperty(Atomics, 'wait', { + enumerable: false, + writable: true, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/false-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/wait/false-for-timeout-agent.js new file mode 100644 index 0000000000..32966ed782 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/false-for-timeout-agent.js @@ -0,0 +1,78 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Boolean -> If argument is true, return 1. If argument is false, return +0. + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf: function() { + return false; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]: function() { + return false; + } + }; + + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const status1 = Atomics.wait(i32a, 0, 0, false); + const status2 = Atomics.wait(i32a, 0, 0, valueOf); + const status3 = Atomics.wait(i32a, 0, 0, toPrimitive); + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.report(status3); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); + +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/false-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/false-for-timeout.js new file mode 100644 index 0000000000..c107178601 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/false-for-timeout.js @@ -0,0 +1,50 @@ +// |reftest| skip-if(!xulRuntime.shell||!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- browser cannot block main thread, Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Boolean -> If argument is true, return 1. If argument is false, return +0. + +features: [Atomics, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +flags: [CanBlockIsTrue] +---*/ + +const i32a = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)); + +const valueOf = { + valueOf: function() { + return false; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]: function() { + return false; + } +}; + +assert.sameValue( + Atomics.wait(i32a, 0, 0, false), + 'timed-out', + 'Atomics.wait(i32a, 0, 0, false) returns "timed-out"' +); +assert.sameValue( + Atomics.wait(i32a, 0, 0, valueOf), + 'timed-out', + 'Atomics.wait(i32a, 0, 0, valueOf) returns "timed-out"' +); +assert.sameValue( + Atomics.wait(i32a, 0, 0, toPrimitive), + 'timed-out', + 'Atomics.wait(i32a, 0, 0, toPrimitive) returns "timed-out"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/good-views.js b/js/src/tests/test262/built-ins/Atomics/wait/good-views.js new file mode 100644 index 0000000000..67e4da6314 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/good-views.js @@ -0,0 +1,69 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Test Atomics.wait on arrays that allow atomic operations, + in an Agent that is allowed to wait. +includes: [atomicsHelper.js] +features: [Atomics] +---*/ + +// Let's assume 'wait' is not allowed on the main thread, +// even in the shell. + +$262.agent.start(` + var sab = new SharedArrayBuffer(1024); + var ab = new ArrayBuffer(16); + + 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 " + Atomics.wait(view, 0, 0, 0)) + $262.agent.report("B " + Atomics.wait(view, 0, 37, 0)); + + // 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); + $262.agent.report("C " + Atomics.wait(view, Idx, 0)); + } + + $262.agent.report("done"); + $262.agent.leaving(); +`); + +assert.sameValue( + $262.agent.getReport(), + 'A timed-out', + '$262.agent.getReport() returns "A timed-out"' +); + +assert.sameValue( + $262.agent.getReport(), + 'B not-equal', + '$262.agent.getReport() returns "B not-equal"' +); + +var r; +while ((r = $262.agent.getReport()) !== "done") { + assert.sameValue( + r, + 'C not-equal', + '$262.agent.getReport() returns "C not-equal"' + ); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/length.js b/js/src/tests/test262/built-ins/Atomics/wait/length.js new file mode 100644 index 0000000000..0cf786fa59 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/length.js @@ -0,0 +1,35 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2015 André Bargull. All rights reserved. +// Copyright (C) 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Atomics.wait.length is 4. +info: | + Atomics.wait ( 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] +---*/ + +verifyProperty(Atomics.wait, 'length', { + value: 4, + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/name.js b/js/src/tests/test262/built-ins/Atomics/wait/name.js new file mode 100644 index 0000000000..b9a8813627 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/name.js @@ -0,0 +1,21 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2015 André Bargull. All rights reserved. +// Copyright (C) 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Atomics.wait.name is "wait". +includes: [propertyHelper.js] +features: [Atomics] +---*/ + +verifyProperty(Atomics.wait, 'name', { + value: 'wait', + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/nan-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/nan-for-timeout.js new file mode 100644 index 0000000000..373083aa5a --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/nan-for-timeout.js @@ -0,0 +1,46 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + NaN timeout arg should result in an infinite timeout +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4.Let q be ? ToNumber(timeout). + ... + Undefined Return NaN. + 5.If q is NaN, let t be +∞, else let t be max(q, 0) + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + $262.agent.report(Atomics.wait(i32a, 0, 0, NaN)); // NaN => +Infinity + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue(Atomics.notify(i32a, 0), 1, 'Atomics.notify(i32a, 0) returns 1'); +assert.sameValue($262.agent.getReport(), "ok", '$262.agent.getReport() returns "ok"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/negative-index-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/negative-index-throws.js new file mode 100644 index 0000000000..b7562dd0fd --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/negative-index-throws.js @@ -0,0 +1,44 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a RangeError is index < 0 +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 2.Let i be ? ValidateAtomicAccess(typedArray, index). + ... + 2.Let accessIndex be ? ToIndex(requestIndex). + ... + 2.b If integerIndex < 0, throw a RangeError exception + +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(RangeError, function() { + Atomics.wait(i32a, -Infinity, poisoned, poisoned); +}, '`Atomics.wait(i32a, -Infinity, poisoned, poisoned)` throws RangeError'); +assert.throws(RangeError, function() { + Atomics.wait(i32a, -7.999, poisoned, poisoned); +}, '`Atomics.wait(i32a, -7.999, poisoned, poisoned)` throws RangeError'); +assert.throws(RangeError, function() { + Atomics.wait(i32a, -1, poisoned, poisoned); +}, '`Atomics.wait(i32a, -1, poisoned, poisoned)` throws RangeError'); +assert.throws(RangeError, function() { + Atomics.wait(i32a, -300, poisoned, poisoned); +}, '`Atomics.wait(i32a, -300, poisoned, poisoned)` throws RangeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/negative-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/wait/negative-timeout-agent.js new file mode 100644 index 0000000000..1bed54bd71 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/negative-timeout-agent.js @@ -0,0 +1,42 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Test that Atomics.wait times out with a negative timeout +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + var i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + $262.agent.report(Atomics.wait(i32a, 0, 0, -5)); // -5 => 0 + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/negative-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/negative-timeout.js new file mode 100644 index 0000000000..299f4d307f --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/negative-timeout.js @@ -0,0 +1,23 @@ +// |reftest| skip-if(!xulRuntime.shell||!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- browser cannot block main thread, Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Test that Atomics.wait times out with a negative timeout +features: [Atomics, SharedArrayBuffer, TypedArray] +flags: [CanBlockIsTrue] +---*/ + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +assert.sameValue( + Atomics.wait(i32a, 0, 0, -1), + "timed-out", + 'Atomics.wait(i32a, 0, 0, -1) returns "timed-out"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-no-operation.js b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-no-operation.js new file mode 100644 index 0000000000..082d1f26dd --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-no-operation.js @@ -0,0 +1,62 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Test that Atomics.wait returns the right result when it timed out and that + the time to time out is reasonable. + info: | + 17. Let awoken be Suspend(WL, W, t). + 18. If awoken is true, then + a. Assert: W is not on the list of waiters in WL. + 19. Else, + a.Perform RemoveWaiter(WL, W). +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i32a, 0, 0, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +// NO OPERATION OCCURS HERE! + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-add.js b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-add.js new file mode 100644 index 0000000000..27a2914b2e --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-add.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to Add operation +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i32a, 0, 0, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.add(i32a, 0, 1); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-and.js b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-and.js new file mode 100644 index 0000000000..13dfa1cfb7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-and.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to And operation +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i32a, 0, 0, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.and(i32a, 0, 1); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-compareExchange.js b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-compareExchange.js new file mode 100644 index 0000000000..1da28e628f --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-compareExchange.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to compareExchange operation +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i32a, 0, 0, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.compareExchange(i32a, 0, 0, 1); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-exchange.js b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-exchange.js new file mode 100644 index 0000000000..88793bf8ef --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-exchange.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to exchange operation +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i32a, 0, 0, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.exchange(i32a, 0, 1); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-or.js b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-or.js new file mode 100644 index 0000000000..6b457df301 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-or.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to Or operation +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i32a, 0, 0, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.or(i32a, 0, 1); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-store.js b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-store.js new file mode 100644 index 0000000000..0ab8075e14 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-store.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to Store operation +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i32a, 0, 0, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.store(i32a, 0, 0x111111); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-sub.js b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-sub.js new file mode 100644 index 0000000000..24bc5127eb --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-sub.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to Sub operation +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i32a, 0, 0, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.sub(i32a, 0, 1); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-xor.js b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-xor.js new file mode 100644 index 0000000000..0d0802c42c --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/no-spurious-wakeup-on-xor.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Waiter does not spuriously notify on index which is subject to xor operation +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +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(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i32a, 0, 0, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +Atomics.xor(i32a, 0, 1); + +const lapse = $262.agent.getReport(); +assert( + lapse >= TIMEOUT, + 'The result of `(lapse >= TIMEOUT)` is true' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/non-int32-typedarray-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/non-int32-typedarray-throws.js new file mode 100644 index 0000000000..7ff12e1357 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/non-int32-typedarray-throws.js @@ -0,0 +1,81 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if typedArray arg is not an Int32Array +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 1.Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + ... + 5.If onlyInt32 is true, then + If typeName is not "Int32Array", throw a TypeError exception. +features: [Atomics, Float32Array, Float64Array, Int8Array, TypedArray, Uint16Array, Uint8Array, Uint8ClampedArray] +---*/ + +const poisoned = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, function() { + const view = new Float64Array( + new SharedArrayBuffer(Float64Array.BYTES_PER_ELEMENT * 8) + ); + Atomics.wait(view, poisoned, poisoned, poisoned); +}, '`const view = new Float64Array( new SharedArrayBuffer(Float64Array.BYTES_PER_ELEMENT * 8) ); Atomics.wait(view, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + const view = new Float32Array( + new SharedArrayBuffer(Float32Array.BYTES_PER_ELEMENT * 4) + ); + Atomics.wait(view, poisoned, poisoned, poisoned); +}, '`const view = new Float32Array( new SharedArrayBuffer(Float32Array.BYTES_PER_ELEMENT * 4) ); Atomics.wait(view, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + const view = new Int16Array( + new SharedArrayBuffer(Int16Array.BYTES_PER_ELEMENT * 2) + ); + Atomics.wait(view, poisoned, poisoned, poisoned); +}, '`const view = new Int16Array( new SharedArrayBuffer(Int16Array.BYTES_PER_ELEMENT * 2) ); Atomics.wait(view, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + const view = new Int8Array( + new SharedArrayBuffer(Int8Array.BYTES_PER_ELEMENT) + ); + Atomics.wait(view, poisoned, poisoned, poisoned); +}, '`const view = new Int8Array( new SharedArrayBuffer(Int8Array.BYTES_PER_ELEMENT) ); Atomics.wait(view, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + const view = new Uint32Array( + new SharedArrayBuffer(Uint32Array.BYTES_PER_ELEMENT * 4) + ); + Atomics.wait(view, poisoned, poisoned, poisoned); +}, '`const view = new Uint32Array( new SharedArrayBuffer(Uint32Array.BYTES_PER_ELEMENT * 4) ); Atomics.wait(view, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + const view = new Uint16Array( + new SharedArrayBuffer(Uint16Array.BYTES_PER_ELEMENT * 2) + ); + Atomics.wait(view, poisoned, poisoned, poisoned); +}, '`const view = new Uint16Array( new SharedArrayBuffer(Uint16Array.BYTES_PER_ELEMENT * 2) ); Atomics.wait(view, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + const view = new Uint8Array( + new SharedArrayBuffer(Uint8Array.BYTES_PER_ELEMENT) + ); + Atomics.wait(view, poisoned, poisoned, poisoned); +}, '`const view = new Uint8Array( new SharedArrayBuffer(Uint8Array.BYTES_PER_ELEMENT) ); Atomics.wait(view, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + const view = new Uint8ClampedArray( + new SharedArrayBuffer(Uint8ClampedArray.BYTES_PER_ELEMENT) + ); + Atomics.wait(view, poisoned, poisoned, poisoned); +}, '`const view = new Uint8ClampedArray( new SharedArrayBuffer(Uint8ClampedArray.BYTES_PER_ELEMENT) ); Atomics.wait(view, poisoned, poisoned, poisoned)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/non-shared-bufferdata-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/non-shared-bufferdata-throws.js new file mode 100644 index 0000000000..dcee5b7c34 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/non-shared-bufferdata-throws.js @@ -0,0 +1,37 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if typedArray.buffer is not a SharedArrayBuffer +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 1.Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + ... + 9.If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception. + ... + 4.If bufferData is a Data Block, return false. +features: [ArrayBuffer, Atomics, TypedArray] +---*/ + +const i32a = new Int32Array( + new ArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, function() { + Atomics.wait(i32a, 0, 0, 0); +}, '`Atomics.wait(i32a, 0, 0, 0)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait(i32a, poisoned, poisoned, poisoned); +}, '`Atomics.wait(i32a, poisoned, poisoned, poisoned)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/not-a-typedarray-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/not-a-typedarray-throws.js new file mode 100644 index 0000000000..484d1affec --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/not-a-typedarray-throws.js @@ -0,0 +1,32 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if the typedArray arg is not a TypedArray object +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 1.Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + ... + 3.If typedArray does not have a [[TypedArrayName]] internal slot, throw a TypeError exception. + +features: [Atomics] +---*/ + +var poisoned = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, function() { + Atomics.wait({}, 0, 0, 0); +}, '`Atomics.wait({}, 0, 0, 0)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait({}, poisoned, poisoned, poisoned); +}, '`Atomics.wait({}, poisoned, poisoned, poisoned)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/not-an-object-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/not-an-object-throws.js new file mode 100644 index 0000000000..64ce6c2277 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/not-an-object-throws.js @@ -0,0 +1,51 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if typedArray arg is not an Object +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 1.Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + ... + 2. if Type(typedArray) is not Object, throw a TypeError exception +features: [Atomics, Symbol] +---*/ + +var poisoned = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(TypeError, function() { + Atomics.wait(null, poisoned, poisoned, poisoned); +}, '`Atomics.wait(null, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait(undefined, poisoned, poisoned, poisoned); +}, '`Atomics.wait(undefined, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait(true, poisoned, poisoned, poisoned); +}, '`Atomics.wait(true, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait(false, poisoned, poisoned, poisoned); +}, '`Atomics.wait(false, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait('***string***', poisoned, poisoned, poisoned); +}, '`Atomics.wait(\'***string***\', poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait(Number.NEGATIVE_INFINITY, poisoned, poisoned, poisoned); +}, '`Atomics.wait(Number.NEGATIVE_INFINITY, poisoned, poisoned, poisoned)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait(Symbol('***symbol***'), poisoned, poisoned, poisoned); +}, '`Atomics.wait(Symbol(\'***symbol***\'), poisoned, poisoned, poisoned)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/null-bufferdata-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/null-bufferdata-throws.js new file mode 100644 index 0000000000..0b8ab82185 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/null-bufferdata-throws.js @@ -0,0 +1,46 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.wait +description: > + A null value for bufferData (detached) throws a TypeError +info: | + Atomics.wait( typedArray, index, value, timeout ) + + Let buffer be ? ValidateIntegerTypedArray(typedArray, true). + ... + + Let buffer be ? ValidateTypedArray(typedArray). + ... + + If IsDetachedBuffer(buffer) is true, throw a TypeError exception. + ... + + If arrayBuffer.[[ArrayBufferData]] is null, return true. + +includes: [detachArrayBuffer.js] +features: [ArrayBuffer, Atomics, TypedArray] +---*/ + +const i32a = new Int32Array( + new ArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf: function() { + 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.wait(i32a, poisoned, poisoned, poisoned); +}, '`Atomics.wait(i32a, poisoned, poisoned, poisoned)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/null-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/wait/null-for-timeout-agent.js new file mode 100644 index 0000000000..a2cd76790a --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/null-for-timeout-agent.js @@ -0,0 +1,78 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Null -> Return +0. + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf: function() { + return null; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]: function() { + return null; + } + }; + + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const status1 = Atomics.wait(i32a, 0, 0, null); + const status2 = Atomics.wait(i32a, 0, 0, valueOf); + const status3 = Atomics.wait(i32a, 0, 0, toPrimitive); + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.report(status3); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); + +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/null-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/null-for-timeout.js new file mode 100644 index 0000000000..a336e07a7e --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/null-for-timeout.js @@ -0,0 +1,52 @@ +// |reftest| skip-if(!xulRuntime.shell||!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- browser cannot block main thread, Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Null -> Return +0. + +features: [Atomics, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +flags: [CanBlockIsTrue] +---*/ + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const valueOf = { + valueOf: function() { + return null; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]: function() { + return null; + } +}; + +assert.sameValue( + Atomics.wait(i32a, 0, 0, null), + "timed-out", + 'Atomics.wait(i32a, 0, 0, null) returns "timed-out"' +); +assert.sameValue( + Atomics.wait(i32a, 0, 0, valueOf), + "timed-out", + 'Atomics.wait(i32a, 0, 0, valueOf) returns "timed-out"' +); +assert.sameValue( + Atomics.wait(i32a, 0, 0, toPrimitive), + "timed-out", + 'Atomics.wait(i32a, 0, 0, toPrimitive) returns "timed-out"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/object-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/wait/object-for-timeout-agent.js new file mode 100644 index 0000000000..90ecd630e0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/object-for-timeout-agent.js @@ -0,0 +1,84 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Null -> Return +0. + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf: function() { + return 0; + } + }; + + const toString = { + toString: function() { + return "0"; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]: function() { + return 0; + } + }; + + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const status1 = Atomics.wait(i32a, 0, 0, valueOf); + const status2 = Atomics.wait(i32a, 0, 0, toString); + const status3 = Atomics.wait(i32a, 0, 0, toPrimitive); + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.report(status3); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); + +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/object-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/object-for-timeout.js new file mode 100644 index 0000000000..14c99ff248 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/object-for-timeout.js @@ -0,0 +1,61 @@ +// |reftest| skip-if(!xulRuntime.shell||!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- browser cannot block main thread, Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Object -> Apply the following steps: + + Let primValue be ? ToPrimitive(argument, hint Number). + Return ? ToNumber(primValue). + +features: [Atomics, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +flags: [CanBlockIsTrue] +---*/ + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const valueOf = { + valueOf: function() { + return 0; + } +}; + +const toString = { + toString: function() { + return "0"; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]: function() { + return 0; + } +}; + +assert.sameValue( + Atomics.wait(i32a, 0, 0, valueOf), + 'timed-out', + 'Atomics.wait(i32a, 0, 0, valueOf) returns "timed-out"' +); +assert.sameValue( + Atomics.wait(i32a, 0, 0, toString), + 'timed-out', + 'Atomics.wait(i32a, 0, 0, toString) returns "timed-out"' +); +assert.sameValue( + Atomics.wait(i32a, 0, 0, toPrimitive), + 'timed-out', + 'Atomics.wait(i32a, 0, 0, toPrimitive) returns "timed-out"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/out-of-range-index-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/out-of-range-index-throws.js new file mode 100644 index 0000000000..d2dd3da578 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/out-of-range-index-throws.js @@ -0,0 +1,43 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a RangeError if value of index arg is out of range +info: | + Atomics.wait( 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, SharedArrayBuffer, TypedArray] +---*/ + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisoned = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(RangeError, function() { + Atomics.wait(i32a, Infinity, poisoned, poisoned); +}, '`Atomics.wait(i32a, Infinity, poisoned, poisoned)` throws RangeError'); +assert.throws(RangeError, function() { + Atomics.wait(i32a, -1, poisoned, poisoned); +}, '`Atomics.wait(i32a, -1, poisoned, poisoned)` throws RangeError'); +assert.throws(RangeError, function() { + Atomics.wait(i32a, 4, poisoned, poisoned); +}, '`Atomics.wait(i32a, 4, poisoned, poisoned)` throws RangeError'); +assert.throws(RangeError, function() { + Atomics.wait(i32a, 200, poisoned, poisoned); +}, '`Atomics.wait(i32a, 200, poisoned, poisoned)` throws RangeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/poisoned-object-for-timeout-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/wait/poisoned-object-for-timeout-throws-agent.js new file mode 100644 index 0000000000..ae1882d4a1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/poisoned-object-for-timeout-throws-agent.js @@ -0,0 +1,82 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + False timeout arg should result in an +0 timeout +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Null -> Return +0. + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; + +$262.agent.start(` + const poisonedValueOf = { + valueOf: function() { + throw new Error("should not evaluate this code"); + } + }; + + const poisonedToPrimitive = { + [Symbol.toPrimitive]: function() { + 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.wait(i32a, 0, 0, poisonedValueOf); + } catch (error) { + status1 = "poisonedValueOf"; + } + try { + Atomics.wait(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.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'poisonedValueOf', + '$262.agent.getReport() returns "poisonedValueOf"' +); +assert.sameValue( + $262.agent.getReport(), + 'poisonedToPrimitive', + '$262.agent.getReport() returns "poisonedToPrimitive"' +); + +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/poisoned-object-for-timeout-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/poisoned-object-for-timeout-throws.js new file mode 100644 index 0000000000..cffe81af60 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/poisoned-object-for-timeout-throws.js @@ -0,0 +1,46 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Object -> Apply the following steps: + + Let primValue be ? ToPrimitive(argument, hint Number). + Return ? ToNumber(primValue). + +features: [Atomics, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +---*/ + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +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"); + } +}; + +assert.throws(Test262Error, function() { + Atomics.wait(i32a, 0, 0, poisonedValueOf); +}, '`Atomics.wait(i32a, 0, 0, poisonedValueOf)` throws Test262Error'); + +assert.throws(Test262Error, function() { + Atomics.wait(i32a, 0, 0, poisonedToPrimitive); +}, '`Atomics.wait(i32a, 0, 0, poisonedToPrimitive)` throws Test262Error'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/shell.js b/js/src/tests/test262/built-ins/Atomics/wait/shell.js new file mode 100644 index 0000000000..c55dbb8399 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/shell.js @@ -0,0 +1,344 @@ +// GENERATED, DO NOT EDIT +// 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/wait/symbol-for-index-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-index-throws-agent.js new file mode 100644 index 0000000000..771b497c4e --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-index-throws-agent.js @@ -0,0 +1,95 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.wait( 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. + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +---*/ + +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.wait(i32a, Symbol("1"), poisonedValueOf, poisonedValueOf); + } catch (error) { + status1 = 'Symbol("1")'; + } + try { + Atomics.wait(i32a, Symbol("2"), poisonedToPrimitive, poisonedToPrimitive); + } catch (error) { + status2 = 'Symbol("2")'; + } + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'Symbol("1")', + '$262.agent.getReport() returns "Symbol("1")"' +); +assert.sameValue( + $262.agent.getReport(), + 'Symbol("2")', + '$262.agent.getReport() returns "Symbol("2")"' +); + +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-index-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-index-throws.js new file mode 100644 index 0000000000..d5f12ffbdf --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-index-throws.js @@ -0,0 +1,64 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.wait( 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, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +---*/ + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const poisonedValueOf = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +const poisonedToPrimitive = { + [Symbol.toPrimitive]: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +assert.throws(Test262Error, function() { + Atomics.wait(i32a, poisonedValueOf, poisonedValueOf, poisonedValueOf); +}, '`Atomics.wait(i32a, poisonedValueOf, poisonedValueOf, poisonedValueOf)` throws Test262Error'); + +assert.throws(Test262Error, function() { + Atomics.wait(i32a, poisonedToPrimitive, poisonedToPrimitive, poisonedToPrimitive); +}, '`Atomics.wait(i32a, poisonedToPrimitive, poisonedToPrimitive, poisonedToPrimitive)` throws Test262Error'); + +assert.throws(TypeError, function() { + Atomics.wait(i32a, Symbol('foo'), poisonedValueOf, poisonedValueOf); +}, '`Atomics.wait(i32a, Symbol(\'foo\'), poisonedValueOf, poisonedValueOf)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait(i32a, Symbol('foo'), poisonedToPrimitive, poisonedToPrimitive); +}, '`Atomics.wait(i32a, Symbol(\'foo\'), poisonedToPrimitive, poisonedToPrimitive)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-timeout-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-timeout-throws-agent.js new file mode 100644 index 0000000000..d30d0f0488 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-timeout-throws-agent.js @@ -0,0 +1,70 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Symbol --> Throw a TypeError exception. + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +---*/ + +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.wait(i32a, 0, 0, Symbol("1")); + } catch (error) { + status1 = 'Symbol("1")'; + } + try { + Atomics.wait(i32a, 0, 0, Symbol("2")); + } catch (error) { + status2 = 'Symbol("2")'; + } + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'Symbol("1")', + '$262.agent.getReport() returns "Symbol("1")"' +); +assert.sameValue( + $262.agent.getReport(), + 'Symbol("2")', + '$262.agent.getReport() returns "Symbol("2")"' +); + +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-timeout-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-timeout-throws.js new file mode 100644 index 0000000000..a6be3df183 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-timeout-throws.js @@ -0,0 +1,50 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Symbol --> Throw a TypeError exception. + +features: [Atomics, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +---*/ + +var buffer = new SharedArrayBuffer(1024); +var i32a = new Int32Array(buffer); + +var poisonedValueOf = { + valueOf: function() { + throw new Test262Error('should not evaluate this code'); + } +}; + +var poisonedToPrimitive = { + [Symbol.toPrimitive]: function() { + throw new Test262Error('passing a poisoned object using @@ToPrimitive'); + } +}; + +assert.throws(Test262Error, function() { + Atomics.wait(i32a, 0, 0, poisonedValueOf); +}, '`Atomics.wait(i32a, 0, 0, poisonedValueOf)` throws Test262Error'); + +assert.throws(Test262Error, function() { + Atomics.wait(i32a, 0, 0, poisonedToPrimitive); +}, '`Atomics.wait(i32a, 0, 0, poisonedToPrimitive)` throws Test262Error'); + +assert.throws(TypeError, function() { + Atomics.wait(i32a, 0, 0, Symbol("foo")); +}, '`Atomics.wait(i32a, 0, 0, Symbol("foo"))` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait(i32a, 0, 0, Symbol("foo")); +}, '`Atomics.wait(i32a, 0, 0, Symbol("foo"))` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-value-throws-agent.js b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-value-throws-agent.js new file mode 100644 index 0000000000..5491987f91 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-value-throws-agent.js @@ -0,0 +1,86 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if value arg is a Symbol +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 3. Let v be ? ToInt32(value). + + ToInt32(value) + + 1.Let number be ? ToNumber(argument). + + Symbol --> Throw a TypeError exception. + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +---*/ + +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.wait(i32a, 0, Symbol("1"), poisonedValueOf); + } catch (error) { + status1 = 'Symbol("1")'; + } + try { + Atomics.wait(i32a, 0, Symbol("2"), poisonedToPrimitive); + } catch (error) { + status2 = 'Symbol("2")'; + } + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'Symbol("1")', + '$262.agent.getReport() returns "Symbol("1")"' +); +assert.sameValue( + $262.agent.getReport(), + 'Symbol("2")', + '$262.agent.getReport() returns "Symbol("2")"' +); + +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-value-throws.js b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-value-throws.js new file mode 100644 index 0000000000..52a0bbfbf0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/symbol-for-value-throws.js @@ -0,0 +1,55 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if value arg is a Symbol +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 3. Let v be ? ToInt32(value). + + ToInt32(value) + + 1.Let number be ? ToNumber(argument). + + Symbol --> Throw a TypeError exception. + +features: [Atomics, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +---*/ + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +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"); + } +}; + +assert.throws(Test262Error, function() { + Atomics.wait(i32a, 0, poisonedValueOf, poisonedValueOf); +}, '`Atomics.wait(i32a, 0, poisonedValueOf, poisonedValueOf)` throws Test262Error'); + +assert.throws(Test262Error, function() { + Atomics.wait(i32a, 0, poisonedToPrimitive, poisonedToPrimitive); +}, '`Atomics.wait(i32a, 0, poisonedToPrimitive, poisonedToPrimitive)` throws Test262Error'); + +assert.throws(TypeError, function() { + Atomics.wait(i32a, 0, Symbol("foo"), poisonedValueOf); +}, '`Atomics.wait(i32a, 0, Symbol("foo"), poisonedValueOf)` throws TypeError'); + +assert.throws(TypeError, function() { + Atomics.wait(i32a, 0, Symbol("foo"), poisonedToPrimitive); +}, '`Atomics.wait(i32a, 0, Symbol("foo"), poisonedToPrimitive)` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/true-for-timeout-agent.js b/js/src/tests/test262/built-ins/Atomics/wait/true-for-timeout-agent.js new file mode 100644 index 0000000000..383815abc1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/true-for-timeout-agent.js @@ -0,0 +1,78 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + True timeout arg should result in an +0 timeout +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Boolean -> If argument is true, return 1. If argument is false, return +0. + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; + +$262.agent.start(` + const valueOf = { + valueOf: function() { + return true; + } + }; + + const toPrimitive = { + [Symbol.toPrimitive]: function() { + return true; + } + }; + + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const status1 = Atomics.wait(i32a, 0, 0, true); + const status2 = Atomics.wait(i32a, 0, 0, valueOf); + const status3 = Atomics.wait(i32a, 0, 0, toPrimitive); + + $262.agent.report(status1); + $262.agent.report(status2); + $262.agent.report(status3); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); +assert.sameValue( + $262.agent.getReport(), + 'timed-out', + '$262.agent.getReport() returns "timed-out"' +); + +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/true-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/true-for-timeout.js new file mode 100644 index 0000000000..3dbc97048a --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/true-for-timeout.js @@ -0,0 +1,52 @@ +// |reftest| skip-if(!xulRuntime.shell||!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- browser cannot block main thread, Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Throws a TypeError if index arg can not be converted to an Integer +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4. Let q be ? ToNumber(timeout). + + Boolean -> If argument is true, return 1. If argument is false, return +0. + +features: [Atomics, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray] +flags: [CanBlockIsTrue] +---*/ + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +const valueOf = { + valueOf: function() { + return true; + } +}; + +const toPrimitive = { + [Symbol.toPrimitive]: function() { + return true; + } +}; + +assert.sameValue( + Atomics.wait(i32a, 0, 0, true), + 'timed-out', + 'Atomics.wait(i32a, 0, 0, true) returns "timed-out"' +); +assert.sameValue( + Atomics.wait(i32a, 0, 0, valueOf), + 'timed-out', + 'Atomics.wait(i32a, 0, 0, valueOf) returns "timed-out"' +); +assert.sameValue( + Atomics.wait(i32a, 0, 0, toPrimitive), + 'timed-out', + 'Atomics.wait(i32a, 0, 0, toPrimitive) returns "timed-out"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/undefined-for-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/undefined-for-timeout.js new file mode 100644 index 0000000000..834b962422 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/undefined-for-timeout.js @@ -0,0 +1,73 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Undefined timeout arg should result in an infinite timeout +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 4.Let q be ? ToNumber(timeout). + ... + Undefined Return NaN. + 5.If q is NaN, let t be +∞, else let t be max(q, 0) + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const WAIT_INDEX = 0; // Index all agents are waiting on +const RUNNING = 1; +const NUMAGENT = 2; // Total number of agents started +const NOTIFYCOUNT = 2; // Total number of agents to notify up + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + var i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + // undefined => NaN => +Infinity + $262.agent.report("A " + Atomics.wait(i32a, 0, 0, undefined)); + $262.agent.leaving(); + }); +`); + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + var i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + // undefined timeout arg => NaN => +Infinity + $262.agent.report("B " + Atomics.wait(i32a, 0, 0)); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, NUMAGENT); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + Atomics.notify(i32a, WAIT_INDEX, NOTIFYCOUNT), + NOTIFYCOUNT, + 'Atomics.notify(i32a, WAIT_INDEX, NOTIFYCOUNT) returns the value of `NOTIFYCOUNT` (2)' +); + +const reports = []; +for (var i = 0; i < NUMAGENT; i++) { + reports.push($262.agent.getReport()); +} +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"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/undefined-index-defaults-to-zero.js b/js/src/tests/test262/built-ins/Atomics/wait/undefined-index-defaults-to-zero.js new file mode 100644 index 0000000000..3ea0dcc133 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/undefined-index-defaults-to-zero.js @@ -0,0 +1,53 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.wait +description: > + An undefined index arg should translate to 0 +info: | + Atomics.wait( 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. + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.long; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + $262.agent.report(Atomics.wait(i32a, undefined, 0, ${TIMEOUT})); // undefined index => 0 + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue(Atomics.notify(i32a, 0), 1, 'Atomics.notify(i32a, 0) returns 1'); // notify at index 0 +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); // notify again at index 0, and 0 agents should be woken +assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/validate-arraytype-before-index-coercion.js b/js/src/tests/test262/built-ins/Atomics/wait/validate-arraytype-before-index-coercion.js new file mode 100644 index 0000000000..313d965bec --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/validate-arraytype-before-index-coercion.js @@ -0,0 +1,44 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2019 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + TypedArray type is validated before `index` argument is coerced. +info: | + 24.4.11 Atomics.wait ( typedArray, index, value, timeout ) + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + ... + + 24.4.1.1 ValidateSharedIntegerTypedArray ( typedArray [ , onlyInt32 ] ) + ... + 4. Let typeName be typedArray.[[TypedArrayName]]. + 5. If onlyInt32 is true, then + a. If typeName is not "Int32Array", throw a TypeError exception. + 6. Else, + a. If typeName is not "Int8Array", "Uint8Array", "Int16Array", "Uint16Array", "Int32Array", + or "Uint32Array", throw a TypeError exception. + ... +features: [Atomics] +---*/ + +var index = { + valueOf() { + throw new Test262Error("index coerced"); + } +}; + +var badArrayTypes = [ + Int8Array, Uint8Array, Int16Array, Uint16Array, Uint32Array, + Uint8ClampedArray, Float32Array, Float64Array +]; + +for (var badArrayType of badArrayTypes) { + var typedArray = new badArrayType(new SharedArrayBuffer(8)); + assert.throws(TypeError, function() { + Atomics.wait(typedArray, index, 0, 0); + }); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/validate-arraytype-before-timeout-coercion.js b/js/src/tests/test262/built-ins/Atomics/wait/validate-arraytype-before-timeout-coercion.js new file mode 100644 index 0000000000..bed63347e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/validate-arraytype-before-timeout-coercion.js @@ -0,0 +1,44 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2019 André Bargull. 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 `timeout` argument is coerced. +info: | + 24.4.11 Atomics.wait ( typedArray, index, value, timeout ) + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + ... + + 24.4.1.1 ValidateSharedIntegerTypedArray ( typedArray [ , onlyInt32 ] ) + ... + 4. Let typeName be typedArray.[[TypedArrayName]]. + 5. If onlyInt32 is true, then + a. If typeName is not "Int32Array", throw a TypeError exception. + 6. Else, + a. If typeName is not "Int8Array", "Uint8Array", "Int16Array", "Uint16Array", "Int32Array", + or "Uint32Array", throw a TypeError exception. + ... +features: [Atomics] +---*/ + +var timeout = { + valueOf() { + throw new Test262Error("timeout coerced"); + } +}; + +var badArrayTypes = [ + Int8Array, Uint8Array, Int16Array, Uint16Array, Uint32Array, + Uint8ClampedArray, Float32Array, Float64Array +]; + +for (var badArrayType of badArrayTypes) { + var typedArray = new badArrayType(new SharedArrayBuffer(8)); + assert.throws(TypeError, function() { + Atomics.wait(typedArray, 0, 0, timeout); + }); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/validate-arraytype-before-value-coercion.js b/js/src/tests/test262/built-ins/Atomics/wait/validate-arraytype-before-value-coercion.js new file mode 100644 index 0000000000..6b2a6547a7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/validate-arraytype-before-value-coercion.js @@ -0,0 +1,44 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')) -- Atomics is not enabled unconditionally +// Copyright (C) 2019 André Bargull. 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: | + 24.4.11 Atomics.wait ( typedArray, index, value, timeout ) + 1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true). + ... + + 24.4.1.1 ValidateSharedIntegerTypedArray ( typedArray [ , onlyInt32 ] ) + ... + 4. Let typeName be typedArray.[[TypedArrayName]]. + 5. If onlyInt32 is true, then + a. If typeName is not "Int32Array", throw a TypeError exception. + 6. Else, + a. If typeName is not "Int8Array", "Uint8Array", "Int16Array", "Uint16Array", "Int32Array", + or "Uint32Array", throw a TypeError exception. + ... +features: [Atomics] +---*/ + +var value = { + valueOf() { + throw new Test262Error("value coerced"); + } +}; + +var badArrayTypes = [ + Int8Array, Uint8Array, Int16Array, Uint16Array, Uint32Array, + Uint8ClampedArray, Float32Array, Float64Array +]; + +for (var badArrayType of badArrayTypes) { + var typedArray = new badArrayType(new SharedArrayBuffer(8)); + assert.throws(TypeError, function() { + Atomics.wait(typedArray, 0, value, 0); + }); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/value-not-equal.js b/js/src/tests/test262/built-ins/Atomics/wait/value-not-equal.js new file mode 100644 index 0000000000..e5ecb4a34b --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/value-not-equal.js @@ -0,0 +1,62 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Returns "not-equal" when value arg does not match an index in the typedArray +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 3.Let v be ? ToInt32(value). + ... + 14.If v is not equal to w, then + a.Perform LeaveCriticalSection(WL). + b. Return the String "not-equal". + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; + +var 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.wait(i32a, 0, 0)); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +// NB: We don't actually explicitly need to wait for the agent to start in this +// test case, we only do it for consistency with other test cases which do +// require the main agent to wait and yield control. + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + value.toString(), + '$262.agent.getReport() returns value.toString()' +); +assert.sameValue( + $262.agent.getReport(), + 'not-equal', + '$262.agent.getReport() returns "not-equal"' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/wait-index-value-not-equal.js b/js/src/tests/test262/built-ins/Atomics/wait/wait-index-value-not-equal.js new file mode 100644 index 0000000000..1947cd6a93 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/wait-index-value-not-equal.js @@ -0,0 +1,60 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Returns "not-equal" when value of index is not equal +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 14.If v is not equal to w, then + a.Perform LeaveCriticalSection(WL). + b. Return the String "not-equal". + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.small; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + $262.agent.report(Atomics.wait(i32a, 0, 44, ${TIMEOUT})); + $262.agent.report(Atomics.wait(i32a, 0, 251.4, ${TIMEOUT})); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +// NB: We don't actually explicitly need to wait for the agent to start in this +// test case, we only do it for consistency with other test cases which do +// require the main agent to wait and yield control. + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue( + $262.agent.getReport(), + 'not-equal', + '$262.agent.getReport() returns "not-equal"' +); +assert.sameValue( + $262.agent.getReport(), + 'not-equal', + '$262.agent.getReport() returns "not-equal"' +); +assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/waiterlist-block-indexedposition-wake.js b/js/src/tests/test262/built-ins/Atomics/wait/waiterlist-block-indexedposition-wake.js new file mode 100644 index 0000000000..f3b2a06300 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/waiterlist-block-indexedposition-wake.js @@ -0,0 +1,78 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + Get the correct WaiterList +info: | + Atomics.wait( typedArray, index, value, timeout ) + + ... + 11. Let WL be GetWaiterList(block, indexedPosition). + ... + + + GetWaiterList( block, i ) + + ... + 4. Return the WaiterList that is referenced by the pair (block, i). + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +var NUMAGENT = 2; +var RUNNING = 4; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + // Wait on index 0 + $262.agent.report(Atomics.wait(i32a, 0, 0, Infinity)); + $262.agent.leaving(); + }); +`); + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + // Wait on index 2 + $262.agent.report(Atomics.wait(i32a, 2, 0, Infinity)); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 5) +); + +$262.agent.safeBroadcast(i32a); + +// Wait until all agents started. +$262.agent.waitUntil(i32a, RUNNING, NUMAGENT); + +// Notify index 1, notifies nothing +assert.sameValue(Atomics.notify(i32a, 1), 0, 'Atomics.notify(i32a, 1) returns 0'); + +// Notify index 3, notifies nothing +assert.sameValue(Atomics.notify(i32a, 3), 0, 'Atomics.notify(i32a, 3) returns 0'); + +// Notify index 2, notifies 1 +var woken = 0; +while ((woken = Atomics.notify(i32a, 2)) === 0) ; +assert.sameValue(woken, 1, 'Atomics.notify(i32a, 2) returns 1'); +assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"'); + +// Notify index 0, notifies 1 +var woken = 0; +while ((woken = Atomics.notify(i32a, 0)) === 0) ; +assert.sameValue(woken, 1, 'Atomics.notify(i32a, 0) returns 1'); +assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/waiterlist-order-of-operations-is-fifo.js b/js/src/tests/test262/built-ins/Atomics/wait/waiterlist-order-of-operations-is-fifo.js new file mode 100644 index 0000000000..42fd5d4827 --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/waiterlist-order-of-operations-is-fifo.js @@ -0,0 +1,96 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wait +description: > + New waiters should be applied to the end of the list and woken by order they entered the list (FIFO) +info: | + Atomics.wait( typedArray, index, value, timeout ) + + 16.Perform AddWaiter(WL, W). + ... + 3.Add W to the end of the list of waiters in WL. + +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +var NUMAGENT = 3; + +var WAIT_INDEX = 0; +var RUNNING = 1; +var LOCK_INDEX = 2; + +for (var i = 0; i < NUMAGENT; i++) { + var agentNum = i; + + $262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + // Synchronize workers before reporting the initial report. + while (Atomics.compareExchange(i32a, ${LOCK_INDEX}, 0, 1) !== 0) ; + + // Report the agent number before waiting. + $262.agent.report(${agentNum}); + + // Wait until restarted by main thread. + var status = Atomics.wait(i32a, ${WAIT_INDEX}, 0); + + // Report wait status. + $262.agent.report(status); + + // Report the agent number after waiting. + $262.agent.report(${agentNum}); + + $262.agent.leaving(); + }); + `); +} + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); + +// Wait until all agents started. +$262.agent.waitUntil(i32a, RUNNING, NUMAGENT); + +// Agents may be started in any order. +const started = []; +for (var i = 0; i < NUMAGENT; i++) { + // Wait until an agent entered its critical section. + $262.agent.waitUntil(i32a, LOCK_INDEX, 1); + + // Record the agent number. + started.push($262.agent.getReport()); + + // The agent may have been interrupted between reporting its initial report + // and the `Atomics.wait` call. Try to yield control to ensure the agent + // actually started to wait. + $262.agent.tryYield(); + + // Now continue with the next agent. + Atomics.store(i32a, LOCK_INDEX, 0); +} + +// Agents must notify in the order they waited. +for (var i = 0; i < NUMAGENT; i++) { + var woken = 0; + while ((woken = Atomics.notify(i32a, WAIT_INDEX, 1)) === 0) ; + + assert.sameValue(woken, 1, + 'Atomics.notify(i32a, WAIT_INDEX, 1) returns 1, at index = ' + i); + + assert.sameValue($262.agent.getReport(), 'ok', + '$262.agent.getReport() returns "ok", at index = ' + i); + + assert.sameValue($262.agent.getReport(), started[i], + '$262.agent.getReport() returns the value of `started[' + i + ']`'); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Atomics/wait/was-woken-before-timeout.js b/js/src/tests/test262/built-ins/Atomics/wait/was-woken-before-timeout.js new file mode 100644 index 0000000000..b1f132660e --- /dev/null +++ b/js/src/tests/test262/built-ins/Atomics/wait/was-woken-before-timeout.js @@ -0,0 +1,64 @@ +// |reftest| skip-if(!this.hasOwnProperty('Atomics')||!this.hasOwnProperty('SharedArrayBuffer')||(this.hasOwnProperty('getBuildConfiguration')&&getBuildConfiguration()['arm64-simulator'])) -- Atomics,SharedArrayBuffer is not enabled unconditionally, ARM64 Simulator cannot emulate atomics +// Copyright (C) 2018 Amal Hussein. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-atomics.wait +description: > + Test that Atomics.wait returns the right result when it was awoken before + a timeout +info: | + Atomics.wait( 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. +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const RUNNING = 1; +const TIMEOUT = $262.agent.timeouts.huge; + +$262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + + const before = $262.agent.monotonicNow(); + const unpark = Atomics.wait(i32a, 0, 0, ${TIMEOUT}); + const duration = $262.agent.monotonicNow() - before; + + $262.agent.report(duration); + $262.agent.report(unpark); + $262.agent.leaving(); + }); +`); + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) +); + +$262.agent.safeBroadcast(i32a); +$262.agent.waitUntil(i32a, RUNNING, 1); + +// Try to yield control to ensure the agent actually started to wait. +$262.agent.tryYield(); + +assert.sameValue(Atomics.notify(i32a, 0), 1, 'Atomics.notify(i32a, 0) returns 1'); + +const lapse = $262.agent.getReport(); + +assert( + lapse < TIMEOUT, + 'The result of `(lapse < TIMEOUT)` is true' +); +assert.sameValue($262.agent.getReport(), 'ok', '$262.agent.getReport() returns "ok"'); + +reportCompare(0, 0); |