ECMA-262 (12th Edition) ECMAScript 2021 Language Specification - page 55

 

  Главная      Manuals     ECMA-262 (12th Edition) ECMAScript 2021 Language Specification

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     53      54      55      56     ..

 

 

 

ECMA-262 (12th Edition) ECMAScript 2021 Language Specification - page 55

 

 

8.  If 

IsDetachedBuffer

(

buffer

) is 

true

, throw a 

TypeError

 exception.

9.  Let 

viewOffset

 be 

view

.[[ByteOffset]].

10.  Let 

viewSize

 be 

view

.[[ByteLength]].

11.  Let 

elementSize

 be the Element Size value specified in 

Table 60

 for Element Type 

type

.

12.  If 

getIndex

 + 

elementSize

 > 

viewSize

, throw a 

RangeError

 exception.

13.  Let 

bufferIndex

 be 

getIndex

 + 

viewOffset

.

14.  Return 

SetValueInBuffer

(

buffer

bufferIndex

type

numberValue

false

Unordered

isLittleEndian

).

The DataView 

constructor

:

is 

%DataView%

.

is the initial value of the 

"DataView"

 property of the 

global object

.

creates and initializes a new DataView object when called as a 

constructor

.

is not intended to be called as a function and will throw an exception when called in that manner.
is designed to be subclassable. It may be used as the value of an 

extends

extends

 clause of a class definition. Subclass

constructors that intend to inherit the specified DataView behaviour must include a 

super

super

 call to the

DataView 

constructor

 to create and initialize subclass instances with the internal state necessary to support the

DataView.prototype

DataView.prototype

 built-in methods.

When the 

DataView

DataView

 function is called with at least one argument 

buffer

, the following steps are taken:

1.  If NewTarget is 

undefined

, throw a 

TypeError

 exception.

2.  Perform ? 

RequireInternalSlot

(

buffer

, [[ArrayBufferData]]).

3.  Let 

offset

 be ? 

ToIndex

(

byteOffset

).

4.  If 

IsDetachedBuffer

(

buffer

) is 

true

, throw a 

TypeError

 exception.

5.  Let 

bufferByteLength

 be 

buffer

.[[ArrayBufferByteLength]].

6.  If 

offset

 > 

bufferByteLength

, throw a 

RangeError

 exception.

7.  If 

byteLength

 is 

undefined

, then

a.  Let 

viewByteLength

 be 

bufferByteLength

 - 

offset

.

8.  Else,

a.  Let 

viewByteLength

 be ? 

ToIndex

(

byteLength

).

b.  If 

offset

 + 

viewByteLength

 > 

bufferByteLength

, throw a 

RangeError

 exception.

9.  Let 

O

 be ? 

OrdinaryCreateFromConstructor

(NewTarget, 

"%DataView.prototype%"

, « [[DataView]],

[[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] »).

10.  If 

IsDetachedBuffer

(

buffer

) is 

true

, throw a 

TypeError

 exception.

11.  Set 

O

.[[ViewedArrayBuffer]] to 

buffer

.

12.  Set 

O

.[[ByteLength]] to 

viewByteLength

.

13.  Set 

O

.[[ByteOffset]] to 

offset

.

14.  Return 

O

.

The DataView 

constructor

:

25.3.2  The DataView Constructor

25.3.2.1  DataView ( 

buffer

 [ , 

byteOffset

 [ , 

byteLength

 ] ] )

25.3.3  Properties of the DataView Constructor

720

has a [[Prototype]] internal slot whose value is 

%Function.prototype%

.

has the following properties:

The initial value of 

DataView.prototype

DataView.prototype

 is the 

DataView prototype object

.

This property has the attributes { [[Writable]]: 

false

, [[Enumerable]]: 

false

, [[Configurable]]: 

false

 }.

The 

DataView prototype object

:

is 

%DataView.prototype%

.

has a [[Prototype]] internal slot whose value is 

%Object.prototype%

.

is an 

ordinary object

.

does not have a [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], or [[ByteOffset]] internal slot.

DataView.prototype.buffer

DataView.prototype.buffer

 is an 

accessor property

 whose set accessor function is 

undefined

. Its get

accessor function performs the following steps:

1.  Let 

O

 be the 

this

 value.

2.  Perform ? 

RequireInternalSlot

(

O

, [[DataView]]).

3. 

Assert

O

 has a [[ViewedArrayBuffer]] internal slot.

4.  Let 

buffer

 be 

O

.[[ViewedArrayBuffer]].

5.  Return 

buffer

.

DataView.prototype.byteLength

DataView.prototype.byteLength

 is an 

accessor property

 whose set accessor function is 

undefined

. Its get

accessor function performs the following steps:

1.  Let 

O

 be the 

this

 value.

2.  Perform ? 

RequireInternalSlot

(

O

, [[DataView]]).

3. 

Assert

O

 has a [[ViewedArrayBuffer]] internal slot.

4.  Let 

buffer

 be 

O

.[[ViewedArrayBuffer]].

5.  If 

IsDetachedBuffer

(

buffer

) is 

true

, throw a 

TypeError

 exception.

6.  Let 

size

 be 

O

.[[ByteLength]].

7.  Return 

size

).

DataView.prototype.byteOffset

DataView.prototype.byteOffset

 is an 

accessor property

 whose set accessor function is 

undefined

. Its get

accessor function performs the following steps:

1.  Let 

O

 be the 

this

 value.

2.  Perform ? 

RequireInternalSlot

(

O

, [[DataView]]).

25.3.3.1  DataView.prototype

25.3.4  Properties of the DataView Prototype Object

25.3.4.1  get DataView.prototype.buffer

25.3.4.2  get DataView.prototype.byteLength

25.3.4.3  get DataView.prototype.byteOffset

721

3. 

Assert

O

 has a [[ViewedArrayBuffer]] internal slot.

4.  Let 

buffer

 be 

O

.[[ViewedArrayBuffer]].

5.  If 

IsDetachedBuffer

(

buffer

) is 

true

, throw a 

TypeError

 exception.

6.  Let 

offset

 be 

O

.[[ByteOffset]].

7.  Return 

offset

).

The initial value of 

DataView.prototype.constructor

DataView.prototype.constructor

 is 

%DataView%

.

When the 

getBigInt64

getBigInt64

 method is called with argument 

byteOffset

 and optional argument 

littleEndian

, the

following steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  Return ? 

GetViewValue

(

v

byteOffset

littleEndian

BigInt64

).

When the 

getBigUint64

getBigUint64

 method is called with argument 

byteOffset

 and optional argument 

littleEndian

, the

following steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  Return ? 

GetViewValue

(

v

byteOffset

littleEndian

BigUint64

).

When the 

getFloat32

getFloat32

 method is called with argument 

byteOffset

 and optional argument 

littleEndian

, the following

steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

GetViewValue

(

v

byteOffset

littleEndian

Float32

).

When the 

getFloat64

getFloat64

 method is called with argument 

byteOffset

 and optional argument 

littleEndian

, the following

steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

GetViewValue

(

v

byteOffset

littleEndian

Float64

).

When the 

getInt8

getInt8

 method is called with argument 

byteOffset

, the following steps are taken:

1.  Let 

v

 be the 

this

 value.

25.3.4.4  DataView.prototype.constructor

25.3.4.5  DataView.prototype.getBigInt64 ( 

byteOffset

 [ , 

littleEndian

 ] )

25.3.4.6  DataView.prototype.getBigUint64 ( 

byteOffset

 [ , 

littleEndian

 ] )

25.3.4.7  DataView.prototype.getFloat32 ( 

byteOffset

 [ , 

littleEndian

 ] )

25.3.4.8  DataView.prototype.getFloat64 ( 

byteOffset

 [ , 

littleEndian

 ] )

25.3.4.9  DataView.prototype.getInt8 ( 

byteOffset

 )

722

2.  Return ? 

GetViewValue

(

v

byteOffset

true

Int8

).

When the 

getInt16

getInt16

 method is called with argument 

byteOffset

 and optional argument 

littleEndian

, the following

steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

GetViewValue

(

v

byteOffset

littleEndian

Int16

).

When the 

getInt32

getInt32

 method is called with argument 

byteOffset

 and optional argument 

littleEndian

, the following

steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

GetViewValue

(

v

byteOffset

littleEndian

Int32

).

When the 

getUint8

getUint8

 method is called with argument 

byteOffset

, the following steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  Return ? 

GetViewValue

(

v

byteOffset

true

Uint8

).

When the 

getUint16

getUint16

 method is called with argument 

byteOffset

 and optional argument 

littleEndian

, the following

steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

GetViewValue

(

v

byteOffset

littleEndian

Uint16

).

When the 

getUint32

getUint32

 method is called with argument 

byteOffset

 and optional argument 

littleEndian

, the following

steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

GetViewValue

(

v

byteOffset

littleEndian

Uint32

).

When the 

setBigInt64

setBigInt64

 method is called with arguments 

byteOffset

 and 

value

 and optional argument 

littleEndian

,

the following steps are taken:

25.3.4.10  DataView.prototype.getInt16 ( 

byteOffset

 [ , 

littleEndian

 ] )

25.3.4.11  DataView.prototype.getInt32 ( 

byteOffset

 [ , 

littleEndian

 ] )

25.3.4.12  DataView.prototype.getUint8 ( 

byteOffset

 )

25.3.4.13  DataView.prototype.getUint16 ( 

byteOffset

 [ , 

littleEndian

 ] )

25.3.4.14  DataView.prototype.getUint32 ( 

byteOffset

 [ , 

littleEndian

 ] )

25.3.4.15  DataView.prototype.setBigInt64 ( 

byteOffset

value

 [ , 

littleEndian

 ] )

723

1.  Let 

v

 be the 

this

 value.

2.  Return ? 

SetViewValue

(

v

byteOffset

littleEndian

BigInt64

value

).

When the 

setBigUint64

setBigUint64

 method is called with arguments 

byteOffset

 and 

value

 and optional argument 

littleEndian

,

the following steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  Return ? 

SetViewValue

(

v

byteOffset

littleEndian

BigUint64

value

).

When the 

setFloat32

setFloat32

 method is called with arguments 

byteOffset

 and 

value

 and optional argument 

littleEndian

, the

following steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

SetViewValue

(

v

byteOffset

littleEndian

Float32

value

).

When the 

setFloat64

setFloat64

 method is called with arguments 

byteOffset

 and 

value

 and optional argument 

littleEndian

, the

following steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

SetViewValue

(

v

byteOffset

littleEndian

Float64

value

).

When the 

setInt8

setInt8

 method is called with arguments 

byteOffset

 and 

value

, the following steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  Return ? 

SetViewValue

(

v

byteOffset

true

Int8

value

).

When the 

setInt16

setInt16

 method is called with arguments 

byteOffset

 and 

value

 and optional argument 

littleEndian

, the

following steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

SetViewValue

(

v

byteOffset

littleEndian

Int16

value

).

When the 

setInt32

setInt32

 method is called with arguments 

byteOffset

 and 

value

 and optional argument 

littleEndian

, the

following steps are taken:

25.3.4.16  DataView.prototype.setBigUint64 ( 

byteOffset

value

 [ , 

littleEndian

 ] )

25.3.4.17  DataView.prototype.setFloat32 ( 

byteOffset

value

 [ , 

littleEndian

 ] )

25.3.4.18  DataView.prototype.setFloat64 ( 

byteOffset

value

 [ , 

littleEndian

 ] )

25.3.4.19  DataView.prototype.setInt8 ( 

byteOffset

value

 )

25.3.4.20  DataView.prototype.setInt16 ( 

byteOffset

value

 [ , 

littleEndian

 ] )

25.3.4.21  DataView.prototype.setInt32 ( 

byteOffset

value

 [ , 

littleEndian

 ] )

724

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

SetViewValue

(

v

byteOffset

littleEndian

Int32

value

).

When the 

setUint8

setUint8

 method is called with arguments 

byteOffset

 and 

value

, the following steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  Return ? 

SetViewValue

(

v

byteOffset

true

Uint8

value

).

When the 

setUint16

setUint16

 method is called with arguments 

byteOffset

 and 

value

 and optional argument 

littleEndian

, the

following steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

SetViewValue

(

v

byteOffset

littleEndian

Uint16

value

).

When the 

setUint32

setUint32

 method is called with arguments 

byteOffset

 and 

value

 and optional argument 

littleEndian

, the

following steps are taken:

1.  Let 

v

 be the 

this

 value.

2.  If 

littleEndian

 is not present, set 

littleEndian

 to 

false

.

3.  Return ? 

SetViewValue

(

v

byteOffset

littleEndian

Uint32

value

).

The initial value of the 

@@toStringTag

 property is the String value 

"DataView"

.

This property has the attributes { [[Writable]]: 

false

, [[Enumerable]]: 

false

, [[Configurable]]: 

true

 }.

DataView instances are ordinary objects that inherit properties from the 

DataView prototype object

. DataView

instances each have [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], and [[ByteOffset]] internal slots.

NOTE

The Atomics object:

The value of the [[DataView]] internal slot is not used within this specification. The simple
presence of that internal slot is used within the specification to identify objects created using the
DataView 

constructor

.

25.3.4.22  DataView.prototype.setUint8 ( 

byteOffset

value

 )

25.3.4.23  DataView.prototype.setUint16 ( 

byteOffset

value

 [ , 

littleEndian

 ] )

25.3.4.24  DataView.prototype.setUint32 ( 

byteOffset

value

 [ , 

littleEndian

 ] )

25.3.4.25  DataView.prototype [ @@toStringTag ]

25.3.5  Properties of DataView Instances

25.4  The Atomics Object

725

is 

%Atomics%

.

is the initial value of the 

"Atomics"

 property of the 

global object

.

is an 

ordinary object

.

has a [[Prototype]] internal slot whose value is 

%Object.prototype%

.

does not have a [[Construct]] internal method; it cannot be used as a 

constructor

 with the 

new

new

 operator.

does not have a [[Call]] internal method; it cannot be invoked as a function.

The Atomics object provides functions that operate indivisibly (atomically) on shared memory array cells as well as
functions that let agents wait for and dispatch primitive events. When used with discipline, the Atomics functions
allow multi-

agent

 programs that communicate through shared memory to execute in a well-understood order even on

parallel CPUs. The rules that govern shared-memory communication are provided by the 

memory model

, defined

below.

NOTE

The abstract operation ValidateIntegerTypedArray takes argument 

typedArray

 and optional argument 

waitable

 (a

Boolean). It performs the following steps when called:

1.  If 

waitable

 is not present, set 

waitable

 to 

false

.

2.  Let 

buffer

 be ? 

ValidateTypedArray

(

typedArray

).

3.  Let 

typeName

 be 

typedArray

.[[TypedArrayName]].

4.  Let 

type

 be the Element Type value in 

Table 60

 for 

typeName

.

5.  If 

waitable

 is 

true

, then

a.  If 

typeName

 is not 

"Int32Array"

 or 

"BigInt64Array"

, throw a 

TypeError

 exception.

6.  Else,

a.  If ! 

IsUnclampedIntegerElementType

(

type

) is 

false

 and ! 

IsBigIntElementType

(

type

) is 

false

, throw a

TypeError

 exception.

7.  Return 

buffer

.

The abstract operation ValidateAtomicAccess takes arguments 

typedArray

 and 

requestIndex

. It performs the following

steps when called:

1. 

Assert

typedArray

 is an Object that has a [[ViewedArrayBuffer]] internal slot.

2.  Let 

length

 be 

typedArray

.[[ArrayLength]].

3.  Let 

accessIndex

 be ? 

ToIndex

(

requestIndex

).

4. 

Assert

accessIndex

 

 0.

5.  If 

accessIndex

 

 

length

, throw a 

RangeError

 exception.

6.  Let 

arrayTypeName

 be 

typedArray

.[[TypedArrayName]].

7.  Let 

elementSize

 be the Element Size value specified in 

Table 60

 for 

arrayTypeName

.

8.  Let 

offset

 be 

typedArray

.[[ByteOffset]].

9.  Return (

accessIndex

 

×

 

elementSize

) + 

offset

.

For informative guidelines for programming and implementing shared memory in ECMAScript,
please see the notes at the end of the 

memory model

 section.

25.4.1  Abstract Operations for Atomics

25.4.1.1  ValidateIntegerTypedArray ( 

typedArray

 [ , 

waitable

 ] )

25.4.1.2  ValidateAtomicAccess ( 

typedArray

requestIndex

 )

726

WaiterList

 is a semantic object that contains an ordered list of those agents that are waiting on a location (

block

i

) in

shared memory; 

block

 is a 

Shared Data Block

 and 

i

 a byte offset into the memory of 

block

. A WaiterList object also

optionally contains a 

Synchronize event

 denoting the previous leaving of its critical section.

Initially a WaiterList object has an empty list and no 

Synchronize event

.

The 

agent cluster

 has a store of WaiterList objects; the store is indexed by (

block

i

). WaiterLists ar

agent

-independent:

a lookup in the store of WaiterLists by (

block

i

) will result in the same WaiterList object in any 

agent

 in the 

agent

cluster

.

Each WaiterList has a 

critical section

 that controls exclusive access to that WaiterList during evaluation. Only a single

agent

 may enter a WaiterList's critical section at one time. Entering and leaving a WaiterList's critical section is

controlled by the 

abstract operations

 

EnterCriticalSection

 and 

LeaveCriticalSection

. Operations on a WaiterList—

adding and removing waiting agents, traversing the list of agents, suspending and notifying agents on the list, setting
and retrieving the 

Synchronize event

—may only be performed by agents that have entered the WaiterList's critical

section.

The abstract operation GetWaiterList takes arguments 

block

 (a 

Shared Data Block

) and 

i

 (a non-negative 

integer

). It

performs the following steps when called:

1. 

Assert

block

 is a 

Shared Data Block

.

2. 

Assert

i

 and 

i

 + 3 are valid byte offsets within the memory of 

block

.

3. 

Assert

i

 is divisible by 4.

4.  Return the 

WaiterList

 that is referenced by the pair (

block

i

).

The abstract operation EnterCriticalSection takes argument 

WL

 (a 

WaiterList

). It performs the following steps when

called:

1. 

Assert

: The calling 

agent

 is not in the 

critical section

 for any 

WaiterList

.

2.  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).

3.  If 

WL

 has a 

Synchronize event

, then

a.  NOTE: A 

WL

 whose 

critical section

 has been entered at least once has a 

Synchronize event

 set by

LeaveCriticalSection

.

b.  Let 

execution

 be the [[CandidateExecution]] field of the 

surrounding agent

's 

Agent Record

.

c.  Let 

eventsRecord

 be the 

Agent Events Record

 in 

execution

.[[EventsRecords]] whose [[AgentSignifier]] is

AgentSignifier

().

d.  Let 

entererEventList

 be 

eventsRecord

.[[EventList]].

e.  Let 

enterEvent

 be a new 

Synchronize event

.

f.  Append 

enterEvent

 to 

entererEventList

.

g.  Let 

leaveEvent

 be the 

Synchronize event

 in 

WL

.

h.  Append (

leaveEvent

enterEvent

) to 

eventsRecord

.[[AgentSynchronizesWith]].

EnterCriticalSection has 

contention

 when an 

agent

 attempting to enter the 

critical section

 must wait for another 

agent

to leave it. When there is no contention, FIFO order of EnterCriticalSection calls is observable. When there is
contention, an implementation may choose an arbitrary order but may not cause an 

agent

 to wait indefinitely.

25.4.1.3  GetWaiterList ( 

block

i

 )

25.4.1.4  EnterCriticalSection ( 

WL

 )

727

The abstract operation LeaveCriticalSection takes argument 

WL

 (a 

WaiterList

). It performs the following steps when

called:

1. 

Assert

: The calling 

agent

 is in the 

critical section

 for 

WL

.

2.  Let 

execution

 be the [[CandidateExecution]] field of the calling surrounding's 

Agent Record

.

3.  Let 

eventsRecord

 be the 

Agent Events Record

 in 

execution

.[[EventsRecords]] whose [[AgentSignifier]] is

AgentSignifier

().

4.  Let 

leaverEventList

 be 

eventsRecord

.[[EventList]].

5.  Let 

leaveEvent

 be a new 

Synchronize event

.

6.  Append 

leaveEvent

 to 

leaverEventList

.

7.  Set the 

Synchronize event

 in 

WL

 to 

leaveEvent

.

8.  Leave the 

critical section

 for 

WL

.

The abstract operation AddWaiter takes arguments 

WL

 (a 

WaiterList

) and 

W

 (an 

agent

 signifier). It performs the

following steps when called:

1. 

Assert

: The calling 

agent

 is in the 

critical section

 for 

WL

.

2. 

Assert

W

 is not on the list of waiters in any 

WaiterList

.

3.  Add 

W

 to the end of the list of waiters in 

WL

.

The abstract operation RemoveWaiter takes arguments 

WL

 (a 

WaiterList

) and 

W

 (an 

agent

 signifier). It performs the

following steps when called:

1. 

Assert

: The calling 

agent

 is in the 

critical section

 for 

WL

.

2. 

Assert

W

 is on the list of waiters in 

WL

.

3.  Remove 

W

 from the list of waiters in 

WL

.

The abstract operation RemoveWaiters takes arguments 

WL

 (a 

WaiterList

) and 

c

 (a non-negative 

integer

 or +

). It

performs the following steps when called:

1. 

Assert

: The calling 

agent

 is in the 

critical section

 for 

WL

.

2.  Let 

L

 be a new empty 

List

.

3.  Let 

S

 be a reference to the list of waiters in 

WL

.

4.  Repeat, while 

c

 > 0 and 

S

 is not an empty 

List

,

a.  Let 

W

 be the first waiter in 

S

.

b.  Add 

W

 to the end of 

L

.

c.  Remove 

W

 from 

S

.

d.  If 

c

 is finite, set 

c

 to 

c

 - 1.

5.  Return 

L

.

25.4.1.5  LeaveCriticalSection ( 

WL

 )

25.4.1.6  AddWaiter ( 

WL

W

 )

25.4.1.7  RemoveWaiter ( 

WL

W

 )

25.4.1.8  RemoveWaiters ( 

WL

c

 )

25.4.1.9  SuspendAgent ( 

WL

W

timeout

 )

728

The abstract operation SuspendAgent takes arguments 

WL

 (a 

WaiterList

), 

W

 (an 

agent

 signifier), and 

timeout

 (a non-

negative 

integer

). It performs the following steps when called:

1. 

Assert

: The calling 

agent

 is in the 

critical section

 for 

WL

.

2. 

Assert

W

 is equivalent to 

AgentSignifier

().

3. 

Assert

W

 is on the list of waiters in 

WL

.

4. 

Assert

AgentCanSuspend

() is 

true

.

5.  Perform 

LeaveCriticalSection

(

WL

) and suspend 

W

 for up to 

timeout

 milliseconds, performing the combined

operation in such a way that a notification that arrives after the 

critical section

 is exited but before the

suspension takes effect is not lost. 

W

 can notify either because the timeout expired or because it was notified

explicitly by another 

agent

 calling 

NotifyWaiter

(

WL

W

), and not for any other reasons at all.

6.  Perform 

EnterCriticalSection

(

WL

).

7.  If 

W

 was notified explicitly by another 

agent

 calling 

NotifyWaiter

(

WL

W

), return 

true

.

8.  Return 

false

.

The abstract operation NotifyWaiter takes arguments 

WL

 (a 

WaiterList

) and 

W

 (an 

agent

 signifier). It performs the

following steps when called:

1. 

Assert

: The calling 

agent

 is in the 

critical section

 for 

WL

.

2.  Notify the 

agent

 

W

.

NOTE

The abstract operation AtomicReadModifyWrite takes arguments 

typedArray

index

value

, and 

op

 (a 

read-modify-write

modification function

). 

op

 takes two 

List

 of byte values arguments and returns a 

List

 of byte values. This 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 when called:

1.  Let 

buffer

 be ? 

ValidateIntegerTypedArray

(

typedArray

).

2.  Let 

indexedPosition

 be ? 

ValidateAtomicAccess

(

typedArray

index

).

3.  Let 

arrayTypeName

 be 

typedArray

.[[TypedArrayName]].

4.  If 

typedArray

.[[ContentType]] is 

BigInt

, let 

v

 be ? 

ToBigInt

(

value

).

5.  Otherwise, let 

v

ToIntegerOrInfinity

(

value

)).

6.  If 

IsDetachedBuffer

(

buffer

) is 

true

, throw a 

TypeError

 exception.

7.  NOTE: The above check is not redundant with the check in 

ValidateIntegerTypedArray

 because the call to

ToBigInt

 or 

ToIntegerOrInfinity

 on the preceding lines can have arbitrary side effects, which could cause the

buffer to become detached.

8.  Let 

elementType

 be the Element Type value in 

Table 60

 for 

arrayTypeName

.

9.  Return 

GetModifySetValueInBuffer

(

buffer

indexedPosition

elementType

v

op

).

The abstract operation ByteListBitwiseOp takes arguments 

op

 (a sequence of Unicode code points), 

xBytes

 (a 

List

 of

The embedding may delay notifying 

W

, e.g. for resource management reasons, but 

W

 must

eventually be notified in order to guarantee forward progress.

25.4.1.10  NotifyWaiter ( 

WL

W

 )

25.4.1.11  AtomicReadModifyWrite ( 

typedArray

index

value

op

 )

25.4.1.12  ByteListBitwiseOp ( 

op

xBytes

yBytes

 )

729

byte values), and 

yBytes

 (a 

List

 of byte values). The operation atomically performs a bitwise operation on all byte

values of the arguments and returns a 

List

 of byte values. It performs the following steps when called:

1. 

Assert

op

 is 

&&

^^

, or 

||

.

2. 

Assert

xBytes

 and 

yBytes

 have the same number of elements.

3.  Let 

result

 be a new empty 

List

.

4.  Let 

i

 be 0.

5.  For each element 

xByte

 of 

xBytes

, do

a.  Let 

yByte

 be 

yBytes

[

i

].

b.  If 

op

 is 

&&

, let 

resultByte

 be the result of applying the bitwise AND operation to 

xByte

 and 

yByte

.

c.  Else if 

op

 is 

^^

, let 

resultByte

 be the result of applying the bitwise exclusive OR (XOR) operation to 

xByte

and 

yByte

.

d.  Else, 

op

 is 

||

. Let 

resultByte

 be the result of applying the bitwise inclusive OR operation to 

xByte

 and

yByte

.

e.  Set 

i

 to 

i

 + 1.

f.  Append 

resultByte

 to the end of 

result

.

6.  Return 

result

.

The abstract operation ByteListEqual takes arguments 

xBytes

 (a 

List

 of byte values) and 

yBytes

 (a 

List

 of byte values).

It performs the following steps when called:

1.  If 

xBytes

 and 

yBytes

 do not have the same number of elements, return 

false

.

2.  Let 

i

 be 0.

3.  For each element 

xByte

 of 

xBytes

, do

a.  Let 

yByte

 be 

yBytes

[

i

].

b.  If 

xByte

 

 

yByte

, return 

false

.

c.  Set 

i

 to 

i

 + 1.

4.  Return 

true

.

The following steps are taken:

1.  Let 

type

 be the Element Type value in 

Table 60

 for 

typedArray

.[[TypedArrayName]].

2.  Let 

isLittleEndian

 be the value of the [[LittleEndian]] field of the 

surrounding agent

's 

Agent Record

.

3.  Let 

add

 be a new 

read-modify-write modification function

 with parameters (

xBytes

yBytes

) that captures 

type

and 

isLittleEndian

 and performs the following steps atomically when called:

a.  Let 

x

 be 

RawBytesToNumeric

(

type

xBytes

isLittleEndian

).

b.  Let 

y

 be 

RawBytesToNumeric

(

type

yBytes

isLittleEndian

).

c.  Let 

T

 be 

Type

(

x

).

d.  Let 

sum

 be 

T

::add(

x

y

).

e.  Let 

sumBytes

 be 

NumericToRawBytes

(

type

sum

isLittleEndian

).

f. 

Assert

sumBytes

xBytes

, and 

yBytes

 have the same number of elements.

g.  Return 

sumBytes

.

4.  Return ? 

AtomicReadModifyWrite

(

typedArray

index

value

add

).

25.4.1.13  ByteListEqual ( 

xBytes

yBytes

 )

25.4.2  Atomics.add ( 

typedArray

index

value

 )

730

The following steps are taken:

1.  Let 

and

 be a new 

read-modify-write modification function

 with parameters (

xBytes

yBytes

) that captures

nothing and performs the following steps atomically when called:

a.  Return 

ByteListBitwiseOp

(

&&

xBytes

yBytes

).

2.  Return ? 

AtomicReadModifyWrite

(

typedArray

index

value

and

).

The following steps are taken:

1.  Let 

buffer

 be ? 

ValidateIntegerTypedArray

(

typedArray

).

2.  Let 

block

 be 

buffer

.[[ArrayBufferData]].

3.  Let 

indexedPosition

 be ? 

ValidateAtomicAccess

(

typedArray

index

).

4.  Let 

arrayTypeName

 be 

typedArray

.[[TypedArrayName]].

5.  If 

typedArray

.[[ContentType]] is 

BigInt

, then

a.  Let 

expected

 be ? 

ToBigInt

(

expectedValue

).

b.  Let 

replacement

 be ? 

ToBigInt

(

replacementValue

).

6.  Else,

a.  Let 

expected

(? 

ToIntegerOrInfinity

(

expectedValue

)).

b.  Let 

replacement

ToIntegerOrInfinity

(

replacementValue

)).

7.  If 

IsDetachedBuffer

(

buffer

) is 

true

, throw a 

TypeError

 exception.

8.  NOTE: The above check is not redundant with the check in 

ValidateIntegerTypedArray

 because the call to

ToBigInt

 or 

ToIntegerOrInfinity

 on the preceding lines can have arbitrary side effects, which could cause the

buffer to become detached.

9.  Let 

elementType

 be the Element Type value in 

Table 60

 for 

arrayTypeName

.

10.  Let 

elementSize

 be the Element Size value specified in 

Table 60

 for Element Type 

elementType

.

11.  Let 

isLittleEndian

 be the value of the [[LittleEndian]] field of the 

surrounding agent

's 

Agent Record

.

12.  Let 

expectedBytes

 be 

NumericToRawBytes

(

elementType

expected

isLittleEndian

).

13.  Let 

replacementBytes

 be 

NumericToRawBytes

(

elementType

replacement

isLittleEndian

).

14.  If 

IsSharedArrayBuffer

(

buffer

) is 

true

, then

a.  Let 

execution

 be the [[CandidateExecution]] field of the 

surrounding agent

's 

Agent Record

.

b.  Let 

eventList

 be the [[EventList]] field of the element in 

execution

.[[EventsRecords]] whose

[[AgentSignifier]] is 

AgentSignifier

().

c.  Let 

rawBytesRead

 be a 

List

 of length 

elementSize

 whose elements are nondeterministically chosen byte

values.

d.  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.

e.  NOTE: The comparison of the expected value and the read value is performed outside of the 

read-

modify-write modification function

 to avoid needlessly strong synchronization when the expected value

is not equal to the read value.

f.  If 

ByteListEqual

(

rawBytesRead

expectedBytes

) is 

true

, then

i.  Let 

second

 be a new 

read-modify-write modification function

 with parameters (

oldBytes

newBytes

)

that captures nothing and performs the following steps atomically when called:

1.  Return 

newBytes

.

25.4.3  Atomics.and ( 

typedArray

index

value

 )

25.4.4  Atomics.compareExchange ( 

typedArray

index

expectedValue

replacementValue

 )

731

ii.  Let 

event

 be 

ReadModifyWriteSharedMemory

 { [[Order]]: 

SeqCst

, [[NoTear]]: 

true

, [[Block]]:

block

, [[ByteIndex]]: 

indexedPosition

, [[ElementSize]]: 

elementSize

, [[Payload]]: 

replacementBytes

,

[[ModifyOp]]: 

second

 }.

g.  Else,

i.  Let 

event

 be 

ReadSharedMemory

 { [[Order]]: 

SeqCst

, [[NoTear]]: 

true

, [[Block]]: 

block

,

[[ByteIndex]]: 

indexedPosition

, [[ElementSize]]: 

elementSize

 }.

h.  Append 

event

 to 

eventList

.

i.  Append 

Chosen Value Record

 { [[Event]]: 

event

, [[ChosenValue]]: 

rawBytesRead

 } to 

execution

.

[[ChosenValues]].

15.  Else,

a.  Let 

rawBytesRead

 be a 

List

 of length 

elementSize

 whose elements are the sequence of 

elementSize

 bytes

starting with 

block

[

indexedPosition

].

b.  If 

ByteListEqual

(

rawBytesRead

expectedBytes

) is 

true

, then

i.  Store the individual bytes of 

replacementBytes

 into 

block

, starting at 

block

[

indexedPosition

].

16.  Return 

RawBytesToNumeric

(

elementType

rawBytesRead

isLittleEndian

).

The following steps are taken:

1.  Let 

second

 be a new 

read-modify-write modification function

 with parameters (

oldBytes

newBytes

) that captures

nothing and performs the following steps atomically when called:

a.  Return 

newBytes

.

2.  Return ? 

AtomicReadModifyWrite

(

typedArray

index

value

second

).

The following steps are taken:

1.  Let 

n

 be ? 

ToIntegerOrInfinity

(

size

).

2.  Let 

AR

 be the 

Agent Record

 of the 

surrounding agent

.

3.  If 

n

 = 1, return 

AR

.[[IsLockFree1]].

4.  If 

n

 = 2, return 

AR

.[[IsLockFree2]].

5.  If 

n

 = 4, return 

true

.

6.  If 

n

 = 8, return 

AR

.[[IsLockFree8]].

7.  Return 

false

.

25.4.5  Atomics.exchange ( 

typedArray

index

value

 )

25.4.6  Atomics.isLockFree ( 

size

 )

732

NOTE

The following steps are taken:

1.  Let 

buffer

 be ? 

ValidateIntegerTypedArray

(

typedArray

).

2.  Let 

indexedPosition

 be ? 

ValidateAtomicAccess

(

typedArray

index

).

3.  If 

IsDetachedBuffer

(

buffer

) is 

true

, throw a 

TypeError

 exception.

4.  NOTE: The above check is not redundant with the check in 

ValidateIntegerTypedArray

 because the call to

ValidateAtomicAccess

 on the preceding line can have arbitrary side effects, which could cause the buffer to

become detached.

5.  Let 

arrayTypeName

 be 

typedArray

.[[TypedArrayName]].

6.  Let 

elementType

 be the Element Type value in 

Table 60

 for 

arrayTypeName

.

7.  Return 

GetValueFromBuffer

(

buffer

indexedPosition

elementType

true

SeqCst

).

The following steps are taken:

1.  Let 

or

 be a new 

read-modify-write modification function

 with parameters (

xBytes

yBytes

) that captures nothing

and performs the following steps atomically when called:

a.  Return 

ByteListBitwiseOp

(

||

xBytes

yBytes

).

2.  Return ? 

AtomicReadModifyWrite

(

typedArray

index

value

or

).

The following steps are taken:

1.  Let 

buffer

 be ? 

ValidateIntegerTypedArray

(

typedArray

).

2.  Let 

indexedPosition

 be ? 

ValidateAtomicAccess

(

typedArray

index

).

3.  Let 

arrayTypeName

 be 

typedArray

.[[TypedArrayName]].

4.  If 

arrayTypeName

 is 

"BigUint64Array"

 or 

"BigInt64Array"

, let 

v

 be ? 

ToBigInt

(

value

).

5.  Otherwise, let 

v

ToIntegerOrInfinity

(

value

)).

Atomics.isLockFree

Atomics.isLockFree

() is an optimization primitive. The intuition is that if the atomic step

of an atomic primitive (

compareExchange

compareExchange

load

load

store

store

add

add

sub

sub

and

and

or

or

xor

xor

, or

exchange

exchange

) on a datum of size 

n

 bytes will be performed without the calling 

agent

 acquiring a

lock outside the 

n

 bytes comprising the datum, then 

Atomics.isLockFree

Atomics.isLockFree

(

n

) will return

true

. High-performance algorithms will use 

Atomics.isLockFree

Atomics.isLockFree

 to determine whether to

use locks or atomic operations in critical sections. If an atomic primitive is not lock-free then it is
often more efficient for an algorithm to provide its own locking.

Atomics.isLockFree

Atomics.isLockFree

(4) always returns 

true

 as that can be supported on all known

relevant hardware. Being able to assume this will generally simplify programs.

Regardless of the value of 

Atomics.isLockFree

Atomics.isLockFree

, all atomic operations are guaranteed to be

atomic. For example, they will never have a visible operation take place in the middle of the
operation (e.g., "tearing").

25.4.7  Atomics.load ( 

typedArray

index

 )

25.4.8  Atomics.or ( 

typedArray

index

value

 )

25.4.9  Atomics.store ( 

typedArray

index

value

 )

733

6.  If 

IsDetachedBuffer

(

buffer

) is 

true

, throw a 

TypeError

 exception.

7.  NOTE: The above check is not redundant with the check in 

ValidateIntegerTypedArray

 because the call to

ToBigInt

 or 

ToIntegerOrInfinity

 on the preceding lines can have arbitrary side effects, which could cause the

buffer to become detached.

8.  Let 

elementType

 be the Element Type value in 

Table 60

 for 

arrayTypeName

.

9.  Perform 

SetValueInBuffer

(

buffer

indexedPosition

elementType

v

true

SeqCst

).

10.  Return 

v

.

The following steps are taken:

1.  Let 

type

 be the Element Type value in 

Table 60

 for 

typedArray

.[[TypedArrayName]].

2.  Let 

isLittleEndian

 be the value of the [[LittleEndian]] field of the 

surrounding agent

's 

Agent Record

.

3.  Let 

subtract

 be a new 

read-modify-write modification function

 with parameters (

xBytes

yBytes

) that captures

type

 and 

isLittleEndian

 and performs the following steps atomically when called:

a.  Let 

x

 be 

RawBytesToNumeric

(

type

xBytes

isLittleEndian

).

b.  Let 

y

 be 

RawBytesToNumeric

(

type

yBytes

isLittleEndian

).

c.  Let 

T

 be 

Type

(

x

).

d.  Let 

difference

 be 

T

::subtract(

x

y

).

e.  Let 

differenceBytes

 be 

NumericToRawBytes

(

type

difference

isLittleEndian

).

f. 

Assert

differenceBytes

xBytes

, and 

yBytes

 have the same number of elements.

g.  Return 

differenceBytes

.

4.  Return ? 

AtomicReadModifyWrite

(

typedArray

index

value

subtract

).

Atomics.wait

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:

1.  Let 

buffer

 be ? 

ValidateIntegerTypedArray

(

typedArray

true

).

2.  If 

IsSharedArrayBuffer

(

buffer

) is 

false

, throw a 

TypeError

 exception.

3.  Let 

indexedPosition

 be ? 

ValidateAtomicAccess

(

typedArray

index

).

4.  Let 

arrayTypeName

 be 

typedArray

.[[TypedArrayName]].

5.  If 

arrayTypeName

 is 

"BigInt64Array"

, let 

v

 be ? 

ToBigInt64

(

value

).

6.  Otherwise, let 

v

 be ? 

ToInt32

(

value

).

7.  Let 

q

 be ? 

ToNumber

(

timeout

).

8.  If 

q

 is 

NaN

 or 

+

𝔽

, let 

t

 be +

; else if 

q

 is 

-

𝔽

, let 

t

 be 0; else let 

t

 be 

max

(

q

), 0).

9.  Let 

B

 be 

AgentCanSuspend

().

10.  If 

B

 is 

false

, throw a 

TypeError

 exception.

11.  Let 

block

 be 

buffer

.[[ArrayBufferData]].

12.  Let 

WL

 be 

GetWaiterList

(

block

indexedPosition

).

13.  Perform 

EnterCriticalSection

(

WL

).

14.  Let 

elementType

 be the Element Type value in 

Table 60

 for 

arrayTypeName

.

15.  Let 

w

 be ! 

GetValueFromBuffer

(

buffer

indexedPosition

elementType

true

SeqCst

).

16.  If 

v

 

 

w

, then

a.  Perform 

LeaveCriticalSection

(

WL

).

b.  Return the String 

"not-equal"

.

25.4.10  Atomics.sub ( 

typedArray

index

value

 )

25.4.11  Atomics.wait ( 

typedArray

index

value

timeout

 )

734

17.  Let 

W

 be 

AgentSignifier

().

18.  Perform 

AddWaiter

(

WL

W

).

19.  Let 

notified

 be 

SuspendAgent

(

WL

W

t

).

20.  If 

notified

 is 

true

, then

a. 

Assert

W

 is not on the list of waiters in 

WL

.

21.  Else,

a.  Perform 

RemoveWaiter

(

WL

W

).

22.  Perform 

LeaveCriticalSection

(

WL

).

23.  If 

notified

 is 

true

, return the String 

"ok"

.

24.  Return the String 

"timed-out"

.

Atomics.notify

Atomics.notify

 notifies some agents that are sleeping in the wait queue. The following steps are taken:

1.  Let 

buffer

 be ? 

ValidateIntegerTypedArray

(

typedArray

true

).

2.  Let 

indexedPosition

 be ? 

ValidateAtomicAccess

(

typedArray

index

).

3.  If 

count

 is 

undefined

, let 

c

 be +

.

4.  Else,

a.  Let 

intCount

 be ? 

ToIntegerOrInfinity

(

count

).

b.  Let 

c

 be 

max

(

intCount

, 0).

5.  Let 

block

 be 

buffer

.[[ArrayBufferData]].

6.  Let 

arrayTypeName

 be 

typedArray

.[[TypedArrayName]].

7.  If 

IsSharedArrayBuffer

(

buffer

) is 

false

, return 

+0

𝔽

.

8.  Let 

WL

 be 

GetWaiterList

(

block

indexedPosition

).

9.  Let 

n

 be 0.

10.  Perform 

EnterCriticalSection

(

WL

).

11.  Let 

S

 be 

RemoveWaiters

(

WL

c

).

12.  Repeat, while 

S

 is not an empty 

List

,

a.  Let 

W

 be the first 

agent

 in 

S

.

b.  Remove 

W

 from the front of 

S

.

c.  Perform 

NotifyWaiter

(

WL

W

).

d.  Set 

n

 to 

n

 + 1.

13.  Perform 

LeaveCriticalSection

(

WL

).

14.  Return 

n

).

The following steps are taken:

1.  Let 

xor

 be a new 

read-modify-write modification function

 with parameters (

xBytes

yBytes

) that captures

nothing and performs the following steps atomically when called:

a.  Return 

ByteListBitwiseOp

(

^^

xBytes

yBytes

).

2.  Return ? 

AtomicReadModifyWrite

(

typedArray

index

value

xor

).

The initial value of the 

@@toStringTag

 property is the String value 

"Atomics"

.

25.4.12  Atomics.notify ( 

typedArray

index

count

 )

25.4.13  Atomics.xor ( 

typedArray

index

value

 )

25.4.14  Atomics [ @@toStringTag ]

735

 

 

 

 

 

 

 

Content      ..     53      54      55      56     ..