Skip to content

Commit 67e63a5

Browse files
committed
Normative: Allow Atomics methods to work on ArrayBuffers.
Allow Atomics methods to work on ArrayBuffers in a fully deterministic fashion. Atomics.wait still throws when used on ArrayBuffers, while Atomics.notify always returns 0.
1 parent 6fa3b1a commit 67e63a5

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

spec.html

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36957,23 +36957,26 @@ <h1>SetValueInBuffer ( _arrayBuffer_, _byteIndex_, _type_, _value_, _isTypedArra
3695736957

3695836958
<emu-clause id="sec-getmodifysetvalueinbuffer" aoid="GetModifySetValueInBuffer">
3695936959
<h1>GetModifySetValueInBuffer ( _arrayBuffer_, _byteIndex_, _type_, _value_, _op_ [ , _isLittleEndian_ ] )</h1>
36960-
<p>The abstract operation GetModifySetValueInBuffer takes six parameters, a SharedArrayBuffer _arrayBuffer_, a nonnegative integer _byteIndex_, a TypedArray element type _type_, a Number or BigInt _value_, a read-modify-write modification function _op_, and optionally a Boolean _isLittleEndian_. This operation performs the following steps:</p>
36960+
<p>The abstract operation GetModifySetValueInBuffer takes six parameters, an ArrayBuffer or SharedArrayBuffer _arrayBuffer_, a nonnegative integer _byteIndex_, a TypedArray element type _type_, a Number or BigInt _value_, a read-modify-write modification function _op_, and optionally a Boolean _isLittleEndian_. This operation performs the following steps:</p>
3696136961
<emu-alg>
36962-
1. Assert: IsSharedArrayBuffer(_arrayBuffer_) is *true*.
3696336962
1. Assert: There are sufficient bytes in _arrayBuffer_ starting at _byteIndex_ to represent a value of _type_.
3696436963
1. Assert: ! IsNonNegativeInteger(_byteIndex_) is *true*.
3696536964
1. Assert: Type(_value_) is BigInt if ! IsBigIntElementType(_type_) is *true*; otherwise, Type(_value_) is Number.
3696636965
1. Let _block_ be _arrayBuffer_.[[ArrayBufferData]].
3696736966
1. Let _elementSize_ be the Element Size value specified in <emu-xref href="#table-the-typedarray-constructors"></emu-xref> for Element Type _type_.
3696836967
1. If _isLittleEndian_ is not present, set _isLittleEndian_ to the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
3696936968
1. Let _rawBytes_ be NumericToRawBytes(_type_, _value_, _isLittleEndian_).
36970-
1. Let _execution_ be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
36971-
1. Let _eventList_ be the [[EventList]] field of the element in _execution_.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
36972-
1. Let _rawBytesRead_ be a List of length _elementSize_ of nondeterministically chosen byte values.
36973-
1. NOTE: In implementations, _rawBytesRead_ is the result of a load-link, of a load-exclusive, or of an operand of a read-modify-write instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
36974-
1. Let _rmwEvent_ be ReadModifyWriteSharedMemory { [[Order]]: ~SeqCst~, [[NoTear]]: *true*, [[Block]]: _block_, [[ByteIndex]]: _byteIndex_, [[ElementSize]]: _elementSize_, [[Payload]]: _rawBytes_, [[ModifyOp]]: _op_ }.
36975-
1. Append _rmwEvent_ to _eventList_.
36976-
1. Append Chosen Value Record { [[Event]]: _rmwEvent_, [[ChosenValue]]: _rawBytesRead_ } to _execution_.[[ChosenValues]].
36969+
1. If IsSharedArrayBuffer(_arrayBuffer_) is *true*, then
36970+
1. Let _execution_ be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
36971+
1. Let _eventList_ be the [[EventList]] field of the element in _execution_.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
36972+
1. Let _rawBytesRead_ be a List of length _elementSize_ of nondeterministically chosen byte values.
36973+
1. NOTE: In implementations, _rawBytesRead_ is the result of a load-link, of a load-exclusive, or of an operand of a read-modify-write instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
36974+
1. Let _rmwEvent_ be ReadModifyWriteSharedMemory { [[Order]]: ~SeqCst~, [[NoTear]]: *true*, [[Block]]: _block_, [[ByteIndex]]: _byteIndex_, [[ElementSize]]: _elementSize_, [[Payload]]: _rawBytes_, [[ModifyOp]]: _op_ }.
36975+
1. Append _rmwEvent_ to _eventList_.
36976+
1. Append Chosen Value Record { [[Event]]: _rmwEvent_, [[ChosenValue]]: _rawBytesRead_ } to _execution_.[[ChosenValues]].
36977+
1. Else,
36978+
1. Let _rawBytesAtIndex_ be a List of _elementSize_ containing, in order, the _elementSize_ sequence of bytes starting with _block_[_byteIndex_].
36979+
1. Let _rawBytesRead_ be _op_(_rawBytesAtIndex_, _rawBytes_).
3697736980
1. Return RawBytesToNumeric(_type_, _rawBytesRead_, _isLittleEndian_).
3697836981
</emu-alg>
3697936982
</emu-clause>
@@ -37648,9 +37651,9 @@ <h1>The Atomics Object</h1>
3764837651
<emu-clause id="sec-abstract-operations-for-atomics">
3764937652
<h1>Abstract Operations for Atomics</h1>
3765037653

37651-
<emu-clause id="sec-validatesharedintegertypedarray" aoid="ValidateSharedIntegerTypedArray">
37652-
<h1>ValidateSharedIntegerTypedArray ( _typedArray_ [ , _waitable_ ] )</h1>
37653-
<p>The abstract operation ValidateSharedIntegerTypedArray takes one argument _typedArray_ and an optional Boolean _waitable_. It performs the following steps:</p>
37654+
<emu-clause id="sec-validateintegertypedarray" aoid="ValidateIntegerTypedArray" oldid="sec-validatesharedintegertypedarray">
37655+
<h1>ValidateIntegerTypedArray ( _typedArray_ [ , _waitable_ ] )</h1>
37656+
<p>The abstract operation ValidateIntegerTypedArray takes one argument _typedArray_ and an optional Boolean _waitable_. It performs the following steps:</p>
3765437657
<emu-alg>
3765537658
1. If _waitable_ is not present, set _waitable_ to *false*.
3765637659
1. Perform ? RequireInternalSlot(_typedArray_, [[TypedArrayName]]).
@@ -37662,7 +37665,6 @@ <h1>ValidateSharedIntegerTypedArray ( _typedArray_ [ , _waitable_ ] )</h1>
3766237665
1. If ! IsUnclampedIntegerElementType(_type_) is *false* and ! IsBigIntElementType(_type_) is *false*, throw a *TypeError* exception.
3766337666
1. Assert: _typedArray_ has a [[ViewedArrayBuffer]] internal slot.
3766437667
1. Let _buffer_ be _typedArray_.[[ViewedArrayBuffer]].
37665-
1. If IsSharedArrayBuffer(_buffer_) is *false*, throw a *TypeError* exception.
3766637668
1. Return _buffer_.
3766737669
</emu-alg>
3766837670
</emu-clause>
@@ -37796,7 +37798,7 @@ <h1>NotifyWaiter ( _WL_, _W_ )</h1>
3779637798
<h1>AtomicReadModifyWrite ( _typedArray_, _index_, _value_, _op_ )</h1>
3779737799
<p>The abstract operation AtomicReadModifyWrite takes four arguments, _typedArray_, _index_, _value_, and a pure combining operation _op_. The pure combining operation _op_ takes two List of byte values arguments and returns a List of byte values. The operation atomically loads a value, combines it with another value, and stores the result of the combination. It returns the loaded value. It performs the following steps:</p>
3779837800
<emu-alg>
37799-
1. Let _buffer_ be ? ValidateSharedIntegerTypedArray(_typedArray_).
37801+
1. Let _buffer_ be ? ValidateIntegerTypedArray(_typedArray_).
3780037802
1. Let _i_ be ? ValidateAtomicAccess(_typedArray_, _index_).
3780137803
1. Let _arrayTypeName_ be _typedArray_.[[TypedArrayName]].
3780237804
1. If _typedArray_.[[ContentType]] is ~BigInt~, let _v_ be ? ToBigInt(_value_).
@@ -37813,7 +37815,7 @@ <h1>AtomicReadModifyWrite ( _typedArray_, _index_, _value_, _op_ )</h1>
3781337815
<h1>AtomicLoad ( _typedArray_, _index_ )</h1>
3781437816
<p>The abstract operation AtomicLoad takes two arguments, _typedArray_, _index_. The operation atomically loads a value and returns the loaded value. It performs the following steps:</p>
3781537817
<emu-alg>
37816-
1. Let _buffer_ be ? ValidateSharedIntegerTypedArray(_typedArray_).
37818+
1. Let _buffer_ be ? ValidateIntegerTypedArray(_typedArray_).
3781737819
1. Let _i_ be ? ValidateAtomicAccess(_typedArray_, _index_).
3781837820
1. Let _arrayTypeName_ be _typedArray_.[[TypedArrayName]].
3781937821
1. Let _elementSize_ be the Element Size value specified in <emu-xref href="#table-the-typedarray-constructors"></emu-xref> for _arrayTypeName_.
@@ -37887,7 +37889,7 @@ <h1>Atomics.and ( _typedArray_, _index_, _value_ )</h1>
3788737889
<h1>Atomics.compareExchange ( _typedArray_, _index_, _expectedValue_, _replacementValue_ )</h1>
3788837890
<p>The following steps are taken:</p>
3788937891
<emu-alg>
37890-
1. Let _buffer_ be ? ValidateSharedIntegerTypedArray(_typedArray_).
37892+
1. Let _buffer_ be ? ValidateIntegerTypedArray(_typedArray_).
3789137893
1. Let _i_ be ? ValidateAtomicAccess(_typedArray_, _index_).
3789237894
1. Let _arrayTypeName_ be _typedArray_.[[TypedArrayName]].
3789337895
1. If _typedArray_.[[ContentType]] is ~BigInt~, then
@@ -37959,7 +37961,7 @@ <h1>Atomics.or ( _typedArray_, _index_, _value_ )</h1>
3795937961
<h1>Atomics.store ( _typedArray_, _index_, _value_ )</h1>
3796037962
<p>The following steps are taken:</p>
3796137963
<emu-alg>
37962-
1. Let _buffer_ be ? ValidateSharedIntegerTypedArray(_typedArray_).
37964+
1. Let _buffer_ be ? ValidateIntegerTypedArray(_typedArray_).
3796337965
1. Let _i_ be ? ValidateAtomicAccess(_typedArray_, _index_).
3796437966
1. Let _arrayTypeName_ be _typedArray_.[[TypedArrayName]].
3796537967
1. If _arrayTypeName_ is *"BigUint64Array"* or *"BigInt64Array"*, let _v_ be ? ToBigInt(_value_).
@@ -37995,7 +37997,8 @@ <h1>Atomics.sub ( _typedArray_, _index_, _value_ )</h1>
3799537997
<h1>Atomics.wait ( _typedArray_, _index_, _value_, _timeout_ )</h1>
3799637998
<p>`Atomics.wait` puts the calling agent in a wait queue and puts it to sleep until it is notified or the sleep times out. The following steps are taken:</p>
3799737999
<emu-alg>
37998-
1. Let _buffer_ be ? ValidateSharedIntegerTypedArray(_typedArray_, *true*).
38000+
1. Let _buffer_ be ? ValidateIntegerTypedArray(_typedArray_, *true*).
38001+
1. If IsSharedArrayBuffer(_buffer_) is *false*, throw a *TypeError* exception.
3799938002
1. Let _i_ be ? ValidateAtomicAccess(_typedArray_, _index_).
3800038003
1. Let _arrayTypeName_ be _typedArray_.[[TypedArrayName]].
3800138004
1. If _arrayTypeName_ is *"BigInt64Array"*, let _v_ be ? ToBigInt64(_value_).
@@ -38031,7 +38034,7 @@ <h1>Atomics.wait ( _typedArray_, _index_, _value_, _timeout_ )</h1>
3803138034
<h1>Atomics.notify ( _typedArray_, _index_, _count_ )</h1>
3803238035
<p>`Atomics.notify` notifies some agents that are sleeping in the wait queue. The following steps are taken:</p>
3803338036
<emu-alg>
38034-
1. Let _buffer_ be ? ValidateSharedIntegerTypedArray(_typedArray_, *true*).
38037+
1. Let _buffer_ be ? ValidateIntegerTypedArray(_typedArray_, *true*).
3803538038
1. Let _i_ be ? ValidateAtomicAccess(_typedArray_, _index_).
3803638039
1. If _count_ is *undefined*, let _c_ be *+&infin;*.
3803738040
1. Else,
@@ -38042,6 +38045,7 @@ <h1>Atomics.notify ( _typedArray_, _index_, _count_ )</h1>
3804238045
1. Let _arrayTypeName_ be _typedArray_.[[TypedArrayName]].
3804338046
1. Let _elementSize_ be the Element Size value specified in <emu-xref href="#table-the-typedarray-constructors"></emu-xref> for _arrayTypeName_.
3804438047
1. Let _indexedPosition_ be (_i_ &times; _elementSize_) + _offset_.
38048+
1. If IsSharedArrayBuffer(_buffer_) is *false*, return 0.
3804538049
1. Let _WL_ be GetWaiterList(_block_, _indexedPosition_).
3804638050
1. Let _n_ be 0.
3804738051
1. Perform EnterCriticalSection(_WL_).

0 commit comments

Comments
 (0)