페이지 표시 설정

25 구조화된 데이터

25.1 ArrayBuffer 객체

25.1.1 표기법

이 절, 25.4, 29의 아래 설명에서는 read-modify-write 수정 함수 내부 데이터 구조를 사용합니다.

read-modify-write 수정 함수는 바이트 값의 두 List를 인수로 받고 바이트 값의 List를 반환하는 Abstract Closure로 표현되는 수학적 함수입니다. 이러한 Abstract Closure는 다음 프로퍼티를 모두 만족합니다:

  • 모든 알고리즘 단계를 원자적으로 수행합니다.
  • 개별 알고리즘 단계는 관찰할 수 없습니다.
참고

read-modify-write 수정 함수의 알고리즘 단계가 순수한 수학적 함수를 구성하는지 검증하는 데 도움이 되도록 다음 편집 관례를 권장합니다:

25.1.2 고정 길이 및 크기 조절 가능한 ArrayBuffer 객체

고정 길이 ArrayBuffer는 생성된 후 바이트 길이를 변경할 수 없는 ArrayBuffer입니다.

크기 조절 가능한 ArrayBuffer는 ArrayBuffer.prototype.resize ( newLength ) 호출을 통해 생성 후 바이트 길이를 변경할 수 있는 ArrayBuffer입니다.

생성되는 ArrayBuffer 객체의 종류는 ArrayBuffer ( length [ , options ] )에 전달되는 인수에 따라 달라집니다.

25.1.3 ArrayBuffer 객체를 위한 추상 연산

25.1.3.1 AllocateArrayBuffer ( 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 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 인스턴스를 분리하면 기반 저장소로 사용되는 Data Block을 인스턴스와 분리하고 버퍼의 바이트 길이를 0으로 설정합니다.

25.1.3.6 CloneArrayBuffer ( sourceBuffer, sourceByteOffset, sourceLength )

추상 연산 CloneArrayBuffer. 인수 sourceBuffer ((ArrayBuffer 또는 SharedArrayBuffer)), sourceByteOffset (음이 아닌 정수) 및 sourceLength (음이 아닌 정수). 반환값: (정상 완료 (값: ArrayBuffer) 또는 throw 완료). sourceByteOffset에서 시작하여 sourceLength 바이트 동안의 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의 구현은 다음 요구 사항을 준수해야 합니다:

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의 바이트 요소를 연결하고 IEEE 754-2019 binary16 값의 리틀 엔디언 비트 문자열 인코딩으로 해석한 값으로 둡니다.
    2. value가 NaN이면 NaN을 반환합니다.
    3. value에 대응하는 Number 값을 반환합니다.
  4. type이 float32이면, 다음을 수행합니다.
    1. value를 rawBytes의 바이트 요소를 연결하고 IEEE 754-2019 binary32 값의 리틀 엔디언 비트 문자열 인코딩으로 해석한 값으로 둡니다.
    2. value가 NaN이면 NaN을 반환합니다.
    3. value에 대응하는 Number 값을 반환합니다.
  5. type이 float64이면, 다음을 수행합니다.
    1. value를 rawBytes의 바이트 요소를 연결하고 IEEE 754-2019 binary64 값의 리틀 엔디언 비트 문자열 인코딩으로 해석한 값으로 둡니다.
    2. value가 NaN이면 NaN을 반환합니다.
    3. value에 대응하는 Number 값을 반환합니다.
  6. IsUnsignedElementType(type)이 true이면, 다음을 수행합니다.
    1. intValue를 rawBytes의 바이트 요소를 연결하고 부호 없는 리틀 엔디언 이진수의 비트 문자열 인코딩으로 해석한 값으로 둡니다.
  7. 그렇지 않으면,
    1. intValue를 rawBytes의 바이트 요소를 연결하고 비트 길이가 elementSize × 8인 이진 리틀 엔디언 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 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를 요소가 비결정적으로 선택된 바이트 값인 길이 elementSize의 List로 둡니다.
  7. 참고: 구현체에서 rawValue는 기반 하드웨어의 비원자적 또는 원자적 읽기 명령 결과입니다. 비결정성은 약한 일관성을 갖는 하드웨어의 관찰 가능한 동작을 설명하기 위한 메모리 모델의 의미론적 규정입니다.
  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 값을 표현하기에 충분한 바이트가 있습니다.
  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의 바이트를 요소로 갖는 List로 둡니다.
  7. 단언: rawValue의 요소 수는 elementSize입니다.
  8. isLittleEndian이 존재하지 않으면, 다음을 수행합니다.
    1. agentRecord를 주변 에이전트의 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바이트를 요소로 갖는 List로 둡니다. 바이트는 리틀 엔디언 순서로 배열됩니다. value가 NaN이면 rawBytes를 구현체가 선택한 임의의 IEEE 754-2019 binary16 형식 NaN 인코딩으로 설정할 수 있습니다. 구현체는 구현체에서 구별 가능한 각 NaN 값에 대해 항상 동일한 인코딩을 선택해야 합니다.
  2. 그렇지 않고 type이 float32이면, 다음을 수행합니다.
    1. rawBytes를 roundTiesToEven 모드를 사용하여 value를 IEEE 754-2019 binary32 형식으로 변환한 결과인 4바이트를 요소로 갖는 List로 둡니다. 바이트는 리틀 엔디언 순서로 배열됩니다. value가 NaN이면 rawBytes를 구현체가 선택한 임의의 IEEE 754-2019 binary32 형식 NaN 인코딩으로 설정할 수 있습니다. 구현체는 구현체에서 구별 가능한 각 NaN 값에 대해 항상 동일한 인코딩을 선택해야 합니다.
  3. 그렇지 않고 type이 float64이면, 다음을 수행합니다.
    1. rawBytes를 value의 IEEE 754-2019 binary64 형식 인코딩인 8바이트를 요소로 갖는 List로 둡니다. 바이트는 리틀 엔디언 순서로 배열됩니다. 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바이트 이진 인코딩을 요소로 갖는 List로 둡니다. 바이트는 리틀 엔디언 순서로 배열됩니다.
    5. 그렇지 않으면,
      1. rawBytes를 intValue의 n바이트 이진 2의 보수 인코딩을 요소로 갖는 List로 둡니다. 바이트는 리틀 엔디언 순서로 배열됩니다.
  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 값을 표현하기에 충분한 바이트가 있습니다.
  3. 단언: IsBigIntElementType(type)이 true이면 value는 BigInt이고, 그렇지 않으면 value는 Number입니다.
  4. block을 arrayBuffer.[[ArrayBufferData]]로 둡니다.
  5. elementSize를 Element Type type에 대해 표 71에 지정된 Element Size 값으로 둡니다.
  6. agentRecord를 주변 에이전트의 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의 개별 바이트를 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 값을 표현하기에 충분한 바이트가 있습니다.
  3. 단언: IsBigIntElementType(type)이 true이면 value는 BigInt이고, 그렇지 않으면 value는 Number입니다.
  4. block을 arrayBuffer.[[ArrayBufferData]]로 둡니다.
  5. elementSize를 Element Type type에 대해 표 71에 지정된 Element Size 값으로 둡니다.
  6. agentRecord를 주변 에이전트의 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를 요소가 비결정적으로 선택된 바이트 값인 길이 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개의 바이트 시퀀스를 요소로 갖는 길이 elementSize의 List로 둡니다.
    2. rawBytesModified를 op(rawBytesRead, rawBytes)로 둡니다.
    3. rawBytesModified의 개별 바이트를 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 프로토타입 객체입니다.

이 프로퍼티는 { [[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 프로토타입 객체의 프로퍼티

ArrayBuffer 프로토타입 객체는:

  • %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가 분리되거나 크기가 조절되었을 수 있습니다.
  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 프로토타입 객체에서 프로퍼티를 상속합니다. 각 ArrayBuffer 인스턴스에는 [[ArrayBufferData]] 내부 슬롯, [[ArrayBufferByteLength]] 내부 슬롯, [[ArrayBufferDetachKey]] 내부 슬롯이 있습니다. 크기 조절 가능한 각 ArrayBuffer 인스턴스에는 [[ArrayBufferMaxByteLength]] 내부 슬롯도 있습니다.

[[ArrayBufferData]]가 null인 ArrayBuffer 인스턴스는 분리된 것으로 간주되며, ArrayBuffer 인스턴스에 포함된 데이터에 접근하거나 수정하는 모든 연산자는 실패합니다.

[[ArrayBufferDetachKey]]가 undefined 이외의 값으로 설정된 ArrayBuffer 인스턴스는 모든 DetachArrayBuffer 호출에서 동일한 “detach key”를 인수로 전달해야 하며, 그렇지 않으면 TypeError가 발생합니다. 이 내부 슬롯은 이 명세의 알고리즘이 아니라 특정 임베딩 환경에 의해서만 설정됩니다.

25.1.8 크기 조절 가능한 ArrayBuffer 지침

참고 1

다음은 크기 조절 가능한 ArrayBuffer를 사용하는 ECMAScript 프로그래머를 위한 지침입니다.

가능한 경우 프로그램을 배포 환경에서 테스트할 것을 권장합니다. 사용 가능한 물리 메모리의 양은 하드웨어 장치마다 크게 다릅니다. 마찬가지로 가상 메모리 하위 시스템도 하드웨어 장치와 운영 체제에 따라 크게 다릅니다. 64비트 데스크톱 웹 브라우저에서 메모리 부족 오류 없이 실행되는 애플리케이션이 32비트 모바일 웹 브라우저에서는 메모리 부족이 발생할 수 있습니다.

크기 조절 가능한 ArrayBuffer의 "maxByteLength" 옵션 값을 선택할 때는 애플리케이션에 가능한 가장 작은 크기를 선택할 것을 권장합니다. "maxByteLength"가 1,073,741,824(230바이트 또는 1GiB)를 초과하지 않을 것을 권장합니다.

특정 최대 크기로 크기 조절 가능한 ArrayBuffer를 성공적으로 생성했다고 해서 이후의 크기 조절도 성공한다는 보장은 없다는 점에 유의하시기 바랍니다.

참고 2

다음은 크기 조절 가능한 ArrayBuffer를 구현하는 ECMAScript 구현자를 위한 지침입니다.

크기 조절 가능한 ArrayBuffer는 크기 조절 시 복사하는 방식, 가상 메모리를 미리 예약하여 제자리 확장하는 방식, 또는 생성자의 "maxByteLength" 옵션 값에 따라 두 방식을 조합하여 구현할 수 있습니다.

웹 브라우저처럼 호스트가 다중 테넌트인 경우(즉, 여러 ECMAScript 애플리케이션을 동시에 실행하는 경우), 구현체가 가상 메모리를 예약하여 제자리 확장을 구현하기로 선택한다면 32비트와 64비트 구현 모두 "maxByteLength" ≥ 1GiB~1.5GiB인 값에 대해 예외를 던질 것을 권장합니다. 이는 하나의 애플리케이션이 가상 메모리 주소 공간을 고갈시킬 가능성을 줄이고 상호 운용성 위험을 줄이기 위한 것입니다.

MMU가 없는 임베디드 장치에서 실행되는 경우처럼 호스트에 가상 메모리가 없거나 호스트가 복사 방식으로만 크기 조절을 구현하는 경우 "maxByteLength" 옵션에 대해 임의의 Number value for 값을 허용할 수 있습니다. 그러나 요청한 크기의 메모리 블록을 절대로 할당할 수 없는 경우 RangeError를 던질 것을 권장합니다. 예를 들어 요청 크기가 장치에서 사용할 수 있는 최대 메모리 양보다 큰 경우입니다.

25.2 SharedArrayBuffer 객체

25.2.1 고정 길이 및 확장 가능한 SharedArrayBuffer 객체

고정 길이 SharedArrayBuffer는 생성된 후 바이트 길이를 변경할 수 없는 SharedArrayBuffer입니다.

확장 가능한 SharedArrayBuffer는 SharedArrayBuffer.prototype.grow ( newLength ) 호출을 통해 생성 후 바이트 길이를 늘릴 수 있는 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의 구현은 다음 요구 사항을 준수해야 합니다:

참고

위의 두 번째 요구 사항은 buffer의 현재 바이트 길이를 언제 또는 어떻게 읽는지 의도적으로 모호하게 규정합니다. 바이트 길이는 기반 하드웨어의 원자적 read-modify-write 연산을 통해 업데이트해야 하므로 load-link/store-conditional 또는 load-exclusive/store-exclusive 명령 쌍을 사용하는 아키텍처에서는 쌍을 이루는 명령을 명령 스트림에서 가까이 유지하고자 할 수 있습니다. 따라서 SharedArrayBuffer.prototype.grow ( newLength ) 자체는 HostGrowSharedArrayBuffer를 호출하기 전에 newByteLength에 대한 범위 검사를 수행하지 않으며 현재 바이트 길이를 언제 읽어야 하는지에 대한 요구 사항도 없습니다.

이는 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는 분리될 수 없으며 내부 [[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 프로토타입 객체입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } 속성을 갖습니다.

25.2.4.2 get SharedArrayBuffer [ %Symbol.species% ]

SharedArrayBuffer[%Symbol.species%]는 set 접근자 함수가 undefined인 접근자 프로퍼티입니다. get 접근자 함수는 호출되면 다음 단계를 수행합니다:

  1. this 값을 반환합니다.

이 함수의 "name" 프로퍼티 값은 "get [Symbol.species]"입니다.

25.2.5 SharedArrayBuffer 프로토타입 객체의 프로퍼티

SharedArrayBuffer 프로토타입 객체는:

  • %SharedArrayBuffer.prototype%입니다.
  • 값이 %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 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 바이트로 구성된 새로운 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)가 항상 후보 실행에 추가됩니다.

SharedArrayBuffer.prototype.grow의 병렬 호출은 전순서화됩니다. 예를 들어 서로 경합하는 두 호출 sab.grow(10)과 sab.grow(20)을 생각해 보십시오. 두 호출 중 하나가 반드시 경합에서 이깁니다. 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 프로토타입 객체에서 프로퍼티를 상속합니다. 각 SharedArrayBuffer 인스턴스에는 [[ArrayBufferData]] 내부 슬롯이 있습니다. 확장 가능하지 않은 각 SharedArrayBuffer 인스턴스에는 [[ArrayBufferByteLength]] 내부 슬롯이 있습니다. 확장 가능한 각 SharedArrayBuffer 인스턴스에는 [[ArrayBufferByteLengthData]] 내부 슬롯과 [[ArrayBufferMaxByteLength]] 내부 슬롯이 있습니다.

참고

SharedArrayBuffer 인스턴스는 ArrayBuffer 인스턴스와 달리 절대 분리되지 않습니다.

25.2.7 확장 가능한 SharedArrayBuffer 지침

참고 1

다음은 확장 가능한 SharedArrayBuffer를 사용하는 ECMAScript 프로그래머를 위한 지침입니다.

가능한 경우 프로그램을 배포 환경에서 테스트할 것을 권장합니다. 사용 가능한 물리 메모리의 양은 하드웨어 장치마다 크게 다릅니다. 마찬가지로 가상 메모리 하위 시스템도 하드웨어 장치와 운영 체제에 따라 크게 다릅니다. 64비트 데스크톱 웹 브라우저에서 메모리 부족 오류 없이 실행되는 애플리케이션이 32비트 모바일 웹 브라우저에서는 메모리 부족이 발생할 수 있습니다.

확장 가능한 SharedArrayBuffer의 "maxByteLength" 옵션 값을 선택할 때는 애플리케이션에 가능한 가장 작은 크기를 선택할 것을 권장합니다. "maxByteLength"가 1073741824, 즉 1GiB를 초과하지 않을 것을 권장합니다.

특정 최대 크기로 확장 가능한 SharedArrayBuffer를 성공적으로 생성했다고 해서 이후의 확장도 성공한다는 보장은 없다는 점에 유의하시기 바랍니다.

확장 가능한 SharedArrayBuffer의 길이를 읽는 모든 로드가 동기화 seq-cst 로드는 아닙니다. 예를 들어 u8[idx]와 같은 정수 인덱스 프로퍼티 접근의 범위 검사를 위한 길이 로드는 동기화되지 않습니다. 일반적으로 명시적 동기화가 없으면 한 프로퍼티 접근이 범위 안에 있다는 사실이 동일한 에이전트의 이후 프로퍼티 접근도 범위 안에 있음을 의미하지 않습니다. 반대로 SharedArrayBuffer, %TypedArray%.prototype, DataView.prototype의 length 및 byteLength getter를 통한 명시적 길이 로드는 동기화됩니다. TypedArray가 완전히 범위를 벗어났는지 검사하기 위해 내장 메서드가 수행하는 길이 로드도 동기화됩니다.

참고 2

다음은 확장 가능한 SharedArrayBuffer를 구현하는 ECMAScript 구현자를 위한 지침입니다.

확장 가능한 SharedArrayBuffer는 가상 메모리를 미리 예약하여 제자리 확장하는 방식으로 구현할 것을 권장합니다.

확장 연산은 확장 가능한 SharedArrayBuffer에 대한 메모리 접근과 병렬로 발생할 수 있으므로 메모리 모델의 제약 조건은 순서 없는 접근조차 “찢어짐”이 발생하지 않도록 요구합니다(값의 비트가 서로 섞이지 않아야 합니다). 실제로 이는 확장 가능한 SharedArrayBuffer의 기반 데이터 블록을 전 세계를 중지하지 않고 복사하여 확장할 수 없음을 의미합니다. 구현 전략으로 전 세계를 중지하는 방식은 직렬화 지점을 도입하고 느리므로 권장하지 않습니다.

확장된 메모리는 병렬로 경합하는 접근을 포함하여 생성되는 순간부터 0으로 채워진 것으로 보여야 합니다. 이는 필요 시 0으로 채워지는 가상 메모리 페이지를 사용하거나, 메모리를 수동으로 0으로 채우는 경우 주의 깊은 동기화를 사용하여 달성할 수 있습니다.

확장 가능한 SharedArrayBuffer의 TypedArray 뷰에 대한 정수 인덱스 프로퍼티 접근은 확장 불가능한 SharedArrayBuffer의 TypedArray 뷰에 대한 접근과 유사하게 최적화할 수 있도록 의도됩니다. 이는 정수 인덱스 프로퍼티 로드가 기반 버퍼의 길이에 대해 동기화되지 않기 때문입니다(위의 프로그래머 지침 참조). 예를 들어 프로퍼티 접근의 범위 검사를 여전히 루프 밖으로 끌어올릴 수 있습니다.

MMU가 없는 임베디드 장치에서 실행되는 경우처럼 가상 메모리가 없는 호스트에서는 확장 가능한 SharedArrayBuffer를 복사 방식으로 구현하기가 실제로 어렵습니다. 이러한 호스트에서 확장 가능한 SharedArrayBuffer의 메모리 사용 동작은 가상 메모리를 갖는 호스트와 크게 다를 수 있습니다. 이러한 호스트는 사용자에게 메모리 사용 예상치를 명확히 전달해야 합니다.

25.3 DataView 객체

25.3.1 DataView 객체를 위한 추상 연산

25.3.1.1 DataView With Buffer Witness Records

DataView With Buffer Witness Record는 DataView와 뷰가 참조하는 버퍼의 캐시된 바이트 길이를 함께 캡슐화하는 데 사용되는 Record입니다. 뷰가 참조하는 버퍼가 확장 가능한 SharedArrayBuffer일 때 바이트 길이 데이터 블록에 대한 ReadSharedMemory 이벤트가 하나만 존재하도록 보장하는 데 도움을 주기 위해 사용됩니다.

DataView With Buffer Witness Records에는 표 73에 나열된 필드가 있습니다.

표 73: DataView With Buffer Witness Record 필드
필드 이름 값 의미
[[Object]] a DataView 버퍼의 바이트 길이를 로드하는 DataView 객체입니다.
[[CachedBufferByteLength]] a non-negative integer or detached Record가 생성될 때 객체의 [[ViewedArrayBuffer]]의 바이트 길이입니다.

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 인스턴스의 함수가 뷰의 버퍼에서 값을 가져오는 데 사용됩니다. 호출되면 다음 단계를 수행한다.

  1. ? RequireInternalSlot(view, [[DataView]])를 수행합니다.
  2. 단언: view에는 [[ViewedArrayBuffer]] 내부 슬롯이 있습니다.
  3. getIndex를 ? ToIndex(requestIndex)로 둡니다.
  4. isLittleEndian을 ToBoolean(isLittleEndian)으로 설정합니다.
  5. viewOffset을 view.[[ByteOffset]]으로 둡니다.
  6. viewRecord를 MakeDataViewWithBufferWitnessRecord(view, unordered)로 둡니다.
  7. 참고: view의 기반 버퍼가 확장 가능한 SharedArrayBuffer일 때 범위 검사는 동기화 연산이 아닙니다.
  8. IsViewOutOfBounds(viewRecord)가 true이면 TypeError 예외를 던집니다.
  9. viewSize를 GetViewByteLength(viewRecord)로 둡니다.
  10. 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 인스턴스의 함수가 뷰의 버퍼에 값을 저장하는 데 사용됩니다. 호출되면 다음 단계를 수행한다.

  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의 기반 버퍼가 확장 가능한 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 프로토타입 객체입니다.

이 프로퍼티는 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } 속성을 갖습니다.

25.3.4 DataView 프로토타입 객체의 프로퍼티

DataView 프로토타입 객체는:

  • %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 프로토타입 객체에서 프로퍼티를 상속하는 일반 객체입니다. 각 DataView 인스턴스에는 [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] 내부 슬롯이 있습니다.

참고

[[DataView]] 내부 슬롯의 값은 이 명세 안에서 사용되지 않습니다. 해당 내부 슬롯이 존재한다는 사실 자체가 명세에서 DataView 생성자를 사용하여 생성된 객체를 식별하는 데 사용됩니다.

25.4 Atomics 객체

Atomics 객체는:

  • %Atomics%입니다.
  • 전역 객체의 "Atomics" 프로퍼티의 초기 값입니다.
  • 일반 객체입니다.
  • 값이 %Object.prototype%인 [[Prototype]] 내부 슬롯을 갖습니다.
  • [[Construct]] 내부 메서드를 갖지 않으므로 new 연산자와 함께 생성자로 사용할 수 없습니다.
  • [[Call]] 내부 메서드를 갖지 않으므로 함수로 호출할 수 없습니다.

Atomics 객체는 공유 메모리 배열 셀에 대해 분할 불가능하게(원자적으로) 동작하는 함수와 에이전트가 기본 이벤트를 기다리고 디스패치하도록 하는 함수를 제공합니다. 규율 있게 사용하면 Atomics 함수는 공유 메모리를 통해 통신하는 다중 에이전트 프로그램이 병렬 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를 호출한 에이전트입니다.
[[PromiseCapability]] a PromiseCapability Record or blocking Atomics.waitAsync 호출을 나타내는 경우 결과 promise이며, 그렇지 않으면 blocking입니다.
[[TimeoutTime]] a non-negative extended mathematical value 타임아웃이 트리거될 수 있는 가장 이른 시간이며 시간 값을 사용하여 계산합니다.
[[Result]] "ok" or "timed-out" 호출의 반환 값입니다.

25.4.2 WaiterList Records

WaiterList Record는 Atomics.wait, Atomics.waitAsync, Atomics.notify를 통한 에이전트의 대기 및 알림을 설명하는 데 사용됩니다.

WaiterList Record에는 표 75에 나열된 필드가 있습니다.

표 75: WaiterList Record 필드
필드 이름 값 의미
[[Waiters]] a List of Waiter Records 이 WaiterList와 연결된 위치에서 대기 중인 Atomics.wait 또는 Atomics.waitAsync 호출입니다.
[[MostRecentLeaveEvent]] a Synchronize event or empty 임계 구역에서 가장 최근에 나간 이벤트이며, 임계 구역에 한 번도 들어간 적이 없으면 empty입니다.

동일한 agent signifier를 갖는 여러 Waiter Record가 하나의 WaiterList에 있을 수 있습니다.

에이전트 클러스터에는 WaiterList Records 저장소가 있습니다. 이 저장소는 (block, i)로 인덱싱되며, 여기서 block은 Shared Data Block이고 i는 block 메모리 안의 바이트 오프셋입니다. WaiterList Records는 에이전트와 독립적입니다. WaiterList Records 저장소에서 (block, i)로 조회하면 에이전트 클러스터의 어떤 에이전트에서도 동일한 WaiterList Record가 결과로 나옵니다.

각 WaiterList Record에는 평가 중 해당 WaiterList Record에 대한 배타적 접근을 제어하는 임계 구역이 있습니다. 한 번에 하나의 에이전트만 WaiterList Record의 임계 구역에 들어갈 수 있습니다. WaiterList Record의 임계 구역에 들어가고 나가는 것은 추상 연산 EnterCriticalSection 및 LeaveCriticalSection이 제어합니다. WaiterList Record에 대한 연산—대기 중인 에이전트 추가 및 제거, 에이전트 목록 순회, 목록의 에이전트 일시 중단 및 알림, Synchronize 이벤트 설정 및 가져오기—은 WaiterList Record의 임계 구역에 들어간 에이전트만 수행할 수 있습니다.

25.4.3 Atomics를 위한 추상 연산

25.4.3.1 ValidateIntegerTypedArray ( ta, waitable )

추상 연산 ValidateIntegerTypedArray. 인수 ta (ECMAScript 언어 값) 및 waitable (Boolean). 반환값: (정상 완료 (값: TypedArray With Buffer Witness 레코드) 또는 throw 완료). %Atomics% 함수와 함께 사용할 수 있는 TypedArray, 특히 공유 메모리와의 원자적 상호작용을 보장할 수 있는 TypedArray를 제한하는 데 사용됩니다. 호출되면 다음 단계를 수행한다.

  1. 참고: ta의 기반 버퍼가 확장 가능한 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 메서드에서 모든 인수 강제 변환이 수행된 후 원자적 연산을 위해 기반 버퍼 안의 인덱스를 다시 검증합니다. 인수 강제 변환은 임의의 부수 효과를 가질 수 있어 버퍼가 범위를 벗어나게 할 수 있기 때문입니다. 이 연산은 ta의 기반 버퍼가 SharedArrayBuffer인 경우 예외를 던지지 않습니다. 호출되면 다음 단계를 수행한다.

  1. 참고: ta의 기반 버퍼가 확장 가능한 SharedArrayBuffer인 경우, 경계 검사는 동기화 작업이 아닙니다.
  2. taRecord를 ? ValidateTypedArrayBounds(ta, unordered)로 설정합니다.
  3. 단언: byteIndexInBuffer ≥ ta.[[ByteOffset]].
  4. elementSize를 TypedArrayElementSize(ta)로 설정합니다.
  5. elementLastByteIndex를 byteIndexInBuffer + elementSize - 1로 설정합니다.
  6. elementLastByteIndex ≥ taRecord.[[CachedBufferByteLength]]이면 RangeError 예외를 던집니다.
  7. 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 메모리 안의 유효한 바이트 오프셋입니다.
  2. 쌍 (block, i)가 참조하는 WaiterList Record를 반환합니다.

25.4.3.6 EnterCriticalSection ( waiterList )

추상 연산 EnterCriticalSection. 인수 waiterList (WaiterList 레코드). 반환값: unused. 호출되면 다음 단계를 수행한다.

  1. 단언: 주변 에이전트는 어떤 WaiterList Record의 임계 구역에도 들어가 있지 않습니다.
  2. 어떤 에이전트도 waiterList의 임계 구역에 있지 않을 때까지 기다린 다음, 다른 에이전트가 들어가는 것을 허용하지 않고 waiterList의 임계 구역에 들어갑니다.
  3. waiterList.[[MostRecentLeaveEvent]]가 empty가 아니면, 다음을 수행합니다.
    1. 참고: 임계 구역에 한 번 이상 들어간 waiterList에는 LeaveCriticalSection이 설정한 Synchronize 이벤트가 있습니다.
    2. agentRecord를 주변 에이전트의 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은 임계 구역에 들어가려는 에이전트가 다른 에이전트가 나갈 때까지 기다려야 할 때 경합이 발생합니다. 경합이 없으면 EnterCriticalSection 호출의 FIFO 순서를 관찰할 수 있습니다. 경합이 있는 경우 구현체는 임의의 순서를 선택할 수 있지만 에이전트를 무기한 기다리게 해서는 안 됩니다.

25.4.3.7 LeaveCriticalSection ( waiterList )

추상 연산 LeaveCriticalSection. 인수 waiterList (WaiterList 레코드). 반환값: unused. 호출되면 다음 단계를 수행한다.

  1. 단언: 주변 에이전트는 waiterList의 임계 구역 안에 있습니다.
  2. agentRecord를 주변 에이전트의 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의 임계 구역에서 나갑니다.
  9. unused를 반환합니다.

25.4.3.8 AddWaiter ( waiterList, waiterRecord )

추상 연산 AddWaiter. 인수 waiterList (WaiterList 레코드) 및 waiterRecord (Waiter 레코드). 반환값: unused. 호출되면 다음 단계를 수행한다.

  1. 단언: 주변 에이전트는 waiterList의 임계 구역 안에 있습니다.
  2. 단언: waiterList.[[Waiters]]에는 [[PromiseCapability]] 필드가 waiterRecord.[[PromiseCapability]]이고 [[AgentSignifier]] 필드가 waiterRecord.[[AgentSignifier]]인 Waiter Record가 없습니다.
  3. waiterRecord를 waiterList.[[Waiters]]에 추가합니다.
  4. unused를 반환합니다.

25.4.3.9 RemoveWaiter ( waiterList, waiterRecord )

추상 연산 RemoveWaiter. 인수 waiterList (WaiterList 레코드) 및 waiterRecord (Waiter 레코드). 반환값: unused. 호출되면 다음 단계를 수행한다.

  1. 단언: 주변 에이전트는 waiterList의 임계 구역 안에 있습니다.
  2. 단언: waiterList.[[Waiters]]에는 waiterRecord가 포함되어 있습니다.
  3. waiterRecord를 waiterList.[[Waiters]]에서 제거합니다.
  4. unused를 반환합니다.

25.4.3.10 RemoveWaiters ( waiterList, count )

추상 연산 RemoveWaiters. 인수 waiterList (WaiterList 레코드) 및 count ((음이 아닌 정수 또는 +∞)). 반환값: 리스트 (요소: Waiter 레코드). 호출되면 다음 단계를 수행한다.

  1. 단언: 주변 에이전트는 waiterList의 임계 구역 안에 있습니다.
  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. 단언: 주변 에이전트는 waiterList의 임계 구역 안에 있습니다.
  2. 단언: waiterList.[[Waiters]]에는 waiterRecord가 포함되어 있습니다.
  3. thisAgent를 AgentSignifier()로 둡니다.
  4. 단언: waiterRecord.[[AgentSignifier]]는 thisAgent입니다.
  5. 단언: waiterRecord.[[PromiseCapability]]은 blocking입니다.
  6. 단언: AgentCanSuspend()는 true입니다.
  7. LeaveCriticalSection(waiterList)을 수행하고 시간이 waiterRecord.[[TimeoutTime]]이 될 때까지 주변 에이전트를 일시 중단합니다. 이 두 연산은 임계 구역을 나간 후 일시 중단이 실제로 적용되기 전에 도착한 알림이 유실되지 않는 방식으로 결합하여 수행합니다. 주변 에이전트는 타임아웃 또는 다른 에이전트가 waiterList와 thisAgent를 인수로 NotifyWaiter를 호출하는 경우에만 일시 중단에서 깨어날 수 있습니다(즉, Atomics.notify 호출을 통해).
  8. EnterCriticalSection(waiterList)을 수행합니다.
  9. unused를 반환합니다.

25.4.3.12 NotifyWaiter ( waiterList, waiterRecord )

추상 연산 NotifyWaiter. 인수 waiterList (WaiterList 레코드) 및 waiterRecord (Waiter 레코드). 반환값: unused. 호출되면 다음 단계를 수행한다.

  1. 단언: 주변 에이전트는 waiterList의 임계 구역 안에 있습니다.
  2. waiterRecord.[[PromiseCapability]]이 blocking이면, 다음을 수행합니다.
    1. signifier가 waiterRecord.[[AgentSignifier]]인 에이전트를 일시 중단에서 깨웁니다.
    2. 참고: 이로 인해 에이전트는 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를 반환합니다.
참고

에이전트는 다른 에이전트의 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. 참고: 동기식 즉시 타임아웃에는 특별한 처리가 없습니다. 비동기식 즉시 타임아웃은 빠르게 실패하고 불필요한 Promise job을 피하기 위해 특별히 처리됩니다.
    2. LeaveCriticalSection(waiterList)을 수행합니다.
    3. ! CreateDataPropertyOrThrow(resultObj, "async", false)를 수행합니다.
    4. ! CreateDataPropertyOrThrow(resultObj, "value", "timed-out")를 수행합니다.
    5. resultObj를 반환합니다.
  21. thisAgent를 AgentSignifier()로 둡니다.
  22. now를 현재 시간을 식별하는 시간 값(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은 전력 소비를 줄이거나 타이밍 공격을 완화하기 위해 타이머 해상도를 낮추는 등 필요한 경우 구현체가 타임아웃을 늘릴 수 있게 합니다. 이 값은 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을 현재 시간을 식별하는 시간 값(UTC)으로 둡니다.
      2. 단언: ℝ(timeOfJobExecution) ≥ waiterRecord.[[TimeoutTime]]입니다(시간 값의 잠재적인 비단조성은 무시합니다).
      3. waiterRecord.[[Result]]를 "timed-out"으로 설정합니다.
      4. RemoveWaiter(waiterList, waiterRecord)을 수행합니다.
      5. NotifyWaiter(waiterList, waiterRecord)을 수행합니다.
    3. LeaveCriticalSection(waiterList)을 수행합니다.
    4. unused를 반환합니다.
  2. now를 현재 시간을 식별하는 시간 값(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 Record로 둡니다.
  2. execution을 agentRecord.[[CandidateExecution]]으로 둡니다.
  3. eventsRecord를 [[AgentSignifier]]가 AgentSignifier()인 execution.[[EventsRecords]]의 Agent Events Record로 둡니다.
  4. rawBytesRead를 요소가 비결정적으로 선택된 바이트 값인 길이 elementSize의 List로 둡니다.
  5. 참고: 구현체에서 rawBytesRead는 기반 하드웨어의 load-link, load-exclusive 또는 read-modify-write 명령의 피연산자 결과입니다. 비결정성은 약한 일관성을 갖는 하드웨어의 관찰 가능한 동작을 설명하기 위한 메모리 모델의 의미론적 규정입니다.
  6. 참고: 기대 값과 읽은 값의 비교는 기대 값이 읽은 값과 같지 않을 때 불필요하게 강한 동기화를 피하기 위해 read-modify-write 수정 함수 밖에서 수행됩니다.
  7. ByteListEqual(rawBytesRead, expectedBytes)이 true이면, 다음을 수행합니다.
    1. second를 아무것도 캡처하지 않고 매개변수 (oldBytes, newBytes)를 가지며 호출될 때 다음 단계를 원자적으로 수행하는 새로운 read-modify-write 수정 함수로 둡니다:
      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는 바이트 값의 두 List 인수를 받고 바이트 값의 List를 반환합니다. 이 연산은 값을 원자적으로 로드하고 다른 값과 결합한 다음 결합 결과를 저장합니다. 로드한 값을 반환합니다. 호출되면 다음 단계를 수행한다.

  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 (리스트 (요소: 바이트 값)). 반환값: 리스트 (요소: 바이트 값). 이 연산은 인수의 모든 바이트 값에 대해 비트 연산을 원자적으로 수행하고 바이트 값의 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에 비트 단위 XOR(배타적 OR) 연산을 적용한 결과로 둡니다.
    4. 그렇지 않으면,
      1. 단언: op는 |입니다.
      2. resultByte를 xByte와 yByte에 비트 단위 OR(포괄적 OR) 연산을 적용한 결과로 둡니다.
    5. i를 i + 1로 설정합니다.
    6. result에 resultByte를 추가합니다.
  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)를 가지며 호출될 때 다음 단계를 원자적으로 수행하는 새로운 read-modify-write 수정 함수로 둡니다:
    1. type을 TypedArrayElementType(ta)로 둡니다.
    2. agentRecord를 주변 에이전트의 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)를 가지며 호출될 때 다음 단계를 원자적으로 수행하는 새로운 read-modify-write 수정 함수로 둡니다:
    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 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개의 바이트 시퀀스를 요소로 갖는 길이 elementSize의 List로 둡니다.
    2. ByteListEqual(rawBytesRead, expectedBytes)이 true이면, 다음을 수행합니다.
      1. replacementBytes의 개별 바이트를 block[byteIndexInBuffer]에서 시작하여 block에 저장합니다.
  15. RawBytesToNumeric(elementType, rawBytesRead, isLittleEndian)을 반환합니다.

25.4.7 Atomics.exchange ( ta, index, value )

이 함수는 호출되면 다음 단계를 수행합니다:

  1. second를 아무것도 캡처하지 않고 매개변수 (oldBytes, newBytes)를 가지며 호출될 때 다음 단계를 원자적으로 수행하는 새로운 read-modify-write 수정 함수로 둡니다:
    1. newBytes를 반환합니다.
  2. ? AtomicReadModifyWrite(ta, index, value, second)를 반환합니다.

25.4.8 Atomics.isLockFree ( size )

이 함수는 호출되면 다음 단계를 수행합니다:

  1. n을 ? ToIntegerOrInfinity(size)로 둡니다.
  2. agentRecord를 주변 에이전트의 Agent Record로 둡니다.
  3. n = 1이면 agentRecord.[[IsLockFree1]]을 반환합니다.
  4. n = 2이면 agentRecord.[[IsLockFree2]]를 반환합니다.
  5. n = 4이면 true를 반환합니다.
  6. n = 8이면 agentRecord.[[IsLockFree8]]을 반환합니다.
  7. false를 반환합니다.
참고

이 함수는 최적화 프리미티브입니다. 직관적으로 크기 n바이트인 데이터에 대한 원자적 프리미티브(compareExchange, load, store, add, sub, and, or, xor, exchange)의 원자적 단계가 데이터를 구성하는 n바이트 밖에서 주변 에이전트가 락을 획득하지 않고 수행된다면 Atomics.isLockFree(n)은 true를 반환합니다. 고성능 알고리즘은 이 함수를 사용하여 임계 구역에서 락을 사용할지 원자적 연산을 사용할지 결정합니다. 원자적 프리미티브가 lock-free가 아니면 알고리즘이 자체 락을 제공하는 것이 더 효율적인 경우가 많습니다.

Atomics.isLockFree(4)는 알려진 모든 관련 하드웨어에서 지원할 수 있으므로 항상 true를 반환합니다. 이를 가정할 수 있으면 일반적으로 프로그램을 단순화할 수 있습니다.

이 함수가 반환하는 값과 관계없이 모든 원자적 연산은 원자성이 보장됩니다. 예를 들어 연산 중간에 관찰 가능한 동작이 발생하는 일(예: “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 )

이 함수는 대기 큐에서 잠들어 있는 일부 에이전트에 알립니다.

호출되면 다음 단계를 수행합니다:

  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. IsSharedArrayBuffer(buffer)가 false이면, +0𝔽를 반환합니다.
  7. block을 buffer.[[ArrayBufferData]]로 설정합니다.
  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)를 가지며 호출될 때 다음 단계를 원자적으로 수행하는 새로운 read-modify-write 수정 함수로 둡니다:
    1. ByteListBitwiseOp(|, xBytes, yBytes)를 반환합니다.
  2. ? AtomicReadModifyWrite(ta, index, value, or)를 반환합니다.

25.4.12 Atomics.pause ( )

이 함수는 프로그램이 값을 기다리며 스핀 루프 중이라는 힌트를 CPU에 제공합니다.

호출되면 다음 단계를 수행합니다:

  1. ECMAScript 구현체의 실행 환경이 현재 실행 중인 코드가 스핀 대기 루프에 있다는 사실을 운영 체제나 CPU에 알리는 것을 지원하면 해당 신호를 보냅니다.
  2. undefined를 반환합니다.
참고 1

이 메서드는 mutex 내부의 spinlock 빠른 경로와 같은 스핀 대기 루프를 구현하는 프로그램이 값을 기다리며 스핀 중이라는 힌트를 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)를 가지며 호출될 때 다음 단계를 원자적으로 수행하는 새로운 read-modify-write 수정 함수로 둡니다:
    1. type을 TypedArrayElementType(ta)로 둡니다.
    2. agentRecord를 주변 에이전트의 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 )

이 함수는 주변 에이전트를 대기 큐에 넣고 알림을 받거나 대기 시간이 초과될 때까지 일시 중단한 다음, 이러한 경우를 구별하는 String을 반환합니다.

호출되면 다음 단계를 수행합니다:

  1. ? DoWait(sync, ta, index, value, timeout)를 반환합니다.

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

이 함수는 호출 에이전트가 알림을 받거나 타임아웃에 도달하면 이행되는 Promise를 반환합니다.

호출되면 다음 단계를 수행합니다:

  1. ? DoWait(async, ta, index, value, timeout)를 반환합니다.

25.4.17 Atomics.xor ( ta, index, value )

이 함수는 호출되면 다음 단계를 수행합니다:

  1. xor를 아무것도 캡처하지 않고 매개변수 (xBytes, yBytes)를 가지며 호출될 때 다음 단계를 원자적으로 수행하는 새로운 read-modify-write 수정 함수로 둡니다:
    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 텍스트를 파싱하고 구성하는 데 사용하는 두 함수 parse와 stringify를 포함합니다.
  • 값이 %Object.prototype%인 [[Prototype]] 내부 슬롯을 갖습니다.
  • [[Construct]] 내부 메서드를 갖지 않으므로 new 연산자와 함께 생성자로 사용할 수 없습니다.
  • [[Call]] 내부 메서드를 갖지 않으므로 함수로 호출할 수 없습니다.

JSON 데이터 교환 형식은 ECMA-404에 정의되어 있습니다. 이 명세에서 사용하는 JSON 교환 형식은 ECMA-404에 설명된 것과 정확히 같습니다. JSON.parse 및 JSON.stringify의 적합한 구현체는 형식에서 삭제하거나 확장하지 않고 ECMA-404에 설명된 정확한 교환 형식을 지원해야 합니다.

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 language value를 생성합니다. JSON 형식은 ECMAScript 리터럴, Array Initializer, Object Initializer의 구문과 유사한 구문으로 리터럴, 배열, 객체를 나타냅니다. 파싱 후 JSON 객체는 ECMAScript 객체로 실체화됩니다. JSON 배열은 ECMAScript Array 인스턴스로 실체화됩니다. JSON 문자열, 숫자, 불리언, null은 ECMAScript String, Number, Boolean, null로 실체화됩니다.

선택적 reviver 매개변수는 결과를 필터링하고 변환할 수 있는 함수입니다. 파싱으로 생성된 각 값에 대해 reviver는 세 인수(연결된 프로퍼티 키, 값, 컨텍스트 객체)로 호출됩니다. 프로퍼티가 수정되지 않았고 값이 프리미티브이면 제공된 컨텍스트 객체에는 대응하는 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를 ! Evaluation of script로 둡니다.
  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 교환 형식을 지원하려면 다른 parse 함수를 정의하여 수행해야 합니다.

참고 1

유효한 JSON 텍스트는 ECMAScript PrimaryExpression 구문의 부분집합입니다. 1 단계는 jsonString이 해당 부분집합을 준수하는지 검증하고, 8 단계는 평가가 적절한 타입의 값을 반환하는지 단언합니다.

그러나 13.2.5.6이 ParseJSON 중에는 다르게 동작하므로 동일한 소스 텍스트를 JSON이 아니라 PrimaryExpression으로 평가하면 다른 결과가 생성될 수 있습니다. 또한 객체 리터럴의 중복 "__proto__" 프로퍼티에 대한 Early Error 역시 ParseJSON 중에는 적용되지 않으므로, 문법과 일치하더라도 ParseJSON이 허용하는 모든 텍스트가 PrimaryExpression으로 유효한 것은 아닙니다.

참고 2

객체 안에 중복된 이름의 String이 있는 경우 어휘적으로 앞선 동일 키의 값은 덮어써야 합니다.

25.5.2.2 JSON Parse Record

JSON Parse Record는 JSON 텍스트에서 파싱된 값의 초기 상태를 설명하는 데 사용되는 Record입니다.

JSON Parse Records에는 표 76에 나열된 필드가 있습니다.

표 76: JSON Parse Record 필드
필드 이름 값 의미
[[ParseNode]] a Parse Node 컨텍스트 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 Records를 포함합니다. 그렇지 않으면 빈 List입니다.
[[Entries]] a List of JSON Parse Records [[Value]]가 Array가 아닌 Object이면 [[Value]]의 항목에 대응하는 JSON Parse Records를 포함합니다. 그렇지 않으면 빈 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에 [[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를 루트로 하는 파스 트리에 대해 너비 우선 탐색을 수행하고 JSON 값에 대응하는 비단말의 인스턴스인 첫 번째 노드를 반환하며, 그러한 노드가 없으면 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의 각 비단말 type에 대해 다음을 수행합니다.
      1. candidate가 type의 인스턴스이면, 다음을 수행합니다.
        1. 참고: JSON 문법에서 number 토큰은 음수 값을 나타낼 수 있습니다. ECMAScript에서 부정은 UnaryExpression이 - 뒤에 파생된 UnaryExpression이 오는 형태로 파싱되는 단항 연산으로 표현됩니다.
        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가 비단말의 인스턴스이며 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 값의 원시 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 language value를 나타내는 UTF-16 인코딩 JSON 형식의 String 또는 undefined를 반환합니다. 세 매개변수를 받을 수 있습니다. value 매개변수는 ECMAScript language value이며 일반적으로 객체 또는 배열이지만 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 Records에는 표 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 단일 문자 이스케이프 시퀀스
코드 포인트 유니코드 문자 이름 이스케이프 시퀀스
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을 유니코드 이스케이프 시퀀스로 나타냅니다. 호출되면 다음 단계를 수행한다.

  1. n을 codeUnit의 숫자 값으로 둡니다.
  2. 단언: n ≤ 0xFFFF입니다.
  3. hex를 n을 소문자 16진수로 형식화한 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 } 속성을 갖습니다.