If you find any part of this specification unclear or confusing, please file an issue .

I attempted to write this specification draft with an eye towards intelligibility and clarifying issues, rather than looking exactly like the final specification. In particular, the translation of the operations on the Number type into the new form are omitted, as they are identical to the previous definitions and would be expressed only as a lengthy refactoring to skip when reading this text.

This proposal adds arbitrary-precision integers to ECMAScript. For motivation and a high-level introduction, see the explainer document .

The abstract operation BigInt::sameValueZero with two arguments x and y of BigInt type:

The abstract operation BigInt::sameValue with two arguments x and y of BigInt type:

The abstract operation BigInt::equal with two arguments x and y of BigInt type returns true if x and y have the same mathematical integer value and false otherwise.

The abstract operation BigInt::lessThan with two arguments x and y of BigInt type returns true if x is less than y and false otherwise.

The abstract operation BigInt::unsignedRightShift with two arguments x and y of type BigInt:

The abstract operation BigInt::signedRightShift with arguments x and y of type BigInt:

Semantics here should be equivalent to a bitwise shift, treating the BigInt as an infinite length string of binary two's complement digits.

The abstract operation BigInt::leftShift with two arguments x and y of BigInt:

The abstract operation BigInt::subtract with two arguments x and y of BigInt type returns the BigInt representing the difference x minus y .

The abstract operation BigInt::add with two arguments x and y of BigInt type returns a BigInt representing the sum of x and y .

The sign of the result equals the sign of the dividend.

Even if the result has a much larger bit width than the input, the exact mathematical answer is given.

The abstract operation BigInt::multiply with two arguments x and y of BigInt type returns a BigInt representing the result of multiplying x and y .

The abstract operation BigInt::bitwiseNOT with an argument x of BigInt type returns the one's complement of x ; that is, - x - 1.

There is only one 0n value; -0n is the same as 0n .

The abstract operation BigInt::unaryMinus with an argument x of BigInt type returns the result of negating x .

The BigInt type represents a mathematical integer value. The value may be any size and is not limited to a particular bit-width. Generally, where not otherwise noted, operations are designed to return exact mathematically-based answers. For binary operations, BigInts act as two's complement binary strings, with negative numbers treated as having bits set infinitely to the left.

The first and subsequent editions of ECMAScript have provided, for certain operators, implicit numeric conversions that could lose precision or truncate. These legacy implicit conversions are maintained for backward compatibility, but not provided for BigInt in order to minimize opportunity for programmer error, and to leave open the option of generalized value types in a future edition.

Because the numeric types are in general not convertible without loss of precision or truncation, the ECMAScript language provides no implicit conversion among these types. Programmers must explicitly call Number and BigInt functions to convert among types when calling a function which requires another type.

The T ::unit value and T :: op operations are not a part of the ECMAScript language; they are defined here solely to aid the specification of the semantics of the ECMAScript language. Other abstract operations are defined throughout this specification.

ECMAScript has two built-in numeric types: Number and BigInt. In this specification, every numeric type T contains a multiplicative identity value denoted T ::unit. The specification types also have the following abstract operations, likewise denoted T :: op for a given operation with specification name op . Unless noted otherwise, argument and result types are all T .

The MV is rounded to a value of the Number type.

The comparison x === y , where x and y are values, produces true or false . Such a comparison is performed as follows:

The comparison x == y , where x and y are values, produces true or false . Such a comparison is performed as follows:

The comparison x < y , where x and y are values, produces true , false , or undefined (which indicates that at least one operand is NaN ). In addition to x and y the algorithm takes a Boolean flag named LeftFirst as a parameter. The flag is used to control the order in which operations with potentially visible side-effects are performed upon x and y . It is necessary because ECMAScript specifies left to right evaluation of expressions. The default value of LeftFirst is true and indicates that the x parameter corresponds to an expression that occurs to the left of the y parameter's corresponding expression. If LeftFirst is false , the reverse is the case and operations must be performed upon y before x . Such a comparison is performed as follows:

The internal comparison abstract operation SameValueNonNumeric( x , y ), where neither x nor y are numeric type values, produces true or false . Such a comparison is performed as follows:

The internal comparison abstract operation SameValueZero( x , y ), where x and y are ECMAScript language values, produces true or false . Such a comparison is performed as follows:

The internal comparison abstract operation SameValue( x , y ), where x and y are ECMAScript language values, produces true or false . Such a comparison is performed as follows:

The abstract operation RequireObjectCoercible throws an error if argument is a value that cannot be converted to an Object using ToObject . It is defined by Table 7 :

The abstract operation ToNumeric returns value converted to a numeric value of type Number or BigInt. This abstract operation functions as follows:

The abstract operation ToObject converts argument to a value of type Object according to Table 6 :

The abstract operation ToString converts a BigInt i to String format as follows:

The abstract operation ToString converts argument to a value of type String according to Table 5 :

Some differences should be noted between the syntax of a StringNumericLiteral and a NumericLiteral :

The abstract operation ToNumber converts argument to a value of type Number according to Table 4 :

The abstract operation ToBoolean converts argument to a value of type Boolean according to Table 3 :

The BigInt type has no implicit conversions in the ECMAScript language; programmers must call BigInt explicitly to convert values from other types.

The production A : A @ B , where @ is one of the bitwise operators in the productions above, is evaluated as follows:

Performs a zero-filling bitwise right shift operation on the left operand by the amount specified by the right operand.

Performs a sign-filling bitwise right shift operation on the left operand by the amount specified by the right operand.

Performs a bitwise left shift operation on the left operand by the amount specified by the right operand.

Step 7 differs from step 5 of the Abstract Relational Comparison algorithm, by using the logical-or operation instead of the logical-and operation.

No hint is provided in the calls to ToPrimitive in steps 5 and 6. All standard objects except Date objects handle the absence of a hint as if the hint Number were given; Date objects handle the absence of a hint as if the hint String were given. Exotic objects may handle the absence of a hint in some other manner.

The unary - operator converts its operand to Number type and then negates it. Negating +0 produces -0 , and negating -0 produces +0 .

The initial value of the @@toStringTag property is the String value "BigInt" .

The toString function is not generic; it throws a TypeError exception if its this value is not a BigInt or a BigInt object. Therefore, it cannot be transferred to other kinds of objects for use as a method.

The optional radix should be an integer value in the inclusive range 2 to 36. If radix not present or is undefined the Number 10 is used as the value of radix .

The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

Produces a String value that represents this BigInt value formatted according to the conventions of the host environment's current locale. This function is implementation-dependent, and it is permissible, but not encouraged, for it to return the same thing as toString .

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the BigInt.prototype.toLocaleString method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of the toLocaleString method is used.

The initial value of BigInt.prototype.constructor is the intrinsic object %BigInt% .

The phrase “this BigInt value” within the specification of a method refers to the result returned by calling the abstract operation thisBigIntValue with the this value of the method invocation passed as the argument.

The abstract operation thisBigIntValue( value ) performs the following steps:

The value of the [[Prototype]] internal slot of the BigInt prototype object is the intrinsic object %ObjectPrototype% .

The BigInt prototype object is the intrinsic object %BigIntPrototype% . The BigInt prototype object is an ordinary object. The BigInt prototype is not a BigInt object; it does not have a [[BigIntData]] internal slot.

The initial value of BigInt.prototype is the intrinsic object %BigIntPrototype% .

When the BigInt.asIntN is called with two arguments bits and bigint , the following steps are taken:

When the BigInt.asUintN function is called with two arguments bits and bigint , the following steps are taken:

The BigInt constructor has the following properties:

The value of the [[Prototype]] internal slot of the BigInt constructor is the intrinsic object %FunctionPrototype% .

When BigInt is called with argument value , the following steps are taken:

The BigInt constructor is not intended to be used with the new operator or to be subclassed. It may be used as the value of an extends clause of a class definition but a super call to the BigInt constructor will cause an exception.

The BigInt constructor is the %BigInt% intrinsic object and the initial value of the BigInt property of the global object . When BigInt is called as a function, it performs a type conversion.

Seein the second-to-last paragraph for the definition of the phrase "The Number value for".

When Number is called with argument value , the following steps are taken:

The abstract operation SerializeJSONProperty with arguments key , and holder has access to ReplacerFunction from the invocation of the stringify method. Its algorithm is as follows:

7 TypedArrays and DataViews

BigInt is integrated into TypedArray, DataView, SharedArrayBuffer and Atomics by providing Int64 and Uint64 access as represented by BigInts on the ECMAScript side.

7.1 TypedArray Objects Table 9: The TypedArray Constructors Constructor Name and Intrinsic Element Type Element Size Conversion Operation Description Equivalent C Type BigInt64Array

%BigInt64Array% BigInt64 8 ToBigInt64 64-bit two's complement signed integer signed long long BigUint64Array

%BigUint64Array% BigUint64 8 ToBigUint64 64-bit unsigned integer unsigned long long

7.2 StringToBigInt ( argument ) Apply the algorithm in 3.1.3.1 with the following changes: Replace the StrUnsignedDecimalLiteral production with DecimalDigits to not allow Infinity , decimal points, or exponents.

production with to not allow , decimal points, or exponents. If the MV is NaN , return NaN , otherwise return the BigInt which exactly corresponds to the MV, rather than rounding to a Number. Editor's Note "" ) is 0n according to the logic in 3.1.3.1 . StringToBigInt() isaccording to the logic in

7.3 ToBigInt ( argument ) The abstract operation ToBigInt converts its argument argument to a BigInt value, or throws if an implicit conversion from Number would be required. Let prim be ? ToPrimitive ( argument , hint Number). Return the value that prim corresponds to in Table 10 . Table 10: BigInt Conversions Argument Type Result Undefined Throw a TypeError exception. Null Throw a TypeError exception. Boolean Return 1n if prim is true and 0n if prim is false . BigInt Return prim . Number Throw a TypeError exception. String Let n be StringToBigInt ( prim ). If n is NaN , throw a SyntaxError exception. Return n . Symbol Throw a TypeError exception.

7.4 ToBigInt64 ( argument ) The abstract operation ToBigInt64 converts argument to one of 264 integer values in the range -263 through 263-1, inclusive. This abstract operation functions as follows: Let n be ? ToBigInt ( argument ). Let int64bit be n modulo 264. If int64bit ≥ 263, return int64bit - 264; otherwise return int64bit .

7.5 ToBigUint64 ( argument ) The abstract operation ToBigUint64 converts argument to one of 264 integer values in the range 0 through 264-1, inclusive. This abstract operation functions as follows: Let n be ? ToBigInt ( argument ). Let int64bit be n modulo 264. Return int64bit .

7.6 RawBytesTo Number Numeric ( type , rawBytes , isLittleEndian ) The abstract operation RawBytesTo Number Numeric takes three parameters, a String type , a List rawBytes , and a Boolean isLittleEndian . This operation performs the following steps: Let elementSize be the Number value of the Element Size value specified in Table 9 for Element Type type . If isLittleEndian is false , reverse the order of the elements of rawBytes . If type is "Float32" , then Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2008 binary32 value. If value is an IEEE 754-2008 binary32 NaN value, return the NaN Number value. Return the Number value that corresponds to value . If type is "Float64" , then Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2008 binary64 value. If value is an IEEE 754-2008 binary64 NaN value, return the NaN Number value. Return the Number value that corresponds to value . If the first code unit of type is "U" or type is "BigUint64" , then Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of an unsigned little-endian binary number. Else, Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of a binary little-endian two's complement number of bit length elementSize × 8. If type is "BigUint64" or "BigInt64" , return the BigInt value that corresponds to intValue . Otherwise, return the Number value that corresponds to intValue .

7.7 Number Numeric ToRawBytes( type , value , isLittleEndian ) The abstract operation Number Numeric ToRawBytes takes three parameters, a String type , a BigInt or a Number value , and a Boolean isLittleEndian . This operation performs the following steps: If type is "Float32" , then Set rawBytes to a List containing the 4 bytes that are the result of converting value to IEEE 754-2008 binary32 format using “Round to nearest, ties to even” rounding mode. If isLittleEndian is false , the bytes are arranged in big endian order. Otherwise, the bytes are arranged in little endian order. If value is NaN , rawValue may be set to any implementation chosen IEEE 754-2008 binary32 format Not-a-Number encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value. Else if type is "Float64" , then Set rawBytes to a List containing the 8 bytes that are the IEEE 754-2008 binary64 format encoding of value . If isLittleEndian is false , the bytes are arranged in big endian order. Otherwise, the bytes are arranged in little endian order. If value is NaN , rawValue may be set to any implementation chosen IEEE 754-2008 binary64 format Not-a-Number encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value. Else, Let n be the Number value of the Element Size specified in Table 9 for Element Type type . Let convOp be the abstract operation named in the Conversion Operation column in Table 9 for Element Type type . Let intValue be convOp ( value ) treated as a mathematical value, whether the result is a BigInt or Number . If intValue ≥ 0, then Let rawBytes be a List containing the n -byte binary encoding of intValue . If isLittleEndian is false , the bytes are ordered in big endian order. Otherwise, the bytes are ordered in little endian order. Else, Let rawBytes be a List containing the n -byte binary two's complement encoding of intValue . If isLittleEndian is false , the bytes are ordered in big endian order. Otherwise, the bytes are ordered in little endian order. Return rawBytes .

7.8 IntegerIndexedElementSet ( O , index , value ) The abstract operation IntegerIndexedElementSet with arguments O , index , and value performs the following steps: Assert: Type ( index ) is Number. Assert: O is an Object that has [[ViewedArrayBuffer]], [[ArrayLength]], [[ByteOffset]], and [[TypedArrayName]] internal slots. Let arrayTypeName be the String value of O .[[TypedArrayName]]. Let elementType be the String value of the Element Type value in Table 9 for arrayTypeName . If arrayTypeName is "BigUint64Array" or "BigInt64Array" , let numValue be ? ToBigInt ( value ). Otherwise, let numValue be ? ToNumber ( value ). Let buffer be O .[[ViewedArrayBuffer]]. If IsDetachedBuffer ( buffer ) is true , throw a TypeError exception. If IsInteger ( index ) is false , return false . If index = -0 , return false . Let length be O .[[ArrayLength]]. If index < 0 or index ≥ length , return false . Let offset be O .[[ByteOffset]]. Let elementSize be the Number value of the Element Size value specified in Table 9 for arrayTypeName . Let indexedPosition be ( index × elementSize ) + offset . Perform SetValueInBuffer ( buffer , indexedPosition , elementType , numValue , true , "Unordered" ). Return true .

7.9 SetValueInBuffer ( arrayBuffer , byteIndex , type , value , isTypedArray , order [ , isLittleEndian ] ) The abstract operation SetValueInBuffer takes seven parameters, an ArrayBuffer or SharedArrayBuffer arrayBuffer , an integer byteIndex , a String type , a Number value , a Boolean isTypedArray , a String order , and optionally a Boolean isLittleEndian . This operation performs the following steps: Assert: IsDetachedBuffer ( arrayBuffer ) is false . Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type . Assert: byteIndex is an integer value ≥ 0. Assert: Type ( value ) is BigInt if type is "BigInt64" or "BigUint64" ; otherwise, Type ( value ) is Number . Let block be arrayBuffer .[[ArrayBufferData]]. Let elementSize be the Number value of the Element Size value specified in Table 9 for Element Type type . If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent 's Agent Record . Let rawBytes be Number Numeric ToRawBytes( type , value , isLittleEndian ). If IsSharedArrayBuffer( arrayBuffer ) is true , then Let execution be the [[CandidateExecution]] field of the surrounding agent 's Agent Record . Let eventList be the [[EventList]] field of the element in execution .[[EventLists]] whose [[AgentSignifier]] is AgentSignifier(). If isTypedArray is true and type is "Int8" , "Uint8" , "Int16" , "Uint16" , "Int32" , or "Uint32" , or if type is "BigInt64" or "BigUint64" and order is not "Init" or "Unordered" , let noTear be true ; otherwise let noTear be false . Append WriteSharedMemory{ [[Order]]: order , [[NoTear]]: noTear , [[Block]]: block , [[ByteIndex]]: byteIndex , [[ElementSize]]: elementSize , [[Payload]]: rawBytes } to eventList . Else, store the individual bytes of rawBytes into block , in order, starting at block [ byteIndex ]. Return NormalCompletion ( undefined ). Editor's Note BigInt64 and BigUint64, like Float64, are excluded from the list of types which experience noTear writes. That is, non-atomic writes may be observed in a partially completed state.

7.10 GetValueFromBuffer ( arrayBuffer , byteIndex , type , isTypedArray , order [ , isLittleEndian ] ) The abstract operation GetValueFromBuffer takes six parameters, an ArrayBuffer or SharedArrayBuffer arrayBuffer , an integer byteIndex , a String type , a Boolean isTypedArray , a String order , and optionally a Boolean isLittleEndian . This operation performs the following steps: Assert: IsDetachedBuffer ( arrayBuffer ) is false . Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type . Assert: byteIndex is an integer value ≥ 0. Let block be arrayBuffer .[[ArrayBufferData]]. Let elementSize be the Number value of the Element Size value specified in Table 9 for Element Type type . If IsSharedArrayBuffer( arrayBuffer ) is true , then Let execution be the [[CandidateExecution]] field of the surrounding agent 's Agent Record . Let eventList be the [[EventList]] field of the element in execution .[[EventLists]] whose [[AgentSignifier]] is AgentSignifier(). If isTypedArray is true and type is "Int8" , "Uint8" , "Int16" , "Uint16" , "Int32" , or "Uint32" or if type is "BigInt64" or "BigUint64" and order is not "Init" or "Unordered" , let noTear be true ; otherwise let noTear be false . Let rawValue be a List of length elementSize of nondeterministically chosen byte values. NOTE: In implementations, rawValue is the result of a non-atomic or atomic read instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency. Let readEvent be ReadSharedMemory{ [[Order]]: order , [[NoTear]]: noTear , [[Block]]: block , [[ByteIndex]]: byteIndex , [[ElementSize]]: elementSize }. Append readEvent to eventList . Append Chosen Value Record { [[Event]]: readEvent , [[ChosenValue]]: rawValue } to execution .[[ChosenValues]]. Else, let rawValue be a List of elementSize containing, in order, the elementSize sequence of bytes starting with block [ byteIndex ]. If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent 's Agent Record . Return RawBytesTo Number Numeric ( type , rawValue , isLittleEndian ).

7.11 GetModifySetValueInBuffer( arrayBuffer , byteIndex , type , value , op [ , isLittleEndian ] ) The abstract operation GetModifySetValueInBuffer takes six parameters, a SharedArrayBuffer arrayBuffer , a nonnegative integer byteIndex , a String type , a Number value , a semantic function op , and optionally a Boolean isLittleEndian . This operation performs the following steps: Assert: IsSharedArrayBuffer( arrayBuffer ) is true . Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type . Assert: byteIndex is an integer value ≥ 0. Assert: Type ( value ) is BigInt if type is "BigInt64" or "BigUint64" ; otherwise, Type ( value ) is Number . Let block be arrayBuffer .[[ArrayBufferData]]. Let elementSize be the Number value of the Element Size value specified in Table 9 for Element Type type . If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent 's Agent Record . Let rawBytes be Number Numeric ToRawBytes( type , value , isLittleEndian ). Let execution be the [[CandidateExecution]] field of the surrounding agent 's Agent Record . Let eventList be the [[EventList]] field of the element in execution .[[EventLists]] whose [[AgentSignifier]] is AgentSignifier(). Let rawBytesRead be a List of length elementSize of nondeterministically chosen byte values. NOTE: In implementations, rawBytesRead is the result of a load-link, of a load-exclusive, or of an operand of a read-modify-write instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency. Let rmwEvent be ReadModifyWriteSharedMemory{ [[Order]]: "SeqCst" , [[NoTear]]: true , [[Block]]: block , [[ByteIndex]]: byteIndex , [[ElementSize]]: elementSize , [[Payload]]: rawBytes , [[ModifyOp]]: op }. Append rmwEvent to eventList . Append Chosen Value Record { [[Event]]: rmwEvent , [[ChosenValue]]: rawBytesRead } to execution .[[ChosenValues]]. Return RawBytesTo Number Numeric ( type , rawBytesRead , isLittleEndian ).

7.13 AtomicReadModifyWrite( typedArray , index , value , op ) The abstract operation AtomicReadModifyWrite takes four arguments, typedArray , index , value , and a pure combining operation op . The pure combining operation op takes two List of byte values arguments and returns a List of byte values. The operation atomically loads a value, combines it with another value, and stores the result of the combination. It returns the loaded value. It performs the following steps: Let buffer be ? ValidateSharedIntegerTypedArray ( typedArray ). Let i be ? ValidateAtomicAccess( typedArray , index ). Let arrayTypeName be typedArray .[[TypedArrayName]]. If arrayTypeName is "BigUint64Array" or "BigInt64Array" , let v be ? ToBigInt ( v ). Otherwise, let v be ? ToInteger ( value ). Let elementSize be the Number value of the Element Size value specified in Table 9 for arrayTypeName . Let elementType be the String value of the Element Type value in Table 9 for arrayTypeName . Let offset be typedArray .[[ByteOffset]]. Let indexedPosition be ( i × elementSize ) + offset . Return GetModifySetValueInBuffer ( buffer , indexedPosition , elementType , v , op ).

7.14 Atomics.compareExchange ( typedArray , index , expectedValue , replacementValue ) The following steps are taken: Let buffer be ? ValidateSharedIntegerTypedArray ( typedArray ). Let i be ? ValidateAtomicAccess( typedArray , index ). If arrayTypeName is "BigUint64Array" or "BigInt64Array" , Let expected be ? ToBigInt ( expectedValue ). Let replacement be ? ToBigInt ( replacementValue ). Otherwise, Let expected be ? ToInteger ( expectedValue ). Let replacement be ? ToInteger ( replacementValue ). Let arrayTypeName be typedArray .[[TypedArrayName]]. Let elementType be the String value of the Element Type value in Table 9 for arrayTypeName . Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent 's Agent Record . Let expectedBytes be Number Numeric ToRawBytes( elementType , expected , isLittleEndian ). Let elementSize be the Number value of the Element Size value specified in Table 9 for arrayTypeName . Let offset be typedArray .[[ByteOffset]]. Let indexedPosition be ( i × elementSize ) + offset . Let compareExchange denote a semantic function of two List of byte values arguments that returns the second argument if the first argument is element-wise equal to expectedBytes . Return GetModifySetValueInBuffer ( buffer , indexedPosition , elementType , replacement , compareExchange ).

7.15 Atomics.isLockFree( size ) The following steps are taken: Let n be ? ToInteger ( size ). Let AR be the Agent Record of the surrounding agent . If n equals 1, return AR .[[IsLockFree1]]. If n equals 2, return AR .[[IsLockFree2]]. If n equals 4, return true . If n equals 8, return AR .[[IsLockFree8]]. Return false . Note Atomics.isLockFree () is an optimization primitive. The intuition is that if the atomic step of an atomic primitive ( compareExchange , load , store , add , sub , and , or , xor , or exchange ) on a datum of size n bytes will be performed without the calling agent acquiring a lock outside the n bytes comprising the datum, then Atomics.isLockFree ( n ) will return true . High-performance algorithms will use Atomics.isLockFree to determine whether to use locks or atomic operations in critical sections. If an atomic primitive is not lock-free then it is often more efficient for an algorithm to provide its own locking. Atomics.isLockFree (4) always returns true as that can be supported on all known relevant hardware. Being able to assume this will generally simplify programs. Regardless of the value of Atomics.isLockFree , all atomic operations are guaranteed to be atomic. For example, they will never have a visible operation take place in the middle of the operation (e.g., "tearing").

7.16 Atomics.wait( typedArray , index , value , timeout ) Atomics.wait puts the calling agent in a wait queue and puts it to sleep until it is awoken or the sleep times out. The following steps are taken: Let buffer be ? ValidateSharedIntegerTypedArray ( typedArray , true ). Let i be ? ValidateAtomicAccess( typedArray , index ). If typedArray .[[TypedArrayName]] is "BigInt64Array" , let v be ? ToBigInt64 ( value ). Otherwise, let v be ? ToInt32 ( value ). Let q be ? ToNumber ( timeout ). If q is NaN , let t be +∞ , else let t be max ( q , 0). Let B be AgentCanSuspend(). If B is false , throw a TypeError exception. Let block be buffer .[[ArrayBufferData]]. Let offset be typedArray .[[ByteOffset]]. Let elementSize be the Number value of the Element Size value specified in Table 9 for arrayTypeName . Let indexedPosition be ( i × 4 elementSize ) + offset . Let WL be GetWaiterList( block , indexedPosition ). Perform EnterCriticalSection( WL ). Let w be ! AtomicLoad( typedArray , i ). If v is not equal to w , then Perform LeaveCriticalSection( WL ). Return the String "not-equal" . Let W be AgentSignifier(). Perform AddWaiter( WL , W ). Let awoken be Suspend( WL , W , t ). If awoken is true , then Assert: W is not on the list of waiters in WL . Else, Perform RemoveWaiter( WL , W ). Perform LeaveCriticalSection( WL ). If awoken is true , return the String "ok" . Return the String "timed-out" .

7.17 Atomics.notify( typedArray , index , count ) Atomics.notify wakes up some agents that are sleeping in the wait queue. The following steps are taken: Let buffer be ? ValidateSharedIntegerTypedArray ( typedArray , true ). Let i be ? ValidateAtomicAccess( typedArray , index ). If count is undefined , let c be +∞ . Else, Let intCount be ? ToInteger ( count ). Let c be max ( intCount , 0). Let block be buffer .[[ArrayBufferData]]. Let offset be typedArray .[[ByteOffset]]. Let elementSize be the Number value of the Element Size value specified in Table 9 for arrayTypeName . Let indexedPosition be ( i × 4 elementSize ) + offset . Let WL be GetWaiterList( block , indexedPosition ). Let n be 0. Perform EnterCriticalSection( WL ). Let S be RemoveWaiters( WL , c ). Repeat, while S is not an empty List , Let W be the first agent in S . Remove W from the front of S . Perform WakeWaiter( WL , W ). Add 1 to n . Perform LeaveCriticalSection( WL ). Return n .

7.18 Atomics.store( typedArray , index , value ) The following steps are taken: Let buffer be ? ValidateSharedIntegerTypedArray ( typedArray ). Let i be ? ValidateAtomicAccess( typedArray , index ). If arrayTypeName is "BigUint64Array" or "BigInt64Array" , let v be ? ToBigInt ( value ). Otherwise, let v be ? ToInteger ( value ). Let arrayTypeName be typedArray .[[TypedArrayName]]. Let elementSize be the Number value of the Element Size value specified in Table 9 for arrayTypeName . Let elementType be the String value of the Element Type value in Table 9 for arrayTypeName . Let offset be typedArray .[[ByteOffset]]. Let indexedPosition be ( i × elementSize ) + offset . Perform SetValueInBuffer ( buffer , indexedPosition , elementType , v , true , "SeqCst" ). Return v .

7.19 %TypedArray%.prototype.sort ( comparefn ) %TypedArray% .prototype.sort is a distinct function that, except as described below, implements the same requirements as those of Array.prototype.sort as defined in 22.1.3.25 . The implementation of the %TypedArray% .prototype.sort specification may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer indexed properties are not sparse. The only internal methods of the this object that the algorithm may call are [[Get]] and [[Set]]. This function is not generic. The this value must be an object with a [[TypedArrayName]] internal slot. Upon entry, the following steps are performed to initialize evaluation of the sort function. These steps are used instead of the entry steps in 22.1.3.25 : If comparefn is not undefined and IsCallable ( comparefn ) is false , throw a TypeError exception. Let obj be the this value. Let buffer be ? ValidateTypedArray ( obj ). Let len be obj .[[ArrayLength]]. The implementation-defined sort order condition for exotic objects is not applied by %TypedArray% .prototype.sort . The following version of SortCompare is used by %TypedArray% .prototype.sort . It performs a numeric comparison rather than the string comparison used in 22.1.3.25 . SortCompare has access to the comparefn and buffer values of the current invocation of the sort method. When the TypedArray SortCompare abstract operation is called with two arguments x and y , the following steps are taken: Assert: Both Type ( x ) and Type ( y ) is Number or both are BigInt . If comparefn is not undefined , then Let v be ? ToNumber (? Call ( comparefn , undefined , « x , y »)). If IsDetachedBuffer ( buffer ) is true , throw a TypeError exception. If v is NaN , return +0 . Return v . If x and y are both NaN , return +0 . If x is NaN , return 1. If y is NaN , return -1. If x < y , return -1. If x > y , return 1. If x is -0 and y is +0 , return -1. If x is +0 and y is -0 , return 1. Return +0 . Note Because NaN always compares greater than any other value, NaN property values always sort to the end of the result when comparefn is not provided.

7.20 TypedArraySpeciesCreate ( exemplar , argumentList ) The abstract operation TypedArraySpeciesCreate with arguments exemplar and argumentList is used to specify the creation of a new TypedArray object using a constructor function that is derived from exemplar . It performs the following steps: Assert: exemplar is an Object that has a [[TypedArrayName]] internal slot. Let defaultConstructor be the intrinsic object listed in column one of Table 9 for exemplar .[[TypedArrayName]]. Let constructor be ? SpeciesConstructor ( exemplar , defaultConstructor ). Return Let result be ? TypedArrayCreate ( constructor , argumentList ). Assert: result has a [[TypedArrayName]] internal slot. If result .[[TypedArrayName]] contains the substring "Big" and exemplar .[[TypedArrayName]] does not contain the substring "Big" , or vice versa, throw a TypeError exception. Return result .

7.21 %TypedArray%.prototype.fill ( value [ , start [ , end ] ] ) The interpretation and use of the arguments of %TypedArray% .prototype.fill are the same as for Array.prototype.fill as defined in 22.1.3.6 . The following steps are taken: Let O be the this value. Perform ? ValidateTypedArray ( O ). Let len be O .[[ArrayLength]]. If O .[[TypedArrayName]] is "BigUint64Array" or "BigInt64Array" , let value be ? ToBigInt ( value ). Otherwise, let value be ? ToNumber ( value ). Let relativeStart be ? ToInteger ( start ). If relativeStart < 0, let k be max (( len + relativeStart ), 0); else let k be min ( relativeStart , len ). If end is undefined , let relativeEnd be len ; else let relativeEnd be ? ToInteger ( end ). If relativeEnd < 0, let final be max (( len + relativeEnd ), 0); else let final be min ( relativeEnd , len ). If IsDetachedBuffer ( O .[[ViewedArrayBuffer]]) is true , throw a TypeError exception. Repeat, while k < final Let Pk be ! ToString ( k ). Perform ! Set ( O , Pk , value , true ). Increase k by 1. Return O .

7.22 %TypedArray%.prototype.set ( array [ , offset ] ) Sets multiple values in this TypedArray , reading the values from the object array . The optional offset value indicates the first element index in this TypedArray where values are written. If omitted, it is assumed to be 0. Assert: array is any ECMAScript language value other than an Object with a [[TypedArrayName]] internal slot. If it is such an Object, the definition in 7.23 applies. Let target be the this value. If Type ( target ) is not Object, throw a TypeError exception. If target does not have a [[TypedArrayName]] internal slot, throw a TypeError exception. Assert: target has a [[ViewedArrayBuffer]] internal slot. Let targetOffset be ? ToInteger ( offset ). If targetOffset < 0, throw a RangeError exception. Let targetBuffer be target .[[ViewedArrayBuffer]]. If IsDetachedBuffer ( targetBuffer ) is true , throw a TypeError exception. Let targetLength be target .[[ArrayLength]]. Let targetName be the String value of target .[[TypedArrayName]]. Let targetElementSize be the Number value of the Element Size value specified in Table 9 for targetName . Let targetType be the String value of the Element Type value in Table 9 for targetName . Let targetByteOffset be target .[[ByteOffset]]. Let src be ? ToObject ( array ). Let srcLength be ? ToLength (? Get ( src , "length" )). If srcLength + targetOffset > targetLength , throw a RangeError exception. Let targetByteIndex be targetOffset × targetElementSize + targetByteOffset . Let k be 0. Let limit be targetByteIndex + targetElementSize × srcLength . Repeat, while targetByteIndex < limit Let Pk be ! ToString ( k ). Let kNumber be ? ToNumber (? Get ( src , Pk )). Let value be ? Get ( src , Pk ). If target .[[TypedArrayName]] is "BigUint64Array" or "BigInt64Array" , let value be ? ToBigInt ( value ). Otherwise, let value be ? ToNumber ( value ). If IsDetachedBuffer ( targetBuffer ) is true , throw a TypeError exception. Perform SetValueInBuffer ( targetBuffer , targetByteIndex , targetType , kNumber value , true , "Unordered" ). Set k to k + 1. Set targetByteIndex to targetByteIndex + targetElementSize . Return undefined .

7.23 %TypedArray%.prototype.set( typedArray [ , offset ] ) Sets multiple values in this TypedArray , reading the values from the typedArray argument object. The optional offset value indicates the first element index in this TypedArray where values are written. If omitted, it is assumed to be 0. Assert: typedArray has a [[TypedArrayName]] internal slot. If it does not, the definition in 7.22 applies. Let target be the this value. If Type ( target ) is not Object, throw a TypeError exception. If target does not have a [[TypedArrayName]] internal slot, throw a TypeError exception. Assert: target has a [[ViewedArrayBuffer]] internal slot. Let targetOffset be ? ToInteger ( offset ). If targetOffset < 0, throw a RangeError exception. Let targetBuffer be target .[[ViewedArrayBuffer]]. If IsDetachedBuffer ( targetBuffer ) is true , throw a TypeError exception. Let targetLength be target .[[ArrayLength]]. Let srcBuffer be typedArray .[[ViewedArrayBuffer]]. If IsDetachedBuffer ( srcBuffer ) is true , throw a TypeError exception. Let targetName be the String value of target .[[TypedArrayName]]. Let targetType be the String value of the Element Type value in Table 9 for targetName . Let targetElementSize be the Number value of the Element Size value specified in Table 9 for targetName . Let targetByteOffset be target .[[ByteOffset]]. Let srcName be the String value of typedArray .[[TypedArrayName]]. Let srcType be the String value of the Element Type value in Table 9 for srcName . Let srcElementSize be the Number value of the Element Size value specified in Table 9 for srcName . Let srcLength be typedArray .[[ArrayLength]]. Let srcByteOffset be typedArray .[[ByteOffset]]. If srcLength + targetOffset > targetLength , throw a RangeError exception. If one of srcType and targetType contains the substring "Big" and the other does not, throw a TypeError exception. If both IsSharedArrayBuffer( srcBuffer ) and IsSharedArrayBuffer( targetBuffer ) are true , then If srcBuffer .[[ArrayBufferData]] and targetBuffer .[[ArrayBufferData]] are the same Shared Data Block values, let same be true ; else let same be false . Else, let same be SameValue ( srcBuffer , targetBuffer ). If same is true , then Let srcByteLength be typedArray .[[ByteLength]]. Let srcBuffer be ? CloneArrayBuffer ( srcBuffer , srcByteOffset , srcByteLength , %ArrayBuffer% ). NOTE: %ArrayBuffer% is used to clone srcBuffer because is it known to not have any observable side-effects. Let srcByteIndex be 0. Else, let srcByteIndex be srcByteOffset . Let targetByteIndex be targetOffset × targetElementSize + targetByteOffset . Let limit be targetByteIndex + targetElementSize × srcLength . If SameValue ( srcType , targetType ) is true , then NOTE: If srcType and targetType are the same, the transfer must be performed in a manner that preserves the bit-level encoding of the source data. Repeat, while targetByteIndex < limit Let value be GetValueFromBuffer ( srcBuffer , srcByteIndex , "Uint8" , true , "Unordered" ). Perform SetValueInBuffer ( targetBuffer , targetByteIndex , "Uint8" , value , true , "Unordered" ). Set srcByteIndex to srcByteIndex + 1. Set targetByteIndex to targetByteIndex + 1. Else, Repeat, while targetByteIndex < limit Let value be GetValueFromBuffer ( srcBuffer , srcByteIndex , srcType , true , "Unordered" ). Perform SetValueInBuffer ( targetBuffer , targetByteIndex , targetType , value , true , "Unordered" ). Set srcByteIndex to srcByteIndex + srcElementSize . Set targetByteIndex to targetByteIndex + targetElementSize . Return undefined .

7.24 TypedArray ( typedArray ) This description applies only if the TypedArray function is called with at least one argument and the Type of the first argument is Object and that object has a [[TypedArrayName]] internal slot. TypedArray called with argument typedArray performs the following steps: Assert: Type ( typedArray ) is Object and typedArray has a [[TypedArrayName]] internal slot. If NewTarget is undefined , throw a TypeError exception. Let constructorName be the String value of the Constructor Name value specified in Table 9 for this TypedArray constructor. Let O be ? AllocateTypedArray ( constructorName , NewTarget, "% TypedArray Prototype%" ). Let srcArray be typedArray . Let srcData be srcArray .[[ViewedArrayBuffer]]. If IsDetachedBuffer ( srcData ) is true , throw a TypeError exception. Let elementType be the String value of the Element Type value in Table 9 for constructorName . Let elementLength be srcArray .[[ArrayLength]]. Let srcName be the String value of srcArray .[[TypedArrayName]]. Let srcType be the String value of the Element Type value in Table 9 for srcName . Let srcElementSize be the Element Size value in Table 9 for srcName . Let srcByteOffset be srcArray .[[ByteOffset]]. Let elementSize be the Element Size value in Table 9 for constructorName . Let byteLength be elementSize × elementLength . If IsSharedArrayBuffer( srcData ) is false , then Let bufferConstructor be ? SpeciesConstructor ( srcData , %ArrayBuffer% ). Else, Let bufferConstructor be %ArrayBuffer% . If SameValue ( elementType , srcType ) is true , then If IsDetachedBuffer ( srcData ) is true , throw a TypeError exception. Let data be ? CloneArrayBuffer ( srcData , srcByteOffset , byteLength , bufferConstructor ). Else, Let data be ? AllocateArrayBuffer ( bufferConstructor , byteLength ). If IsDetachedBuffer ( srcData ) is true , throw a TypeError exception. If one of srcType and elementType contains the substring "Big" and the other does not, throw a TypeError exception. Let srcByteIndex be srcByteOffset . Let targetByteIndex be 0. Let count be elementLength . Repeat, while count > 0 Let value be GetValueFromBuffer ( srcData , srcByteIndex , srcType , true , "Unordered" ). Perform SetValueInBuffer ( data , targetByteIndex , elementType , value , true , "Unordered" ). Set srcByteIndex to srcByteIndex + srcElementSize . Set targetByteIndex to targetByteIndex + elementSize . Decrement count by 1. Set O .[[ViewedArrayBuffer]] to data . Set O .[[ByteLength]] to byteLength . Set O .[[ByteOffset]] to 0. Set O .[[ArrayLength]] to elementLength . Return O .

7.25 SetViewValue ( view , requestIndex , isLittleEndian , type , value ) The abstract operation SetViewValue with arguments view , requestIndex , isLittleEndian , type , and value is used by functions on DataView instances to store values into the view's buffer. It performs the following steps: If Type ( view ) is not Object, throw a TypeError exception. If view does not have a [[DataView]] internal slot, throw a TypeError exception. Assert: view has a [[ViewedArrayBuffer]] internal slot. Let getIndex be ? ToIndex ( requestIndex ). If type is "BigUint64" or "BigInt64" , let v be ? ToBigInt ( value ). Otherwise, let v be ? ToInteger ( value ). Set isLittleEndian to ToBoolean ( isLittleEndian ). Let buffer be view .[[ViewedArrayBuffer]]. If IsDetachedBuffer ( buffer ) is true , throw a TypeError exception. Let viewOffset be view .[[ByteOffset]]. Let viewSize be view .[[ByteLength]]. Let elementSize be the Number value of the Element Size value specified in Table 9 for Element Type type . If getIndex + elementSize > viewSize , throw a RangeError exception. Let bufferIndex be getIndex + viewOffset . Return SetValueInBuffer ( buffer , bufferIndex , type , v , false , "Unordered" , isLittleEndian ).

7.26 DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] ) When the getBigInt64 method is called with argument byteOffset and optional argument littleEndian , the following steps are taken: Let v be the this value. If littleEndian is not present, let littleEndian be undefined . Return ? GetViewValue ( v , byteOffset , littleEndian , "BigInt64" ).

7.27 DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] ) When the getBigUint64 method is called with argument byteOffset and optional argument littleEndian , the following steps are taken: Let v be the this value. If littleEndian is not present, let littleEndian be undefined . Return ? GetViewValue ( v , byteOffset , littleEndian , "BigUint64" ).

7.28 DataView.prototype.setBigInt64 ( byteOffset , value [ , littleEndian ] ) When the setBigInt64 method is called with arguments byteOffset and value , the following steps are taken: Let v be the this value. If littleEndian is not present, let littleEndian be undefined . Return ? SetViewValue ( v , byteOffset , littleEndian , "BigInt64" , value ).