25 構造化データ

25.1 ArrayBuffer オブジェクト

25.1.1 記法

本節、および 25.429 における以下の記述は、read-modify-write 変更関数 (modification function) の内部データ構造を用いる。

read-modify-write 変更関数 とは、2 つのバイト値 List を引数に取り、バイト値List を返す抽象クロージャとして表現される数学的関数である。これらの抽象クロージャは以下のすべての性質を満たす:

  • アルゴリズムの全ステップをアトミックに実行する。
  • 個々のアルゴリズムステップは観測不可能である。
Note

read-modify-write 変更関数のアルゴリズムステップが純粋な数学的関数を成していることの検証を助けるため、次の編集上の慣例を推奨する:

  • 直接または呼び出される抽象操作・抽象クロージャを経由して、そのパラメータと捕捉した値以外の言語値や仕様上の値へアクセスしない。
  • 直接または遷移的に Completion Record を返す抽象操作や抽象クロージャを呼び出さない。
  • Completion Record を返さない。

25.1.2 固定長およびリサイズ可能 ArrayBuffer オブジェクト

固定長 ArrayBuffer とは、生成後にバイト長が変化しない ArrayBuffer である。

リサイズ可能 ArrayBuffer とは、ArrayBuffer.prototype.resize ( newLength ) の呼び出しによって生成後にバイト長を変更し得る ArrayBuffer である。

生成される ArrayBuffer オブジェクトの種類は、ArrayBuffer ( length [ , options ] ) に渡された引数に依存する。

25.1.3 ArrayBuffer オブジェクトに関する抽象操作

25.1.3.1 AllocateArrayBuffer ( constructor, byteLength [ , maxByteLength ] )

The abstract operation AllocateArrayBuffer takes arguments constructor (a constructor) and byteLength (a non-negative integer) and optional argument maxByteLength (a non-negative integer or empty) and returns either a normal completion containing an ArrayBuffer or a throw completion. ArrayBuffer を生成するために使用される。 It performs the following steps when called:

  1. slots を « [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferDetachKey]] » とする。
  2. maxByteLength が存在し empty でないなら allocatingResizableBuffertrue、そうでなければ false とする。
  3. allocatingResizableBuffertrue なら
    1. byteLength > maxByteLength なら RangeError 例外を投げる。
    2. [[ArrayBufferMaxByteLength]]slots に追加する。
  4. obj を ? OrdinaryCreateFromConstructor(constructor, "%ArrayBuffer.prototype%", slots) とする。
  5. block を ? CreateByteDataBlock(byteLength) とする。
  6. obj.[[ArrayBufferData]]block を設定する。
  7. obj.[[ArrayBufferByteLength]]byteLength を設定する。
  8. allocatingResizableBuffertrue なら
    1. maxByteLength バイトから成る Data Block block を生成できない場合 RangeError 例外を投げる。
    2. 注: リサイズ可能 ArrayBuffer はインプレース成長で実装可能となるよう設計されている。実装は例えば仮想メモリを事前確保できない場合に投げてもよい。
    3. obj.[[ArrayBufferMaxByteLength]]maxByteLength を設定する。
  9. obj を返す。

25.1.3.2 ArrayBufferByteLength ( arrayBuffer, order )

The abstract operation ArrayBufferByteLength takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer) and order (seq-cst or unordered) and returns a non-negative integer. It performs the following steps when called:

  1. IsSharedArrayBuffer(arrayBuffer) が true かつ arrayBuffer[[ArrayBufferByteLengthData]] 内部スロットを持つなら
    1. bufferByteLengthBlockarrayBuffer.[[ArrayBufferByteLengthData]] とする。
    2. rawLengthGetRawBytesFromSharedBlock(bufferByteLengthBlock, 0, biguint64, true, order) とする。
    3. isLittleEndian を周囲のエージェントの Agent Record[[LittleEndian]] フィールドの値とする。
    4. (RawBytesToNumeric(biguint64, rawLength, isLittleEndian)) を返す。
  2. アサート: IsDetachedBuffer(arrayBuffer) は false
  3. arrayBuffer.[[ArrayBufferByteLength]] を返す。

25.1.3.3 ArrayBufferCopyAndDetach ( arrayBuffer, newLength, preserveResizability )

The abstract operation ArrayBufferCopyAndDetach takes arguments arrayBuffer (an ECMAScript language value), newLength (an ECMAScript language value), and preserveResizability (preserve-resizability or fixed-length) and returns either a normal completion containing an ArrayBuffer or a throw completion. It performs the following steps when called:

  1. RequireInternalSlot(arrayBuffer, [[ArrayBufferData]]) を実行。
  2. IsSharedArrayBuffer(arrayBuffer) が true なら TypeError 例外。
  3. newLengthundefined なら
    1. newByteLengtharrayBuffer.[[ArrayBufferByteLength]] とする。
  4. そうでなければ
    1. newByteLength を ? ToIndex(newLength) とする。
  5. IsDetachedBuffer(arrayBuffer) が true なら TypeError 例外。
  6. preserveResizabilitypreserve-resizability かつ IsFixedLengthArrayBuffer(arrayBuffer) が false なら
    1. newMaxByteLengtharrayBuffer.[[ArrayBufferMaxByteLength]] とする。
  7. そうでなければ
    1. newMaxByteLengthempty とする。
  8. arrayBuffer.[[ArrayBufferDetachKey]]undefined でなければ TypeError 例外。
  9. newBuffer を ? AllocateArrayBuffer(%ArrayBuffer%, newByteLength, newMaxByteLength) とする。
  10. copyLengthmin(newByteLength, arrayBuffer.[[ArrayBufferByteLength]]) とする。
  11. fromBlockarrayBuffer.[[ArrayBufferData]] とする。
  12. toBlocknewBuffer.[[ArrayBufferData]] とする。
  13. CopyDataBlockBytes(toBlock, 0, fromBlock, 0, copyLength) を実行。
  14. 注: 新しい Data Block の生成および旧 Data Block からのコピーは観測不可能。実装はゼロコピー移動や realloc として実装してよい。
  15. DetachArrayBuffer(arrayBuffer) を実行。
  16. 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:

  1. arrayBuffer.[[ArrayBufferData]]null なら true を返す。
  2. 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 normal completion containing unused or a throw completion. It performs the following steps when called:

  1. アサート: IsSharedArrayBuffer(arrayBuffer) は false
  2. key が存在しなければ keyundefined に設定。
  3. arrayBuffer.[[ArrayBufferDetachKey]]key でなければ TypeError 例外。
  4. arrayBuffer.[[ArrayBufferData]]null に設定。
  5. arrayBuffer.[[ArrayBufferByteLength]] を 0 に設定。
  6. unused を返す。
Note

ArrayBuffer インスタンスをデタッチすることは、裏付けとして使用される Data Block をそのインスタンスから切り離し、バイト長を 0 に設定する。

25.1.3.6 CloneArrayBuffer ( srcBuffer, srcByteOffset, srcLength )

The abstract operation CloneArrayBuffer takes arguments srcBuffer (an ArrayBuffer or a SharedArrayBuffer), srcByteOffset (a non-negative integer), and srcLength (a non-negative integer) and returns either a normal completion containing an ArrayBuffer or a throw completion. srcByteOffset で開始し srcLength バイト継続する範囲の srcBuffer のデータをコピーした新しい ArrayBuffer を作成する。 It performs the following steps when called:

  1. アサート: IsDetachedBuffer(srcBuffer) は false
  2. targetBuffer を ? AllocateArrayBuffer(%ArrayBuffer%, srcLength) とする。
  3. srcBlocksrcBuffer.[[ArrayBufferData]] とする。
  4. targetBlocktargetBuffer.[[ArrayBufferData]] とする。
  5. CopyDataBlockBytes(targetBlock, 0, srcBlock, srcByteOffset, srcLength) を実行。
  6. targetBuffer を返す。

25.1.3.7 GetArrayBufferMaxByteLengthOption ( options )

The abstract operation GetArrayBufferMaxByteLengthOption takes argument options (an ECMAScript language value) and returns either a normal completion containing either a non-negative integer or empty, or a throw completion. It performs the following steps when called:

  1. options がオブジェクトでなければ empty を返す。
  2. maxByteLength を ? Get(options, "maxByteLength") とする。
  3. maxByteLengthundefined なら empty を返す。
  4. ToIndex(maxByteLength) を返す。

25.1.3.8 HostResizeArrayBuffer ( buffer, newByteLength )

The host-defined abstract operation HostResizeArrayBuffer takes arguments buffer (an ArrayBuffer) and newByteLength (a non-negative integer) and returns either a normal completion containing either handled or unhandled, or a throw completion. ホストbuffer実装定義のリサイズを行う機会を提供する。ホストがリサイズを扱わない場合、既定動作のため unhandled を返してよい。

HostResizeArrayBuffer の実装は以下に従わなければならない:

  • 抽象操作buffer をデタッチしない。
  • 抽象操作handled で正常完了した場合、buffer.[[ArrayBufferByteLength]]newByteLength である。

HostResizeArrayBuffer の既定実装は NormalCompletion(unhandled) を返すことである。

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:

  1. arrayBuffer[[ArrayBufferMaxByteLength]] 内部スロットを持つなら false を返す。
  2. true を返す。

25.1.3.10 IsUnsignedElementType ( type )

The abstract operation IsUnsignedElementType takes argument type (a TypedArray element type) and returns a Boolean. 引数 type が符号なし TypedArray 要素型か検証する。 It performs the following steps when called:

  1. typeuint8, uint8clamped, uint16, uint32, biguint64 のいずれかなら true を返す。
  2. false を返す。

25.1.3.11 IsUnclampedIntegerElementType ( type )

The abstract operation IsUnclampedIntegerElementType takes argument type (a TypedArray element type) and returns a Boolean. 引数 typeuint8clamped を除く整数 TypedArray 要素型か検証する。 It performs the following steps when called:

  1. typeint8, uint8, int16, uint16, int32, uint32 のいずれかなら true
  2. false を返す。

25.1.3.12 IsBigIntElementType ( type )

The abstract operation IsBigIntElementType takes argument type (a TypedArray element type) and returns a Boolean. 引数 type が BigInt TypedArray 要素型か検証する。 It performs the following steps when called:

  1. typebiguint64 または bigint64 のいずれかなら true
  2. false を返す。

25.1.3.13 IsNoTearConfiguration ( type, order )

The abstract operation IsNoTearConfiguration takes arguments type (a TypedArray element type) and order (seq-cst, unordered, or init) and returns a Boolean. It performs the following steps when called:

  1. IsUnclampedIntegerElementType(type) が true なら true を返す。
  2. IsBigIntElementType(type) が true かつ orderinit でも unordered でもないなら true を返す。
  3. false を返す。

25.1.3.14 RawBytesToNumeric ( type, rawBytes, isLittleEndian )

The abstract operation RawBytesToNumeric takes arguments type (a TypedArray element type), rawBytes (a List of byte values), and isLittleEndian (a Boolean) and returns a Number or a BigInt. It performs the following steps when called:

  1. elementSize を要素型 type について Table 73 に指定された要素サイズ値とする。
  2. isLittleEndianfalse なら rawBytes の要素順を反転する。
  3. typefloat16 なら
    1. valuerawBytes のバイト要素を連結し IEEE 754-2019 binary16 値のリトルエンディアンビット列エンコーディングとして解釈したものとする。
    2. value が NaN なら NaN を返す。
    3. value に対応する Number 値を返す。
  4. typefloat32 なら
    1. valuerawBytes のバイト要素を連結し IEEE 754-2019 binary32 値のリトルエンディアンビット列エンコーディングとして解釈したものとする。
    2. value が NaN なら NaN
    3. 対応する Number 値を返す。
  5. typefloat64 なら
    1. valuerawBytes のバイト要素を連結し IEEE 754-2019 binary64 値のリトルエンディアンビット列エンコーディングとして解釈したものとする。
    2. value が NaN なら NaN
    3. 対応する Number 値を返す。
  6. IsUnsignedElementType(type) が true なら
    1. intValuerawBytes のバイト要素を連結し符号なしリトルエンディアン 2 進数のビット列エンコーディングとして解釈したものとする。
  7. そうでなければ
    1. intValuerawBytes のバイト要素を連結しビット長 elementSize × 8 のリトルエンディアン 2 の補数表現として解釈したものとする。
  8. IsBigIntElementType(type) が true なら intValue に対応する BigInt 値を返す。
  9. そうでなければ intValue に対応する Number 値を返す。

25.1.3.15 GetRawBytesFromSharedBlock ( block, byteIndex, type, isTypedArray, order )

The abstract operation GetRawBytesFromSharedBlock takes arguments block (a Shared Data Block), byteIndex (a non-negative integer), type (a TypedArray element type), isTypedArray (a Boolean), and order (seq-cst or unordered) and returns a List of byte values. It performs the following steps when called:

  1. elementSize を要素型 type について Table 73 に指定された要素サイズ値とする。
  2. execution を周囲のエージェントの Agent Record[[CandidateExecution]] フィールドとする。
  3. eventsRecordexecution.[[EventsRecords]] のうち [[AgentSignifier]]AgentSignifier() である Agent Events Record とする。
  4. isTypedArraytrue かつ IsNoTearConfiguration(type, order) が true なら noTear = true、そうでなければ false
  5. rawValue を長さ elementSizeList で、その要素が非決定的に選ばれたバイト値とする。
  6. 注: 実装では rawValue は基盤ハードウェア上の非アトミックまたはアトミック read 命令の結果。非決定性は弱い一貫性ハードウェアの観測可能動作を記述するメモリモデル上の意味的規定。
  7. readEventReadSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize } とする。
  8. readEventeventsRecord.[[EventList]] に追加。
  9. Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: rawValue } を execution.[[ChosenValues]] に追加。
  10. 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 integer), type (a TypedArray element type), isTypedArray (a Boolean), and order (seq-cst or unordered) and optional argument isLittleEndian (a Boolean) and returns a Number or a BigInt. It performs the following steps when called:

  1. アサート: IsDetachedBuffer(arrayBuffer) は false
  2. アサート: arrayBufferbyteIndex から type の値を表現するのに十分なバイトが存在する。
  3. blockarrayBuffer.[[ArrayBufferData]] とする。
  4. elementSize を要素型 type について Table 73 に指定された要素サイズ値とする。
  5. IsSharedArrayBuffer(arrayBuffer) が true なら
    1. アサート: blockShared Data Block
    2. rawValueGetRawBytesFromSharedBlock(block, byteIndex, type, isTypedArray, order) とする。
  6. そうでなければ
    1. rawValue を、byteIndex (含む) から byteIndex + elementSize (含まない) のインデックスにある block のバイトからなる List とする。
  7. アサート: rawValue の要素数は elementSize
  8. isLittleEndian が存在しなければ、周囲のエージェントの Agent Record[[LittleEndian]] フィールドの値を設定。
  9. RawBytesToNumeric(type, rawValue, isLittleEndian) を返す。

25.1.3.17 NumericToRawBytes ( type, value, isLittleEndian )

The abstract operation NumericToRawBytes takes arguments type (a TypedArray element type), value (a Number or a BigInt), and isLittleEndian (a Boolean) and returns a List of byte values. It performs the following steps when called:

  1. typefloat16 なら
    1. rawBytes を、value を roundTiesToEven モードで IEEE 754-2019 binary16 形式に変換した結果の 2 バイトを要素とする List とする。バイトはリトルエンディアン順。valueNaN の場合、rawBytes は実装が選ぶ任意の IEEE 754-2019 binary16 NaN エンコーディングとなり得る。実装は区別可能な各 NaN 値に常に同じエンコーディングを選択しなければならない。
  2. Else if typefloat32 なら
    1. 同様に 4 バイト (binary32)。
  3. Else if typefloat64 なら
    1. 同様に 8 バイト (binary64)。
  4. Else
    1. n を要素型 type について Table 73 に指定された要素サイズ値とする。
    2. conversionOperationTable 73 の変換操作列に type について示された抽象操作とする。
    3. intValue(! conversionOperation(value)) とする。
    4. intValue ≥ 0 なら
      1. rawBytesintValuen バイト 2 進エンコーディング (リトルエンディアン) を要素とする List とする。
    5. そうでなければ
      1. rawBytesintValuen バイト 2 の補数エンコーディング (リトルエンディアン) を要素とする List とする。
  5. isLittleEndianfalse なら rawBytes の順序を反転。
  6. 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 integer), type (a TypedArray element type), value (a Number or a BigInt), isTypedArray (a Boolean), and order (seq-cst, unordered, or init) and optional argument isLittleEndian (a Boolean) and returns unused. It performs the following steps when called:

  1. アサート: IsDetachedBuffer(arrayBuffer) は false
  2. アサート: byteIndex から始まり type の値を表す十分なバイトが存在する。
  3. アサート: IsBigIntElementType(type) が true なら value は BigInt、そうでなければ Number。
  4. blockarrayBuffer.[[ArrayBufferData]] とする。
  5. elementSize を要素型 type について Table 73 に指定された要素サイズ値。
  6. isLittleEndian が存在しなければ周囲のエージェントの Agent Record[[LittleEndian]] フィールド値を設定。
  7. rawBytesNumericToRawBytes(type, value, isLittleEndian) とする。
  8. IsSharedArrayBuffer(arrayBuffer) が true なら
    1. execution を周囲のエージェントの Agent Record[[CandidateExecution]] フィールド。
    2. eventsRecordexecution.[[EventsRecords]] 内で [[AgentSignifier]]AgentSignifier() の Agent Events Record
    3. isTypedArraytrue かつ IsNoTearConfiguration(type, order) が true なら noTear = true、そうでなければ false
    4. WriteSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes } を eventsRecord.[[EventList]] に追加。
  9. そうでなければ
    1. rawBytes の各バイトを block[byteIndex] から順に格納。
  10. 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 integer), type (a TypedArray element type), value (a Number or a BigInt), and op (a read-modify-write modification function) and returns a Number or a BigInt. It performs the following steps when called:

  1. アサート: IsDetachedBuffer(arrayBuffer) は false
  2. アサート: byteIndex から type の値を表す十分なバイトが存在する。
  3. アサート: IsBigIntElementType(type) が true なら value は BigInt、そうでなければ Number。
  4. blockarrayBuffer.[[ArrayBufferData]] とする。
  5. elementSize を要素型 type について Table 73 に指定された要素サイズ値。
  6. isLittleEndian を周囲のエージェントの Agent Record[[LittleEndian]] フィールド値とする。
  7. rawBytesNumericToRawBytes(type, value, isLittleEndian) とする。
  8. IsSharedArrayBuffer(arrayBuffer) が true なら
    1. execution を周囲のエージェントの Agent Record[[CandidateExecution]]
    2. eventsRecordexecution.[[EventsRecords]] 内で [[AgentSignifier]]AgentSignifier() の Agent Events Record
    3. rawBytesRead を長さ elementSizeList(非決定的に選ばれたバイト値)。
    4. 注: rawBytesRead は基盤ハードウェア上の read-modify-write 命令、load-link、load-exclusive などのオペランド結果。非決定性は弱い一貫性ハードウェアの観測可能動作を記述。
    5. rmwEventReadModifyWriteSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes, [[ModifyOp]]: op } とする。
    6. rmwEventeventsRecord.[[EventList]] に追加。
    7. Chosen Value Record { [[Event]]: rmwEvent, [[ChosenValue]]: rawBytesRead } を execution.[[ChosenValues]] に追加。
  9. そうでなければ
    1. rawBytesRead を長さ elementSizeList で、block[byteIndex] からの elementSize バイト列。
    2. rawBytesModifiedop(rawBytesRead, rawBytes) とする。
    3. rawBytesModified の各バイトを block[byteIndex] から格納。
  10. RawBytesToNumeric(type, rawBytesRead, isLittleEndian) を返す。

25.1.4 ArrayBuffer コンストラクター

ArrayBuffer コンストラクター:

  • %ArrayBuffer% である。
  • グローバルオブジェクト"ArrayBuffer" プロパティの初期値である。
  • コンストラクターとして呼び出された際、新しい ArrayBuffer を生成し初期化する。
  • 関数として呼び出すことは意図されておらず、その形で呼び出されると例外を投げる。
  • クラス定義の extends 句の値として使用できる。指定された ArrayBuffer の挙動を継承するサブクラスコンストラクターは、ArrayBuffer.prototype 組込みメソッドをサポートするために必要な内部状態でサブクラスインスタンスを生成・初期化するため、ArrayBuffer コンストラクターへの super 呼び出しを含める必要がある。

25.1.4.1 ArrayBuffer ( length [ , options ] )

この関数は呼び出し時に次を行う:

  1. NewTarget が undefined なら TypeError 例外。
  2. byteLength を ? ToIndex(length) とする。
  3. requestedMaxByteLength を ? GetArrayBufferMaxByteLengthOption(options) とする。
  4. AllocateArrayBuffer(NewTarget, byteLength, requestedMaxByteLength) を返す。

25.1.5 ArrayBuffer コンストラクターのプロパティ

ArrayBuffer コンストラクター:

  • [[Prototype]] 内部スロットの値が %Function.prototype% である。
  • 以下のプロパティを持つ:

25.1.5.1 ArrayBuffer.isView ( arg )

この関数は呼び出し時に次を行う:

  1. arg がオブジェクトでなければ false を返す。
  2. arg[[ViewedArrayBuffer]] 内部スロットを持てば true を返す。
  3. false を返す。

25.1.5.2 ArrayBuffer.prototype

ArrayBuffer.prototype の初期値は ArrayBuffer プロトタイプオブジェクトである。

このプロパティは { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } の属性を持つ。

25.1.5.3 get ArrayBuffer [ %Symbol.species% ]

ArrayBuffer[%Symbol.species%] は set アクセサが undefinedアクセサプロパティであり、その get アクセサは呼び出し時に次を行う:

  1. this 値を返す。

この関数の "name" プロパティ値は "get [Symbol.species]" である。

Note

ArrayBuffer.prototype.slice ( start, end ) は通常、派生オブジェクトを生成するために this 値のコンストラクターを用いる。しかしサブクラスコンストラクターは %Symbol.species% プロパティを再定義することで ArrayBuffer.prototype.slice ( start, end ) メソッドの既定挙動を上書きできる。

25.1.6 ArrayBuffer プロトタイプオブジェクトのプロパティ

ArrayBuffer プロトタイプオブジェクト:

  • %ArrayBuffer.prototype% である。
  • [[Prototype]] 内部スロットの値が %Object.prototype% である。
  • 通常のオブジェクトである。
  • [[ArrayBufferData]] および [[ArrayBufferByteLength]] 内部スロットを持たない。

25.1.6.1 get ArrayBuffer.prototype.byteLength

ArrayBuffer.prototype.byteLength は set アクセサが undefinedアクセサプロパティであり、その get アクセサは呼び出し時に次を行う:

  1. Othis 値とする。
  2. RequireInternalSlot(O, [[ArrayBufferData]]) を実行。
  3. IsSharedArrayBuffer(O) が true なら TypeError 例外。
  4. IsDetachedBuffer(O) が true なら +0𝔽 を返す。
  5. lengthO.[[ArrayBufferByteLength]] とする。
  6. 𝔽(length) を返す。

25.1.6.2 ArrayBuffer.prototype.constructor

ArrayBuffer.prototype.constructor の初期値は %ArrayBuffer% である。

25.1.6.3 get ArrayBuffer.prototype.detached

ArrayBuffer.prototype.detached は set アクセサが undefinedアクセサプロパティであり、その get アクセサは呼び出し時に次を行う:

  1. Othis 値。
  2. RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) が true なら TypeError 例外。
  4. IsDetachedBuffer(O) を返す。

25.1.6.4 get ArrayBuffer.prototype.maxByteLength

ArrayBuffer.prototype.maxByteLength は set アクセサが undefinedアクセサプロパティであり、その get アクセサは呼び出し時に次を行う:

  1. Othis 値。
  2. RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) が true なら TypeError 例外。
  4. IsDetachedBuffer(O) が true なら +0𝔽 を返す。
  5. IsFixedLengthArrayBuffer(O) が true なら
    1. lengthO.[[ArrayBufferByteLength]] とする。
  6. そうでなければ
    1. lengthO.[[ArrayBufferMaxByteLength]] とする。
  7. 𝔽(length) を返す。

25.1.6.5 get ArrayBuffer.prototype.resizable

ArrayBuffer.prototype.resizable は set アクセサが undefinedアクセサプロパティであり、その get アクセサは呼び出し時に次を行う:

  1. Othis 値。
  2. RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) が true なら TypeError 例外。
  4. IsFixedLengthArrayBuffer(O) が false なら true を返し、そうでなければ false を返す。

25.1.6.6 ArrayBuffer.prototype.resize ( newLength )

このメソッドは呼び出し時に次を行う:

  1. Othis 値。
  2. RequireInternalSlot(O, [[ArrayBufferMaxByteLength]])。
  3. IsSharedArrayBuffer(O) が true なら TypeError 例外。
  4. newByteLength を ? ToIndex(newLength) とする。
  5. IsDetachedBuffer(O) が true なら TypeError 例外。
  6. newByteLength > O.[[ArrayBufferMaxByteLength]] なら RangeError 例外。
  7. hostHandled を ? HostResizeArrayBuffer(O, newByteLength) とする。
  8. hostHandledhandled なら undefined を返す。
  9. oldBlockO.[[ArrayBufferData]] とする。
  10. newBlock を ? CreateByteDataBlock(newByteLength) とする。
  11. copyLengthmin(newByteLength, O.[[ArrayBufferByteLength]]) とする。
  12. CopyDataBlockBytes(newBlock, 0, oldBlock, 0, copyLength) を実行。
  13. 注: 新旧 Data Block の生成・コピーは観測不可能。実装はインプレース成長・縮小として実装してもよい。
  14. O.[[ArrayBufferData]]newBlock に設定。
  15. O.[[ArrayBufferByteLength]]newByteLength に設定。
  16. undefined を返す。

25.1.6.7 ArrayBuffer.prototype.slice ( start, end )

このメソッドは呼び出し時に次を行う:

  1. Othis 値。
  2. RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) が true なら TypeError 例外。
  4. IsDetachedBuffer(O) が true なら TypeError 例外。
  5. lenO.[[ArrayBufferByteLength]] とする。
  6. relativeStart を ? ToIntegerOrInfinity(start) とする。
  7. relativeStart = -∞ なら first = 0。
  8. Else if relativeStart < 0 なら first = max(len + relativeStart, 0)。
  9. Else first = min(relativeStart, len)。
  10. endundefined なら relativeEnd = len、そうでなければ ? ToIntegerOrInfinity(end)。
  11. relativeEnd = -∞ なら final = 0。
  12. Else if relativeEnd < 0 なら final = max(len + relativeEnd, 0)。
  13. Else final = min(relativeEnd, len)。
  14. newLenmax(final - first, 0) とする。
  15. ctor を ? SpeciesConstructor(O, %ArrayBuffer%) とする。
  16. new を ? Construct(ctor, « 𝔽(newLen) ») とする。
  17. RequireInternalSlot(new, [[ArrayBufferData]])。
  18. IsSharedArrayBuffer(new) が true なら TypeError
  19. IsDetachedBuffer(new) が true なら TypeError
  20. SameValue(new, O) が true なら TypeError
  21. new.[[ArrayBufferByteLength]] < newLen なら TypeError
  22. 注: 以上の副作用で O がデタッチまたはリサイズされた可能性。
  23. IsDetachedBuffer(O) が true なら TypeError
  24. fromBufO.[[ArrayBufferData]]
  25. toBufnew.[[ArrayBufferData]]
  26. currentLenO.[[ArrayBufferByteLength]]
  27. first < currentLen なら
    1. countmin(newLen, currentLen - first)。
    2. CopyDataBlockBytes(toBuf, 0, fromBuf, first, count) を実行。
  28. new を返す。

25.1.6.8 ArrayBuffer.prototype.transfer ( [ newLength ] )

このメソッドは呼び出し時に次を行う:

  1. Othis 値。
  2. ArrayBufferCopyAndDetach(O, newLength, preserve-resizability) を返す。

25.1.6.9 ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] )

このメソッドは呼び出し時に次を行う:

  1. Othis 値。
  2. ArrayBufferCopyAndDetach(O, newLength, fixed-length) を返す。

25.1.6.10 ArrayBuffer.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティの初期値は文字列 "ArrayBuffer" である。

このプロパティは { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } の属性を持つ。

25.1.7 ArrayBuffer インスタンスのプロパティ

ArrayBuffer インスタンスは ArrayBuffer プロトタイプオブジェクトからプロパティを継承する。各 ArrayBuffer インスタンスは [[ArrayBufferData]] 内部スロット、[[ArrayBufferByteLength]] 内部スロット、[[ArrayBufferDetachKey]] 内部スロットを持つ。リサイズ可能な ArrayBuffer インスタンスはさらに [[ArrayBufferMaxByteLength]] 内部スロットを持つ。

[[ArrayBufferData]]null の ArrayBuffer インスタンスはデタッチされていると見なされ、当該インスタンスに含まれるデータへアクセスまたは変更を試みる演算子はすべて失敗する。

[[ArrayBufferDetachKey]]undefined 以外に設定されている ArrayBuffer インスタンスでは、その同じ「デタッチキー」を引数として渡す DetachArrayBuffer 呼び出しのみが必要であり、そうでなければ TypeError になる。この内部スロットは特定の埋め込み環境によってのみ設定され、本仕様のアルゴリズムでは設定されない。

25.1.8 リサイズ可能 ArrayBuffer ガイドライン

Note 1

以下はリサイズ可能 ArrayBuffer を扱う ECMAScript プログラマー向けガイドラインである。

可能であれば展開環境でプログラムをテストすることを推奨する。利用可能な物理メモリ量はハードウェアデバイス間で大きく異なる。同様に仮想メモリサブシステムもデバイスや OS により大きく異なる。64 ビットデスクトップ Web ブラウザでメモリ不足を起こさないアプリケーションが 32 ビットモバイル Web ブラウザではメモリ不足になる可能性がある。

リサイズ可能 ArrayBuffer"maxByteLength" オプション値を選ぶ際、アプリケーションにとって可能な限り小さいサイズを選ぶことを推奨する。"maxByteLength" は 1,073,741,824 (230 バイト, 1GiB) を超えないことを推奨する。

特定の最大サイズでリサイズ可能 ArrayBuffer を生成できても、将来のリサイズが成功する保証はない点に留意されたい。

Note 2

以下はリサイズ可能 ArrayBuffer を実装する ECMAScript 実装者向けガイドラインである。

リサイズ可能 ArrayBuffer は、リサイズ時コピー、仮想メモリを事前確保したインプレース成長、またはコンストラクターの "maxByteLength" オプション値に応じた両者の組み合わせとして実装できる。

ホストが (多数の ECMAScript アプリケーションを同時に実行する) マルチテナントであり、インプレース成長を仮想メモリ予約で実装する場合、32 ビット/64 ビット実装ともに "maxByteLength" ≥ 1GiB〜1.5GiB の値に対して例外を投げることを推奨する。これは単一アプリケーションによる仮想アドレス空間の枯渇可能性と相互運用性リスクを低減するためである。

ホストに仮想メモリが無い (MMU 無し組込みデバイスなど) 場合、またはコピーによるリサイズのみを実装する場合、"maxByteLength" オプションに任意の Number value for を受け入れてもよい。ただし要求サイズのメモリブロックを決して割り当てられない場合は RangeError を投げることを推奨する。例えば要求サイズがデバイスで利用可能な最大メモリ量を超える場合など。

25.2 SharedArrayBuffer オブジェクト

25.2.1 固定長および成長可能 (growable) SharedArrayBuffer オブジェクト

固定長 SharedArrayBuffer とは、生成後にそのバイト長が変更できない SharedArrayBuffer である。

成長可能 SharedArrayBuffer とは、SharedArrayBuffer.prototype.grow ( newLength ) の呼び出しによって生成後にバイト長を増やすことができる SharedArrayBuffer である。

生成される SharedArrayBuffer オブジェクトの種別は、SharedArrayBuffer ( length [ , options ] ) に渡された引数に依存する。

25.2.2 SharedArrayBuffer オブジェクト用抽象操作

25.2.2.1 AllocateSharedArrayBuffer ( constructor, byteLength [ , maxByteLength ] )

The abstract operation AllocateSharedArrayBuffer takes arguments constructor (a constructor) and byteLength (a non-negative integer) and optional argument maxByteLength (a non-negative integer or empty) and returns either a normal completion containing a SharedArrayBuffer or a throw completion. SharedArrayBuffer を生成するために用いられる。 It performs the following steps when called:

  1. slots を « [[ArrayBufferData]] » とする。
  2. maxByteLength が存在しかつ empty でないなら allocatingGrowableBuffer = true、そうでなければ false とする。
  3. allocatingGrowableBuffertrue なら
    1. byteLength > maxByteLength なら RangeError 例外を投げる。
    2. [[ArrayBufferByteLengthData]][[ArrayBufferMaxByteLength]]slots に追加する。
  4. そうでなければ
    1. [[ArrayBufferByteLength]]slots に追加する。
  5. obj を ? OrdinaryCreateFromConstructor(constructor, "%SharedArrayBuffer.prototype%", slots) とする。
  6. allocatingGrowableBuffertrue なら allocLength = maxByteLength、そうでなければ allocLength = byteLength
  7. block を ? CreateSharedByteDataBlock(allocLength) とする。
  8. obj.[[ArrayBufferData]]block を設定する。
  9. allocatingGrowableBuffertrue なら
    1. アサート: byteLengthmaxByteLength
    2. byteLengthBlock を ? CreateSharedByteDataBlock(8) とする。
    3. SetValueInBuffer(byteLengthBlock, 0, biguint64, (byteLength), true, seq-cst) を実行。
    4. obj.[[ArrayBufferByteLengthData]]byteLengthBlock を設定。
    5. obj.[[ArrayBufferMaxByteLength]]maxByteLength を設定。
  10. そうでなければ
    1. obj.[[ArrayBufferByteLength]]byteLength を設定。
  11. obj を返す。

25.2.2.2 IsSharedArrayBuffer ( obj )

The abstract operation IsSharedArrayBuffer takes argument obj (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. オブジェクトが ArrayBuffer / SharedArrayBuffer あるいはそのサブタイプかどうかを判定する。 It performs the following steps when called:

  1. bufferDataobj.[[ArrayBufferData]] とする。
  2. bufferDatanull なら false を返す。
  3. bufferDataData Block なら false を返す。
  4. アサート: bufferDataShared Data Block である。
  5. true を返す。

25.2.2.3 HostGrowSharedArrayBuffer ( buffer, newByteLength )

The host-defined abstract operation HostGrowSharedArrayBuffer takes arguments buffer (a SharedArrayBuffer) and newByteLength (a non-negative integer) and returns either a normal completion containing either handled or unhandled, or a throw completion. ホストbuffer実装定義の成長処理を行う機会を与える。ホストが処理しない場合は既定動作として unhandled を返してよい。

HostGrowSharedArrayBuffer の実装は以下の要件に従わなければならない:

  • 抽象操作unhandled で正常完了しない(= それ以外で正常完了する)場合で、newByteLengthbuffer の現在のバイト長より小さい、または newByteLength > buffer.[[ArrayBufferMaxByteLength]] のいずれかなら RangeError 例外を投げる。
  • isLittleEndian を周囲のエージェントの Agent Record[[LittleEndian]] フィールド値とする。抽象操作handled で正常完了した場合、[[Order]]seq-cst[[Payload]]NumericToRawBytes(biguint64, newByteLength, isLittleEndian)、[[Block]]buffer.[[ArrayBufferByteLengthData]][[ByteIndex]] が 0、[[ElementSize]] が 8 の WriteSharedMemory または ReadModifyWriteSharedMemory イベントを周囲のエージェントの候補実行 (candidate execution) に追加し、SharedArrayBuffer.prototype.grow への競合する呼び出しが「失われない」(沈黙して何もしないことがない)ようにする。
Note

上記 2 つ目の要件は、buffer の現在バイト長をどのよう/いつ読み取るかについて意図的に曖昧にしている。基盤ハードウェア上でバイト長をアトミック read-modify-write で更新する必要があるため、load-link/store-conditional や load-exclusive/store-exclusive 命令対を用いるアーキテクチャでは命令ペアを命令ストリーム内で近接させたい場合がある。そのため SharedArrayBuffer.prototype.grow 自体は HostGrowSharedArrayBuffer を呼ぶ前に newByteLength の境界チェックを行わず、また現在のバイト長をいつ読むかを規定しない。

これは HostResizeArrayBuffer と対照的であり、後者では newByteLength が 0 以上かつ buffer.[[ArrayBufferMaxByteLength]] 以下であることが保証される。

HostGrowSharedArrayBuffer の既定実装は NormalCompletion(unhandled) を返す。

25.2.3 SharedArrayBuffer コンストラクター

SharedArrayBuffer コンストラクター:

  • %SharedArrayBuffer% である。
  • ホストがそれを提供する場合)グローバルオブジェクト"SharedArrayBuffer" プロパティの初期値である。
  • コンストラクターとして呼ばれたとき新しい SharedArrayBuffer を生成し初期化する。
  • 関数として呼び出すことは意図されておらず、その形で呼び出されると例外を投げる。
  • クラス定義の extends 句の値として使用できる。指定された SharedArrayBuffer の挙動を継承するサブクラスコンストラクターは SharedArrayBuffer.prototype の組込みメソッドを支える内部状態でサブクラスインスタンスを生成・初期化するため super 呼び出しを含めねばならない。

ホストが SharedArrayBuffer への並行アクセスを提供しない場合、グローバルオブジェクト"SharedArrayBuffer" プロパティを省略してよい。

Note

ArrayBuffer と異なり、SharedArrayBuffer はデタッチされず、その内部 [[ArrayBufferData]] スロットが null になることはない。

25.2.3.1 SharedArrayBuffer ( length [ , options ] )

この関数は呼び出し時に次を行う:

  1. NewTarget が undefined なら TypeError 例外。
  2. byteLength を ? ToIndex(length) とする。
  3. requestedMaxByteLength を ? GetArrayBufferMaxByteLengthOption(options) とする。
  4. AllocateSharedArrayBuffer(NewTarget, byteLength, requestedMaxByteLength) を返す。

25.2.4 SharedArrayBuffer コンストラクターのプロパティ

SharedArrayBuffer コンストラクター:

  • [[Prototype]] 内部スロット値が %Function.prototype% である。
  • 以下のプロパティを持つ:

25.2.4.1 SharedArrayBuffer.prototype

SharedArrayBuffer.prototype の初期値は SharedArrayBuffer プロトタイプオブジェクトである。

このプロパティは { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } を持つ。

25.2.4.2 get SharedArrayBuffer [ %Symbol.species% ]

SharedArrayBuffer[%Symbol.species%] は set アクセサが undefinedアクセサプロパティであり、その get アクセサの挙動は次の通り:

  1. this 値を返す。

この関数の "name" プロパティ値は "get [Symbol.species]" である。

25.2.5 SharedArrayBuffer プロトタイプオブジェクトのプロパティ

SharedArrayBuffer プロトタイプオブジェクト:

  • %SharedArrayBuffer.prototype% である。
  • [[Prototype]] 内部スロット値は %Object.prototype% である。
  • 通常のオブジェクトである。
  • [[ArrayBufferData]][[ArrayBufferByteLength]] 内部スロットを持たない。

25.2.5.1 get SharedArrayBuffer.prototype.byteLength

SharedArrayBuffer.prototype.byteLength は set アクセサが undefinedアクセサプロパティであり、その get アクセサは呼び出し時に以下を行う:

  1. Othis 値とする。
  2. RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) が false なら TypeError 例外。
  4. lengthArrayBufferByteLength(O, seq-cst) とする。
  5. 𝔽(length) を返す。

25.2.5.2 SharedArrayBuffer.prototype.constructor

SharedArrayBuffer.prototype.constructor の初期値は %SharedArrayBuffer% である。

25.2.5.3 SharedArrayBuffer.prototype.grow ( newLength )

このメソッドは呼び出し時に以下を行う:

  1. Othis 値とする。
  2. RequireInternalSlot(O, [[ArrayBufferMaxByteLength]])。
  3. IsSharedArrayBuffer(O) が false なら TypeError 例外。
  4. newByteLength を ? ToIndex(newLength) とする。
  5. hostHandled を ? HostGrowSharedArrayBuffer(O, newByteLength) とする。
  6. hostHandledhandled なら undefined を返す。
  7. isLittleEndian を周囲のエージェントの Agent Record[[LittleEndian]] フィールド値とする。
  8. byteLengthBlockO.[[ArrayBufferByteLengthData]] とする。
  9. currentByteLengthRawBytesGetRawBytesFromSharedBlock(byteLengthBlock, 0, biguint64, true, seq-cst) とする。
  10. newByteLengthRawBytesNumericToRawBytes(biguint64, (newByteLength), isLittleEndian) とする。
  11. 繰り返し、
    1. 注: 競合する grow を全順序化し、失われたり沈黙して無視されたりしないようにするための compare-and-exchange ループ。
    2. currentByteLength(RawBytesToNumeric(biguint64, currentByteLengthRawBytes, isLittleEndian)) とする。
    3. newByteLength = currentByteLength なら undefined を返す。
    4. newByteLength < currentByteLength または newByteLength > O.[[ArrayBufferMaxByteLength]] なら RangeError 例外。
    5. byteLengthDeltanewByteLength - currentByteLength とする。
    6. byteLengthDelta バイトから成る新しい Shared Data Block 値を作成できないなら RangeError 例外。
    7. 注: ここで新しい Shared Data Block を作って差し替えるわけではない。最大サイズの Shared Data Block を事前確保する仕様上のモデルであり、メモリ不足なら RangeError を投げることを要求するための手順。
    8. readByteLengthRawBytesAtomicCompareExchangeInSharedBlock(byteLengthBlock, 0, 8, currentByteLengthRawBytes, newByteLengthRawBytes) とする。
    9. ByteListEqual(readByteLengthRawBytes, currentByteLengthRawBytes) が true なら undefined を返す。
    10. currentByteLengthRawBytesreadByteLengthRawBytes に設定。
Note

長さ更新の compare-exchange の擬似的失敗は許されない。新しい長さの境界チェックが通り、実装がメモリ不足でない場合、候補実行には常に ReadModifyWriteSharedMemory イベント(成功した compare-exchange)が追加される。

SharedArrayBuffer.prototype.grow への並列呼び出しは全順序化される。例: sab.grow(10)sab.grow(20) が競合する場合、必ずどちらかが勝つ。sab.grow(10)sab.grow(20) の後でも sab を縮めることはなく、その場合は RangeError を投げる。

25.2.5.4 get SharedArrayBuffer.prototype.growable

SharedArrayBuffer.prototype.growable は set アクセサが undefinedアクセサプロパティであり、get アクセサは次を行う:

  1. Othis 値。
  2. RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) が false なら TypeError 例外。
  4. IsFixedLengthArrayBuffer(O) が false なら true、そうでなければ false を返す。

25.2.5.5 get SharedArrayBuffer.prototype.maxByteLength

SharedArrayBuffer.prototype.maxByteLength は set アクセサが undefinedアクセサプロパティであり、get アクセサは次を行う:

  1. Othis 値。
  2. RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) が false なら TypeError 例外。
  4. IsFixedLengthArrayBuffer(O) が true なら
    1. lengthO.[[ArrayBufferByteLength]] とする。
  5. そうでなければ
    1. lengthO.[[ArrayBufferMaxByteLength]] とする。
  6. 𝔽(length) を返す。

25.2.5.6 SharedArrayBuffer.prototype.slice ( start, end )

このメソッドは呼び出し時に以下を行う:

  1. Othis 値。
  2. RequireInternalSlot(O, [[ArrayBufferData]])。
  3. IsSharedArrayBuffer(O) が false なら TypeError 例外。
  4. lenArrayBufferByteLength(O, seq-cst) とする。
  5. relativeStart を ? ToIntegerOrInfinity(start) とする。
  6. relativeStart = -∞ なら first = 0。
  7. そうでなく relativeStart < 0 なら first = max(len + relativeStart, 0)。
  8. それ以外は first = min(relativeStart, len)。
  9. endundefined なら relativeEnd = len; そうでなければ ? ToIntegerOrInfinity(end)。
  10. relativeEnd = -∞ なら final = 0。
  11. そうでなく relativeEnd < 0 なら final = max(len + relativeEnd, 0)。
  12. それ以外は final = min(relativeEnd, len)。
  13. newLen = max(final - first, 0)。
  14. ctor = ? SpeciesConstructor(O, %SharedArrayBuffer%)。
  15. new = ? Construct(ctor, « 𝔽(newLen) »)。
  16. RequireInternalSlot(new, [[ArrayBufferData]])。
  17. IsSharedArrayBuffer(new) が false なら TypeError
  18. new.[[ArrayBufferData]]O.[[ArrayBufferData]] と同一なら TypeError
  19. ArrayBufferByteLength(new, seq-cst) < newLen なら TypeError
  20. fromBuf = O.[[ArrayBufferData]]
  21. toBuf = new.[[ArrayBufferData]]
  22. CopyDataBlockBytes(toBuf, 0, fromBuf, first, newLen) を実行。
  23. new を返す。

25.2.5.7 SharedArrayBuffer.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティの初期値は文字列 "SharedArrayBuffer" である。

このプロパティは { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } を持つ。

25.2.6 SharedArrayBuffer インスタンスのプロパティ

SharedArrayBuffer インスタンスは SharedArrayBuffer プロトタイプオブジェクトからプロパティを継承する。各インスタンスは [[ArrayBufferData]] 内部スロットを持つ。成長不可のインスタンスは [[ArrayBufferByteLength]] 内部スロットを持つ。成長可能インスタンスは [[ArrayBufferByteLengthData]] および [[ArrayBufferMaxByteLength]] 内部スロットを持つ。

Note

ArrayBuffer と異なり、SharedArrayBuffer インスタンスは決してデタッチされない。

25.2.7 成長可能 SharedArrayBuffer ガイドライン

Note 1

以下は成長可能 SharedArrayBuffer を扱う ECMAScript プログラマー向けガイドラインである。

可能な限り実際のデプロイ環境でテストすることを推奨する。利用可能な物理メモリ量はハードウェア間で大きく異なる。同様に仮想メモリサブシステムもハードウェアや OS により大きく異なる。64 ビットデスクトップブラウザで正常なアプリが 32 ビットモバイルブラウザではメモリ不足になる可能性がある。

成長可能 SharedArrayBuffer"maxByteLength" オプション値はアプリで必要な最小限の値を選ぶことを推奨し、1,073,741,824 (1GiB) を超えないことを推奨する。

特定の最大サイズで成長可能 SharedArrayBuffer を生成できても、将来の grow が成功する保証はない。

成長可能 SharedArrayBuffer の長さ読み出しの全てが同期的 (seq-cst) 読みとは限らない。u8[idx] のような整数インデックス付きプロパティアクセスの境界チェックに用いる長さの読み出しは同期化されない。一般に明示的同期が無い場合、あるアクセスがインバウンドでも同じエージェント内の後続アクセスもインバウンドとは限らない。対照的に SharedArrayBuffer の length / byteLength ゲッター、%TypedArray%.prototype、DataView.prototype を介した明示的読み出しは同期化される。TypedArray が完全に out-of-bounds かを確認するための組込みメソッドによる長さの読み出しも同期化される。

Note 2

以下は成長可能 SharedArrayBuffer を実装する実装者向けガイドラインである。

成長可能 SharedArrayBuffer は仮想メモリ事前予約によるインプレース成長で実装することを推奨する。

grow 操作は基盤メモリアクセスと並行し得るため、メモリモデル上の制約として非順序 (unordered) アクセスでも「ティア」(値の一部が混ざる) を起こしてはならない。実際には基盤データブロックをコピーで拡張する(世界停止を伴う)手法では実装しづらい。世界停止は直列化ポイントを導入し遅いため推奨しない。

追加されたメモリは作成直後(競合アクセスに対しても)ゼロ化されているように見えねばならない。ゼロ初期化オンデマンドの仮想メモリページ、または手動ゼロ化時の慎重な同期で実現できる。

成長可能 SharedArrayBuffer 上の TypedArray ビューの整数インデックス付きプロパティアクセスは、基礎バッファ長へのアクセスが同期化されない(前述)ため、非成長 SharedArrayBuffer 上の場合と同様に最適化可能なことを意図している。例えば境界チェックをループ外へホイストできる。

仮想メモリを持たない(MMU の無い組込み等)ホストでコピー方式による実装は困難である。そうしたホストにおけるメモリ使用は仮想メモリを持つホストと大きく異なる可能性があるため、メモリ使用の期待値を明確に伝えるべきである。

25.3 DataView オブジェクト

25.3.1 DataView オブジェクト用抽象操作

25.3.1.1 DataView With Buffer Witness Record

DataView With Buffer Witness Record は、DataView と、その参照バッファのキャッシュされたバイト長をカプセル化するための Record 値である。これは、参照バッファが成長可能 SharedArrayBuffer である場合にバイト長データブロックに対する単一の共有メモリ読み出しイベントを保証する助けとして用いられる。

DataView With Buffer Witness Record は Table 75 に示すフィールドを持つ。

Table 75: DataView With Buffer Witness Record のフィールド
Field Name Value Meaning
[[Object]] a DataView バッファのバイト長が読み込まれる DataView オブジェクト。
[[CachedBufferByteLength]] a non-negative integer or detached Record 作成時点のオブジェクトの [[ViewedArrayBuffer]] のバイト長。

25.3.1.2 MakeDataViewWithBufferWitnessRecord ( obj, order )

The abstract operation MakeDataViewWithBufferWitnessRecord takes arguments obj (a DataView) and order (seq-cst or unordered) and returns a DataView With Buffer Witness Record. It performs the following steps when called:

  1. bufferobj.[[ViewedArrayBuffer]] とする。
  2. IsDetachedBuffer(buffer) が true なら
    1. byteLength = detached
  3. そうでなければ
    1. byteLength = ArrayBufferByteLength(buffer, order)。
  4. DataView With Buffer Witness Record { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength } を返す。

25.3.1.3 GetViewByteLength ( viewRecord )

The abstract operation GetViewByteLength takes argument viewRecord (a DataView With Buffer Witness Record) and returns a non-negative integer. It performs the following steps when called:

  1. アサート: IsViewOutOfBounds(viewRecord) は false
  2. viewviewRecord.[[Object]] とする。
  3. view.[[ByteLength]]auto でないなら view.[[ByteLength]] を返す。
  4. アサート: IsFixedLengthArrayBuffer(view.[[ViewedArrayBuffer]]) は false
  5. byteOffset = view.[[ByteOffset]]
  6. byteLength = viewRecord.[[CachedBufferByteLength]]
  7. アサート: byteLengthdetached ではない。
  8. byteLength - byteOffset を返す。

25.3.1.4 IsViewOutOfBounds ( viewRecord )

The abstract operation IsViewOutOfBounds takes argument viewRecord (a DataView With Buffer Witness Record) and returns a Boolean. It performs the following steps when called:

  1. viewviewRecord.[[Object]] とする。
  2. bufferByteLengthviewRecord.[[CachedBufferByteLength]] とする。
  3. アサート: IsDetachedBuffer(view.[[ViewedArrayBuffer]]) が true であることと bufferByteLengthdetached であることは同値。
  4. bufferByteLengthdetached なら true を返す。
  5. byteOffsetStart = view.[[ByteOffset]]
  6. view.[[ByteLength]]auto なら
    1. byteOffsetEnd = bufferByteLength
  7. そうでなければ
    1. byteOffsetEnd = byteOffsetStart + view.[[ByteLength]]
  8. byteOffsetStart > bufferByteLength または byteOffsetEnd > bufferByteLength なら true
  9. 注: 長さ 0 の DataView は out-of-bounds とみなさない。
  10. false を返す。

25.3.1.5 GetViewValue ( view, requestIndex, isLittleEndian, type )

The abstract operation GetViewValue takes arguments view (an ECMAScript language value), requestIndex (an ECMAScript language value), isLittleEndian (an ECMAScript language value), and type (a TypedArray element type) and returns either a normal completion containing either a Number or a BigInt, or a throw completion. DataView インスタンス上の関数からビューのバッファから値を取得する際に使用される。 It performs the following steps when called:

  1. RequireInternalSlot(view, [[DataView]])。
  2. アサート: view[[ViewedArrayBuffer]] 内部スロットを持つ。
  3. getIndex = ? ToIndex(requestIndex)。
  4. isLittleEndian = ToBoolean(isLittleEndian)。
  5. viewOffset = view.[[ByteOffset]]
  6. viewRecord = MakeDataViewWithBufferWitnessRecord(view, unordered)。
  7. 注: view のバッファが成長可能 SharedArrayBuffer の場合、境界チェックは同期化されない操作。
  8. IsViewOutOfBounds(viewRecord) が true なら TypeError 例外。
  9. viewSize = GetViewByteLength(viewRecord)。
  10. elementSizeTable 73 における要素型 type の要素サイズ値とする。
  11. getIndex + elementSize > viewSize なら RangeError 例外。
  12. bufferIndex = getIndex + viewOffset
  13. 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 ECMAScript language value), requestIndex (an ECMAScript language value), isLittleEndian (an ECMAScript language value), type (a TypedArray element type), and value (an ECMAScript language value) and returns either a normal completion containing undefined or a throw completion. DataView インスタンス上の関数からビューのバッファへ値を書き込むために使用される。 It performs the following steps when called:

  1. RequireInternalSlot(view, [[DataView]])。
  2. アサート: view[[ViewedArrayBuffer]] 内部スロットを持つ。
  3. getIndex = ? ToIndex(requestIndex)。
  4. IsBigIntElementType(type) が true なら numberValue = ? ToBigInt(value)。
  5. そうでなければ numberValue = ? ToNumber(value)。
  6. isLittleEndian = ToBoolean(isLittleEndian)。
  7. viewOffset = view.[[ByteOffset]]
  8. viewRecord = MakeDataViewWithBufferWitnessRecord(view, unordered)。
  9. 注: view のバッファが成長可能 SharedArrayBuffer の場合、境界チェックは同期化されない。
  10. IsViewOutOfBounds(viewRecord) が true なら TypeError 例外。
  11. viewSize = GetViewByteLength(viewRecord)。
  12. elementSizeTable 73type の要素サイズ値とする。
  13. getIndex + elementSize > viewSize なら RangeError 例外。
  14. bufferIndex = getIndex + viewOffset
  15. SetValueInBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, numberValue, false, unordered, isLittleEndian) を実行。
  16. undefined を返す。

25.3.2 DataView コンストラクター

DataView コンストラクター:

  • %DataView% である。
  • グローバルオブジェクト"DataView" プロパティの初期値である。
  • コンストラクターとして呼ばれた際に新しい DataView を生成し初期化する。
  • 関数として呼び出すことは意図されず、その形で呼ぶと例外を投げる。
  • クラス定義の extends 句の値として使用できる。指定された DataView の挙動を継承するサブクラスコンストラクターは DataView.prototype の組込みメソッドを支える内部状態でインスタンスを初期化するため super 呼び出しを含めねばならない。

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

この関数は呼び出し時に次を行う:

  1. NewTarget が undefined なら TypeError 例外。
  2. RequireInternalSlot(buffer, [[ArrayBufferData]])。
  3. offset = ? ToIndex(byteOffset)。
  4. IsDetachedBuffer(buffer) が true なら TypeError 例外。
  5. bufferByteLength = ArrayBufferByteLength(buffer, seq-cst)。
  6. offset > bufferByteLength なら RangeError 例外。
  7. bufferIsFixedLength = IsFixedLengthArrayBuffer(buffer)。
  8. byteLengthundefined なら
    1. bufferIsFixedLengthtrue なら
      1. viewByteLength = bufferByteLength - offset
    2. そうでなければ
      1. viewByteLength = auto
  9. そうでなければ
    1. viewByteLength = ? ToIndex(byteLength)。
    2. offset + viewByteLength > bufferByteLength なら RangeError 例外。
  10. O = ? OrdinaryCreateFromConstructor(NewTarget, "%DataView.prototype%", « [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] »)。
  11. IsDetachedBuffer(buffer) が true なら TypeError 例外。
  12. bufferByteLength = ArrayBufferByteLength(buffer, seq-cst) に再設定。
  13. offset > bufferByteLength なら RangeError 例外。
  14. byteLengthundefined でないなら
    1. offset + viewByteLength > bufferByteLength なら RangeError 例外。
  15. O.[[ViewedArrayBuffer]] = buffer
  16. O.[[ByteLength]] = viewByteLength
  17. O.[[ByteOffset]] = offset
  18. O を返す。

25.3.3 DataView コンストラクターのプロパティ

DataView コンストラクター:

  • [[Prototype]] 内部スロット値が %Function.prototype% である。
  • 以下のプロパティを持つ:

25.3.3.1 DataView.prototype

DataView.prototype の初期値は DataView プロトタイプオブジェクトである。

このプロパティは { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } を持つ。

25.3.4 DataView プロトタイプオブジェクトのプロパティ

DataView プロトタイプオブジェクト:

  • %DataView.prototype% である。
  • [[Prototype]] 内部スロット値は %Object.prototype% である。
  • 通常のオブジェクトである。
  • [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] 内部スロットを持たない。

25.3.4.1 get DataView.prototype.buffer

DataView.prototype.buffer は set アクセサが undefinedアクセサプロパティであり、その get アクセサは以下を行う:

  1. Othis 値。
  2. RequireInternalSlot(O, [[DataView]])。
  3. アサート: O[[ViewedArrayBuffer]] 内部スロットを持つ。
  4. buffer = O.[[ViewedArrayBuffer]]
  5. buffer を返す。

25.3.4.2 get DataView.prototype.byteLength

DataView.prototype.byteLength は set アクセサが undefinedアクセサプロパティであり、その get アクセサは以下を行う:

  1. Othis 値。
  2. RequireInternalSlot(O, [[DataView]])。
  3. アサート: O[[ViewedArrayBuffer]] 内部スロットを持つ。
  4. viewRecord = MakeDataViewWithBufferWitnessRecord(O, seq-cst)。
  5. IsViewOutOfBounds(viewRecord) が true なら TypeError 例外。
  6. size = GetViewByteLength(viewRecord)。
  7. 𝔽(size) を返す。

25.3.4.3 get DataView.prototype.byteOffset

DataView.prototype.byteOffset は set アクセサが undefinedアクセサプロパティであり、その get アクセサは以下を行う:

  1. Othis 値。
  2. RequireInternalSlot(O, [[DataView]])。
  3. アサート: O[[ViewedArrayBuffer]] 内部スロットを持つ。
  4. viewRecord = MakeDataViewWithBufferWitnessRecord(O, seq-cst)。
  5. IsViewOutOfBounds(viewRecord) が true なら TypeError 例外。
  6. offset = O.[[ByteOffset]]
  7. 𝔽(offset) を返す。

25.3.4.4 DataView.prototype.constructor

DataView.prototype.constructor の初期値は %DataView% である。

25.3.4.5 DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] )

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. GetViewValue(view, byteOffset, littleEndian, bigint64) を返す。

25.3.4.6 DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] )

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. GetViewValue(view, byteOffset, littleEndian, biguint64) を返す。

25.3.4.7 DataView.prototype.getFloat16 ( byteOffset [ , littleEndian ] )

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. GetViewValue(view, byteOffset, littleEndian, float16) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. GetViewValue(view, byteOffset, littleEndian, float32) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. GetViewValue(view, byteOffset, littleEndian, float64) を返す。

25.3.4.10 DataView.prototype.getInt8 ( byteOffset )

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. GetViewValue(view, byteOffset, true, int8) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. GetViewValue(view, byteOffset, littleEndian, int16) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. GetViewValue(view, byteOffset, littleEndian, int32) を返す。

25.3.4.13 DataView.prototype.getUint8 ( byteOffset )

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. GetViewValue(view, byteOffset, true, uint8) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. GetViewValue(view, byteOffset, littleEndian, uint16) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. GetViewValue(view, byteOffset, littleEndian, uint32) を返す。

25.3.4.16 DataView.prototype.setBigInt64 ( byteOffset, value [ , littleEndian ] )

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. SetViewValue(view, byteOffset, littleEndian, bigint64, value) を返す。

25.3.4.17 DataView.prototype.setBigUint64 ( byteOffset, value [ , littleEndian ] )

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. SetViewValue(view, byteOffset, littleEndian, biguint64, value) を返す。

25.3.4.18 DataView.prototype.setFloat16 ( byteOffset, value [ , littleEndian ] )

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. SetViewValue(view, byteOffset, littleEndian, float16, value) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. SetViewValue(view, byteOffset, littleEndian, float32, value) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. SetViewValue(view, byteOffset, littleEndian, float64, value) を返す。

25.3.4.21 DataView.prototype.setInt8 ( byteOffset, value )

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. SetViewValue(view, byteOffset, true, int8, value) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. SetViewValue(view, byteOffset, littleEndian, int16, value) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. SetViewValue(view, byteOffset, littleEndian, int32, value) を返す。

25.3.4.24 DataView.prototype.setUint8 ( byteOffset, value )

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. SetViewValue(view, byteOffset, true, uint8, value) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. SetViewValue(view, byteOffset, littleEndian, uint16, value) を返す。

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

このメソッドは呼び出し時に以下を行う:

  1. viewthis 値。
  2. littleEndian が存在しなければ littleEndian = false
  3. SetViewValue(view, byteOffset, littleEndian, uint32, value) を返す。

25.3.4.27 DataView.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティ初期値は文字列 "DataView" である。

このプロパティは { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } を持つ。

25.3.5 DataView インスタンスのプロパティ

DataView インスタンスは DataView プロトタイプオブジェクトからプロパティを継承する。各インスタンスは [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] 内部スロットを持つ。

Note

[[DataView]] 内部スロットの値自体は仕様内では使用されない。その内部スロットが存在すること自体で DataView コンストラクターにより生成されたオブジェクトであることを識別する。

25.4 Atomics オブジェクト

Atomics オブジェクトは次の通りである:

  • %Atomics% である。
  • グローバルオブジェクト"Atomics" プロパティの初期値である。
  • 通常のオブジェクトである。
  • その [[Prototype]] 内部スロットの値は %Object.prototype% である。
  • [[Construct]] 内部メソッドを持たない;new 演算子でコンストラクタとして使用できない。
  • [[Call]] 内部メソッドを持たない;関数として呼び出せない。

Atomics オブジェクトは共有メモリ配列セルに対して不可分(アトミック)に動作する関数、およびエージェントがプリミティブなイベントを待機・送出するための関数を提供する。規律を守って用いることで、共有メモリを介して通信するマルチエージェントプログラムは、並列 CPU 上であっても理解可能な順序で実行される。共有メモリ通信を支配する規則は後述のメモリモデルで定義される。

Note

ECMAScript での共有メモリのプログラミングおよび実装に関する参考指針については、メモリモデル節末尾の注記を参照のこと。

25.4.1 Waiter Record

Waiter RecordAtomics.wait または Atomics.waitAsync への特定の呼び出しを表すために用いられる Record 値である。

Waiter Record は Table 76 に挙げるフィールドを持つ。

Table 76: Waiter Record のフィールド
フィールド名 意味
[[AgentSignifier]] エージェント識別子 Atomics.wait または Atomics.waitAsync を呼び出したエージェント。
[[PromiseCapability]] PromiseCapability Record または blocking Atomics.waitAsync の呼び出しを表す場合はその結果の Promise、それ以外は blocking
[[TimeoutTime]] 非負の拡張数学的値 タイムアウトが発火し得る最も早い時刻;時間値を用いて計算される。
[[Result]] "ok" または "timed-out" 呼び出しの戻り値。

25.4.2 WaiterList Records

WaiterList RecordAtomics.wait, Atomics.waitAsync, Atomics.notify を通じたエージェントの待機と通知を説明するために用いられる。

WaiterList Record は Table 77 に挙げるフィールドを持つ。

Table 77: WaiterList Record のフィールド
フィールド名 意味
[[Waiters]] Waiter RecordList この WaiterList が関連付けられているロケーションで待機している Atomics.wait または Atomics.waitAsync への呼び出し。
[[MostRecentLeaveEvent]] Synchronize event または empty 直近にそのクリティカルセクションを離れたイベント。未入場なら empty

同一のエージェント識別子を持つ複数の Waiter Record が 1 つの WaiterList に存在し得る。

エージェントクラスタは WaiterList Record の保管領域を持ち、そのインデックスは (block, i) であり、blockShared Data Blocki はそのメモリ内のバイトオフセットである。WaiterList Record はエージェント非依存であり、(block, i) による WaiterList Record の参照はクラスタ内どのエージェントからも同一の WaiterList Record を得る。

各 WaiterList Record はその評価中の排他的アクセスを制御する クリティカルセクション を持つ。同時に入場できるのは 1 つのエージェントのみである。クリティカルセクションへの入退場は抽象操作 EnterCriticalSectionLeaveCriticalSection により制御される。待機エージェントの追加/削除、リスト走査、リスト上のエージェントのサスペンドおよび通知、Synchronize event の設定/取得といった WaiterList Record 上の操作は、クリティカルセクションへ入場したエージェントのみが実行できる。

25.4.3 Atomics のための抽象操作

25.4.3.1 ValidateIntegerTypedArray ( typedArray, waitable )

The abstract operation ValidateIntegerTypedArray takes arguments typedArray (an ECMAScript language value) and waitable (a Boolean) and returns 正常完了で TypedArray With Buffer Witness Record を含むか、または throw completion. It performs the following steps when called:

  1. taRecord を ? ValidateTypedArray(typedArray, unordered) の結果とする。
  2. 注: typedArray の裏付けバッファが拡張可能な SharedArrayBuffer のとき、境界チェックは同期化操作ではない。
  3. もし waitabletrue なら、
    1. もし typedArray.[[TypedArrayName]]"Int32Array" でも "BigInt64Array" でもないなら TypeError 例外を投げる。
  4. それ以外なら、
    1. typeTypedArrayElementType(typedArray) とする。
    2. IsUnclampedIntegerElementType(type) が false かつ IsBigIntElementType(type) が false なら TypeError 例外を投げる。
  5. taRecord を返す。

25.4.3.2 ValidateAtomicAccess ( taRecord, requestIndex )

The abstract operation ValidateAtomicAccess takes arguments taRecord (a TypedArray With Buffer Witness Record) and requestIndex (an ECMAScript language value) and returns 正常完了で整数を含むか、または throw completion. It performs the following steps when called:

  1. lengthTypedArrayLength(taRecord) とする。
  2. accessIndex を ? ToIndex(requestIndex) とする。
  3. 事前条件: accessIndex ≥ 0.
  4. もし accessIndexlength なら RangeError 例外を投げる。
  5. typedArraytaRecord.[[Object]] とする。
  6. elementSizeTypedArrayElementSize(typedArray) とする。
  7. offsettypedArray.[[ByteOffset]] とする。
  8. (accessIndex × elementSize) + offset を返す。

25.4.3.3 ValidateAtomicAccessOnIntegerTypedArray ( typedArray, requestIndex )

The abstract operation ValidateAtomicAccessOnIntegerTypedArray takes arguments typedArray (an ECMAScript language value) and requestIndex (an ECMAScript language value) and returns 正常完了で整数を含むか、または throw completion. It performs the following steps when called:

  1. taRecord を ? ValidateIntegerTypedArray(typedArray, false) とする。
  2. ValidateAtomicAccess(taRecord, requestIndex) を返す。

25.4.3.4 RevalidateAtomicAccess ( typedArray, byteIndexInBuffer )

The abstract operation RevalidateAtomicAccess takes arguments typedArray (a TypedArray) and byteIndexInBuffer (an integer) and returns 正常完了で unused を含むか、または throw completion. この操作は Atomics メソッド内で全ての引数強制が行われた後(それらには任意の副作用があり得て、バッファを out of bounds にし得る)、アトミック操作のための裏付けバッファ内のインデックスを再検証する。typedArray の裏付けバッファが SharedArrayBuffer の場合、この操作は例外を投げない。 It performs the following steps when called:

  1. taRecordMakeTypedArrayWithBufferWitnessRecord(typedArray, unordered) とする。
  2. 注: typedArray の裏付けバッファが拡張可能な SharedArrayBuffer のとき、境界チェックは同期化操作ではない。
  3. もし IsTypedArrayOutOfBounds(taRecord) が true なら TypeError 例外を投げる。
  4. 事前条件: byteIndexInBuffertypedArray.[[ByteOffset]].
  5. もし byteIndexInBuffertaRecord.[[CachedBufferByteLength]] なら RangeError 例外を投げる。
  6. unused を返す。

25.4.3.5 GetWaiterList ( block, i )

The abstract operation GetWaiterList takes arguments block (a Shared Data Block) and i (4 で割り切れる非負整数) and returns WaiterList Record. It performs the following steps when called:

  1. 事前条件: i および i + 3 は block のメモリ内の有効なバイトオフセットである。
  2. 組 (block, i) により参照される WaiterList Record を返す。

25.4.3.6 EnterCriticalSection ( WL )

The abstract operation EnterCriticalSection takes argument WL (a WaiterList Record) and returns unused. It performs the following steps when called:

  1. 事前条件: 周囲のエージェントはいかなる WaiterList Recordクリティカルセクションにも入っていない。
  2. いずれのエージェントも WLクリティカルセクションにいないまで待ち、次に(他のエージェントを入れずに)WLクリティカルセクションへ入る。
  3. もし WL.[[MostRecentLeaveEvent]]empty でないなら、
    1. 注: WLクリティカルセクションが少なくとも一度入場された場合、LeaveCriticalSection により Synchronize event が設定されている。
    2. execution を周囲エージェントの Agent Record[[CandidateExecution]] フィールドとする。
    3. eventsRecordexecution.[[EventsRecords]] のうち [[AgentSignifier]]AgentSignifier() である Agent Events Record とする。
    4. enterEvent を新たな Synchronize event とする。
    5. enterEventeventsRecord.[[EventList]] に追加する。
    6. (WL.[[MostRecentLeaveEvent]], enterEvent) を eventsRecord.[[AgentSynchronizesWith]] に追加する。
  4. unused を返す。

EnterCriticalSection は、クリティカルセクションへ入ろうとするエージェントが他のエージェントの退出を待たねばならないとき 競合 (contention) を持つ。競合がないとき、EnterCriticalSection 呼び出しの FIFO 順序は観測可能である。競合があるとき、実装は任意の順序を選択できるが、エージェントを無期限に待たせてはならない。

25.4.3.7 LeaveCriticalSection ( WL )

The abstract operation LeaveCriticalSection takes argument WL (a WaiterList Record) and returns unused. It performs the following steps when called:

  1. 事前条件: 周囲のエージェントは WLクリティカルセクション内にいる。
  2. execution を周囲エージェントの Agent Record[[CandidateExecution]] フィールドとする。
  3. eventsRecordexecution.[[EventsRecords]] のうち [[AgentSignifier]]AgentSignifier() の Agent Events Record とする。
  4. leaveEvent を新たな Synchronize event とする。
  5. leaveEventeventsRecord.[[EventList]] に追加する。
  6. WL.[[MostRecentLeaveEvent]]leaveEvent に設定する。
  7. WLクリティカルセクションを離れる。
  8. unused を返す。

25.4.3.8 AddWaiter ( WL, waiterRecord )

The abstract operation AddWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. 事前条件: 周囲のエージェントは WLクリティカルセクション内にいる。
  2. 事前条件: WL.[[Waiters]][[PromiseCapability]] フィールドが waiterRecord.[[PromiseCapability]] かつ [[AgentSignifier]] フィールドが waiterRecord.[[AgentSignifier]] である Waiter Record は存在しない。
  3. waiterRecordWL.[[Waiters]] に追加する。
  4. unused を返す。

25.4.3.9 RemoveWaiter ( WL, waiterRecord )

The abstract operation RemoveWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. 事前条件: 周囲のエージェントは WLクリティカルセクション内にいる。
  2. 事前条件: WL.[[Waiters]]waiterRecord を含む。
  3. waiterRecordWL.[[Waiters]] から除去する。
  4. unused を返す。

25.4.3.10 RemoveWaiters ( WL, c )

The abstract operation RemoveWaiters takes arguments WL (a WaiterList Record) and c (非負整数または +∞) and returns Waiter RecordList. It performs the following steps when called:

  1. 事前条件: 周囲のエージェントは WLクリティカルセクション内にいる。
  2. lenWL.[[Waiters]] の要素数とする。
  3. nmin(c, len) とする。
  4. LWL.[[Waiters]] の最初の n 要素からなる List とする。
  5. WL.[[Waiters]] の最初の n 要素を除去する。
  6. L を返す。

25.4.3.11 SuspendThisAgent ( WL, waiterRecord )

The abstract operation SuspendThisAgent takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. 事前条件: 周囲のエージェントは WLクリティカルセクション内にいる。
  2. 事前条件: WL.[[Waiters]]waiterRecord を含む。
  3. thisAgentAgentSignifier() とする。
  4. 事前条件: waiterRecord.[[AgentSignifier]]thisAgent である。
  5. 事前条件: waiterRecord.[[PromiseCapability]]blocking である。
  6. 事前条件: AgentCanSuspend() は true である。
  7. LeaveCriticalSection(WL) を行い、サスペンドが有効になる前に通知が到着しても失われない方法で、周囲のエージェントを waiterRecord.[[TimeoutTime]] の時刻までサスペンドし、その後周囲のエージェントはサスペンド解除される。サスペンド解除はタイムアウト、または他のエージェントが NotifyWaiterWL, thisAgent で呼び出した(つまり Atomics.notify 呼び出し経由)場合のみ起こる。
  8. EnterCriticalSection(WL) を実行する。
  9. unused を返す。

25.4.3.12 NotifyWaiter ( WL, waiterRecord )

The abstract operation NotifyWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. 事前条件: 周囲のエージェントは WLクリティカルセクション内にいる。
  2. もし waiterRecord.[[PromiseCapability]]blocking なら、
    1. 識別子が waiterRecord.[[AgentSignifier]] であるエージェントをサスペンドから起こす。
    2. 注: これによりエージェントは SuspendThisAgent 内の実行を再開する。
  3. そうでなく AgentSignifier() が waiterRecord.[[AgentSignifier]] なら、
    1. promiseCapabilitywaiterRecord.[[PromiseCapability]] とする。
    2. ! Call(promiseCapability.[[Resolve]], undefined, « waiterRecord.[[Result]] ») を実行する。
  4. その他の場合、
    1. EnqueueResolveInAgentJob(waiterRecord.[[AgentSignifier]], waiterRecord.[[PromiseCapability]], waiterRecord.[[Result]]) を実行する。
  5. unused を返す。
Note

エージェントは、ホストへ渡す以外の形で他エージェントの promise capability にアクセスしてはならない。

25.4.3.13 EnqueueResolveInAgentJob ( agentSignifier, promiseCapability, resolution )

The abstract operation EnqueueResolveInAgentJob takes arguments agentSignifier (an agent signifier), promiseCapability (a PromiseCapability Record), and resolution ("ok" or "timed-out") and returns unused. It performs the following steps when called:

  1. resolveJob を、引数なしで agentSignifier, promiseCapability, resolution を捕捉し、呼び出されたとき次を行う新たな Job Abstract Closure とする:
    1. 事前条件: AgentSignifier() は agentSignifier である。
    2. ! Call(promiseCapability.[[Resolve]], undefined, « resolution ») を実行する。
    3. unused を返す。
  2. realmInTargetAgent を ! GetFunctionRealm(promiseCapability.[[Resolve]]) とする。
  3. 事前条件: agentSignifierrealmInTargetAgent.[[AgentSignifier]] である。
  4. HostEnqueueGenericJob(resolveJob, realmInTargetAgent) を実行する。
  5. unused を返す。

25.4.3.14 DoWait ( mode, typedArray, index, value, timeout )

The abstract operation DoWait takes arguments mode (sync or async), typedArray (an ECMAScript language value), index (an ECMAScript language value), value (an ECMAScript language value), and timeout (an ECMAScript language value) and returns 正常完了で Object, "not-equal", "timed-out", "ok" のいずれか、または throw completion. It performs the following steps when called:

  1. taRecord を ? ValidateIntegerTypedArray(typedArray, true) とする。
  2. buffertaRecord.[[Object]].[[ViewedArrayBuffer]] とする。
  3. もし IsSharedArrayBuffer(buffer) が false なら TypeError 例外を投げる。
  4. i を ? ValidateAtomicAccess(taRecord, index) とする。
  5. arrayTypeNametypedArray.[[TypedArrayName]] とする。
  6. もし arrayTypeName"BigInt64Array" なら v を ? ToBigInt64(value) とする。
  7. そうでなければ v を ? ToInt32(value) とする。
  8. q を ? ToNumber(timeout) とする。
  9. もし qNaN 又は +∞𝔽 なら t を +∞ とする;q-∞𝔽 なら t を 0;それ以外は tmax((q), 0) とする。
  10. もし modesync かつ AgentCanSuspend() が false なら TypeError 例外を投げる。
  11. blockbuffer.[[ArrayBufferData]] とする。
  12. offsettypedArray.[[ByteOffset]] とする。
  13. byteIndexInBuffer を (i × 4) + offset とする。
  14. WLGetWaiterList(block, byteIndexInBuffer) とする。
  15. もし modesync なら
    1. promiseCapabilityblocking とする。
    2. resultObjectundefined とする。
  16. それ以外なら
    1. promiseCapability を ! NewPromiseCapability(%Promise%) とする。
    2. resultObjectOrdinaryObjectCreate(%Object.prototype%) とする。
  17. EnterCriticalSection(WL) を実行する。
  18. elementTypeTypedArrayElementType(typedArray) とする。
  19. wGetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst) とする。
  20. もし vw なら
    1. LeaveCriticalSection(WL) を実行する。
    2. もし modesync なら "not-equal" を返す。
    3. CreateDataPropertyOrThrow(resultObject, "async", false) を実行。
    4. CreateDataPropertyOrThrow(resultObject, "value", "not-equal") を実行。
    5. resultObject を返す。
  21. もし t = 0 かつ modeasync なら
    1. 注: 同期即時タイムアウトには特別扱いはない。非同期即時タイムアウトは失敗を速め、不要な Promise ジョブを避ける特別扱いを持つ。
    2. LeaveCriticalSection(WL) を実行する。
    3. CreateDataPropertyOrThrow(resultObject, "async", false) を実行。
    4. CreateDataPropertyOrThrow(resultObject, "value", "timed-out") を実行。
    5. resultObject を返す。
  22. thisAgentAgentSignifier() とする。
  23. now を現在時刻 (UTC) を示す time value とする。
  24. additionalTimeout実装定義の非負数学的値とする。
  25. timeoutTime(now) + t + additionalTimeout とする。
  26. 注: t が +∞ のとき timeoutTime も +∞。
  27. waiterRecord を新たな Waiter Record { [[AgentSignifier]]: thisAgent, [[PromiseCapability]]: promiseCapability, [[TimeoutTime]]: timeoutTime, [[Result]]: "ok" } とする。
  28. AddWaiter(WL, waiterRecord) を実行する。
  29. もし modesync なら
    1. SuspendThisAgent(WL, waiterRecord) を実行する。
  30. それ以外で timeoutTime有限なら
    1. EnqueueAtomicsWaitAsyncTimeoutJob(WL, waiterRecord) を実行する。
  31. LeaveCriticalSection(WL) を実行する。
  32. もし modesync なら waiterRecord.[[Result]] を返す。
  33. CreateDataPropertyOrThrow(resultObject, "async", true) を実行。
  34. CreateDataPropertyOrThrow(resultObject, "value", promiseCapability.[[Promise]]) を実行。
  35. resultObject を返す。
Note

additionalTimeout は、電力消費削減やタイミング攻撃緩和のためのタイマー分解能粗化など、実装が必要に応じてタイムアウトにパディングを追加することを許容する。値は DoWait の呼び出しごとに異なり得る。

25.4.3.15 EnqueueAtomicsWaitAsyncTimeoutJob ( WL, waiterRecord )

The abstract operation EnqueueAtomicsWaitAsyncTimeoutJob takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. timeoutJob を、引数なしで WLwaiterRecord を捕捉し、呼び出されたとき以下を行う新たな Job Abstract Closure とする:
    1. EnterCriticalSection(WL) を実行する。
    2. もし WL.[[Waiters]]waiterRecord を含むなら
      1. timeOfJobExecution を現在時刻 (UTC) を示す time value とする。
      2. 事前条件: (timeOfJobExecution) ≥ waiterRecord.[[TimeoutTime]]時間値の非単調性は無視)。
      3. waiterRecord.[[Result]]"timed-out" に設定する。
      4. RemoveWaiter(WL, waiterRecord) を実行する。
      5. NotifyWaiter(WL, waiterRecord) を実行する。
    3. LeaveCriticalSection(WL) を実行する。
    4. unused を返す。
  2. now を現在時刻 (UTC) を示す time value とする。
  3. currentRealm を現在の Realm Record とする。
  4. HostEnqueueTimeoutJob(timeoutJob, currentRealm, 𝔽(waiterRecord.[[TimeoutTime]]) - now) を実行する。
  5. unused を返す。

25.4.3.16 AtomicCompareExchangeInSharedBlock ( block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes )

The abstract operation AtomicCompareExchangeInSharedBlock takes arguments block (a Shared Data Block), byteIndexInBuffer (an integer), elementSize (a non-negative integer), expectedBytes (a List of byte values), and replacementBytes (a List of byte values) and returns byte 値の List. It performs the following steps when called:

  1. execution を周囲エージェントの Agent Record[[CandidateExecution]] フィールドとする。
  2. eventsRecordexecution.[[EventsRecords]] のうち [[AgentSignifier]]AgentSignifier() の Agent Events Record とする。
  3. rawBytesRead を長さ elementSizeList とし、要素は非決定的に選ばれるバイト値とする。
  4. 注: 実装では rawBytesRead は基盤ハードウェア上のロードリンク、ロード排他、または read-modify-write 命令のオペランドの結果である。この非決定性は弱い一貫性を持つハードウェアの観測可能な振る舞いを記述するための意味的規定。
  5. 注: 期待値と読み取った値の比較は read-modify-write 変更関数の外で行い、期待値不一致の場合に不必要な強い同期化を避ける。
  6. もし ByteListEqual(rawBytesRead, expectedBytes) が true なら
    1. second を (oldBytes, newBytes) を引数に取り何も捕捉せず呼ばれるとアトミックに次を行う新たな read-modify-write 変更関数とし、newBytes を返す。
    2. eventReadModifyWriteSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize, [[Payload]]: replacementBytes, [[ModifyOp]]: second } とする。
  7. それ以外なら
    1. eventReadSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize } とする。
  8. eventeventsRecord.[[EventList]] に追加する。
  9. Chosen Value Record { [[Event]]: event, [[ChosenValue]]: rawBytesRead } を execution.[[ChosenValues]] に追加する。
  10. rawBytesRead を返す。

25.4.3.17 AtomicReadModifyWrite ( typedArray, index, value, op )

The abstract operation AtomicReadModifyWrite takes arguments typedArray (an ECMAScript language value), index (an ECMAScript language value), value (an ECMAScript language value), and op (a read-modify-write modification function) and returns 正常完了で Number または BigInt を含むか、または throw completion. op は2つの byte 値 List を引数に取り、byte 値 List を返す。この操作は値をアトミックに読み込み、別の値と結合し、その結合を格納し、読み込んだ値を返す。 It performs the following steps when called:

  1. byteIndexInBuffer を ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index) とする。
  2. もし typedArray.[[ContentType]]bigint なら v を ? ToBigInt(value) とする。
  3. それ以外は v𝔽(? ToIntegerOrInfinity(value)) とする。
  4. RevalidateAtomicAccess(typedArray, byteIndexInBuffer) を実行する。
  5. buffertypedArray.[[ViewedArrayBuffer]] とする。
  6. elementTypeTypedArrayElementType(typedArray) とする。
  7. GetModifySetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, op) を返す。

25.4.3.18 ByteListBitwiseOp ( op, xBytes, yBytes )

The abstract operation ByteListBitwiseOp takes arguments op (&, ^, または |), xBytes (a List of byte values), and yBytes (a List of byte values) and returns byte 値の List. この操作は引数の全てのバイト値に対してビット単位演算をアトミックに行い、byte 値の List を返す。 It performs the following steps when called:

  1. 事前条件: xBytesyBytes は同じ要素数を持つ。
  2. result を新たな空 List とする。
  3. i を 0 とする。
  4. 各要素 xByte について
    1. yByteyBytes[i] とする。
    2. もし op& なら
      1. resultBytexByteyByte のビット単位 AND の結果とする。
    3. そうでなく op^ なら
      1. resultBytexByteyByte のビット単位 XOR の結果とする。
    4. それ以外
      1. 事前条件: op|
      2. resultBytexByteyByte のビット単位 OR の結果とする。
    5. ii + 1 にする。
    6. resultByteresult に追加する。
  5. result を返す。

25.4.3.19 ByteListEqual ( xBytes, yBytes )

The abstract operation ByteListEqual takes arguments xBytes (a List of byte values) and yBytes (a List of byte values) and returns Boolean. It performs the following steps when called:

  1. もし xBytesyBytes が同じ要素数でなければ false を返す。
  2. i を 0 とする。
  3. 各要素 xByte について
    1. yByteyBytes[i] とする。
    2. もし xByteyByte なら false を返す。
    3. ii + 1 にする。
  4. true を返す。

25.4.4 Atomics.add ( typedArray, index, value )

この関数は呼び出されたとき次を行う:

  1. add を (xBytes, yBytes) を引数に取り typedArray を捕捉し、呼ばれるとアトミックに以下を行う新たな read-modify-write 変更関数とする:
    1. typeTypedArrayElementType(typedArray) とする。
    2. isLittleEndian を周囲エージェントの Agent Record[[LittleEndian]] フィールドの値とする。
    3. xRawBytesToNumeric(type, xBytes, isLittleEndian) とする。
    4. yRawBytesToNumeric(type, yBytes, isLittleEndian) とする。
    5. もし x が Number なら
      1. sumNumber::add(x, y) とする。
    6. それ以外
      1. 事前条件: x は BigInt。
      2. sumBigInt::add(x, y) とする。
    7. sumBytesNumericToRawBytes(type, sum, isLittleEndian) とする。
    8. 事前条件: sumBytes, xBytes, yBytes は同じ要素数。
    9. sumBytes を返す。
  2. AtomicReadModifyWrite(typedArray, index, value, add) を返す。

25.4.5 Atomics.and ( typedArray, index, value )

この関数は呼び出されたとき次を行う:

  1. and を (xBytes, yBytes) を引数に取り何も捕捉せず、呼ばれるとアトミックに次を行う新たな read-modify-write 変更関数とし、ByteListBitwiseOp(&, xBytes, yBytes) を返す。
  2. AtomicReadModifyWrite(typedArray, index, value, and) を返す。

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

この関数は呼び出されたとき次を行う:

  1. byteIndexInBuffer を ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index) とする。
  2. buffertypedArray.[[ViewedArrayBuffer]] とする。
  3. blockbuffer.[[ArrayBufferData]] とする。
  4. もし typedArray.[[ContentType]]bigint なら
    1. expected を ? ToBigInt(expectedValue) とする。
    2. replacement を ? ToBigInt(replacementValue) とする。
  5. それ以外
    1. expected𝔽(? ToIntegerOrInfinity(expectedValue)) とする。
    2. replacement𝔽(? ToIntegerOrInfinity(replacementValue)) とする。
  6. RevalidateAtomicAccess(typedArray, byteIndexInBuffer) を実行する。
  7. elementTypeTypedArrayElementType(typedArray) とする。
  8. elementSizeTypedArrayElementSize(typedArray) とする。
  9. isLittleEndian を周囲エージェントの Agent Record[[LittleEndian]] フィールド値とする。
  10. expectedBytesNumericToRawBytes(elementType, expected, isLittleEndian) とする。
  11. replacementBytesNumericToRawBytes(elementType, replacement, isLittleEndian) とする。
  12. もし IsSharedArrayBuffer(buffer) が true なら
    1. rawBytesReadAtomicCompareExchangeInSharedBlock(block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes) とする。
  13. それ以外
    1. rawBytesRead を長さ elementSizeList とし、block[byteIndexInBuffer] から始まる elementSize バイト列とする。
    2. もし ByteListEqual(rawBytesRead, expectedBytes) が true なら
      1. replacementBytes の各バイトを blockblock[byteIndexInBuffer] から書き込む。
  14. RawBytesToNumeric(elementType, rawBytesRead, isLittleEndian) を返す。

25.4.7 Atomics.exchange ( typedArray, index, value )

この関数は呼び出されたとき次を行う:

  1. second を (oldBytes, newBytes) を引数に取り何も捕捉せず、呼ばれるとアトミックに newBytes を返す read-modify-write 変更関数とする。
  2. AtomicReadModifyWrite(typedArray, index, value, second) を返す。

25.4.8 Atomics.isLockFree ( size )

この関数は呼び出されたとき次を行う:

  1. n を ? ToIntegerOrInfinity(size) とする。
  2. AR を周囲エージェントの Agent Record とする。
  3. もし n = 1 なら AR.[[IsLockFree1]] を返す。
  4. もし n = 2 なら AR.[[IsLockFree2]] を返す。
  5. もし n = 4 なら true を返す。
  6. もし n = 8 なら AR.[[IsLockFree8]] を返す。
  7. false を返す。
Note

この関数は最適化プリミティブである。直感的には、サイズ n バイトのデータに対するアトミックプリミティブ(compareExchange, load, store, add, sub, and, or, xor, exchange)のアトミックステップが、そのデータ n バイト外のロックを取得せずに実行されるなら Atomics.isLockFree(n) は true を返す。高性能アルゴリズムはこの関数を用いてクリティカルセクションでロックを使うかアトミック操作を使うかを決定する。アトミックプリミティブがロックフリーでない場合、アルゴリズムが独自のロックを提供する方がしばしば効率的である。

Atomics.isLockFree(4) は常に true を返し、これは全ての関連ハードウェアでサポート可能である。これを前提できることでプログラムは一般に単純化する。

この関数が返す値に関わらず、全てのアトミック操作はアトミックであることが保証される。例えば、操作の途中で可視な操作が発生(いわゆる「tearing」)することは決してない。

25.4.9 Atomics.load ( typedArray, index )

この関数は呼び出されたとき次を行う:

  1. byteIndexInBuffer を ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index) とする。
  2. RevalidateAtomicAccess(typedArray, byteIndexInBuffer) を実行する。
  3. buffertypedArray.[[ViewedArrayBuffer]] とする。
  4. elementTypeTypedArrayElementType(typedArray) とする。
  5. GetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst) を返す。

25.4.10 Atomics.or ( typedArray, index, value )

この関数は呼び出されたとき次を行う:

  1. or を (xBytes, yBytes) を引数に取り何も捕捉せず、呼ばれるとアトミックに ByteListBitwiseOp(|, xBytes, yBytes) を返す read-modify-write 変更関数とする。
  2. AtomicReadModifyWrite(typedArray, index, value, or) を返す。

25.4.11 Atomics.store ( typedArray, index, value )

この関数は呼び出されたとき次を行う:

  1. byteIndexInBuffer を ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index) とする。
  2. もし typedArray.[[ContentType]]bigint なら v を ? ToBigInt(value) とする。
  3. それ以外は v𝔽(? ToIntegerOrInfinity(value)) とする。
  4. RevalidateAtomicAccess(typedArray, byteIndexInBuffer) を実行する。
  5. buffertypedArray.[[ViewedArrayBuffer]] とする。
  6. elementTypeTypedArrayElementType(typedArray) とする。
  7. SetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, true, seq-cst) を実行する。
  8. v を返す。

25.4.12 Atomics.sub ( typedArray, index, value )

この関数は呼び出されたとき次を行う:

  1. subtract を (xBytes, yBytes) を引数に取り typedArray を捕捉し、呼ばれるとアトミックに以下を行う新たな read-modify-write 変更関数とする:
    1. typeTypedArrayElementType(typedArray) とする。
    2. isLittleEndian を周囲エージェントの Agent Record[[LittleEndian]] フィールド値とする。
    3. xRawBytesToNumeric(type, xBytes, isLittleEndian) とする。
    4. yRawBytesToNumeric(type, yBytes, isLittleEndian) とする。
    5. もし x が Number なら
      1. differenceNumber::subtract(x, y) とする。
    6. それ以外
      1. 事前条件: x は BigInt。
      2. differenceBigInt::subtract(x, y) とする。
    7. differenceBytesNumericToRawBytes(type, difference, isLittleEndian) とする。
    8. 事前条件: differenceBytes, xBytes, yBytes は同じ要素数。
    9. differenceBytes を返す。
  2. AtomicReadModifyWrite(typedArray, index, value, subtract) を返す。

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

この関数は周囲のエージェントを待機キューに入れ、通知またはタイムアウトまでサスペンドし、それらを区別する文字列を返す。

呼び出されたとき次を行う:

  1. DoWait(sync, typedArray, index, value, timeout) を返す。

25.4.14 Atomics.waitAsync ( typedArray, index, value, timeout )

この関数は、呼び出しエージェントが通知されるかタイムアウトに達したとき解決される Promise を返す。

呼び出されたとき次を行う:

  1. DoWait(async, typedArray, index, value, timeout) を返す。

25.4.15 Atomics.notify ( typedArray, index, count )

この関数は待機キューでスリープしている一部のエージェントに通知する。

呼び出されたとき次を行う:

  1. taRecord を ? ValidateIntegerTypedArray(typedArray, true) とする。
  2. byteIndexInBuffer を ? ValidateAtomicAccess(taRecord, index) とする。
  3. もし countundefined なら
    1. c を +∞ とする。
  4. それ以外
    1. intCount を ? ToIntegerOrInfinity(count) とする。
    2. cmax(intCount, 0) とする。
  5. buffertypedArray.[[ViewedArrayBuffer]] とする。
  6. blockbuffer.[[ArrayBufferData]] とする。
  7. もし IsSharedArrayBuffer(buffer) が false なら +0𝔽 を返す。
  8. WLGetWaiterList(block, byteIndexInBuffer) とする。
  9. EnterCriticalSection(WL) を実行する。
  10. SRemoveWaiters(WL, c) とする。
  11. S の要素 W について
    1. NotifyWaiter(WL, W) を実行する。
  12. LeaveCriticalSection(WL) を実行する。
  13. nS の要素数とする。
  14. 𝔽(n) を返す。

25.4.16 Atomics.xor ( typedArray, index, value )

この関数は呼び出されたとき次を行う:

  1. xor を (xBytes, yBytes) を引数に取り何も捕捉せず、呼ばれるとアトミックに ByteListBitwiseOp(^, xBytes, yBytes) を返す read-modify-write 変更関数とする。
  2. AtomicReadModifyWrite(typedArray, index, value, xor) を返す。

25.4.17 Atomics [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティの初期値は文字列値 "Atomics" である。

このプロパティは属性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } を持つ。

25.5 JSON オブジェクト

JSON オブジェクトは次の通りである:

  • %JSON% である。
  • グローバルオブジェクト"JSON" プロパティの初期値である。
  • 通常のオブジェクトである。
  • parsestringify の 2 つの関数を含み、JSON テキストの構文解析と構築に使用される。
  • [[Prototype]] 内部スロットの値は %Object.prototype% である。
  • [[Construct]] 内部メソッドを持たず、new 演算子でコンストラクタとして使用できない。
  • [[Call]] 内部メソッドを持たず、関数として呼び出せない。

JSON データ交換形式は ECMA-404 に定義される。本仕様で使用される JSON 交換形式は ECMA-404 に記述されるものと正確に同一である。JSON.parse および JSON.stringify の適合実装は ECMA-404 仕様に記述された交換形式を、削除や拡張なしにサポートしなければならない。

25.5.1 JSON.parse ( text [ , reviver ] )

この関数は JSON テキスト(JSON 形式の文字列)を構文解析し、ECMAScript 言語値を生成する。JSON 形式はリテラル、配列、オブジェクトを ECMAScript のリテラル、配列初期化子、オブジェクト初期化子に類似した構文で表現する。構文解析後、JSON オブジェクトは ECMAScript オブジェクトとして実体化され、JSON 配列は ECMAScript の Array インスタンスとして実体化される。JSON の文字列、数値、真偽値、および null はそれぞれ ECMAScript の String, Number, Boolean, null として実体化される。

任意の reviver パラメータは 2 つのパラメータ key, value を取る関数であり、結果をフィルタおよび変換できる。構文解析で生成された各 key/value ペアで呼び出され、その戻り値が元の値の代わりに使用される。受け取ったものをそのまま返した場合、構造は変更されない。undefined を返した場合、そのプロパティは結果から削除される。

  1. jsonString を ? ToString(text) とする。
  2. unfiltered を ? ParseJSON(jsonString) とする。
  3. もし IsCallable(reviver) が true なら
    1. rootOrdinaryObjectCreate(%Object.prototype%) とする。
    2. rootName を空文字列とする。
    3. CreateDataPropertyOrThrow(root, rootName, unfiltered) を実行する。
    4. InternalizeJSONProperty(root, rootName, reviver) を返す。
  4. それ以外
    1. unfiltered を返す。

この関数の "length" プロパティは 2𝔽 である。

25.5.1.1 ParseJSON ( text )

The abstract operation ParseJSON takes argument text (a String) and returns 正常完了で ECMAScript 言語値を含むか、または throw completion. It performs the following steps when called:

  1. もし StringToCodePoints(text) が ECMA-404 で規定された有効な JSON テキストでないなら SyntaxError 例外を投げる。
  2. scriptString"(", text, ");"文字列連結とする。
  3. script を ParseText(scriptString, Script) とする。
  4. 注: 13.2.5.1 で定義される早期エラールールは上記 ParseText 呼び出しに特別な扱いを持つ。
  5. 事前条件: script は Parse Node。
  6. result を ! script の評価 とする。
  7. 注: 13.2.5.5 で定義される PropertyDefinitionEvaluation の意味論は ParseJSON 中特別な扱いを持つ。
  8. 事前条件: result は String, Number, Boolean, ArrayLiteralObjectLiteral により定義される Object, または null のいずれかである。
  9. result を返す。

適合実装が JSON.parse の JSON 文法を拡張することは許されない。修正または拡張された JSON 交換形式をサポートしたい実装は別の parse 関数を定義しなければならない。

Note 1

有効な JSON テキストは ECMAScript PrimaryExpression 構文の部分集合である。ステップ 1jsonString がその部分集合に従うことを検証し、ステップ 8 は評価が適切な型の値を返すことを保証する。

しかし、13.2.5.5 が ParseJSON 中で異なる振る舞いをするため、同一のソーステキストを PrimaryExpression として評価した場合と JSON として評価した場合で異なる結果を生むことがある。さらにオブジェクトリテラル内の重複 "__proto__" プロパティの Early Error(ParseJSON 中は適用されない)により、文法に合致していても ParseJSON が受理するすべてのテキストが PrimaryExpression として有効とは限らない。

Note 2

オブジェクト内に重複する name String が存在する場合、字句的に先行する同一キーの値は上書きされる。

25.5.1.2 InternalizeJSONProperty ( holder, name, reviver )

The abstract operation InternalizeJSONProperty takes arguments holder (an Object), name (a String), and reviver (a function object) and returns 正常完了で ECMAScript 言語値を含むか、または throw completion.

Note

このアルゴリズムは [[Delete]] または CreateDataPropertyfalse を返しても例外を投げないことを意図している。

呼び出されたとき次を行う:

  1. val を ? Get(holder, name) とする。
  2. もし val が Object なら
    1. isArray を ? IsArray(val) とする。
    2. もし isArraytrue なら
      1. len を ? LengthOfArrayLike(val) とする。
      2. I を 0 とする。
      3. I < len の間繰り返す:
        1. prop を ! ToString(𝔽(I)) とする。
        2. newElement を ? InternalizeJSONProperty(val, prop, reviver) とする。
        3. もし newElementundefined なら
          1. val.[[Delete]](prop) を実行。
        4. それ以外
          1. CreateDataProperty(val, prop, newElement) を実行。
        5. II + 1 にする。
    3. それ以外
      1. keys を ? EnumerableOwnProperties(val, key) とする。
      2. 各 String P について
        1. newElement を ? InternalizeJSONProperty(val, P, reviver) とする。
        2. もし newElementundefined なら
          1. val.[[Delete]](P) を実行。
        3. それ以外
          1. CreateDataProperty(val, P, newElement) を実行。
  3. ? Call(reviver, holder, « name, val ») を返す。

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

この関数は value を UTF-16 エンコードされた JSON 形式の文字列か undefined で表現して返す。3 つのパラメータを取る。value通常オブジェクトまたは配列であるが、String, Boolean, Number, null も指定可能。任意の replacer はオブジェクトや配列の文字列化方法を変更する関数、または文字列と数値の配列であり、文字列化に含めるプロパティを選択する包含リストとして振る舞う。任意の space は String または Number で、人間可読性向上のため結果に空白を挿入できる。

呼び出されたとき次を行う:

  1. stack を新たな空 List とする。
  2. indent を空文字列とする。
  3. PropertyListundefined とする。
  4. ReplacerFunctionundefined とする。
  5. もし replacer が Object なら
    1. もし IsCallable(replacer) が true なら
      1. ReplacerFunctionreplacer に設定する。
    2. それ以外
      1. isArray を ? IsArray(replacer) とする。
      2. もし isArraytrue なら
        1. PropertyList を新たな空 List とする。
        2. len を ? LengthOfArrayLike(replacer) とする。
        3. k を 0 とする。
        4. k < len の間繰り返す:
          1. prop を ! ToString(𝔽(k)) とする。
          2. v を ? Get(replacer, prop) とする。
          3. itemundefined とする。
          4. もし v が String なら
            1. itemv とする。
          5. それ以外で v が Number なら
            1. item を ! ToString(v) とする。
          6. それ以外で v が Object なら
            1. もし v[[StringData]] または [[NumberData]] 内部スロットを持つなら item を ? ToString(v) とする。
          7. もし itemundefined でなく かつ PropertyList に含まれていなければ itemPropertyList に追加する。
          8. kk + 1 にする。
  6. もし space が Object なら
    1. もし space[[NumberData]] 内部スロットを持つなら
      1. space を ? ToNumber(space) とする。
    2. それ以外で space[[StringData]] 内部スロットを持つなら
      1. space を ? ToString(space) とする。
  7. もし space が Number なら
    1. spaceMV を ! ToIntegerOrInfinity(space) とする。
    2. spaceMVmin(10, spaceMV) に設定する。
    3. もし spaceMV < 1 なら gap を空文字列、それ以外はコード単位 0x0020 (SPACE) の spaceMV 回繰り返しからなる文字列値とする。
  8. それ以外で space が String なら
    1. もし space の長さ ≤ 10 なら gapspace とし、そうでなければ space の 0 から 10 までの部分文字列とする。
  9. それ以外
    1. gap を空文字列とする。
  10. wrapperOrdinaryObjectCreate(%Object.prototype%) とする。
  11. CreateDataPropertyOrThrow(wrapper, 空文字列, value) を実行する。
  12. stateJSON Serialization Record { [[ReplacerFunction]]: ReplacerFunction, [[Stack]]: stack, [[Indent]]: indent, [[Gap]]: gap, [[PropertyList]]: PropertyList } とする。
  13. SerializeJSONProperty(state, 空文字列, wrapper) を返す。

この関数の "length" プロパティは 3𝔽 である。

Note 1

JSON 構造は任意の深さにネスト可能であるが非循環でなければならない。value が循環構造であるか含む場合、この関数は TypeError 例外を投げねばならない。以下は文字列化できない値の例:

a = [];
a[0] = a;
my_text = JSON.stringify(a); // これは TypeError を投げなければならない。
Note 2

シンボリックなプリミティブ値は以下のようにレンダリングされる:

  • null 値は JSON テキストでは文字列値 "null" として表現される。
  • undefined 値はレンダリングされない。
  • true 値は JSON テキストでは文字列値 "true" として表現される。
  • false 値は JSON テキストでは文字列値 "false" として表現される。
Note 3

文字列値は QUOTATION MARK (") コード単位で囲まれる。コード単位 "\\ 接頭辞でエスケープされる。制御文字コード単位は \uHHHH のエスケープシーケンス、または短い形式 \b (BACKSPACE), \f (FORM FEED), \n (LINE FEED), \r (CARRIAGE RETURN), \t (CHARACTER TABULATION) に置換される。

Note 4

有限の数値は ToString(number) 呼び出しと同様に文字列化される。NaN と符号に関わらず Infinity は文字列値 "null" として表現される。

Note 5

JSON 表現を持たない値(undefined や関数など)は文字列を生成しない。代わりに undefined を生成する。配列ではこれらの値は文字列値 "null" として表現され、オブジェクトでは表現不能な値はそのプロパティが文字列化から除外される。

Note 6

オブジェクトは U+007B (LEFT CURLY BRACKET) で開始し、0 個以上のプロパティを U+002C (COMMA) で区切り、U+007D (RIGHT CURLY BRACKET) で閉じる。プロパティはプロパティ名を表す引用符付き String、U+003A (COLON)、およびその文字列化された値で構成される。配列は U+005B (LEFT SQUARE BRACKET) で開始し、0 個以上の値を U+002C (COMMA) で区切り、U+005D (RIGHT SQUARE BRACKET) で閉じる。

25.5.2.1 JSON Serialization Record

JSON Serialization Record は JSON 形式へのシリアライズを可能にするために用いられる Record 値である。

JSON Serialization Record は Table 78 に挙げるフィールドを持つ。

Table 78: JSON Serialization Record のフィールド
フィールド名 意味
[[ReplacerFunction]] 関数オブジェクトまたは undefined オブジェクトプロパティに代替値を提供できる関数(JSON.stringify の replacer パラメータ)。
[[PropertyList]] String の List または undefined 非配列オブジェクトをシリアライズする際に含めるプロパティ名(JSON.stringify の replacer パラメータ)。
[[Gap]] String インデント単位(JSON.stringify の space パラメータ)。
[[Stack]] Object の List シリアライズ処理中の入れ子オブジェクト集合。循環構造検出に使用。
[[Indent]] String 現在のインデント。

25.5.2.2 SerializeJSONProperty ( state, key, holder )

The abstract operation SerializeJSONProperty takes arguments state (a JSON Serialization Record), key (a String), and holder (an Object) and returns 正常完了で String または undefined を含むか、または throw completion. It performs the following steps when called:

  1. value を ? Get(holder, key) とする。
  2. もし value が Object かまたは value が BigInt なら
    1. toJSON を ? GetV(value, "toJSON") とする。
    2. もし IsCallable(toJSON) が true なら
      1. value を ? Call(toJSON, value, « key ») とする。
  3. もし state.[[ReplacerFunction]]undefined でなければ
    1. value を ? Call(state.[[ReplacerFunction]], holder, « key, value ») とする。
  4. もし value が Object なら
    1. もし value[[NumberData]] 内部スロットを持つなら
      1. value を ? ToNumber(value) とする。
    2. それ以外で [[StringData]] 内部スロットを持つなら
      1. value を ? ToString(value) とする。
    3. それ以外で [[BooleanData]] 内部スロットを持つなら
      1. valuevalue.[[BooleanData]] とする。
    4. それ以外で [[BigIntData]] 内部スロットを持つなら
      1. valuevalue.[[BigIntData]] とする。
  5. もし valuenull なら "null" を返す。
  6. もし valuetrue なら "true" を返す。
  7. もし valuefalse なら "false" を返す。
  8. もし value が String なら QuoteJSONString(value) を返す。
  9. もし value が Number なら
    1. もし value有限なら ! ToString(value) を返す。
    2. "null" を返す。
  10. もし value が BigInt なら TypeError 例外を投げる。
  11. もし value が Object かつ IsCallable(value) が false なら
    1. isArray を ? IsArray(value) とする。
    2. もし isArraytrue なら ? SerializeJSONArray(state, value) を返す。
    3. SerializeJSONObject(state, value) を返す。
  12. undefined を返す。

25.5.2.3 QuoteJSONString ( value )

The abstract operation QuoteJSONString takes argument value (a String) and returns String. value を 0x0022 (QUOTATION MARK) コード単位で囲み、その内部の特定コード単位をエスケープする。この操作は 6.1.4 に記述される通り UTF-16 エンコードされたコードポイント列として value を解釈する。 It performs the following steps when called:

  1. product をコード単位 0x0022 (QUOTATION MARK) だけからなる文字列値とする。
  2. StringToCodePoints(value) の各コードポイント C について
    1. もし CTable 79 の “Code Point” 列に記載されているなら
      1. productproduct と対応行の “Escape Sequence” 列のエスケープシーケンスの文字列連結とする。
    2. それ以外で C の数値が 0x0020 (SPACE) 未満か、C が前方サロゲートまたは後方サロゲートと同じ数値なら
      1. unitC の数値と同じ数値を持つコード単位とする。
      2. productproductUnicodeEscape(unit) の文字列連結とする。
    3. それ以外
      1. productproduct と UTF16EncodeCodePoint(C) の文字列連結とする。
  3. productproduct とコード単位 0x0022 (QUOTATION MARK) の文字列連結とする。
  4. product を返す。
Table 79: JSON 単一文字エスケープシーケンス
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.2.4 UnicodeEscape ( C )

The abstract operation UnicodeEscape takes argument C (a code unit) and returns String. C を Unicode エスケープシーケンスとして表現する。 It performs the following steps when called:

  1. nC の数値とする。
  2. 事前条件: n ≤ 0xFFFF.
  3. hexn の小文字 16 進数形式の文字列表現とする。
  4. コード単位 0x005C (REVERSE SOLIDUS), "u", および StringPad(hex, 4, "0", start) の文字列連結を返す。

25.5.2.5 SerializeJSONObject ( state, value )

The abstract operation SerializeJSONObject takes arguments state (a JSON Serialization Record) and value (an Object) and returns 正常完了で String を含むか、または throw completion. オブジェクトをシリアライズする。 It performs the following steps when called:

  1. もし state.[[Stack]]value を含むなら構造が循環しているので TypeError 例外を投げる。
  2. valuestate.[[Stack]] に追加する。
  3. stepBackstate.[[Indent]] とする。
  4. state.[[Indent]]state.[[Indent]]state.[[Gap]]文字列連結とする。
  5. もし state.[[PropertyList]]undefined でなければ
    1. Kstate.[[PropertyList]] とする。
  6. それ以外
    1. K を ? EnumerableOwnProperties(value, key) とする。
  7. partial を新たな空 List とする。
  8. K の要素 P について
    1. strP を ? SerializeJSONProperty(state, P, value) とする。
    2. もし strPundefined でなければ
      1. memberQuoteJSONString(P) とする。
      2. membermember":"文字列連結とする。
      3. もし state.[[Gap]] が空文字列でなければ
        1. membermember とコード単位 0x0020 (SPACE) の文字列連結とする。
      4. membermemberstrP文字列連結とする。
      5. memberpartial に追加する。
  9. もし partial が空なら
    1. final"{}" とする。
  10. それ以外
    1. もし state.[[Gap]] が空文字列なら
      1. propertiespartial の全要素文字列をコード単位 0x002C (COMMA) で区切って連結した String 値とし(先頭や末尾には挿入しない)、final"{", properties, "}"文字列連結とする。
    2. それ以外
      1. separator を コード単位 0x002C (COMMA), 0x000A (LINE FEED), state.[[Indent]]文字列連結とする。
      2. propertiespartial の全要素文字列を separator で区切って連結した String 値とし(先頭/末尾には挿入しない)、final"{", コード単位 0x000A (LINE FEED), state.[[Indent]], properties, コード単位 0x000A (LINE FEED), stepBack, "}"文字列連結とする。
  11. state.[[Stack]] の最後の要素を除去する。
  12. state.[[Indent]]stepBack に設定する。
  13. final を返す。

25.5.2.6 SerializeJSONArray ( state, value )

The abstract operation SerializeJSONArray takes arguments state (a JSON Serialization Record) and value (an ECMAScript language value) and returns 正常完了で String を含むか、または throw completion. 配列をシリアライズする。 It performs the following steps when called:

  1. もし state.[[Stack]]value を含むなら構造が循環しているので TypeError 例外を投げる。
  2. valuestate.[[Stack]] に追加する。
  3. stepBackstate.[[Indent]] とする。
  4. state.[[Indent]]state.[[Indent]]state.[[Gap]]文字列連結とする。
  5. partial を新たな空 List とする。
  6. len を ? LengthOfArrayLike(value) とする。
  7. index を 0 とする。
  8. index < len の間繰り返す:
    1. strP を ? SerializeJSONProperty(state, ! ToString(𝔽(index)), value) とする。
    2. もし strPundefined なら
      1. "null"partial に追加する。
    3. それ以外
      1. strPpartial に追加する。
    4. indexindex + 1 にする。
  9. もし partial が空なら
    1. final"[]" とする。
  10. それ以外
    1. もし state.[[Gap]] が空文字列なら
      1. propertiespartial の全要素文字列をコード単位 0x002C (COMMA) で区切って連結した String 値とする。
      2. final"[", properties, "]"文字列連結とする。
    2. それ以外
      1. separator を コード単位 0x002C (COMMA), コード単位 0x000A (LINE FEED), state.[[Indent]]文字列連結とする。
      2. propertiespartial の全要素文字列を separator で区切って連結した String 値とする。
      3. final"[", コード単位 0x000A (LINE FEED), state.[[Indent]], properties, コード単位 0x000A (LINE FEED), stepBack, "]"文字列連結とする。
  11. state.[[Stack]] の最後の要素を除去する。
  12. state.[[Indent]]stepBack に設定する。
  13. final を返す。
Note

配列の表現には +0𝔽(含む)から array.length(含まない)までの要素のみが含まれる。配列インデックスでないキーのプロパティは文字列化から除外される。配列は左角括弧、要素を COMMA で区切り、右角括弧で表現される。

25.5.3 JSON [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティの初期値は文字列値 "JSON" である。

このプロパティは属性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } を持つ。