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);