Skip to content

Commit

Permalink
Normative: Allow Atomics methods to work on ArrayBuffers.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
syg committed Mar 23, 2020
1 parent f114433 commit 94a146d
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -36958,23 +36958,26 @@ <h1>SetValueInBuffer ( _arrayBuffer_, _byteIndex_, _type_, _value_, _isTypedArra

<emu-clause id="sec-getmodifysetvalueinbuffer" aoid="GetModifySetValueInBuffer">
<h1>GetModifySetValueInBuffer ( _arrayBuffer_, _byteIndex_, _type_, _value_, _op_ [ , _isLittleEndian_ ] )</h1>
<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>
<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>
<emu-alg>
1. Assert: IsSharedArrayBuffer(_arrayBuffer_) is *true*.
1. Assert: There are sufficient bytes in _arrayBuffer_ starting at _byteIndex_ to represent a value of _type_.
1. Assert: ! IsNonNegativeInteger(_byteIndex_) is *true*.
1. Assert: Type(_value_) is BigInt if ! IsBigIntElementType(_type_) is *true*; otherwise, Type(_value_) is Number.
1. Let _block_ be _arrayBuffer_.[[ArrayBufferData]].
1. Let _elementSize_ be the Element Size value specified in <emu-xref href="#table-the-typedarray-constructors"></emu-xref> for Element Type _type_.
1. If _isLittleEndian_ is not present, set _isLittleEndian_ to the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
1. Let _rawBytes_ be NumericToRawBytes(_type_, _value_, _isLittleEndian_).
1. Let _execution_ be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
1. Let _eventList_ be the [[EventList]] field of the element in _execution_.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
1. Let _rawBytesRead_ be a List of length _elementSize_ of nondeterministically chosen byte values.
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.
1. Let _rmwEvent_ be ReadModifyWriteSharedMemory { [[Order]]: ~SeqCst~, [[NoTear]]: *true*, [[Block]]: _block_, [[ByteIndex]]: _byteIndex_, [[ElementSize]]: _elementSize_, [[Payload]]: _rawBytes_, [[ModifyOp]]: _op_ }.
1. Append _rmwEvent_ to _eventList_.
1. Append Chosen Value Record { [[Event]]: _rmwEvent_, [[ChosenValue]]: _rawBytesRead_ } to _execution_.[[ChosenValues]].
1. If IsSharedArrayBuffer(_arrayBuffer_) is *true*, then
1. Let _execution_ be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
1. Let _eventList_ be the [[EventList]] field of the element in _execution_.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
1. Let _rawBytesRead_ be a List of length _elementSize_ of nondeterministically chosen byte values.
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.
1. Let _rmwEvent_ be ReadModifyWriteSharedMemory { [[Order]]: ~SeqCst~, [[NoTear]]: *true*, [[Block]]: _block_, [[ByteIndex]]: _byteIndex_, [[ElementSize]]: _elementSize_, [[Payload]]: _rawBytes_, [[ModifyOp]]: _op_ }.
1. Append _rmwEvent_ to _eventList_.
1. Append Chosen Value Record { [[Event]]: _rmwEvent_, [[ChosenValue]]: _rawBytesRead_ } to _execution_.[[ChosenValues]].
1. Else,
1. Let _rawBytesAtIndex_ be a List of _elementSize_ containing, in order, the _elementSize_ sequence of bytes starting with _block_[_byteIndex_].
1. Let _rawBytesRead_ be _op_(_rawBytesAtIndex_, _rawBytes_).
1. Return RawBytesToNumeric(_type_, _rawBytesRead_, _isLittleEndian_).
</emu-alg>
</emu-clause>
Expand Down Expand Up @@ -37996,6 +37999,7 @@ <h1>Atomics.wait ( _typedArray_, _index_, _value_, _timeout_ )</h1>
<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>
<emu-alg>
1. Let _buffer_ be ? ValidateIntegerTypedArray(_typedArray_, *true*).
1. If IsSharedArrayBuffer(_buffer_) is *false*, throw a *TypeError* exception.
1. Let _i_ be ? ValidateAtomicAccess(_typedArray_, _index_).
1. Let _arrayTypeName_ be _typedArray_.[[TypedArrayName]].
1. If _arrayTypeName_ is *"BigInt64Array"*, let _v_ be ? ToBigInt64(_value_).
Expand Down Expand Up @@ -38042,6 +38046,7 @@ <h1>Atomics.notify ( _typedArray_, _index_, _count_ )</h1>
1. Let _arrayTypeName_ be _typedArray_.[[TypedArrayName]].
1. Let _elementSize_ be the Element Size value specified in <emu-xref href="#table-the-typedarray-constructors"></emu-xref> for _arrayTypeName_.
1. Let _indexedPosition_ be (_i_ &times; _elementSize_) + _offset_.
1. If IsSharedArrayBuffer(_buffer_) is *false*, return 0.
1. Let _WL_ be GetWaiterList(_block_, _indexedPosition_).
1. Let _n_ be 0.
1. Perform EnterCriticalSection(_WL_).
Expand Down

0 comments on commit 94a146d

Please sign in to comment.