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