From 6d4b4eba98c5866d4f23972db674120424393303 Mon Sep 17 00:00:00 2001
From: Rick Waldron <waldron.rick@gmail.com>
Date: Tue, 7 Apr 2020 15:39:15 -0400
Subject: [PATCH] Atomics.waitAsync: false, nan, negative, null, object zero
 timeouts

---
 .../waitAsync/false-for-timeout-agent.js      | 37 +++++---
 .../Atomics/waitAsync/false-for-timeout.js    | 24 ++++-
 .../built-ins/Atomics/waitAsync/good-views.js | 18 ++--
 .../Atomics/waitAsync/nan-for-timeout.js      |  6 +-
 .../waitAsync/negative-timeout-agent.js       |  2 +-
 .../Atomics/waitAsync/negative-timeout.js     | 15 +--
 .../waitAsync/null-for-timeout-agent.js       | 88 ++++++++++++++++++
 .../Atomics/waitAsync/null-for-timeout.js     | 59 ++++++++++++
 .../waitAsync/object-for-timeout-agent.js     | 93 +++++++++++++++++++
 .../Atomics/waitAsync/object-for-timeout.js   | 67 +++++++++++++
 10 files changed, 371 insertions(+), 38 deletions(-)
 create mode 100644 test/built-ins/Atomics/waitAsync/null-for-timeout-agent.js
 create mode 100644 test/built-ins/Atomics/waitAsync/null-for-timeout.js
 create mode 100644 test/built-ins/Atomics/waitAsync/object-for-timeout-agent.js
 create mode 100644 test/built-ins/Atomics/waitAsync/object-for-timeout.js

diff --git a/test/built-ins/Atomics/waitAsync/false-for-timeout-agent.js b/test/built-ins/Atomics/waitAsync/false-for-timeout-agent.js
index b03c60788e..bc733dda98 100644
--- a/test/built-ins/Atomics/waitAsync/false-for-timeout-agent.js
+++ b/test/built-ins/Atomics/waitAsync/false-for-timeout-agent.js
@@ -35,14 +35,12 @@ $262.agent.start(`
   $262.agent.receiveBroadcast(async (sab) => {
     const i32a = new Int32Array(sab);
     Atomics.add(i32a, ${RUNNING}, 1);
-
-    const status1 = await Atomics.waitAsync(i32a, 0, 0, false).value;
-    const status2 = await Atomics.waitAsync(i32a, 0, 0, valueOf).value;
-    const status3 = await Atomics.waitAsync(i32a, 0, 0, toPrimitive).value;
-
-    $262.agent.report(status1);
-    $262.agent.report(status2);
-    $262.agent.report(status3);
+    $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();
   });
 `);
@@ -53,24 +51,37 @@ const i32a = new Int32Array(
 
 $262.agent.safeBroadcast(i32a);
 $262.agent.waitUntil(i32a, RUNNING, 1);
-
-// Try to yield control to ensure the agent actually started to wait.
 $262.agent.tryYield();
 
 assert.sameValue(
   $262.agent.getReport(),
   'timed-out',
-  '$262.agent.getReport() returns "timed-out"'
+  'await Atomics.waitAsync(i32a, 0, 0, false).value resolves to "timed-out"'
 );
 assert.sameValue(
   $262.agent.getReport(),
   'timed-out',
-  '$262.agent.getReport() returns "timed-out"'
+  'await Atomics.waitAsync(i32a, 0, 0, valueOf).value resolves to "timed-out"'
 );
 assert.sameValue(
   $262.agent.getReport(),
   'timed-out',
-  '$262.agent.getReport() returns "timed-out"'
+  'await Atomics.waitAsync(i32a, 0, 0, toPrimitive).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, false).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, valueOf).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, toPrimitive).value resolves to "timed-out"'
 );
 
 assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0');
diff --git a/test/built-ins/Atomics/waitAsync/false-for-timeout.js b/test/built-ins/Atomics/waitAsync/false-for-timeout.js
index 5dd8de86b6..c745b32b73 100644
--- a/test/built-ins/Atomics/waitAsync/false-for-timeout.js
+++ b/test/built-ins/Atomics/waitAsync/false-for-timeout.js
@@ -34,12 +34,30 @@ const toPrimitive = {
   }
 };
 
+assert.sameValue(
+  Atomics.waitAsync(i32a, 0, 0, false).value,
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, false).value resolves to "timed-out"'
+);
+
+assert.sameValue(
+  Atomics.waitAsync(i32a, 0, 0, valueOf).value,
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, false).value resolves to "timed-out"'
+);
+
+assert.sameValue(
+  Atomics.waitAsync(i32a, 0, 0, toPrimitive).value,
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, false).value resolves to "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");
-    assert.sameValue(outcomes[0], "timed-out");
-    assert.sameValue(outcomes[0], "timed-out");
+    assert.sameValue(outcomes[0], 'timed-out');
+    assert.sameValue(outcomes[0], 'timed-out');
+    assert.sameValue(outcomes[0], 'timed-out');
   }, $DONE).then($DONE, $DONE);
diff --git a/test/built-ins/Atomics/waitAsync/good-views.js b/test/built-ins/Atomics/waitAsync/good-views.js
index 15e851b511..d7f3a8c348 100644
--- a/test/built-ins/Atomics/waitAsync/good-views.js
+++ b/test/built-ins/Atomics/waitAsync/good-views.js
@@ -4,13 +4,10 @@
 /*---
 esid: sec-atomics.waitasync
 description: >
-  Test Atomics.waitAsync on arrays that allow atomic operations,
-  in an Agent that is allowed to wait.
+  Test Atomics.waitAsync on arrays that allow atomic operations
 includes: [atomicsHelper.js]
 features: [Atomics.waitAsync, Atomics]
 ---*/
-// Let's assume 'wait' is not allowed on the main thread,
-// even in the shell.
 
 $262.agent.start(`
   (async () => {
@@ -27,8 +24,8 @@ $262.agent.start(`
     var view = new Int32Array(sab, 32, 20);
 
     view[0] = 0;
-    $262.agent.report("A " + (await Atomics.waitAsync(view, 0, 0, 0)))
-    $262.agent.report("B " + (await Atomics.waitAsync(view, 0, 37, 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));
 
     // In-bounds boundary cases for indexing
     for ( let IdxGen of good_indices ) {
@@ -37,9 +34,8 @@ $262.agent.start(`
         // Atomics.store() computes an index from Idx in the same way as other
         // Atomics operations, not quite like view[Idx].
         Atomics.store(view, Idx, 37);
-        $262.agent.report("C " + (await Atomics.waitAsync(view, Idx, 0)));
+        $262.agent.report("C " + (await Atomics.waitAsync(view, Idx, 0).value));
     }
-
     $262.agent.report("done");
     $262.agent.leaving();
   })();
@@ -48,13 +44,13 @@ $262.agent.start(`
 assert.sameValue(
   $262.agent.getReport(),
   'A timed-out',
-  '$262.agent.getReport() returns "A timed-out"'
+  '"A " + (await Atomics.waitAsync(view, 0, 0, 0).value resolves to "A timed-out"'
 );
 
 assert.sameValue(
   $262.agent.getReport(),
   'B not-equal',
-  '$262.agent.getReport() returns "B not-equal"'
+  '"B " + (await Atomics.waitAsync(view, 0, 37, 0).value resolves to "B not-equal"'
 );
 
 var r;
@@ -62,6 +58,6 @@ while ((r = $262.agent.getReport()) !== "done") {
   assert.sameValue(
     r,
     'C not-equal',
-    '$262.agent.getReport() returns "C not-equal"'
+    '"C " + (await Atomics.waitAsync(view, Idx, 0).value resolves to "C not-equal"'
   );
 }
diff --git a/test/built-ins/Atomics/waitAsync/nan-for-timeout.js b/test/built-ins/Atomics/waitAsync/nan-for-timeout.js
index 4fd9364aa9..d3d82a2352 100644
--- a/test/built-ins/Atomics/waitAsync/nan-for-timeout.js
+++ b/test/built-ins/Atomics/waitAsync/nan-for-timeout.js
@@ -25,7 +25,7 @@ $262.agent.start(`
     const i32a = new Int32Array(sab);
     Atomics.add(i32a, ${RUNNING}, 1);
 
-    $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, NaN));  // NaN => +Infinity
+    $262.agent.report(await Atomics.waitAsync(i32a, 0, 0, NaN).value);  // NaN => +Infinity
     $262.agent.leaving();
   });
 `);
@@ -36,9 +36,7 @@ const i32a = new Int32Array(
 
 $262.agent.safeBroadcast(i32a);
 $262.agent.waitUntil(i32a, RUNNING, 1);
-
-// Try to yield control to ensure the agent actually started to wait.
 $262.agent.tryYield();
 
 assert.sameValue(Atomics.notify(i32a, 0), 1, 'Atomics.notify(i32a, 0) returns 1');
-assert.sameValue($262.agent.getReport(), "ok", '$262.agent.getReport() returns "ok"');
+assert.sameValue($262.agent.getReport(), "ok", 'await Atomics.waitAsync(i32a, 0, 0, NaN).value resolves to "ok"');
diff --git a/test/built-ins/Atomics/waitAsync/negative-timeout-agent.js b/test/built-ins/Atomics/waitAsync/negative-timeout-agent.js
index 639c06abc7..6244fcc1ba 100644
--- a/test/built-ins/Atomics/waitAsync/negative-timeout-agent.js
+++ b/test/built-ins/Atomics/waitAsync/negative-timeout-agent.js
@@ -33,6 +33,6 @@ $262.agent.tryYield();
 assert.sameValue(
   $262.agent.getReport(),
   'timed-out',
-  '$262.agent.getReport() returns "timed-out"'
+  'await Atomics.waitSync(i32a, 0, 0, -5).value resolves to "timed-out"'
 );
 assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0');
diff --git a/test/built-ins/Atomics/waitAsync/negative-timeout.js b/test/built-ins/Atomics/waitAsync/negative-timeout.js
index 94627ab64e..0776ca54e5 100644
--- a/test/built-ins/Atomics/waitAsync/negative-timeout.js
+++ b/test/built-ins/Atomics/waitAsync/negative-timeout.js
@@ -12,9 +12,12 @@ const i32a = new Int32Array(
   new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)
 );
 
-let {async, value} = Atomics.waitAsync(i32a, 0, 0, -1);
-
-
-value.then(outcome => {
-  assert.sameValue(outcome, "timed-out");
-}, $DONE).then($DONE, $DONE);
+Promise.all([
+    Atomics.waitAsync(i32a, 0, 0, -1).value,
+  ]).then(outcomes => {
+    assert.sameValue(
+      outcomes[0],
+      'timed-out',
+      'Atomics.waitAsync(i32a, 0, 0, -1).value resolves to "timed-out"'
+    );
+  }, $DONE).then($DONE, $DONE);
diff --git a/test/built-ins/Atomics/waitAsync/null-for-timeout-agent.js b/test/built-ins/Atomics/waitAsync/null-for-timeout-agent.js
new file mode 100644
index 0000000000..1e515ab14e
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/null-for-timeout-agent.js
@@ -0,0 +1,88 @@
+// 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 )
+
+  4. Let q be ? ToNumber(timeout).
+
+    Null -> Return +0.
+
+includes: [atomicsHelper.js]
+features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics]
+---*/
+
+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.safeBroadcast(i32a);
+$262.agent.waitUntil(i32a, RUNNING, 1);
+
+// Try to yield control to ensure the agent actually started to wait.
+$262.agent.tryYield();
+
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.waitAsync(i32a, 0, 0, null).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.waitAsync(i32a, 0, 0, valueOf).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.waitAsync(i32a, 0, 0, toPrimitive).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, null).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, valueOf).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, toPrimitive).value resolves to "timed-out"'
+);
+
+assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0');
diff --git a/test/built-ins/Atomics/waitAsync/null-for-timeout.js b/test/built-ins/Atomics/waitAsync/null-for-timeout.js
new file mode 100644
index 0000000000..cc4d369f49
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/null-for-timeout.js
@@ -0,0 +1,59 @@
+// 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 )
+
+  4. Let q be ? ToNumber(timeout).
+
+    Null -> Return +0.
+
+features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics]
+flags: [async]
+---*/
+
+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',
+  'Atomics.waitAsync(i32a, 0, 0, null).value resolves to "timed-out"'
+);
+assert.sameValue(
+  Atomics.waitAsync(i32a, 0, 0, valueOf).value,
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, valueOf).value resolves to "timed-out"'
+);
+assert.sameValue(
+  Atomics.waitAsync(i32a, 0, 0, toPrimitive).value,
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, toPrimitive).value resolves to "timed-out"'
+);
+
+Promise.all([
+    Atomics.waitAsync(i32a, 0, 0, null).value,
+    Atomics.waitAsync(i32a, 0, 0, valueOf).value,
+    Atomics.waitAsync(i32a, 0, 0, toPrimitive).value,
+  ]).then(outcomes => {
+    assert.sameValue(outcomes[0], "timed-out");
+    assert.sameValue(outcomes[0], "timed-out");
+    assert.sameValue(outcomes[0], "timed-out");
+  }, $DONE).then($DONE, $DONE);
diff --git a/test/built-ins/Atomics/waitAsync/object-for-timeout-agent.js b/test/built-ins/Atomics/waitAsync/object-for-timeout-agent.js
new file mode 100644
index 0000000000..b5da2cd39e
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/object-for-timeout-agent.js
@@ -0,0 +1,93 @@
+// 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.wait( typedArray, index, value, timeout )
+
+  4. Let q be ? ToNumber(timeout).
+
+    Null -> Return +0.
+
+includes: [atomicsHelper.js]
+features: [Atomics.waitAsync, SharedArrayBuffer, TypedArray, Atomics]
+---*/
+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.safeBroadcast(i32a);
+$262.agent.waitUntil(i32a, RUNNING, 1);
+
+// Try to yield control to ensure the agent actually started to wait.
+$262.agent.tryYield();
+
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.waitAsync(i32a, 0, 0, valueOf).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.waitAsync(i32a, 0, 0, toString).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'await Atomics.waitAsync(i32a, 0, 0, toPrimitive).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, valueOf).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, toString).value resolves to "timed-out"'
+);
+assert.sameValue(
+  $262.agent.getReport(),
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, toPrimitive).value resolves to "timed-out"'
+);
+
+assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0');
diff --git a/test/built-ins/Atomics/waitAsync/object-for-timeout.js b/test/built-ins/Atomics/waitAsync/object-for-timeout.js
new file mode 100644
index 0000000000..207f6bfde6
--- /dev/null
+++ b/test/built-ins/Atomics/waitAsync/object-for-timeout.js
@@ -0,0 +1,67 @@
+// 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.wait( typedArray, index, value, timeout )
+
+  4. Let q be ? ToNumber(timeout).
+
+    Object -> Apply the following steps:
+
+      Let primValue be ? ToPrimitive(argument, hint Number).
+      Return ? ToNumber(primValue).
+
+features: [Atomics.waitAsync, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray, computed-property-names, Atomics]
+flags: [async]
+---*/
+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',
+  'Atomics.waitAsync(i32a, 0, 0, valueOf).value resolves to "timed-out"'
+);
+assert.sameValue(
+  Atomics.waitAsync(i32a, 0, 0, toString).value,
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, toString).value resolves to "timed-out"'
+);
+assert.sameValue(
+  Atomics.waitAsync(i32a, 0, 0, toPrimitive).value,
+  'timed-out',
+  'Atomics.waitAsync(i32a, 0, 0, toPrimitive).value resolves to "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");
+    assert.sameValue(outcomes[0], "timed-out");
+    assert.sameValue(outcomes[0], "timed-out");
+  }, $DONE).then($DONE, $DONE);