You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TypedArray, %TypedArray%.from, and Array.from have a lot of redundancy between their iterator vs. array-like consumption branches, but they are also unnecessarily divergent from each other.
API
iterator input
array-like input
new TypedArray(input)
IteratorToList (no specified length limit but implementations don't even make it to 2**32)
InitializeTypedArrayFromList
AllocateTypedArrayBuffer with the requested length (throwing if greater than a threshold that is at most 2**53 - 1 but in actual implementations is much lower)
For each element, ? Set
InitializeTypedArrayFromArrayLike
AllocateTypedArrayBuffer with length LengthOfArrayLike(input) (which clamps to non-negative integers ≤ 2**53 - 1)
For each element, ? Get and ? Set
%TypedArray%.from(input)
IteratorToList (no specified length limit but implementations don't even make it to 2**32)
TypedArrayCreateFromConstructor with the requested length (receiver-aware but validates a TypedArray result)
For each element, ? Set
TypedArrayCreateFromConstructor with length LengthOfArrayLike(input)
For each element, ? Get and ? Set
Array.from(input)
ArrayCreate(0) or Construct(C) (receiver-aware)
GetIteratorFromMethod
For each iterator result, do
If k ≥ 2**53 - 1, throw (an actual Array will never reach this point; a non-Array can in principle but actual implementations are non-conformant for e.g. Array.from.call(new Proxy({}, { defineProperty: () => true }), (function*(){ for(;;) yield 0; })()) well below even 2**32)
? IteratorStepValue
If DONE, ? Set "length" (for an Array, this will throw for length ≥ 2**32) and return
? CreateDataPropertyOrThrow (for an Array, [[DefineOwnProperty]] requires also updating length up to 2**32 - 1 before switching to OrdinaryDefineOwnProperty)
ArrayCreate(LengthOfArrayLike(input)) or Construct(LengthOfArrayLike(C)) (receiver-aware, and ArrayCreate rejects length ≥ 2**32)
For each element, ? Get and ? CreateDataPropertyOrThrow (for an Array, [[DefineOwnProperty]] requires also updating length up to 2**32 - 1 before switching to OrdinaryDefineOwnProperty)
? Set "length" (for an Array, this will throw for length ≥ 2**32)
The two TypedArray APIs are very similar to each other, and the difference between branches inside of each is basically that iterator input is "fully" consumed up front to determine a length for allocation before entering a ? Set loop while non-iterator input is used to allocate with length LengthOfArrayLike before entering a ? Get + ? Set loop (i.e., the former performs all [fallible] reads before any [fallible] write, while the latter performs element reads and writes in [fallible] pairs before advancing). It would be nice to impose a threshold on the former (presumably implementation-defined but normatively capped at 2**53 - 1, corresponding with the eventual constraints of AllocateTypedArrayBuffer anyway), which (if desired) could also be used to consolidate the branches into something like
If usingIterator is not undefined, then
Let limit be TypedArraySizeLimit(C).
Let arrayLike be ? IteratorToArrayLike(? GetIteratorFromMethod(source, usingIterator), limit).
Else,
NOTE: source is not an iterable object, so assume it is already an array-like object.
Let arrayLike be ? ToObject(source).
NOTE: When usingIterator is not undefined, arrayLike is not observable from ECMAScript code and each of the following calls upon it will neither call user code nor return an abrupt completion.
Let len be ? LengthOfArrayLike(arrayLike).
Let O be ? TypedArrayCreateFromConstructor(C, « 𝔽(len) »).
Let k be 0.
Repeat, while k < len,
Let Pk be ! ToString(𝔽(k)).
Let kValue be ? Get(arrayLike, Pk).
If mapping is true, then
Let mappedValue be ? Call(mapper, thisArg, « kValue, 𝔽(k) »).
Else,
Let mappedValue be kValue.
Perform ? Set(O, Pk, mappedValue, true).
Set k to k + 1.
Array.from could be left alone, or (because the iterator branch already operates by read/write pairs) similarly consolidated via use of a non-observable iterator. I prefer leaving it for now, but at any rate not applying normative changes (unless we actually want to support the currently non-conformant behavior that never reaches 2**53 - 1).
The text was updated successfully, but these errors were encountered:
TypedArray, %TypedArray%.from, and Array.from have a lot of redundancy between their iterator vs. array-like consumption branches, but they are also unnecessarily divergent from each other.
new TypedArray(input)
%TypedArray%.from(input)
Array.from(input)
Array.from.call(new Proxy({}, { defineProperty: () => true }), (function*(){ for(;;) yield 0; })())
well below even 2**32)length
up to 2**32 - 1 before switching to OrdinaryDefineOwnProperty)length
up to 2**32 - 1 before switching to OrdinaryDefineOwnProperty)The two TypedArray APIs are very similar to each other, and the difference between branches inside of each is basically that iterator input is "fully" consumed up front to determine a length for allocation before entering a ? Set loop while non-iterator input is used to allocate with length LengthOfArrayLike before entering a ? Get + ? Set loop (i.e., the former performs all [fallible] reads before any [fallible] write, while the latter performs element reads and writes in [fallible] pairs before advancing). It would be nice to impose a threshold on the former (presumably implementation-defined but normatively capped at 2**53 - 1, corresponding with the eventual constraints of AllocateTypedArrayBuffer anyway), which (if desired) could also be used to consolidate the branches into something like
Array.from could be left alone, or (because the iterator branch already operates by read/write pairs) similarly consolidated via use of a non-observable iterator. I prefer leaving it for now, but at any rate not applying normative changes (unless we actually want to support the currently non-conformant behavior that never reaches 2**53 - 1).
The text was updated successfully, but these errors were encountered: