25 Structured Data
25.1 ArrayBuffer Objects
25.1.1 Notation
The descriptions below in this section,
A read-modify-write modification function is a mathematical function that is represented as an
- They perform all their algorithm steps atomically.
- Their individual algorithm steps are not observable.
To aid verifying that a read-modify-write modification function's algorithm steps constitute a pure, mathematical function, the following editorial conventions are recommended:
- They do not access, directly or transitively via invoked
abstract operations andAbstract Closures , any language or specification values except their parameters and captured values. - They do not invoke, directly or transitively,
abstract operations andAbstract Closures that returnCompletion Records . - They do not return
Completion Records .
25.1.2 Fixed-length and Resizable ArrayBuffer Objects
A fixed-length ArrayBuffer is an ArrayBuffer whose byte length cannot change after creation.
A resizable ArrayBuffer is an ArrayBuffer whose byte length may change after creation via calls to
The kind of ArrayBuffer object that is created depends on the arguments passed to
25.1.3 Abstract Operations For ArrayBuffer Objects
25.1.3.1 AllocateArrayBuffer ( ctor, byteLength [ , maxByteLength ] )
The abstract operation AllocateArrayBuffer takes arguments ctor (a
- Let slots be « [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferDetachKey]] ».
- If maxByteLength is present and maxByteLength is not
empty , let allocatingResizableBuffer betrue ; else let allocatingResizableBuffer befalse . - If allocatingResizableBuffer is
true , then- If byteLength > maxByteLength, throw a
RangeError exception. - Append [[ArrayBufferMaxByteLength]] to slots.
- If byteLength > maxByteLength, throw a
- Let obj be ?
OrdinaryCreateFromConstructor (ctor," , slots).%ArrayBuffer.prototype% " - Let block be ?
CreateByteDataBlock (byteLength). - Set obj.[[ArrayBufferData]] to block.
- Set obj.[[ArrayBufferByteLength]] to byteLength.
- If allocatingResizableBuffer is
true , then- If it is not possible to create a
Data Block block consisting of maxByteLength bytes, throw aRangeError exception. NOTE : Resizable ArrayBuffers are designed to be implementable with in-place growth. Implementations may throw if, for example, virtual memory cannot be reserved up front.- Set obj.[[ArrayBufferMaxByteLength]] to maxByteLength.
- If it is not possible to create a
- Return obj.
25.1.3.2 ArrayBufferByteLength ( arrayBuffer, order )
The abstract operation ArrayBufferByteLength takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer) and order (
- If
IsGrowableSharedArrayBuffer (arrayBuffer) istrue , then- Let bufferByteLengthBlock be arrayBuffer.[[ArrayBufferByteLengthData]].
- Let rawLength be
GetRawBytesFromSharedBlock (bufferByteLengthBlock, 0,biguint64 ,true , order). - Let agentRecord be the
Agent Record of thesurrounding agent . - Let isLittleEndian be agentRecord.[[LittleEndian]].
- Return
ℝ (RawBytesToNumeric (biguint64 , rawLength, isLittleEndian)).
Assert :IsDetachedBuffer (arrayBuffer) isfalse .- Return arrayBuffer.[[ArrayBufferByteLength]].
25.1.3.3 ArrayBufferCopyAndDetach ( arrayBuffer, newLength, preserveResizability )
The abstract operation ArrayBufferCopyAndDetach takes arguments arrayBuffer (an
- Perform ?
RequireInternalSlot (arrayBuffer, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (arrayBuffer) istrue , throw aTypeError exception. - If newLength is
undefined , then- Let newByteLength be arrayBuffer.[[ArrayBufferByteLength]].
- Else,
- Let newByteLength be ?
ToIndex (newLength).
- Let newByteLength be ?
- If
IsDetachedBuffer (arrayBuffer) istrue , throw aTypeError exception. - If preserveResizability is
preserve-resizability andIsFixedLengthArrayBuffer (arrayBuffer) isfalse , then- Let newMaxByteLength be arrayBuffer.[[ArrayBufferMaxByteLength]].
- Else,
- Let newMaxByteLength be
empty .
- Let newMaxByteLength be
- If arrayBuffer.[[ArrayBufferDetachKey]] is not
undefined , throw aTypeError exception. - Let newBuffer be ?
.AllocateArrayBuffer (%ArrayBuffer% , newByteLength, newMaxByteLength) - Let copyLength be
min (newByteLength, arrayBuffer.[[ArrayBufferByteLength]]). - Let fromBlock be arrayBuffer.[[ArrayBufferData]].
- Let toBlock be newBuffer.[[ArrayBufferData]].
- Perform
CopyDataBlockBytes (toBlock, 0, fromBlock, 0, copyLength). NOTE : Neither creation of the newData Block nor copying from the oldData Block are observable. Implementations may implement this method as a zero-copy move or arealloc.- Perform !
DetachArrayBuffer (arrayBuffer). - Return newBuffer.
25.1.3.4 IsDetachedBuffer ( arrayBuffer )
The abstract operation IsDetachedBuffer takes argument arrayBuffer (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It performs the following steps when called:
- If arrayBuffer.[[ArrayBufferData]] is
null , returntrue . - Return
false .
25.1.3.5 DetachArrayBuffer ( arrayBuffer [ , key ] )
The abstract operation DetachArrayBuffer takes argument arrayBuffer (an ArrayBuffer) and optional argument key (anything) and returns either a
Assert :IsSharedArrayBuffer (arrayBuffer) isfalse .- If key is not present, set key to
undefined . - If arrayBuffer.[[ArrayBufferDetachKey]] is not key, throw a
TypeError exception. - Set arrayBuffer.[[ArrayBufferData]] to
null . - Set arrayBuffer.[[ArrayBufferByteLength]] to 0.
- Return
unused .
Detaching an ArrayBuffer instance disassociates the
25.1.3.6 CloneArrayBuffer ( sourceBuffer, sourceByteOffset, sourceLength )
The abstract operation CloneArrayBuffer takes arguments sourceBuffer (an ArrayBuffer or a SharedArrayBuffer), sourceByteOffset (a non-negative
Assert :IsDetachedBuffer (sourceBuffer) isfalse .- Let targetBuffer be ?
.AllocateArrayBuffer (%ArrayBuffer% , sourceLength) - Let sourceBlock be sourceBuffer.[[ArrayBufferData]].
- Let targetBlock be targetBuffer.[[ArrayBufferData]].
- Perform
CopyDataBlockBytes (targetBlock, 0, sourceBlock, sourceByteOffset, sourceLength). - Return targetBuffer.
25.1.3.7 GetArrayBufferMaxByteLengthOption ( options )
The abstract operation GetArrayBufferMaxByteLengthOption takes argument options (an
- If options
is not an Object , returnempty . - Let maxByteLength be ?
Get (options,"maxByteLength" ). - If maxByteLength is
undefined , returnempty . - Return ?
ToIndex (maxByteLength).
25.1.3.8 HostResizeArrayBuffer ( buffer, newByteLength )
The
The implementation of HostResizeArrayBuffer must conform to the following requirements:
- The abstract operation does not detach buffer.
- If the abstract operation completes normally with
handled , buffer.[[ArrayBufferByteLength]] is newByteLength.
The default implementation of HostResizeArrayBuffer is to return
25.1.3.9 IsFixedLengthArrayBuffer ( arrayBuffer )
The abstract operation IsFixedLengthArrayBuffer takes argument arrayBuffer (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It performs the following steps when called:
- If arrayBuffer has an [[ArrayBufferMaxByteLength]] internal slot, return
false . - Return
true .
25.1.3.10 IsUnsignedElementType ( type )
The abstract operation IsUnsignedElementType takes argument type (a
- If type is one of
uint8 ,uint8clamped ,uint16 ,uint32 , orbiguint64 , returntrue . - Return
false .
25.1.3.11 IsUnclampedIntegerElementType ( type )
The abstract operation IsUnclampedIntegerElementType takes argument type (a
- If type is one of
int8 ,uint8 ,int16 ,uint16 ,int32 , oruint32 , returntrue . - Return
false .
25.1.3.12 IsBigIntElementType ( type )
The abstract operation IsBigIntElementType takes argument type (a
- If type is either
biguint64 orbigint64 , returntrue . - Return
false .
25.1.3.13 IsNoTearConfiguration ( type, order )
The abstract operation IsNoTearConfiguration takes arguments type (a
- If
IsUnclampedIntegerElementType (type) istrue , returntrue . - If
IsBigIntElementType (type) istrue and order is neitherinit norunordered , returntrue . - Return
false .
25.1.3.14 RawBytesToNumeric ( type, rawBytes, isLittleEndian )
The abstract operation RawBytesToNumeric takes arguments type (a
- Let elementSize be the Element Size value specified in
Table 70 for Element Type type. - If isLittleEndian is
false , reverse the order of the elements of rawBytes. - If type is
float16 , then- Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an
IEEE 754-2019 binary16 value. - If value is a NaN, return
NaN . - Return the Number value that corresponds to value.
- Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an
- If type is
float32 , then- Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an
IEEE 754-2019 binary32 value. - If value is a NaN, return
NaN . - Return the Number value that corresponds to value.
- Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an
- If type is
float64 , then- Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an
IEEE 754-2019 binary64 value. - If value is a NaN, return
NaN . - Return the Number value that corresponds to value.
- Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an
- If
IsUnsignedElementType (type) istrue , then- Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of an unsigned little-endian binary number.
- Else,
- Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of a binary little-endian two's complement number of bit length elementSize × 8.
- If
IsBigIntElementType (type) istrue , return the BigInt value that corresponds to intValue. - Return the Number value that corresponds to intValue.
25.1.3.15 GetRawBytesFromSharedBlock ( block, byteIndex, type, isTypedArray, order )
The abstract operation GetRawBytesFromSharedBlock takes arguments block (a
- Let elementSize be the Element Size value specified in
Table 70 for Element Type type. - Let agentRecord be the
Agent Record of thesurrounding agent . - Let execution be agentRecord.[[CandidateExecution]].
- Let eventsRecord be the
Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] isAgentSignifier (). - If isTypedArray is
true andIsNoTearConfiguration (type, order) istrue , let noTear betrue ; else let noTear befalse . - Let rawValue be a
List of length elementSize whose elements are nondeterministically chosenbyte values . 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 thememory model to describe observable behaviour of hardware with weak consistency.- Let readEvent be
ReadSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize }. - Append readEvent to eventsRecord.[[EventList]].
- Append
Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: rawValue } to execution.[[ChosenValues]]. - Return rawValue.
25.1.3.16 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isTypedArray, order [ , isLittleEndian ] )
The abstract operation GetValueFromBuffer takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative
Assert :IsDetachedBuffer (arrayBuffer) isfalse .Assert : There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.- Let block be arrayBuffer.[[ArrayBufferData]].
- Let elementSize be the Element Size value specified in
Table 70 for Element Type type. - If
IsSharedArrayBuffer (arrayBuffer) istrue , thenAssert : block is aShared Data Block .- Let rawValue be
GetRawBytesFromSharedBlock (block, byteIndex, type, isTypedArray, order).
- Else,
Assert : The number of elements in rawValue is elementSize.- If isLittleEndian is not present, then
- Let agentRecord be the
Agent Record of thesurrounding agent . - Set isLittleEndian to agentRecord.[[LittleEndian]].
- Let agentRecord be the
- Return
RawBytesToNumeric (type, rawValue, isLittleEndian).
25.1.3.17 NumericToRawBytes ( type, value, isLittleEndian )
The abstract operation NumericToRawBytes takes arguments type (a
- If type is
float16 , then- Let rawBytes be a
List whose elements are the 2 bytes that are the result of converting value toIEEE 754-2019 binary16 format using roundTiesToEven mode. The bytes are arranged in little endian order. If value isNaN , rawBytes may be set to any implementation chosenIEEE 754-2019 binary16 format NaN encoding. An implementation must always choose the same encoding for each implementation distinguishableNaN value.
- Let rawBytes be a
- Else if type is
float32 , then- Let rawBytes be a
List whose elements are the 4 bytes that are the result of converting value toIEEE 754-2019 binary32 format using roundTiesToEven mode. The bytes are arranged in little endian order. If value isNaN , rawBytes may be set to any implementation chosenIEEE 754-2019 binary32 format NaN encoding. An implementation must always choose the same encoding for each implementation distinguishableNaN value.
- Let rawBytes be a
- Else if type is
float64 , then- Let rawBytes be a
List whose elements are the 8 bytes that are theIEEE 754-2019 binary64 format encoding of value. The bytes are arranged in little endian order. If value isNaN , rawBytes may be set to any implementation chosenIEEE 754-2019 binary64 format NaN encoding. An implementation must always choose the same encoding for each implementation distinguishableNaN value.
- Let rawBytes be a
- Else,
- Let n be the Element Size value specified in
Table 70 for Element Type type. - Let conversionOperation be the abstract operation named in the “Conversion Operation” column of
Table 70 for Element Type type. - Let intValue be
ℝ (! conversionOperation(value)). - If intValue ≥ 0, then
- Let rawBytes be a
List whose elements are the n-byte binary encoding of intValue. The bytes are ordered in little endian order.
- Let rawBytes be a
- Else,
- Let rawBytes be a
List whose elements are the n-byte binary two's complement encoding of intValue. The bytes are ordered in little endian order.
- Let rawBytes be a
- Let n be the Element Size value specified in
- If isLittleEndian is
false , reverse the order of the elements of rawBytes. - Return rawBytes.
25.1.3.18 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order [ , isLittleEndian ] )
The abstract operation SetValueInBuffer takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative
Assert :IsDetachedBuffer (arrayBuffer) isfalse .Assert : There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.Assert : valueis a BigInt ifIsBigIntElementType (type) istrue ; else, valueis a Number .- Let block be arrayBuffer.[[ArrayBufferData]].
- Let elementSize be the Element Size value specified in
Table 70 for Element Type type. - Let agentRecord be the
Agent Record of thesurrounding agent . - If isLittleEndian is not present, then
- Set isLittleEndian to agentRecord.[[LittleEndian]].
- Let rawBytes be
NumericToRawBytes (type, value, isLittleEndian). - If
IsSharedArrayBuffer (arrayBuffer) istrue , then- Let execution be agentRecord.[[CandidateExecution]].
- Let eventsRecord be the
Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] isAgentSignifier (). - If isTypedArray is
true andIsNoTearConfiguration (type, order) istrue , let noTear betrue ; else let noTear befalse . - Append
WriteSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes } to eventsRecord.[[EventList]].
- Else,
- Store the individual bytes of rawBytes into block, starting at block[byteIndex].
- Return
unused .
25.1.3.19 GetModifySetValueInBuffer ( arrayBuffer, byteIndex, type, value, op )
The abstract operation GetModifySetValueInBuffer takes arguments arrayBuffer (an ArrayBuffer or a SharedArrayBuffer), byteIndex (a non-negative
Assert :IsDetachedBuffer (arrayBuffer) isfalse .Assert : There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.Assert : valueis a BigInt ifIsBigIntElementType (type) istrue ; else, valueis a Number .- Let block be arrayBuffer.[[ArrayBufferData]].
- Let elementSize be the Element Size value specified in
Table 70 for Element Type type. - Let agentRecord be the
Agent Record of thesurrounding agent . - Let isLittleEndian be agentRecord.[[LittleEndian]].
- Let rawBytes be
NumericToRawBytes (type, value, isLittleEndian). - If
IsSharedArrayBuffer (arrayBuffer) istrue , then- Let execution be agentRecord.[[CandidateExecution]].
- Let eventsRecord be the
Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] isAgentSignifier (). - Let rawBytesRead be a
List of length elementSize whose elements are nondeterministically chosenbyte values . 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 thememory model to describe observable behaviour of hardware with weak consistency.- Let rmwEvent be
ReadModifyWriteSharedMemory { [[Order]]:seq-cst , [[NoTear]]:true , [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes, [[ModifyOp]]: op }. - Append rmwEvent to eventsRecord.[[EventList]].
- Append
Chosen Value Record { [[Event]]: rmwEvent, [[ChosenValue]]: rawBytesRead } to execution.[[ChosenValues]].
- Else,
- Let rawBytesRead be a
List of length elementSize whose elements are the sequence of elementSize bytes starting with block[byteIndex]. - Let rawBytesModified be op(rawBytesRead, rawBytes).
- Store the individual bytes of rawBytesModified into block, starting at block[byteIndex].
- Let rawBytesRead be a
- Return
RawBytesToNumeric (type, rawBytesRead, isLittleEndian).
25.1.4 The ArrayBuffer Constructor
The ArrayBuffer
- is
%ArrayBuffer% . - is the initial value of the
"ArrayBuffer" property of theglobal object . - creates and initializes a new ArrayBuffer when called as a
constructor . - is not intended to be called as a function and will throw an exception when called in that manner.
- may be used as the value of an
extendsclause of a class definition. Subclassconstructors that intend to inherit the specified ArrayBuffer behaviour must include asupercall to the ArrayBufferconstructor to create and initialize subclass instances with the internal state necessary to support the built-in methods ofArrayBuffer.prototype.
25.1.4.1 ArrayBuffer ( length [ , options ] )
This function performs the following steps when called:
- If NewTarget is
undefined , throw aTypeError exception. - Let byteLength be ?
ToIndex (length). - Let requestedMaxByteLength be ?
GetArrayBufferMaxByteLengthOption (options). - Return ?
AllocateArrayBuffer (NewTarget, byteLength, requestedMaxByteLength).
25.1.5 Properties of the ArrayBuffer Constructor
The ArrayBuffer
- has a [[Prototype]] internal slot whose value is
%Function.prototype% . - has the following properties:
25.1.5.1 ArrayBuffer.isView ( arg )
This function performs the following steps when called:
- If arg
is not an Object , returnfalse . - If arg has a [[ViewedArrayBuffer]] internal slot, return
true . - Return
false .
25.1.5.2 ArrayBuffer.prototype
The initial value of ArrayBuffer.prototype is the
This property has the attributes { [[Writable]]:
25.1.5.3 get ArrayBuffer [ %Symbol.species% ]
ArrayBuffer[%Symbol.species%] is an
- Return the
this value.
The value of the
25.1.6 Properties of the ArrayBuffer Prototype Object
The ArrayBuffer prototype object:
- is
%ArrayBuffer.prototype% . - has a [[Prototype]] internal slot whose value is
%Object.prototype% . - is an
ordinary object . - does not have an [[ArrayBufferData]] or [[ArrayBufferByteLength]] internal slot.
25.1.6.1 get ArrayBuffer.prototype.byteLength
ArrayBuffer.prototype.byteLength is an
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (obj) istrue , throw aTypeError exception. - If
IsDetachedBuffer (obj) istrue , return+0 𝔽. - Let length be obj.[[ArrayBufferByteLength]].
- Return
𝔽 (length).
25.1.6.2 ArrayBuffer.prototype.constructor
The initial value of ArrayBuffer.prototype.constructor is
25.1.6.3 get ArrayBuffer.prototype.detached
ArrayBuffer.prototype.detached is an
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (obj) istrue , throw aTypeError exception. - Return
IsDetachedBuffer (obj).
25.1.6.4 get ArrayBuffer.prototype.maxByteLength
ArrayBuffer.prototype.maxByteLength is an
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (obj) istrue , throw aTypeError exception. - If
IsDetachedBuffer (obj) istrue , return+0 𝔽. - If
IsFixedLengthArrayBuffer (obj) istrue , then- Let length be obj.[[ArrayBufferByteLength]].
- Else,
- Let length be obj.[[ArrayBufferMaxByteLength]].
- Return
𝔽 (length).
25.1.6.5 get ArrayBuffer.prototype.resizable
ArrayBuffer.prototype.resizable is an
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (obj) istrue , throw aTypeError exception. - If
IsFixedLengthArrayBuffer (obj) isfalse , returntrue . - Return
false .
25.1.6.6 ArrayBuffer.prototype.resize ( newLength )
This method performs the following steps when called:
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[ArrayBufferMaxByteLength]]). - If
IsSharedArrayBuffer (obj) istrue , throw aTypeError exception. - Let newByteLength be ?
ToIndex (newLength). - If
IsDetachedBuffer (obj) istrue , throw aTypeError exception. - If newByteLength > obj.[[ArrayBufferMaxByteLength]], throw a
RangeError exception. - Let hostHandled be ?
HostResizeArrayBuffer (obj, newByteLength). - If hostHandled is
handled , returnundefined . - Let oldBlock be obj.[[ArrayBufferData]].
- Let newBlock be ?
CreateByteDataBlock (newByteLength). - Let copyLength be
min (newByteLength, obj.[[ArrayBufferByteLength]]). - Perform
CopyDataBlockBytes (newBlock, 0, oldBlock, 0, copyLength). NOTE : Neither creation of the newData Block nor copying from the oldData Block are observable. Implementations may implement this method as in-place growth or shrinkage.- Set obj.[[ArrayBufferData]] to newBlock.
- Set obj.[[ArrayBufferByteLength]] to newByteLength.
- Return
undefined .
25.1.6.7 ArrayBuffer.prototype.slice ( start, end )
This method performs the following steps when called:
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (obj) istrue , throw aTypeError exception. - If
IsDetachedBuffer (obj) istrue , throw aTypeError exception. - Let length be obj.[[ArrayBufferByteLength]].
- Let relativeStart be ?
ToIntegerOrInfinity (start). - If relativeStart = -∞, let first be 0.
- Else if relativeStart < 0, let first be
max (length + relativeStart, 0). - Else, let first be
min (relativeStart, length). - If end is
undefined , let relativeEnd be length; else let relativeEnd be ?ToIntegerOrInfinity (end). - If relativeEnd = -∞, let final be 0.
- Else if relativeEnd < 0, let final be
max (length + relativeEnd, 0). - Else, let final be
min (relativeEnd, length). - Let newLength be
max (final - first, 0). - Let ctor be ?
SpeciesConstructor (obj,%ArrayBuffer% ). - Let new be ?
Construct (ctor, «𝔽 (newLength) »). - Perform ?
RequireInternalSlot (new, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (new) istrue , throw aTypeError exception. - If
IsDetachedBuffer (new) istrue , throw aTypeError exception. - If
SameValue (new, obj) istrue , throw aTypeError exception. - If new.[[ArrayBufferByteLength]] < newLength, throw a
TypeError exception. NOTE : Side-effects of the above steps may have detached or resized obj.- If
IsDetachedBuffer (obj) istrue , throw aTypeError exception. - Let fromBuf be obj.[[ArrayBufferData]].
- Let toBuf be new.[[ArrayBufferData]].
- Let currentLength be obj.[[ArrayBufferByteLength]].
- If first < currentLength, then
- Let count be
min (newLength, currentLength - first). - Perform
CopyDataBlockBytes (toBuf, 0, fromBuf, first, count).
- Let count be
- Return new.
25.1.6.8 ArrayBuffer.prototype.transfer ( [ newLength ] )
This method performs the following steps when called:
- Let obj be the
this value. - Return ?
ArrayBufferCopyAndDetach (obj, newLength,preserve-resizability ).
25.1.6.9 ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] )
This method performs the following steps when called:
- Let obj be the
this value. - Return ?
ArrayBufferCopyAndDetach (obj, newLength,fixed-length ).
25.1.6.10 ArrayBuffer.prototype [ %Symbol.toStringTag% ]
The initial value of the
This property has the attributes { [[Writable]]:
25.1.7 Properties of ArrayBuffer Instances
ArrayBuffer instances inherit properties from the
ArrayBuffer instances whose [[ArrayBufferData]] is
ArrayBuffer instances whose [[ArrayBufferDetachKey]] is set to a value other than
25.1.8 Resizable ArrayBuffer Guidelines
The following are guidelines for ECMAScript programmers working with
We recommend that programs be tested in their deployment environments where possible. The amount of available physical memory differs greatly between hardware devices. Similarly, virtual memory subsystems also differ greatly between hardware devices as well as operating systems. An application that runs without out-of-memory errors on a 64-bit desktop web browser could run out of memory on a 32-bit mobile web browser.
When choosing a value for the
Please note that successfully constructing a
The following are guidelines for ECMAScript implementers implementing
If a
If a
25.2 SharedArrayBuffer Objects
25.2.1 Fixed-length and Growable SharedArrayBuffer Objects
A fixed-length SharedArrayBuffer is a SharedArrayBuffer whose byte length cannot change after creation.
A growable SharedArrayBuffer is a SharedArrayBuffer whose byte length may increase after creation via calls to
The kind of SharedArrayBuffer object that is created depends on the arguments passed to
25.2.2 Abstract Operations for SharedArrayBuffer Objects
25.2.2.1 AllocateSharedArrayBuffer ( ctor, byteLength [ , maxByteLength ] )
The abstract operation AllocateSharedArrayBuffer takes arguments ctor (a
- Let slots be « [[ArrayBufferData]] ».
- If maxByteLength is present and maxByteLength is not
empty , let allocatingGrowableBuffer betrue ; else let allocatingGrowableBuffer befalse . - If allocatingGrowableBuffer is
true , then- If byteLength > maxByteLength, throw a
RangeError exception. - Append [[ArrayBufferByteLengthData]] and [[ArrayBufferMaxByteLength]] to slots.
- If byteLength > maxByteLength, throw a
- Else,
- Append [[ArrayBufferByteLength]] to slots.
- Let obj be ?
OrdinaryCreateFromConstructor (ctor," , slots).%SharedArrayBuffer.prototype% " - If allocatingGrowableBuffer is
true , let allocLength be maxByteLength; else let allocLength be byteLength. - Let block be ?
CreateSharedByteDataBlock (allocLength). - Set obj.[[ArrayBufferData]] to block.
- If allocatingGrowableBuffer is
true , thenAssert : byteLength ≤ maxByteLength.- Let byteLengthBlock be ?
CreateSharedByteDataBlock (8). - Perform
SetValueInBuffer (byteLengthBlock, 0,biguint64 ,ℤ (byteLength),true ,seq-cst ). - Set obj.[[ArrayBufferByteLengthData]] to byteLengthBlock.
- Set obj.[[ArrayBufferMaxByteLength]] to maxByteLength.
- Else,
- Set obj.[[ArrayBufferByteLength]] to byteLength.
- Return obj.
25.2.2.2 IsSharedArrayBuffer ( obj )
The abstract operation IsSharedArrayBuffer takes argument obj (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It tests whether an object is a SharedArrayBuffer. It performs the following steps when called:
- If obj.[[ArrayBufferData]] is a
Shared Data Block , returntrue . - Return
false .
25.2.2.3 IsGrowableSharedArrayBuffer ( obj )
The abstract operation IsGrowableSharedArrayBuffer takes argument obj (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It tests whether an object is a
- If
IsSharedArrayBuffer (obj) istrue and obj has an [[ArrayBufferByteLengthData]] internal slot, returntrue . - Return
false .
25.2.2.4 HostGrowSharedArrayBuffer ( buffer, newByteLength )
The
The implementation of HostGrowSharedArrayBuffer must conform to the following requirements:
- If the abstract operation does not complete normally with
unhandled , and newByteLength < the current byte length of the buffer or newByteLength > buffer.[[ArrayBufferMaxByteLength]], throw aRangeError exception. - Let agentRecord be the
Agent Record of thesurrounding agent . Let isLittleEndian be agentRecord.[[LittleEndian]]. If the abstract operation completes normally withhandled , aWriteSharedMemory orReadModifyWriteSharedMemory event whose [[Order]] isseq-cst , [[Payload]] isNumericToRawBytes (biguint64 , newByteLength, isLittleEndian), [[Block]] is buffer.[[ArrayBufferByteLengthData]], [[ByteIndex]] is 0, and [[ElementSize]] is 8 is added to thesurrounding agent 'scandidate execution such that racing calls toSharedArrayBuffer.prototype.grow ( newLength ) are not “lost”, i.e. silently do nothing.
The second requirement above is intentionally vague about how or when the current byte length of buffer is read. Because the byte length must be updated via an atomic read-modify-write operation on the underlying hardware, architectures that use load-link/store-conditional or load-exclusive/store-exclusive instruction pairs may wish to keep the paired instructions close in the instruction stream. As such,
This is in contrast with
The default implementation of HostGrowSharedArrayBuffer is to return
25.2.3 The SharedArrayBuffer Constructor
The SharedArrayBuffer
- is
%SharedArrayBuffer% . - is the initial value of the
"SharedArrayBuffer" property of theglobal object , if that property is present (see below). - creates and initializes a new SharedArrayBuffer when called as a
constructor . - is not intended to be called as a function and will throw an exception when called in that manner.
- may be used as the value of an
extendsclause of a class definition. Subclassconstructors that intend to inherit the specified SharedArrayBuffer behaviour must include asupercall to the SharedArrayBufferconstructor to create and initialize subclass instances with the internal state necessary to support the built-in methods ofSharedArrayBuffer.prototype.
Whenever a
Unlike an ArrayBuffer, a SharedArrayBuffer cannot become detached, and its internal [[ArrayBufferData]] slot is never
25.2.3.1 SharedArrayBuffer ( length [ , options ] )
This function performs the following steps when called:
- If NewTarget is
undefined , throw aTypeError exception. - Let byteLength be ?
ToIndex (length). - Let requestedMaxByteLength be ?
GetArrayBufferMaxByteLengthOption (options). - Return ?
AllocateSharedArrayBuffer (NewTarget, byteLength, requestedMaxByteLength).
25.2.4 Properties of the SharedArrayBuffer Constructor
The SharedArrayBuffer
- has a [[Prototype]] internal slot whose value is
%Function.prototype% . - has the following properties:
25.2.4.1 SharedArrayBuffer.prototype
The initial value of SharedArrayBuffer.prototype is the
This property has the attributes { [[Writable]]:
25.2.4.2 get SharedArrayBuffer [ %Symbol.species% ]
SharedArrayBuffer[%Symbol.species%] is an
- Return the
this value.
The value of the
25.2.5 Properties of the SharedArrayBuffer Prototype Object
The SharedArrayBuffer prototype object:
- is
%SharedArrayBuffer.prototype% . - has a [[Prototype]] internal slot whose value is
%Object.prototype% . - is an
ordinary object . - does not have an [[ArrayBufferData]] or [[ArrayBufferByteLength]] internal slot.
25.2.5.1 get SharedArrayBuffer.prototype.byteLength
SharedArrayBuffer.prototype.byteLength is an
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (obj) isfalse , throw aTypeError exception. - Let length be
ArrayBufferByteLength (obj,seq-cst ). - Return
𝔽 (length).
25.2.5.2 SharedArrayBuffer.prototype.constructor
The initial value of SharedArrayBuffer.prototype.constructor is
25.2.5.3 SharedArrayBuffer.prototype.grow ( newLength )
This method performs the following steps when called:
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[ArrayBufferMaxByteLength]]). - If
IsSharedArrayBuffer (obj) isfalse , throw aTypeError exception. - Let newByteLength be ?
ToIndex (newLength). - Let hostHandled be ?
HostGrowSharedArrayBuffer (obj, newByteLength). - If hostHandled is
handled , returnundefined . - Let agentRecord be the
Agent Record of thesurrounding agent . - Let isLittleEndian be agentRecord.[[LittleEndian]].
- Let byteLengthBlock be obj.[[ArrayBufferByteLengthData]].
- Let currentByteLengthRawBytes be
GetRawBytesFromSharedBlock (byteLengthBlock, 0,biguint64 ,true ,seq-cst ). - Let newByteLengthRawBytes be
NumericToRawBytes (biguint64 ,ℤ (newByteLength), isLittleEndian). - Repeat,
NOTE : This is a compare-and-exchange loop to ensure that parallel, racing grows of the same buffer are totally ordered, are not lost, and do not silently do nothing. The loop exits if it was able to attempt to grow uncontended.- Let currentByteLength be
ℝ (RawBytesToNumeric (biguint64 , currentByteLengthRawBytes, isLittleEndian)). - If newByteLength = currentByteLength, return
undefined . - If newByteLength < currentByteLength or newByteLength > obj.[[ArrayBufferMaxByteLength]], throw a
RangeError exception. - Let byteLengthDelta be newByteLength - currentByteLength.
- If it is impossible to create a new
Shared Data Block value consisting of byteLengthDelta bytes, throw aRangeError exception. NOTE : No newShared Data Block is constructed and used here. The observable behaviour of growable SharedArrayBuffers is specified by allocating amax -sizedShared Data Block at construction time, and this step captures the requirement that implementations that run out of memory must throw aRangeError .- Let readByteLengthRawBytes be
AtomicCompareExchangeInSharedBlock (byteLengthBlock, 0, 8, currentByteLengthRawBytes, newByteLengthRawBytes). - If
ByteListEqual (readByteLengthRawBytes, currentByteLengthRawBytes) istrue , returnundefined . - Set currentByteLengthRawBytes to readByteLengthRawBytes.
Spurious failures of the compare-exchange to update the length are prohibited. If the bounds checking for the new length passes and the implementation is not out of memory, a
Parallel calls to SharedArrayBuffer.prototype.grow are totally ordered. For example, consider two racing calls: sab.grow(10) and sab.grow(20). One of the two calls is guaranteed to win the race. The call to sab.grow(10) will never shrink sab even if sab.grow(20) happened first; in that case it will instead throw a RangeError.
25.2.5.4 get SharedArrayBuffer.prototype.growable
SharedArrayBuffer.prototype.growable is an
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (obj) isfalse , throw aTypeError exception. - If
IsFixedLengthArrayBuffer (obj) isfalse , returntrue . - Return
false .
25.2.5.5 get SharedArrayBuffer.prototype.maxByteLength
SharedArrayBuffer.prototype.maxByteLength is an
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (obj) isfalse , throw aTypeError exception. - If
IsFixedLengthArrayBuffer (obj) istrue , then- Let length be obj.[[ArrayBufferByteLength]].
- Else,
- Let length be obj.[[ArrayBufferMaxByteLength]].
- Return
𝔽 (length).
25.2.5.6 SharedArrayBuffer.prototype.slice ( start, end )
This method performs the following steps when called:
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (obj) isfalse , throw aTypeError exception. - Let length be
ArrayBufferByteLength (obj,seq-cst ). - Let relativeStart be ?
ToIntegerOrInfinity (start). - If relativeStart = -∞, let first be 0.
- Else if relativeStart < 0, let first be
max (length + relativeStart, 0). - Else, let first be
min (relativeStart, length). - If end is
undefined , let relativeEnd be length; else let relativeEnd be ?ToIntegerOrInfinity (end). - If relativeEnd = -∞, let final be 0.
- Else if relativeEnd < 0, let final be
max (length + relativeEnd, 0). - Else, let final be
min (relativeEnd, length). - Let newLength be
max (final - first, 0). - Let ctor be ?
SpeciesConstructor (obj,%SharedArrayBuffer% ). - Let new be ?
Construct (ctor, «𝔽 (newLength) »). - Perform ?
RequireInternalSlot (new, [[ArrayBufferData]]). - If
IsSharedArrayBuffer (new) isfalse , throw aTypeError exception. - If new.[[ArrayBufferData]] is obj.[[ArrayBufferData]], throw a
TypeError exception. - If
ArrayBufferByteLength (new,seq-cst ) < newLength, throw aTypeError exception. - Let fromBuf be obj.[[ArrayBufferData]].
- Let toBuf be new.[[ArrayBufferData]].
- Perform
CopyDataBlockBytes (toBuf, 0, fromBuf, first, newLength). - Return new.
25.2.5.7 SharedArrayBuffer.prototype [ %Symbol.toStringTag% ]
The initial value of the
This property has the attributes { [[Writable]]:
25.2.6 Properties of SharedArrayBuffer Instances
SharedArrayBuffer instances inherit properties from the
SharedArrayBuffer instances, unlike ArrayBuffer instances, are never detached.
25.2.7 Growable SharedArrayBuffer Guidelines
The following are guidelines for ECMAScript programmers working with
We recommend that programs be tested in their deployment environments where possible. The amount of available physical memory differ greatly between hardware devices. Similarly, virtual memory subsystems also differ greatly between hardware devices as well as operating systems. An application that runs without out-of-memory errors on a 64-bit desktop web browser could run out of memory on a 32-bit mobile web browser.
When choosing a value for the
Please note that successfully constructing a
Not all loads of a u8[idx], are not synchronizing. In general, in the absence of explicit synchronization, one property access being in-bound does not imply a subsequent property access in the same length and byteLength getters on SharedArrayBuffer,
The following are guidelines for ECMAScript implementers implementing
We recommend
Because grow operations can happen in parallel with memory accesses on a
Grown memory must appear zeroed from the moment of its creation, including to any racy accesses in parallel. This can be accomplished via zero-filled-on-demand virtual memory pages, or careful synchronization if manually zeroing memory.
In practice it is difficult to implement
25.3 DataView Objects
25.3.1 Abstract Operations For DataView Objects
25.3.1.1 DataView With Buffer Witness Records
A DataView With Buffer Witness Record is a
DataView With Buffer Witness Records have the fields listed in
| Field Name | Value | Meaning |
|---|---|---|
| [[Object]] | a DataView | The DataView object whose buffer's byte length is loaded. |
| [[CachedBufferByteLength]] |
a non-negative |
The byte length of the object's [[ViewedArrayBuffer]] when the |
25.3.1.2 MakeDataViewWithBufferWitnessRecord ( obj, order )
The abstract operation MakeDataViewWithBufferWitnessRecord takes arguments obj (a DataView) and order (
- Let buffer be obj.[[ViewedArrayBuffer]].
- If
IsDetachedBuffer (buffer) istrue , then- Let byteLength be
detached .
- Let byteLength be
- Else,
- Let byteLength be
ArrayBufferByteLength (buffer, order).
- Let byteLength be
- Return the
DataView With Buffer Witness Record { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength }.
25.3.1.3 GetViewByteLength ( viewRecord )
The abstract operation GetViewByteLength takes argument viewRecord (a
Assert :IsViewOutOfBounds (viewRecord) isfalse .- Let view be viewRecord.[[Object]].
- If view.[[ByteLength]] is not
auto , return view.[[ByteLength]]. Assert :IsFixedLengthArrayBuffer (view.[[ViewedArrayBuffer]]) isfalse .- Let byteOffset be view.[[ByteOffset]].
- Let byteLength be viewRecord.[[CachedBufferByteLength]].
Assert : byteLength is notdetached .- Return byteLength - byteOffset.
25.3.1.4 IsViewOutOfBounds ( viewRecord )
The abstract operation IsViewOutOfBounds takes argument viewRecord (a
- Let view be viewRecord.[[Object]].
- Let bufferByteLength be viewRecord.[[CachedBufferByteLength]].
- If
IsDetachedBuffer (view.[[ViewedArrayBuffer]]) istrue , thenAssert : bufferByteLength isdetached .- Return
true .
Assert : bufferByteLength is a non-negativeinteger .- Let byteOffsetStart be view.[[ByteOffset]].
- If view.[[ByteLength]] is
auto , then- Let byteOffsetEnd be bufferByteLength.
- Else,
- Let byteOffsetEnd be byteOffsetStart + view.[[ByteLength]].
NOTE : A 0-length DataView whose [[ByteOffset]] is bufferByteLength is not considered out-of-bounds.- If byteOffsetStart > bufferByteLength or byteOffsetEnd > bufferByteLength, return
true . - Return
false .
25.3.1.5 GetViewValue ( view, requestIndex, isLittleEndian, type )
The abstract operation GetViewValue takes arguments view (an
- Perform ?
RequireInternalSlot (view, [[DataView]]). Assert : view has a [[ViewedArrayBuffer]] internal slot.- Let getIndex be ?
ToIndex (requestIndex). - Set isLittleEndian to
ToBoolean (isLittleEndian). - Let viewOffset be view.[[ByteOffset]].
- Let viewRecord be
MakeDataViewWithBufferWitnessRecord (view,unordered ). NOTE : Bounds checking is not a synchronizing operation when view's backing buffer is agrowable SharedArrayBuffer .- If
IsViewOutOfBounds (viewRecord) istrue , throw aTypeError exception. - Let viewSize be
GetViewByteLength (viewRecord). - Let elementSize be the Element Size value specified in
Table 70 for Element Type type. - If getIndex + elementSize > viewSize, throw a
RangeError exception. - Let bufferIndex be getIndex + viewOffset.
- Return
GetValueFromBuffer (view.[[ViewedArrayBuffer]], bufferIndex, type,false ,unordered , isLittleEndian).
25.3.1.6 SetViewValue ( view, requestIndex, isLittleEndian, type, value )
The abstract operation SetViewValue takes arguments view (an
- Perform ?
RequireInternalSlot (view, [[DataView]]). Assert : view has a [[ViewedArrayBuffer]] internal slot.- Let getIndex be ?
ToIndex (requestIndex). - If
IsBigIntElementType (type) istrue , let number be ?ToBigInt (value). - Else, let number be ?
ToNumber (value). - Set isLittleEndian to
ToBoolean (isLittleEndian). - Let viewOffset be view.[[ByteOffset]].
- Let viewRecord be
MakeDataViewWithBufferWitnessRecord (view,unordered ). NOTE : Bounds checking is not a synchronizing operation when view's backing buffer is agrowable SharedArrayBuffer .- If
IsViewOutOfBounds (viewRecord) istrue , throw aTypeError exception. - Let viewSize be
GetViewByteLength (viewRecord). - Let elementSize be the Element Size value specified in
Table 70 for Element Type type. - If getIndex + elementSize > viewSize, throw a
RangeError exception. - Let bufferIndex be getIndex + viewOffset.
- Perform
SetValueInBuffer (view.[[ViewedArrayBuffer]], bufferIndex, type, number,false ,unordered , isLittleEndian). - Return
undefined .
25.3.2 The DataView Constructor
The DataView
- is
%DataView% . - is the initial value of the
"DataView" property of theglobal object . - creates and initializes a new DataView when called as a
constructor . - is not intended to be called as a function and will throw an exception when called in that manner.
- may be used as the value of an
extendsclause of a class definition. Subclassconstructors that intend to inherit the specified DataView behaviour must include asupercall to the DataViewconstructor to create and initialize subclass instances with the internal state necessary to support the built-in methods ofDataView.prototype.
25.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] )
This function performs the following steps when called:
- If NewTarget is
undefined , throw aTypeError exception. - Perform ?
RequireInternalSlot (buffer, [[ArrayBufferData]]). - Let offset be ?
ToIndex (byteOffset). - If
IsDetachedBuffer (buffer) istrue , throw aTypeError exception. - Let bufferByteLength be
ArrayBufferByteLength (buffer,seq-cst ). - If offset > bufferByteLength, throw a
RangeError exception. - Let bufferIsFixedLength be
IsFixedLengthArrayBuffer (buffer). - If byteLength is
undefined , then- If bufferIsFixedLength is
true , then- Let viewByteLength be bufferByteLength - offset.
- Else,
- Let viewByteLength be
auto .
- Let viewByteLength be
- If bufferIsFixedLength is
- Else,
- Let viewByteLength be ?
ToIndex (byteLength). - If offset + viewByteLength > bufferByteLength, throw a
RangeError exception.
- Let viewByteLength be ?
- Let obj be ?
OrdinaryCreateFromConstructor (NewTarget," , « [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] »).%DataView.prototype% " - If
IsDetachedBuffer (buffer) istrue , throw aTypeError exception. - Set bufferByteLength to
ArrayBufferByteLength (buffer,seq-cst ). - If offset > bufferByteLength, throw a
RangeError exception. - If byteLength is not
undefined , then- If offset + viewByteLength > bufferByteLength, throw a
RangeError exception.
- If offset + viewByteLength > bufferByteLength, throw a
- Set obj.[[ViewedArrayBuffer]] to buffer.
- Set obj.[[ByteLength]] to viewByteLength.
- Set obj.[[ByteOffset]] to offset.
- Return obj.
25.3.3 Properties of the DataView Constructor
The DataView
- has a [[Prototype]] internal slot whose value is
%Function.prototype% . - has the following properties:
25.3.3.1 DataView.prototype
The initial value of DataView.prototype is the
This property has the attributes { [[Writable]]:
25.3.4 Properties of the DataView Prototype Object
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.
25.3.4.1 get DataView.prototype.buffer
DataView.prototype.buffer is an
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[DataView]]). Assert : obj has a [[ViewedArrayBuffer]] internal slot.- Let buffer be obj.[[ViewedArrayBuffer]].
- Return buffer.
25.3.4.2 get DataView.prototype.byteLength
DataView.prototype.byteLength is an
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[DataView]]). Assert : obj has a [[ViewedArrayBuffer]] internal slot.- Let viewRecord be
MakeDataViewWithBufferWitnessRecord (obj,seq-cst ). - If
IsViewOutOfBounds (viewRecord) istrue , throw aTypeError exception. - Let size be
GetViewByteLength (viewRecord). - Return
𝔽 (size).
25.3.4.3 get DataView.prototype.byteOffset
DataView.prototype.byteOffset is an
- Let obj be the
this value. - Perform ?
RequireInternalSlot (obj, [[DataView]]). Assert : obj has a [[ViewedArrayBuffer]] internal slot.- Let viewRecord be
MakeDataViewWithBufferWitnessRecord (obj,seq-cst ). - If
IsViewOutOfBounds (viewRecord) istrue , throw aTypeError exception. - Let offset be obj.[[ByteOffset]].
- Return
𝔽 (offset).
25.3.4.4 DataView.prototype.constructor
The initial value of DataView.prototype.constructor is
25.3.4.5 DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - Return ?
GetViewValue (view, byteOffset, littleEndian,bigint64 ).
25.3.4.6 DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - Return ?
GetViewValue (view, byteOffset, littleEndian,biguint64 ).
25.3.4.7 DataView.prototype.getFloat16 ( byteOffset [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
GetViewValue (view, byteOffset, littleEndian,float16 ).
25.3.4.8 DataView.prototype.getFloat32 ( byteOffset [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
GetViewValue (view, byteOffset, littleEndian,float32 ).
25.3.4.9 DataView.prototype.getFloat64 ( byteOffset [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
GetViewValue (view, byteOffset, littleEndian,float64 ).
25.3.4.10 DataView.prototype.getInt8 ( byteOffset )
This method performs the following steps when called:
- Let view be the
this value. - Return ?
GetViewValue (view, byteOffset,true ,int8 ).
25.3.4.11 DataView.prototype.getInt16 ( byteOffset [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
GetViewValue (view, byteOffset, littleEndian,int16 ).
25.3.4.12 DataView.prototype.getInt32 ( byteOffset [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
GetViewValue (view, byteOffset, littleEndian,int32 ).
25.3.4.13 DataView.prototype.getUint8 ( byteOffset )
This method performs the following steps when called:
- Let view be the
this value. - Return ?
GetViewValue (view, byteOffset,true ,uint8 ).
25.3.4.14 DataView.prototype.getUint16 ( byteOffset [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
GetViewValue (view, byteOffset, littleEndian,uint16 ).
25.3.4.15 DataView.prototype.getUint32 ( byteOffset [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
GetViewValue (view, byteOffset, littleEndian,uint32 ).
25.3.4.16 DataView.prototype.setBigInt64 ( byteOffset, value [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - Return ?
SetViewValue (view, byteOffset, littleEndian,bigint64 , value).
25.3.4.17 DataView.prototype.setBigUint64 ( byteOffset, value [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - Return ?
SetViewValue (view, byteOffset, littleEndian,biguint64 , value).
25.3.4.18 DataView.prototype.setFloat16 ( byteOffset, value [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
SetViewValue (view, byteOffset, littleEndian,float16 , value).
25.3.4.19 DataView.prototype.setFloat32 ( byteOffset, value [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
SetViewValue (view, byteOffset, littleEndian,float32 , value).
25.3.4.20 DataView.prototype.setFloat64 ( byteOffset, value [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
SetViewValue (view, byteOffset, littleEndian,float64 , value).
25.3.4.21 DataView.prototype.setInt8 ( byteOffset, value )
This method performs the following steps when called:
- Let view be the
this value. - Return ?
SetViewValue (view, byteOffset,true ,int8 , value).
25.3.4.22 DataView.prototype.setInt16 ( byteOffset, value [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
SetViewValue (view, byteOffset, littleEndian,int16 , value).
25.3.4.23 DataView.prototype.setInt32 ( byteOffset, value [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
SetViewValue (view, byteOffset, littleEndian,int32 , value).
25.3.4.24 DataView.prototype.setUint8 ( byteOffset, value )
This method performs the following steps when called:
- Let view be the
this value. - Return ?
SetViewValue (view, byteOffset,true ,uint8 , value).
25.3.4.25 DataView.prototype.setUint16 ( byteOffset, value [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
SetViewValue (view, byteOffset, littleEndian,uint16 , value).
25.3.4.26 DataView.prototype.setUint32 ( byteOffset, value [ , littleEndian ] )
This method performs the following steps when called:
- Let view be the
this value. - If littleEndian is not present, set littleEndian to
false . - Return ?
SetViewValue (view, byteOffset, littleEndian,uint32 , value).
25.3.4.27 DataView.prototype [ %Symbol.toStringTag% ]
The initial value of the
This property has the attributes { [[Writable]]:
25.3.5 Properties of DataView Instances
DataView instances are
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
25.4 The Atomics Object
The Atomics object:
- is
%Atomics% . - is the initial value of the
"Atomics" property of theglobal 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 thenewoperator. - 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
For informative guidelines for programming and implementing shared memory in ECMAScript, please see the notes at the end of the
25.4.1 Waiter Record
A Waiter Record is a Atomics.wait or Atomics.waitAsync.
A Waiter Record has fields listed in
| Field Name | Value | Meaning |
|---|---|---|
| [[AgentSignifier]] |
an |
The Atomics.wait or Atomics.waitAsync.
|
| [[PromiseCapability]] |
a |
If denoting a call to Atomics.waitAsync, the resulting promise, otherwise |
| [[TimeoutTime]] |
a non-negative |
The earliest time by which timeout may be triggered; computed using |
| [[Result]] |
|
The return value of the call. |
25.4.2 WaiterList Records
A WaiterList Record is used to explain waiting and notification of Atomics.wait, Atomics.waitAsync, and Atomics.notify.
A WaiterList Record has fields listed in
| Field Name | Value | Meaning |
|---|---|---|
| [[Waiters]] |
a |
The calls to Atomics.wait or Atomics.waitAsync that are waiting on the location with which this WaiterList is associated.
|
| [[MostRecentLeaveEvent]] |
a |
The event of the most recent leaving of its critical section, or |
There can be multiple
The
Each WaiterList Record has a critical section that controls exclusive access to that WaiterList Record during evaluation. Only a single
25.4.3 Abstract Operations for Atomics
25.4.3.1 ValidateIntegerTypedArray ( ta, waitable )
The abstract operation ValidateIntegerTypedArray takes arguments ta (an
- Let taRecord be ?
ValidateTypedArray (ta,unordered ). NOTE : Bounds checking is not a synchronizing operation when ta's backing buffer is agrowable SharedArrayBuffer .- If waitable is
true , then- If ta.[[TypedArrayName]] is neither
"Int32Array" nor"BigInt64Array" , throw aTypeError exception.
- If ta.[[TypedArrayName]] is neither
- Else,
- Let type be
TypedArrayElementType (ta). - If
IsUnclampedIntegerElementType (type) isfalse andIsBigIntElementType (type) isfalse , throw aTypeError exception.
- Let type be
- Return taRecord.
25.4.3.2 ValidateAtomicAccess ( taRecord, requestIndex )
The abstract operation ValidateAtomicAccess takes arguments taRecord (a
- Let length be
TypedArrayLength (taRecord). - Let accessIndex be ?
ToIndex (requestIndex). Assert : accessIndex ≥ 0.- If accessIndex ≥ length, throw a
RangeError exception. - Let ta be taRecord.[[Object]].
- Let elementSize be
TypedArrayElementSize (ta). - Let offset be ta.[[ByteOffset]].
- Return (accessIndex × elementSize) + offset.
25.4.3.3 ValidateAtomicAccessOnIntegerTypedArray ( ta, requestIndex )
The abstract operation ValidateAtomicAccessOnIntegerTypedArray takes arguments ta (an
- Let taRecord be ?
ValidateIntegerTypedArray (ta,false ). - Return ?
ValidateAtomicAccess (taRecord, requestIndex).
25.4.3.4 RevalidateAtomicAccess ( ta, byteIndexInBuffer )
The abstract operation RevalidateAtomicAccess takes arguments ta (a
- Let taRecord be
MakeTypedArrayWithBufferWitnessRecord (ta,unordered ). NOTE : Bounds checking is not a synchronizing operation when ta's backing buffer is agrowable SharedArrayBuffer .- If
IsTypedArrayOutOfBounds (taRecord) istrue , throw aTypeError exception. Assert : byteIndexInBuffer ≥ ta.[[ByteOffset]].- If byteIndexInBuffer ≥ taRecord.[[CachedBufferByteLength]], throw a
RangeError exception. - Return
unused .
25.4.3.5 GetWaiterList ( block, i )
The abstract operation GetWaiterList takes arguments block (a
Assert : i and i + 3 are valid byte offsets within the memory of block.- Return the
WaiterList Record that is referenced by the pair (block, i).
25.4.3.6 EnterCriticalSection ( waiterList )
The abstract operation EnterCriticalSection takes argument waiterList (a
Assert : Thesurrounding agent is not in thecritical section for anyWaiterList Record .- Wait until no
agent is in thecritical section for waiterList, then enter thecritical section for waiterList (without allowing any otheragent to enter). - If waiterList.[[MostRecentLeaveEvent]] is not
empty , thenNOTE : A waiterList whosecritical section has been entered at least once has aSynchronize event set byLeaveCriticalSection .- Let agentRecord be the
Agent Record of thesurrounding agent . - Let execution be agentRecord.[[CandidateExecution]].
- Let eventsRecord be the
Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] isAgentSignifier (). - Let enterEvent be a new
Synchronize event . - Append enterEvent to eventsRecord.[[EventList]].
- Append (waiterList.[[MostRecentLeaveEvent]], enterEvent) to eventsRecord.[[AgentSynchronizesWith]].
- Return
unused .
EnterCriticalSection has contention when an
25.4.3.7 LeaveCriticalSection ( waiterList )
The abstract operation LeaveCriticalSection takes argument waiterList (a
Assert : Thesurrounding agent is in thecritical section for waiterList.- Let agentRecord be the
Agent Record of thesurrounding agent . - Let execution be agentRecord.[[CandidateExecution]].
- Let eventsRecord be the
Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] isAgentSignifier (). - Let leaveEvent be a new
Synchronize event . - Append leaveEvent to eventsRecord.[[EventList]].
- Set waiterList.[[MostRecentLeaveEvent]] to leaveEvent.
- Leave the
critical section for waiterList. - Return
unused .
25.4.3.8 AddWaiter ( waiterList, waiterRecord )
The abstract operation AddWaiter takes arguments waiterList (a
Assert : Thesurrounding agent is in thecritical section for waiterList.Assert : There is noWaiter Record in waiterList.[[Waiters]] whose [[PromiseCapability]] field is waiterRecord.[[PromiseCapability]] and whose [[AgentSignifier]] field is waiterRecord.[[AgentSignifier]].- Append waiterRecord to waiterList.[[Waiters]].
- Return
unused .
25.4.3.9 RemoveWaiter ( waiterList, waiterRecord )
The abstract operation RemoveWaiter takes arguments waiterList (a
Assert : Thesurrounding agent is in thecritical section for waiterList.Assert : waiterList.[[Waiters]] contains waiterRecord.- Remove waiterRecord from waiterList.[[Waiters]].
- Return
unused .
25.4.3.10 RemoveWaiters ( waiterList, count )
The abstract operation RemoveWaiters takes arguments waiterList (a
Assert : Thesurrounding agent is in thecritical section for waiterList.- Let length be the number of elements in waiterList.[[Waiters]].
- Set count to
min (count, length). - Let waiters be a
List whose elements are the first count elements of waiterList.[[Waiters]]. - Remove the first count elements of waiterList.[[Waiters]].
- Return waiters.
25.4.3.11 SuspendThisAgent ( waiterList, waiterRecord )
The abstract operation SuspendThisAgent takes arguments waiterList (a
Assert : Thesurrounding agent is in thecritical section for waiterList.Assert : waiterList.[[Waiters]] contains waiterRecord.- Let thisAgent be
AgentSignifier (). Assert : waiterRecord.[[AgentSignifier]] is thisAgent.Assert : waiterRecord.[[PromiseCapability]] isblocking .Assert :AgentCanSuspend () istrue .- Perform
LeaveCriticalSection (waiterList) and suspend thesurrounding agent until the time is waiterRecord.[[TimeoutTime]], performing the combined operation in such a way that a notification that arrives after thecritical section is exited but before the suspension takes effect is not lost. Thesurrounding agent can only wake from suspension due to a timeout or due to anotheragent callingNotifyWaiter with arguments waiterList and thisAgent (i.e. via a call toAtomics.notify). - Perform
EnterCriticalSection (waiterList). - Return
unused .
25.4.3.12 NotifyWaiter ( waiterList, waiterRecord )
The abstract operation NotifyWaiter takes arguments waiterList (a
Assert : Thesurrounding agent is in thecritical section for waiterList.- If waiterRecord.[[PromiseCapability]] is
blocking , then- Wake the
agent whose signifier is waiterRecord.[[AgentSignifier]] from suspension. NOTE : This causes theagent to resume execution inSuspendThisAgent .
- Wake the
- Else if
AgentSignifier () is waiterRecord.[[AgentSignifier]], then- Let promiseCapability be waiterRecord.[[PromiseCapability]].
- Perform !
Call (promiseCapability.[[Resolve]],undefined , « waiterRecord.[[Result]] »).
- Else,
- Perform
EnqueueResolveInAgentJob (waiterRecord.[[AgentSignifier]], waiterRecord.[[PromiseCapability]], waiterRecord.[[Result]]).
- Perform
- Return
unused .
25.4.3.13 EnqueueResolveInAgentJob ( agentSignifier, promiseCapability, resolution )
The abstract operation EnqueueResolveInAgentJob takes arguments agentSignifier (an
- Let resolveJob be a new
Job Abstract Closure with no parameters that captures agentSignifier, promiseCapability, and resolution and performs the following steps when called:Assert :AgentSignifier () is agentSignifier.- Perform !
Call (promiseCapability.[[Resolve]],undefined , « resolution »). - Return
unused .
- Let realmInTargetAgent be !
GetFunctionRealm (promiseCapability.[[Resolve]]). Assert : agentSignifier is realmInTargetAgent.[[AgentSignifier]].- Perform
HostEnqueueGenericJob (resolveJob, realmInTargetAgent). - Return
unused .
25.4.3.14 DoWait ( mode, ta, index, value, timeout )
The abstract operation DoWait takes arguments mode (
- Let taRecord be ?
ValidateIntegerTypedArray (ta,true ). - Let buffer be taRecord.[[Object]].[[ViewedArrayBuffer]].
- If
IsSharedArrayBuffer (buffer) isfalse , throw aTypeError exception. - Let byteIndexInBuffer be ?
ValidateAtomicAccess (taRecord, index). - Let arrayTypeName be ta.[[TypedArrayName]].
- If arrayTypeName is
"BigInt64Array" , let expected be ?ToBigInt64 (value). - Else, let expected be ?
ToInt32 (value). - Let timeoutNumber be ?
ToNumber (timeout). - If timeoutNumber is either
NaN or+∞ 𝔽, let realTimeout be +∞. - Else if timeoutNumber is
-∞ 𝔽, let realTimeout be 0. - Else, let realTimeout be
max (ℝ (timeoutNumber), 0). - If mode is
sync andAgentCanSuspend () isfalse , throw aTypeError exception. - Let block be buffer.[[ArrayBufferData]].
- Let waiterList be
GetWaiterList (block, byteIndexInBuffer). - If mode is
sync , then- Let promiseCapability be
blocking . - Let resultObj be
undefined .
- Let promiseCapability be
- Else,
- Let promiseCapability be !
NewPromiseCapability (%Promise% ). - Let resultObj be
OrdinaryObjectCreate (%Object.prototype% ).
- Let promiseCapability be !
- Perform
EnterCriticalSection (waiterList). - Let elementType be
TypedArrayElementType (ta). - Let witness be
GetValueFromBuffer (buffer, byteIndexInBuffer, elementType,true ,seq-cst ). - If expected ≠ witness, then
- Perform
LeaveCriticalSection (waiterList). - If mode is
sync , return"not-equal" . - Perform !
CreateDataPropertyOrThrow (resultObj,"async" ,false ). - Perform !
CreateDataPropertyOrThrow (resultObj,"value" ,"not-equal" ). - Return resultObj.
- Perform
- If realTimeout = 0 and mode is
async , thenNOTE : There is no special handling of synchronous immediate timeouts. Asynchronous immediate timeouts have special handling in order to fail fast and avoid unnecessary Promise jobs.- Perform
LeaveCriticalSection (waiterList). - Perform !
CreateDataPropertyOrThrow (resultObj,"async" ,false ). - Perform !
CreateDataPropertyOrThrow (resultObj,"value" ,"timed-out" ). - Return resultObj.
- Let thisAgent be
AgentSignifier (). - Let now be the
time value (UTC) identifying the current time. - Let additionalTimeout be an
implementation-defined non-negativemathematical value . - Let timeoutTime be
ℝ (now) + realTimeout + additionalTimeout. NOTE : When realTimeout is +∞, timeoutTime is also +∞.- Let waiterRecord be a new
Waiter Record { [[AgentSignifier]]: thisAgent, [[PromiseCapability]]: promiseCapability, [[TimeoutTime]]: timeoutTime, [[Result]]:"ok" }. - Perform
AddWaiter (waiterList, waiterRecord). - If mode is
sync , then- Perform
SuspendThisAgent (waiterList, waiterRecord).
- Perform
- Else if timeoutTime is
finite , then- Perform
EnqueueAtomicsWaitAsyncTimeoutJob (waiterList, waiterRecord).
- Perform
- Perform
LeaveCriticalSection (waiterList). - If mode is
sync , return waiterRecord.[[Result]]. - Perform !
CreateDataPropertyOrThrow (resultObj,"async" ,true ). - Perform !
CreateDataPropertyOrThrow (resultObj,"value" , promiseCapability.[[Promise]]). - Return resultObj.
additionalTimeout allows implementations to pad timeouts as necessary, such as for reducing power consumption or coarsening timer resolution to mitigate timing attacks. This value may differ from call to call of DoWait.
25.4.3.15 EnqueueAtomicsWaitAsyncTimeoutJob ( waiterList, waiterRecord )
The abstract operation EnqueueAtomicsWaitAsyncTimeoutJob takes arguments waiterList (a
- Let timeoutJob be a new
Job Abstract Closure with no parameters that captures waiterList and waiterRecord and performs the following steps when called:- Perform
EnterCriticalSection (waiterList). - If waiterList.[[Waiters]] contains waiterRecord, then
- Let timeOfJobExecution be the
time value (UTC) identifying the current time. Assert :ℝ (timeOfJobExecution) ≥ waiterRecord.[[TimeoutTime]] (ignoring potential non-monotonicity oftime values ).- Set waiterRecord.[[Result]] to
"timed-out" . - Perform
RemoveWaiter (waiterList, waiterRecord). - Perform
NotifyWaiter (waiterList, waiterRecord).
- Let timeOfJobExecution be the
- Perform
LeaveCriticalSection (waiterList). - Return
unused .
- Perform
- Let now be the
time value (UTC) identifying the current time. - Let currentRealm be
the current Realm Record . - Perform
HostEnqueueTimeoutJob (timeoutJob, currentRealm,𝔽 (waiterRecord.[[TimeoutTime]]) - now). - Return
unused .
25.4.3.16 AtomicCompareExchangeInSharedBlock ( block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes )
The abstract operation AtomicCompareExchangeInSharedBlock takes arguments block (a
- Let agentRecord be the
Agent Record of thesurrounding agent . - Let execution be agentRecord.[[CandidateExecution]].
- Let eventsRecord be the
Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] isAgentSignifier (). - Let rawBytesRead be a
List of length elementSize whose elements are nondeterministically chosenbyte values . 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 thememory model to describe observable behaviour of hardware with weak consistency.NOTE : The comparison of the expected value and the read value is performed outside of theread-modify-write modification function to avoid needlessly strong synchronization when the expected value is not equal to the read value.- If
ByteListEqual (rawBytesRead, expectedBytes) istrue , then- 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:- Return newBytes.
- Let event be
ReadModifyWriteSharedMemory { [[Order]]:seq-cst , [[NoTear]]:true , [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize, [[Payload]]: replacementBytes, [[ModifyOp]]: second }.
- Let second be a new
- Else,
- Let event be
ReadSharedMemory { [[Order]]:seq-cst , [[NoTear]]:true , [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize }.
- Let event be
- Append event to eventsRecord.[[EventList]].
- Append
Chosen Value Record { [[Event]]: event, [[ChosenValue]]: rawBytesRead } to execution.[[ChosenValues]]. - Return rawBytesRead.
25.4.3.17 AtomicReadModifyWrite ( ta, index, value, op )
The abstract operation AtomicReadModifyWrite takes arguments ta (an
- Let byteIndexInBuffer be ?
ValidateAtomicAccessOnIntegerTypedArray (ta, index). - If ta.[[ContentType]] is
bigint , let coerced be ?ToBigInt (value). - Else, let coerced be
𝔽 (?ToIntegerOrInfinity (value)). - Perform ?
RevalidateAtomicAccess (ta, byteIndexInBuffer). - Let buffer be ta.[[ViewedArrayBuffer]].
- Let elementType be
TypedArrayElementType (ta). - Return
GetModifySetValueInBuffer (buffer, byteIndexInBuffer, elementType, coerced, op).
25.4.3.18 ByteListBitwiseOp ( op, xBytes, yBytes )
The abstract operation ByteListBitwiseOp takes arguments op (&, ^, or |), xBytes (a
Assert : xBytes and yBytes have the same number of elements.- Let result be a new empty
List . - Let i be 0.
- For each element xByte of xBytes, do
- Let yByte be yBytes[i].
- If op is
&, then- Let resultByte be the result of applying the bitwise AND operation to xByte and yByte.
- Else if op is
^, then- Let resultByte be the result of applying the bitwise exclusive OR (XOR) operation to xByte and yByte.
- Else,
Assert : op is|.- Let resultByte be the result of applying the bitwise inclusive OR operation to xByte and yByte.
- Set i to i + 1.
- Append resultByte to result.
- Return result.
25.4.3.19 ByteListEqual ( xBytes, yBytes )
The abstract operation ByteListEqual takes arguments xBytes (a
- If xBytes and yBytes do not have the same number of elements, return
false . - Let i be 0.
- For each element xByte of xBytes, do
- Let yByte be yBytes[i].
- If xByte ≠ yByte, return
false . - Set i to i + 1.
- Return
true .
25.4.4 Atomics.add ( ta, index, value )
This function performs the following steps when called:
- Let add be a new
read-modify-write modification function with parameters (xBytes, yBytes) that captures ta and performs the following steps atomically when called:- Let type be
TypedArrayElementType (ta). - Let agentRecord be the
Agent Record of thesurrounding agent . - Let isLittleEndian be agentRecord.[[LittleEndian]].
- Let x be
RawBytesToNumeric (type, xBytes, isLittleEndian). - Let y be
RawBytesToNumeric (type, yBytes, isLittleEndian). - If x
is a Number , then- Let sum be
Number::add (x, y).
- Let sum be
- Else,
Assert : xis a BigInt .- Let sum be
BigInt::add (x, y).
- Let sumBytes be
NumericToRawBytes (type, sum, isLittleEndian). Assert : sumBytes, xBytes, and yBytes have the same number of elements.- Return sumBytes.
- Let type be
- Return ?
AtomicReadModifyWrite (ta, index, value, add).
25.4.5 Atomics.and ( ta, index, value )
This function performs the following steps when called:
- 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:- Return
ByteListBitwiseOp (&, xBytes, yBytes).
- Return
- Return ?
AtomicReadModifyWrite (ta, index, value, and).
25.4.6 Atomics.compareExchange ( ta, index, expectedValue, replacementValue )
This function performs the following steps when called:
- Let byteIndexInBuffer be ?
ValidateAtomicAccessOnIntegerTypedArray (ta, index). - Let buffer be ta.[[ViewedArrayBuffer]].
- Let block be buffer.[[ArrayBufferData]].
- If ta.[[ContentType]] is
bigint , then - Else,
- Let expected be
𝔽 (?ToIntegerOrInfinity (expectedValue)). - Let replacement be
𝔽 (?ToIntegerOrInfinity (replacementValue)).
- Let expected be
- Perform ?
RevalidateAtomicAccess (ta, byteIndexInBuffer). - Let elementType be
TypedArrayElementType (ta). - Let elementSize be
TypedArrayElementSize (ta). - Let agentRecord be the
Agent Record of thesurrounding agent . - Let isLittleEndian be agentRecord.[[LittleEndian]].
- Let expectedBytes be
NumericToRawBytes (elementType, expected, isLittleEndian). - Let replacementBytes be
NumericToRawBytes (elementType, replacement, isLittleEndian). - If
IsSharedArrayBuffer (buffer) istrue , then- Let rawBytesRead be
AtomicCompareExchangeInSharedBlock (block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes).
- Let rawBytesRead be
- Else,
- Let rawBytesRead be a
List of length elementSize whose elements are the sequence of elementSize bytes starting with block[byteIndexInBuffer]. - If
ByteListEqual (rawBytesRead, expectedBytes) istrue , then- Store the individual bytes of replacementBytes into block, starting at block[byteIndexInBuffer].
- Let rawBytesRead be a
- Return
RawBytesToNumeric (elementType, rawBytesRead, isLittleEndian).
25.4.7 Atomics.exchange ( ta, index, value )
This function performs the following steps when called:
- 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:- Return newBytes.
- Return ?
AtomicReadModifyWrite (ta, index, value, second).
25.4.8 Atomics.isLockFree ( size )
This function performs the following steps when called:
- Let n be ?
ToIntegerOrInfinity (size). - Let agentRecord be the
Agent Record of thesurrounding agent . - If n = 1, return agentRecord.[[IsLockFree1]].
- If n = 2, return agentRecord.[[IsLockFree2]].
- If n = 4, return
true . - If n = 8, return agentRecord.[[IsLockFree8]].
- Return
false .
This function 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 Atomics.isLockFree(n) will return
Atomics.isLockFree(4) always returns
Regardless of the value returned by this function, 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.9 Atomics.load ( ta, index )
This function performs the following steps when called:
- Let byteIndexInBuffer be ?
ValidateAtomicAccessOnIntegerTypedArray (ta, index). - Perform ?
RevalidateAtomicAccess (ta, byteIndexInBuffer). - Let buffer be ta.[[ViewedArrayBuffer]].
- Let elementType be
TypedArrayElementType (ta). - Return
GetValueFromBuffer (buffer, byteIndexInBuffer, elementType,true ,seq-cst ).
25.4.10 Atomics.notify ( ta, index, count )
This function notifies some
It performs the following steps when called:
- Let taRecord be ?
ValidateIntegerTypedArray (ta,true ). - Let byteIndexInBuffer be ?
ValidateAtomicAccess (taRecord, index). - If count is
undefined , then- Set count to +∞.
- Else,
- Let intCount be ?
ToIntegerOrInfinity (count). - Set count to
max (intCount, 0).
- Let intCount be ?
- Let buffer be ta.[[ViewedArrayBuffer]].
- Let block be buffer.[[ArrayBufferData]].
- If
IsSharedArrayBuffer (buffer) isfalse , return+0 𝔽. - Let waiterList be
GetWaiterList (block, byteIndexInBuffer). - Perform
EnterCriticalSection (waiterList). - Let waiters be
RemoveWaiters (waiterList, count). - For each element waiterRecord of waiters, do
- Perform
NotifyWaiter (waiterList, waiterRecord).
- Perform
- Perform
LeaveCriticalSection (waiterList). - Let waitersCount be the number of elements in waiters.
- Return
𝔽 (waitersCount).
25.4.11 Atomics.or ( ta, index, value )
This function performs the following steps when called:
- 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:- Return
ByteListBitwiseOp (|, xBytes, yBytes).
- Return
- Return ?
AtomicReadModifyWrite (ta, index, value, or).
25.4.12 Atomics.pause ( )
This function provides a hint to the CPU that the program is spin looping while waiting on a value.
It performs the following steps when called:
- If the execution environment of the ECMAScript implementation supports signaling to the operating system or CPU that the current executing code is in a spin-wait loop, send that signal.
- Return
undefined .
This method is designed for programs implementing spin-wait loops, such as spinlock fast paths inside of mutexes, to provide a hint to the CPU that it is spinning while waiting on a value. It has no observable behaviour other than timing.
Implementations are expected to implement a pause or yield instruction if the best practices of the underlying architecture recommends such instructions in spin loops. For example, the Intel Optimization Manual recommends the pause instruction.
Implementations are encouraged to have an internal upper bound on the maximum amount of time paused on the order of tens to hundreds of nanoseconds.
Due to the overhead of function calls, it is reasonable that an inlined call to this method in an optimizing compiler waits a different amount of time than a non-inlined call.
25.4.13 Atomics.store ( ta, index, value )
This function performs the following steps when called:
- Let byteIndexInBuffer be ?
ValidateAtomicAccessOnIntegerTypedArray (ta, index). - If ta.[[ContentType]] is
bigint , let coerced be ?ToBigInt (value). - Else, let coerced be
𝔽 (?ToIntegerOrInfinity (value)). - Perform ?
RevalidateAtomicAccess (ta, byteIndexInBuffer). - Let buffer be ta.[[ViewedArrayBuffer]].
- Let elementType be
TypedArrayElementType (ta). - Perform
SetValueInBuffer (buffer, byteIndexInBuffer, elementType, coerced,true ,seq-cst ). - Return coerced.
25.4.14 Atomics.sub ( ta, index, value )
This function performs the following steps when called:
- Let subtract be a new
read-modify-write modification function with parameters (xBytes, yBytes) that captures ta and performs the following steps atomically when called:- Let type be
TypedArrayElementType (ta). - Let agentRecord be the
Agent Record of thesurrounding agent . - Let isLittleEndian be agentRecord.[[LittleEndian]].
- Let x be
RawBytesToNumeric (type, xBytes, isLittleEndian). - Let y be
RawBytesToNumeric (type, yBytes, isLittleEndian). - If x
is a Number , then- Let difference be
Number::subtract (x, y).
- Let difference be
- Else,
Assert : xis a BigInt .- Let difference be
BigInt::subtract (x, y).
- Let differenceBytes be
NumericToRawBytes (type, difference, isLittleEndian). Assert : differenceBytes, xBytes, and yBytes have the same number of elements.- Return differenceBytes.
- Let type be
- Return ?
AtomicReadModifyWrite (ta, index, value, subtract).
25.4.15 Atomics.wait ( ta, index, value, timeout )
This function puts the
It performs the following steps when called:
- Return ?
DoWait (sync , ta, index, value, timeout).
25.4.16 Atomics.waitAsync ( ta, index, value, timeout )
25.4.17 Atomics.xor ( ta, index, value )
This function performs the following steps when called:
- 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:- Return
ByteListBitwiseOp (^, xBytes, yBytes).
- Return
- Return ?
AtomicReadModifyWrite (ta, index, value, xor).
25.4.18 Atomics [ %Symbol.toStringTag% ]
The initial value of the
This property has the attributes { [[Writable]]:
25.5 The JSON Object
The JSON object:
- is
%JSON% . - is the initial value of the
"JSON" property of theglobal object . - is an
ordinary object . - contains two functions,
parseandstringify, that are used to parse and construct JSON texts. - 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 thenewoperator. - does not have a [[Call]] internal method; it cannot be invoked as a function.
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.
25.5.1 JSON.isRawJSON ( obj )
This function performs the following steps when called:
- If obj
is an Object and obj has an [[IsRawJSON]] internal slot, returntrue . - Return
false .
25.5.2 JSON.parse ( text [ , reviver ] )
This function parses a JSON text (a JSON-formatted String) and produces an
The optional reviver parameter is a function that can filter and transform the results. For each value produced by the parse, reviver is called with three arguments (the associated
- Let jsonString be ?
ToString (text). - Let parseResult be ?
ParseJSON (jsonString). - Let unfiltered be parseResult.[[Value]].
- If
IsCallable (reviver) isfalse , return unfiltered. - Let root be
OrdinaryObjectCreate (%Object.prototype% ). - Let rootName be the empty String.
- Perform !
CreateDataPropertyOrThrow (root, rootName, unfiltered). - Let snapshot be
.CreateJSONParseRecord (parseResult.[[ParseNode]], rootName, unfiltered) - Return ?
InternalizeJSONProperty (root, rootName, reviver, snapshot).
The
25.5.2.1 ParseJSON ( text )
The abstract operation ParseJSON takes argument text (a String) and returns either a
- If
StringToCodePoints (text) is not a valid JSON text as specified in ECMA-404, throw aSyntaxError exception. - Let scriptString be the
string-concatenation of"(" , text, and");" . - Let script be
ParseText (scriptString,Script ). NOTE : Theearly error rules defined in13.2.5.1 have special handling for the above invocation ofParseText .Assert : script is aParse Node .- Let result be !
.Evaluation of script NOTE : ThePropertyDefinitionEvaluation semantics defined in13.2.5.6 have special handling for the above evaluation.Assert : result is either a String, a Number, a Boolean, an Object that is defined by either anArrayLiteral or anObjectLiteral , ornull .- Return the
Record { [[ParseNode]]: script, [[Value]]: result }.
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.
Valid JSON text is a subset of the ECMAScript
However, because
In the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten.
25.5.2.2 JSON Parse Record
A JSON Parse Record is a
JSON Parse Records have the fields listed in
| Field Name | Value | Meaning |
|---|---|---|
| [[ParseNode]] | a |
The context |
| [[Key]] | a |
The |
| [[Value]] | an |
The value produced by evaluation of [[ParseNode]]. |
| [[Elements]] | a |
If [[Value]] is an Array, this contains the JSON Parse Records corresponding with the elements of [[Value]]. Otherwise, this is an empty |
| [[Entries]] | a |
If [[Value]] is a non-Array Object, this contains the JSON Parse Records corresponding with the entries of [[Value]]. Otherwise, this is an empty |
25.5.2.3 CreateJSONParseRecord ( parseNode, key, value )
The abstract operation CreateJSONParseRecord takes arguments parseNode (a
- Let typedValueNode be
ShallowestContainedJSONValue (parseNode). Assert : typedValueNode is notempty .- Let elements be a new empty
List . - Let entries be a new empty
List . - If value
is an Object , then- Let isArray be !
.IsArray (value) - If isArray is
true , thenAssert : typedValueNode is anArrayLiteral Parse Node .- Let contentNodes be the
JSONArrayLiteralContentNodes of typedValueNode. - Let length be the number of elements in contentNodes.
- Let valueLength be !
.LengthOfArrayLike (value) Assert : valueLength is length.- Let index be 0.
- Repeat, while index < length,
- Else,
Assert : typedValueNode is anObjectLiteral Parse Node .- Let propertyNodes be the
PropertyDefinitionNodes of typedValueNode. NOTE : Because value was produced from JSON text and has not been modified, all of itsproperty keys are Strings and will be exhaustively enumerated.- Let keys be !
.EnumerableOwnProperties (value,key ) - For each String propertyKey of keys, do
NOTE : In the case of JSON text specifying multiple name/value pairs with the same name for a single object (such as{"a":"lost","a":"kept"}), the value for the corresponding property of the resulting ECMAScript object is specified by the last pair with that name.- Let propertyDefinition be
empty . - For each
Parse Node propertyNode of propertyNodes, do- Let propertyName be the
PropName of propertyNode. - If propertyName is propertyKey, set propertyDefinition to propertyNode.
- Let propertyName be the
Assert : propertyDefinition is .PropertyDefinition : PropertyName : AssignmentExpression - Let propertyValueNode be the
AssignmentExpression of propertyDefinition. - Let entryParseRecord be CreateJSONParseRecord(propertyValueNode, propertyKey, !
).Get (value, propertyKey) - Append entryParseRecord to entries.
- Let isArray be !
- Else,
Assert : typedValueNode is neither anArrayLiteral Parse Node nor anObjectLiteral Parse Node .
- Return the
JSON Parse Record { [[ParseNode]]: typedValueNode, [[Key]]: key, [[Value]]: value, [[Elements]]: elements, [[Entries]]: entries }.
25.5.2.4 InternalizeJSONProperty ( holder, name, reviver, parseRecord )
The abstract operation InternalizeJSONProperty takes arguments holder (an Object), name (a String), reviver (a
This algorithm intentionally does not throw an exception if either [[Delete]] or
It performs the following steps when called:
- Let value be ?
Get (holder, name). - Let context be
OrdinaryObjectCreate (%Object.prototype% ). - If parseRecord is a
JSON Parse Record andSameValue (parseRecord.[[Value]], value) istrue , then- If value
is not an Object , then- Let parseNode be parseRecord.[[ParseNode]].
Assert : parseNode is neither anArrayLiteral Parse Node nor anObjectLiteral Parse Node .- Let sourceText be the
source text matched by parseNode. - Perform !
CreateDataPropertyOrThrow (context,"source" ,CodePointsToString (sourceText)).
- Let elementRecords be parseRecord.[[Elements]].
- Let entryRecords be parseRecord.[[Entries]].
- If value
- Else,
- If value
is an Object , then- Let isArray be ?
IsArray (value). - If isArray is
true , then- Let elementRecordsLength be the number of elements in elementRecords.
- Let length be ?
LengthOfArrayLike (value). - Let index be 0.
- Repeat, while index < length,
- Let propertyKey be !
ToString (𝔽 (index)). - If index < elementRecordsLength, let elementRecord be elementRecords[index]; else let elementRecord be
empty . - Let newElement be ? InternalizeJSONProperty(value, propertyKey, reviver, elementRecord).
- If newElement is
undefined , then- Perform ?
value.[[Delete]](propertyKey) .
- Perform ?
- Else,
- Perform ?
CreateDataProperty (value, propertyKey, newElement).
- Perform ?
- Set index to index + 1.
- Let propertyKey be !
- Else,
- Let keys be ?
EnumerableOwnProperties (value,key ). - For each String propertyKey of keys, do
- If there exists an element entry of entryRecords such that entry.[[Key]] is propertyKey, let entryRecord be entry; else let entryRecord be
empty . - Let newElement be ? InternalizeJSONProperty(value, propertyKey, reviver, entryRecord).
- If newElement is
undefined , then- Perform ?
value.[[Delete]](propertyKey) .
- Perform ?
- Else,
- Perform ?
CreateDataProperty (value, propertyKey, newElement).
- Perform ?
- If there exists an element entry of entryRecords such that entry.[[Key]] is propertyKey, let entryRecord be entry; else let entryRecord be
- Let keys be ?
- Let isArray be ?
- Return ?
Call (reviver, holder, « name, value, context »).
25.5.2.5 Static Semantics: ShallowestContainedJSONValue ( root )
The abstract operation ShallowestContainedJSONValue takes argument root (a
- Let activeFunc be the
active function object . Assert : activeFunc is aJSON.parsebuilt-infunction object (seeJSON.parse ).- Let types be «
NullLiteral ,BooleanLiteral ,NumericLiteral ,StringLiteral ,ArrayLiteral ,ObjectLiteral ,UnaryExpression ». - Let unaryExpr be
empty . - Let queue be « root ».
- Repeat, while queue is not empty,
- Let candidate be the first element of queue.
- Remove the first element from queue.
- Let queuedChildren be
false . - For each nonterminal type of types, do
- If candidate is an instance of type, then
NOTE : In the JSON grammar, anumbertoken may represent a negative value. In ECMAScript, negation is represented as a unary operation in which aUnaryExpression parses to a-followed by a derivedUnaryExpression .- If type is
UnaryExpression , then- If the parent of candidate is not a
UnaryExpression Parse Node , set unaryExpr to candidate.
- If the parent of candidate is not a
- Else if type is
NumericLiteral , thenAssert : candidate is contained within unaryExpr.- Return unaryExpr.
- Else,
- Return candidate.
- If queuedChildren is
false , candidate is an instance of a nonterminal, and candidateContains type istrue , then- Let children be a
List containing each child node of candidate, in order. - Set queue to the
list-concatenation of queue and children. - Set queuedChildren to
true .
- Let children be a
- If candidate is an instance of type, then
- Return
empty .
25.5.2.6 Static Semantics: JSONArrayLiteralContentNodes
The
Assert :Elision is not present.- If
ElementList is not present, return a new emptyList . - Return the JSONArrayLiteralContentNodes of
ElementList .
Assert :Elision is not present.- Return «
AssignmentExpression ».
Assert :Elision is not present.- Let elements be the JSONArrayLiteralContentNodes of the derived
ElementList . - Return the
list-concatenation of elements and «AssignmentExpression ».
NOTE : JSON text as specified in ECMA-404 does not includeSpreadElement .Assert : This step is never reached.
25.5.3 JSON.rawJSON ( text )
This function returns an object representing raw JSON text of a string, number, boolean, or null value.
- Let jsonString be ?
ToString (text). - If jsonString is the empty String, throw a
SyntaxError exception. - If the first code unit of jsonString is not either an ASCII lowercase letter code unit (0x0061 through 0x007A, inclusive), an ASCII digit code unit (0x0030 through 0x0039, inclusive), 0x0022 (QUOTATION MARK), or 0x002D (HYPHEN-MINUS), throw a
SyntaxError exception. - If the last code unit of jsonString is not either an ASCII lowercase letter code unit (0x0061 through 0x007A, inclusive), an ASCII digit code unit (0x0030 through 0x0039, inclusive), or 0x0022 (QUOTATION MARK), throw a
SyntaxError exception. - Let parseResult be ?
ParseJSON (jsonString). Assert : parseResult.[[Value]] is either a String, a Number, a Boolean, ornull .- Let internalSlotsList be « [[IsRawJSON]] ».
- Let obj be
OrdinaryObjectCreate (null , internalSlotsList). - Perform !
CreateDataPropertyOrThrow (obj,"rawJSON" , jsonString). - Perform !
SetIntegrityLevel (obj,frozen ). - Return obj.
25.5.4 JSON.stringify ( value [ , replacer [ , space ] ] )
This function returns a String in UTF-16 encoded JSON format representing an
It performs the following steps when called:
- Let stack be a new empty
List . - Let indent be the empty String.
- Let propertyList be
undefined . - Let replacerFunc be
undefined . - If replacer
is an Object , then- If
IsCallable (replacer) istrue , then- Set replacerFunc to replacer.
- Else,
- Let isArray be ?
IsArray (replacer). - If isArray is
true , then- Set propertyList to a new empty
List . - Let length be ?
LengthOfArrayLike (replacer). - Let k be 0.
- Repeat, while k < length,
- Let propertyKey be !
ToString (𝔽 (k)). - Let propertyValue be ?
Get (replacer, propertyKey). - Let item be
undefined . - If propertyValue
is a String , then- Set item to propertyValue.
- Else if propertyValue
is a Number , then- Set item to !
ToString (propertyValue).
- Set item to !
- Else if propertyValue
is an Object , then- If propertyValue has a [[StringData]] or [[NumberData]] internal slot, set item to ?
ToString (propertyValue).
- If propertyValue has a [[StringData]] or [[NumberData]] internal slot, set item to ?
- If item is not
undefined and propertyList does not contain item, then- Append item to propertyList.
- Set k to k + 1.
- Let propertyKey be !
- Set propertyList to a new empty
- Let isArray be ?
- If
- If space
is an Object , then - If space
is a Number , then- Let spaceMV be !
ToIntegerOrInfinity (space). - Set spaceMV to
min (10, spaceMV). - If spaceMV < 1, let gap be the empty String; else let gap be the String value containing spaceMV occurrences of the code unit 0x0020 (SPACE).
- Let spaceMV be !
- Else if space
is a String , then- If the length of space ≤ 10, let gap be space; else let gap be the
substring of space from 0 to 10.
- If the length of space ≤ 10, let gap be space; else let gap be the
- Else,
- Let gap be the empty String.
- Let wrapper be
OrdinaryObjectCreate (%Object.prototype% ). - Perform !
CreateDataPropertyOrThrow (wrapper, the empty String, value). - Let state be the
JSON Serialization Record { [[ReplacerFunction]]: replacerFunc, [[Stack]]: stack, [[Indent]]: indent, [[Gap]]: gap, [[PropertyList]]: propertyList }. - Return ?
SerializeJSONProperty (state, the empty String, wrapper).
The
JSON structures are allowed to be nested to any depth, but they must be acyclic. If value is or contains a cyclic structure, then this function must throw a
a = [];
a[0] = a;
my_text = JSON.stringify(a); // This must throw a TypeError.
Symbolic primitive values are rendered as follows:
-
The
null value is rendered in JSON text as the String value"null" . -
The
undefined value is not rendered. -
The
true value is rendered in JSON text as the String value"true" . -
The
false value is rendered in JSON text as the String value"false" .
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).
Values that do not have a JSON representation (such as
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
25.5.4.1 JSON Serialization Record
A JSON Serialization Record is a
JSON Serialization Records have the fields listed in
| Field Name | Value | Meaning |
|---|---|---|
| [[ReplacerFunction]] | a |
A function that can supply replacement values for object properties (from JSON.stringify's replacer parameter). |
| [[PropertyList]] | either a |
The names of properties to include when serializing a non-array object (from JSON.stringify's replacer parameter). |
| [[Gap]] | a String | The unit of indentation (from JSON.stringify's space parameter). |
| [[Stack]] | a |
The set of nested objects that are in the process of being serialized. Used to detect cyclic structures. |
| [[Indent]] | a String | The current indentation. |
25.5.4.2 SerializeJSONProperty ( state, key, holder )
The abstract operation SerializeJSONProperty takes arguments state (a
- Let value be ?
Get (holder, key). - If value
is an Object or valueis a BigInt , then- Let toJSON be ?
GetV (value,"toJSON" ). - If
IsCallable (toJSON) istrue , then- Set value to ?
Call (toJSON, value, « key »).
- Set value to ?
- Let toJSON be ?
- If state.[[ReplacerFunction]] is not
undefined , then- Set value to ?
Call (state.[[ReplacerFunction]], holder, « key, value »).
- Set value to ?
- If value
is an Object , then- If value has an [[IsRawJSON]] internal slot, then
- Let rawJSON be !
.Get (value,"rawJSON" ) Assert : rawJSONis a String .- Return rawJSON.
- Let rawJSON be !
- If value has a [[NumberData]] internal slot, then
- Set value to ?
ToNumber (value).
- Set value to ?
- Else if value has a [[StringData]] internal slot, then
- Set value to ?
ToString (value).
- Set value to ?
- Else if value has a [[BooleanData]] internal slot, then
- Set value to value.[[BooleanData]].
- Else if value has a [[BigIntData]] internal slot, then
- Set value to value.[[BigIntData]].
- If value has an [[IsRawJSON]] internal slot, then
- If value is
null , return"null" . - If value is
true , return"true" . - If value is
false , return"false" . - If value
is a String , returnQuoteJSONString (value). - If value
is a Number , then - If value
is a BigInt , throw aTypeError exception. - If value
is an Object andIsCallable (value) isfalse , then- Let isArray be ?
IsArray (value). - If isArray is
true , then- Return ?
SerializeJSONArray (state, value).
- Return ?
- Return ?
SerializeJSONObject (state, value).
- Let isArray be ?
- Return
undefined .
25.5.4.3 QuoteJSONString ( value )
The abstract operation QuoteJSONString takes argument value (a String) and returns a String. It wraps value in 0x0022 (QUOTATION MARK) code units and escapes certain other code units within it. This operation interprets value as a sequence of UTF-16 encoded code points, as described in
- Let product be the String value consisting solely of the code unit 0x0022 (QUOTATION MARK).
- For each code point codePoint of
StringToCodePoints (value), do- If codePoint is listed in the “Code Point” column of
Table 77 , then- Set product to the
string-concatenation of product and the escape sequence for codePoint as specified in the “Escape Sequence” column of the corresponding row.
- Set product to the
- Else if codePoint has a numeric value less than 0x0020 (SPACE) or codePoint has the same numeric value as a
leading surrogate ortrailing surrogate , then- Let unit be the code unit whose numeric value is the numeric value of codePoint.
- Set product to the
string-concatenation of product andUnicodeEscape (unit).
- Else,
- Set product to the
string-concatenation of product andUTF16EncodeCodePoint (codePoint).
- Set product to the
- If codePoint is listed in the “Code Point” column of
- Set product to the
string-concatenation of product and the code unit 0x0022 (QUOTATION MARK). - Return product.
| Code Point | Unicode Character Name | Escape Sequence |
|---|---|---|
| U+0008 | BACKSPACE |
\b
|
| U+0009 | CHARACTER TABULATION |
\t
|
| U+000A | LINE FEED (LF) |
\n
|
| U+000C | FORM FEED (FF) |
\f
|
| U+000D | CARRIAGE RETURN (CR) |
\r
|
| U+0022 | QUOTATION MARK |
\"
|
| U+005C | REVERSE SOLIDUS |
\\
|
25.5.4.4 UnicodeEscape ( codeUnit )
The abstract operation UnicodeEscape takes argument codeUnit (a code unit) and returns a String. It represents codeUnit as a Unicode escape sequence. It performs the following steps when called:
- Let n be the numeric value of codeUnit.
Assert : n ≤ 0xFFFF.- Let hex be the String representation of n, formatted as a lowercase hexadecimal number.
- Return the
string-concatenation of the code unit 0x005C (REVERSE SOLIDUS),"u" , andStringPad (hex, 4,"0" ,start ).
25.5.4.5 SerializeJSONObject ( state, value )
The abstract operation SerializeJSONObject takes arguments state (a
- If state.[[Stack]] contains value, throw a
TypeError exception because the structure is cyclical. - Append value to state.[[Stack]].
- Let stepBack be state.[[Indent]].
- Set state.[[Indent]] to the
string-concatenation of state.[[Indent]] and state.[[Gap]]. - If state.[[PropertyList]] is not
undefined , then- Let keys be state.[[PropertyList]].
- Else,
- Let keys be ?
EnumerableOwnProperties (value,key ).
- Let keys be ?
- Let partial be a new empty
List . - For each element propertyKey of keys, do
- Let stringP be ?
SerializeJSONProperty (state, propertyKey, value). - If stringP is not
undefined , then- Let member be
QuoteJSONString (propertyKey). - Set member to the
string-concatenation of member and":" . - If state.[[Gap]] is not the empty String, then
- Set member to the
string-concatenation of member and the code unit 0x0020 (SPACE).
- Set member to the
- Set member to the
string-concatenation of member and stringP. - Append member to partial.
- Let member be
- Let stringP be ?
- If partial is empty, then
- Let final be
"{}" .
- Let final be
- Else,
- If state.[[Gap]] is the empty String, then
- Let properties be the String value formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with the code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String.
- Let final be the
string-concatenation of"{" , properties, and"}" .
- Else,
- Let separator be the
string-concatenation of the code unit 0x002C (COMMA), the code unit 0x000A (LINE FEED), and state.[[Indent]]. - Let properties be the String value 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.
- Let final be the
string-concatenation of"{" , the code unit 0x000A (LINE FEED), state.[[Indent]], properties, the code unit 0x000A (LINE FEED), stepBack, and"}" .
- Let separator be the
- If state.[[Gap]] is the empty String, then
- Remove the last element of state.[[Stack]].
- Set state.[[Indent]] to stepBack.
- Return final.
25.5.4.6 SerializeJSONArray ( state, value )
The abstract operation SerializeJSONArray takes arguments state (a
- If state.[[Stack]] contains value, throw a
TypeError exception because the structure is cyclical. - Append value to state.[[Stack]].
- Let stepBack be state.[[Indent]].
- Set state.[[Indent]] to the
string-concatenation of state.[[Indent]] and state.[[Gap]]. - Let partial be a new empty
List . - Let length be ?
LengthOfArrayLike (value). - Let index be 0.
- Repeat, while index < length,
- Let stringP be ?
SerializeJSONProperty (state, !ToString (𝔽 (index)), value). - If stringP is
undefined , then- Append
"null" to partial.
- Append
- Else,
- Append stringP to partial.
- Set index to index + 1.
- Let stringP be ?
- If partial is empty, then
- Let final be
"[]" .
- Let final be
- Else,
- If state.[[Gap]] is the empty String, then
- Let properties be the String value formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with the code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String.
- Let final be the
string-concatenation of"[" , properties, and"]" .
- Else,
- Let separator be the
string-concatenation of the code unit 0x002C (COMMA), the code unit 0x000A (LINE FEED), and state.[[Indent]]. - Let properties be the String value 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.
- Let final be the
string-concatenation of"[" , the code unit 0x000A (LINE FEED), state.[[Indent]], properties, the code unit 0x000A (LINE FEED), stepBack, and"]" .
- Let separator be the
- If state.[[Gap]] is the empty String, then
- Remove the last element of state.[[Stack]].
- Set state.[[Indent]] to stepBack.
- Return final.
The representation of arrays includes only the elements in the array.length (exclusive). Properties whose keys are not
25.5.5 JSON [ %Symbol.toStringTag% ]
The initial value of the
This property has the attributes { [[Writable]]: