Skip to content

24 Structured Data

24.1 ArrayBuffer Objects

24.1.1 Abstract Operations For ArrayBuffer Objects

24.1.1.1 AllocateArrayBuffer ( constructor, byteLength )

The abstract operation AllocateArrayBuffer with arguments constructor and byteLength is used to create an ArrayBuffer object. It performs the following steps:

  1. Let obj be ? OrdinaryCreateFromConstructor(constructor, "%ArrayBufferPrototype%", « [[ArrayBufferData]], [[ArrayBufferByteLength]] »).
  2. Assert: byteLength is an integer value ≥ 0.
  3. Let block be ? CreateByteDataBlock(byteLength).
  4. Set obj.[[ArrayBufferData]] to block.
  5. Set obj.[[ArrayBufferByteLength]] to byteLength.
  6. Return obj.

24.1.1.2 IsDetachedBuffer ( arrayBuffer )

The abstract operation IsDetachedBuffer with argument arrayBuffer performs the following steps:

  1. Assert: Type(arrayBuffer) is Object and it has an [[ArrayBufferData]] internal slot.
  2. If arrayBuffer.[[ArrayBufferData]] is null, return true.
  3. Return false.

24.1.1.3 DetachArrayBuffer ( arrayBuffer )

The abstract operation DetachArrayBuffer with argument arrayBuffer performs the following steps:

  1. Assert: Type(arrayBuffer) is Object and it has [[ArrayBufferData]] and [[ArrayBufferByteLength]] internal slots.
  2. Assert: IsSharedArrayBuffer(arrayBuffer) is false.
  3. Set arrayBuffer.[[ArrayBufferData]] to null.
  4. Set arrayBuffer.[[ArrayBufferByteLength]] to 0.
  5. Return NormalCompletion(null).
Note

Detaching an ArrayBuffer instance disassociates the Data Block used as its backing store from the instance and sets the byte length of the buffer to 0. No operations defined by this specification use the DetachArrayBuffer abstract operation. However, an ECMAScript implementation or host environment may define such operations.

24.1.1.4 CloneArrayBuffer ( srcBuffer, srcByteOffset, srcLength [ , cloneConstructor ] )

The abstract operation CloneArrayBuffer takes four parameters, an ArrayBuffer srcBuffer, an integer offset srcByteOffset, an integer length srcLength, and optionally a constructor function cloneConstructor. It creates a new ArrayBuffer whose data is a copy of srcBuffer's data over the range starting at srcByteOffset and continuing for srcLength bytes. This operation performs the following steps:

  1. Assert: Type(srcBuffer) is Object and it has an [[ArrayBufferData]] internal slot.
  2. If cloneConstructor is not present, then
    1. Set cloneConstructor to ? SpeciesConstructor(srcBuffer, %ArrayBuffer%).
    2. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception.
  3. Else, Assert: IsConstructor(cloneConstructor) is true.
  4. Let srcBlock be srcBuffer.[[ArrayBufferData]].
  5. Let targetBuffer be ? AllocateArrayBuffer(cloneConstructor, srcLength).
  6. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception.
  7. Let targetBlock be targetBuffer.[[ArrayBufferData]].
  8. Perform CopyDataBlockBytes(targetBlock, 0, srcBlock, srcByteOffset, srcLength).
  9. Return targetBuffer.

24.1.1.5 RawBytesToNumber( type, rawBytes, isLittleEndian )

The abstract operation RawBytesToNumber takes three parameters, a String type, a List rawBytes, and a Boolean isLittleEndian. This operation performs the following steps:

  1. Let elementSize be the Number value of the Element Size value specified in Table 50 for Element Type type.
  2. If isLittleEndian is false, reverse the order of the elements of rawBytes.
  3. If type is "Float32", then
    1. Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2008 binary32 value.
    2. If value is an IEEE 754-2008 binary32 NaN value, return the NaN Number value.
    3. Return the Number value that corresponds to value.
  4. If type is "Float64", then
    1. Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2008 binary64 value.
    2. If value is an IEEE 754-2008 binary64 NaN value, return the NaN Number value.
    3. Return the Number value that corresponds to value.
  5. If the first code unit of type is "U", then
    1. Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of an unsigned little-endian binary number.
  6. Else,
    1. Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of a binary little-endian 2's complement number of bit length elementSize × 8.
  7. Return the Number value that corresponds to intValue.

24.1.1.6 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isTypedArray, order [ , isLittleEndian ] )

The abstract operation GetValueFromBuffer takes six parameters, an ArrayBuffer or SharedArrayBuffer arrayBuffer, an integer byteIndex, a String type, a Boolean isTypedArray, a String order, and optionally a Boolean isLittleEndian. This operation performs the following steps:

  1. Assert: IsDetachedBuffer(arrayBuffer) is false.
  2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.
  3. Assert: byteIndex is an integer value ≥ 0.
  4. Let block be arrayBuffer.[[ArrayBufferData]].
  5. Let elementSize be the Number value of the Element Size value specified in Table 50 for Element Type type.
  6. If IsSharedArrayBuffer(arrayBuffer) is true, then
    1. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
    2. Let eventList be the [[EventList]] field of the element in execution.[[EventLists]] whose [[AgentSignifier]] is AgentSignifier().
    3. If isTypedArray is true and type is "Int8", "Uint8", "Int16", "Uint16", "Int32", or "Uint32", let noTear be true; otherwise let noTear be false.
    4. Let rawValue be a List of length elementSize of nondeterministically chosen byte values.
    5. NOTE: In implementations, rawValue is the result of a non-atomic or atomic read instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
    6. Let readEvent be ReadSharedMemory{ [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize }.
    7. Append readEvent to eventList.
    8. Append Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: rawValue } to execution.[[ChosenValues]].
  7. Else, let rawValue be a List of elementSize containing, in order, the elementSize sequence of bytes starting with block[byteIndex].
  8. If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  9. Return RawBytesToNumber(type, rawValue, isLittleEndian).

24.1.1.7 NumberToRawBytes( type, value, isLittleEndian )

The abstract operation NumberToRawBytes takes three parameters, a String type, a Number value, and a Boolean isLittleEndian. This operation performs the following steps:

  1. If type is "Float32", then
    1. Let rawBytes be a List containing the 4 bytes that are the result of converting value to IEEE 754-2008 binary32 format using “Round to nearest, ties to even” rounding mode. If isLittleEndian is false, the bytes are arranged in big endian order. Otherwise, the bytes are arranged in little endian order. If value is NaN, rawBytes may be set to any implementation chosen IEEE 754-2008 binary32 format Not-a-Number encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value.
  2. Else if type is "Float64", then
    1. Let rawBytes be a List containing the 8 bytes that are the IEEE 754-2008 binary64 format encoding of value. If isLittleEndian is false, the bytes are arranged in big endian order. Otherwise, the bytes are arranged in little endian order. If value is NaN, rawBytes may be set to any implementation chosen IEEE 754-2008 binary64 format Not-a-Number encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value.
  3. Else,
    1. Let n be the Number value of the Element Size specified in Table 50 for Element Type type.
    2. Let convOp be the abstract operation named in the Conversion Operation column in Table 50 for Element Type type.
    3. Let intValue be convOp(value).
    4. If intValue ≥ 0, then
      1. Let rawBytes be a List containing the n-byte binary encoding of intValue. If isLittleEndian is false, the bytes are ordered in big endian order. Otherwise, the bytes are ordered in little endian order.
    5. Else,
      1. Let rawBytes be a List containing the n-byte binary 2's complement encoding of intValue. If isLittleEndian is false, the bytes are ordered in big endian order. Otherwise, the bytes are ordered in little endian order.
  4. Return rawBytes.

24.1.1.8 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order [ , isLittleEndian ] )

The abstract operation SetValueInBuffer takes seven parameters, an ArrayBuffer or SharedArrayBuffer arrayBuffer, an integer byteIndex, a String type, a Number value, a Boolean isTypedArray, a String order, and optionally a Boolean isLittleEndian. This operation performs the following steps:

  1. Assert: IsDetachedBuffer(arrayBuffer) is false.
  2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.
  3. Assert: byteIndex is an integer value ≥ 0.
  4. Assert: Type(value) is Number.
  5. Let block be arrayBuffer.[[ArrayBufferData]].
  6. Let elementSize be the Number value of the Element Size value specified in Table 50 for Element Type type.
  7. If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  8. Let rawBytes be NumberToRawBytes(type, value, isLittleEndian).
  9. If IsSharedArrayBuffer(arrayBuffer) is true, then
    1. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
    2. Let eventList be the [[EventList]] field of the element in execution.[[EventLists]] whose [[AgentSignifier]] is AgentSignifier().
    3. If isTypedArray is true and type is "Int8", "Uint8", "Int16", "Uint16", "Int32", or "Uint32", let noTear be true; otherwise let noTear be false.
    4. Append WriteSharedMemory{ [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes } to eventList.
  10. Else, store the individual bytes of rawBytes into block, in order, starting at block[byteIndex].
  11. Return NormalCompletion(undefined).

24.1.1.9 GetModifySetValueInBuffer( arrayBuffer, byteIndex, type, value, op [ , isLittleEndian ] )

The abstract operation GetModifySetValueInBuffer takes six parameters, a SharedArrayBuffer arrayBuffer, a nonnegative integer byteIndex, a String type, a Number value, a semantic function op, and optionally a Boolean isLittleEndian. This operation performs the following steps:

  1. Assert: IsSharedArrayBuffer(arrayBuffer) is true.
  2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.
  3. Assert: byteIndex is an integer value ≥ 0.
  4. Assert: Type(value) is Number.
  5. Let block be arrayBuffer.[[ArrayBufferData]].
  6. Let elementSize be the Number value of the Element Size value specified in Table 50 for Element Type type.
  7. If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  8. Let rawBytes be NumberToRawBytes(type, value, isLittleEndian).
  9. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
  10. Let eventList be the [[EventList]] field of the element in execution.[[EventLists]] whose [[AgentSignifier]] is AgentSignifier().
  11. Let rawBytesRead be a List of length elementSize of nondeterministically chosen byte values.
  12. 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.
  13. Let rmwEvent be ReadModifyWriteSharedMemory{ [[Order]]: "SeqCst", [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes, [[ModifyOp]]: op }.
  14. Append rmwEvent to eventList.
  15. Append Chosen Value Record { [[Event]]: rmwEvent, [[ChosenValue]]: rawBytesRead } to execution.[[ChosenValues]].
  16. Return RawBytesToNumber(type, rawBytesRead, isLittleEndian).

24.1.2 The ArrayBuffer Constructor

The ArrayBuffer constructor is the %ArrayBuffer% intrinsic object and the initial value of the ArrayBuffer property of the global object. When called as a constructor it creates and initializes a new ArrayBuffer object. ArrayBuffer is not intended to be called as a function and will throw an exception when called in that manner.

The ArrayBuffer constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified ArrayBuffer behaviour must include a super call to the ArrayBuffer constructor to create and initialize subclass instances with the internal state necessary to support the ArrayBuffer.prototype built-in methods.

24.1.2.1 ArrayBuffer ( length )

When the ArrayBuffer function is called with argument length, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let byteLength be ? ToIndex(length).
  3. Return ? AllocateArrayBuffer(NewTarget, byteLength).

24.1.3 Properties of the ArrayBuffer Constructor

The value of the [[Prototype]] internal slot of the ArrayBuffer constructor is the intrinsic object %FunctionPrototype%.

The ArrayBuffer constructor has the following properties:

24.1.3.1 ArrayBuffer.isView ( arg )

The isView function takes one argument arg, and performs, the following steps are taken:

  1. If Type(arg) is not Object, return false.
  2. If arg has a [[ViewedArrayBuffer]] internal slot, return true.
  3. Return false.

24.1.3.2 ArrayBuffer.prototype

The initial value of ArrayBuffer.prototype is the intrinsic object %ArrayBufferPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.1.3.3 get ArrayBuffer [ @@species ]

ArrayBuffer[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

Note

ArrayBuffer prototype methods normally use their this object's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.

24.1.4 Properties of the ArrayBuffer Prototype Object

The ArrayBuffer prototype object is the intrinsic object %ArrayBufferPrototype%. The value of the [[Prototype]] internal slot of the ArrayBuffer prototype object is the intrinsic object %ObjectPrototype%. The ArrayBuffer prototype object is an ordinary object. It does not have an [[ArrayBufferData]] or [[ArrayBufferByteLength]] internal slot.

24.1.4.1 get ArrayBuffer.prototype.byteLength

ArrayBuffer.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. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception.
  4. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  5. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  6. Let length be O.[[ArrayBufferByteLength]].
  7. Return length.

24.1.4.2 ArrayBuffer.prototype.constructor

The initial value of ArrayBuffer.prototype.constructor is the intrinsic object %ArrayBuffer%.

24.1.4.3 ArrayBuffer.prototype.slice ( start, end )

The following steps are taken:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception.
  4. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  5. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  6. Let len be O.[[ArrayBufferByteLength]].
  7. Let relativeStart be ? ToInteger(start).
  8. If relativeStart < 0, let first be max((len + relativeStart), 0); else let first be min(relativeStart, len).
  9. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToInteger(end).
  10. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let final be min(relativeEnd, len).
  11. Let newLen be max(final-first, 0).
  12. Let ctor be ? SpeciesConstructor(O, %ArrayBuffer%).
  13. Let new be ? Construct(ctor, « newLen »).
  14. If new does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception.
  15. If IsSharedArrayBuffer(new) is true, throw a TypeError exception.
  16. If IsDetachedBuffer(new) is true, throw a TypeError exception.
  17. If SameValue(new, O) is true, throw a TypeError exception.
  18. If new.[[ArrayBufferByteLength]] < newLen, throw a TypeError exception.
  19. NOTE: Side-effects of the above steps may have detached O.
  20. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  21. Let fromBuf be O.[[ArrayBufferData]].
  22. Let toBuf be new.[[ArrayBufferData]].
  23. Perform CopyDataBlockBytes(toBuf, 0, fromBuf, first, newLen).
  24. Return new.

24.1.4.4 ArrayBuffer.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "ArrayBuffer".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.1.5 Properties of the ArrayBuffer Instances

ArrayBuffer instances inherit properties from the ArrayBuffer prototype object. ArrayBuffer instances each have an [[ArrayBufferData]] internal slot and an [[ArrayBufferByteLength]] internal slot.

ArrayBuffer instances whose [[ArrayBufferData]] is null are considered to be detached and all operators to access or modify data contained in the ArrayBuffer instance will fail.

24.2 SharedArrayBuffer Objects

24.2.1 Abstract Operations for SharedArrayBuffer Objects

24.2.1.1 AllocateSharedArrayBuffer( constructor, byteLength )

The abstract operation AllocateSharedArrayBuffer with arguments constructor and byteLength is used to create a SharedArrayBuffer object. It performs the following steps:

  1. Let obj be ? OrdinaryCreateFromConstructor(constructor, "%SharedArrayBufferPrototype%", « [[ArrayBufferData]], [[ArrayBufferByteLength]] »).
  2. Assert: byteLength is a nonnegative integer.
  3. Let block be ? CreateSharedByteDataBlock(byteLength).
  4. Set obj.[[ArrayBufferData]] to block.
  5. Set obj.[[ArrayBufferByteLength]] to byteLength.
  6. Return obj.

24.2.1.2 IsSharedArrayBuffer( obj )

IsSharedArrayBuffer tests whether an object is an ArrayBuffer, a SharedArrayBuffer, or a subtype of either. It performs the following steps:

  1. Assert: Type(obj) is Object and it has an [[ArrayBufferData]] internal slot.
  2. Let bufferData be obj.[[ArrayBufferData]].
  3. If bufferData is null, return false.
  4. If bufferData is a Data Block, return false.
  5. Assert: bufferData is a Shared Data Block.
  6. Return true.

24.2.2 The SharedArrayBuffer Constructor

The SharedArrayBuffer constructor is the %SharedArrayBuffer% intrinsic object and the initial value of the SharedArrayBuffer property of the global object. When called as a constructor it creates and initializes a new SharedArrayBuffer object. SharedArrayBuffer is not intended to be called as a function and will throw an exception when called in that manner.

The SharedArrayBuffer constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified SharedArrayBuffer behaviour must include a super call to the SharedArrayBuffer constructor to create and initialize subclass instances with the internal state necessary to support the SharedArrayBuffer.prototype built-in methods.

Note

Unlike an ArrayBuffer, a SharedArrayBuffer cannot become detached, and its internal [[ArrayBufferData]] slot is never null.

24.2.2.1 SharedArrayBuffer( length )

When the SharedArrayBuffer function is called with optional argument length, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let byteLength be ? ToIndex(length).
  3. Return ? AllocateSharedArrayBuffer(NewTarget, byteLength).

24.2.3 Properties of the SharedArrayBuffer Constructor

The value of the [[Prototype]] internal slot of the SharedArrayBuffer constructor is the intrinsic object %FunctionPrototype%.

The SharedArrayBuffer constructor has the following properties:

24.2.3.1 SharedArrayBuffer.prototype

The initial value of SharedArrayBuffer.prototype is the intrinsic object %SharedArrayBufferPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.2.3.2 get SharedArrayBuffer [ @@species ]

SharedArrayBuffer[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

24.2.4 Properties of the SharedArrayBuffer Prototype Object

The SharedArrayBuffer prototype object is the intrinsic object %SharedArrayBufferPrototype%. The value of the [[Prototype]] internal slot of the SharedArrayBuffer prototype object is the intrinsic object %ObjectPrototype%. The SharedArrayBuffer prototype object is an ordinary object. It does not have an [[ArrayBufferData]] or [[ArrayBufferByteLength]] internal slot.

24.2.4.1 get SharedArrayBuffer.prototype.byteLength

SharedArrayBuffer.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. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception.
  4. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  5. Let length be O.[[ArrayBufferByteLength]].
  6. Return length.

24.2.4.2 SharedArrayBuffer.prototype.constructor

The initial value of SharedArrayBuffer.prototype.constructor is the intrinsic object %SharedArrayBuffer%.

24.2.4.3 SharedArrayBuffer.prototype.slice( start, end )

The following steps are taken:

  1. Let O be the this value.
  2. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception.
  4. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  5. Let len be O.[[ArrayBufferByteLength]].
  6. Let relativeStart be ? ToInteger(start).
  7. If relativeStart < 0, let first be max((len + relativeStart), 0); else let first be min(relativeStart, len).
  8. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToInteger(end).
  9. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let final be min(relativeEnd, len).
  10. Let newLen be max(final - first, 0).
  11. Let ctor be ? SpeciesConstructor(O, %SharedArrayBuffer%).
  12. Let new be ? Construct(ctor, « newLen »).
  13. If new does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception.
  14. If IsSharedArrayBuffer(new) is false, throw a TypeError exception.
  15. If new.[[ArrayBufferData]] and O.[[ArrayBufferData]] are the same Shared Data Block values, throw a TypeError exception.
  16. If new.[[ArrayBufferByteLength]] < newLen, throw a TypeError exception.
  17. Let fromBuf be O.[[ArrayBufferData]].
  18. Let toBuf be new.[[ArrayBufferData]].
  19. Perform CopyDataBlockBytes(toBuf, 0, fromBuf, first, newLen).
  20. Return new.

24.2.4.4 SharedArrayBuffer.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "SharedArrayBuffer".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.2.5 Properties of the SharedArrayBuffer Instances

SharedArrayBuffer instances inherit properties from the SharedArrayBuffer prototype object. SharedArrayBuffer instances each have an [[ArrayBufferData]] internal slot and an [[ArrayBufferByteLength]] internal slot.

Note

SharedArrayBuffer instances, unlike ArrayBuffer instances, are never detached.

24.3 DataView Objects

24.3.1 Abstract Operations For DataView Objects

24.3.1.1 GetViewValue ( view, requestIndex, isLittleEndian, type )

The abstract operation GetViewValue with arguments view, requestIndex, isLittleEndian, and type is used by functions on DataView instances to retrieve values from the view's buffer. It performs the following steps:

  1. If Type(view) is not Object, throw a TypeError exception.
  2. If view does not have a [[DataView]] internal slot, throw a TypeError exception.
  3. Assert: view has a [[ViewedArrayBuffer]] internal slot.
  4. Let getIndex be ? ToIndex(requestIndex).
  5. Set isLittleEndian to ToBoolean(isLittleEndian).
  6. Let buffer be view.[[ViewedArrayBuffer]].
  7. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  8. Let viewOffset be view.[[ByteOffset]].
  9. Let viewSize be view.[[ByteLength]].
  10. Let elementSize be the Number value of the Element Size value specified in Table 50 for Element Type type.
  11. If getIndex + elementSize > viewSize, throw a RangeError exception.
  12. Let bufferIndex be getIndex + viewOffset.
  13. Return GetValueFromBuffer(buffer, bufferIndex, type, false, "Unordered", isLittleEndian).

24.3.1.2 SetViewValue ( view, requestIndex, isLittleEndian, type, value )

The abstract operation SetViewValue with arguments view, requestIndex, isLittleEndian, type, and value is used by functions on DataView instances to store values into the view's buffer. It performs the following steps:

  1. If Type(view) is not Object, throw a TypeError exception.
  2. If view does not have a [[DataView]] internal slot, throw a TypeError exception.
  3. Assert: view has a [[ViewedArrayBuffer]] internal slot.
  4. Let getIndex be ? ToIndex(requestIndex).
  5. Let numberValue be ? ToNumber(value).
  6. Set isLittleEndian to ToBoolean(isLittleEndian).
  7. Let buffer be view.[[ViewedArrayBuffer]].
  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 Number value of the Element Size value specified in Table 50 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).

24.3.2 The DataView Constructor

The DataView constructor is the %DataView% intrinsic object and the initial value of the DataView property of the global object. When called as a constructor it creates and initializes a new DataView object. DataView is not intended to be called as a function and will throw an exception when called in that manner.

The DataView constructor is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified DataView behaviour must include a super call to the DataView constructor to create and initialize subclass instances with the internal state necessary to support the DataView.prototype built-in methods.

24.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] )

When the DataView is called with at least one argument buffer, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If Type(buffer) is not Object, throw a TypeError exception.
  3. If buffer does not have an [[ArrayBufferData]] internal slot, throw a TypeError exception.
  4. Let offset be ? ToIndex(byteOffset).
  5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  6. Let bufferByteLength be buffer.[[ArrayBufferByteLength]].
  7. If offset > bufferByteLength, throw a RangeError exception.
  8. If byteLength is either not present or undefined, then
    1. Let viewByteLength be bufferByteLength - offset.
  9. Else,
    1. Let viewByteLength be ? ToIndex(byteLength).
    2. If offset+viewByteLength > bufferByteLength, throw a RangeError exception.
  10. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%DataViewPrototype%", « [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] »).
  11. Set O.[[ViewedArrayBuffer]] to buffer.
  12. Set O.[[ByteLength]] to viewByteLength.
  13. Set O.[[ByteOffset]] to offset.
  14. Return O.

24.3.3 Properties of the DataView Constructor

The value of the [[Prototype]] internal slot of the DataView constructor is the intrinsic object %FunctionPrototype%.

The DataView constructor has the following properties:

24.3.3.1 DataView.prototype

The initial value of DataView.prototype is the intrinsic object %DataViewPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.3.4 Properties of the DataView Prototype Object

The DataView prototype object is the intrinsic object %DataViewPrototype%. The value of the [[Prototype]] internal slot of the DataView prototype object is the intrinsic object %ObjectPrototype%. The DataView prototype object is an ordinary object. It does not have a [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], or [[ByteOffset]] internal slot.

24.3.4.1 get 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. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have a [[DataView]] internal slot, throw a TypeError exception.
  4. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  5. Let buffer be O.[[ViewedArrayBuffer]].
  6. Return buffer.

24.3.4.2 get 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. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have a [[DataView]] internal slot, throw a TypeError exception.
  4. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  5. Let buffer be O.[[ViewedArrayBuffer]].
  6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  7. Let size be O.[[ByteLength]].
  8. Return size.

24.3.4.3 get 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. If Type(O) is not Object, throw a TypeError exception.
  3. If O does not have a [[DataView]] internal slot, throw a TypeError exception.
  4. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  5. Let buffer be O.[[ViewedArrayBuffer]].
  6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  7. Let offset be O.[[ByteOffset]].
  8. Return offset.

24.3.4.4 DataView.prototype.constructor

The initial value of DataView.prototype.constructor is the intrinsic object %DataView%.

24.3.4.5 DataView.prototype.getFloat32 ( byteOffset [ , littleEndian ] )

When the 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, let littleEndian be false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Float32").

24.3.4.6 DataView.prototype.getFloat64 ( byteOffset [ , littleEndian ] )

When the 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, let littleEndian be false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Float64").

24.3.4.7 DataView.prototype.getInt8 ( byteOffset )

When the getInt8 method is called with argument byteOffset, the following steps are taken:

  1. Let v be the this value.
  2. Return ? GetViewValue(v, byteOffset, true, "Int8").

24.3.4.8 DataView.prototype.getInt16 ( byteOffset [ , littleEndian ] )

When the 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, let littleEndian be false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Int16").

24.3.4.9 DataView.prototype.getInt32 ( byteOffset [ , littleEndian ] )

When the 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, let littleEndian be undefined.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Int32").

24.3.4.10 DataView.prototype.getUint8 ( byteOffset )

When the 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").

24.3.4.11 DataView.prototype.getUint16 ( byteOffset [ , littleEndian ] )

When the 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, let littleEndian be false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Uint16").

24.3.4.12 DataView.prototype.getUint32 ( byteOffset [ , littleEndian ] )

When the 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, let littleEndian be false.
  3. Return ? GetViewValue(v, byteOffset, littleEndian, "Uint32").

24.3.4.13 DataView.prototype.setFloat32 ( byteOffset, value [ , littleEndian ] )

When the 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, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Float32", value).

24.3.4.14 DataView.prototype.setFloat64 ( byteOffset, value [ , littleEndian ] )

When the 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, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Float64", value).

24.3.4.15 DataView.prototype.setInt8 ( byteOffset, value )

When the 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).

24.3.4.16 DataView.prototype.setInt16 ( byteOffset, value [ , littleEndian ] )

When the 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, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Int16", value).

24.3.4.17 DataView.prototype.setInt32 ( byteOffset, value [ , littleEndian ] )

When the setInt32 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, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Int32", value).

24.3.4.18 DataView.prototype.setUint8 ( byteOffset, value )

When the 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).

24.3.4.19 DataView.prototype.setUint16 ( byteOffset, value [ , littleEndian ] )

When the 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, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Uint16", value).

24.3.4.20 DataView.prototype.setUint32 ( byteOffset, value [ , littleEndian ] )

When the 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, let littleEndian be false.
  3. Return ? SetViewValue(v, byteOffset, littleEndian, "Uint32", value).

24.3.4.21 DataView.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "DataView".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.3.5 Properties of DataView Instances

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

24.4 The Atomics Object

The Atomics object is the %Atomics% intrinsic object and the initial value of the Atomics property of the global object. The Atomics object is a single ordinary object.

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.

The value of the [[Prototype]] internal slot of the Atomics object is the intrinsic object %ObjectPrototype%.

The Atomics object does not have a [[Construct]] internal method; it is not possible to use the Atomics object as a constructor with the new operator.

The Atomics object does not have a [[Call]] internal method; it is not possible to invoke the Atomics object as a function.

Note

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

24.4.1 Abstract Operations for Atomics

24.4.1.1 ValidateSharedIntegerTypedArray(typedArray [ , onlyInt32 ] )

The abstract operation ValidateSharedIntegerTypedArray takes one argument typedArray and an optional Boolean onlyInt32. It performs the following steps:

  1. If the onlyInt32 argument was not provided, set onlyInt32 to false.
  2. If Type(typedArray) is not Object, throw a TypeError exception.
  3. If typedArray does not have a [[TypedArrayName]] internal slot, throw a TypeError exception.
  4. Let typeName be typedArray.[[TypedArrayName]].
  5. If onlyInt32 is true, then
    1. If typeName is not "Int32Array", throw a TypeError exception.
  6. Else,
    1. If typeName is not "Int8Array", "Uint8Array", "Int16Array", "Uint16Array", "Int32Array", or "Uint32Array", throw a TypeError exception.
  7. Assert: typedArray has a [[ViewedArrayBuffer]] internal slot.
  8. Let buffer be typedArray.[[ViewedArrayBuffer]].
  9. If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception.
  10. Return buffer.

24.4.1.2 ValidateAtomicAccess( typedArray, requestIndex )

The abstract operation ValidateAtomicAccess takes two arguments, typedArray and requestIndex. It performs the following steps:

  1. Assert: typedArray is an Object that has a [[ViewedArrayBuffer]] internal slot.
  2. Let accessIndex be ? ToIndex(requestIndex).
  3. Let length be typedArray.[[ArrayLength]].
  4. Assert: accessIndex ≥ 0.
  5. If accessIndexlength, throw a RangeError exception.
  6. Return accessIndex.

24.4.1.3 GetWaiterList( block, i )

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

The agent cluster has a store of WaiterList objects; the store is indexed by (block, i). WaiterLists are 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.

Operations on a WaiterList -- adding and removing waiting agents, traversing the list of agents, suspending and waking agents on the list -- may only be performed by agents that have entered the WaiterList's critical section.

The abstract operation GetWaiterList takes two arguments, a Shared Data Block block and a nonnegative integer i. It performs the following steps:

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

24.4.1.4 EnterCriticalSection( WL )

The abstract operation EnterCriticalSection takes one argument, a WaiterList WL. It performs the following steps:

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

24.4.1.5 LeaveCriticalSection( WL )

The abstract operation LeaveCriticalSection takes one argument, a WaiterList WL. It performs the following steps:

  1. Assert: The calling agent is in the critical section for WL.
  2. Leave the critical section for WL.

24.4.1.6 AddWaiter( WL, W )

The abstract operation AddWaiter takes two arguments, a WaiterList WL and an agent signifier W. It performs the following steps:

  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.

24.4.1.7 RemoveWaiter( WL, W )

The abstract operation RemoveWaiter takes two arguments, a WaiterList WL and an agent signifier W. It performs the following steps:

  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.

24.4.1.8 RemoveWaiters( WL, c )

The abstract operation RemoveWaiters takes two arguments, a WaiterList WL and nonnegative integer c. It performs the following steps:

  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,
    1. Let W be the first waiter in S.
    2. Add W to the end of L.
    3. Remove W from S.
    4. Subtract 1 from c.
  5. Return L.

24.4.1.9 Suspend( WL, W, timeout )

The abstract operation Suspend takes three arguments, a WaiterList WL, an agent signifier W, and a nonnegative, non-NaN Number timeout. It performs the following steps:

  1. Assert: The calling agent is in the critical section for WL.
  2. Assert: W is equal 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 wakeup that arrives after the critical section is exited but before the suspension takes effect is not lost. W can wake up either because the timeout expired or because it was woken explicitly by another agent calling WakeWaiter(WL, W), and not for any other reasons at all.
  6. Perform EnterCriticalSection(WL).
  7. If W was woken explicitly by another agent calling WakeWaiter(WL, W), return true.
  8. Return false.

24.4.1.10 WakeWaiter( WL, W )

The abstract operation WakeWaiter takes two arguments, a WaiterList WL and an agent signifier W. It performs the following steps:

  1. Assert: The calling agent is in the critical section for WL.
  2. Assert: W is on the list of waiters in WL.
  3. Wake the agent W.
Note

The embedding may delay waking W, e.g. for resource management reasons, but W must eventually be woken in order to guarantee forward progress.

24.4.1.11 AtomicReadModifyWrite( typedArray, index, value, op )

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:

  1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray).
  2. Let i be ? ValidateAtomicAccess(typedArray, index).
  3. Let v be ? ToInteger(value).
  4. Let arrayTypeName be typedArray.[[TypedArrayName]].
  5. Let elementSize be the Number value of the Element Size value specified in Table 50 for arrayTypeName.
  6. Let elementType be the String value of the Element Type value in Table 50 for arrayTypeName.
  7. Let offset be typedArray.[[ByteOffset]].
  8. Let indexedPosition be (i × elementSize) + offset.
  9. Return GetModifySetValueInBuffer(buffer, indexedPosition, elementType, v, op).

24.4.1.12 AtomicLoad( typedArray, index )

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:

  1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray).
  2. Let i be ? ValidateAtomicAccess(typedArray, index).
  3. Let arrayTypeName be typedArray.[[TypedArrayName]].
  4. Let elementSize be the Number value of the Element Size value specified in Table 50 for arrayTypeName.
  5. Let elementType be the String value of the Element Type value in Table 50 for arrayTypeName.
  6. Let offset be typedArray.[[ByteOffset]].
  7. Let indexedPosition be (i × elementSize) + offset.
  8. Return GetValueFromBuffer(buffer, indexedPosition, elementType, true, "SeqCst").

24.4.2 Atomics.add( typedArray, index, value )

Let add denote a semantic function of two List of byte values arguments that applies the addition operation to the Number values corresponding to the List of byte values arguments and returns a List of byte values corresponding to the result of that operation.

The following steps are taken:

  1. Return ? AtomicReadModifyWrite(typedArray, index, value, add).

24.4.3 Atomics.and( typedArray, index, value )

Let and denote a semantic function of two List of byte values arguments that applies the bitwise-and operation element-wise to the two arguments and returns a List of byte values corresponding to the result of that operation.

The following steps are taken:

  1. Return ? AtomicReadModifyWrite(typedArray, index, value, and).

24.4.4 Atomics.compareExchange( typedArray, index, expectedValue, replacementValue )

The following steps are taken:

  1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray).
  2. Let i be ? ValidateAtomicAccess(typedArray, index).
  3. Let expected be ? ToInteger(expectedValue).
  4. Let replacement be ? ToInteger(replacementValue).
  5. Let arrayTypeName be typedArray.[[TypedArrayName]].
  6. Let elementType be the String value of the Element Type value in Table 50 for arrayTypeName.
  7. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  8. Let expectedBytes be NumberToRawBytes(elementType, expected, isLittleEndian).
  9. Let elementSize be the Number value of the Element Size value specified in Table 50 for arrayTypeName.
  10. Let offset be typedArray.[[ByteOffset]].
  11. Let indexedPosition be (i × elementSize) + offset.
  12. Let compareExchange denote a semantic function of two List of byte values arguments that returns the second argument if the first argument is element-wise equal to expectedBytes.
  13. Return GetModifySetValueInBuffer(buffer, indexedPosition, elementType, replacement, compareExchange).

24.4.5 Atomics.exchange( typedArray, index, value )

Let second denote a semantic function of two List of byte values arguments that returns its second argument.

The following steps are taken:

  1. Return ? AtomicReadModifyWrite(typedArray, index, value, second).

24.4.6 Atomics.isLockFree( size )

The following steps are taken:

  1. Let n be ? ToInteger(size).
  2. Let AR be the Agent Record of the surrounding agent.
  3. If n equals 1, return AR.[[IsLockFree1]].
  4. If n equals 2, return AR.[[IsLockFree2]].
  5. If n equals 4, return true.
  6. Return false.
Note

Atomics.isLockFree() is an optimization primitive. The intuition is that if the atomic step of an atomic primitive (compareExchange, load, store, add, sub, and, or, xor, or 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(n) will return true. High-performance algorithms will use 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(4) always returns true as that can be supported on all known relevant hardware. Being able to assume this will generally simplify programs.

24.4.7 Atomics.load( typedArray, index )

The following steps are taken:

  1. Return ? AtomicLoad(typedArray, index).

24.4.8 Atomics.or( typedArray, index, value )

Let or denote a semantic function of two List of byte values arguments that applies the bitwise-or operation element-wise to the two arguments and returns a List of byte values corresponding to the result of that operation.

The following steps are taken:

  1. Return ? AtomicReadModifyWrite(typedArray, index, value, or).

24.4.9 Atomics.store( typedArray, index, value )

The following steps are taken:

  1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray).
  2. Let i be ? ValidateAtomicAccess(typedArray, index).
  3. Let v be ? ToInteger(value).
  4. Let arrayTypeName be typedArray.[[TypedArrayName]].
  5. Let elementSize be the Number value of the Element Size value specified in Table 50 for arrayTypeName.
  6. Let elementType be the String value of the Element Type value in Table 50 for arrayTypeName.
  7. Let offset be typedArray.[[ByteOffset]].
  8. Let indexedPosition be (i × elementSize) + offset.
  9. Perform SetValueInBuffer(buffer, indexedPosition, elementType, v, true, "SeqCst").
  10. Return v.

24.4.10 Atomics.sub( typedArray, index, value )

Let subtract denote a semantic function of two List of byte values arguments that applies the subtraction operation to the Number values corresponding to the List of byte values arguments and returns a List of byte values corresponding to the result of that operation.

The following steps are taken:

  1. Return ? AtomicReadModifyWrite(typedArray, index, value, subtract).

24.4.11 Atomics.wait( typedArray, index, value, timeout )

Atomics.wait puts the calling agent in a wait queue and puts it to sleep until it is awoken or the sleep times out. The following steps are taken:

  1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true).
  2. Let i be ? ValidateAtomicAccess(typedArray, index).
  3. Let v be ? ToInt32(value).
  4. Let q be ? ToNumber(timeout).
  5. If q is NaN, let t be +∞, else let t be max(q, 0).
  6. Let B be AgentCanSuspend().
  7. If B is false, throw a TypeError exception.
  8. Let block be buffer.[[ArrayBufferData]].
  9. Let offset be typedArray.[[ByteOffset]].
  10. Let indexedPosition be (i × 4) + offset.
  11. Let WL be GetWaiterList(block, indexedPosition).
  12. Perform EnterCriticalSection(WL).
  13. Let w be ! AtomicLoad(typedArray, i).
  14. If v is not equal to w, then
    1. Perform LeaveCriticalSection(WL).
    2. Return the String "not-equal".
  15. Let W be AgentSignifier().
  16. Perform AddWaiter(WL, W).
  17. Let awoken be Suspend(WL, W, t).
  18. Perform RemoveWaiter(WL, W).
  19. Perform LeaveCriticalSection(WL).
  20. If awoken is true, return the String "ok".
  21. Return the String "timed-out".

24.4.12 Atomics.wake( typedArray, index, count )

Atomics.wake wakes up some agents that are sleeping in the wait queue. The following steps are taken:

  1. Let buffer be ? ValidateSharedIntegerTypedArray(typedArray, true).
  2. Let i be ? ValidateAtomicAccess(typedArray, index).
  3. If count is undefined, let c be +∞.
  4. Else,
    1. Let intCount be ? ToInteger(count).
    2. Let c be max(intCount, 0).
  5. Let block be buffer.[[ArrayBufferData]].
  6. Let offset be typedArray.[[ByteOffset]].
  7. Let indexedPosition be (i × 4) + offset.
  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,
    1. Let W be the first agent in S.
    2. Remove W from the front of S.
    3. Perform WakeWaiter(WL, W).
    4. Add 1 to n.
  13. Perform LeaveCriticalSection(WL).
  14. Return n.

24.4.13 Atomics.xor( typedArray, index, value )

Let xor denote a semantic function of two List of byte values arguments that applies the bitwise-xor operation element-wise to the two arguments and returns a List of byte values corresponding to the result of that operation.

The following steps are taken:

  1. Return ? AtomicReadModifyWrite(typedArray, index, value, xor).

24.4.14 Atomics [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Atomics".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.5 The JSON Object

The JSON object is the %JSON% intrinsic object and the initial value of the JSON property of the global object. The JSON object is a single ordinary object that contains two functions, parse and stringify, that are used to parse and construct JSON texts. The JSON Data Interchange Format is defined in ECMA-404. The JSON interchange format used in this specification is exactly that described by ECMA-404.

Conforming implementations of JSON.parse and JSON.stringify must support the exact interchange format described in the ECMA-404 specification without any deletions or extensions to the format.

The value of the [[Prototype]] internal slot of the JSON object is the intrinsic object %ObjectPrototype%. The value of the [[Extensible]] internal slot of the JSON object is set to true.

The JSON object does not have a [[Construct]] internal method; it is not possible to use the JSON object as a constructor with the new operator.

The JSON object does not have a [[Call]] internal method; it is not possible to invoke the JSON object as a function.

24.5.1 JSON.parse ( text [ , reviver ] )

The parse function parses a JSON text (a JSON-formatted String) and produces an ECMAScript value. The JSON format represents literals, arrays, and objects with a syntax similar to the syntax for ECMAScript literals, Array Initializers, and Object Initializers. After parsing, JSON objects are realized as ECMAScript objects. JSON arrays are realized as ECMAScript Array instances. JSON strings, numbers, booleans, and null are realized as ECMAScript Strings, Numbers, Booleans, and null.

The optional reviver parameter is a function that takes two parameters, key and value. It can filter and transform the results. It is called with each of the key/value pairs produced by the parse, and its return value is used instead of the original value. If it returns what it received, the structure is not modified. If it returns undefined then the property is deleted from the result.

  1. Let JText be ? ToString(text).
  2. Parse JText interpreted as UTF-16 encoded Unicode points (6.1.4) as a JSON text as specified in ECMA-404. Throw a SyntaxError exception if JText is not a valid JSON text as defined in that specification.
  3. Let scriptText be the result of concatenating "(", JText, and ");".
  4. Let completion be the result of parsing and evaluating scriptText as if it was the source text of an ECMAScript Script, but using the alternative definition of DoubleStringCharacter provided below. The extended PropertyDefinitionEvaluation semantics defined in B.3.1 must not be used during the evaluation.
  5. Let unfiltered be completion.[[Value]].
  6. Assert: unfiltered is either a String, Number, Boolean, Null, or an Object that is defined by either an ArrayLiteral or an ObjectLiteral.
  7. If IsCallable(reviver) is true, then
    1. Let root be ObjectCreate(%ObjectPrototype%).
    2. Let rootName be the empty String.
    3. Let status be CreateDataProperty(root, rootName, unfiltered).
    4. Assert: status is true.
    5. Return ? InternalizeJSONProperty(root, rootName).
  8. Else,
    1. Return unfiltered.

The length property of the parse function is 2.

JSON allows Unicode code units 0x2028 (LINE SEPARATOR) and 0x2029 (PARAGRAPH SEPARATOR) to directly appear in String literals without using an escape sequence. This is enabled by using the following alternative definition of DoubleStringCharacter when parsing scriptText in step 4:

DoubleStringCharacter :: SourceCharacter but not one of " or \ or U+0000 through U+001F \ EscapeSequence
  • The SV of DoubleStringCharacter :: SourceCharacter but not one of " or \ or U+0000 through U+001F is the UTF16Encoding of the code point value of SourceCharacter.
Note

Valid JSON text is a subset of the ECMAScript PrimaryExpression syntax as modified by Step 4 above. Step 2 verifies that JText conforms to that subset, and step 6 verifies that that parsing and evaluation returns a value of an appropriate type.

24.5.1.1 Runtime Semantics: InternalizeJSONProperty( holder, name )

The abstract operation InternalizeJSONProperty is a recursive abstract operation that takes two parameters: a holder object and the String name of a property in that object. InternalizeJSONProperty uses the value of reviver that was originally passed to the above parse function.

  1. Let val be ? Get(holder, name).
  2. If Type(val) is Object, then
    1. Let isArray be ? IsArray(val).
    2. If isArray is true, then
      1. Let I be 0.
      2. Let len be ? ToLength(? Get(val, "length")).
      3. Repeat, while I < len,
        1. Let newElement be ? InternalizeJSONProperty(val, ! ToString(I)).
        2. If newElement is undefined, then
          1. Perform ? val.[[Delete]](! ToString(I)).
        3. Else,
          1. Perform ? CreateDataProperty(val, ! ToString(I), newElement).
          2. NOTE: This algorithm intentionally does not throw an exception if CreateDataProperty returns false.
        4. Add 1 to I.
    3. Else,
      1. Let keys be ? EnumerableOwnProperties(val, "key").
      2. For each String P in keys, do
        1. Let newElement be ? InternalizeJSONProperty(val, P).
        2. If newElement is undefined, then
          1. Perform ? val.[[Delete]](P).
        3. Else,
          1. Perform ? CreateDataProperty(val, P, newElement).
          2. NOTE: This algorithm intentionally does not throw an exception if CreateDataProperty returns false.
  3. Return ? Call(reviver, holder, « name, val »).

It is not permitted for a conforming implementation of JSON.parse to extend the JSON grammars. If an implementation wishes to support a modified or extended JSON interchange format it must do so by defining a different parse function.

Note

In the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten.

24.5.2 JSON.stringify ( value [ , replacer [ , space ] ] )

The stringify function returns a String in UTF-16 encoded JSON format representing an ECMAScript value. It can take three parameters. The value parameter is an ECMAScript value, which is usually an object or array, although it can also be a String, Boolean, Number or null. The optional replacer parameter is either a function that alters the way objects and arrays are stringified, or an array of Strings and Numbers that acts as an inclusion list for selecting the object properties that will be stringified. The optional space parameter is a String or Number that allows the result to have white space injected into it to improve human readability.

These are the steps in stringifying an object:

  1. Let stack be a new empty List.
  2. Let indent be the empty String.
  3. Let PropertyList and ReplacerFunction be undefined.
  4. If Type(replacer) is Object, then
    1. If IsCallable(replacer) is true, then
      1. Let ReplacerFunction be replacer.
    2. Else,
      1. Let isArray be ? IsArray(replacer).
      2. If isArray is true, then
        1. Let PropertyList be a new empty List.
        2. Let len be ? ToLength(? Get(replacer, "length")).
        3. Let k be 0.
        4. Repeat, while k<len,
          1. Let v be ? Get(replacer, ! ToString(k)).
          2. Let item be undefined.
          3. If Type(v) is String, let item be v.
          4. Else if Type(v) is Number, let item be ! ToString(v).
          5. Else if Type(v) is Object, then
            1. If v has a [[StringData]] or [[NumberData]] internal slot, let item be ? ToString(v).
          6. If item is not undefined and item is not currently an element of PropertyList, then
            1. Append item to the end of PropertyList.
          7. Let k be k+1.
  5. If Type(space) is Object, then
    1. If space has a [[NumberData]] internal slot, then
      1. Let space be ? ToNumber(space).
    2. Else if space has a [[StringData]] internal slot, then
      1. Let space be ? ToString(space).
  6. If Type(space) is Number, then
    1. Let space be min(10, ToInteger(space)).
    2. Set gap to a String containing space occurrences of code unit 0x0020 (SPACE). This will be the empty String if space is less than 1.
  7. Else if Type(space) is String, then
    1. If the number of elements in space is 10 or less, set gap to space; otherwise set gap to a String consisting of the first 10 elements of space.
  8. Else,
    1. Set gap to the empty String.
  9. Let wrapper be ObjectCreate(%ObjectPrototype%).
  10. Let status be CreateDataProperty(wrapper, the empty String, value).
  11. Assert: status is true.
  12. Return ? SerializeJSONProperty(the empty String, wrapper).

The length property of the stringify function is 3.

Note 1

JSON structures are allowed to be nested to any depth, but they must be acyclic. If value is or contains a cyclic structure, then the stringify function must throw a TypeError exception. This is an example of a value that cannot be stringified:


          a = [];
          a[0] = a;
          my_text = JSON.stringify(a); // This must throw a TypeError.
        
Note 2

Symbolic primitive values are rendered as follows:

  • The null value is rendered in JSON text as the String null.
  • The undefined value is not rendered.
  • The true value is rendered in JSON text as the String true.
  • The false value is rendered in JSON text as the String false.
Note 3

String values are wrapped in QUOTATION MARK (") code units. The code units " and \ are escaped with \ prefixes. Control characters code units are replaced with escape sequences \uHHHH, or with the shorter forms, \b (BACKSPACE), \f (FORM FEED), \n (LINE FEED), \r (CARRIAGE RETURN), \t (CHARACTER TABULATION).

Note 4

Finite numbers are stringified as if by calling ToString(number). NaN and Infinity regardless of sign are represented as the String null.

Note 5

Values that do not have a JSON representation (such as undefined and functions) do not produce a String. Instead they produce the undefined value. In arrays these values are represented as the String null. In objects an unrepresentable value causes the property to be excluded from stringification.

Note 6

An object is rendered as U+007B (LEFT CURLY BRACKET) followed by zero or more properties, separated with a U+002C (COMMA), closed with a U+007D (RIGHT CURLY BRACKET). A property is a quoted String representing the key or property name, a U+003A (COLON), and then the stringified property value. An array is rendered as an opening U+005B (LEFT SQUARE BRACKET followed by zero or more values, separated with a U+002C (COMMA), closed with a U+005D (RIGHT SQUARE BRACKET).

24.5.2.1 Runtime Semantics: SerializeJSONProperty ( key, holder )

The abstract operation SerializeJSONProperty with arguments key, and holder has access to ReplacerFunction from the invocation of the stringify method. Its algorithm is as follows:

  1. Let value be ? Get(holder, key).
  2. If Type(value) is Object, then
    1. Let toJSON be ? Get(value, "toJSON").
    2. If IsCallable(toJSON) is true, then
      1. Set value to ? Call(toJSON, value, « key »).
  3. If ReplacerFunction is not undefined, then
    1. Set value to ? Call(ReplacerFunction, holder, « key, value »).
  4. If Type(value) is Object, then
    1. If value has a [[NumberData]] internal slot, then
      1. Set value to ? ToNumber(value).
    2. Else if value has a [[StringData]] internal slot, then
      1. Set value to ? ToString(value).
    3. Else if value has a [[BooleanData]] internal slot, then
      1. Set value to value.[[BooleanData]].
  5. If value is null, return "null".
  6. If value is true, return "true".
  7. If value is false, return "false".
  8. If Type(value) is String, return QuoteJSONString(value).
  9. If Type(value) is Number, then
    1. If value is finite, return ! ToString(value).
    2. Return "null".
  10. If Type(value) is Object and IsCallable(value) is false, then
    1. Let isArray be ? IsArray(value).
    2. If isArray is true, return ? SerializeJSONArray(value).
    3. Return ? SerializeJSONObject(value).
  11. Return undefined.

24.5.2.2 Runtime Semantics: QuoteJSONString ( value )

The abstract operation QuoteJSONString with argument value wraps a String value in QUOTATION MARK code units and escapes certain other code units within it.

  1. Let product be code unit 0x0022 (QUOTATION MARK).
  2. For each code unit C in value, do
    1. If C is 0x0022 (QUOTATION MARK) or 0x005C (REVERSE SOLIDUS), then
      1. Set product to the concatenation of product and code unit 0x005C (REVERSE SOLIDUS).
      2. Set product to the concatenation of product and C.
    2. Else if C is 0x0008 (BACKSPACE), 0x000C (FORM FEED), 0x000A (LINE FEED), 0x000D (CARRIAGE RETURN), or 0x0009 (CHARACTER TABULATION), then
      1. Set product to the concatenation of product and code unit 0x005C (REVERSE SOLIDUS).
      2. Let abbrev be the String value corresponding to the value of C as follows:
        BACKSPACE "b"
        FORM FEED (FF) "f"
        LINE FEED (LF) "n"
        CARRIAGE RETURN (CR) "r"
        CHARACTER TABULATION "t"
      3. Set product to the concatenation of product and abbrev.
    3. Else if C has a code unit value less than 0x0020 (SPACE), then
      1. Set product to the concatenation of product and code unit 0x005C (REVERSE SOLIDUS).
      2. Set product to the concatenation of product and "u".
      3. Let hex be the string result of converting the numeric code unit value of C to a String of four lowercase hexadecimal digits.
      4. Set product to the concatenation of product and hex.
    4. Else,
      1. Set product to the concatenation of product and C.
  3. Set product to the concatenation of product and code unit 0x0022 (QUOTATION MARK).
  4. Return product.

24.5.2.3 Runtime Semantics: SerializeJSONObject ( value )

The abstract operation SerializeJSONObject with argument value serializes an object. It has access to the stack, indent, gap, and PropertyList values of the current invocation of the stringify method.

  1. If stack contains value, throw a TypeError exception because the structure is cyclical.
  2. Append value to stack.
  3. Let stepback be indent.
  4. Set indent to the concatenation of indent and gap.
  5. If PropertyList is not undefined, then
    1. Let K be PropertyList.
  6. Else,
    1. Let K be ? EnumerableOwnProperties(value, "key").
  7. Let partial be a new empty List.
  8. For each element P of K, do
    1. Let strP be ? SerializeJSONProperty(P, value).
    2. If strP is not undefined, then
      1. Let member be QuoteJSONString(P).
      2. Set member to the concatenation of member and the String ":".
      3. If gap is not the empty String, then
        1. Set member to the concatenation of member and code unit 0x0020 (SPACE).
      4. Set member to the concatenation of member and strP.
      5. Append member to partial.
  9. If partial is empty, then
    1. Let final be "{}".
  10. Else,
    1. If gap is the empty String, then
      1. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String.
      2. Let final be the result of concatenating "{", properties, and "}".
    2. Else gap is not the empty String,
      1. Let separator be the result of concatenating code unit 0x002C (COMMA), code unit 0x000A (LINE FEED), and indent.
      2. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with separator. The separator String is not inserted either before the first String or after the last String.
      3. Let final be the result of concatenating "{", code unit 0x000A (LINE FEED), indent, properties, code unit 0x000A (LINE FEED), stepback, and "}".
  11. Remove the last element of stack.
  12. Set indent to stepback.
  13. Return final.

24.5.2.4 Runtime Semantics: SerializeJSONArray ( value )

The abstract operation SerializeJSONArray with argument value serializes an array. It has access to the stack, indent, and gap values of the current invocation of the stringify method.

  1. If stack contains value, throw a TypeError exception because the structure is cyclical.
  2. Append value to stack.
  3. Let stepback be indent.
  4. Set indent to the concatenation of indent and gap.
  5. Let partial be a new empty List.
  6. Let len be ? ToLength(? Get(value, "length")).
  7. Let index be 0.
  8. Repeat, while index < len
    1. Let strP be ? SerializeJSONProperty(! ToString(index), value).
    2. If strP is undefined, then
      1. Append "null" to partial.
    3. Else,
      1. Append strP to partial.
    4. Increment index by 1.
  9. If partial is empty, then
    1. Let final be "[]".
  10. Else,
    1. If gap is the empty String, then
      1. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String.
      2. Let final be the result of concatenating "[", properties, and "]".
    2. Else,
      1. Let separator be the result of concatenating code unit 0x002C (COMMA), code unit 0x000A (LINE FEED), and indent.
      2. Let properties be a String formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with separator. The separator String is not inserted either before the first String or after the last String.
      3. Let final be the result of concatenating "[", code unit 0x000A (LINE FEED), indent, properties, code unit 0x000A (LINE FEED), stepback, and "]".
  11. Remove the last element of stack.
  12. Set indent to stepback.
  13. Return final.
Note

The representation of arrays includes only the elements between zero and array.length - 1 inclusive. Properties whose keys are not array indexes are excluded from the stringification. An array is stringified as an opening LEFT SQUARE BRACKET, elements separated by COMMA, and a closing RIGHT SQUARE BRACKET.

24.5.3 JSON [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "JSON".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.