| CARVIEW |
- Introduction
- ◢1 Numeric Types
- ◢1.1 The BigInt Type
- 1.1.1 BigInt::unaryMinus (x)
- 1.1.2 BigInt::bitwiseNOT (x)
- 1.1.3 BigInt::exponentiate (base, exponent)
- 1.1.4 BigInt::multiply (x, y)
- 1.1.5 BigInt::divide (x, y)
- 1.1.6 BigInt::remainder (n, d)
- 1.1.7 BigInt::add (x, y)
- 1.1.8 BigInt::subtract (x, y)
- 1.1.9 BigInt::leftShift (x, y)
- 1.1.10 BigInt::signedRightShift (x, y)
- 1.1.11 BigInt::unsignedRightShift (x, y)
- 1.1.12 BigInt::lessThan (x, y)
- 1.1.13 BigInt::equal (x, y)
- 1.1.14 BigInt::sameValue (x, y)
- 1.1.15 BigInt::sameValueZero (x, y)
- 1.1.16 BitwiseOp(op, x, y)
- 1.1.17 BigInt::bitwiseAND (x, y)
- 1.1.18 BigInt::bitwiseXOR (x, y)
- 1.1.19 BigInt::bitwiseOR (x, y)
- ◢1.1 The BigInt Type
- ◢2 Modifications to the Number grammar
- ◢3 Abstract Operations
- ◢4 ECMAScript Language: Expressions
- ◢5 BigInt Objects
- ◢6 Modified algorithms
- ◢7 TypedArrays and DataViews
- 7.1 TypedArray Objects
- 7.2 StringToBigInt ( argument )
- 7.3 ToBigInt ( argument )
- 7.4 ToBigInt64 ( argument )
- 7.5 ToBigUint64 ( argument )
- 7.6 RawBytesTo
NumberNumeric( type, rawBytes, isLittleEndian ) - 7.7
NumberNumericToRawBytes( type, value, isLittleEndian ) - 7.8 IntegerIndexedElementSet ( O, index, value )
- 7.9 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order [ , isLittleEndian ] )
- 7.10 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isTypedArray, order [ , isLittleEndian ] )
- 7.11 GetModifySetValueInBuffer( arrayBuffer, byteIndex, type, value, op [ , isLittleEndian ] )
- 7.12 ValidateSharedIntegerTypedArray(typedArray [ , waitable ] )
- 7.13 AtomicReadModifyWrite( typedArray, index, value, op )
- 7.14 Atomics.compareExchange ( typedArray, index, expectedValue, replacementValue )
- 7.15 Atomics.isLockFree( size )
- 7.16 Atomics.wait( typedArray, index, value, timeout )
- 7.17 Atomics.notify( typedArray, index, count )
- 7.18 Atomics.store( typedArray, index, value )
- 7.19 %TypedArray%.prototype.sort ( comparefn )
- 7.20 TypedArraySpeciesCreate ( exemplar, argumentList )
- 7.21 %TypedArray%.prototype.fill ( value [ , start [ , end ] ] )
- 7.22 %TypedArray%.prototype.set ( array [ , offset ] )
- 7.23 %TypedArray%.prototype.set( typedArray [ , offset ] )
- 7.24 TypedArray ( typedArray )
- 7.25 SetViewValue ( view, requestIndex, isLittleEndian, type, value )
- 7.26 DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] )
- 7.27 DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] )
- 7.28 DataView.prototype.setBigInt64 ( byteOffset, value [ , littleEndian ] )
- 7.29 DataView.prototype.setBigUint64 ( byteOffset, value [ , littleEndian ] )
- 8 Agents
Stage 4 Draft / September 30, 2019
BigInt
Introduction
This proposal adds arbitrary-precision integers to ECMAScript. For motivation and a high-level introduction, see the explainer document.
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.
If you find any part of this specification unclear or confusing, please file an issue.
1Numeric Types
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.
| Invocation Synopsis | Value and Purpose |
|---|---|
| T::unaryMinus(x) |
A specification function invoked when applying the unary minus operator. Called by the semantics of the |
| T::bitwiseNOT(x) |
A specification function invoked when applying the bitwise NOT operator. Called by the semantics of the ~x.
|
| T::exponentiate(x, y) |
A specification function invoked when applying the exponentiation operator. Called by the semantics of the x ** y.
|
| T::multiply(x, y) |
A specification function invoked when applying the multiplication operator. Called by the semantics of the * operatorx * y.
|
| T::divide(x, y) |
A specification function invoked when applying the division operator. Called by the semantics of the / operatorx / y.
|
| T::remainder(x, y) |
A specification function invoked when applying the truncating remainder ("mod") operator. Called by the semantics of the % operatorx % y.
|
| T::add(x, y) |
A specification function invoked when applying the addition operator. Called by the semantics of the + operatorx + y.
|
| T::subtract(x, y) |
A specification function invoked when applying the subtraction operator. Called by the semantics of the - operatorx - y.
|
| T::leftShift(x, y) |
A specification function invoked when applying the left shift operator to two operands, both of type T. Called by the semantics of the << operatorx << y.
|
| T::signedRightShift(x, y) |
A specification function invoked when applying the right shift operator to two operands, both of type T. Called by the semantics of the >> operatorx >> y.
|
| T::unsignedRightShift(x, y) |
A specification function invoked when applying the right shift operator to two operands, both of type T. Called by the semantics of the >>> operatorx >>> y.
|
| T::lessThan(x, y) |
A specification function invoked when applying one of the four partial-order x < y, x > y, x <= y, and x >= y.
|
| T::equal(x, y) |
A specification function invoked when applying x == y, x != y, x === y, and x !== y.
|
| T::sameValue(x, y) |
A specification function invoked when applying |
| T::sameValueZero(x, y) |
A specification function invoked when applying |
| T::bitwiseAND(x, y) |
A specification function invoked when applying x & y.
|
| T::bitwiseXOR(x, y) |
A specification function invoked when applying x ^ y.
|
| T::bitwiseOR(x, y) |
A specification function invoked when applying x | y.
|
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.
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 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.
1.1The BigInt Type
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 BigInt::unit value is
1.1.1BigInt::unaryMinus (x)
The abstract operation BigInt::unaryMinus with an argument x of BigInt type returns the result of negating x.
-0n is the same as 1.1.2BigInt::bitwiseNOT (x)
The abstract operation BigInt::bitwiseNOT with an argument x of BigInt type returns the one's complement of x; that is, -x - 1.
1.1.3BigInt::exponentiate (base, exponent)
- If exponent < 0, throw a
RangeError exception. - If base is
0n and exponent is0n , return1n . - Return a BigInt representing the mathematical value of base raised to the power exponent.
1.1.4BigInt::multiply (x, y)
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.
1.1.5BigInt::divide (x, y)
- If y is
0n , throw aRangeError exception. - Let quotient be the mathematical value of x divided by y.
- Return a BigInt representing quotient rounded towards 0 to the next integral value.
1.1.6BigInt::remainder (n, d)
- If d is
0n , throw aRangeError exception. - If n is
0n , return0n . - Let r be the BigInt defined by the mathematical relation r = n - (d × q) where q is a BigInt that is negative only if n/d is negative and positive only if n/d is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of n and d.
- Return r.
1.1.7BigInt::add (x, 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.
1.1.8BigInt::subtract (x, y)
The abstract operation BigInt::subtract with two arguments x and y of BigInt type returns the BigInt representing the difference x minus y.
1.1.9BigInt::leftShift (x, y)
The abstract operation BigInt::leftShift with two arguments x and y of BigInt:
- If y < 0, then
- Return a BigInt representing x ÷ 2-y, rounding down to the nearest integer, including for negative numbers.
- Return a BigInt representing x × 2y.
1.1.10BigInt::signedRightShift (x, y)
The abstract operation BigInt::signedRightShift with arguments x and y of type BigInt:
- Return BigInt::leftShift(x, -y).
1.1.11BigInt::unsignedRightShift (x, y)
The abstract operation BigInt::unsignedRightShift with two arguments x and y of type BigInt:
- Throw a
TypeError exception.
1.1.12BigInt::lessThan (x, y)
The abstract operation BigInt::lessThan with two arguments x and y of BigInt type returns
1.1.13BigInt::equal (x, y)
The abstract operation BigInt::equal with two arguments x and y of BigInt type returns
1.1.14BigInt::sameValue (x, y)
The abstract operation BigInt::sameValue with two arguments x and y of BigInt type:
- Return BigInt::equal(x, y).
1.1.15BigInt::sameValueZero (x, y)
The abstract operation BigInt::sameValueZero with two arguments x and y of BigInt type:
- Return BigInt::equal(x, y).
1.1.16BitwiseOp(op, x, y)
1.1.17BigInt::bitwiseAND (x, y)
- Return BitwiseOp(
&, x, y).
1.1.18BigInt::bitwiseXOR (x, y)
- Return BitwiseOp(
^, x, y).
1.1.19BigInt::bitwiseOR (x, y)
- Return BitwiseOp(
|, x, y).
2Modifications to the Number grammar
2.1Static Semantics: BigInt Value
-
Let the value of
NumericLiteral be the MV ofNumericLiteralBase represented as BigInt.
-
Let the value of
NumericLiteral be the MV ofDecimalIntegerLiteral represented as BigInt.
2.2Static Semantics: Number Value
The MV is rounded to a value of the Number type.
3Abstract Operations
3.1Type Conversion
The BigInt type has no implicit conversions in the ECMAScript language; programmers must call BigInt explicitly to convert values from other types.
3.1.1ToPrimitive ( input [ , PreferredType ] )
| Input Type | Result |
|---|---|
| BigInt | Return input. |
3.1.2ToBoolean ( argument )
The abstract operation ToBoolean converts argument to a value of type Boolean according to
| Argument Type | Result |
|---|---|
| BigInt |
Return |
3.1.3ToNumber ( argument )
The abstract operation ToNumber converts argument to a value of type Number according to
| Argument Type | Result |
|---|---|
| BigInt |
Throw a |
3.1.3.1ToNumber Applied to the String Type
Some differences should be noted between the syntax of a
-
A
StringNumericLiteral may not include aBigIntLiteralSuffix .
3.1.4ToString ( argument )
The abstract operation ToString converts argument to a value of type String according to
3.1.4.1ToString Applied to the BigInt Type
The abstract operation
- If i is less than zero, return the string-concatenation of the String
"-"andToString (-i). - Return the String value consisting of the code units of the digits of the decimal representation of i.
3.1.5ToObject ( argument )
The abstract operation ToObject converts argument to a value of type Object according to
| Argument Type | Result |
|---|---|
| BigInt | Return a new BigInt object whose [[BigIntData]] internal slot is set to argument. See BigInt Objects for a description of BigInt objects. |
3.1.6ToNumeric ( value )
The abstract operation ToNumeric returns value converted to a numeric value of type Number or BigInt. This abstract operation functions as follows:
- Let primValue be ?
ToPrimitive (value, hint Number). - If
Type (primValue) is BigInt, return primValue. - Return
ToNumber (primValue).
3.1.7RequireObjectCoercible ( argument )
The abstract operation RequireObjectCoercible throws an error if argument is a value that cannot be converted to an Object using
| Argument Type | Result |
|---|---|
| BigInt | Return argument. |
3.2Testing and Comparison Operations
3.2.1SameValue ( x, y )
The internal comparison abstract operation SameValue(x, y), where x and y are ECMAScript language values, produces
- If
Type (x) is different fromType (y), returnfalse . - If
Type (x) is Number or BigInt, thenIf x isNaN and y isNaN , returntrue .If x is+0 and y is-0 , returnfalse .If x is-0 and y is+0 , returnfalse .If x is the same Number value as y, returntrue .Returnfalse .- Return !
Type (x)::sameValue(x, y).
- Return SameValueNon
NumberNumeric(x, y).
3.2.2SameValueZero ( x, y )
The internal comparison abstract operation SameValueZero(x, y), where x and y are ECMAScript language values, produces
- If
Type (x) is different fromType (y), returnfalse . - If
Type (x) is Number or BigInt, thenIf x isNaN and y isNaN , returntrue .If x is+0 and y is-0 , returntrue .If x is-0 and y is+0 , returntrue .If x is the same Number value as y, returntrue .Returnfalse .- Return !
Type (x)::sameValueZero(x, y).
- Return SameValueNon
NumberNumeric(x, y).
3.2.3SameValueNonNumberNumeric ( x, y )
The internal comparison abstract operation SameValueNonNumeric(x, y), where neither x nor y are numeric type values, produces
- Assert:
Type (x) is not Number or BigInt. - Assert:
Type (x) is the same asType (y). - If
Type (x) is Undefined, returntrue . - If
Type (x) is Null, returntrue . - If
Type (x) is String, then- If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return
true ; otherwise, returnfalse .
- If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return
- If
Type (x) is Boolean, then- If x and y are both
true or bothfalse , returntrue ; otherwise, returnfalse .
- If x and y are both
- If
Type (x) is Symbol, then- If x and y are both the same Symbol value, return
true ; otherwise, returnfalse .
- If x and y are both the same Symbol value, return
- If x and y are the same Object value, return
true . Otherwise, returnfalse .
3.2.4Abstract Relational Comparison
The comparison x < y, where x and y are values, produces
- If the LeftFirst flag is
true , then- Let px be ?
ToPrimitive (x, hint Number). - Let py be ?
ToPrimitive (y, hint Number).
- Let px be ?
- Else the order of evaluation needs to be reversed to preserve left to right evaluation,
- Let py be ?
ToPrimitive (y, hint Number). - Let px be ?
ToPrimitive (x, hint Number).
- Let py be ?
- If both px and py are Strings, then
- If py is a prefix of px, return
false . (A String value p is a prefix of String value q if q can be the result of concatenating p and some other String r. Note that any String is a prefix of itself, because r may be the empty String.) - If px is a prefix of py, return
true . - Let k be the smallest nonnegative integer such that the code unit at index k within px is different from the code unit at index k within py. (There must be such a k, for neither String is a prefix of the other.)
- Let m be the integer that is the code unit at index k within px.
- Let n be the integer that is the code unit at index k within py.
- If m < n, return
true . Otherwise, returnfalse .
- If py is a prefix of px, return
- Else,
Let nx be ?ToNumber (px). Because px and py are primitive values evaluation order is not important.Let ny be ?ToNumber (py).If nx isNaN , returnundefined .If ny isNaN , returnundefined .If nx and ny are the same Number value, returnfalse .If nx is+0 and ny is-0 , returnfalse .If nx is-0 and ny is+0 , returnfalse .If nx is+∞ , returnfalse .If ny is+∞ , returntrue .If ny is-∞ , returnfalse .If nx is-∞ , returntrue .If the mathematical value of nx is less than the mathematical value of ny —note that these mathematical values are both finite and not both zero—returntrue . Otherwise, returnfalse .- If
Type (px) is BigInt andType (py) is String, then- Let ny be
StringToBigInt (py). - If ny is
NaN , returnundefined . - Return BigInt::lessThan(px, ny).
- Let ny be
- If
Type (px) is String andType (py) is BigInt, then- Let nx be
StringToBigInt (px). - If nx is
NaN , returnundefined . - Return BigInt::lessThan(nx, py).
- Let nx be
- Let nx be ?
ToNumeric (px). NOTE: Because px and py are primitive values evaluation order is not important. - Let ny be ?
ToNumeric (py). - If
Type (nx) is the same asType (ny), returnType (nx)::lessThan(nx, ny). - Assert:
Type (nx) is BigInt andType (ny) is Number, orType (nx) is Number andType (ny) is BigInt. - If nx or ny is
NaN , returnundefined . - If nx is
-∞ or ny is+∞ , returntrue . - If nx is
+∞ or ny is-∞ , returnfalse . - If the mathematical value of nx is less than the mathematical value of ny, return
true , otherwise returnfalse .
3.2.5Abstract Equality Comparison
The comparison x == y, where x and y are values, produces
- If
Type (x) is the same asType (y), then- Return the result of performing
Strict Equality Comparison x === y.
- Return the result of performing
- If x is
null and y isundefined , returntrue . - If x is
undefined and y isnull , returntrue . - If
Type (x) is Number andType (y) is String, return the result of the comparison x ==ToNumber (y). - If
Type (x) is String andType (y) is Number, return the result of the comparisonToNumber (x) == y. - If
Type (x) is BigInt andType (y) is String, then- Let n be
StringToBigInt (y). - If n is
NaN , returnfalse . - Return the result of the comparison x == n.
- Let n be
- If
Type (x) is String andType (y) is BigInt, return the result of the comparison y == x. - If
Type (x) is Boolean, return the result of the comparisonToNumber (x) == y. - If
Type (y) is Boolean, return the result of the comparison x ==ToNumber (y). - If
Type (x) is either String, Number, BigInt, or Symbol andType (y) is Object, return the result of the comparison x == ?ToPrimitive (y). - If
Type (x) is Object andType (y) is either String, Number, BigInt, or Symbol, return the result of the comparison ?ToPrimitive (x) == y. - If
Type (x) is BigInt andType (y) is Number, or ifType (x) is Number andType (y) is BigInt, then- If x or y are any of
NaN ,+∞ , or-∞ , returnfalse . - If the mathematical value of x is equal to the mathematical value of y, return
true , otherwise returnfalse .
- If x or y are any of
- Return
false .
3.2.6Strict Equality Comparison
The comparison x === y, where x and y are values, produces
- If
Type (x) is different fromType (y), returnfalse . - If
Type (x) is Number or BigInt, thenIf x isNaN , returnfalse .If y isNaN , returnfalse .If x is the same Number value as y, returntrue .If x is+0 and y is-0 , returntrue .If x is-0 and y is+0 , returntrue .Returnfalse .- Return !
Type (x)::equal(x, y).
- Return SameValueNon
NumberNumeric(x, y).
4ECMAScript Language: Expressions
4.1Update Expressions
4.1.1Postfix Increment Operator
4.1.1.1Runtime Semantics: Evaluation
- Let lhs be the result of evaluating
LeftHandSideExpression . Let oldValue be ?ToNumber (?GetValue (lhs)).Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the+operator (see12.8.5 ).- Let oldValue be ?
ToNumeric (?GetValue (lhs)). - Let newValue be ?
Type (oldvalue)::add(oldValue,Type (oldValue)::unit). - Perform ?
PutValue (lhs, newValue). - Return oldValue.
4.1.2Postfix Decrement Operator
4.1.2.1Runtime Semantics: Evaluation
- Let lhs be the result of evaluating
LeftHandSideExpression . Let oldValue be ?ToNumber (?GetValue (lhs)).Let newValue be the result of subtracting the value 1 from oldValue, using the same rules as for the-operator (see12.8.5 ).- Let oldValue be ?
ToNumeric (?GetValue (lhs)). - Let newValue be ?
Type (oldvalue)::subtract(oldValue,Type (oldValue)::unit). - Perform ?
PutValue (lhs, newValue). - Return oldValue.
4.1.3Prefix Increment Operator
4.1.3.1Runtime Semantics: Evaluation
- Let expr be the result of evaluating
UnaryExpression . Let oldValue be ?ToNumber (?GetValue (expr)).Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the+operator (see12.8.5 ).- Let oldValue be ?
ToNumeric (?GetValue (expr)). - Let newValue be ?
Type (oldvalue)::add(oldValue,Type (oldValue)::unit). - Perform ?
PutValue (expr, newValue). - Return newValue.
4.1.4Prefix Decrement Operator
4.1.4.1Runtime Semantics: Evaluation
- Let expr be the result of evaluating
UnaryExpression . Let oldValue be ?ToNumber (?GetValue (expr)).Let newValue be the result of subtracting the value 1 from oldValue, using the same rules as for the-operator (see12.8.5 ).- Let oldValue be ?
ToNumeric (?GetValue (expr)). - Let newValue be ?
Type (oldvalue)::subtract(oldValue,Type (oldValue)::unit). - Perform ?
PutValue (expr, newValue). - Return newValue.
4.2Unary Operators
4.2.1The typeof Operator
4.2.1.1Runtime Semantics: Evaluation
| Type of val | Result |
|---|---|
| BigInt |
"bigint"
|
4.2.2Unary + Operator
The unary + operator converts its operand to Number type.
4.2.2.1Runtime Semantics: Evaluation
- Let expr be the result of evaluating
UnaryExpression . - Return ?
ToNumber (?GetValue (expr)).
+ will throw on BigInts. The semantics here are designed to allow expressions of the form +x to always return Numbers, which is necessary to preserve assumptions made by asm.js.4.2.3Unary - Operator
The unary - operator converts its operand to Number type and then negates it. Negating
4.2.3.1Runtime Semantics: Evaluation
- Let expr be the result of evaluating
UnaryExpression . - Let oldValue be ?
ToNumber ToNumeric (?GetValue (expr)). If oldValue isNaN , returnNaN .Return the result of negating oldValue; that is, compute a Number with the same magnitude but opposite sign.- Let T be
Type (oldValue). - Return ? T::unaryMinus(oldValue).
4.2.4Bitwise NOT Operator ( ~ )
4.2.4.1Runtime Semantics: Evaluation
- Let expr be the result of evaluating
UnaryExpression . - Let oldValue be ?
ToInt32 ToNumeric (?GetValue (expr)). Return the result of applying bitwise complement to oldValue. The result is a signed 32-bit integer.- Let T be
Type (oldValue). - Return ? T::bitwiseNOT(oldValue).
4.3Exponentiation Operator
4.3.1Runtime Semantics: Evaluation
- Let left be the result of evaluating UpdateExpression.
- Let leftValue be ?
GetValue (left). - Let right be the result of evaluating ExponentiationExpression.
- Let rightValue be ?
GetValue (right). - Let base be ?
ToNumber ToNumeric (leftValue). - Let exponent be ?
ToNumber ToNumeric (rightValue). Return the result ofApplying the ** operator with base and exponent as specified in12.7.3.4 .- If
Type (base) is different fromType (exponent), throw aTypeError exception. - Return ?
Type (base)::exponentiate(base, exponent).
4.4Multiplicative Operators
4.4.1Runtime Semantics: Evaluation
- Let left be the result of evaluating
MultiplicativeExpression . - Let leftValue be ?
GetValue (left). - Let right be the result of evaluating
ExponentiationExpression . - Let rightValue be ?
GetValue (right). - Let lnum be ?
ToNumber ToNumeric (leftValue). - Let rnum be ?
ToNumber ToNumeric (rightValue). Return the result of applying theMultiplicativeOperator (*,/, or%) to lnum and rnum as specified in12.7.3.1 ,12.7.3.2 , or12.7.3.3 .- If
Type (lnum) is different fromType (rnum), throw aTypeError exception. - Let T be
Type (lnum). - If
MultiplicativeOperator is*, return T::multiply(lnum, rnum). - If
MultiplicativeOperator is/, return T::divide(lnum, rnum). - Otherwise,
MultiplicativeOperator is%; return T::remainder(lnum, rnum).
4.5Additive Operators
4.5.1The Addition Operator ( + )
The addition operator either performs string concatenation or numeric addition.
4.5.1.1Runtime Semantics: Evaluation
- Let lref be the result of evaluating
AdditiveExpression . - Let lval be ?
GetValue (lref). - Let rref be the result of evaluating
MultiplicativeExpression . - Let rval be ?
GetValue (rref). - Let lprim be ?
ToPrimitive (lval). - Let rprim be ?
ToPrimitive (rval). - If
Type (lprim) is String orType (rprim) is String, then - Let lnum be ?
ToNumber ToNumeric (lprim). - Let rnum be ?
ToNumber ToNumeric (rprim). Return the result of applying the addition operation to lnum and rnum. See the Note below12.8.5 .- If
Type (lnum) is different fromType (rnum), throw aTypeError exception. - Let T be
Type (lnum). - Return T::add(lnum, rnum).
No hint is provided in the calls to
Step 7 differs from step 5 of the
4.5.2The Subtraction Operator ( - )
4.5.2.1Runtime Semantics: Evaluation
- Let lref be the result of evaluating
AdditiveExpression . - Let lval be ?
GetValue (lref). - Let rref be the result of evaluating
MultiplicativeExpression . - Let rval be ?
GetValue (rref). - Let lnum be ?
ToNumber ToNumeric (lval). - Let rnum be ?
ToNumber ToNumeric (rval). Return the result of applying the subtraction operation to lnum and rnum. See the note below12.8.5 .- If
Type (lnum) is different fromType (rnum), throw aTypeError exception. - Let T be
Type (lnum). - Return T::subtract(lnum, rnum).
4.6Bitwise Shift Operators
4.6.1The Left Shift Operator ( << )
Performs a bitwise left shift operation on the left operand by the amount specified by the right operand.
4.6.1.1Runtime Semantics: Evaluation
- Let lref be the result of evaluating
ShiftExpression . - Let lval be ?
GetValue (lref). - Let rref be the result of evaluating
AdditiveExpression . - Let rval be ?
GetValue (rref). - Let lnum be ?
ToInt32 ToNumeric (lval). - Let rnum be ?
ToUint32 ToNumeric (rval). Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.Return the result of left shifting lnum by shiftCount bits. The result is a signed 32-bit integer.- If
Type (lnum) is different fromType (rnum), throw aTypeError exception. - Let T be
Type (lnum). - Return T::leftShift(lnum, rnum).
4.6.2The Signed Right Shift Operator ( >> )
Performs a sign-filling bitwise right shift operation on the left operand by the amount specified by the right operand.
4.6.2.1Runtime Semantics: Evaluation
- Let lref be the result of evaluating
ShiftExpression . - Let lval be ?
GetValue (lref). - Let rref be the result of evaluating
AdditiveExpression . - Let rval be ?
GetValue (rref). - Let lnum be ?
ToInt32 ToNumeric (lval). - Let rnum be ?
ToUint32 ToNumeric (rval). Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.Return the result of performing a sign-extending right shift of lnum by shiftCount bits. The most significant bit is propagated. The result is a signed 32-bit integer.- If
Type (lnum) is different fromType (rnum), throw aTypeError exception. - Let T be
Type (lnum). - Return T::signedRightShift(lnum, rnum).
4.6.3The Unsigned Right Shift Operator ( >>> )
Performs a zero-filling bitwise right shift operation on the left operand by the amount specified by the right operand.
4.6.3.1Runtime Semantics: Evaluation
- Let lref be the result of evaluating
ShiftExpression . - Let lval be ?
GetValue (lref). - Let rref be the result of evaluating
AdditiveExpression . - Let rval be ?
GetValue (rref). - Let lnum be ?
ToInt32 ToNumeric (lval). - Let rnum be ?
ToUint32 ToNumeric (rval). Let shiftCount be the result of masking out all but the least significant 5 bits of rnum, that is, compute rnum & 0x1F.Return the result of performing a zero-filling right shift of lnum by shiftCount bits. Vacated bits are filled with zero. The result is an unsigned 32-bit integer.- If
Type (lnum) is different fromType (rnum), throw aTypeError exception. - Let T be
Type (lnum). - Return T::unsignedRightShift(lnum, rnum).
4.7Binary Bitwise Operators
4.7.1Runtime Semantics: Evaluation
The production
- Let lref be the result of evaluating A.
- Let lval be ?
GetValue (lref). - Let rref be the result of evaluating B.
- Let rval be ?
GetValue (rref). - Let lnum be ?
ToInt32 ToNumeric (lval). - Let rnum be ?
ToUint32 ToNumeric (rval). - If
Type (lnum) is different fromType (rnum), throw aTypeError exception. - Let T be
Type (lnum). - If @ is
&, return T::bitwiseAND(lnum, rnum). - If @ is
|, return T::bitwiseOR(lnum, rnum). - Otherwise, @ is
^; return T::bitwiseXOR(lnum, rnum).
5BigInt Objects
5.1The BigInt Constructor
The BigInt constructor is the %BigInt% intrinsic object and the initial value of the BigInt property of the BigInt is called as a function, it performs a type conversion.
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.
5.1.1IsInteger ( number )
- Assert:
Type (number) is Number. - If number is
NaN ,+∞ , or-∞ , returnfalse . - Let integer be !
ToInteger (number). - If !
SameValueZero (integer, number) isfalse , returnfalse . - Otherwise, return
true .
5.1.2NumberToBigInt ( number )
5.1.3BigInt ( value )
When BigInt is called with argument value, the following steps are taken:
- If NewTarget is not
undefined , throw aTypeError exception. - Let prim be ?
ToPrimitive (value, hint Number). - If
Type (prim) is Number, return ?NumberToBigInt (prim). - Otherwise, return ?
ToBigInt (value).
5.2Properties of the BigInt Constructor
The value of the [[Prototype]] internal slot of the BigInt constructor is the intrinsic object
The BigInt constructor has the following properties:
5.2.1BigInt.asUintN ( bits, bigint )
When the BigInt.asUintN function is called with two arguments bits and bigint, the following steps are taken:
5.2.2BigInt.asIntN ( bits, bigint )
When the BigInt.asIntN is called with two arguments bits and bigint, the following steps are taken:
5.2.3BigInt.prototype
The initial value of BigInt.prototype is the intrinsic object
This property has the attributes { [[Writable]]:
5.3Properties of the BigInt Prototype Object
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 value of the [[Prototype]] internal slot of the BigInt prototype object is the intrinsic object
The abstract operation thisBigIntValue(value) performs the following steps:
The phrase “this BigInt value” within the specification of a method refers to the result returned by calling the abstract operation thisBigIntValue with the
5.3.1BigInt.prototype.constructor
The initial value of BigInt.prototype.constructor is the intrinsic object
5.3.2BigInt.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )
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.
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.
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.
5.3.3BigInt.prototype.toString ( [ radix ] )
The optional radix should be an integer value in the inclusive range 2 to 36. If radix not present or is
The following steps are performed:
- Let x be ? thisBigIntValue(
this value). - If radix is not present, let radixNumber be 10.
- Else if radix is
undefined , let radixNumber be 10. - Else, let radixNumber be ?
ToInteger (radix). - If radixNumber < 2 or radixNumber > 36, throw a
RangeError exception. - If radixNumber = 10, return !
ToString (x). - Return the String representation of this Number value using the radix specified by radixNumber. Letters
a-zare used for digits with values 10 through 35. The precise algorithm is implementation-dependent, however the algorithm should be a generalization of that specified in3.1.4.1 .
The toString function is not generic; it throws a
5.3.4BigInt.prototype.valueOf ( )
- Return ? thisBigIntValue(
this value).
5.3.5BigInt.prototype [ @@toStringTag ]
The initial value of the @@toStringTag property is the String value "BigInt".
This property has the attributes { [[Writable]]:
6Modified algorithms
6.1Runtime Semantics: SerializeJSONProperty ( key, holder )
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:
- Let value be ?
Get (holder, key). - If
Type (value) is Object or BigInt, then- Let toJSON be ?
Get GetV (value,"toJSON"). - If
IsCallable (toJSON) istrue , then- Set value to ?
Call (toJSON, value, « key »).
- Set value to ?
- Let toJSON be ?
- If ReplacerFunction is not
undefined , then- Set value to ?
Call (ReplacerFunction, holder, « key, value »).
- Set value to ?
- If
Type (value) is Object, then- If value has a [[NumberData]] internal slot, then
- Set value to ?
ToNumber (value).
- Set value to ?
- Else if value has a [[StringData]] internal slot, then
- Set value to ?
ToString (value).
- Set value to ?
- Else if value has a [[BooleanData]] internal slot, then
- Set value to value.[[BooleanData]].
- Else if value has a [[BigIntData]] internal slot, then
- Set value to value.[[BigIntData]].
- If value has a [[NumberData]] internal slot, then
- If value is
null , return"null". - If value is
true , return"true". - If value is
false , return"false". - If
Type (value) is String, returnQuoteJSONString (value). - If
Type (value) is Number, then- If value is finite, return !
ToString (value). - Else, return
"null".
- If value is finite, return !
- If
Type (value) is BigInt, throw aTypeError exception. - If
Type (value) is Object andIsCallable (value) isfalse , then- Let isArray be ?
IsArray (value). - If isArray is
true , return ?SerializeJSONArray (value). - Else, return ?
SerializeJSONObject (value).
- Let isArray be ?
- Return
undefined .
6.2Number ( value )
When Number is called with argument value, the following steps are taken:
- If no arguments were passed to this function invocation, let n be
+0 . - Else,
- If NewTarget is
undefined , return n. - Let O be ?
OrdinaryCreateFromConstructor (NewTarget,"%NumberPrototype%", « [[NumberData]] »). - Set O.[[NumberData]] to n.
- Return O.
6.3Math.pow ( base, exponent )
7TypedArrays 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.1TypedArray Objects
| Constructor Name and Intrinsic | Element Type | Element Size | Conversion Operation | Description | Equivalent C Type |
|---|---|---|---|---|---|
|
BigInt64Array
%BigInt64Array% |
BigInt64 | 8 |
|
64-bit two's complement signed integer | signed long long |
|
BigUint64Array
%BigUint64Array% |
BigUint64 | 8 |
|
64-bit unsigned integer | unsigned long long |
7.2StringToBigInt ( argument )
Apply the algorithm in
- Replace the
StrUnsignedDecimalLiteral production withDecimalDigits to not allowInfinity , decimal points, or exponents. - If the MV is
NaN , returnNaN , otherwise return the BigInt which exactly corresponds to the MV, rather than rounding to a Number.
7.3ToBigInt ( 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 .
| Argument Type | Result |
|---|---|
| Undefined |
Throw a |
| Null |
Throw a |
| Boolean |
Return 1n if prim is 0n if prim is |
| BigInt | Return prim. |
| Number |
Throw a |
| String |
|
| Symbol |
Throw a |
7.4ToBigInt64 ( 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:
7.5ToBigUint64 ( 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:
7.6RawBytesToNumberNumeric( type, rawBytes, isLittleEndian )
The abstract operation RawBytesToNumberNumeric takes three parameters, a String type, a
- 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.7NumberNumericToRawBytes( type, value, isLittleEndian )
The abstract operation NumberNumericToRawBytes 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 isfalse , the bytes are arranged in big endian order. Otherwise, the bytes are arranged in little endian order. If value isNaN , 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 distinguishableNaN value.
- Set rawBytes to a
- 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 isfalse , the bytes are arranged in big endian order. Otherwise, the bytes are arranged in little endian order. If value isNaN , 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 distinguishableNaN value.
- Set rawBytes to a
- 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 isfalse , the bytes are ordered in big endian order. Otherwise, the bytes are ordered in little endian order.
- Let rawBytes be a
- Else,
- Let rawBytes be a
List containing the n-byte binary two's complement encoding of intValue. If isLittleEndian isfalse , the bytes are ordered in big endian order. Otherwise, the bytes are ordered in little endian order.
- Let rawBytes be a
- Let n be the Number value of the Element Size specified in
- Return rawBytes.
7.8IntegerIndexedElementSet ( 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) istrue , throw aTypeError exception. - If
IsInteger (index) isfalse , returnfalse . - If index =
-0 , returnfalse . - 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.9SetValueInBuffer ( 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) isfalse . - 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 'sAgent Record . - Let rawBytes be
NumberNumericToRawBytes(type, value, isLittleEndian). - If IsSharedArrayBuffer(arrayBuffer) is
true , then- Let execution be the [[CandidateExecution]] field of the
surrounding agent 'sAgent 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 betrue ; otherwise let noTear befalse . - Append WriteSharedMemory{ [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes } to eventList.
- Let execution be the [[CandidateExecution]] field of the
- Else, store the individual bytes of rawBytes into block, in order, starting at block[byteIndex].
- Return
NormalCompletion (undefined ).
7.10GetValueFromBuffer ( 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) isfalse . - 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 'sAgent 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 betrue ; otherwise let noTear befalse . - 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]].
- Let execution be the [[CandidateExecution]] field of the
- 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 'sAgent Record . - Return RawBytesTo
NumberNumeric(type, rawValue, isLittleEndian).
7.11GetModifySetValueInBuffer( 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 'sAgent Record . - Let rawBytes be
NumberNumericToRawBytes(type, value, isLittleEndian). - Let execution be the [[CandidateExecution]] field of the
surrounding agent 'sAgent 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
NumberNumeric(type, rawBytesRead, isLittleEndian).
7.12ValidateSharedIntegerTypedArray(typedArray [ , waitable ] )
The abstract operation ValidateSharedIntegerTypedArray takes one argument typedArray and an optional Boolean waitable. It performs the following steps:
- If waitable is not present, set waitable to
false . - If
Type (typedArray) is not Object, throw aTypeError exception. - If typedArray does not have a [[TypedArrayName]] internal slot, throw a
TypeError exception. - Let typeName be typedArray.[[TypedArrayName]].
- If waitable is
true , then- If typeName is not
"Int32Array"or"BigInt64Array", throw aTypeError exception.
- If typeName is not
- Else,
- If typeName is not
"Int8Array","Uint8Array","Int16Array","Uint16Array","Int32Array","Uint32Array","BigUint64Array", or"BigInt64Array", throw aTypeError exception.
- If typeName is not
- Assert: typedArray has a [[ViewedArrayBuffer]] internal slot.
- Let buffer be typedArray.[[ViewedArrayBuffer]].
- If IsSharedArrayBuffer(buffer) is
false , throw aTypeError exception. - Return buffer.
7.13AtomicReadModifyWrite( 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
- 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.14Atomics.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", - Otherwise,
- 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 'sAgent Record . - Let expectedBytes be
NumberNumericToRawBytes(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
compareExchangedenote a semantic function of twoList 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.15Atomics.isLockFree( size )
The following steps are taken:
- Let n be ?
ToInteger (size). - Let AR be the
Agent Record of thesurrounding 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 .
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 Atomics.isLockFree(n) will return
Atomics.isLockFree(4) always returns
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.16Atomics.wait( typedArray, index, value, timeout )
Atomics.wait puts the calling
- 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 bemax (q, 0). - Let B be AgentCanSuspend().
- If B is
false , throw aTypeError 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 ×
4elementSize) + 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.17Atomics.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 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 ×
4elementSize) + 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.
- Let W be the first
- Perform LeaveCriticalSection(WL).
- Return n.
7.18Atomics.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 )
.prototype.sort is a distinct function that, except as described below, implements the same requirements as those of Array.prototype.sort as defined in .prototype.sort specification may be optimized with the knowledge that the
This function is not generic. The
Upon entry, the following steps are performed to initialize evaluation of the sort function. These steps are used instead of the entry steps in
- If comparefn is not
undefined andIsCallable (comparefn) isfalse , throw aTypeError 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 .prototype.sort.
The following version of .prototype.sort. It performs a numeric comparison rather than the string comparison used in sort method.
When the TypedArray
- Assert: Both
Type (x) andType (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) istrue , throw aTypeError exception. - If v is
NaN , return+0 . - Return v.
- Let v be ?
- 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 .
Because
7.20TypedArraySpeciesCreate ( 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). ReturnLet 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 aTypeError exception. - Return result.
7.21%TypedArray%.prototype.fill ( value [ , start [ , end ] ] )
The interpretation and use of the arguments of .prototype.fill are the same as for Array.prototype.fill as defined in
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 bemin (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 bemin (relativeEnd, len). - If
IsDetachedBuffer (O.[[ViewedArrayBuffer]]) istrue , throw aTypeError exception. - Repeat, while k < final
- 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 in7.23 applies. - Let target be the
this value. - If
Type (target) is not Object, throw aTypeError 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) istrue , throw aTypeError 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) istrue , throw aTypeError exception. - Perform
SetValueInBuffer (targetBuffer, targetByteIndex, targetType,kNumbervalue,true ,"Unordered"). - Set k to k + 1.
- Set targetByteIndex to targetByteIndex + targetElementSize.
- Let Pk be !
- 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 aTypeError 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) istrue , throw aTypeError exception. - Let targetLength be target.[[ArrayLength]].
- Let srcBuffer be typedArray.[[ViewedArrayBuffer]].
- If
IsDetachedBuffer (srcBuffer) istrue , throw aTypeError 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 aTypeError 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 betrue ; else let same befalse .
- If srcBuffer.[[ArrayBufferData]] and targetBuffer.[[ArrayBufferData]] are the same Shared
- 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) istrue , 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.
- Let value be
- 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.
- Let value be
- Repeat, while targetByteIndex < limit
- Return
undefined .
7.24TypedArray ( 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 aTypeError 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,"%TypedArrayPrototype%"). - Let srcArray be typedArray.
- Let srcData be srcArray.[[ViewedArrayBuffer]].
- If
IsDetachedBuffer (srcData) istrue , throw aTypeError 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% ).
- Let bufferConstructor be ?
- Else,
- Let bufferConstructor be
%ArrayBuffer% .
- Let bufferConstructor be
- If
SameValue (elementType, srcType) istrue , then- If
IsDetachedBuffer (srcData) istrue , throw aTypeError exception. - Let data be ?
CloneArrayBuffer (srcData, srcByteOffset, byteLength, bufferConstructor).
- If
- Else,
- Let data be ?
AllocateArrayBuffer (bufferConstructor, byteLength). - If
IsDetachedBuffer (srcData) istrue , throw aTypeError exception. - If one of srcType and elementType contains the substring
"Big"and the other does not, throw aTypeError 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.
- Let value be
- Let data be ?
- Set O.[[ViewedArrayBuffer]] to data.
- Set O.[[ByteLength]] to byteLength.
- Set O.[[ByteOffset]] to 0.
- Set O.[[ArrayLength]] to elementLength.
- Return O.
7.25SetViewValue ( 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 aTypeError 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) istrue , throw aTypeError 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.26DataView.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.27DataView.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.28DataView.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).
7.29DataView.prototype.setBigUint64 ( byteOffset, value [ , littleEndian ] )
When the setBigUint64 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,"BigUint64", value).
8Agents
An agent comprises a set of ECMAScript execution contexts, an
An
Some web browsers share a single
While an
| Field Name | Value | Meaning |
|---|---|---|
| [[LittleEndian]] | Boolean | The default value computed for the isLittleEndian parameter when it is needed by the algorithms |
| [[CanBlock]] | Boolean | Determines whether the |
| [[Signifier]] | Any globally-unique value | Uniquely identifies the |
| [[IsLockFree1]] | Boolean | |
| [[IsLockFree2]] | Boolean | |
| [[IsLockFree8]] | Boolean | |
| [[CandidateExecution]] | A candidate execution |
See the memory model. |
Once the values of [[Signifier]], [[IsLockFree1]], [[IsLockFree2]], and [[IsLockFree8]] have been observed by any
The values of [[IsLockFree1]], [[IsLockFree2]], and [[IsLockFree8]] are not necessarily determined by the hardware, but may also reflect implementation choices that can vary over time and between ECMAScript implementations.
There is no [[IsLockFree4]] property: 4-byte atomic operations are always lock-free.
In practice, if an atomic operation is implemented with any type of lock the operation is not lock-free. Lock-free does not imply wait-free: there is no upper bound on how many machine steps may be required to complete a lock-free atomic operation.
That an atomic access of size n is lock-free does not imply anything about the (perceived) atomicity of non-atomic accesses of size n, specifically, non-atomic accesses may still be performed as a sequence of several separate memory accesses. See ReadSharedMemory and WriteSharedMemory for details.