25 구조화된 데이터 (Structured Data)

25.1 ArrayBuffer 객체

25.1.1 표기 (Notation)

본 절, 25.4, 그리고 29 에서의 아래 설명들은 read-modify-write 수정 함수 내부 데이터 구조를 사용한다.

read-modify-write 수정 함수란 두 개의 바이트 값 List 를 인수로 받고 바이트 값 List 를 반환하는 추상 클로저로 표현되는 수학적 함수이다. 이러한 추상 클로저는 다음 모든 성질을 만족한다:

  • 알고리즘 단계 전부를 원자적으로 수행한다.
  • 개별 알고리즘 단계는 관측 불가능하다.
Note

read-modify-write 수정 함수의 알고리즘 단계가 순수한 수학적 함수임을 검증하는 데 도움을 주기 위해 다음 편집 지침을 권장한다:

  • 직접 또는 호출된 추상 연산과 추상 클로저를 통한 간접 접근을 포함하여, 매개변수와 캡처된 값 외의 어떤 언어/명세 값에도 접근하지 않는다.
  • Completion Record 를 반환하는 추상 연산이나 추상 클로저를 직접 또는 간접으로 호출하지 않는다.
  • Completion Record 를 반환하지 않는다.

25.1.2 고정 길이 및 크기 변경 가능(ArrayBuffer) 객체

fixed-length ArrayBuffer 는 생성 후 바이트 길이가 변하지 않는 ArrayBuffer 이다.

resizable ArrayBufferArrayBuffer.prototype.resize ( newLength ) 호출을 통해 생성 후 바이트 길이가 변할 수 있는 ArrayBuffer 이다.

어떤 종류의 ArrayBuffer 객체가 생성되는지는 ArrayBuffer ( length [ , options ] ) 에 전달된 인수에 따라 결정된다.

25.1.3 ArrayBuffer 객체를 위한 추상 연산

25.1.3.1 AllocateArrayBuffer ( constructor, byteLength [ , maxByteLength ] )

The abstract operation AllocateArrayBuffer takes arguments constructor (a constructor) and byteLength (a non-negative integer) and optional argument maxByteLength (a non-negative integer or empty) and returns ArrayBuffer 를 포함하는 정상 완료 또는 throw completion. ArrayBuffer 를 생성하는 데 사용된다. It performs the following steps when called:

  1. slots = « [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferDetachKey]] ».
  2. maxByteLength 가 존재하고 empty 가 아니면 allocatingResizableBuffer = true; 그렇지 않으면 false.
  3. allocatingResizableBuffer = true 이면
    1. byteLength > maxByteLength 이면 RangeError 예외.
    2. slots[[ArrayBufferMaxByteLength]] 추가.
  4. obj = ? OrdinaryCreateFromConstructor(constructor, "%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. NOTE: Resizable ArrayBuffer 는 제자리(in-place) 증가로 구현 가능하도록 설계되었다. 예를 들어 가상 메모리를 미리 예약할 수 없는 경우 구현은 예외를 던질 수 있다.
    3. obj.[[ArrayBufferMaxByteLength]] = maxByteLength.
  9. obj 반환.

25.1.3.2 ArrayBufferByteLength ( arrayBuffer, order )

The abstract operation ArrayBufferByteLength takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer) and order (seq-cst or unordered) and returns 음이 아닌 정수. It performs the following steps when called:

  1. IsSharedArrayBuffer(arrayBuffer) = true 그리고 arrayBuffer[[ArrayBufferByteLengthData]] 내부 슬롯을 가지면
    1. bufferByteLengthBlock = arrayBuffer.[[ArrayBufferByteLengthData]].
    2. rawLength = GetRawBytesFromSharedBlock(bufferByteLengthBlock, 0, biguint64, true, order).
    3. isLittleEndian = 주변 에이전트의 Agent Record[[LittleEndian]] 필드 값.
    4. Return (RawBytesToNumeric(biguint64, rawLength, isLittleEndian)).
  2. Assert: IsDetachedBuffer(arrayBuffer) = false.
  3. Return arrayBuffer.[[ArrayBufferByteLength]].

25.1.3.3 ArrayBufferCopyAndDetach ( arrayBuffer, newLength, preserveResizability )

The abstract operation ArrayBufferCopyAndDetach takes arguments arrayBuffer (an ECMAScript language value), newLength (an ECMAScript language value), and preserveResizability (preserve-resizability or fixed-length) and returns ArrayBuffer 를 포함하는 정상 완료 또는 throw completion. It performs the following steps when called:

  1. RequireInternalSlot(arrayBuffer, [[ArrayBufferData]]) 수행.
  2. IsSharedArrayBuffer(arrayBuffer) = true 이면 TypeError 예외.
  3. newLengthundefined 이면
    1. newByteLength = arrayBuffer.[[ArrayBufferByteLength]].
  4. Else
    1. newByteLength = ? ToIndex(newLength).
  5. IsDetachedBuffer(arrayBuffer) = true 이면 TypeError 예외.
  6. preserveResizability = preserve-resizability 그리고 IsFixedLengthArrayBuffer(arrayBuffer) = false 이면
    1. newMaxByteLength = arrayBuffer.[[ArrayBufferMaxByteLength]].
  7. Else
    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. NOTE: 새 Data Block 생성과 구 Data Block 으로부터의 복사는 관측 불가능하다. 구현은 zero-copy 이동 또는 realloc 으로 최적화할 수 있다.
  15. DetachArrayBuffer(arrayBuffer) 수행.
  16. newBuffer 반환.

25.1.3.4 IsDetachedBuffer ( arrayBuffer )

The abstract operation IsDetachedBuffer takes argument arrayBuffer (an ArrayBuffer or a SharedArrayBuffer) and returns Boolean. It performs the following steps when called:

  1. arrayBuffer.[[ArrayBufferData]]null 이면 true 반환.
  2. false 반환.

25.1.3.5 DetachArrayBuffer ( arrayBuffer [ , key ] )

The abstract operation DetachArrayBuffer takes argument arrayBuffer (an ArrayBuffer) and optional argument key (anything) and returns unused 를 포함하는 정상 완료 또는 throw completion. It performs the following steps when called:

  1. Assert: IsSharedArrayBuffer(arrayBuffer) = false.
  2. key 가 존재하지 않으면 key = undefined.
  3. arrayBuffer.[[ArrayBufferDetachKey]]key 이면 TypeError 예외.
  4. arrayBuffer.[[ArrayBufferData]] = null.
  5. arrayBuffer.[[ArrayBufferByteLength]] = 0.
  6. unused 반환.
Note

ArrayBuffer 인스턴스를 분리(detach)하면 그 인스턴스가 사용하던 Data Block 과의 연결이 끊어지고 버퍼의 바이트 길이는 0이 된다.

25.1.3.6 CloneArrayBuffer ( srcBuffer, srcByteOffset, srcLength )

The abstract operation CloneArrayBuffer takes arguments srcBuffer (an ArrayBuffer or a SharedArrayBuffer), srcByteOffset (a non-negative integer), and srcLength (a non-negative integer) and returns ArrayBuffer 를 포함하는 정상 완료 또는 throw completion. srcByteOffset 부터 srcLength 바이트 범위의 srcBuffer 데이터를 복사한 새 ArrayBuffer 를 생성한다. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(srcBuffer) = false.
  2. targetBuffer = ? AllocateArrayBuffer(%ArrayBuffer%, srcLength).
  3. srcBlock = srcBuffer.[[ArrayBufferData]].
  4. targetBlock = targetBuffer.[[ArrayBufferData]].
  5. CopyDataBlockBytes(targetBlock, 0, srcBlock, srcByteOffset, srcLength) 수행.
  6. targetBuffer 반환.

25.1.3.7 GetArrayBufferMaxByteLengthOption ( options )

The abstract operation GetArrayBufferMaxByteLengthOption takes argument options (an ECMAScript language value) and returns 음이 아닌 정수 또는 empty 를 포함하는 정상 완료, 또는 throw completion. It performs the following steps when called:

  1. options 가 Object 가 아니면 empty 반환.
  2. maxByteLength = ? Get(options, "maxByteLength").
  3. maxByteLength = undefined 이면 empty 반환.
  4. Return ? ToIndex(maxByteLength).

25.1.3.8 HostResizeArrayBuffer ( buffer, newByteLength )

The host-defined abstract operation HostResizeArrayBuffer takes arguments buffer (an ArrayBuffer) and newByteLength (a non-negative integer) and returns handled 또는 unhandled 를 포함하는 정상 완료, 또는 throw completion. 호스트buffer 에 대한 구현 정의 크기 조정을 수행할 기회를 제공한다. 크기 조정을 처리하지 않으려면 기본 동작을 위해 unhandled 를 반환할 수 있다.

HostResizeArrayBuffer 구현은 다음 요구사항을 준수해야 한다:

  • buffer 를 분리(detach)하지 않는다.
  • 정상 완료로 handled 를 반환하면 buffer.[[ArrayBufferByteLength]] = newByteLength 이다.

기본 구현은 NormalCompletion(unhandled) 를 반환한다.

25.1.3.9 IsFixedLengthArrayBuffer ( arrayBuffer )

The abstract operation IsFixedLengthArrayBuffer takes argument arrayBuffer (an ArrayBuffer or a SharedArrayBuffer) and returns Boolean. It performs the following steps when called:

  1. arrayBuffer[[ArrayBufferMaxByteLength]] 내부 슬롯을 가지면 false 반환.
  2. true 반환.

25.1.3.10 IsUnsignedElementType ( type )

The abstract operation IsUnsignedElementType takes argument type (a TypedArray element type) and returns Boolean. 인수 type 이 부호 없는 TypedArray 요소 타입인지 검증한다. It performs the following steps when called:

  1. typeuint8, uint8clamped, uint16, uint32, biguint64 중 하나이면 true 반환.
  2. false 반환.

25.1.3.11 IsUnclampedIntegerElementType ( type )

The abstract operation IsUnclampedIntegerElementType takes argument type (a TypedArray element type) and returns Boolean. 인수 typeuint8clamped 를 제외한 정수 TypedArray 요소 타입인지 검증한다. It performs the following steps when called:

  1. typeint8, uint8, int16, uint16, int32, uint32 중 하나이면 true 반환.
  2. false 반환.

25.1.3.12 IsBigIntElementType ( type )

The abstract operation IsBigIntElementType takes argument type (a TypedArray element type) and returns Boolean. 인수 type 이 BigInt TypedArray 요소 타입인지 검증한다. It performs the following steps when called:

  1. typebiguint64 또는 bigint64 이면 true 반환.
  2. false 반환.

25.1.3.13 IsNoTearConfiguration ( type, order )

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

  1. IsUnclampedIntegerElementType(type) = true 이면 true 반환.
  2. IsBigIntElementType(type) = true 이고 orderinit, unordered 가 아니면 true 반환.
  3. false 반환.

25.1.3.14 RawBytesToNumeric ( type, rawBytes, isLittleEndian )

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

  1. elementSize = Table 73 에서 요소 타입 type 에 대해 지정된 Element Size 값.
  2. isLittleEndian = false 이면 rawBytes 요소 순서를 반전.
  3. type = float16 이면
    1. value = rawBytes 바이트들을 이어 붙인 후 little-endian 비트열로 해석한 IEEE 754-2019 binary16 값.
    2. value 가 NaN 이면 NaN 반환.
    3. value 에 해당하는 Number 값 반환.
  4. type = float32 이면
    1. (동일 절차, binary32) → NaN 처리 동일.
  5. type = float64 이면
    1. (동일 절차, binary64) → NaN 처리 동일.
  6. IsUnsignedElementType(type) = true 이면
    1. intValue = rawBytes 바이트들을 이어 붙여 해석한 unsigned little-endian 이진 수.
  7. Else
    1. intValue = rawBytes 바이트들을 이어 붙여 해석한 길이 (elementSize × 8) 비트의 little-endian 2의 보수 이진 수.
  8. IsBigIntElementType(type) = true 이면 intValue 에 해당하는 BigInt 반환.
  9. 그렇지 않으면 intValue 에 해당하는 Number 반환.

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

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

  1. elementSize = Table 73 에서 요소 타입 type 의 Element Size 값.
  2. execution = 주변 에이전트의 Agent Record[[CandidateExecution]] 필드.
  3. eventsRecord = execution.[[EventsRecords]][[AgentSignifier]] = AgentSignifier() 인 Agent Events Record.
  4. isTypedArray = true 그리고 IsNoTearConfiguration(type, order) = true 이면 noTear = true, 아니면 false.
  5. rawValue = 길이 elementSize 이고 요소가 비결정적으로 선택된 바이트 값인 List.
  6. NOTE: 구현에서 rawValue 는 하드웨어의 비원자/원자 읽기 결과이다. 비결정성은 약한 일관성 하드웨어의 관측 가능 동작을 기술하기 위한 의미적 규정이다.
  7. readEvent = ReadSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize }.
  8. eventsRecord.[[EventList]]readEvent 추가.
  9. execution.[[ChosenValues]]Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: rawValue } 추가.
  10. rawValue 반환.

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

The abstract operation GetValueFromBuffer takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), isTypedArray (a Boolean), and order (seq-cst or unordered) and optional argument isLittleEndian (a Boolean) and returns Number 또는 BigInt. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(arrayBuffer) = false.
  2. Assert: byteIndex 에서 시작하여 type 값을 표현하기에 충분한 바이트가 존재.
  3. block = arrayBuffer.[[ArrayBufferData]].
  4. elementSize = Table 73 에서 type 의 Element Size.
  5. IsSharedArrayBuffer(arrayBuffer) = true 이면
    1. Assert: blockShared Data Block.
    2. rawValue = GetRawBytesFromSharedBlock(block, byteIndex, type, isTypedArray, order).
  6. Else
    1. rawValue = block 에서 [byteIndex, byteIndex + elementSize) 구간의 바이트 List.
  7. Assert: rawValue 길이 = elementSize.
  8. isLittleEndian 미지정이면 주변 에이전트 Agent Record[[LittleEndian]] 값으로 설정.
  9. Return RawBytesToNumeric(type, rawValue, isLittleEndian).

25.1.3.17 NumericToRawBytes ( type, value, isLittleEndian )

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

  1. type = float16 이면
    1. rawBytes = value 를 roundTiesToEven 방식으로 IEEE 754-2019 binary16 형식으로 변환한 2바이트 List (little endian). valueNaN 이면 구현이 선택한 binary16 NaN 인코딩(구현 구분 가능한 동일 NaN 에 대해 항상 동일 인코딩)을 사용.
  2. Else if type = float32
    1. (동일, 4바이트 binary32)
  3. Else if type = float64
    1. (동일, 8바이트 binary64)
  4. Else
    1. n = Table 73 에서 type 의 Element Size.
    2. conversionOperation = Table 73 변환 연산 열의 type 에 해당하는 추상 연산.
    3. intValue = (! conversionOperation(value)).
    4. intValue ≥ 0 이면
      1. rawBytes = intValuen 바이트 이진 인코딩 (little endian).
    5. Else
      1. rawBytes = intValuen 바이트 2의 보수 이진 인코딩 (little endian).
  5. isLittleEndian = false 이면 rawBytes 순서 반전.
  6. rawBytes 반환.

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

The abstract operation SetValueInBuffer takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), value (a Number or a BigInt), isTypedArray (a Boolean), and order (seq-cst, unordered, or init) and optional argument isLittleEndian (a Boolean) and returns unused. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(arrayBuffer) = false.
  2. Assert: byteIndex 에서 시작하여 type 값을 표현하기 충분한 바이트 존재.
  3. Assert: IsBigIntElementType(type) = true 이면 value 는 BigInt; 아니면 Number.
  4. block = arrayBuffer.[[ArrayBufferData]].
  5. elementSize = Table 73 에서 type 의 Element Size.
  6. isLittleEndian 미지정이면 주변 에이전트 Agent Record[[LittleEndian]] 값으로 설정.
  7. rawBytes = NumericToRawBytes(type, value, isLittleEndian).
  8. IsSharedArrayBuffer(arrayBuffer) = true 이면
    1. execution = 주변 에이전트 Agent Record[[CandidateExecution]].
    2. eventsRecord = execution.[[EventsRecords]] 중 현재 AgentSignifier() 와 일치하는 것.
    3. isTypedArray = true 그리고 IsNoTearConfiguration(type, order) = true 이면 noTear = true; 아니면 false.
    4. WriteSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes } 를 eventsRecord.[[EventList]] 에 추가.
  9. Else
    1. rawBytes 개별 바이트를 block[byteIndex] 부터 순서대로 저장.
  10. unused 반환.

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

The abstract operation GetModifySetValueInBuffer takes arguments arrayBuffer (an ArrayBuffer or a SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), value (a Number or a BigInt), and op (a read-modify-write modification function) and returns Number 또는 BigInt. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(arrayBuffer) = false.
  2. Assert: byteIndex 에서 시작하여 type 값을 표현하기 충분한 바이트 존재.
  3. Assert: IsBigIntElementType(type) = true 이면 value 는 BigInt; 아니면 Number.
  4. block = arrayBuffer.[[ArrayBufferData]].
  5. elementSize = Table 73 에서 type 의 Element Size.
  6. isLittleEndian = 주변 에이전트 Agent Record[[LittleEndian]] 값.
  7. rawBytes = NumericToRawBytes(type, value, isLittleEndian).
  8. IsSharedArrayBuffer(arrayBuffer) = true 이면
    1. execution = 주변 에이전트 Agent Record[[CandidateExecution]].
    2. eventsRecord = execution.[[EventsRecords]] 중 현재 AgentSignifier() 에 해당하는 것.
    3. rawBytesRead = 길이 elementSize 인, 비결정적으로 선택된 바이트 값 List.
    4. NOTE: 구현에서 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. eventsRecord.[[EventList]]rmwEvent 추가.
    7. execution.[[ChosenValues]]Chosen Value Record { [[Event]]: rmwEvent, [[ChosenValue]]: rawBytesRead } 추가.
  9. Else
    1. rawBytesRead = 길이 elementSize 인 바이트 시퀀스 (block[byteIndex] 부터).
    2. rawBytesModified = op(rawBytesRead, rawBytes).
    3. rawBytesModified 바이트를 block[byteIndex] 부터 저장.
  10. Return 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. Return ? 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]" 이다.

Note

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. O = this 값.
  2. RequireInternalSlot(O, [[ArrayBufferData]]) 수행.
  3. IsSharedArrayBuffer(O) = true 이면 TypeError 예외.
  4. IsDetachedBuffer(O) = true 이면 +0𝔽 반환.
  5. length = O.[[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. O = this 값.
  2. RequireInternalSlot(O, [[ArrayBufferData]]) 수행.
  3. IsSharedArrayBuffer(O) = true 이면 TypeError 예외.
  4. Return IsDetachedBuffer(O).

25.1.6.4 get ArrayBuffer.prototype.maxByteLength

ArrayBuffer.prototype.maxByteLength 는 set 접근자 함수가 undefined접근자 프로퍼티이다. 그 get 접근자 함수는 호출 시 다음 단계를 수행한다:

  1. O = this 값.
  2. RequireInternalSlot(O, [[ArrayBufferData]]) 수행.
  3. IsSharedArrayBuffer(O) = true 이면 TypeError 예외.
  4. IsDetachedBuffer(O) = true 이면 +0𝔽 반환.
  5. IsFixedLengthArrayBuffer(O) = true 이면
    1. length = O.[[ArrayBufferByteLength]].
  6. Else
    1. length = O.[[ArrayBufferMaxByteLength]].
  7. 𝔽(length) 반환.

25.1.6.5 get ArrayBuffer.prototype.resizable

ArrayBuffer.prototype.resizable 는 set 접근자 함수가 undefined접근자 프로퍼티이다. 그 get 접근자 함수는 호출 시 다음 단계를 수행한다:

  1. O = this 값.
  2. RequireInternalSlot(O, [[ArrayBufferData]]) 수행.
  3. IsSharedArrayBuffer(O) = true 이면 TypeError 예외.
  4. IsFixedLengthArrayBuffer(O) = false 이면 true 반환; 아니면 false 반환.

25.1.6.6 ArrayBuffer.prototype.resize ( newLength )

이 메서드는 호출 시 다음 단계를 수행한다:

  1. O = this 값.
  2. RequireInternalSlot(O, [[ArrayBufferMaxByteLength]]) 수행.
  3. IsSharedArrayBuffer(O) = true 이면 TypeError 예외.
  4. newByteLength = ? ToIndex(newLength).
  5. IsDetachedBuffer(O) = true 이면 TypeError 예외.
  6. newByteLength > O.[[ArrayBufferMaxByteLength]] 이면 RangeError 예외.
  7. hostHandled = ? HostResizeArrayBuffer(O, newByteLength).
  8. hostHandled = handled 이면 undefined 반환.
  9. oldBlock = O.[[ArrayBufferData]].
  10. newBlock = ? CreateByteDataBlock(newByteLength).
  11. copyLength = min(newByteLength, O.[[ArrayBufferByteLength]]).
  12. CopyDataBlockBytes(newBlock, 0, oldBlock, 0, copyLength) 수행.
  13. NOTE: 새 Data Block 생성과 복사는 관측 불가능하며, 구현은 제자리 증가/축소로 구현할 수 있다.
  14. O.[[ArrayBufferData]] = newBlock.
  15. O.[[ArrayBufferByteLength]] = newByteLength.
  16. undefined 반환.

25.1.6.7 ArrayBuffer.prototype.slice ( start, end )

이 메서드는 호출 시 다음 단계를 수행한다:

  1. O = this 값.
  2. RequireInternalSlot(O, [[ArrayBufferData]]) 수행.
  3. IsSharedArrayBuffer(O) = true 이면 TypeError 예외.
  4. IsDetachedBuffer(O) = true 이면 TypeError 예외.
  5. len = O.[[ArrayBufferByteLength]].
  6. relativeStart = ? ToIntegerOrInfinity(start).
  7. relativeStart = -∞ 이면 first = 0.
  8. Else if relativeStart < 0 이면 first = max(len + relativeStart, 0).
  9. Else first = min(relativeStart, len).
  10. end = undefined 이면 relativeEnd = len; 아니면 relativeEnd = ? ToIntegerOrInfinity(end).
  11. relativeEnd = -∞ 이면 final = 0.
  12. Else if relativeEnd < 0 이면 final = max(len + relativeEnd, 0).
  13. Else final = min(relativeEnd, len).
  14. newLen = max(final - first, 0).
  15. ctor = ? SpeciesConstructor(O, %ArrayBuffer%).
  16. new = ? Construct(ctor, « 𝔽(newLen) »).
  17. RequireInternalSlot(new, [[ArrayBufferData]]) 수행.
  18. IsSharedArrayBuffer(new) = true 이면 TypeError 예외.
  19. IsDetachedBuffer(new) = true 이면 TypeError 예외.
  20. SameValue(new, O) = true 이면 TypeError 예외.
  21. new.[[ArrayBufferByteLength]] < newLen 이면 TypeError 예외.
  22. NOTE: 위 단계의 부작용으로 O 가 분리 또는 크기 변경되었을 수 있다.
  23. IsDetachedBuffer(O) = true 이면 TypeError 예외.
  24. fromBuf = O.[[ArrayBufferData]].
  25. toBuf = new.[[ArrayBufferData]].
  26. currentLen = O.[[ArrayBufferByteLength]].
  27. first < currentLen 이면
    1. count = min(newLen, currentLen - first).
    2. CopyDataBlockBytes(toBuf, 0, fromBuf, first, count) 수행.
  28. new 반환.

25.1.6.8 ArrayBuffer.prototype.transfer ( [ newLength ] )

이 메서드는 호출 시 다음 단계를 수행한다:

  1. O = this 값.
  2. Return ? ArrayBufferCopyAndDetach(O, newLength, preserve-resizability).

25.1.6.9 ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] )

이 메서드는 호출 시 다음 단계를 수행한다:

  1. O = this 값.
  2. Return ? ArrayBufferCopyAndDetach(O, 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]] 내부 슬롯을 갖는다. 크기 변경 가능한 인스턴스는 [[ArrayBufferMaxByteLength]] 내부 슬롯도 갖는다.

[[ArrayBufferData]]null 인 ArrayBuffer 인스턴스는 분리(detached)된 것으로 간주되며 해당 ArrayBuffer 내 데이터에 접근·수정하는 모든 연산은 실패한다.

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

25.1.8 크기 변경 가능 ArrayBuffer 가이드라인

Note 1

다음은 크기 변경 가능 ArrayBuffer 를 사용하는 ECMAScript 프로그래머를 위한 지침이다.

가능하다면 배포 환경에서 프로그램을 테스트하는 것을 권장한다. 사용 가능한 물리 메모리 양은 하드웨어 장치마다 크게 다르다. 유사하게 가상 메모리 서브시스템 역시 하드웨어 및 운영체제에 따라 크게 다르다. 64비트 데스크톱 웹 브라우저에서 메모리 부족 없이 동작하는 애플리케이션이 32비트 모바일 웹 브라우저에서는 메모리를 소진할 수 있다.

크기 변경 가능 ArrayBuffer 의 "maxByteLength" 옵션 값을 선택할 때는 애플리케이션에 필요한 최소 가능한 값을 선택할 것을 권장한다. "maxByteLength" 가 1,073,741,824 (230 바이트, 1GiB) 를 초과하지 않도록 권장한다.

특정 최대 크기에 대해 크기 변경 가능 ArrayBuffer 를 성공적으로 생성했다 해서 이후 모든 크기 변경이 성공함을 보장하지 않는다.

Note 2

다음은 크기 변경 가능 ArrayBuffer 를 구현하는 ECMAScript 구현자들을 위한 지침이다.

Resizable ArrayBuffer 는 크기 변경 시 복사를 수행하거나, 가상 메모리를 미리 예약하는 제자리 증가(in-place growth), 또는 생성자 "maxByteLength" 값에 따라 양자의 혼합으로 구현될 수 있다.

호스트가 다중 테넌트(예: 동시에 여러 ECMAScript 애플리케이션 실행) 환경(웹 브라우저 등)이고 구현이 가상 메모리 예약을 통한 제자리 증가를 선택한다면, 32비트와 64비트 구현 모두에서 "maxByteLength" ≥ 1GiB~1.5GiB 값에 대해 예외를 던질 것을 권장한다. 이는 단일 애플리케이션이 가상 주소 공간을 고갈시킬 가능성과 상호 운용성 위험을 줄이기 위함이다.

호스트에 가상 메모리가 없거나(예: MMU 없는 임베디드 장치), 혹은 호스트가 복사 기반 크기 조정만 구현한다면 "maxByteLength" 옵션에 대해 임의의 Number value for 를 받을 수 있다. 하지만 요청된 크기의 메모리 블록을 절대 할당할 수 없다면 RangeError 를 던질 것을 권장한다(예: 요청 크기가 장치에서 사용 가능한 최대 메모리보다 큰 경우).

25.2 SharedArrayBuffer 객체

25.2.1 고정 길이 및 증가 가능(Growable) SharedArrayBuffer 객체

fixed-length SharedArrayBuffer 는 생성 후 바이트 길이가 변경될 수 없는 SharedArrayBuffer 이다.

growable SharedArrayBufferSharedArrayBuffer.prototype.grow ( newLength ) 호출을 통해 생성 후 바이트 길이가 증가할 수 있는 SharedArrayBuffer 이다.

생성되는 SharedArrayBuffer 객체의 종류는 SharedArrayBuffer ( length [ , options ] ) 에 전달되는 인수에 따라 결정된다.

25.2.2 SharedArrayBuffer 객체를 위한 추상 연산

25.2.2.1 AllocateSharedArrayBuffer ( constructor, byteLength [ , maxByteLength ] )

The abstract operation AllocateSharedArrayBuffer takes arguments constructor (a constructor) and byteLength (a non-negative integer) and optional argument maxByteLength (a non-negative integer or empty) and returns SharedArrayBuffer 를 포함하는 정상 완료 또는 throw completion. SharedArrayBuffer 를 생성하는 데 사용된다. It performs the following steps when called:

  1. slots = « [[ArrayBufferData]] ».
  2. maxByteLength 가 존재하고 empty 가 아니면 allocatingGrowableBuffer = true; 아니면 false.
  3. allocatingGrowableBuffer = true 이면
    1. byteLength > maxByteLength 이면 RangeError 예외.
    2. slots[[ArrayBufferByteLengthData]][[ArrayBufferMaxByteLength]] 추가.
  4. Else
    1. slots[[ArrayBufferByteLength]] 추가.
  5. obj = ? OrdinaryCreateFromConstructor(constructor, "%SharedArrayBuffer.prototype%", slots).
  6. allocatingGrowableBuffer = true 이면 allocLength = maxByteLength; 아니면 allocLength = byteLength.
  7. block = ? CreateSharedByteDataBlock(allocLength).
  8. obj.[[ArrayBufferData]] = block.
  9. allocatingGrowableBuffer = true 이면
    1. Assert: byteLengthmaxByteLength.
    2. byteLengthBlock = ? CreateSharedByteDataBlock(8).
    3. SetValueInBuffer(byteLengthBlock, 0, biguint64, (byteLength), true, seq-cst) 수행.
    4. obj.[[ArrayBufferByteLengthData]] = byteLengthBlock.
    5. obj.[[ArrayBufferMaxByteLength]] = maxByteLength.
  10. Else
    1. obj.[[ArrayBufferByteLength]] = byteLength.
  11. obj 반환.

25.2.2.2 IsSharedArrayBuffer ( obj )

The abstract operation IsSharedArrayBuffer takes argument obj (an ArrayBuffer or a SharedArrayBuffer) and returns Boolean. 객체가 ArrayBuffer, SharedArrayBuffer, 또는 그 서브타입인지 검사한다. It performs the following steps when called:

  1. bufferData = obj.[[ArrayBufferData]].
  2. bufferDatanull 이면 false 반환.
  3. bufferDataData Block 이면 false 반환.
  4. Assert: bufferDataShared Data Block.
  5. true 반환.

25.2.2.3 HostGrowSharedArrayBuffer ( buffer, newByteLength )

The host-defined abstract operation HostGrowSharedArrayBuffer takes arguments buffer (a SharedArrayBuffer) and newByteLength (a non-negative integer) and returns handled 또는 unhandled 를 포함하는 정상 완료 또는 throw completion. 호스트buffer 에 대해 구현 정의 증가(grow)를 수행할 기회를 제공한다. 처리하지 않으려면 기본 동작을 위해 unhandled 를 반환할 수 있다.

HostGrowSharedArrayBuffer 구현은 다음 요구사항을 따른다:

  • 추상 연산이 unhandled 로 정상 완료하지 않고, newByteLength < buffer 의 현재 바이트 길이이거나 newByteLength > buffer.[[ArrayBufferMaxByteLength]] 이면 RangeError 예외.
  • isLittleEndian = 주변 에이전트 Agent Record[[LittleEndian]] 필드 값. 연산이 handled 로 정상 완료하면, [[Order]] = seq-cst, [[Payload]] = NumericToRawBytes(biguint64, newByteLength, isLittleEndian), [[Block]] = buffer.[[ArrayBufferByteLengthData]], [[ByteIndex]] = 0, [[ElementSize]] = 8 인 WriteSharedMemory 또는 ReadModifyWriteSharedMemory 이벤트가 후보 실행에 추가되어, SharedArrayBuffer.prototype.grow 에 대한 경합 호출이 “소실”(조용히 아무 것도 하지 않음)되지 않도록 한다.
Note

두 번째 요구사항은 buffer 의 현재 바이트 길이를 언제/어떻게 읽는지에 대해 의도적으로 모호하다. 길이 갱신은 하드웨어의 원자적 read-modify-write 명령을 통해 이루어져야 하므로 load-link/store-conditional 또는 load-exclusive/store-exclusive 쌍을 사용하는 구조에서는 명령을 가깝게 유지하고 싶을 수 있다. 따라서 SharedArrayBuffer.prototype.grow 자체는 HostGrowSharedArrayBuffer 호출 전 newByteLength 에 대한 경계 검사를 수행하지 않으며, 현재 바이트 길이를 언제 읽어야 한다는 요구도 없다.

이는 newByteLength 가 0 이상이며 buffer.[[ArrayBufferMaxByteLength]] 이하임이 보장되는 HostResizeArrayBuffer 와 대조적이다.

기본 구현은 NormalCompletion(unhandled) 를 반환한다.

25.2.3 SharedArrayBuffer 생성자

SharedArrayBuffer 생성자:

  • %SharedArrayBuffer% 이다.
  • 해당 프로퍼티가 존재한다면 전역 객체 "SharedArrayBuffer" 프로퍼티의 초기 값이다 (아래 참조).
  • 생성자로 호출되면 새 SharedArrayBuffer 를 생성·초기화한다.
  • 함수로 호출하도록 의도되지 않았으며 그렇게 호출하면 예외를 던진다.
  • 클래스 정의 extends 절의 값으로 사용할 수 있다. 지정된 SharedArrayBuffer 동작을 상속하려는 서브클래스 생성자SharedArrayBuffer.prototype 내장 메서드 동작을 지원하는 데 필요한 내부 상태로 서브클래스 인스턴스를 생성·초기화하기 위해 SharedArrayBuffer 생성자에 대한 super 호출을 포함해야 한다.

호스트가 SharedArrayBuffer 에 대한 동시 접근을 제공하지 않는 경우 전역 객체"SharedArrayBuffer" 프로퍼티를 생략할 수 있다.

Note

ArrayBuffer 와 달리 SharedArrayBuffer 는 분리(detach)되지 않으며 그 내부 [[ArrayBufferData]] 슬롯은 null 이 되지 않는다.

25.2.3.1 SharedArrayBuffer ( length [ , options ] )

이 함수는 호출 시 다음 단계를 수행한다:

  1. NewTarget 이 undefined 이면 TypeError 예외.
  2. byteLength = ? ToIndex(length).
  3. requestedMaxByteLength = ? GetArrayBufferMaxByteLengthOption(options).
  4. Return ? 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. O = this 값.
  2. RequireInternalSlot(O, [[ArrayBufferData]]) 수행.
  3. IsSharedArrayBuffer(O) = false 이면 TypeError 예외.
  4. length = ArrayBufferByteLength(O, seq-cst).
  5. 𝔽(length) 반환.

25.2.5.2 SharedArrayBuffer.prototype.constructor

SharedArrayBuffer.prototype.constructor 의 초기 값은 %SharedArrayBuffer% 이다.

25.2.5.3 SharedArrayBuffer.prototype.grow ( newLength )

이 메서드는 호출 시 다음 단계를 수행한다:

  1. O = this 값.
  2. RequireInternalSlot(O, [[ArrayBufferMaxByteLength]]) 수행.
  3. IsSharedArrayBuffer(O) = false 이면 TypeError 예외.
  4. newByteLength = ? ToIndex(newLength).
  5. hostHandled = ? HostGrowSharedArrayBuffer(O, newByteLength).
  6. hostHandled = handled 이면 undefined 반환.
  7. isLittleEndian = 주변 에이전트 Agent Record[[LittleEndian]] 값.
  8. byteLengthBlock = O.[[ArrayBufferByteLengthData]].
  9. currentByteLengthRawBytes = GetRawBytesFromSharedBlock(byteLengthBlock, 0, biguint64, true, seq-cst).
  10. newByteLengthRawBytes = NumericToRawBytes(biguint64, (newByteLength), isLittleEndian).
  11. 반복:
    1. NOTE: 동일 버퍼에 대한 경합 증가 호출이 완전 순서화되고 유실되지 않으며 침묵 실패하지 않도록 하는 compare-and-exchange 루프이다. 경합 없이 증가 시도 가능하면 루프 종료.
    2. currentByteLength = (RawBytesToNumeric(biguint64, currentByteLengthRawBytes, isLittleEndian)).
    3. newByteLength = currentByteLength 이면 undefined 반환.
    4. newByteLength < currentByteLength 또는 newByteLength > O.[[ArrayBufferMaxByteLength]] 이면 RangeError 예외.
    5. byteLengthDelta = newByteLength - currentByteLength.
    6. byteLengthDelta 바이트로 구성된 새 Shared Data Block 값을 생성할 수 없으면 RangeError 예외.
    7. NOTE: 새 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.
Note

길이 갱신 compare-exchange 의 허위 실패는 금지된다. 새 길이에 대한 경계 검사 통과 및 메모리 부족이 아니면 항상 ReadModifyWriteSharedMemory 이벤트(성공한 compare-exchange)가 후보 실행에 추가된다.

SharedArrayBuffer.prototype.grow 에 대한 병렬 호출은 완전 순서화된다. 예를 들어 sab.grow(10)sab.grow(20) 이 경합할 때 둘 중 하나가 승리하며, sab.grow(20) 이 먼저 일어났다면 sab.grow(10) 호출은 버퍼를 축소하지 않고 대신 RangeError 를 던진다.

25.2.5.4 get SharedArrayBuffer.prototype.growable

SharedArrayBuffer.prototype.growable 는 set 접근자 함수가 undefined접근자 프로퍼티이다. 그 get 접근자 함수는 호출 시 다음을 수행한다:

  1. O = this 값.
  2. RequireInternalSlot(O, [[ArrayBufferData]]) 수행.
  3. IsSharedArrayBuffer(O) = false 이면 TypeError 예외.
  4. IsFixedLengthArrayBuffer(O) = false 이면 true 반환; 아니면 false 반환.

25.2.5.5 get SharedArrayBuffer.prototype.maxByteLength

SharedArrayBuffer.prototype.maxByteLength 는 set 접근자 함수가 undefined접근자 프로퍼티이다. 그 get 접근자 함수는 호출 시 다음을 수행한다:

  1. O = this 값.
  2. RequireInternalSlot(O, [[ArrayBufferData]]) 수행.
  3. IsSharedArrayBuffer(O) = false 이면 TypeError 예외.
  4. IsFixedLengthArrayBuffer(O) = true 이면
    1. length = O.[[ArrayBufferByteLength]].
  5. Else
    1. length = O.[[ArrayBufferMaxByteLength]].
  6. 𝔽(length) 반환.

25.2.5.6 SharedArrayBuffer.prototype.slice ( start, end )

이 메서드는 호출 시 다음 단계를 수행한다:

  1. O = this 값.
  2. RequireInternalSlot(O, [[ArrayBufferData]]) 수행.
  3. IsSharedArrayBuffer(O) = false 이면 TypeError 예외.
  4. len = ArrayBufferByteLength(O, seq-cst).
  5. relativeStart = ? ToIntegerOrInfinity(start).
  6. relativeStart = -∞ 이면 first = 0.
  7. Else if relativeStart < 0 이면 first = max(len + relativeStart, 0).
  8. Else first = min(relativeStart, len).
  9. end = undefined 이면 relativeEnd = len; 아니면 relativeEnd = ? ToIntegerOrInfinity(end).
  10. relativeEnd = -∞ 이면 final = 0.
  11. Else if relativeEnd < 0 이면 final = max(len + relativeEnd, 0).
  12. Else final = min(relativeEnd, len).
  13. newLen = max(final - first, 0).
  14. ctor = ? SpeciesConstructor(O, %SharedArrayBuffer%).
  15. new = ? Construct(ctor, « 𝔽(newLen) »).
  16. RequireInternalSlot(new, [[ArrayBufferData]]) 수행.
  17. IsSharedArrayBuffer(new) = false 이면 TypeError 예외.
  18. new.[[ArrayBufferData]]O.[[ArrayBufferData]] 와 같으면 TypeError 예외.
  19. ArrayBufferByteLength(new, seq-cst) < newLen 이면 TypeError 예외.
  20. fromBuf = O.[[ArrayBufferData]].
  21. toBuf = new.[[ArrayBufferData]].
  22. CopyDataBlockBytes(toBuf, 0, fromBuf, first, newLen) 수행.
  23. new 반환.

25.2.5.7 SharedArrayBuffer.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 프로퍼티 초기 값은 String "SharedArrayBuffer" 이다.

이 프로퍼티 특성은 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.6 SharedArrayBuffer 인스턴스의 프로퍼티

SharedArrayBuffer 인스턴스는 SharedArrayBuffer 프로토타입 객체로부터 프로퍼티를 상속한다. 각 SharedArrayBuffer 인스턴스는 [[ArrayBufferData]] 내부 슬롯을 가진다. 증가 불가능 인스턴스는 [[ArrayBufferByteLength]] 내부 슬롯을 가진다. 증가 가능 인스턴스는 [[ArrayBufferByteLengthData]][[ArrayBufferMaxByteLength]] 내부 슬롯을 가진다.

Note

SharedArrayBuffer 인스턴스는 ArrayBuffer 인스턴스와 달리 분리(detach)되지 않는다.

25.2.7 증가 가능 SharedArrayBuffer 가이드라인

Note 1

다음은 증가 가능 SharedArrayBuffer 를 사용하는 ECMAScript 프로그래머를 위한 지침이다.

가능하다면 배포 환경에서 프로그램을 테스트할 것을 권장한다. 사용 가능한 물리 메모리 양은 하드웨어 장치마다 크게 다르다. 가상 메모리 서브시스템 또한 하드웨어와 운영체제에 따라 매우 다르다. 64비트 데스크톱 웹 브라우저에서 메모리 부족 없이 실행되는 애플리케이션이 32비트 모바일 웹 브라우저에서는 메모리를 소진할 수 있다.

증가 가능 SharedArrayBuffer 의 "maxByteLength" 옵션 값은 애플리케이션에 필요한 최소 크기를 선택할 것을 권장한다. "maxByteLength" 가 1073741824 (1GiB) 를 넘지 않도록 권장한다.

특정 최대 크기로 증가 가능 SharedArrayBuffer 를 성공적으로 생성했더라도 향후 grow 가 항상 성공함을 보장하지 않는다.

증가 가능 SharedArrayBuffer 의 길이(load) 중 모두가 동기화 seq-cst load 는 아니다. 예를 들어 정수 인덱스 프로퍼티 접근의 경계 검사 목적(u8[idx])으로 수행되는 길이 load 는 동기화되지 않는다. 일반적으로 명시적 동기화가 없으면 한 프로퍼티 접근이 경계 내라는 사실이 같은 에이전트의 이후 접근도 경계 내임을 의미하지 않는다. 반면 SharedArrayBuffer 의 length, byteLength 게터, %TypedArray%.prototype, DataView.prototype 을 통한 명시적 길이 load 는 동기화된다. TypedArray 가 완전히 out-of-bounds 인지 검사하기 위해 내장 메서드가 수행하는 길이 load 역시 동기화된다.

Note 2

다음은 증가 가능 SharedArrayBuffer 를 구현하는 ECMAScript 구현자를 위한 지침이다.

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

grow 연산은 증가 가능 SharedArrayBuffer 에 대한 메모리 접근과 병렬로 일어날 수 있으므로, 메모리 모델 제약은 unordered 접근조차 ‘찢어짐(tearing)’이 없어야 함을 요구한다. 실제로 이는 기반 데이터 블록을 ‘세계 정지’ 없이 복사로 증가시킬 수 없음을 의미한다. 직렬화 지점을 만들고 느리기 때문에 ‘세계 정지’ 전략은 권장되지 않는다.

증가된 메모리는 생성 순간부터(경합 접근 포함) 0 으로 보이는 형태여야 한다. 이는 온디맨드 zero-filled 가상 메모리 페이지나 수동 초기화 시 주의 깊은 동기화로 달성할 수 있다.

증가 가능 SharedArrayBuffer 의 TypedArray 뷰에 대한 정수 인덱스 프로퍼티 접근은 (위 프로그래머 지침에서 언급했듯) 기반 버퍼 길이에 대한 동기화 load 가 아니므로 비증가 SharedArrayBuffer 의 TypedArray 접근과 유사하게 최적화될 수 있도록 의도되었다. 예: 경계 검사를 루프 밖으로 끌어올릴 수 있다.

가상 메모리가 없는(예: MMU 없는 임베디드 장치) 호스트에서는 복사 방식으로 증가 가능 SharedArrayBuffer 를 구현하기 어렵다. 이런 호스트에서 메모리 사용 행태는 가상 메모리가 있는 호스트와 크게 다를 수 있으므로 사용자에게 명확히 알릴 필요가 있다.

25.3 DataView 객체

25.3.1 DataView 객체를 위한 추상 연산

25.3.1.1 버퍼 증명(버퍼 위트니스) Record 를 가진 DataView

DataView With Buffer Witness Record 는 DataView 와, 뷰 대상 버퍼의 캐시된 바이트 길이를 함께 캡슐화하기 위해 사용되는 Record 값이다. 이는 뷰 대상 버퍼가 증가 가능 SharedArrayBuffer 인 경우 바이트 길이 데이터 블록에 대해 단일 공유 메모리 읽기 이벤트가 되도록 돕는 용도로 사용된다.

DataView With Buffer Witness Record 는 Table 75 에 나열된 필드를 갖는다.

Table 75: 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 )

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

  1. buffer = obj.[[ViewedArrayBuffer]].
  2. IsDetachedBuffer(buffer) = true 이면
    1. byteLength = detached.
  3. Else
    1. byteLength = ArrayBufferByteLength(buffer, order).
  4. DataView With Buffer Witness Record { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength } 반환.

25.3.1.3 GetViewByteLength ( viewRecord )

The abstract operation GetViewByteLength takes argument viewRecord (a DataView With Buffer Witness Record) and returns 음이 아닌 정수. It performs the following steps when called:

  1. Assert: IsViewOutOfBounds(viewRecord) = false.
  2. view = viewRecord.[[Object]].
  3. view.[[ByteLength]]auto 이면 view.[[ByteLength]] 반환.
  4. Assert: IsFixedLengthArrayBuffer(view.[[ViewedArrayBuffer]]) = false.
  5. byteOffset = view.[[ByteOffset]].
  6. byteLength = viewRecord.[[CachedBufferByteLength]].
  7. Assert: byteLengthdetached.
  8. byteLength - byteOffset 반환.

25.3.1.4 IsViewOutOfBounds ( viewRecord )

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

  1. view = viewRecord.[[Object]].
  2. bufferByteLength = viewRecord.[[CachedBufferByteLength]].
  3. Assert: IsDetachedBuffer(view.[[ViewedArrayBuffer]]) = truebufferByteLength = detached.
  4. bufferByteLength = detached 이면 true 반환.
  5. byteOffsetStart = view.[[ByteOffset]].
  6. view.[[ByteLength]] = auto 이면
    1. byteOffsetEnd = bufferByteLength.
  7. Else
    1. byteOffsetEnd = byteOffsetStart + view.[[ByteLength]].
  8. byteOffsetStart > bufferByteLength 또는 byteOffsetEnd > bufferByteLength 이면 true 반환.
  9. NOTE: 길이 0 DataView 는 out-of-bounds 로 간주되지 않는다.
  10. false 반환.

25.3.1.5 GetViewValue ( view, requestIndex, isLittleEndian, type )

The abstract operation GetViewValue takes arguments view (an ECMAScript language value), requestIndex (an ECMAScript language value), isLittleEndian (an ECMAScript language value), and type (a TypedArray element type) and returns Number 또는 BigInt 를 포함하는 정상 완료 또는 throw completion. DataView 인스턴스 함수들이 뷰의 버퍼에서 값을 읽어올 때 사용된다. It performs the following steps when called:

  1. RequireInternalSlot(view, [[DataView]]) 수행.
  2. Assert: view[[ViewedArrayBuffer]] 내부 슬롯을 가진다.
  3. getIndex = ? ToIndex(requestIndex).
  4. isLittleEndian = ToBoolean(isLittleEndian).
  5. viewOffset = view.[[ByteOffset]].
  6. viewRecord = MakeDataViewWithBufferWitnessRecord(view, unordered).
  7. NOTE: 뷰의 백업 버퍼가 증가 가능 SharedArrayBuffer 인 경우 경계 검사는 동기화 연산이 아니다.
  8. IsViewOutOfBounds(viewRecord) = true 이면 TypeError 예외.
  9. viewSize = GetViewByteLength(viewRecord).
  10. elementSize = Table 73 에서 type 의 Element Size.
  11. getIndex + elementSize > viewSize 이면 RangeError 예외.
  12. bufferIndex = getIndex + viewOffset.
  13. Return GetValueFromBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, false, unordered, isLittleEndian).

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

The abstract operation SetViewValue takes arguments view (an ECMAScript language value), requestIndex (an ECMAScript language value), isLittleEndian (an ECMAScript language value), type (a TypedArray element type), and value (an ECMAScript language value) and returns undefined 를 포함하는 정상 완료 또는 throw completion. DataView 인스턴스 함수들이 뷰의 버퍼에 값을 저장할 때 사용된다. It performs the following steps when called:

  1. RequireInternalSlot(view, [[DataView]]) 수행.
  2. Assert: view[[ViewedArrayBuffer]] 내부 슬롯을 가진다.
  3. getIndex = ? ToIndex(requestIndex).
  4. IsBigIntElementType(type) = true 이면 numberValue = ? ToBigInt(value); 아니면 numberValue = ? ToNumber(value).
  5. isLittleEndian = ToBoolean(isLittleEndian).
  6. viewOffset = view.[[ByteOffset]].
  7. viewRecord = MakeDataViewWithBufferWitnessRecord(view, unordered).
  8. NOTE: 뷰의 백업 버퍼가 증가 가능 SharedArrayBuffer 인 경우 경계 검사는 동기화 연산이 아니다.
  9. IsViewOutOfBounds(viewRecord) = true 이면 TypeError 예외.
  10. viewSize = GetViewByteLength(viewRecord).
  11. elementSize = Table 73 에서 type 의 Element Size.
  12. getIndex + elementSize > viewSize 이면 RangeError 예외.
  13. bufferIndex = getIndex + viewOffset.
  14. SetValueInBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, numberValue, false, unordered, isLittleEndian) 수행.
  15. undefined 반환.

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. Else
      1. viewByteLength = auto.
  9. Else
    1. viewByteLength = ? ToIndex(byteLength).
    2. offset + viewByteLength > bufferByteLength 이면 RangeError 예외.
  10. O = ? OrdinaryCreateFromConstructor(NewTarget, "%DataView.prototype%", « [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] »).
  11. IsDetachedBuffer(buffer) = true 이면 TypeError 예외.
  12. bufferByteLength = ArrayBufferByteLength(buffer, seq-cst).
  13. offset > bufferByteLength 이면 RangeError 예외.
  14. byteLengthundefined 이면
    1. offset + viewByteLength > bufferByteLength 이면 RangeError 예외.
  15. O.[[ViewedArrayBuffer]] = buffer.
  16. O.[[ByteLength]] = viewByteLength.
  17. O.[[ByteOffset]] = offset.
  18. O 반환.

25.3.3 DataView 생성자의 프로퍼티

DataView 생성자:

  • 값이 %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. O = this 값.
  2. RequireInternalSlot(O, [[DataView]]) 수행.
  3. Assert: O[[ViewedArrayBuffer]] 내부 슬롯을 가진다.
  4. buffer = O.[[ViewedArrayBuffer]].
  5. buffer 반환.

25.3.4.2 get DataView.prototype.byteLength

DataView.prototype.byteLength 는 set 접근자 함수가 undefined접근자 프로퍼티이다. 그 get 접근자 함수는 호출 시 다음 단계를 수행한다:

  1. O = this 값.
  2. RequireInternalSlot(O, [[DataView]]) 수행.
  3. Assert: O[[ViewedArrayBuffer]] 내부 슬롯을 가진다.
  4. viewRecord = MakeDataViewWithBufferWitnessRecord(O, seq-cst).
  5. IsViewOutOfBounds(viewRecord) = true 이면 TypeError 예외.
  6. size = GetViewByteLength(viewRecord).
  7. 𝔽(size) 반환.

25.3.4.3 get DataView.prototype.byteOffset

DataView.prototype.byteOffset 는 set 접근자 함수가 undefined접근자 프로퍼티이다. 그 get 접근자 함수는 호출 시 다음 단계를 수행한다:

  1. O = this 값.
  2. RequireInternalSlot(O, [[DataView]]) 수행.
  3. Assert: O[[ViewedArrayBuffer]] 내부 슬롯을 가진다.
  4. viewRecord = MakeDataViewWithBufferWitnessRecord(O, seq-cst).
  5. IsViewOutOfBounds(viewRecord) = true 이면 TypeError 예외.
  6. offset = O.[[ByteOffset]].
  7. 𝔽(offset) 반환.

25.3.4.4 DataView.prototype.constructor

DataView.prototype.constructor 의 초기 값은 %DataView% 이다.

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. Return ? GetViewValue(view, byteOffset, littleEndian, bigint64).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. Return ? GetViewValue(view, byteOffset, littleEndian, biguint64).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, float16).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, float32).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, float64).

25.3.4.10 DataView.prototype.getInt8 ( byteOffset )

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. Return ? GetViewValue(view, byteOffset, true, int8).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, int16).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, int32).

25.3.4.13 DataView.prototype.getUint8 ( byteOffset )

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. Return ? GetViewValue(view, byteOffset, true, uint8).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, uint16).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, uint32).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. Return ? SetViewValue(view, byteOffset, littleEndian, bigint64, value).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. Return ? SetViewValue(view, byteOffset, littleEndian, biguint64, value).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, float16, value).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, float32, value).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, float64, value).

25.3.4.21 DataView.prototype.setInt8 ( byteOffset, value )

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. Return ? SetViewValue(view, byteOffset, true, int8, value).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, int16, value).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, int32, value).

25.3.4.24 DataView.prototype.setUint8 ( byteOffset, value )

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. Return ? SetViewValue(view, byteOffset, true, uint8, value).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, uint16, value).

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

이 메서드는 호출 시 다음 단계를 수행한다:

  1. view = this 값.
  2. littleEndian 미지정이면 littleEndian = false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, uint32, value).

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]] 내부 슬롯을 가진다.

Note

[[DataView]] 내부 슬롯의 값 자체는 명세 내에서 사용되지 않는다. 이 내부 슬롯의 존재 여부가 해당 객체가 DataView 생성자를 사용해 생성되었음을 식별하는 데 사용된다.

25.4 Atomics 객체

Atomics 객체:

  • %Atomics% 이다.
  • 전역 객체 "Atomics" 프로퍼티의 초기 값이다.
  • 일반 객체이다.
  • 값이 %Object.prototype%[[Prototype]] 내부 슬롯을 가진다.
  • [[Construct]] 내부 메서드가 없다; new 연산자로 생성자로 사용할 수 없다.
  • [[Call]] 내부 메서드가 없다; 함수로 호출될 수 없다.

Atomics 객체는 공유 메모리 배열 셀에 대해 분리 불가능(원자적)하게 동작하는 함수들과 에이전트가 원시적 이벤트를 대기/디스패치할 수 있게 하는 함수들을 제공한다. 규범적으로 사용하면 Atomics 함수는 공유 메모리를 통해 통신하는 다중 에이전트 프로그램이 병렬 CPU 상에서도 잘 이해된 순서로 실행되도록 한다. 공유 메모리 통신을 지배하는 규칙은 아래에 정의된 메모리 모델이 제공한다.

Note

ECMAScript 에서 공유 메모리를 프로그래밍/구현하기 위한 비규범적 가이드라인은 메모리 모델 절 끝부분의 주석을 참고하라.

25.4.1 Waiter Record

Waiter Record 는 특정 Atomics.wait 또는 Atomics.waitAsync 호출을 나타내기 위해 사용되는 Record 값이다.

Waiter Record 는 Table 76 에 나열된 필드를 가진다.

Table 76: Waiter Record 필드
필드 이름 의미
[[AgentSignifier]] agent signifier Atomics.wait 또는 Atomics.waitAsync 를 호출한 에이전트.
[[PromiseCapability]] PromiseCapability Record 또는 blocking Atomics.waitAsync 호출을 나타내면 결과 promise, 아니면 blocking.
[[TimeoutTime]] 음이 아닌 확장 수학적 값 타임아웃이 트리거될 수 있는 가장 이른 시각; 시간 값으로 계산.
[[Result]] "ok" 또는 "timed-out" 호출의 반환 값.

25.4.2 WaiterList Records

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

WaiterList Record 는 Table 77 에 나열된 필드를 가진다.

Table 77: WaiterList Record 필드
필드 이름 의미
[[Waiters]] Waiter Record 들의 List 이 WaiterList 가 연관된 위치에서 대기 중인 Atomics.wait / Atomics.waitAsync 호출들.
[[MostRecentLeaveEvent]] Synchronize 이벤트 또는 empty 가장 최근 임계 구역 이탈 이벤트, 또는 한번도 진입한 적 없으면 empty.

같은 agent signifier 를 가진 여러 Waiter Record 가 하나의 WaiterList 에 있을 수 있다.

에이전트 클러스터는 WaiterList Record 의 저장소를 가진다; 저장소는 (block, i) 로 인덱싱되고 blockShared Data Block, iblock 메모리의 바이트 오프셋이다. WaiterList Record 는 에이전트 독립적이다: (block, i) 로 조회하면 클러스터 내 어떤 에이전트에서도 동일한 WaiterList Record 가 결과로 나온다.

각 WaiterList Record 는 평가 중 그 WaiterList Record 에 대한 배타적 접근을 제어하는 critical section 을 가진다. 한 번에 하나의 에이전트만 critical section 에 진입할 수 있다. 진입/이탈은 추상 연산 EnterCriticalSectionLeaveCriticalSection 이 제어한다. WaiterList Record 에 대한 연산—대기 에이전트 추가/제거, 목록 순회, 목록의 에이전트 일시중단/알림, Synchronize 이벤트 설정/조회—는 critical section 에 진입한 에이전트만 수행할 수 있다.

25.4.3 Atomics 를 위한 추상 연산

25.4.3.1 ValidateIntegerTypedArray ( typedArray, waitable )

The abstract operation ValidateIntegerTypedArray takes arguments typedArray (an ECMAScript language value) and waitable (a Boolean) and returns 정상 완료(TypedArray With Buffer Witness Record 포함) 또는 throw completion. It performs the following steps when called:

  1. taRecord = ? ValidateTypedArray(typedArray, unordered).
  2. NOTE: typedArray 의 백업 버퍼가 증가 가능 SharedArrayBuffer 인 경우 경계 검사는 동기화 연산이 아니다.
  3. waitable = true 이면
    1. typedArray.[[TypedArrayName]]"Int32Array", "BigInt64Array" 둘 다 아니면 TypeError 예외.
  4. Else
    1. type = TypedArrayElementType(typedArray).
    2. IsUnclampedIntegerElementType(type) = false 그리고 IsBigIntElementType(type) = false 이면 TypeError 예외.
  5. Return taRecord.

25.4.3.2 ValidateAtomicAccess ( taRecord, requestIndex )

The abstract operation ValidateAtomicAccess takes arguments taRecord (a TypedArray With Buffer Witness Record) and requestIndex (an ECMAScript language value) and returns 정상 완료(정수) 또는 throw completion. It performs the following steps when called:

  1. length = TypedArrayLength(taRecord).
  2. accessIndex = ? ToIndex(requestIndex).
  3. Assert: accessIndex ≥ 0.
  4. accessIndexlength 이면 RangeError 예외.
  5. typedArray = taRecord.[[Object]].
  6. elementSize = TypedArrayElementSize(typedArray).
  7. offset = typedArray.[[ByteOffset]].
  8. Return (accessIndex × elementSize) + offset.

25.4.3.3 ValidateAtomicAccessOnIntegerTypedArray ( typedArray, requestIndex )

The abstract operation ValidateAtomicAccessOnIntegerTypedArray takes arguments typedArray (an ECMAScript language value) and requestIndex (an ECMAScript language value) and returns 정상 완료(정수) 또는 throw completion. It performs the following steps when called:

  1. taRecord = ? ValidateIntegerTypedArray(typedArray, false).
  2. Return ? ValidateAtomicAccess(taRecord, requestIndex).

25.4.3.4 RevalidateAtomicAccess ( typedArray, byteIndexInBuffer )

The abstract operation RevalidateAtomicAccess takes arguments typedArray (a TypedArray) and byteIndexInBuffer (an integer) and returns 정상 완료(unused) 또는 throw completion. 이 연산은 Atomics 메서드에서 모든 인수 강제가 수행된 후 버퍼가 경계 밖이 되었을 수 있으므로 원자 연산용 인덱스를 다시 검증한다. typedArray 의 백업 버퍼가 SharedArrayBuffer 인 경우 이 연산은 throw 하지 않는다. It performs the following steps when called:

  1. taRecord = MakeTypedArrayWithBufferWitnessRecord(typedArray, unordered).
  2. NOTE: typedArray 의 백업 버퍼가 증가 가능 SharedArrayBuffer 인 경우 경계 검사는 동기화되지 않는다.
  3. IsTypedArrayOutOfBounds(taRecord) = true 이면 TypeError 예외.
  4. Assert: byteIndexInBuffertypedArray.[[ByteOffset]].
  5. byteIndexInBuffertaRecord.[[CachedBufferByteLength]] 이면 RangeError 예외.
  6. Return unused.

25.4.3.5 GetWaiterList ( block, i )

The abstract operation GetWaiterList takes arguments block (a Shared Data Block) and i (a non-negative integer that is evenly divisible by 4) and returns WaiterList Record. It performs the following steps when called:

  1. Assert: ii + 3 은 block 메모리의 유효 바이트 오프셋.
  2. Return (block, i) 쌍이 참조하는 WaiterList Record.

25.4.3.6 EnterCriticalSection ( WL )

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

  1. Assert: 주변 에이전트는 어떤 WaiterList Recordcritical section 안에 있지 않다.
  2. 어떤 에이전트도 WLcritical section 에 없을 때까지 대기한 후 다른 에이전트가 진입하지 못하게 한 상태로 진입.
  3. WL.[[MostRecentLeaveEvent]]empty 이면
    1. NOTE: 최소 1번 진입된 WLLeaveCriticalSection 에 의해 Synchronize 이벤트가 설정된다.
    2. execution = 주변 에이전트의 Agent Record.[[CandidateExecution]].
    3. eventsRecord = execution.[[EventsRecords]][[AgentSignifier]] = AgentSignifier() 인 Agent Events Record.
    4. enterEvent = 새로운 Synchronize 이벤트.
    5. eventsRecord.[[EventList]]enterEvent 추가.
    6. eventsRecord.[[AgentSynchronizesWith]] 에 (WL.[[MostRecentLeaveEvent]], enterEvent) 추가.
  4. Return unused.

EnterCriticalSection 은 에이전트가 다른 에이전트가 떠나기를 기다려야 할 때 경합(contention) 이 있다. 경합이 없을 때 EnterCriticalSection 호출의 FIFO 순서가 관측 가능하다. 경합이 있을 때 구현은 임의 순서를 선택할 수 있으나 무기한 대기는 유발할 수 없다.

25.4.3.7 LeaveCriticalSection ( WL )

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

  1. Assert: 주변 에이전트는 WLcritical section 안에 있다.
  2. execution = 주변 에이전트 Agent Record.[[CandidateExecution]].
  3. eventsRecord = execution.[[EventsRecords]][[AgentSignifier]] = AgentSignifier() 인 것.
  4. leaveEvent = 새로운 Synchronize 이벤트.
  5. eventsRecord.[[EventList]]leaveEvent 추가.
  6. WL.[[MostRecentLeaveEvent]] = leaveEvent 로 설정.
  7. WLcritical section 떠남.
  8. Return unused.

25.4.3.8 AddWaiter ( WL, waiterRecord )

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

  1. Assert: 주변 에이전트는 WL critical section 안에 있다.
  2. Assert: WL.[[Waiters]][[PromiseCapability]][[AgentSignifier]] 가 각각 waiterRecord 와 동일한 Waiter Record 가 없다.
  3. WL.[[Waiters]]waiterRecord 추가.
  4. Return unused.

25.4.3.9 RemoveWaiter ( WL, waiterRecord )

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

  1. Assert: 주변 에이전트는 WL critical section 안에 있다.
  2. Assert: WL.[[Waiters]]waiterRecord 를 포함한다.
  3. WL.[[Waiters]] 에서 waiterRecord 제거.
  4. Return unused.

25.4.3.10 RemoveWaiters ( WL, c )

The abstract operation RemoveWaiters takes arguments WL (a WaiterList Record) and c (a non-negative integer or +∞) and returns Waiter Record 들의 List. It performs the following steps when called:

  1. Assert: 주변 에이전트는 WL critical section 안에 있다.
  2. len = WL.[[Waiters]] 요소 수.
  3. n = min(c, len).
  4. L = WL.[[Waiters]] 의 처음 n 요소로 이루어진 List.
  5. WL.[[Waiters]] 의 처음 n 요소 제거.
  6. Return L.

25.4.3.11 SuspendThisAgent ( WL, waiterRecord )

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

  1. Assert: 주변 에이전트는 WL critical section 안에 있다.
  2. Assert: WL.[[Waiters]]waiterRecord 포함.
  3. thisAgent = AgentSignifier().
  4. Assert: waiterRecord.[[AgentSignifier]]thisAgent.
  5. Assert: waiterRecord.[[PromiseCapability]]blocking.
  6. Assert: AgentCanSuspend() = true.
  7. LeaveCriticalSection(WL) 수행 후 주변 에이전트를 waiterRecord.[[TimeoutTime]] 시각까지 일시중단하되, critical section 을 벗어난 직후부터 suspend 적용 전 사이 도착한 알림이 손실되지 않도록 결합된 연산으로 수행. 주변 에이전트는 타임아웃 또는 다른 에이전트가 NotifyWaiter(WL, thisAgent) (즉 Atomics.notify) 를 호출하여 깨어날 수 있다.
  8. EnterCriticalSection(WL) 수행.
  9. Return unused.

25.4.3.12 NotifyWaiter ( WL, waiterRecord )

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

  1. Assert: 주변 에이전트는 WL critical section 안에 있다.
  2. waiterRecord.[[PromiseCapability]]blocking 이면
    1. signifier 가 waiterRecord.[[AgentSignifier]] 인 에이전트를 suspend 에서 깨움.
    2. NOTE: 이는 SuspendThisAgent 내 실행 재개를 유발.
  3. Else if AgentSignifier() 가 waiterRecord.[[AgentSignifier]] 이면
    1. promiseCapability = waiterRecord.[[PromiseCapability]].
    2. Call(promiseCapability.[[Resolve]], undefined, « waiterRecord.[[Result]] ») 수행.
  4. Else
    1. EnqueueResolveInAgentJob(waiterRecord.[[AgentSignifier]], waiterRecord.[[PromiseCapability]], waiterRecord.[[Result]]) 수행.
  5. Return unused.
Note

에이전트는 호스트에 전달하는 것 외에 다른 에이전트의 promise capability 에 접근해서는 안 된다.

25.4.3.13 EnqueueResolveInAgentJob ( agentSignifier, promiseCapability, resolution )

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

  1. resolveJob = 매개변수 없고 agentSignifier, promiseCapability, resolution 을 캡처하며 호출 시:
    1. Assert: AgentSignifier() = agentSignifier.
    2. Call(promiseCapability.[[Resolve]], undefined, « resolution ») 수행.
    3. Return unused.
  2. realmInTargetAgent = ! GetFunctionRealm(promiseCapability.[[Resolve]]).
  3. Assert: agentSignifier = realmInTargetAgent.[[AgentSignifier]].
  4. HostEnqueueGenericJob(resolveJob, realmInTargetAgent) 수행.
  5. Return unused.

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

The abstract operation DoWait takes arguments mode (sync or async), typedArray (an ECMAScript language value), index (an ECMAScript language value), value (an ECMAScript language value), and timeout (an ECMAScript language value) and returns 정상 완료(Object, "not-equal", "timed-out", "ok" 중 하나) 또는 throw completion. It performs the following steps when called:

  1. taRecord = ? ValidateIntegerTypedArray(typedArray, true).
  2. buffer = taRecord.[[Object]].[[ViewedArrayBuffer]].
  3. IsSharedArrayBuffer(buffer) = false 이면 TypeError 예외.
  4. i = ? ValidateAtomicAccess(taRecord, index).
  5. arrayTypeName = typedArray.[[TypedArrayName]].
  6. arrayTypeName = "BigInt64Array" 이면 v = ? ToBigInt64(value); Else v = ? ToInt32(value).
  7. q = ? ToNumber(timeout).
  8. qNaN 또는 +∞𝔽 이면 t = +∞; else if q = -∞𝔽 이면 t = 0; else t = max((q), 0).
  9. mode = sync 그리고 AgentCanSuspend() = false 이면 TypeError 예외.
  10. block = buffer.[[ArrayBufferData]].
  11. offset = typedArray.[[ByteOffset]].
  12. byteIndexInBuffer = (i × 4) + offset.
  13. WL = GetWaiterList(block, byteIndexInBuffer).
  14. mode = sync 이면
    1. promiseCapability = blocking.
    2. resultObject = undefined.
  15. Else
    1. promiseCapability = ! NewPromiseCapability(%Promise%).
    2. resultObject = OrdinaryObjectCreate(%Object.prototype%).
  16. EnterCriticalSection(WL) 수행.
  17. elementType = TypedArrayElementType(typedArray).
  18. w = GetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst).
  19. vw 이면
    1. LeaveCriticalSection(WL) 수행.
    2. mode = sync 이면 "not-equal" 반환.
    3. CreateDataPropertyOrThrow(resultObject, "async", false) 수행.
    4. CreateDataPropertyOrThrow(resultObject, "value", "not-equal") 수행.
    5. Return resultObject.
  20. t = 0 그리고 mode = async 이면
    1. NOTE: 동기 즉시 타임아웃은 특별 처리 없음. 비동기 즉시 타임아웃은 빠른 실패를 위해 특별 처리.
    2. LeaveCriticalSection(WL) 수행.
    3. CreateDataPropertyOrThrow(resultObject, "async", false) 수행.
    4. CreateDataPropertyOrThrow(resultObject, "value", "timed-out") 수행.
    5. Return resultObject.
  21. thisAgent = AgentSignifier().
  22. now = 현재 시간(UTC) time value.
  23. additionalTimeout = 구현 정의 음이 아닌 수학적 값.
  24. timeoutTime = (now) + t + additionalTimeout.
  25. NOTE: t = +∞ 이면 timeoutTime 도 +∞.
  26. waiterRecord = 새 Waiter Record { [[AgentSignifier]]: thisAgent, [[PromiseCapability]]: promiseCapability, [[TimeoutTime]]: timeoutTime, [[Result]]: "ok" }.
  27. AddWaiter(WL, waiterRecord) 수행.
  28. mode = sync 이면
    1. SuspendThisAgent(WL, waiterRecord) 수행.
  29. Else if timeoutTime 유한이면
    1. EnqueueAtomicsWaitAsyncTimeoutJob(WL, waiterRecord) 수행.
  30. LeaveCriticalSection(WL) 수행.
  31. mode = sync 이면 waiterRecord.[[Result]] 반환.
  32. CreateDataPropertyOrThrow(resultObject, "async", true) 수행.
  33. CreateDataPropertyOrThrow(resultObject, "value", promiseCapability.[[Promise]]) 수행.
  34. Return resultObject.
Note

additionalTimeout 은 전력 소비 감소나 타이밍 공격 완화를 위한 타이머 해상도 조정 등 필요 시 타임아웃에 패딩을 허용한다. 호출마다 값이 다를 수 있다.

25.4.3.15 EnqueueAtomicsWaitAsyncTimeoutJob ( WL, waiterRecord )

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

  1. timeoutJob = 매개변수 없고 WL, waiterRecord 캡처하며 호출 시:
    1. EnterCriticalSection(WL) 수행.
    2. WL.[[Waiters]]waiterRecord 포함하면
      1. timeOfJobExecution = 현재 시간(UTC) time value.
      2. Assert: (timeOfJobExecution) ≥ waiterRecord.[[TimeoutTime]] (시간 비단조 가능성 무시).
      3. waiterRecord.[[Result]] = "timed-out".
      4. RemoveWaiter(WL, waiterRecord) 수행.
      5. NotifyWaiter(WL, waiterRecord) 수행.
    3. LeaveCriticalSection(WL) 수행.
    4. Return unused.
  2. now = 현재 시간(UTC) time value.
  3. currentRealm = 현재 Realm Record.
  4. HostEnqueueTimeoutJob(timeoutJob, currentRealm, 𝔽(waiterRecord.[[TimeoutTime]]) - now) 수행.
  5. Return unused.

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

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

  1. execution = 주변 에이전트 Agent Record.[[CandidateExecution]].
  2. eventsRecord = execution.[[EventsRecords]][[AgentSignifier]] = AgentSignifier() 인 것.
  3. rawBytesRead = 길이 elementSize 이고 요소가 비결정적으로 선택된 바이트 값 List.
  4. NOTE: 구현에서 rawBytesRead 는 load-link, load-exclusive, 또는 read-modify-write 명령의 피연산자 결과. 비결정성은 약한 일관성 하드웨어 관측 가능 동작을 기술.
  5. NOTE: 기대값과 읽은 값 비교는 기대값 불일치 시 불필요한 강한 동기화를 피하기 위해 read-modify-write 수정 함수 밖에서 수행.
  6. ByteListEqual(rawBytesRead, expectedBytes) = true 이면
    1. second = 매개변수 (oldBytes, newBytes) 를 가지고 아무것도 캡처하지 않으며 호출 시 원자적으로 newBytes 반환하는 새 read-modify-write 수정 함수.
    2. event = ReadModifyWriteSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize, [[Payload]]: replacementBytes, [[ModifyOp]]: second }.
  7. Else
    1. event = ReadSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize }.
  8. eventsRecord.[[EventList]]event 추가.
  9. execution.[[ChosenValues]]Chosen Value Record { [[Event]]: event, [[ChosenValue]]: rawBytesRead } 추가.
  10. Return rawBytesRead.

25.4.3.17 AtomicReadModifyWrite ( typedArray, index, value, op )

The abstract operation AtomicReadModifyWrite takes arguments typedArray (an ECMAScript language value), index (an ECMAScript language value), value (an ECMAScript language value), and op (a read-modify-write modification function) and returns 정상 완료(Number 또는 BigInt) 또는 throw completion. op 는 두 List (바이트 값) 인수를 받아 바이트 값 List 를 반환한다. 이 연산은 원자적으로 값을 로드하고 다른 값과 결합 후 저장하며 로드한 값을 반환한다. It performs the following steps when called:

  1. byteIndexInBuffer = ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. typedArray.[[ContentType]] = bigint 이면 v = ? ToBigInt(value); 아니면 v = 𝔽(? ToIntegerOrInfinity(value)).
  3. RevalidateAtomicAccess(typedArray, byteIndexInBuffer) 수행.
  4. buffer = typedArray.[[ViewedArrayBuffer]].
  5. elementType = TypedArrayElementType(typedArray).
  6. Return GetModifySetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, op).

25.4.3.18 ByteListBitwiseOp ( op, xBytes, yBytes )

The abstract operation ByteListBitwiseOp takes arguments op (&, ^, or |), xBytes (a List of byte values), and yBytes (a List of byte values) and returns 바이트 값 List. 모든 바이트에 대한 비트 연산을 수행하고 바이트 값 List 를 원자적으로 반환한다. It performs the following steps when called:

  1. Assert: xBytesyBytes 는 동일한 길이.
  2. result = 새 빈 List.
  3. i = 0.
  4. xBytes 요소 xByte 에 대해
    1. yByte = yBytes[i].
    2. op = & 이면
      1. resultByte = xByte AND yByte.
    3. Else if op = ^ 이면
      1. resultByte = xByte XOR yByte.
    4. Else
      1. Assert: op = |.
      2. resultByte = xByte OR yByte.
    5. i = i + 1.
    6. resultresultByte 추가.
  5. Return result.

25.4.3.19 ByteListEqual ( xBytes, yBytes )

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

  1. xBytes, yBytes 길이 다르면 false 반환.
  2. i = 0.
  3. xBytes 요소 xByte 에 대해
    1. yByte = yBytes[i].
    2. xByteyByte 이면 false 반환.
    3. i = i + 1.
  4. Return true.

25.4.4 Atomics.add ( typedArray, index, value )

이 함수는 호출 시 다음 단계를 수행한다:

  1. add = 매개변수 (xBytes, yBytes) 를 가지고 typedArray 를 캡처하며 호출 시 원자적으로:
    1. type = TypedArrayElementType(typedArray).
    2. isLittleEndian = 주변 에이전트 Agent Record[[LittleEndian]] 값.
    3. x = RawBytesToNumeric(type, xBytes, isLittleEndian).
    4. y = RawBytesToNumeric(type, yBytes, isLittleEndian).
    5. x 가 Number 이면
      1. sum = Number::add(x, y).
    6. Else
      1. Assert: x 는 BigInt.
      2. sum = BigInt::add(x, y).
    7. sumBytes = NumericToRawBytes(type, sum, isLittleEndian).
    8. Assert: sumBytes, xBytes, yBytes 길이 동일.
    9. Return sumBytes.
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, add).

25.4.5 Atomics.and ( typedArray, index, value )

이 함수는 호출 시 다음 단계를 수행한다:

  1. and = 매개변수 (xBytes, yBytes) 를 가지고 아무것도 캡처하지 않으며 호출 시 원자적으로:
    1. Return ByteListBitwiseOp(&, xBytes, yBytes).
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, and).

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

이 함수는 호출 시 다음 단계를 수행한다:

  1. byteIndexInBuffer = ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. buffer = typedArray.[[ViewedArrayBuffer]].
  3. block = buffer.[[ArrayBufferData]].
  4. typedArray.[[ContentType]] = bigint 이면
    1. expected = ? ToBigInt(expectedValue).
    2. replacement = ? ToBigInt(replacementValue).
  5. Else
    1. expected = 𝔽(? ToIntegerOrInfinity(expectedValue)).
    2. replacement = 𝔽(? ToIntegerOrInfinity(replacementValue)).
  6. RevalidateAtomicAccess(typedArray, byteIndexInBuffer) 수행.
  7. elementType = TypedArrayElementType(typedArray).
  8. elementSize = TypedArrayElementSize(typedArray).
  9. isLittleEndian = 주변 에이전트 Agent Record.[[LittleEndian]].
  10. expectedBytes = NumericToRawBytes(elementType, expected, isLittleEndian).
  11. replacementBytes = NumericToRawBytes(elementType, replacement, isLittleEndian).
  12. IsSharedArrayBuffer(buffer) = true 이면
    1. rawBytesRead = AtomicCompareExchangeInSharedBlock(block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes).
  13. Else
    1. rawBytesRead = 길이 elementSizeList ( block[byteIndexInBuffer] 로부터 elementSize 바이트 ).
    2. ByteListEqual(rawBytesRead, expectedBytes) = true 이면
      1. replacementBytes 바이트들을 block[byteIndexInBuffer] 부터 저장.
  14. Return RawBytesToNumeric(elementType, rawBytesRead, isLittleEndian).

25.4.7 Atomics.exchange ( typedArray, index, value )

이 함수는 호출 시 다음 단계를 수행한다:

  1. second = 매개변수 (oldBytes, newBytes) 를 가지며 아무것도 캡처하지 않고 호출 시 원자적으로 newBytes 반환하는 read-modify-write 수정 함수.
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, second).

25.4.8 Atomics.isLockFree ( size )

이 함수는 호출 시 다음 단계를 수행한다:

  1. n = ? ToIntegerOrInfinity(size).
  2. AR = 주변 에이전트의 Agent Record.
  3. n = 1 이면 AR.[[IsLockFree1]] 반환.
  4. n = 2 이면 AR.[[IsLockFree2]] 반환.
  5. n = 4 이면 true 반환.
  6. n = 8 이면 AR.[[IsLockFree8]] 반환.
  7. Return false.
Note

이 함수는 최적화용 프리미티브이다. 크기 n 바이트 데이터에 대한 atomic primitive (compareExchange, load, store, add, sub, and, or, xor, exchange) 의 원자 단계가 주변 에이전트가 데이터 범위를 넘어서는 lock 을 획득하지 않고 수행된다면 Atomics.isLockFree(n) 은 true 를 반환한다는 직관을 제공한다. 고성능 알고리즘은 이 함수를 사용해 임계 영역에서 락 vs 원자 연산 사용을 결정한다. 원자 프리미티브가 lock-free 가 아니면 자체 락을 제공하는 편이 종종 더 효율적이다.

Atomics.isLockFree(4) 는 관련 하드웨어 모두에서 지원 가능하므로 항상 true 를 반환한다. 이는 프로그램 단순화에 도움된다.

이 함수 반환값과 무관하게 모든 원자 연산은 원자성이 보장된다. 즉 중간 연산(예: “tearing”)이 관측되지 않는다.

25.4.9 Atomics.load ( typedArray, index )

이 함수는 호출 시 다음 단계를 수행한다:

  1. byteIndexInBuffer = ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. RevalidateAtomicAccess(typedArray, byteIndexInBuffer) 수행.
  3. buffer = typedArray.[[ViewedArrayBuffer]].
  4. elementType = TypedArrayElementType(typedArray).
  5. Return GetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst).

25.4.10 Atomics.or ( typedArray, index, value )

이 함수는 호출 시 다음 단계를 수행한다:

  1. or = 매개변수 (xBytes, yBytes) 를 가지고 아무것도 캡처하지 않으며 호출 시 원자적으로:
    1. Return ByteListBitwiseOp(|, xBytes, yBytes).
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, or).

25.4.11 Atomics.store ( typedArray, index, value )

이 함수는 호출 시 다음 단계를 수행한다:

  1. byteIndexInBuffer = ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. typedArray.[[ContentType]] = bigint 이면 v = ? ToBigInt(value); 아니면 v = 𝔽(? ToIntegerOrInfinity(value)).
  3. RevalidateAtomicAccess(typedArray, byteIndexInBuffer) 수행.
  4. buffer = typedArray.[[ViewedArrayBuffer]].
  5. elementType = TypedArrayElementType(typedArray).
  6. SetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, true, seq-cst) 수행.
  7. Return v.

25.4.12 Atomics.sub ( typedArray, index, value )

이 함수는 호출 시 다음 단계를 수행한다:

  1. subtract = 매개변수 (xBytes, yBytes) 를 가지고 typedArray 를 캡처하며 호출 시 원자적으로:
    1. type = TypedArrayElementType(typedArray).
    2. isLittleEndian = 주변 에이전트 Agent Record.[[LittleEndian]].
    3. x = RawBytesToNumeric(type, xBytes, isLittleEndian).
    4. y = RawBytesToNumeric(type, yBytes, isLittleEndian).
    5. x 가 Number 이면
      1. difference = Number::subtract(x, y).
    6. Else
      1. Assert: x 는 BigInt.
      2. difference = BigInt::subtract(x, y).
    7. differenceBytes = NumericToRawBytes(type, difference, isLittleEndian).
    8. Assert: differenceBytes, xBytes, yBytes 길이 동일.
    9. Return differenceBytes.
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, subtract).

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

이 함수는 주변 에이전트를 대기 큐에 두고 알림 또는 타임아웃까지 일시중단하며 결과 구분 문자열을 반환한다.

호출 시 다음 단계를 수행한다:

  1. Return ? DoWait(sync, typedArray, index, value, timeout).

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

이 함수는 호출 에이전트가 알림을 받거나 타임아웃에 도달했을 때 resolve 되는 Promise 를 반환한다.

호출 시 다음 단계를 수행한다:

  1. Return ? DoWait(async, typedArray, index, value, timeout).

25.4.15 Atomics.notify ( typedArray, index, count )

이 함수는 대기 큐에서 잠자고 있는 일부 에이전트를 깨운다.

호출 시 다음 단계를 수행한다:

  1. taRecord = ? ValidateIntegerTypedArray(typedArray, true).
  2. byteIndexInBuffer = ? ValidateAtomicAccess(taRecord, index).
  3. count = undefined 이면
    1. c = +∞.
  4. Else
    1. intCount = ? ToIntegerOrInfinity(count).
    2. c = max(intCount, 0).
  5. buffer = typedArray.[[ViewedArrayBuffer]].
  6. block = buffer.[[ArrayBufferData]].
  7. IsSharedArrayBuffer(buffer) = false 이면 +0𝔽 반환.
  8. WL = GetWaiterList(block, byteIndexInBuffer).
  9. EnterCriticalSection(WL) 수행.
  10. S = RemoveWaiters(WL, c).
  11. S 요소 W 에 대해
    1. NotifyWaiter(WL, W) 수행.
  12. LeaveCriticalSection(WL) 수행.
  13. n = S 요소 수.
  14. Return 𝔽(n).

25.4.16 Atomics.xor ( typedArray, index, value )

이 함수는 호출 시 다음 단계를 수행한다:

  1. xor = 매개변수 (xBytes, yBytes) 를 가지고 아무것도 캡처하지 않으며 호출 시 원자적으로:
    1. Return ByteListBitwiseOp(^, xBytes, yBytes).
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, xor).

25.4.17 Atomics [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 프로퍼티 초기 값은 String "Atomics" 이다.

이 프로퍼티 특성은 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.5 JSON 객체

JSON 객체:

  • %JSON% 이다.
  • 전역 객체 "JSON" 프로퍼티의 초기 값이다.
  • 일반 객체이다.
  • JSON 텍스트를 파싱 및 구성하기 위한 parsestringify 두 함수 포함.
  • 값이 %Object.prototype%[[Prototype]] 내부 슬롯을 가진다.
  • [[Construct]] 내부 메서드가 없어 new 생성자로 사용할 수 없다.
  • [[Call]] 내부 메서드가 없어 함수로 호출할 수 없다.

JSON 데이터 교환 형식은 ECMA-404 에 정의된다. 본 명세에서 사용하는 JSON 교환 형식은 ECMA-404 에 기술된 것과 정확히 동일하다. JSON.parseJSON.stringify 의 적합 구현은 ECMA-404 명세에 기술된 교환 형식을 삭제나 확장 없이 정확히 지원해야 한다.

25.5.1 JSON.parse ( text [ , reviver ] )

이 함수는 JSON 텍스트(JSON 형식 문자열)를 파싱하여 ECMAScript 언어 값을 생성한다. JSON 형식은 ECMAScript 리터럴, 배열 초기자, 객체 초기자와 유사한 구문으로 리터럴, 배열, 객체를 표현한다. 파싱 후 JSON 객체는 ECMAScript 객체로, JSON 배열은 ECMAScript Array 인스턴스로 실현된다. JSON 문자열, 숫자, 불리언, null 은 ECMAScript String, Number, Boolean 및 null 로 실현된다.

선택적 reviver 매개변수는 key, value 두 매개변수를 받는 함수로 결과를 필터/변환할 수 있다. 파싱에서 생성된 각 key/value 쌍에 대해 호출되며 반환값이 원래 값 대신 사용된다. 받은 값을 그대로 반환하면 구조는 수정되지 않는다. undefined 를 반환하면 그 프로퍼티는 결과에서 삭제된다.

  1. jsonString = ? ToString(text).
  2. unfiltered = ? ParseJSON(jsonString).
  3. IsCallable(reviver) = true 이면
    1. root = OrdinaryObjectCreate(%Object.prototype%).
    2. rootName = 빈 문자열.
    3. CreateDataPropertyOrThrow(root, rootName, unfiltered) 수행.
    4. Return ? InternalizeJSONProperty(root, rootName, reviver).
  4. Else
    1. Return unfiltered.

이 함수의 "length" 프로퍼티는 2𝔽이다.

25.5.1.1 ParseJSON ( text )

The abstract operation ParseJSON takes argument text (a String) and returns 정상 완료(ECMAScript 언어 값) 또는 throw completion. It performs the following steps when called:

  1. StringToCodePoints(text) 가 ECMA-404 에 지정된 유효한 JSON 텍스트가 아니면 SyntaxError 예외.
  2. scriptString = "("text");" 의 문자열 연결.
  3. script = ParseText(scriptString, Script).
  4. NOTE: 13.2.5.1 에 정의된 초기 에러 규칙은 위 ParseText 호출에 대해 특별 처리.
  5. Assert: script 는 Parse Node.
  6. result = ! Evaluation of script.
  7. NOTE: 13.2.5.5 에 정의된 PropertyDefinitionEvaluation 의미론은 위 평가에 대해 특별 처리.
  8. Assert: result 는 String, Number, Boolean, ArrayLiteral 또는 ObjectLiteral 로 정의된 Object, 또는 null.
  9. Return result.

적합한 JSON.parse 구현은 JSON 문법을 확장할 수 없다. 수정/확장된 JSON 교환 형식을 지원하려면 다른 parse 함수를 정의해야 한다.

Note 1

유효 JSON 텍스트는 ECMAScript PrimaryExpression 구문의 부분집합이다. 단계 1jsonString 이 그 부분집합에 부합하는지 검증하고, 8 는 평가 결과가 적절한 타입임을 단언한다.

그러나 13.2.5.5 가 ParseJSON 중 다르게 동작하므로, 동일 소스 텍스트가 PrimaryExpression 으로 평가될 때와 JSON 으로 평가될 때 다른 결과를 낼 수 있다. 또한 객체 리터럴에서 중복 "__proto__" 프로퍼티에 대한 Early Error 가 ParseJSON 중에는 적용되지 않으므로 문법과 일치해도 ParseJSON 이 허용하는 텍스트 일부는 PrimaryExpression 으로 유효하지 않다.

Note 2

객체 내 이름 문자열이 중복될 경우 동일 키의 앞선 값들은 덮어써진다.

25.5.1.2 InternalizeJSONProperty ( holder, name, reviver )

The abstract operation InternalizeJSONProperty takes arguments holder (an Object), name (a String), and reviver (a function object) and returns 정상 완료(ECMAScript 언어 값) 또는 throw completion.

Note

이 알고리즘은 [[Delete]] 또는 CreateDataPropertyfalse 를 반환해도 예외를 던지지 않도록 의도되었다.

호출 시 다음 단계를 수행한다:

  1. val = ? Get(holder, name).
  2. val 이 Object 이면
    1. isArray = ? IsArray(val).
    2. isArray = true 이면
      1. len = ? LengthOfArrayLike(val).
      2. I = 0.
      3. 반복, I < len 동안
        1. prop = ! ToString(𝔽(I)).
        2. newElement = ? InternalizeJSONProperty(val, prop, reviver).
        3. newElement = undefined 이면
          1. val.[[Delete]](prop) 수행.
        4. Else
          1. CreateDataProperty(val, prop, newElement) 수행.
        5. I = I + 1.
    3. Else
      1. keys = ? EnumerableOwnProperties(val, key).
      2. 각 String Pkeys 에 대해
        1. newElement = ? InternalizeJSONProperty(val, P, reviver).
        2. newElement = undefined 이면
          1. val.[[Delete]](P) 수행.
        3. Else
          1. CreateDataProperty(val, P, newElement) 수행.
  3. Return ? Call(reviver, holder, « name, val »).

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

이 함수는 ECMAScript 언어 값을 UTF-16 인코딩된 JSON 형식 String 또는 undefined 로 반환한다. 세 매개변수를 받을 수 있다. value 는 일반적으로 객체나 배열이지만 String, Boolean, Number, null 일 수도 있다. 선택적 replacer 는 객체/배열을 문자열화하는 방식을 바꾸는 함수이거나 문자열/숫자 배열(포함 리스트)이다. 선택적 space 는 결과에 공백을 삽입해 가독성을 높이기 위한 String 또는 Number 이다.

호출 시 다음 단계를 수행한다:

  1. stack = 새 빈 List.
  2. indent = 빈 문자열.
  3. PropertyList = undefined.
  4. ReplacerFunction = undefined.
  5. replacer 가 Object 이면
    1. IsCallable(replacer) = true 이면
      1. ReplacerFunction = replacer.
    2. Else
      1. isArray = ? IsArray(replacer).
      2. isArray = true 이면
        1. PropertyList = 새 빈 List.
        2. len = ? LengthOfArrayLike(replacer).
        3. k = 0.
        4. 반복, k < len 동안
          1. prop = ! ToString(𝔽(k)).
          2. v = ? Get(replacer, prop).
          3. item = undefined.
          4. v 가 String 이면
            1. item = v.
          5. Else if v 가 Number 이면
            1. item = ! ToString(v).
          6. Else if v 가 Object 이면
            1. v[[StringData]] 또는 [[NumberData]] 내부 슬롯이 있으면 item = ? ToString(v).
          7. itemundefined 그리고 PropertyListitem 이 없으면
            1. PropertyListitem 추가.
          8. k = k + 1.
  6. space 가 Object 이면
    1. space[[NumberData]] 내부 슬롯을 가지면
      1. space = ? ToNumber(space).
    2. Else if space[[StringData]] 내부 슬롯을 가지면
      1. space = ? ToString(space).
  7. space 가 Number 이면
    1. spaceMV = ! ToIntegerOrInfinity(space).
    2. spaceMV = min(10, spaceMV).
    3. spaceMV < 1 이면 gap = 빈 문자열; 아니면 gap = 코드 유닛 0x0020 (SPACE) * spaceMV 개.
  8. Else if space 가 String 이면
    1. space 길이 ≤ 10 이면 gap = space; 아니면 gap = space 의 0~10 부분 문자열.
  9. Else
    1. gap = 빈 문자열.
  10. wrapper = OrdinaryObjectCreate(%Object.prototype%).
  11. CreateDataPropertyOrThrow(wrapper, 빈 문자열, value) 수행.
  12. state = JSON Serialization Record { [[ReplacerFunction]]: ReplacerFunction, [[Stack]]: stack, [[Indent]]: indent, [[Gap]]: gap, [[PropertyList]]: PropertyList }.
  13. Return ? SerializeJSONProperty(state, 빈 문자열, wrapper).

이 함수의 "length" 프로퍼티는 3𝔽이다.

Note 1

JSON 구조는 임의 깊이로 중첩 가능하지만 비순환이어야 한다. value 가 순환 구조이면 TypeError 예외를 던져야 한다. 예:

a = [];
a[0] = a;
my_text = JSON.stringify(a); // 여기서는 TypeError 가 발생해야 함.
Note 2

기호적(심볼이 아님) 기본 값들은 다음과 같이 표현된다:

  • null 값 → 문자열 "null".
  • undefined 값 → 렌더되지 않음.
  • true 값 → 문자열 "true".
  • false 값 → 문자열 "false".
Note 3

문자열 값은 QUOTATION MARK (") 코드 유닛으로 둘러싸인다. 코드 유닛 "\\ 접두로 이스케이프. 제어 문자 코드 유닛은 \uHHHH 또는 더 짧은 \b, \f, \n, \r, \t 로 대체.

Note 4

유한수는 ToString(number) 호출과 같이 문자열화된다. 부호와 무관하게 NaN, Infinity 는 문자열 "null" 로 표현.

Note 5

JSON 표현이 없는 값(undefined, 함수 등)은 문자열을 생성하지 않고 undefined 반환. 배열에서는 "null" 로, 객체에서는 해당 프로퍼티가 제외된다.

Note 6

객체는 U+007B 후 0개 이상 프로퍼티 (U+002C 로 구분), U+007D 로 닫힘. 프로퍼티는 따옴표로 둘러싼 이름, U+003A, 문자열화된 값. 배열은 U+005B 후 값들(콤마 구분), U+005D 로 닫힘.

25.5.2.1 JSON Serialization Record

JSON Serialization Record 는 JSON 형식 직렬화를 가능하게 하는 Record 값이다.

JSON Serialization Record 는 Table 78 필드를 가진다.

Table 78: JSON Serialization Record 필드
필드 이름 의미
[[ReplacerFunction]] 함수 객체 또는 undefined 객체 프로퍼티 대체 값을 제공 (JSON.stringify 의 replacer).
[[PropertyList]] 문자열 List 또는 undefined 비배열 객체 직렬화 시 포함할 프로퍼티 이름들 (replacer).
[[Gap]] String 들여쓰기 단위 (space).
[[Stack]] Object List 직렬화 진행 중 중첩 객체 집합 (순환 감지).
[[Indent]] String 현재 들여쓰기.

25.5.2.2 SerializeJSONProperty ( state, key, holder )

The abstract operation SerializeJSONProperty takes arguments state (a JSON Serialization Record), key (a String), and holder (an Object) and returns 정상 완료(String 또는 undefined) 또는 throw completion. It performs the following steps when called:

  1. value = ? Get(holder, key).
  2. value 가 Object 또는 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. [[NumberData]] 슬롯 있으면 value = ? ToNumber(value).
    2. Else if [[StringData]] 슬롯 있으면 value = ? ToString(value).
    3. Else if [[BooleanData]] 슬롯 있으면 value = value.[[BooleanData]].
    4. Else if [[BigIntData]] 슬롯 있으면 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유한수면 ! ToString(value) 반환.
    2. "null" 반환.
  10. value 가 BigInt 이면 TypeError 예외.
  11. value 가 Object 이고 IsCallable(value) = false 이면
    1. isArray = ? IsArray(value).
    2. isArray = true 이면 ? SerializeJSONArray(state, value) 반환.
    3. Return ? SerializeJSONObject(state, value).
  12. Return undefined.

25.5.2.3 QuoteJSONString ( value )

The abstract operation QuoteJSONString takes argument value (a String) and returns String. value 를 0x0022 (QUOTATION MARK) 코드 유닛으로 감싸고 특정 코드 유닛을 이스케이프한다. 이 연산은 6.1.4 에 기술된 대로 value 를 UTF-16 인코딩 코드 포인트 시퀀스로 해석한다. It performs the following steps when called:

  1. product = 코드 유닛 0x0022 로만 구성된 String.
  2. StringToCodePoints(value) 의 각 코드 포인트 C 에 대해
    1. CTable 79 “Code Point” 열에 나열되면
      1. product = product + 해당 행 “Escape Sequence” 열의 이스케이프 시퀀스.
    2. Else if C 의 수치값 < 0x0020 또는 선행/후행 서로게이트와 동일 수치값이면
      1. unit = C 의 수치값을 가진 코드 유닛.
      2. product = product + UnicodeEscape(unit).
    3. Else
      1. product = product + UTF16EncodeCodePoint(C).
  3. product = product + 코드 유닛 0x0022.
  4. Return product.
Table 79: JSON 단일 문자 이스케이프 시퀀스
Code Point 유니코드 이름 Escape Sequence
U+0008 BACKSPACE \b
U+0009 CHARACTER TABULATION \t
U+000A LINE FEED (LF) \n
U+000C FORM FEED (FF) \f
U+000D CARRIAGE RETURN (CR) \r
U+0022 QUOTATION MARK \"
U+005C REVERSE SOLIDUS \\

25.5.2.4 UnicodeEscape ( C )

The abstract operation UnicodeEscape takes argument C (a code unit) and returns String. C 를 유니코드 이스케이프 시퀀스로 표현한다. It performs the following steps when called:

  1. n = C 의 수치값.
  2. Assert: n ≤ 0xFFFF.
  3. hex = n 의 소문자 16진수 문자열 표현.
  4. Return 코드 유닛 0x005C (REVERSE SOLIDUS) + "u" + StringPad(hex, 4, "0", start).

25.5.2.5 SerializeJSONObject ( state, value )

The abstract operation SerializeJSONObject takes arguments state (a JSON Serialization Record) and value (an Object) and returns 정상 완료(String) 또는 throw completion. 객체를 직렬화한다. It performs the following steps when called:

  1. state.[[Stack]]value 를 포함하면 순환 구조이므로 TypeError 예외.
  2. state.[[Stack]]value 추가.
  3. stepBack = state.[[Indent]].
  4. state.[[Indent]] = state.[[Indent]] + state.[[Gap]].
  5. state.[[PropertyList]]undefined 이면
    1. K = state.[[PropertyList]].
  6. Else
    1. K = ? EnumerableOwnProperties(value, key).
  7. partial = 새 빈 List.
  8. K 요소 P 에 대해
    1. strP = ? SerializeJSONProperty(state, P, value).
    2. strPundefined 이면
      1. member = QuoteJSONString(P).
      2. member = member + ":".
      3. state.[[Gap]] ≠ 빈 문자열이면
        1. member = member + 코드 유닛 0x0020 (SPACE).
      4. member = member + strP.
      5. partialmember 추가.
  9. partial 이 비어 있으면
    1. final = "{}".
  10. Else
    1. state.[[Gap]] = 빈 문자열이면
      1. properties = partial 요소를 0x002C (COMMA) 로 연결한 String (선/후방 콤마 없음).
      2. final = "{" + properties + "}".
    2. Else
      1. separator = 0x002C (COMMA) + 0x000A (LINE FEED) + state.[[Indent]].
      2. properties = partial 요소를 separator 로 연결한 String.
      3. final = "{" + 0x000A + state.[[Indent]] + properties + 0x000A + stepBack + "}".
  11. state.[[Stack]] 마지막 요소 제거.
  12. state.[[Indent]] = stepBack.
  13. Return final.

25.5.2.6 SerializeJSONArray ( state, value )

The abstract operation SerializeJSONArray takes arguments state (a JSON Serialization Record) and value (an ECMAScript language value) and returns 정상 완료(String) 또는 throw completion. 배열을 직렬화한다. It performs the following steps when called:

  1. state.[[Stack]]value 포함하면 순환이므로 TypeError 예외.
  2. state.[[Stack]]value 추가.
  3. stepBack = state.[[Indent]].
  4. state.[[Indent]] = state.[[Indent]] + state.[[Gap]].
  5. partial = 새 빈 List.
  6. len = ? LengthOfArrayLike(value).
  7. index = 0.
  8. 반복, index < len 동안
    1. strP = ? SerializeJSONProperty(state, ! ToString(𝔽(index)), value).
    2. strP = undefined 이면
      1. partial"null" 추가.
    3. Else
      1. partialstrP 추가.
    4. index = index + 1.
  9. partial 비어 있으면
    1. final = "[]".
  10. Else
    1. state.[[Gap]] = 빈 문자열이면
      1. properties = partial 요소를 0x002C (COMMA) 로 연결.
      2. final = "[" + properties + "]".
    2. Else
      1. separator = 0x002C (COMMA) + 0x000A (LINE FEED) + state.[[Indent]].
      2. properties = partial 요소를 separator 로 연결.
      3. final = "[" + 0x000A + state.[[Indent]] + properties + 0x000A + stepBack + "]".
  11. state.[[Stack]] 마지막 요소 제거.
  12. state.[[Indent]] = stepBack.
  13. Return final.
Note

배열 표현은 +0𝔽 이상 array.length 미만 인덱스 요소만 포함한다. 배열 인덱스가 아닌 키 프로퍼티는 제외된다. 배열은 여는 대괄호, 콤마로 구분된 요소, 닫는 대괄호로 문자열화된다.

25.5.3 JSON [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 프로퍼티 초기 값은 String "JSON" 이다.

이 프로퍼티 특성은 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.