ページ表示設定

25 構造化データ

25.1 ArrayBuffer オブジェクト

25.1.1 表記法

この節、25.4、および 29 における以下の説明では、read-modify-write modification function 内部データ構造を使用します。

read-modify-write modification function とは、byte 値の2つの List を引数として受け取り、byte 値の List を返す Abstract Closure として表現される数学関数です。これらの Abstract Closure は次のすべての性質を満たします。

  • すべてのアルゴリズム手順を不可分に実行します。
  • 個々のアルゴリズム手順は観測できません。
注

read-modify-write modification function のアルゴリズム手順が純粋な数学関数を構成することの検証を助けるため、次の編集上の規約が推奨されます。

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

固定長 ArrayBuffer とは、作成後に byte length を変更できない ArrayBuffer です。

サイズ変更可能な ArrayBuffer とは、ArrayBuffer.prototype.resize ( newLength ) の呼出しによって作成後に byte length を変更できる ArrayBuffer です。

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

25.1.3 ArrayBuffer オブジェクトのための抽象操作

25.1.3.1 AllocateArrayBuffer ( ctor, byteLength [ , maxByteLength ] )

抽象操作 AllocateArrayBuffer。引数 ctor (コンストラクター) および byteLength (非負整数)および省略可能な引数 maxByteLength ((非負整数 または empty))。戻り値:(正常完了 (値:ArrayBuffer) または throw 完了)。 ArrayBuffer を作成するために使用されます。 呼び出されると、次の手順を実行する。

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

25.1.3.2 ArrayBufferByteLength ( arrayBuffer, order )

抽象操作 ArrayBufferByteLength。引数 arrayBuffer ((ArrayBuffer または SharedArrayBuffer)) および order ((seq-cst または unordered))。戻り値:非負整数。 呼び出されると、次の手順を実行する。

  1. IsGrowableSharedArrayBuffer(arrayBuffer) が true である場合、
    1. bufferByteLengthBlock を arrayBuffer.[[ArrayBufferByteLengthData]] とする。
    2. rawLength を GetRawBytesFromSharedBlock(bufferByteLengthBlock, 0, biguint64, true, order) とする。
    3. agentRecord を周囲の agent の Agent Record とする。
    4. isLittleEndian を agentRecord.[[LittleEndian]] とする。
    5. ℝ(RawBytesToNumeric(biguint64, rawLength, isLittleEndian)) を返す。
  2. 表明: IsDetachedBuffer(arrayBuffer) は false である。
  3. arrayBuffer.[[ArrayBufferByteLength]] を返す。

25.1.3.3 ArrayBufferCopyAndDetach ( arrayBuffer, newLength, preserveResizability )

抽象操作 ArrayBufferCopyAndDetach。引数 arrayBuffer (ECMAScript 言語値)、newLength (ECMAScript 言語値) および preserveResizability ((preserve-resizability または fixed-length))。戻り値:(正常完了 (値:ArrayBuffer) または throw 完了)。 呼び出されると、次の手順を実行する。

  1. ? RequireInternalSlot(arrayBuffer, [[ArrayBufferData]]) を実行する。
  2. IsSharedArrayBuffer(arrayBuffer) が true である場合、TypeError 例外をスローする。
  3. newLength が undefined である場合、
    1. newByteLength を arrayBuffer.[[ArrayBufferByteLength]] とする。
  4. そうでない場合、
    1. newByteLength を ? ToIndex(newLength) とする。
  5. IsDetachedBuffer(arrayBuffer) が true である場合、TypeError 例外をスローする。
  6. preserveResizability が preserve-resizability であり、IsFixedLengthArrayBuffer(arrayBuffer) が false である場合、
    1. newMaxByteLength を arrayBuffer.[[ArrayBufferMaxByteLength]] とする。
  7. そうでない場合、
    1. newMaxByteLength を empty とする。
  8. arrayBuffer.[[ArrayBufferDetachKey]] が undefined でない場合、TypeError 例外をスローする。
  9. newBuffer を ? AllocateArrayBuffer(%ArrayBuffer%, newByteLength, newMaxByteLength) とする。
  10. copyLength を min(newByteLength, arrayBuffer.[[ArrayBufferByteLength]]) とする。
  11. fromBlock を arrayBuffer.[[ArrayBufferData]] とする。
  12. toBlock を newBuffer.[[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 )

抽象操作 IsDetachedBuffer。引数 arrayBuffer ((ArrayBuffer または SharedArrayBuffer))。戻り値:Boolean。 呼び出されると、次の手順を実行する。

  1. arrayBuffer.[[ArrayBufferData]] が null である場合、true を返す。
  2. false を返す。

25.1.3.5 DetachArrayBuffer ( arrayBuffer [ , key ] )

抽象操作 DetachArrayBuffer。引数 arrayBuffer (ArrayBuffer)および省略可能な引数 key (任意の値)。戻り値:(正常完了 (値:unused) または throw 完了)。 呼び出されると、次の手順を実行する。

  1. 表明: IsSharedArrayBuffer(arrayBuffer) は false である。
  2. key が存在しない場合、key を undefined に設定する。
  3. arrayBuffer.[[ArrayBufferDetachKey]] が key でない場合、TypeError 例外をスローする。
  4. arrayBuffer.[[ArrayBufferData]] を null に設定する。
  5. arrayBuffer.[[ArrayBufferByteLength]] を 0 に設定する。
  6. unused を返す。
注

ArrayBuffer インスタンスを detach すると、その backing store として使用される Data Block がインスタンスから切り離され、バッファの byte length が 0 に設定されます。

25.1.3.6 CloneArrayBuffer ( sourceBuffer, sourceByteOffset, sourceLength )

抽象操作 CloneArrayBuffer。引数 sourceBuffer ((ArrayBuffer または SharedArrayBuffer))、sourceByteOffset (非負整数) および sourceLength (非負整数)。戻り値:(正常完了 (値:ArrayBuffer) または throw 完了)。 sourceByteOffset から始まり sourceLength byte 続く範囲の sourceBuffer のデータのコピーをデータとして持つ新しい ArrayBuffer を作成します。 呼び出されると、次の手順を実行する。

  1. 表明: IsDetachedBuffer(sourceBuffer) は false である。
  2. targetBuffer を ? AllocateArrayBuffer(%ArrayBuffer%, sourceLength) とする。
  3. sourceBlock を sourceBuffer.[[ArrayBufferData]] とする。
  4. targetBlock を targetBuffer.[[ArrayBufferData]] とする。
  5. CopyDataBlockBytes(targetBlock, 0, sourceBlock, sourceByteOffset, sourceLength) を実行する。
  6. targetBuffer を返す。

25.1.3.7 GetArrayBufferMaxByteLengthOption ( options )

抽象操作 GetArrayBufferMaxByteLengthOption。引数 options (ECMAScript 言語値)。戻り値:(正常完了 (値:(非負整数 または empty)) または throw 完了)。 呼び出されると、次の手順を実行する。

  1. options が Object でない場合、empty を返す。
  2. maxByteLength を ? Get(options, "maxByteLength") とする。
  3. maxByteLength が undefined である場合、empty を返す。
  4. ? ToIndex(maxByteLength) を返す。

25.1.3.8 HostResizeArrayBuffer ( buffer, newByteLength )

ホスト定義の抽象操作 HostResizeArrayBuffer。引数 buffer (ArrayBuffer) および newByteLength (非負整数)。戻り値:(正常完了 (値:(handled または unhandled)) または throw 完了)。 ホストに buffer の実装定義のサイズ変更を実行する機会を与えます。ホストが buffer のサイズ変更を処理しないことを選択した場合、既定の動作を使用するため unhandled を返してもかまいません。

HostResizeArrayBuffer の実装は次の要件に適合しなければなりません。

  • この抽象操作は buffer を detach しません。
  • この抽象操作が handled で正常に完了した場合、buffer.[[ArrayBufferByteLength]] は newByteLength です。

HostResizeArrayBuffer の既定の実装は NormalCompletion(unhandled) を返します。

25.1.3.9 IsFixedLengthArrayBuffer ( arrayBuffer )

抽象操作 IsFixedLengthArrayBuffer。引数 arrayBuffer ((ArrayBuffer または SharedArrayBuffer))。戻り値:Boolean。 呼び出されると、次の手順を実行する。

  1. arrayBuffer が [[ArrayBufferMaxByteLength]] 内部スロットを持つ場合、false を返す。
  2. true を返す。

25.1.3.10 IsUnsignedElementType ( type )

抽象操作 IsUnsignedElementType。引数 type (TypedArray 要素型)。戻り値:Boolean。 引数 type が符号なし TypedArray 要素型であるかどうかを検証します。 呼び出されると、次の手順を実行する。

  1. type が uint8、uint8clamped、uint16、uint32、または biguint64 のいずれかである場合、true を返す。
  2. false を返す。

25.1.3.11 IsUnclampedIntegerElementType ( type )

抽象操作 IsUnclampedIntegerElementType。引数 type (TypedArray 要素型)。戻り値:Boolean。 引数 type が uint8clamped を除く Integer TypedArray 要素型であるかどうかを検証します。 呼び出されると、次の手順を実行する。

  1. type が int8、uint8、int16、uint16、int32、または uint32 のいずれかである場合、true を返す。
  2. false を返す。

25.1.3.12 IsBigIntElementType ( type )

抽象操作 IsBigIntElementType。引数 type (TypedArray 要素型)。戻り値:Boolean。 引数 type が BigInt TypedArray 要素型であるかどうかを検証します。 呼び出されると、次の手順を実行する。

  1. type が biguint64 または bigint64 のいずれかである場合、true を返す。
  2. false を返す。

25.1.3.13 IsNoTearConfiguration ( type, order )

抽象操作 IsNoTearConfiguration。引数 type (TypedArray 要素型) および order ((seq-cst、unordered または init))。戻り値:Boolean。 呼び出されると、次の手順を実行する。

  1. IsUnclampedIntegerElementType(type) が true である場合、true を返す。
  2. IsBigIntElementType(type) が true かつ order が seq-cst である場合、true を返す。
  3. false を返す。

25.1.3.14 RawBytesToNumeric ( type, rawBytes, isLittleEndian )

抽象操作 RawBytesToNumeric。引数 type (TypedArray 要素型)、rawBytes (リスト (要素:バイト値)) および isLittleEndian (Boolean)。戻り値:(Number または BigInt)。 呼び出されると、次の手順を実行する。

  1. elementSize を Element Type type について 表 71 で規定される Element Size 値とする。
  2. isLittleEndian が false である場合、rawBytes の要素の順序を反転する。
  3. type が float16 である場合、
    1. value を、rawBytes の byte 要素を連結し、IEEE 754-2019 binary16 値の little-endian ビット文字列エンコーディングとして解釈したものとする。
    2. value が NaN である場合、NaN を返す。
    3. value に対応する Number 値を返す。
  4. type が float32 である場合、
    1. value を、rawBytes の byte 要素を連結し、IEEE 754-2019 binary32 値の little-endian ビット文字列エンコーディングとして解釈したものとする。
    2. value が NaN である場合、NaN を返す。
    3. value に対応する Number 値を返す。
  5. type が float64 である場合、
    1. value を、rawBytes の byte 要素を連結し、IEEE 754-2019 binary64 値の little-endian ビット文字列エンコーディングとして解釈したものとする。
    2. value が NaN である場合、NaN を返す。
    3. value に対応する Number 値を返す。
  6. IsUnsignedElementType(type) が true である場合、
    1. intValue を、rawBytes の byte 要素を連結し、符号なし little-endian 2進数のビット文字列エンコーディングとして解釈したものとする。
  7. そうでない場合、
    1. intValue を、rawBytes の byte 要素を連結し、ビット長 elementSize × 8 の little-endian 2の補数2進数のビット文字列エンコーディングとして解釈したものとする。
  8. IsBigIntElementType(type) が true である場合、intValue に対応する BigInt 値を返す。
  9. intValue に対応する Number 値を返す。

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

抽象操作 GetRawBytesFromSharedBlock。引数 block (共有データブロック)、byteIndex (非負整数)、type (TypedArray 要素型)、isTypedArray (Boolean) および order ((seq-cst または unordered))。戻り値:リスト (要素:バイト値)。 呼び出されると、次の手順を実行する。

  1. elementSize を Element Type type について 表 71 で規定される Element Size 値とする。
  2. agentRecord を周囲の agent の Agent Record とする。
  3. execution を agentRecord.[[CandidateExecution]] とする。
  4. eventsRecord を、[[AgentSignifier]] が AgentSignifier() である execution.[[EventsRecords]] の Agent Events Record とする。
  5. isTypedArray が true かつ IsNoTearConfiguration(type, order) が true である場合、noTear を true とする。そうでない場合、noTear を false とする。
  6. rawValue を、要素が非決定的に選択された byte 値である長さ elementSize の List とする。
  7. 注記: 実装では、rawValue は基礎となるハードウェア上の非 atomic または atomic read 命令の結果である。この非決定性は、弱い一貫性を持つハードウェアの観測可能な動作を記述するためのメモリモデルの意味論的規定である。
  8. readEvent を ReadSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize } とする。
  9. readEvent を eventsRecord.[[EventList]] に追加する。
  10. Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: rawValue } を execution.[[ChosenValues]] に追加する。
  11. rawValue を返す。

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

抽象操作 GetValueFromBuffer。引数 arrayBuffer ((ArrayBuffer または SharedArrayBuffer))、byteIndex (非負整数)、type (TypedArray 要素型)、isTypedArray (Boolean) および order ((seq-cst または unordered))および省略可能な引数 isLittleEndian (Boolean)。戻り値:(Number または BigInt)。 呼び出されると、次の手順を実行する。

  1. 表明: IsDetachedBuffer(arrayBuffer) は false である。
  2. 表明: arrayBuffer には byteIndex から始まり type の値を表現するのに十分な byte が存在する。
  3. block を arrayBuffer.[[ArrayBufferData]] とする。
  4. elementSize を Element Type type について 表 71 で規定される Element Size 値とする。
  5. IsSharedArrayBuffer(arrayBuffer) が true である場合、
    1. 表明: block は Shared Data Block である。
    2. rawValue を GetRawBytesFromSharedBlock(block, byteIndex, type, isTypedArray, order) とする。
  6. そうでない場合、
    1. rawValue を、byteIndex(含む)から byteIndex + elementSize(含まない)までの区間のインデックスにある block の byte を要素とする List とする。
  7. 表明: rawValue の要素数は elementSize である。
  8. isLittleEndian が存在しない場合、
    1. agentRecord を周囲の agent の Agent Record とする。
    2. isLittleEndian を agentRecord.[[LittleEndian]] に設定する。
  9. RawBytesToNumeric(type, rawValue, isLittleEndian) を返す。

25.1.3.17 NumericToRawBytes ( type, value, isLittleEndian )

抽象操作 NumericToRawBytes。引数 type (TypedArray 要素型)、value ((Number または BigInt)) および isLittleEndian (Boolean)。戻り値:リスト (要素:バイト値)。 呼び出されると、次の手順を実行する。

  1. type が float16 である場合、
    1. rawBytes を、roundTiesToEven モードを使用して value を IEEE 754-2019 binary16 形式へ変換した結果である2 byte を要素とする List とする。byte は little endian 順に並べる。value が NaN である場合、rawBytes は実装が選択した任意の IEEE 754-2019 binary16 形式 NaN エンコーディングに設定してもよい。実装は、実装上区別可能な各 NaN 値について常に同じエンコーディングを選択しなければならない。
  2. そうでなく、type が float32 である場合、
    1. rawBytes を、roundTiesToEven モードを使用して value を IEEE 754-2019 binary32 形式へ変換した結果である4 byte を要素とする List とする。byte は little endian 順に並べる。value が NaN である場合、rawBytes は実装が選択した任意の IEEE 754-2019 binary32 形式 NaN エンコーディングに設定してもよい。実装は、実装上区別可能な各 NaN 値について常に同じエンコーディングを選択しなければならない。
  3. そうでなく、type が float64 である場合、
    1. rawBytes を、value の IEEE 754-2019 binary64 形式エンコーディングである8 byte を要素とする List とする。byte は little endian 順に並べる。value が NaN である場合、rawBytes は実装が選択した任意の IEEE 754-2019 binary64 形式 NaN エンコーディングに設定してもよい。実装は、実装上区別可能な各 NaN 値について常に同じエンコーディングを選択しなければならない。
  4. そうでない場合、
    1. n を Element Type type について 表 71 で規定される Element Size 値とする。
    2. conversionOperation を Element Type type について 表 71 の「Conversion Operation」列で名前が示される抽象操作とする。
    3. intValue を ℝ(! conversionOperation(value)) とする。
    4. intValue ≥ 0 である場合、
      1. rawBytes を intValue の n-byte 2進エンコーディングを要素とする List とする。byte は little endian 順に並べる。
    5. そうでない場合、
      1. rawBytes を intValue の n-byte 2進2の補数エンコーディングを要素とする List とする。byte は little endian 順に並べる。
  5. isLittleEndian が false である場合、rawBytes の要素の順序を反転する。
  6. rawBytes を返す。

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

抽象操作 SetValueInBuffer。引数 arrayBuffer ((ArrayBuffer または SharedArrayBuffer))、byteIndex (非負整数)、type (TypedArray 要素型)、value ((Number または BigInt))、isTypedArray (Boolean) および order ((seq-cst、unordered または init))および省略可能な引数 isLittleEndian (Boolean)。戻り値:unused。 呼び出されると、次の手順を実行する。

  1. 表明: IsDetachedBuffer(arrayBuffer) は false である。
  2. 表明: arrayBuffer には byteIndex から始まり type の値を表現するのに十分な byte が存在する。
  3. 表明: IsBigIntElementType(type) が true である場合、value は BigInt である。そうでない場合、value は Number である。
  4. block を arrayBuffer.[[ArrayBufferData]] とする。
  5. elementSize を Element Type type について 表 71 で規定される Element Size 値とする。
  6. agentRecord を周囲の agent の Agent Record とする。
  7. isLittleEndian が存在しない場合、
    1. isLittleEndian を agentRecord.[[LittleEndian]] に設定する。
  8. rawBytes を NumericToRawBytes(type, value, isLittleEndian) とする。
  9. IsSharedArrayBuffer(arrayBuffer) が true である場合、
    1. execution を agentRecord.[[CandidateExecution]] とする。
    2. eventsRecord を、[[AgentSignifier]] が AgentSignifier() である execution.[[EventsRecords]] の Agent Events Record とする。
    3. isTypedArray が true かつ IsNoTearConfiguration(type, order) が true である場合、noTear を true とする。そうでない場合、noTear を false とする。
    4. WriteSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes } を eventsRecord.[[EventList]] に追加する。
  10. そうでない場合、
    1. rawBytes の個々の byte を block[byteIndex] から開始して block に保存する。
  11. unused を返す。

25.1.3.19 GetModifySetValueInBuffer ( arrayBuffer, byteIndex, type, value, op )

抽象操作 GetModifySetValueInBuffer。引数 arrayBuffer ((ArrayBuffer または SharedArrayBuffer))、byteIndex (非負整数)、type (TypedArray 要素型)、value ((Number または BigInt)) および op (a read-modify-write modification function)。戻り値:(Number または BigInt)。 呼び出されると、次の手順を実行する。

  1. 表明: IsDetachedBuffer(arrayBuffer) は false である。
  2. 表明: arrayBuffer には byteIndex から始まり type の値を表現するのに十分な byte が存在する。
  3. 表明: IsBigIntElementType(type) が true である場合、value は BigInt である。そうでない場合、value は Number である。
  4. block を arrayBuffer.[[ArrayBufferData]] とする。
  5. elementSize を Element Type type について 表 71 で規定される Element Size 値とする。
  6. agentRecord を周囲の agent の Agent Record とする。
  7. isLittleEndian を agentRecord.[[LittleEndian]] とする。
  8. rawBytes を NumericToRawBytes(type, value, isLittleEndian) とする。
  9. IsSharedArrayBuffer(arrayBuffer) が true である場合、
    1. execution を agentRecord.[[CandidateExecution]] とする。
    2. eventsRecord を、[[AgentSignifier]] が AgentSignifier() である execution.[[EventsRecords]] の Agent Events Record とする。
    3. rawBytesRead を、要素が非決定的に選択された byte 値である長さ elementSize の List とする。
    4. 注記: 実装では、rawBytesRead は基礎となるハードウェア上の load-link、load-exclusive、または read-modify-write 命令のオペランドの結果である。この非決定性は、弱い一貫性を持つハードウェアの観測可能な動作を記述するためのメモリモデルの意味論的規定である。
    5. rmwEvent を ReadModifyWriteSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes, [[ModifyOp]]: op } とする。
    6. rmwEvent を eventsRecord.[[EventList]] に追加する。
    7. Chosen Value Record { [[Event]]: rmwEvent, [[ChosenValue]]: rawBytesRead } を execution.[[ChosenValues]] に追加する。
  10. そうでない場合、
    1. rawBytesRead を、block[byteIndex] から始まる elementSize byte の列を要素とする長さ elementSize の List とする。
    2. rawBytesModified を op(rawBytesRead, rawBytes) とする。
    3. rawBytesModified の個々の byte を block[byteIndex] から開始して block に保存する。
  11. 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 コンストラクターは:

  • 値が %Function.prototype% である [[Prototype]] 内部スロットを持ちます。
  • 次のプロパティを持ちます。

25.1.5.1 ArrayBuffer.isView ( arg )

この関数は呼び出されたとき、次の手順を実行します。

  1. arg が Object でない場合、false を返す。
  2. arg が [[ViewedArrayBuffer]] 内部スロットを持つ場合、true を返す。
  3. false を返す。

25.1.5.2 ArrayBuffer.prototype

ArrayBuffer.prototype の初期値は ArrayBuffer prototype オブジェクトです。

このプロパティは属性 { [[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]" です。

注

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

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

ArrayBuffer prototype オブジェクトは:

  • %ArrayBuffer.prototype% です。
  • 値が %Object.prototype% である [[Prototype]] 内部スロットを持ちます。
  • 通常オブジェクトです。
  • [[ArrayBufferData]] または [[ArrayBufferByteLength]] 内部スロットを持ちません。

25.1.6.1 get ArrayBuffer.prototype.byteLength

ArrayBuffer.prototype.byteLength は、set アクセサー関数が undefined であるアクセサープロパティです。その get アクセサー関数は、呼び出されたときに次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[ArrayBufferData]]) を実行する。
  3. IsSharedArrayBuffer(obj) が true である場合、TypeError 例外をスローする。
  4. IsDetachedBuffer(obj) が true である場合、+0𝔽 を返す。
  5. length を obj.[[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. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[ArrayBufferData]]) を実行する。
  3. IsSharedArrayBuffer(obj) が true である場合、TypeError 例外をスローする。
  4. IsDetachedBuffer(obj) を返す。

25.1.6.4 get ArrayBuffer.prototype.maxByteLength

ArrayBuffer.prototype.maxByteLength は、set アクセサー関数が undefined であるアクセサープロパティです。その get アクセサー関数は、呼び出されたときに次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[ArrayBufferData]]) を実行する。
  3. IsSharedArrayBuffer(obj) が true である場合、TypeError 例外をスローする。
  4. IsDetachedBuffer(obj) が true である場合、+0𝔽 を返す。
  5. IsFixedLengthArrayBuffer(obj) が true である場合、
    1. length を obj.[[ArrayBufferByteLength]] とする。
  6. そうでない場合、
    1. length を obj.[[ArrayBufferMaxByteLength]] とする。
  7. 𝔽(length) を返す。

25.1.6.5 get ArrayBuffer.prototype.resizable

ArrayBuffer.prototype.resizable は、set アクセサー関数が undefined であるアクセサープロパティです。その get アクセサー関数は、呼び出されたときに次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[ArrayBufferData]]) を実行する。
  3. IsSharedArrayBuffer(obj) が true である場合、TypeError 例外をスローする。
  4. IsFixedLengthArrayBuffer(obj) が false である場合、true を返す。
  5. false を返す。

25.1.6.6 ArrayBuffer.prototype.resize ( newLength )

このメソッドは呼び出されたとき、次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[ArrayBufferMaxByteLength]]) を実行する。
  3. IsSharedArrayBuffer(obj) が true である場合、TypeError 例外をスローする。
  4. newByteLength を ? ToIndex(newLength) とする。
  5. IsDetachedBuffer(obj) が true である場合、TypeError 例外をスローする。
  6. newByteLength > obj.[[ArrayBufferMaxByteLength]] である場合、RangeError 例外をスローする。
  7. hostHandled を ? HostResizeArrayBuffer(obj, newByteLength) とする。
  8. hostHandled が handled である場合、undefined を返す。
  9. oldBlock を obj.[[ArrayBufferData]] とする。
  10. newBlock を ? CreateByteDataBlock(newByteLength) とする。
  11. copyLength を min(newByteLength, obj.[[ArrayBufferByteLength]]) とする。
  12. CopyDataBlockBytes(newBlock, 0, oldBlock, 0, copyLength) を実行する。
  13. 注記: 新しい Data Block の作成も、古い Data Block からのコピーも観測できない。実装はこのメソッドをインプレースの拡張または縮小として実装してもよい。
  14. obj.[[ArrayBufferData]] を newBlock に設定する。
  15. obj.[[ArrayBufferByteLength]] を newByteLength に設定する。
  16. undefined を返す。

25.1.6.7 ArrayBuffer.prototype.slice ( start, end )

このメソッドは呼び出されたとき、次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[ArrayBufferData]]) を実行する。
  3. IsSharedArrayBuffer(obj) が true である場合、TypeError 例外をスローする。
  4. IsDetachedBuffer(obj) が true である場合、TypeError 例外をスローする。
  5. length を obj.[[ArrayBufferByteLength]] とする。
  6. first を ? ToClampedIndex(start, length) とする。
  7. end が undefined である場合、final を length とする。そうでない場合、final を ? ToClampedIndex(end, length) とする。
  8. newLength を max(final - first, 0) とする。
  9. ctor を ? SpeciesConstructor(obj, %ArrayBuffer%) とする。
  10. new を ? Construct(ctor, « 𝔽(newLength) ») とする。
  11. ? RequireInternalSlot(new, [[ArrayBufferData]]) を実行する。
  12. IsSharedArrayBuffer(new) が true である場合、TypeError 例外をスローする。
  13. IsDetachedBuffer(new) が true である場合、TypeError 例外をスローする。
  14. SameValue(new, obj) が true である場合、TypeError 例外をスローする。
  15. new.[[ArrayBufferByteLength]] < newLength である場合、TypeError 例外をスローする。
  16. 注記: 上記手順の副作用によって obj が detach またはサイズ変更されている可能性がある。
  17. IsDetachedBuffer(obj) が true である場合、TypeError 例外をスローする。
  18. fromBlock を obj.[[ArrayBufferData]] とする。
  19. toBlock を new.[[ArrayBufferData]] とする。
  20. currentLength を obj.[[ArrayBufferByteLength]] とする。
  21. maxCount を currentLength - first とする。
  22. maxCount > 0 である場合、
    1. count を min(newLength, maxCount) とする。
    2. CopyDataBlockBytes(toBlock, 0, fromBlock, first, count) を実行する。
  23. new を返す。

25.1.6.8 ArrayBuffer.prototype.transfer ( [ newLength ] )

このメソッドは呼び出されたとき、次の手順を実行します。

  1. obj を this 値とする。
  2. ? ArrayBufferCopyAndDetach(obj, newLength, preserve-resizability) を返す。

25.1.6.9 ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] )

このメソッドは呼び出されたとき、次の手順を実行します。

  1. obj を this 値とする。
  2. ? ArrayBufferCopyAndDetach(obj, newLength, fixed-length) を返す。

25.1.6.10 ArrayBuffer.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティの初期値は String 値 "ArrayBuffer" です。

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

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

ArrayBuffer インスタンスは ArrayBuffer prototype オブジェクトからプロパティを継承します。各 ArrayBuffer インスタンスは [[ArrayBufferData]] 内部スロット、[[ArrayBufferByteLength]] 内部スロット、および [[ArrayBufferDetachKey]] 内部スロットを持ちます。サイズ変更可能な ArrayBuffer インスタンスはそれぞれ [[ArrayBufferMaxByteLength]] 内部スロットを持ちます。

[[ArrayBufferData]] が null である ArrayBuffer インスタンスは detached であるとみなされ、ArrayBuffer インスタンスに含まれるデータへアクセスまたは変更するすべての演算子は失敗します。

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

25.1.8 サイズ変更可能な ArrayBuffer のガイドライン

注 1

以下は、サイズ変更可能な ArrayBuffer を扱う ECMAScript プログラマー向けのガイドラインです。

可能な場合、プログラムは配備環境でテストすることを推奨します。利用可能な物理メモリ量はハードウェアデバイス間で大きく異なります。同様に、仮想メモリサブシステムもハードウェアデバイス間およびオペレーティングシステム間で大きく異なります。64ビットのデスクトップ Web ブラウザーで out-of-memory エラーなしに実行できるアプリケーションでも、32ビットのモバイル Web ブラウザーではメモリ不足になる可能性があります。

サイズ変更可能な ArrayBuffer の "maxByteLength" オプションの値を選択する場合、アプリケーションに必要な最小のサイズを選択することを推奨します。"maxByteLength" は 1,073,741,824(230 byte、すなわち 1GiB)を超えないことを推奨します。

特定の最大サイズでサイズ変更可能な ArrayBuffer を正常に構築できたとしても、将来のサイズ変更が成功することを保証するものではないことに注意してください。

注 2

以下は、サイズ変更可能な ArrayBuffer を実装する ECMAScript 実装者向けのガイドラインです。

サイズ変更可能な ArrayBuffer は、サイズ変更時にコピーする方法、仮想メモリを事前に予約することによるインプレース拡張、またはコンストラクターの "maxByteLength" オプションの値に応じて両方を組み合わせる方法で実装できます。

Web ブラウザーのようにホストがマルチテナントである(すなわち、多数の ECMAScript アプリケーションを同時に実行する)場合で、その実装が仮想メモリを予約してインプレース拡張を実装することを選択する場合、32ビット実装と64ビット実装の両方で "maxByteLength" ≥ 1GiB から 1.5GiB の値に対してスローすることを推奨します。これは、単一のアプリケーションが仮想メモリアドレス空間を使い果たす可能性を低減し、相互運用性のリスクを低減するためです。

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

25.2 SharedArrayBuffer オブジェクト

25.2.1 固定長および拡張可能な SharedArrayBuffer オブジェクト

固定長 SharedArrayBuffer とは、作成後に byte length を変更できない SharedArrayBuffer です。

拡張可能な SharedArrayBuffer とは、SharedArrayBuffer.prototype.grow ( newLength ) の呼出しによって作成後に byte length を増加できる SharedArrayBuffer です。

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

25.2.2 SharedArrayBuffer オブジェクトのための抽象操作

25.2.2.1 AllocateSharedArrayBuffer ( ctor, byteLength [ , maxByteLength ] )

抽象操作 AllocateSharedArrayBuffer。引数 ctor (コンストラクター) および byteLength (非負整数)および省略可能な引数 maxByteLength ((非負整数 または empty))。戻り値:(正常完了 (値:SharedArrayBuffer) または throw 完了)。 SharedArrayBuffer を作成するために使用されます。 呼び出されると、次の手順を実行する。

  1. slots を « [[ArrayBufferData]] » とする。
  2. maxByteLength が存在し、かつ maxByteLength が empty でない場合、allocatingGrowableBuffer を true とする。そうでない場合、allocatingGrowableBuffer を false とする。
  3. allocatingGrowableBuffer が true である場合、
    1. byteLength > maxByteLength である場合、RangeError 例外をスローする。
    2. slots に [[ArrayBufferByteLengthData]] および [[ArrayBufferMaxByteLength]] を追加する。
  4. そうでない場合、
    1. slots に [[ArrayBufferByteLength]] を追加する。
  5. obj を ? OrdinaryCreateFromConstructor(ctor, "%SharedArrayBuffer.prototype%", slots) とする。
  6. allocatingGrowableBuffer が true である場合、allocationLength を maxByteLength とする。そうでない場合、allocationLength を byteLength とする。
  7. block を ? CreateSharedByteDataBlock(allocationLength) とする。
  8. obj.[[ArrayBufferData]] を block に設定する。
  9. allocatingGrowableBuffer が true である場合、
    1. 表明: byteLength ≤ maxByteLength。
    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 )

抽象操作 IsSharedArrayBuffer。引数 obj ((ArrayBuffer または SharedArrayBuffer))。戻り値:Boolean。 オブジェクトが SharedArrayBuffer であるかどうかを判定します。 呼び出されると、次の手順を実行する。

  1. obj.[[ArrayBufferData]] が Shared Data Block である場合、true を返す。
  2. false を返す。

25.2.2.3 IsGrowableSharedArrayBuffer ( obj )

抽象操作 IsGrowableSharedArrayBuffer。引数 obj ((ArrayBuffer または SharedArrayBuffer))。戻り値:Boolean。 オブジェクトが拡張可能な SharedArrayBuffer であるかどうかを判定します。 呼び出されると、次の手順を実行する。

  1. IsSharedArrayBuffer(obj) が true であり、obj が [[ArrayBufferByteLengthData]] 内部スロットを持つ場合、true を返す。
  2. false を返す。

25.2.2.4 HostGrowSharedArrayBuffer ( buffer, newByteLength )

ホスト定義の抽象操作 HostGrowSharedArrayBuffer。引数 buffer (SharedArrayBuffer) および newByteLength (非負整数)。戻り値:(正常完了 (値:(handled または unhandled)) または throw 完了)。 ホストに buffer の実装定義の拡張を実行する機会を与えます。ホストが buffer の拡張を処理しないことを選択した場合、既定の動作を使用するため unhandled を返してもかまいません。

HostGrowSharedArrayBuffer の実装は次の要件に適合しなければなりません。

  • この抽象操作が unhandled で正常に完了しない場合で、newByteLength < buffer の現在の byte length または newByteLength > buffer.[[ArrayBufferMaxByteLength]] である場合、RangeError 例外をスローします。
  • agentRecord を周囲の agent の Agent Record とする。isLittleEndian を agentRecord.[[LittleEndian]] とする。この抽象操作が handled で正常に完了した場合、[[Order]] が seq-cst、[[Payload]] が NumericToRawBytes(biguint64, newByteLength, isLittleEndian)、[[Block]] が buffer.[[ArrayBufferByteLengthData]]、[[ByteIndex]] が 0、[[ElementSize]] が 8 である WriteSharedMemory または ReadModifyWriteSharedMemory イベントが周囲の agent の candidate execution に追加され、SharedArrayBuffer.prototype.grow ( newLength ) の競合する呼出しが「失われる」、すなわち黙って何もしないことがないようにします。
注

上記の第2要件は、buffer の現在の byte length をどのように、またいつ読み取るかについて意図的に曖昧にしています。byte length は基礎となるハードウェア上の atomic read-modify-write 操作を介して更新されなければならないため、load-link/store-conditional または load-exclusive/store-exclusive 命令ペアを使用するアーキテクチャでは、対となる命令を命令ストリーム内で近接させたい場合があります。そのため、SharedArrayBuffer.prototype.grow ( newLength ) 自体は HostGrowSharedArrayBuffer を呼び出す前に newByteLength の境界検査を行わず、現在の byte length をいつ読み取るかについての要件もありません。

これは、0 ≤ newByteLength ≤ buffer.[[ArrayBufferMaxByteLength]] が保証される HostResizeArrayBuffer とは対照的です。

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

25.2.3 SharedArrayBuffer コンストラクター

SharedArrayBuffer コンストラクターは:

  • %SharedArrayBuffer% です。
  • そのプロパティが存在する場合(以下を参照)、グローバルオブジェクトの "SharedArrayBuffer" プロパティの初期値です。
  • コンストラクターとして呼び出されたとき、新しい SharedArrayBuffer を作成して初期化します。
  • 関数として呼び出されることを意図しておらず、そのように呼び出されると例外をスローします。
  • クラス定義の extends 節の値として使用できます。規定された SharedArrayBuffer の動作を継承しようとするサブクラスコンストラクターは、SharedArrayBuffer.prototype の組込みメソッドをサポートするために必要な内部状態を持つサブクラスインスタンスを作成して初期化するため、SharedArrayBuffer コンストラクターへの super 呼出しを含まなければなりません。

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

注

ArrayBuffer とは異なり、SharedArrayBuffer は detached になることがなく、その内部 [[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 コンストラクターは:

  • 値が %Function.prototype% である [[Prototype]] 内部スロットを持ちます。
  • 次のプロパティを持ちます。

25.2.4.1 SharedArrayBuffer.prototype

SharedArrayBuffer.prototype の初期値は SharedArrayBuffer prototype オブジェクトです。

このプロパティは属性 { [[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 Prototype オブジェクトのプロパティ

SharedArrayBuffer prototype オブジェクトは:

  • %SharedArrayBuffer.prototype% です。
  • 値が %Object.prototype% である [[Prototype]] 内部スロットを持ちます。
  • 通常オブジェクトです。
  • [[ArrayBufferData]] または [[ArrayBufferByteLength]] 内部スロットを持ちません。

25.2.5.1 get SharedArrayBuffer.prototype.byteLength

SharedArrayBuffer.prototype.byteLength は、set アクセサー関数が undefined であるアクセサープロパティです。その get アクセサー関数は、呼び出されたときに次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[ArrayBufferData]]) を実行する。
  3. IsSharedArrayBuffer(obj) が false である場合、TypeError 例外をスローする。
  4. length を ArrayBufferByteLength(obj, seq-cst) とする。
  5. 𝔽(length) を返す。

25.2.5.2 SharedArrayBuffer.prototype.constructor

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

25.2.5.3 SharedArrayBuffer.prototype.grow ( newLength )

このメソッドは呼び出されたとき、次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[ArrayBufferMaxByteLength]]) を実行する。
  3. IsSharedArrayBuffer(obj) が false である場合、TypeError 例外をスローする。
  4. newByteLength を ? ToIndex(newLength) とする。
  5. hostHandled を ? HostGrowSharedArrayBuffer(obj, newByteLength) とする。
  6. hostHandled が handled である場合、undefined を返す。
  7. agentRecord を周囲の agent の Agent Record とする。
  8. isLittleEndian を agentRecord.[[LittleEndian]] とする。
  9. byteLengthBlock を obj.[[ArrayBufferByteLengthData]] とする。
  10. currentByteLengthRawBytes を GetRawBytesFromSharedBlock(byteLengthBlock, 0, biguint64, true, seq-cst) とする。
  11. newByteLengthRawBytes を NumericToRawBytes(biguint64, ℤ(newByteLength), isLittleEndian) とする。
  12. 次を繰り返す。
    1. 注記: これは、同じバッファに対する並列で競合する拡張が全順序付けされ、失われず、黙って何もしないことがないようにするための compare-and-exchange ループである。競合なしに拡張を試行できた場合、ループは終了する。
    2. currentByteLength を ℝ(RawBytesToNumeric(biguint64, currentByteLengthRawBytes, isLittleEndian)) とする。
    3. newByteLength = currentByteLength である場合、undefined を返す。
    4. newByteLength < currentByteLength または newByteLength > obj.[[ArrayBufferMaxByteLength]] である場合、RangeError 例外をスローする。
    5. byteLengthDelta を newByteLength - currentByteLength とする。
    6. byteLengthDelta byte からなる新しい Shared Data Block 値を作成できない場合、RangeError 例外をスローする。
    7. 注記: ここでは新しい Shared Data Block は構築も使用もされない。拡張可能な SharedArrayBuffer の観測可能な動作は、構築時に最大サイズの Shared Data Block を割り当てることで規定され、この手順はメモリ不足となった実装が RangeError をスローしなければならないという要件を表現している。
    8. readByteLengthRawBytes を AtomicCompareExchangeInSharedBlock(byteLengthBlock, 0, 8, currentByteLengthRawBytes, newByteLengthRawBytes) とする。
    9. ByteListEqual(readByteLengthRawBytes, currentByteLengthRawBytes) が true である場合、undefined を返す。
    10. currentByteLengthRawBytes を readByteLengthRawBytes に設定する。
注

長さを更新する compare-exchange の偽の失敗は禁止されています。新しい長さの境界検査に合格し、実装がメモリ不足でない場合、ReadModifyWriteSharedMemory イベント(すなわち成功した compare-exchange)は常に candidate execution に追加されます。

SharedArrayBuffer.prototype.grow の並列呼出しは全順序付けされます。たとえば、sab.grow(10) と sab.grow(20) という2つの競合する呼出しを考えます。2つの呼出しのいずれか一方が必ず競争に勝ちます。sab.grow(20) が先に発生した場合でも、sab.grow(10) の呼出しが sab を縮小することは決してなく、その場合は代わりに RangeError をスローします。

25.2.5.4 get SharedArrayBuffer.prototype.growable

SharedArrayBuffer.prototype.growable は、set アクセサー関数が undefined であるアクセサープロパティです。その get アクセサー関数は、呼び出されたときに次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[ArrayBufferData]]) を実行する。
  3. IsSharedArrayBuffer(obj) が false である場合、TypeError 例外をスローする。
  4. IsFixedLengthArrayBuffer(obj) が false である場合、true を返す。
  5. false を返す。

25.2.5.5 get SharedArrayBuffer.prototype.maxByteLength

SharedArrayBuffer.prototype.maxByteLength は、set アクセサー関数が undefined であるアクセサープロパティです。その get アクセサー関数は、呼び出されたときに次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[ArrayBufferData]]) を実行する。
  3. IsSharedArrayBuffer(obj) が false である場合、TypeError 例外をスローする。
  4. IsFixedLengthArrayBuffer(obj) が true である場合、
    1. length を obj.[[ArrayBufferByteLength]] とする。
  5. そうでない場合、
    1. length を obj.[[ArrayBufferMaxByteLength]] とする。
  6. 𝔽(length) を返す。

25.2.5.6 SharedArrayBuffer.prototype.slice ( start, end )

このメソッドは呼び出されたとき、次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[ArrayBufferData]]) を実行する。
  3. IsSharedArrayBuffer(obj) が false である場合、TypeError 例外をスローする。
  4. length を ArrayBufferByteLength(obj, seq-cst) とする。
  5. first を ? ToClampedIndex(start, length) とする。
  6. end が undefined である場合、final を length とする。そうでない場合、final を ? ToClampedIndex(end, length) とする。
  7. newLength を max(final - first, 0) とする。
  8. ctor を ? SpeciesConstructor(obj, %SharedArrayBuffer%) とする。
  9. new を ? Construct(ctor, « 𝔽(newLength) ») とする。
  10. ? RequireInternalSlot(new, [[ArrayBufferData]]) を実行する。
  11. IsSharedArrayBuffer(new) が false である場合、TypeError 例外をスローする。
  12. new.[[ArrayBufferData]] が obj.[[ArrayBufferData]] である場合、TypeError 例外をスローする。
  13. ArrayBufferByteLength(new, seq-cst) < newLength である場合、TypeError 例外をスローする。
  14. fromBlock を obj.[[ArrayBufferData]] とする。
  15. toBlock を new.[[ArrayBufferData]] とする。
  16. CopyDataBlockBytes(toBlock, 0, fromBlock, first, newLength) を実行する。
  17. new を返す。

25.2.5.7 SharedArrayBuffer.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティの初期値は String 値 "SharedArrayBuffer" です。

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

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

SharedArrayBuffer インスタンスは SharedArrayBuffer prototype オブジェクトからプロパティを継承します。各 SharedArrayBuffer インスタンスは [[ArrayBufferData]] 内部スロットを持ちます。拡張可能でない SharedArrayBuffer インスタンスはそれぞれ [[ArrayBufferByteLength]] 内部スロットを持ちます。拡張可能な SharedArrayBuffer インスタンスはそれぞれ [[ArrayBufferByteLengthData]] 内部スロットおよび [[ArrayBufferMaxByteLength]] 内部スロットを持ちます。

注

SharedArrayBuffer インスタンスは ArrayBuffer インスタンスとは異なり、決して detached になりません。

25.2.7 拡張可能な SharedArrayBuffer のガイドライン

注 1

以下は、拡張可能な SharedArrayBuffer を扱う ECMAScript プログラマー向けのガイドラインです。

可能な場合、プログラムは配備環境でテストすることを推奨します。利用可能な物理メモリ量はハードウェアデバイス間で大きく異なります。同様に、仮想メモリサブシステムもハードウェアデバイス間およびオペレーティングシステム間で大きく異なります。64ビットのデスクトップ Web ブラウザーで out-of-memory エラーなしに実行できるアプリケーションでも、32ビットのモバイル Web ブラウザーではメモリ不足になる可能性があります。

拡張可能な SharedArrayBuffer の "maxByteLength" オプションの値を選択する場合、アプリケーションに必要な最小のサイズを選択することを推奨します。"maxByteLength" は 1073741824、すなわち 1GiB を超えないことを推奨します。

特定の最大サイズで拡張可能な SharedArrayBuffer を正常に構築できたとしても、将来の拡張が成功することを保証するものではないことに注意してください。

拡張可能な SharedArrayBuffer の長さに対するすべての load が同期を伴う seq-cst load であるわけではありません。たとえば u8[idx] のような整数インデックス付きプロパティアクセスの境界検査のための長さの load は同期を伴いません。一般に、明示的な同期がない場合、あるプロパティアクセスが境界内であることは、同じ agent 内の後続のプロパティアクセスも境界内であることを意味しません。これに対して、SharedArrayBuffer、%TypedArray%.prototype、および DataView.prototype の length および byteLength getter を介した長さの明示的な load は同期を伴います。TypedArray が完全に境界外かどうかを検査するために組込みメソッドによって実行される長さの load も同期を伴います。

注 2

以下は、拡張可能な SharedArrayBuffer を実装する ECMAScript 実装者向けのガイドラインです。

拡張可能な SharedArrayBuffer は、仮想メモリを事前に予約することによるインプレース拡張として実装することを推奨します。

拡張操作は拡張可能な SharedArrayBuffer へのメモリアクセスと並列に発生し得るため、メモリモデルの制約により、unordered アクセスであっても「tear」(値のビットが混在すること)してはなりません。実際には、これは拡張可能な SharedArrayBuffer の基礎となる data block を、world を停止せずにコピーして拡張することはできないことを意味します。world の停止は直列化点を導入し低速であるため、実装戦略として推奨しません。

拡張されたメモリは、その作成時点から、並列の競合アクセスに対してもゼロで初期化されているように見えなければなりません。これは、ゼロ充填オンデマンドの仮想メモリページを使用するか、メモリを手動でゼロ初期化する場合には慎重な同期を行うことで実現できます。

拡張可能な SharedArrayBuffer の TypedArray view に対する整数インデックス付きプロパティアクセスは、拡張不可能な SharedArrayBuffer の TypedArray view に対するアクセスと同様に最適化可能であることを意図しています。これは、整数インデックス付きプロパティの load が基礎となるバッファの長さに対して同期を伴わないためです(上記のプログラマー向けガイドラインを参照)。たとえば、プロパティアクセスの境界検査をループの外へ hoist することもできます。

MMU のない組込みデバイス上で動作するものなど、仮想メモリを持たないホストでは、拡張可能な SharedArrayBuffer をコピーによって実装することは実際には困難です。そのようなホストにおける拡張可能な SharedArrayBuffer のメモリ使用動作は、仮想メモリを持つホストとは大きく異なる可能性があります。そのようなホストは、メモリ使用量に関する想定をユーザーへ明確に伝えるべきです。

25.3 DataView オブジェクト

25.3.1 DataView オブジェクトのための抽象操作

25.3.1.1 DataView With Buffer Witness Record

DataView With Buffer Witness Record は、DataView と、view しているバッファのキャッシュされた byte length をともにカプセル化するために使用される Record です。view しているバッファが拡張可能な SharedArrayBuffer である場合に、byte length data block に対して単一の ReadSharedMemory イベントしか発生しないことを保証するのに役立ちます。

DataView With Buffer Witness Record は 表 73 に列挙されるフィールドを持ちます。

表 73: DataView With Buffer Witness Record のフィールド
フィールド名 値 意味
[[Object]] a DataView バッファの byte length が読み込まれる DataView オブジェクト。
[[CachedBufferByteLength]] a non-negative integer or detached Record が作成された時点におけるオブジェクトの [[ViewedArrayBuffer]] の byte length。

25.3.1.2 MakeDataViewWithBufferWitnessRecord ( obj, order )

抽象操作 MakeDataViewWithBufferWitnessRecord。引数 obj (DataView) および order ((seq-cst または unordered))。戻り値:DataView With Buffer Witnessレコード。 呼び出されると、次の手順を実行する。

  1. buffer を obj.[[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 )

抽象操作 GetViewByteLength。引数 viewRecord (DataView With Buffer Witnessレコード)。戻り値:非負整数。 呼び出されると、次の手順を実行する。

  1. 表明: IsViewOutOfBounds(viewRecord) は false である。
  2. view を viewRecord.[[Object]] とする。
  3. view.[[ByteLength]] が auto でない場合、view.[[ByteLength]] を返す。
  4. 表明: IsFixedLengthArrayBuffer(view.[[ViewedArrayBuffer]]) は false である。
  5. byteOffset を view.[[ByteOffset]] とする。
  6. byteLength を viewRecord.[[CachedBufferByteLength]] とする。
  7. 表明: byteLength は detached でない。
  8. byteLength - byteOffset を返す。

25.3.1.4 IsViewOutOfBounds ( viewRecord )

抽象操作 IsViewOutOfBounds。引数 viewRecord (DataView With Buffer Witnessレコード)。戻り値:Boolean。 呼び出されると、次の手順を実行する。

  1. view を viewRecord.[[Object]] とする。
  2. bufferByteLength を viewRecord.[[CachedBufferByteLength]] とする。
  3. IsDetachedBuffer(view.[[ViewedArrayBuffer]]) が true である場合、
    1. 表明: bufferByteLength は detached である。
    2. true を返す。
  4. 表明: bufferByteLength は非負整数である。
  5. byteOffsetStart を view.[[ByteOffset]] とする。
  6. view.[[ByteLength]] が auto である場合、
    1. byteOffsetEnd を bufferByteLength とする。
  7. そうでない場合、
    1. byteOffsetEnd を byteOffsetStart + view.[[ByteLength]] とする。
  8. 注記: [[ByteOffset]] が bufferByteLength である長さ0の DataView は境界外とはみなされない。
  9. byteOffsetStart > bufferByteLength または byteOffsetEnd > bufferByteLength である場合、true を返す。
  10. false を返す。

25.3.1.5 GetViewValue ( view, requestIndex, isLittleEndian, type )

抽象操作 GetViewValue。引数 view (ECMAScript 言語値)、requestIndex (ECMAScript 言語値)、isLittleEndian (ECMAScript 言語値) および type (TypedArray 要素型)。戻り値:(正常完了 (値:(Number または BigInt)) または throw 完了)。 DataView インスタンス上の関数が view のバッファから値を取得するために使用されます。 呼び出されると、次の手順を実行する。

  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 の backing buffer が拡張可能な SharedArrayBuffer である場合、境界検査は同期操作ではない。
  8. IsViewOutOfBounds(viewRecord) が true である場合、TypeError 例外をスローする。
  9. viewSize を GetViewByteLength(viewRecord) とする。
  10. elementSize を Element Type type について 表 71 で規定される Element Size 値とする。
  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 )

抽象操作 SetViewValue。引数 view (ECMAScript 言語値)、requestIndex (ECMAScript 言語値)、isLittleEndian (ECMAScript 言語値)、type (TypedArray 要素型) および value (ECMAScript 言語値)。戻り値:(正常完了 (値:unused) または throw 完了)。 DataView インスタンス上の関数が view のバッファへ値を保存するために使用されます。 呼び出されると、次の手順を実行する。

  1. ? RequireInternalSlot(view, [[DataView]]) を実行する。
  2. 表明: view は [[ViewedArrayBuffer]] 内部スロットを持つ。
  3. getIndex を ? ToIndex(requestIndex) とする。
  4. IsBigIntElementType(type) が true である場合、number を ? ToBigInt(value) とする。
  5. そうでない場合、number を ? ToNumber(value) とする。
  6. isLittleEndian を ToBoolean(isLittleEndian) に設定する。
  7. viewOffset を view.[[ByteOffset]] とする。
  8. viewRecord を MakeDataViewWithBufferWitnessRecord(view, unordered) とする。
  9. 注記: view の backing buffer が拡張可能な SharedArrayBuffer である場合、境界検査は同期操作ではない。
  10. IsViewOutOfBounds(viewRecord) が true である場合、TypeError 例外をスローする。
  11. viewSize を GetViewByteLength(viewRecord) とする。
  12. elementSize を Element Type type について 表 71 で規定される Element Size 値とする。
  13. getIndex + elementSize > viewSize である場合、RangeError 例外をスローする。
  14. bufferIndex を getIndex + viewOffset とする。
  15. SetValueInBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, number, false, unordered, isLittleEndian) を実行する。
  16. unused を返す。

25.3.2 DataView コンストラクター

DataView コンストラクターは:

  • %DataView% です。
  • グローバルオブジェクトの "DataView" プロパティの初期値です。
  • コンストラクターとして呼び出されたとき、新しい DataView を作成して初期化します。
  • 関数として呼び出されることを意図しておらず、そのように呼び出されると例外をスローします。
  • クラス定義の extends 節の値として使用できます。規定された DataView の動作を継承しようとするサブクラスコンストラクターは、DataView.prototype の組込みメソッドをサポートするために必要な内部状態を持つサブクラスインスタンスを作成して初期化するため、DataView コンストラクターへの 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. byteLength が undefined である場合、
    1. bufferIsFixedLength が true である場合、
      1. viewByteLength を bufferByteLength - offset とする。
    2. そうでない場合、
      1. viewByteLength を auto とする。
  9. そうでない場合、
    1. viewByteLength を ? ToIndex(byteLength) とする。
    2. offset + viewByteLength > bufferByteLength である場合、RangeError 例外をスローする。
  10. obj を ? OrdinaryCreateFromConstructor(NewTarget, "%DataView.prototype%", « [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] ») とする。
  11. IsDetachedBuffer(buffer) が true である場合、TypeError 例外をスローする。
  12. bufferByteLength を ArrayBufferByteLength(buffer, seq-cst) に設定する。
  13. offset > bufferByteLength である場合、RangeError 例外をスローする。
  14. byteLength が undefined でない場合、
    1. offset + viewByteLength > bufferByteLength である場合、RangeError 例外をスローする。
  15. obj.[[ViewedArrayBuffer]] を buffer に設定する。
  16. obj.[[ByteLength]] を viewByteLength に設定する。
  17. obj.[[ByteOffset]] を offset に設定する。
  18. obj を返す。

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

DataView コンストラクターは:

  • 値が %Function.prototype% である [[Prototype]] 内部スロットを持ちます。
  • 次のプロパティを持ちます。

25.3.3.1 DataView.prototype

DataView.prototype の初期値は DataView prototype オブジェクトです。

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

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

DataView prototype オブジェクトは:

  • %DataView.prototype% です。
  • 値が %Object.prototype% である [[Prototype]] 内部スロットを持ちます。
  • 通常オブジェクトです。
  • [[DataView]]、[[ViewedArrayBuffer]]、[[ByteLength]]、または [[ByteOffset]] 内部スロットを持ちません。

25.3.4.1 get DataView.prototype.buffer

DataView.prototype.buffer は、set アクセサー関数が undefined であるアクセサープロパティです。その get アクセサー関数は、呼び出されたときに次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[DataView]]) を実行する。
  3. 表明: obj は [[ViewedArrayBuffer]] 内部スロットを持つ。
  4. buffer を obj.[[ViewedArrayBuffer]] とする。
  5. buffer を返す。

25.3.4.2 get DataView.prototype.byteLength

DataView.prototype.byteLength は、set アクセサー関数が undefined であるアクセサープロパティです。その get アクセサー関数は、呼び出されたときに次の手順を実行します。

  1. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[DataView]]) を実行する。
  3. 表明: obj は [[ViewedArrayBuffer]] 内部スロットを持つ。
  4. viewRecord を MakeDataViewWithBufferWitnessRecord(obj, 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. obj を this 値とする。
  2. ? RequireInternalSlot(obj, [[DataView]]) を実行する。
  3. 表明: obj は [[ViewedArrayBuffer]] 内部スロットを持つ。
  4. viewRecord を MakeDataViewWithBufferWitnessRecord(obj, seq-cst) とする。
  5. IsViewOutOfBounds(viewRecord) が true である場合、TypeError 例外をスローする。
  6. offset を obj.[[ByteOffset]] とする。
  7. 𝔽(offset) を返す。

25.3.4.4 DataView.prototype.constructor

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

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. ? GetViewValue(view, byteOffset, littleEndian, bigint64) を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. ? GetViewValue(view, byteOffset, littleEndian, biguint64) を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? GetViewValue(view, byteOffset, littleEndian, float16) を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? GetViewValue(view, byteOffset, littleEndian, float32) を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? GetViewValue(view, byteOffset, littleEndian, float64) を返す。

25.3.4.10 DataView.prototype.getInt8 ( byteOffset )

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. ? GetViewValue(view, byteOffset, true, int8) を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? GetViewValue(view, byteOffset, littleEndian, int16) を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? GetViewValue(view, byteOffset, littleEndian, int32) を返す。

25.3.4.13 DataView.prototype.getUint8 ( byteOffset )

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. ? GetViewValue(view, byteOffset, true, uint8) を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? GetViewValue(view, byteOffset, littleEndian, uint16) を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? GetViewValue(view, byteOffset, littleEndian, uint32) を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. ? SetViewValue(view, byteOffset, littleEndian, bigint64, value) を実行する。
  3. undefined を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. ? SetViewValue(view, byteOffset, littleEndian, biguint64, value) を実行する。
  3. undefined を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? SetViewValue(view, byteOffset, littleEndian, float16, value) を実行する。
  4. undefined を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? SetViewValue(view, byteOffset, littleEndian, float32, value) を実行する。
  4. undefined を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? SetViewValue(view, byteOffset, littleEndian, float64, value) を実行する。
  4. undefined を返す。

25.3.4.21 DataView.prototype.setInt8 ( byteOffset, value )

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. ? SetViewValue(view, byteOffset, true, int8, value) を実行する。
  3. undefined を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? SetViewValue(view, byteOffset, littleEndian, int16, value) を実行する。
  4. undefined を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? SetViewValue(view, byteOffset, littleEndian, int32, value) を実行する。
  4. undefined を返す。

25.3.4.24 DataView.prototype.setUint8 ( byteOffset, value )

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. ? SetViewValue(view, byteOffset, true, uint8, value) を実行する。
  3. undefined を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? SetViewValue(view, byteOffset, littleEndian, uint16, value) を実行する。
  4. undefined を返す。

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

このメソッドは呼び出されたとき、次の手順を実行します。

  1. view を this 値とする。
  2. littleEndian が存在しない場合、littleEndian を false に設定する。
  3. ? SetViewValue(view, byteOffset, littleEndian, uint32, value) を実行する。
  4. undefined を返す。

25.3.4.27 DataView.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティの初期値は String 値 "DataView" です。

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

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

DataView インスタンスは DataView prototype オブジェクトからプロパティを継承する通常オブジェクトです。各 DataView インスタンスは [[DataView]]、[[ViewedArrayBuffer]]、[[ByteLength]]、および [[ByteOffset]] 内部スロットを持ちます。

注

[[DataView]] 内部スロットの値はこの仕様内では使用されません。その内部スロットが存在すること自体が、DataView コンストラクターを使用して作成されたオブジェクトを識別するために仕様内で使用されます。

25.4 Atomics オブジェクト

Atomics オブジェクトは:

Atomics オブジェクトは、共有メモリ配列セルに対して不可分(atomic)に動作する関数と、agent がプリミティブイベントを待機および通知できる関数を提供します。規律を守って使用することで、Atomics 関数は、共有メモリを介して通信するマルチ agent プログラムが、並列 CPU 上であっても十分に理解可能な順序で実行されるようにできます。共有メモリ通信を支配する規則は、以下で定義されるメモリモデルによって提供されます。

注

ECMAScript で共有メモリをプログラミングおよび実装するための参考ガイドラインについては、メモリモデル節の末尾にある注記を参照してください。

25.4.1 Waiter Record

Waiter Record は、Atomics.wait または Atomics.waitAsync の特定の呼出しを表すために使用される Record です。

Waiter Record は 表 74 に列挙されるフィールドを持ちます。

表 74: Waiter Record のフィールド
フィールド名 値 意味
[[AgentSignifier]] an agent signifier Atomics.wait または Atomics.waitAsync を呼び出した agent。
[[PromiseCapability]] a PromiseCapability Record or blocking Atomics.waitAsync の呼出しを表す場合は結果の promise、それ以外の場合は blocking。
[[TimeoutTime]] a non-negative extended mathematical value timeout が発生し得る最も早い時刻。time value を使用して計算されます。
[[Result]] "ok" or "timed-out" 呼出しの戻り値。

25.4.2 WaiterList Record

WaiterList Record は、Atomics.wait、Atomics.waitAsync、および Atomics.notify を介した agent の待機と通知を説明するために使用されます。

WaiterList Record は 表 75 に列挙されるフィールドを持ちます。

表 75: WaiterList Record のフィールド
フィールド名 値 意味
[[Waiters]] a List of Waiter Records この WaiterList に関連付けられた位置で待機している Atomics.wait または Atomics.waitAsync の呼出し。
[[MostRecentLeaveEvent]] a Synchronize event or empty その critical section から最後に退出したときのイベント。または critical section に一度も入ったことがない場合は empty。

同じ agent signifier を持つ複数の Waiter Record が WaiterList 内に存在する場合があります。

agent cluster は WaiterList Record の保存領域を持ちます。この保存領域は (block, i) によって索引付けされます。ここで block は Shared Data Block、i は block のメモリ内の byte offset です。WaiterList Record は agent 非依存です。(block, i) によって WaiterList Record の保存領域を検索すると、agent cluster 内のどの agent でも同じ WaiterList Record が得られます。

各 WaiterList Record は、評価中にその WaiterList Record への排他的アクセスを制御するcritical sectionを持ちます。一度に1つの agent だけが WaiterList Record の critical section に入ることができます。WaiterList Record の critical section への進入および退出は、抽象操作 EnterCriticalSection および LeaveCriticalSection によって制御されます。WaiterList Record に対する操作、すなわち待機中 agent の追加と削除、agent リストの走査、リスト上の agent の一時停止と通知、Synchronize イベントの設定と取得は、WaiterList Record の critical section に入った agent のみが実行できます。

25.4.3 Atomics のための抽象操作

25.4.3.1 ValidateIntegerTypedArray ( ta, waitable )

抽象操作 ValidateIntegerTypedArray。引数 ta (ECMAScript 言語値) および waitable (Boolean)。戻り値:(正常完了 (値:TypedArray With Buffer Witnessレコード) または throw 完了)。 %Atomics% 関数で使用できる TypedArray、特に共有メモリとの atomic な相互作用を保証できるものを制限するために使用されます。 呼び出されると、次の手順を実行する。

  1. 注記: ta の backing buffer が拡張可能な SharedArrayBuffer である場合、境界検査は同期操作ではない。
  2. taRecord を ? ValidateTypedArray(ta, unordered) とする。
  3. elementType を TypedArrayElementType(ta) とする。
  4. IsNoTearConfiguration(elementType, seq-cst) が false である場合、TypeError 例外をスローする。
  5. waitable が true であり、elementType が int32 でも bigint64 でもない場合、TypeError 例外をスローする。
  6. taRecord を返す。

25.4.3.2 ValidateAtomicAccess ( taRecord, requestIndex )

抽象操作 ValidateAtomicAccess。引数 taRecord (TypedArray With Buffer Witnessレコード) および requestIndex (ECMAScript 言語値)。戻り値:(正常完了 (値:非負整数) または throw 完了)。 呼び出されると、次の手順を実行する。

  1. length を TypedArrayLength(taRecord) とする。
  2. accessIndex を ? ToIndex(requestIndex) とする。
  3. 表明: accessIndex ≥ 0。
  4. accessIndex ≥ length である場合、RangeError 例外をスローする。
  5. ta を taRecord.[[Object]] とする。
  6. elementSize を TypedArrayElementSize(ta) とする。
  7. offset を ta.[[ByteOffset]] とする。
  8. (accessIndex × elementSize) + offset を返す。

25.4.3.3 ValidateAtomicAccessOnIntegerTypedArray ( ta, requestIndex )

抽象操作 ValidateAtomicAccessOnIntegerTypedArray。引数 ta (ECMAScript 言語値) および requestIndex (ECMAScript 言語値)。戻り値:(正常完了 (値:非負整数) または throw 完了)。 呼び出されると、次の手順を実行する。

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

25.4.3.4 RevalidateAtomicAccess ( ta, byteIndexInBuffer )

抽象操作 RevalidateAtomicAccess。引数 ta (TypedArray) および byteIndexInBuffer (非負整数)。戻り値:(正常完了 (値:unused) または throw 完了)。 この操作は、Atomics メソッドですべての引数の型強制が実行された後、atomic 操作のために backing buffer 内のインデックスを再検証します。引数の型強制には任意の副作用があり得て、それによってバッファが境界外になる可能性があるためです。ta の backing buffer が SharedArrayBuffer である場合、この操作はスローしません。 呼び出されると、次の手順を実行する。

  1. 注記: ta の backing buffer が拡張可能な SharedArrayBuffer である場合、境界検査は同期操作ではない。
  2. taRecord を ? ValidateTypedArrayBounds(ta, unordered) とする。
  3. 表明: byteIndexInBuffer ≥ ta.[[ByteOffset]]。
  4. byteIndexInBuffer ≥ taRecord.[[CachedBufferByteLength]] である場合、RangeError 例外をスローする。
  5. unused を返す。

25.4.3.5 GetWaiterList ( block, i )

抽象操作 GetWaiterList。引数 block (共有データブロック) および i (a non-negative integer that is evenly divisible by 4)。戻り値:WaiterListレコード。 呼び出されると、次の手順を実行する。

  1. 表明: i および i + 3 は block のメモリ内の有効な byte offset である。
  2. 組 (block, i) によって参照される WaiterList Record を返す。

25.4.3.6 EnterCriticalSection ( waiterList )

抽象操作 EnterCriticalSection。引数 waiterList (WaiterListレコード)。戻り値:unused。 呼び出されると、次の手順を実行する。

  1. 表明: 周囲の agent はいずれの WaiterList Record の critical section 内にもいない。
  2. waiterList の critical section 内に agent がいなくなるまで待機し、その後 waiterList の critical section に入る(他のいかなる agent にも入ることを許可しない)。
  3. waiterList.[[MostRecentLeaveEvent]] が empty でない場合、
    1. 注記: critical section に少なくとも1回入った waiterList には、LeaveCriticalSection によって設定された Synchronize イベントがある。
    2. agentRecord を周囲の agent の Agent Record とする。
    3. execution を agentRecord.[[CandidateExecution]] とする。
    4. eventsRecord を、[[AgentSignifier]] が AgentSignifier() である execution.[[EventsRecords]] の Agent Events Record とする。
    5. enterEvent を新しい Synchronize イベントとする。
    6. enterEvent を eventsRecord.[[EventList]] に追加する。
    7. (waiterList.[[MostRecentLeaveEvent]], enterEvent) を eventsRecord.[[AgentSynchronizesWith]] に追加する。
  4. unused を返す。

EnterCriticalSection は、critical section に入ろうとする agent が、別の agent がそこから出るのを待たなければならない場合に競合を持ちます。競合がない場合、EnterCriticalSection 呼出しの FIFO 順序は観測可能です。競合がある場合、実装は任意の順序を選択できますが、agent を無期限に待機させてはなりません。

25.4.3.7 LeaveCriticalSection ( waiterList )

抽象操作 LeaveCriticalSection。引数 waiterList (WaiterListレコード)。戻り値:unused。 呼び出されると、次の手順を実行する。

  1. 表明: 周囲の agent は waiterList の critical section 内にいる。
  2. agentRecord を周囲の agent の Agent Record とする。
  3. execution を agentRecord.[[CandidateExecution]] とする。
  4. eventsRecord を、[[AgentSignifier]] が AgentSignifier() である execution.[[EventsRecords]] の Agent Events Record とする。
  5. leaveEvent を新しい Synchronize イベントとする。
  6. leaveEvent を eventsRecord.[[EventList]] に追加する。
  7. waiterList.[[MostRecentLeaveEvent]] を leaveEvent に設定する。
  8. waiterList の critical section から退出する。
  9. unused を返す。

25.4.3.8 AddWaiter ( waiterList, waiterRecord )

抽象操作 AddWaiter。引数 waiterList (WaiterListレコード) および waiterRecord (Waiterレコード)。戻り値:unused。 呼び出されると、次の手順を実行する。

  1. 表明: 周囲の agent は waiterList の critical section 内にいる。
  2. 表明: [[PromiseCapability]] フィールドが waiterRecord.[[PromiseCapability]] であり、[[AgentSignifier]] フィールドが waiterRecord.[[AgentSignifier]] である Waiter Record は waiterList.[[Waiters]] 内に存在しない。
  3. waiterRecord を waiterList.[[Waiters]] に追加する。
  4. unused を返す。

25.4.3.9 RemoveWaiter ( waiterList, waiterRecord )

抽象操作 RemoveWaiter。引数 waiterList (WaiterListレコード) および waiterRecord (Waiterレコード)。戻り値:unused。 呼び出されると、次の手順を実行する。

  1. 表明: 周囲の agent は waiterList の critical section 内にいる。
  2. 表明: waiterList.[[Waiters]] は waiterRecord を含む。
  3. waiterList.[[Waiters]] から waiterRecord を削除する。
  4. unused を返す。

25.4.3.10 RemoveWaiters ( waiterList, count )

抽象操作 RemoveWaiters。引数 waiterList (WaiterListレコード) および count ((非負整数 または +∞))。戻り値:リスト (要素:Waiterレコード)。 呼び出されると、次の手順を実行する。

  1. 表明: 周囲の agent は waiterList の critical section 内にいる。
  2. length を waiterList.[[Waiters]] の要素数とする。
  3. count を min(count, length) に設定する。
  4. waiters を、waiterList.[[Waiters]] の先頭 count 個の要素を要素とする List とする。
  5. waiterList.[[Waiters]] の先頭 count 個の要素を削除する。
  6. waiters を返す。

25.4.3.11 SuspendThisAgent ( waiterList, waiterRecord )

抽象操作 SuspendThisAgent。引数 waiterList (WaiterListレコード) および waiterRecord (Waiterレコード)。戻り値:unused。 呼び出されると、次の手順を実行する。

  1. 表明: 周囲の agent は waiterList の critical section 内にいる。
  2. 表明: waiterList.[[Waiters]] は waiterRecord を含む。
  3. thisAgent を AgentSignifier() とする。
  4. 表明: waiterRecord.[[AgentSignifier]] は thisAgent である。
  5. 表明: waiterRecord.[[PromiseCapability]] は blocking である。
  6. 表明: AgentCanSuspend() は true である。
  7. LeaveCriticalSection(waiterList) を実行し、時刻が waiterRecord.[[TimeoutTime]] になるまで周囲の agent を一時停止する。この複合操作は、critical section から退出した後、一時停止が有効になる前に到着した通知が失われない方法で実行する。周囲の agent は、timeout または別の agent が引数 waiterList と thisAgent で NotifyWaiter を呼び出すこと(すなわち Atomics.notify の呼出し)によってのみ一時停止から復帰できる。
  8. EnterCriticalSection(waiterList) を実行する。
  9. unused を返す。

25.4.3.12 NotifyWaiter ( waiterList, waiterRecord )

抽象操作 NotifyWaiter。引数 waiterList (WaiterListレコード) および waiterRecord (Waiterレコード)。戻り値:unused。 呼び出されると、次の手順を実行する。

  1. 表明: 周囲の agent は waiterList の critical section 内にいる。
  2. waiterRecord.[[PromiseCapability]] が blocking である場合、
    1. signifier が waiterRecord.[[AgentSignifier]] である agent を一時停止から復帰させる。
    2. 注記: これにより agent は SuspendThisAgent 内で実行を再開する。
  3. そうでなく、AgentSignifier() が waiterRecord.[[AgentSignifier]] である場合、
    1. promiseCapability を waiterRecord.[[PromiseCapability]] とする。
    2. ! Call(promiseCapability.[[Resolve]], undefined, « waiterRecord.[[Result]] ») を実行する。
  4. そうでない場合、
    1. EnqueueResolveInAgentJob(waiterRecord.[[AgentSignifier]], waiterRecord.[[PromiseCapability]], waiterRecord.[[Result]]) を実行する。
  5. unused を返す。
注

agent は、別の agent の promise capability をホストへ渡すこと以外のいかなる目的でもアクセスしてはなりません。

25.4.3.13 EnqueueResolveInAgentJob ( agentSignifier, promiseCapability, resolution )

抽象操作 EnqueueResolveInAgentJob。引数 agentSignifier (an agent signifier)、promiseCapability (PromiseCapabilityレコード) および resolution (("ok" または "timed-out"))。戻り値:unused。 呼び出されると、次の手順を実行する。

  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. 表明: agentSignifier は realmInTargetAgent.[[AgentSignifier]] である。
  4. HostEnqueueGenericJob(resolveJob, realmInTargetAgent) を実行する。
  5. unused を返す。

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

抽象操作 DoWait。引数 mode ((sync または async))、ta (ECMAScript 言語値)、index (ECMAScript 言語値)、value (ECMAScript 言語値) および timeout (ECMAScript 言語値)。戻り値:(正常完了 (値:(Object、"not-equal"、"timed-out" または "ok")) または throw 完了)。 呼び出されると、次の手順を実行する。

  1. taRecord を ? ValidateIntegerTypedArray(ta, true) とする。
  2. buffer を taRecord.[[Object]].[[ViewedArrayBuffer]] とする。
  3. IsSharedArrayBuffer(buffer) が false である場合、TypeError 例外をスローする。
  4. byteIndexInBuffer を ? ValidateAtomicAccess(taRecord, index) とする。
  5. elementType を TypedArrayElementType(ta) とする。
  6. 表明: elementType は bigint64 または int32 のいずれかである。
  7. elementType が bigint64 である場合、expected を ? ToBigInt64(value) とする。そうでない場合、expected を ? ToInt32(value) とする。
  8. timeoutNumber を ? ToNumber(timeout) とする。
  9. timeoutNumber が NaN または +∞𝔽 のいずれかである場合、realTimeout を +∞ とする。
  10. そうでなく、timeoutNumber が -∞𝔽 である場合、realTimeout を 0 とする。
  11. そうでない場合、realTimeout を max(ℝ(timeoutNumber), 0) とする。
  12. mode が sync であり、AgentCanSuspend() が false である場合、TypeError 例外をスローする。
  13. block を buffer.[[ArrayBufferData]] とする。
  14. waiterList を GetWaiterList(block, byteIndexInBuffer) とする。
  15. mode が sync である場合、
    1. promiseCapability を blocking とする。
    2. resultObj を undefined とする。
  16. そうでない場合、
    1. promiseCapability を ! NewPromiseCapability(%Promise%) とする。
    2. resultObj を OrdinaryObjectCreate(%Object.prototype%) とする。
  17. EnterCriticalSection(waiterList) を実行する。
  18. witness を GetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst) とする。
  19. expected ≠ witness である場合、
    1. LeaveCriticalSection(waiterList) を実行する。
    2. mode が sync である場合、"not-equal" を返す。
    3. ! CreateDataPropertyOrThrow(resultObj, "async", false) を実行する。
    4. ! CreateDataPropertyOrThrow(resultObj, "value", "not-equal") を実行する。
    5. resultObj を返す。
  20. realTimeout = 0 かつ mode が async である場合、
    1. 注記: 同期的な即時 timeout に対する特別な処理はない。非同期の即時 timeout には、迅速に失敗して不要な Promise job を回避するための特別な処理がある。
    2. LeaveCriticalSection(waiterList) を実行する。
    3. ! CreateDataPropertyOrThrow(resultObj, "async", false) を実行する。
    4. ! CreateDataPropertyOrThrow(resultObj, "value", "timed-out") を実行する。
    5. resultObj を返す。
  21. thisAgent を AgentSignifier() とする。
  22. now を現在時刻を識別する time value (UTC) とする。
  23. additionalTimeout を実装定義の非負数学値とする。
  24. timeoutTime を ℝ(now) + realTimeout + additionalTimeout とする。
  25. 注記: realTimeout が +∞ である場合、timeoutTime も +∞ である。
  26. waiterRecord を新しい Waiter Record { [[AgentSignifier]]: thisAgent, [[PromiseCapability]]: promiseCapability, [[TimeoutTime]]: timeoutTime, [[Result]]: "ok" } とする。
  27. AddWaiter(waiterList, waiterRecord) を実行する。
  28. mode が sync である場合、
    1. SuspendThisAgent(waiterList, waiterRecord) を実行する。
  29. そうでなく、timeoutTime が有限である場合、
    1. EnqueueAtomicsWaitAsyncTimeoutJob(waiterList, waiterRecord) を実行する。
  30. LeaveCriticalSection(waiterList) を実行する。
  31. mode が sync である場合、waiterRecord.[[Result]] を返す。
  32. ! CreateDataPropertyOrThrow(resultObj, "async", true) を実行する。
  33. ! CreateDataPropertyOrThrow(resultObj, "value", promiseCapability.[[Promise]]) を実行する。
  34. resultObj を返す。
注

additionalTimeout により、実装は消費電力の削減やタイミング攻撃を緩和するためのタイマー分解能の粗粒度化など、必要に応じて timeout を延長できます。この値は DoWait の呼出しごとに異なってもかまいません。

25.4.3.15 EnqueueAtomicsWaitAsyncTimeoutJob ( waiterList, waiterRecord )

抽象操作 EnqueueAtomicsWaitAsyncTimeoutJob。引数 waiterList (WaiterListレコード) および waiterRecord (Waiterレコード)。戻り値:unused。 呼び出されると、次の手順を実行する。

  1. timeoutJob を、waiterList と waiterRecord を捕捉し、パラメーターを持たず、呼び出されたときに次の手順を実行する新しい Job Abstract Closure とする。
    1. EnterCriticalSection(waiterList) を実行する。
    2. waiterList.[[Waiters]] が waiterRecord を含む場合、
      1. timeOfJobExecution を現在時刻を識別する time value (UTC) とする。
      2. 表明: ℝ(timeOfJobExecution) ≥ waiterRecord.[[TimeoutTime]](time value の潜在的な非単調性を無視する)。
      3. waiterRecord.[[Result]] を "timed-out" に設定する。
      4. RemoveWaiter(waiterList, waiterRecord) を実行する。
      5. NotifyWaiter(waiterList, waiterRecord) を実行する。
    3. LeaveCriticalSection(waiterList) を実行する。
    4. unused を返す。
  2. now を現在時刻を識別する time value (UTC) とする。
  3. currentRealm を現在の Realm Record とする。
  4. HostEnqueueTimeoutJob(timeoutJob, currentRealm, 𝔽(waiterRecord.[[TimeoutTime]]) - now) を実行する。
  5. unused を返す。

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

抽象操作 AtomicCompareExchangeInSharedBlock。引数 block (共有データブロック)、byteIndexInBuffer (整数)、elementSize (非負整数)、expectedBytes (リスト (要素:バイト値)) および replacementBytes (リスト (要素:バイト値))。戻り値:リスト (要素:バイト値)。 呼び出されると、次の手順を実行する。

  1. agentRecord を周囲の agent の Agent Record とする。
  2. execution を agentRecord.[[CandidateExecution]] とする。
  3. eventsRecord を、[[AgentSignifier]] が AgentSignifier() である execution.[[EventsRecords]] の Agent Events Record とする。
  4. rawBytesRead を、要素が非決定的に選択された byte 値である長さ elementSize の List とする。
  5. 注記: 実装では、rawBytesRead は基礎となるハードウェア上の load-link、load-exclusive、または read-modify-write 命令のオペランドの結果である。この非決定性は、弱い一貫性を持つハードウェアの観測可能な動作を記述するためのメモリモデルの意味論的規定である。
  6. 注記: 期待値と読み取った値の比較は、期待値と読み取った値が等しくない場合に不必要に強い同期を避けるため、read-modify-write modification function の外部で実行される。
  7. ByteListEqual(rawBytesRead, expectedBytes) が true である場合、
    1. second を、何も捕捉せず、パラメーター (oldBytes, newBytes) を持ち、呼び出されたときに次の手順を atomic に実行する新しい read-modify-write modification function とする。
      1. newBytes を返す。
    2. event を ReadModifyWriteSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize, [[Payload]]: replacementBytes, [[ModifyOp]]: second } とする。
  8. そうでない場合、
    1. event を ReadSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize } とする。
  9. event を eventsRecord.[[EventList]] に追加する。
  10. Chosen Value Record { [[Event]]: event, [[ChosenValue]]: rawBytesRead } を execution.[[ChosenValues]] に追加する。
  11. rawBytesRead を返す。

25.4.3.17 AtomicReadModifyWrite ( ta, index, value, op )

抽象操作 AtomicReadModifyWrite。引数 ta (ECMAScript 言語値)、index (ECMAScript 言語値)、value (ECMAScript 言語値) および op (a read-modify-write modification function)。戻り値:(正常完了 (値:(Number または BigInt)) または throw 完了)。 op は byte 値の List である2つの引数を受け取り、byte 値の List を返します。この操作は値を atomic に読み込み、別の値と結合し、その結合結果を保存します。読み込んだ値を返します。 呼び出されると、次の手順を実行する。

  1. byteIndexInBuffer を ? ValidateAtomicAccessOnIntegerTypedArray(ta, index) とする。
  2. ta.[[ContentType]] が bigint である場合、coerced を ? ToBigInt(value) とする。
  3. そうでない場合、coerced を 𝔽(? ToIntegerOrInfinity(value)) とする。
  4. ? RevalidateAtomicAccess(ta, byteIndexInBuffer) を実行する。
  5. buffer を ta.[[ViewedArrayBuffer]] とする。
  6. elementType を TypedArrayElementType(ta) とする。
  7. GetModifySetValueInBuffer(buffer, byteIndexInBuffer, elementType, coerced, op) を返す。

25.4.3.18 ByteListBitwiseOp ( op, xBytes, yBytes )

抽象操作 ByteListBitwiseOp。引数 op ((&、^ または |))、xBytes (リスト (要素:バイト値)) および yBytes (リスト (要素:バイト値))。戻り値:リスト (要素:バイト値)。 この操作は引数のすべての byte 値に対してビット単位演算を atomic に実行し、byte 値の List を返します。 呼び出されると、次の手順を実行する。

  1. 表明: xBytes と yBytes は同じ要素数を持つ。
  2. result を新しい空の List とする。
  3. i を 0 とする。
  4. xBytes の各要素 xByte について、次を行う。
    1. yByte を yBytes[i] とする。
    2. op が & である場合、
      1. resultByte を xByte と yByte にビット単位 AND 演算を適用した結果とする。
    3. そうでなく、op が ^ である場合、
      1. resultByte を xByte と yByte にビット単位排他的 OR (XOR) 演算を適用した結果とする。
    4. そうでない場合、
      1. 表明: op は | である。
      2. resultByte を xByte と yByte にビット単位包含 OR 演算を適用した結果とする。
    5. i を i + 1 に設定する。
    6. resultByte を result に追加する。
  5. result を返す。

25.4.3.19 ByteListEqual ( xBytes, yBytes )

抽象操作 ByteListEqual。引数 xBytes (リスト (要素:バイト値)) および yBytes (リスト (要素:バイト値))。戻り値:Boolean。 呼び出されると、次の手順を実行する。

  1. xBytes と yBytes が同じ要素数を持たない場合、false を返す。
  2. i を 0 とする。
  3. xBytes の各要素 xByte について、次を行う。
    1. yByte を yBytes[i] とする。
    2. xByte ≠ yByte である場合、false を返す。
    3. i を i + 1 に設定する。
  4. true を返す。

25.4.4 Atomics.add ( ta, index, value )

この関数は呼び出されたとき、次の手順を実行します。

  1. add を、ta を捕捉し、パラメーター (xBytes, yBytes) を持ち、呼び出されたときに次の手順を atomic に実行する新しい read-modify-write modification function とする。
    1. type を TypedArrayElementType(ta) とする。
    2. agentRecord を周囲の agent の Agent Record とする。
    3. isLittleEndian を agentRecord.[[LittleEndian]] とする。
    4. x を RawBytesToNumeric(type, xBytes, isLittleEndian) とする。
    5. y を RawBytesToNumeric(type, yBytes, isLittleEndian) とする。
    6. x が Number である場合、
      1. sum を Number::add(x, y) とする。
    7. そうでない場合、
      1. 表明: x は BigInt である。
      2. sum を BigInt::add(x, y) とする。
    8. sumBytes を NumericToRawBytes(type, sum, isLittleEndian) とする。
    9. 表明: sumBytes、xBytes、および yBytes は同じ要素数を持つ。
    10. sumBytes を返す。
  2. ? AtomicReadModifyWrite(ta, index, value, add) を返す。

25.4.5 Atomics.and ( ta, index, value )

この関数は呼び出されたとき、次の手順を実行します。

  1. and を、何も捕捉せず、パラメーター (xBytes, yBytes) を持ち、呼び出されたときに次の手順を atomic に実行する新しい read-modify-write modification function とする。
    1. ByteListBitwiseOp(&, xBytes, yBytes) を返す。
  2. ? AtomicReadModifyWrite(ta, index, value, and) を返す。

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

この関数は呼び出されたとき、次の手順を実行します。

  1. byteIndexInBuffer を ? ValidateAtomicAccessOnIntegerTypedArray(ta, index) とする。
  2. buffer を ta.[[ViewedArrayBuffer]] とする。
  3. block を buffer.[[ArrayBufferData]] とする。
  4. ta.[[ContentType]] が bigint である場合、
    1. expected を ? ToBigInt(expectedValue) とする。
    2. replacement を ? ToBigInt(replacementValue) とする。
  5. そうでない場合、
    1. expected を 𝔽(? ToIntegerOrInfinity(expectedValue)) とする。
    2. replacement を 𝔽(? ToIntegerOrInfinity(replacementValue)) とする。
  6. ? RevalidateAtomicAccess(ta, byteIndexInBuffer) を実行する。
  7. elementType を TypedArrayElementType(ta) とする。
  8. elementSize を TypedArrayElementSize(ta) とする。
  9. agentRecord を周囲の agent の Agent Record とする。
  10. isLittleEndian を agentRecord.[[LittleEndian]] とする。
  11. expectedBytes を NumericToRawBytes(elementType, expected, isLittleEndian) とする。
  12. replacementBytes を NumericToRawBytes(elementType, replacement, isLittleEndian) とする。
  13. IsSharedArrayBuffer(buffer) が true である場合、
    1. rawBytesRead を AtomicCompareExchangeInSharedBlock(block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes) とする。
  14. そうでない場合、
    1. rawBytesRead を、block[byteIndexInBuffer] から始まる elementSize byte の列を要素とする長さ elementSize の List とする。
    2. ByteListEqual(rawBytesRead, expectedBytes) が true である場合、
      1. replacementBytes の個々の byte を block[byteIndexInBuffer] から開始して block に保存する。
  15. RawBytesToNumeric(elementType, rawBytesRead, isLittleEndian) を返す。

25.4.7 Atomics.exchange ( ta, index, value )

この関数は呼び出されたとき、次の手順を実行します。

  1. second を、何も捕捉せず、パラメーター (oldBytes, newBytes) を持ち、呼び出されたときに次の手順を atomic に実行する新しい read-modify-write modification function とする。
    1. newBytes を返す。
  2. ? AtomicReadModifyWrite(ta, index, value, second) を返す。

25.4.8 Atomics.isLockFree ( size )

この関数は呼び出されたとき、次の手順を実行します。

  1. n を ? ToIntegerOrInfinity(size) とする。
  2. agentRecord を周囲の agent の Agent Record とする。
  3. n = 1 である場合、agentRecord.[[IsLockFree1]] を返す。
  4. n = 2 である場合、agentRecord.[[IsLockFree2]] を返す。
  5. n = 4 である場合、true を返す。
  6. n = 8 である場合、agentRecord.[[IsLockFree8]] を返す。
  7. false を返す。
注

この関数は最適化用プリミティブです。直感的には、サイズ n byte のデータに対する atomic プリミティブ(compareExchange、load、store、add、sub、and、or、xor、または exchange)の atomic な手順が、そのデータを構成する n byte の外側にあるロックを周囲の agent が取得することなく実行される場合、Atomics.isLockFree(n) は true を返します。高性能アルゴリズムは、この関数を使用して critical section でロックを使うか atomic 操作を使うかを判断します。atomic プリミティブが lock-free でない場合、アルゴリズム自身がロックを提供する方が効率的であることがよくあります。

Atomics.isLockFree(4) は、既知のすべての関連ハードウェアでサポートできるため、常に true を返します。これを仮定できることで、一般にプログラムを簡素化できます。

この関数が返す値に関係なく、すべての atomic 操作は atomic であることが保証されます。たとえば、操作の途中で観測可能な操作が発生する(例:「tearing」)ことは決してありません。

25.4.9 Atomics.load ( ta, index )

この関数は呼び出されたとき、次の手順を実行します。

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

25.4.10 Atomics.notify ( ta, index, count )

この関数は、wait queue 内でスリープしているいくつかの agent に通知します。

呼び出されたとき、次の手順を実行します。

  1. taRecord を ? ValidateIntegerTypedArray(ta, true) とする。
  2. byteIndexInBuffer を ? ValidateAtomicAccess(taRecord, index) とする。
  3. count が undefined である場合、
    1. count を +∞ に設定する。
  4. そうでない場合、
    1. intCount を ? ToIntegerOrInfinity(count) とする。
    2. count を max(intCount, 0) に設定する。
  5. buffer を ta.[[ViewedArrayBuffer]] とする。
  6. block を buffer.[[ArrayBufferData]] とする。
  7. IsSharedArrayBuffer(buffer) が false である場合、+0𝔽 を返す。
  8. waiterList を GetWaiterList(block, byteIndexInBuffer) とする。
  9. EnterCriticalSection(waiterList) を実行する。
  10. waiters を RemoveWaiters(waiterList, count) とする。
  11. waiters の各要素 waiterRecord について、次を行う。
    1. NotifyWaiter(waiterList, waiterRecord) を実行する。
  12. LeaveCriticalSection(waiterList) を実行する。
  13. waitersCount を waiters の要素数とする。
  14. 𝔽(waitersCount) を返す。

25.4.11 Atomics.or ( ta, index, value )

この関数は呼び出されたとき、次の手順を実行します。

  1. or を、何も捕捉せず、パラメーター (xBytes, yBytes) を持ち、呼び出されたときに次の手順を atomic に実行する新しい read-modify-write modification function とする。
    1. ByteListBitwiseOp(|, xBytes, yBytes) を返す。
  2. ? AtomicReadModifyWrite(ta, index, value, or) を返す。

25.4.12 Atomics.pause ( )

この関数は、プログラムが値を待ちながらスピンループしていることを CPU に示すヒントを提供します。

呼び出されたとき、次の手順を実行します。

  1. ECMAScript 実装の実行環境が、現在実行中のコードがスピン待機ループ内にあることをオペレーティングシステムまたは CPU に通知することをサポートしている場合、その通知を送る。
  2. undefined を返す。
注 1

このメソッドは、mutex 内の spinlock fast path など、スピン待機ループを実装するプログラムが、値を待ちながらスピンしていることを CPU に示すヒントを提供するために設計されています。タイミング以外の観測可能な動作はありません。

基礎となるアーキテクチャのベストプラクティスがスピンループ内で pause または yield 命令を推奨している場合、実装はそのような命令を実装することが期待されます。たとえば、Intel Optimization Manual は pause 命令を推奨しています。

実装には、一時停止する最大時間について、数十から数百ナノ秒程度の内部上限を設けることが推奨されます。

注 2

関数呼出しのオーバーヘッドにより、最適化コンパイラー内でインライン化されたこのメソッドの呼出しが、インライン化されていない呼出しとは異なる時間待機することは合理的です。

25.4.13 Atomics.store ( ta, index, value )

この関数は呼び出されたとき、次の手順を実行します。

  1. byteIndexInBuffer を ? ValidateAtomicAccessOnIntegerTypedArray(ta, index) とする。
  2. ta.[[ContentType]] が bigint である場合、coerced を ? ToBigInt(value) とする。
  3. そうでない場合、coerced を 𝔽(? ToIntegerOrInfinity(value)) とする。
  4. ? RevalidateAtomicAccess(ta, byteIndexInBuffer) を実行する。
  5. buffer を ta.[[ViewedArrayBuffer]] とする。
  6. elementType を TypedArrayElementType(ta) とする。
  7. SetValueInBuffer(buffer, byteIndexInBuffer, elementType, coerced, true, seq-cst) を実行する。
  8. coerced を返す。

25.4.14 Atomics.sub ( ta, index, value )

この関数は呼び出されたとき、次の手順を実行します。

  1. subtract を、ta を捕捉し、パラメーター (xBytes, yBytes) を持ち、呼び出されたときに次の手順を atomic に実行する新しい read-modify-write modification function とする。
    1. type を TypedArrayElementType(ta) とする。
    2. agentRecord を周囲の agent の Agent Record とする。
    3. isLittleEndian を agentRecord.[[LittleEndian]] とする。
    4. x を RawBytesToNumeric(type, xBytes, isLittleEndian) とする。
    5. y を RawBytesToNumeric(type, yBytes, isLittleEndian) とする。
    6. x が Number である場合、
      1. difference を Number::subtract(x, y) とする。
    7. そうでない場合、
      1. 表明: x は BigInt である。
      2. difference を BigInt::subtract(x, y) とする。
    8. differenceBytes を NumericToRawBytes(type, difference, isLittleEndian) とする。
    9. 表明: differenceBytes、xBytes、および yBytes は同じ要素数を持つ。
    10. differenceBytes を返す。
  2. ? AtomicReadModifyWrite(ta, index, value, subtract) を返す。

25.4.15 Atomics.wait ( ta, index, value, timeout )

この関数は周囲の agent を wait queue に入れて、通知されるか待機が timeout するまで一時停止し、それらのケースを区別する String を返します。

呼び出されたとき、次の手順を実行します。

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

25.4.16 Atomics.waitAsync ( ta, index, value, timeout )

この関数は、呼出し元の agent が通知されるか timeout に達したときに解決される Promise を返します。

呼び出されたとき、次の手順を実行します。

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

25.4.17 Atomics.xor ( ta, index, value )

この関数は呼び出されたとき、次の手順を実行します。

  1. xor を、何も捕捉せず、パラメーター (xBytes, yBytes) を持ち、呼び出されたときに次の手順を atomic に実行する新しい read-modify-write modification function とする。
    1. ByteListBitwiseOp(^, xBytes, yBytes) を返す。
  2. ? AtomicReadModifyWrite(ta, index, value, xor) を返す。

25.4.18 Atomics [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティの初期値は String 値 "Atomics" です。

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

25.5 JSON オブジェクト

JSON オブジェクトは:

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

JSON Data Interchange Format は ECMA-404 で定義されています。この仕様で使用される JSON interchange format は、ECMA-404 で説明されるものと正確に同じです。JSON.parse および JSON.stringify の適合実装は、形式への削除または拡張を行うことなく、ECMA-404 で説明される正確な interchange format をサポートしなければなりません。

25.5.1 JSON.isRawJSON ( obj )

この関数は呼び出されたとき、次の手順を実行します。

  1. obj が Object であり、obj が [[IsRawJSON]] 内部スロットを持つ場合、true を返す。
  2. false を返す。

25.5.2 JSON.parse ( text [ , reviver ] )

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

省略可能な reviver パラメーターは、結果をフィルターおよび変換できる関数です。解析によって生成された各値について、reviver は3つの引数(関連付けられたプロパティキー、値、および context オブジェクト)で呼び出されます。プロパティが変更されておらず、その値がプリミティブである場合、提供される context オブジェクトは、対応する Parse Node のソーステキストを含む "source" プロパティを持ちます。呼出しが undefined を返した場合、そのプロパティは削除されます。そうでない場合、そのプロパティは戻り値を使用するよう再定義されます。

  1. jsonString を ? ToString(text) とする。
  2. parseResult を ? ParseJSON(jsonString) とする。
  3. unfiltered を parseResult.[[Value]] とする。
  4. IsCallable(reviver) が false である場合、unfiltered を返す。
  5. root を OrdinaryObjectCreate(%Object.prototype%) とする。
  6. rootName を空の String とする。
  7. ! CreateDataPropertyOrThrow(root, rootName, unfiltered) を実行する。
  8. snapshot を CreateJSONParseRecord(parseResult.[[ParseNode]], rootName, unfiltered) とする。
  9. ? InternalizeJSONProperty(root, rootName, reviver, snapshot) を返す。

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

25.5.2.1 ParseJSON ( text )

抽象操作 ParseJSON。引数 text (String)。戻り値:(正常完了 (値:レコード (フィールド:[[ParseNode]] (構文解析ノード), [[Value]] (ECMAScript 言語値))) または throw 完了)。 呼び出されると、次の手順を実行する。

  1. StringToCodePoints(text) が ECMA-404 で規定される有効な JSON テキストでない場合、SyntaxError 例外をスローする。
  2. scriptString を "("、text、および ");" の文字列連結とする。
  3. script を ParseText(scriptString, Script) とする。
  4. 注記: 13.2.5.1 で定義される early error 規則には、上記の ParseText 呼出しに対する特別な処理がある。
  5. 表明: script は Parse Node である。
  6. result を ! script の Evaluation とする。
  7. 注記: 13.2.5.6 で定義される PropertyDefinitionEvaluation の意味論には、上記の評価に対する特別な処理がある。
  8. 表明: result は String、Number、Boolean、ArrayLiteral または ObjectLiteral のいずれかによって定義される Object、または null のいずれかである。
  9. Record { [[ParseNode]]: script, [[Value]]: result } を返す。

JSON.parse の適合実装が JSON 文法を拡張することは許可されません。実装が変更または拡張された JSON interchange format をサポートしたい場合、別の parse 関数を定義することによって行わなければなりません。

注 1

有効な JSON テキストは ECMAScript PrimaryExpression 構文の部分集合です。手順 1 は jsonString がその部分集合に適合することを検証し、手順 8 は評価が適切な型の値を返すことを表明します。

ただし、13.2.5.6 は ParseJSON の間では異なる動作をするため、同じソーステキストでも JSON としてではなく PrimaryExpression として評価した場合に異なる結果を生成する可能性があります。さらに、object literal における重複する "__proto__" プロパティに対する Early Error も ParseJSON の間には適用されないため、ParseJSON によって受理されるすべてのテキストが、文法に一致していても PrimaryExpression として有効とは限りません。

注 2

オブジェクト内に重複する名前の String が存在する場合、同じキーについて字句的に先行する値は上書きされなければなりません。

25.5.2.2 JSON Parse Record

JSON Parse Record は、JSON テキストから解析された値の初期状態を記述するために使用される Record です。

JSON Parse Record は 表 76 に列挙されるフィールドを持ちます。

表 76: JSON Parse Record のフィールド
フィールド名 値 意味
[[ParseNode]] a Parse Node context の Parse Node。
[[Key]] a property name [[Value]] が関連付けられているプロパティ名。
[[Value]] an ECMAScript language value [[ParseNode]] の評価によって生成された値。
[[Elements]] a List of JSON Parse Records [[Value]] が Array である場合、[[Value]] の要素に対応する JSON Parse Record を含みます。そうでない場合、空の List です。
[[Entries]] a List of JSON Parse Records [[Value]] が Array でない Object である場合、[[Value]] のエントリに対応する JSON Parse Record を含みます。そうでない場合、空の List です。

25.5.2.3 CreateJSONParseRecord ( parseNode, key, value )

抽象操作 CreateJSONParseRecord。引数 parseNode (構文解析ノード)、key (プロパティ名) および value (ECMAScript 言語値)。戻り値:JSON Parseレコード。 JSON テキストから解析された parseNode と、その評価によって生成された value を再帰的に結合します。 呼び出されると、次の手順を実行する。

  1. typedValueNode を ShallowestContainedJSONValue(parseNode) とする。
  2. 表明: typedValueNode は empty でない。
  3. elements を新しい空の List とする。
  4. entries を新しい空の List とする。
  5. value が Object である場合、
    1. isArray を ! IsArray(value) とする。
    2. isArray が true である場合、
      1. 表明: typedValueNode は ArrayLiteral Parse Node である。
      2. contentNodes を typedValueNode の JSONArrayLiteralContentNodes とする。
      3. length を contentNodes の要素数とする。
      4. valueLength を ! LengthOfArrayLike(value) とする。
      5. 表明: valueLength は length である。
      6. index を 0 とする。
      7. index < length の間、次を繰り返す。
        1. propertyName を ! ToString(𝔽(index)) とする。
        2. elementParseRecord を CreateJSONParseRecord(contentNodes[index], propertyName, ! Get(value, propertyName)) とする。
        3. elementParseRecord を elements に追加する。
        4. index を index + 1 に設定する。
    3. そうでない場合、
      1. 表明: typedValueNode は ObjectLiteral Parse Node である。
      2. propertyNodes を typedValueNode の PropertyDefinitionNodes とする。
      3. 注記: value は JSON テキストから生成されており変更されていないため、そのすべてのプロパティキーは String であり、漏れなく列挙される。
      4. keys を ! EnumerableOwnProperties(value, key) とする。
      5. keys の各 String propertyKey について、次を行う。
        1. 注記: JSON テキストが単一のオブジェクトについて同じ名前を持つ複数の名前と値のペアを指定する場合({"a":"lost","a":"kept"} など)、結果として得られる ECMAScript オブジェクトの対応するプロパティの値は、その名前を持つ最後のペアによって規定される。
        2. propertyDefinition を empty とする。
        3. propertyNodes の各 Parse Node propertyNode について、次を行う。
          1. propertyName を propertyNode の PropName とする。
          2. propertyName が propertyKey である場合、propertyDefinition を propertyNode に設定する。
        4. 表明: propertyDefinition は PropertyDefinition : PropertyName : AssignmentExpression である。
        5. propertyValueNode を propertyDefinition の AssignmentExpression とする。
        6. entryParseRecord を CreateJSONParseRecord(propertyValueNode, propertyKey, ! Get(value, propertyKey)) とする。
        7. entryParseRecord を entries に追加する。
  6. そうでない場合、
    1. 表明: typedValueNode は ArrayLiteral Parse Node でも ObjectLiteral Parse Node でもない。
  7. JSON Parse Record { [[ParseNode]]: typedValueNode, [[Key]]: key, [[Value]]: value, [[Elements]]: elements, [[Entries]]: entries } を返す。

25.5.2.4 InternalizeJSONProperty ( holder, name, reviver, parseRecord )

抽象操作 InternalizeJSONProperty。引数 holder (Object)、name (String)、reviver (関数オブジェクト) および parseRecord ((JSON Parseレコード または empty))。戻り値:(正常完了 (値:ECMAScript 言語値) または throw 完了)。

注

このアルゴリズムは、[[Delete]] または CreateDataProperty のいずれかが false を返しても、意図的に例外をスローしません。

呼び出されたとき、次の手順を実行します。

  1. value を ? Get(holder, name) とする。
  2. context を OrdinaryObjectCreate(%Object.prototype%) とする。
  3. parseRecord が JSON Parse Record であり、SameValue(parseRecord.[[Value]], value) が true である場合、
    1. value が Object でない場合、
      1. parseNode を parseRecord.[[ParseNode]] とする。
      2. 表明: parseNode は ArrayLiteral Parse Node でも ObjectLiteral Parse Node でもない。
      3. sourceText を parseNode によってマッチされたソーステキストとする。
      4. ! CreateDataPropertyOrThrow(context, "source", CodePointsToString(sourceText)) を実行する。
    2. elementRecords を parseRecord.[[Elements]] とする。
    3. entryRecords を parseRecord.[[Entries]] とする。
  4. そうでない場合、
    1. elementRecords を新しい空の List とする。
    2. entryRecords を新しい空の List とする。
  5. value が Object である場合、
    1. isArray を ? IsArray(value) とする。
    2. isArray が true である場合、
      1. elementRecordsLength を elementRecords の要素数とする。
      2. length を ? LengthOfArrayLike(value) とする。
      3. index を 0 とする。
      4. index < length の間、次を繰り返す。
        1. propertyKey を ! ToString(𝔽(index)) とする。
        2. index < elementRecordsLength である場合、elementRecord を elementRecords[index] とする。そうでない場合、elementRecord を empty とする。
        3. newElement を ? InternalizeJSONProperty(value, propertyKey, reviver, elementRecord) とする。
        4. newElement が undefined である場合、
          1. ? value.[[Delete]](propertyKey) を実行する。
        5. そうでない場合、
          1. ? CreateDataProperty(value, propertyKey, newElement) を実行する。
        6. index を index + 1 に設定する。
    3. そうでない場合、
      1. keys を ? EnumerableOwnProperties(value, key) とする。
      2. keys の各 String propertyKey について、次を行う。
        1. entryRecords に entry.[[Key]] が propertyKey である要素 entry が存在する場合、entryRecord を entry とする。そうでない場合、entryRecord を empty とする。
        2. newElement を ? InternalizeJSONProperty(value, propertyKey, reviver, entryRecord) とする。
        3. newElement が undefined である場合、
          1. ? value.[[Delete]](propertyKey) を実行する。
        4. そうでない場合、
          1. ? CreateDataProperty(value, propertyKey, newElement) を実行する。
  6. ? Call(reviver, holder, « name, value, context ») を返す。

25.5.2.5 Static Semantics: ShallowestContainedJSONValue ( root )

抽象操作 ShallowestContainedJSONValue。引数 root (構文解析ノード)。戻り値:(構文解析ノード または empty)。 root を根とする parse tree の幅優先探索を実行し、JSON 値に対応する nonterminal のインスタンスである最初のノードを返します。そのようなノードがない場合は empty を返します。 呼び出されると、次の手順を実行する。

  1. activeFunc をアクティブな関数オブジェクトとする。
  2. 表明: activeFunc は JSON.parse 組込み関数オブジェクトである(JSON.parse を参照)。
  3. types を « NullLiteral, BooleanLiteral, NumericLiteral, StringLiteral, ArrayLiteral, ObjectLiteral, UnaryExpression » とする。
  4. unaryExpr を empty とする。
  5. queue を « root » とする。
  6. queue が空でない間、次を繰り返す。
    1. candidate を queue の最初の要素とする。
    2. queue から最初の要素を削除する。
    3. queuedChildren を false とする。
    4. types の各 nonterminal type について、次を行う。
      1. candidate が type のインスタンスである場合、
        1. 注記: JSON 文法では、number token は負の値を表す場合がある。ECMAScript では、否定は UnaryExpression が - に続いて派生 UnaryExpression を parse する単項操作として表される。
        2. type が UnaryExpression である場合、
          1. candidate の親が UnaryExpression Parse Node でない場合、unaryExpr を candidate に設定する。
        3. そうでなく、type が NumericLiteral である場合、
          1. 表明: candidate は unaryExpr 内に含まれる。
          2. unaryExpr を返す。
        4. そうでない場合、
          1. candidate を返す。
      2. queuedChildren が false、candidate が nonterminal のインスタンス、かつ candidate Contains type が true である場合、
        1. children を candidate の各子ノードを順番に含む List とする。
        2. queue を queue と children のリスト連結に設定する。
        3. queuedChildren を true に設定する。
  7. empty を返す。

25.5.2.6 Static Semantics: JSONArrayLiteralContentNodes

構文指向操作 JSONArrayLiteralContentNodes。引数なし。戻り値:リスト (要素:構文解析ノード)。 次の生成規則ごとに定義される。

ArrayLiteral : [ Elisionopt ] [ ElementList ] [ ElementList , Elisionopt ]
  1. 表明: Elision は存在しない。
  2. ElementList が存在しない場合、新しい空の List を返す。
  3. ElementList の JSONArrayLiteralContentNodes を返す。
ElementList : Elisionopt AssignmentExpression
  1. 表明: Elision は存在しない。
  2. « AssignmentExpression » を返す。
ElementList : ElementList , Elisionopt AssignmentExpression
  1. 表明: Elision は存在しない。
  2. elements を派生 ElementList の JSONArrayLiteralContentNodes とする。
  3. elements と « AssignmentExpression » のリスト連結を返す。
ElementList : Elisionopt SpreadElement ElementList , Elisionopt SpreadElement
  1. 注記: ECMA-404 で規定される JSON テキストには SpreadElement は含まれない。
  2. 表明: この手順には決して到達しない。

25.5.3 JSON.rawJSON ( text )

この関数は、文字列、数値、真偽値、または null 値の raw JSON テキストを表すオブジェクトを返します。

  1. jsonString を ? ToString(text) とする。
  2. jsonString が空の String である場合、SyntaxError 例外をスローする。
  3. jsonString の最初のコード単位が、ASCII 小文字コード単位(0x0061 から 0x007A まで、両端を含む)、ASCII 数字コード単位(0x0030 から 0x0039 まで、両端を含む)、0x0022 (QUOTATION MARK)、または 0x002D (HYPHEN-MINUS) のいずれでもない場合、SyntaxError 例外をスローする。
  4. jsonString の最後のコード単位が、ASCII 小文字コード単位(0x0061 から 0x007A まで、両端を含む)、ASCII 数字コード単位(0x0030 から 0x0039 まで、両端を含む)、または 0x0022 (QUOTATION MARK) のいずれでもない場合、SyntaxError 例外をスローする。
  5. parseResult を ? ParseJSON(jsonString) とする。
  6. 表明: parseResult.[[Value]] は String、Number、Boolean、または null のいずれかである。
  7. internalSlotsList を « [[IsRawJSON]] » とする。
  8. obj を OrdinaryObjectCreate(null, internalSlotsList) とする。
  9. ! CreateDataPropertyOrThrow(obj, "rawJSON", jsonString) を実行する。
  10. ! SetIntegrityLevel(obj, frozen) を実行する。
  11. obj を返す。

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

この関数は、ECMAScript 言語値を表す UTF-16 エンコードされた JSON 形式の String、または undefined を返します。3つのパラメーターを取ることができます。value パラメーターは ECMAScript 言語値であり、通常はオブジェクトまたは配列ですが、String、Boolean、Number、または null にすることもできます。省略可能な replacer パラメーターは、オブジェクトと配列が文字列化される方法を変更する関数、または文字列化するオブジェクトプロパティを選択する包含リストとして機能する String と Number の配列のいずれかです。省略可能な space パラメーターは String または Number であり、人間にとっての可読性を高めるために結果へ空白を挿入できます。

呼び出されたとき、次の手順を実行します。

  1. stack を新しい空の List とする。
  2. indent を空の String とする。
  3. propertyList を undefined とする。
  4. replacerFunc を undefined とする。
  5. replacer が Object である場合、
    1. IsCallable(replacer) が true である場合、
      1. replacerFunc を replacer に設定する。
    2. そうでない場合、
      1. isArray を ? IsArray(replacer) とする。
      2. isArray が true である場合、
        1. propertyList を新しい空の List に設定する。
        2. length を ? LengthOfArrayLike(replacer) とする。
        3. k を 0 とする。
        4. k < length の間、次を繰り返す。
          1. propertyKey を ! ToString(𝔽(k)) とする。
          2. propertyValue を ? Get(replacer, propertyKey) とする。
          3. item を undefined とする。
          4. propertyValue が String である場合、
            1. item を propertyValue に設定する。
          5. そうでなく、propertyValue が Number である場合、
            1. item を ! ToString(propertyValue) に設定する。
          6. そうでなく、propertyValue が Object である場合、
            1. propertyValue が [[StringData]] または [[NumberData]] 内部スロットを持つ場合、item を ? ToString(propertyValue) に設定する。
          7. item が undefined でなく、propertyList が item を含まない場合、
            1. item を propertyList に追加する。
          8. k を k + 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. spaceMV を min(10, spaceMV) に設定する。
    3. spaceMV < 1 である場合、gap を空の String とする。そうでない場合、gap をコード単位 0x0020 (SPACE) が spaceMV 回出現する String 値とする。
  8. そうでなく、space が String である場合、
    1. space の長さ ≤ 10 である場合、gap を space とする。そうでない場合、gap を space の 0 から 10 までの部分文字列とする。
  9. そうでない場合、
    1. gap を空の String とする。
  10. wrapper を OrdinaryObjectCreate(%Object.prototype%) とする。
  11. ! CreateDataPropertyOrThrow(wrapper, 空の String, value) を実行する。
  12. state を JSON Serialization Record { [[ReplacerFunction]]: replacerFunc, [[Stack]]: stack, [[Indent]]: indent, [[Gap]]: gap, [[PropertyList]]: propertyList } とする。
  13. ? SerializeJSONProperty(state, 空の String, wrapper) を返す。

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

注 1

JSON 構造は任意の深さまでネストできますが、非循環でなければなりません。value が循環構造であるか循環構造を含む場合、この関数は TypeError 例外をスローしなければなりません。次は文字列化できない値の例です。

a = [];
a[0] = a;
my_text = JSON.stringify(a); // これは TypeError をスローしなければならない。
注 2

記号的なプリミティブ値は次のように表現されます。

  • null 値は JSON テキスト内で String 値 "null" として表現されます。
  • undefined 値は表現されません。
  • true 値は JSON テキスト内で String 値 "true" として表現されます。
  • false 値は JSON テキスト内で String 値 "false" として表現されます。
注 3

String 値は QUOTATION MARK (") コード単位で囲まれます。コード単位 " および \ は \ 接頭辞によってエスケープされます。制御文字のコード単位はエスケープシーケンス \uHHHH、または短縮形 \b (BACKSPACE)、\f (FORM FEED)、\n (LINE FEED)、\r (CARRIAGE RETURN)、\t (CHARACTER TABULATION) に置き換えられます。

注 4

各有限 Number は、ToString(number) を呼び出した場合と同様に文字列化される。NaN、+∞𝔽、および -∞𝔽 は、String 値 "null" として表される。

注 5

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

注 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.4.1 JSON Serialization Record

JSON Serialization Record は、JSON 形式へのシリアライズを可能にするために使用される Record です。

JSON Serialization Record は 表 77 に列挙されるフィールドを持ちます。

表 77: JSON Serialization Record のフィールド
フィールド名 値 意味
[[ReplacerFunction]] a function object or undefined オブジェクトプロパティの置換値を提供できる関数(JSON.stringify の replacer パラメーターから)。
[[PropertyList]] either a List of Strings or undefined 非配列オブジェクトをシリアライズするときに含めるプロパティ名(JSON.stringify の replacer パラメーターから)。
[[Gap]] a String インデントの単位(JSON.stringify の space パラメーターから)。
[[Stack]] a List of Objects シリアライズ処理中のネストされたオブジェクトの集合。循環構造を検出するために使用されます。
[[Indent]] a String 現在のインデント。

25.5.4.2 SerializeJSONProperty ( state, key, holder )

抽象操作 SerializeJSONProperty。引数 state (JSON Serializationレコード)、key (String) および holder (Object)。戻り値:(正常完了 (値:(String または undefined)) または throw 完了)。 呼び出されると、次の手順を実行する。

  1. value を ? Get(holder, key) とする。
  2. value が Object または 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 が [[IsRawJSON]] 内部スロットを持つ場合、
      1. rawJSON を ! Get(value, "rawJSON") とする。
      2. 表明: rawJSON は String である。
      3. rawJSON を返す。
    2. value が [[NumberData]] 内部スロットを持つ場合、
      1. value を ? ToNumber(value) に設定する。
    3. それ以外で value が [[StringData]] 内部スロットを持つ場合、
      1. value を ? ToString(value) に設定する。
    4. それ以外で value が [[BooleanData]] 内部スロットを持つ場合、
      1. value を value.[[BooleanData]] に設定する。
    5. それ以外で value が [[BigIntData]] 内部スロットを持つ場合、
      1. value を value.[[BigIntData]] に設定する。
  5. value が null である場合、"null" を返す。
  6. value が true である場合、"true" を返す。
  7. value が false である場合、"false" を返す。
  8. value が String である場合、QuoteJSONString(value) を返す。
  9. value が Number である場合、
    1. value が有限 Number である場合、! ToString(value) を返す。
    2. "null" を返す。
  10. value が BigInt である場合、TypeError 例外を投げる。
  11. value が Object であり、IsCallable(value) が false である場合、
    1. isArray を ? IsArray(value) とする。
    2. isArray が true である場合、
      1. ? SerializeJSONArray(state, value) を返す。
    3. ? SerializeJSONObject(state, value) を返す。
  12. undefined を返す。

25.5.4.3 QuoteJSONString ( value )

抽象操作 QuoteJSONString。引数 value (String)。戻り値:String。 value を 0x0022 (QUOTATION MARK) コード単位で囲み、その内部の特定のその他のコード単位をエスケープします。この操作は、6.1.4 で説明されるように、value を UTF-16 エンコードされたコードポイントの列として解釈します。 呼び出されると、次の手順を実行する。

  1. product をコード単位 0x0022 (QUOTATION MARK) のみからなる String 値とする。
  2. StringToCodePoints(value) の各コードポイント codePoint について、次を行う。
    1. codePoint が 表 78 の「Code Point」列に列挙されている場合、
      1. product を product と、対応する行の「Escape Sequence」列で規定される codePoint のエスケープシーケンスとの文字列連結に設定する。
    2. そうでなく、codePoint の数値が 0x0020 (SPACE) より小さいか、codePoint が leading surrogate または trailing surrogate と同じ数値を持つ場合、
      1. unit を数値が codePoint の数値であるコード単位とする。
      2. product を product と UnicodeEscape(unit) の文字列連結に設定する。
    3. そうでない場合、
      1. product を product と UTF16EncodeCodePoint(codePoint) の文字列連結に設定する。
  3. product を product とコード単位 0x0022 (QUOTATION MARK) の文字列連結に設定する。
  4. product を返す。
表 78: JSON 単一文字エスケープシーケンス
コードポイント Unicode 文字名 エスケープシーケンス
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 )

抽象操作 UnicodeEscape。引数 codeUnit (コード単位)。戻り値:String。 codeUnit を Unicode エスケープシーケンスとして表現します。 呼び出されると、次の手順を実行する。

  1. n を codeUnit の数値とする。
  2. 表明: n ≤ 0xFFFF。
  3. hex を、小文字の16進数として書式設定された n の String 表現とする。
  4. コード単位 0x005C (REVERSE SOLIDUS)、"u"、および StringPad(hex, 4, "0", start) の文字列連結を返す。

25.5.4.5 SerializeJSONObject ( state, value )

抽象操作 SerializeJSONObject。引数 state (JSON Serializationレコード) および value (Object)。戻り値:(正常完了 (値:String) または throw 完了)。 オブジェクトをシリアライズします。 呼び出されると、次の手順を実行する。

  1. state.[[Stack]] が value を含む場合、構造が循環しているため TypeError 例外をスローする。
  2. value を state.[[Stack]] に追加する。
  3. stepBack を state.[[Indent]] とする。
  4. state.[[Indent]] を state.[[Indent]] と state.[[Gap]] の文字列連結に設定する。
  5. state.[[PropertyList]] が undefined でない場合、
    1. keys を state.[[PropertyList]] とする。
  6. そうでない場合、
    1. keys を ? EnumerableOwnProperties(value, key) とする。
  7. partial を新しい空の List とする。
  8. keys の各要素 propertyKey について、次を行う。
    1. stringP を ? SerializeJSONProperty(state, propertyKey, value) とする。
    2. stringP が undefined でない場合、
      1. member を QuoteJSONString(propertyKey) とする。
      2. member を member と ":" の文字列連結に設定する。
      3. state.[[Gap]] が空の String でない場合、
        1. member を member とコード単位 0x0020 (SPACE) の文字列連結に設定する。
      4. member を member と stringP の文字列連結に設定する。
      5. member を partial に追加する。
  9. partial が空である場合、
    1. final を "{}" とする。
  10. そうでない場合、
    1. state.[[Gap]] が空の String である場合、
      1. properties を、partial のすべての要素 String を連結し、隣接する各 String の組の間をコード単位 0x002C (COMMA) で区切って形成される String 値とする。最初の String の前にも最後の String の後にもコンマは挿入されない。
      2. final を "{"、properties、および "}" の文字列連結とする。
    2. そうでない場合、
      1. separator をコード単位 0x002C (COMMA)、コード単位 0x000A (LINE FEED)、および state.[[Indent]] の文字列連結とする。
      2. properties を、partial のすべての要素 String を連結し、隣接する各 String の組の間を separator で区切って形成される String 値とする。separator String は最初の String の前にも最後の String の後にも挿入されない。
      3. final を "{"、コード単位 0x000A (LINE FEED)、state.[[Indent]]、properties、コード単位 0x000A (LINE FEED)、stepBack、および "}" の文字列連結とする。
  11. state.[[Stack]] の最後の要素を削除する。
  12. state.[[Indent]] を stepBack に設定する。
  13. final を返す。

25.5.4.6 SerializeJSONArray ( state, value )

抽象操作 SerializeJSONArray。引数 state (JSON Serializationレコード) および value (Object)。戻り値:(正常完了 (値:String) または throw 完了)。 配列をシリアライズします。 呼び出されると、次の手順を実行する。

  1. state.[[Stack]] が value を含む場合、構造が循環しているため TypeError 例外をスローする。
  2. value を state.[[Stack]] に追加する。
  3. stepBack を state.[[Indent]] とする。
  4. state.[[Indent]] を state.[[Indent]] と state.[[Gap]] の文字列連結に設定する。
  5. partial を新しい空の List とする。
  6. length を ? LengthOfArrayLike(value) とする。
  7. index を 0 とする。
  8. index < length の間、次を繰り返す。
    1. stringP を ? SerializeJSONProperty(state, ! ToString(𝔽(index)), value) とする。
    2. stringP が undefined である場合、
      1. "null" を partial に追加する。
    3. そうでない場合、
      1. stringP を partial に追加する。
    4. index を index + 1 に設定する。
  9. partial が空である場合、
    1. final を "[]" とする。
  10. そうでない場合、
    1. state.[[Gap]] が空の String である場合、
      1. properties を、partial のすべての要素 String を連結し、隣接する各 String の組の間をコード単位 0x002C (COMMA) で区切って形成される String 値とする。最初の String の前にも最後の String の後にもコンマは挿入されない。
      2. final を "["、properties、および "]" の文字列連結とする。
    2. そうでない場合、
      1. separator をコード単位 0x002C (COMMA)、コード単位 0x000A (LINE FEED)、および state.[[Indent]] の文字列連結とする。
      2. properties を、partial のすべての要素 String を連結し、隣接する各 String の組の間を separator で区切って形成される String 値とする。separator String は最初の String の前にも最後の String の後にも挿入されない。
      3. final を "["、コード単位 0x000A (LINE FEED)、state.[[Indent]]、properties、コード単位 0x000A (LINE FEED)、stepBack、および "]" の文字列連結とする。
  11. state.[[Stack]] の最後の要素を削除する。
  12. state.[[Indent]] を stepBack に設定する。
  13. final を返す。
注

配列の表現には、+0𝔽(含む)から array.length(含まない)までの区間にある要素のみが含まれます。キーが配列インデックスでないプロパティは文字列化から除外されます。配列は開始 LEFT SQUARE BRACKET、COMMA で区切られた要素、および終了 RIGHT SQUARE BRACKET として文字列化されます。

25.5.5 JSON [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティの初期値は String 値 "JSON" です。

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