Description
Atomics.waitAsync
https://tc39.es/proposal-atomics-wait-async/
(All relevant tests must be completed for TypedArray and BigInt)
features.txt
-
Atomics.waitAsync
waitAsync
- esid: sec-atomics.waitasync
- Check Name
- test/built-ins/Atomics/waitAsync/name.js
- Check length
- test/built-ins/Atomics/waitAsync/length.js
- Check descriptor
- test/built-ins/Atomics/waitAsync/descriptor.js
Atomics.waitAsync(typedArray, index, value, timeout)
- Return DoWait(async, typedArray, index, value, timeout).
- returns a Promise that is resolved when the calling agent is notified
- returns a Promise when the sleep times out
DoWait ( mode, typedArray, index, value, timeout )
-
1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true)
- Test for abrupt return if ValidateSharedIntegerTypedArray throws an error
- ValidateSharedIntegerTypedArray (https://tc39.es/ecma262/#sec-validatesharedintegertypedarray):
- If Type(typedArray) is not Object, throw a TypeError exception
- If typedArray does not have a [[TypedArrayName]] internal slot, throw a TypeError exception
- Let type be the Element Type value in Table 63 for typeName. (https://tc39.es/ecma262/#table-the-typedarray-constructors)
- If waitable is true, then
- If typeName is not "Int32Array" or "BigInt64Array", throw a TypeError exception.
- Else,
- If ! IsUnclampedIntegerElementType(type) is false and ! IsBigIntElementType(type) is false, throw a TypeError exception. (https://tc39.es/ecma262/#sec-isunclampedintegerelementtype https://tc39.es/ecma262/#sec-isbigintelementtype)
- If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception.
- Type(obj) is Object and it has an [[ArrayBufferData]] internal slot.
- If bufferData is null, return false.
- If bufferData is a Data Block, return false.
- Return true.
-
2. Let i be ? ValidateAtomicAccess(typedArray, index).
- Test for abrupt return if ValidateAtomicAccess throws an error
- ValidateAtomicAccess: (https://tc39.es/ecma262/#sec-validateatomicaccess)
- Let accessIndex be ? ToIndex(requestIndex)
- abrupt return if ToIndex throws an error
- If value is undefined, let index be 0 and return index
- If integerIndex < 0, throw a RangeError exception.
- Let index be ! ToLength(integerIndex).
- If ! SameValue(integerIndex, index) is false, throw a RangeError exception.
- abrupt return if ToIndex throws an error
- If accessIndex ≥ length, throw a RangeError exception.
- Let accessIndex be ? ToIndex(requestIndex)
-
3. If arrayTypeName is "BigInt64Array", let v be ? ToBigInt64(value).
- Test for abrupt return if ToBigInt throws an error
- Let n be ? ToBigInt(argument).
- TODO: drill down into ToBigInt
- TODO: drill down into ToPrimitive
- Let int64bit be n modulo 2 ** 64.
- Return int64bit.
-
4. Otherwise, let v be ? ToInt32(value).
- Test for abrupt return if ToInt32 throws an error
- Let number be ? ToNumber(argument)
- ToNumber: (superficial cases only)
- ToNumber(Symbol) --> Throw a TypeError exception.
- abrupt return if ToNumber throws an error
- Let int be the Number value that is the same sign as number and whose magnitude is floor(abs(number)).
- Let int32bit be int modulo 2 ** 32.
- If int32bit ≥ 2 ** 31, return int32bit - 2 ** 32; otherwise return int32bit.
- ToNumber: (superficial cases only)
-
5. Let q be ? ToNumber(timeout)
- Test for abrupt return if ToNumber throws an error
- Let number be ? ToNumber(argument)
- ToNumber: (superficial cases only)
- ToNumber(Symbol) --> Throw a TypeError exception.
- abrupt return if ToNumber throws an error
- ToNumber: (superficial cases only)
-
6. If q is NaN, let t be +∞, else let t be max(q, 0)
- confirm that passing a negative timeout translates to 0ms
- confirm that passing NaN as a timeout translate to +infinity
-
7. If mode is sync, then
- Let B be AgentCanSuspend().
- If B is false, throw a TypeError exception.
- TODO: Identify a way for hosts specify the value of [[CanBlock]]
-
8. Let block be buffer.[[ArrayBufferData]]. NOT DIRECTLY OBSERVABLE
-
9. Let offset be typedArray.[[ByteOffset]]. NOT DIRECTLY OBSERVABLE
-
10. Let indexedPosition be (i × 4) + offset. NOT DIRECTLY OBSERVABLE
-
11. Let WL be GetWaiterList(block, indexedPosition).
- From GetWaiterList: (https://tc39.es/ecma262/#sec-getwaiterlist)
- Return the WaiterList that is referenced by the pair (block, i).
- From GetWaiterList: (https://tc39.es/ecma262/#sec-getwaiterlist)
-
12. Let promiseCapability be undefined. NOT DIRECTLY OBSERVABLE
-
13. If mode is async, then
- Let promiseCapability be ! NewPromiseCapability(%Promise%).
-
14. Perform EnterCriticalSection(WL).
- EnterCriticalSection:
- Wait until no agent is in the critical section for WL, then enter the critical section for WL (without allowing any other agent to enter).
- EnterCriticalSection:
-
15. Let w be ! AtomicLoad(typedArray, i). NOT DIRECTLY OBSERVABLE
-
16. If v is not equal to w, then
- a. Perform LeaveCriticalSection(WL).
- b. If mode is sync, then
- Return the String "not-equal".
- c. Perform ! Call(capability.[[Resolve]], undefined, « "not-equal" »).
- Return promiseCapability.[[Promise]].
-
17. Let W be AgentSignifier() NOT DIRECTLY OBSERVABLE
-
18. Let waiterRecord be a new Waiter Record { [[AgentSignifier]]: W, [[PromiseCapability]]: promiseCapability, [[Timeout]]: t, [[Result]]: "ok" }.
- TODO
-
19. Perform AddWaiter(WL, waiterRecord).
- AddWaiter: (https://tc39.es/proposal-atomics-wait-async/#sec-addwaiter)
- TODO: Review changes present in proposal
- AddWaiter: (https://tc39.es/proposal-atomics-wait-async/#sec-addwaiter)
-
20. If mode is sync, then
- Perform Suspend(WL, W).
- Suspend: (https://tc39.es/proposal-atomics-wait-async/#sec-suspend)
- TODO: Review changes present in proposal
- Suspend: (https://tc39.es/proposal-atomics-wait-async/#sec-suspend)
- Perform Suspend(WL, W).
-
21. Perform LeaveCriticalSection(WL). NOT DIRECTLY OBSERVABLE
-
22. If mode is sync, then
- Return waiterRecord.[[Result]].
-
23. Return promiseCapability.[[Promise]].
Activity