From 956e5af16984de6f37b2bd65c433c77dc975a35c Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Thu, 30 Mar 2023 16:17:49 -0700 Subject: [PATCH 1/4] Editorial: Refactor GetIterator to GetIteratorFromMethod (#3021) This removes the optional _hint_ parameter and the weird recursive call in GetIterator. --- spec.html | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/spec.html b/spec.html index 43979caa4e..791fbc21f4 100644 --- a/spec.html +++ b/spec.html @@ -6797,26 +6797,16 @@

Iterator Records

- +

- GetIterator ( + GetIteratorFromMethod ( _obj_: an ECMAScript language value, - optional _hint_: ~sync~ or ~async~, - optional _method_: a function object, + _method_: a function object, ): either a normal completion containing an Iterator Record or a throw completion

- 1. If _hint_ is not present, set _hint_ to ~sync~. - 1. If _method_ is not present, then - 1. If _hint_ is ~async~, then - 1. Set _method_ to ? GetMethod(_obj_, @@asyncIterator). - 1. If _method_ is *undefined*, then - 1. Let _syncMethod_ be ? GetMethod(_obj_, @@iterator). - 1. Let _syncIteratorRecord_ be ? GetIterator(_obj_, ~sync~, _syncMethod_). - 1. Return CreateAsyncFromSyncIterator(_syncIteratorRecord_). - 1. Otherwise, set _method_ to ? GetMethod(_obj_, @@iterator). 1. Let _iterator_ be ? Call(_method_, _obj_). 1. If _iterator_ is not an Object, throw a *TypeError* exception. 1. Let _nextMethod_ be ? GetV(_iterator_, *"next"*). @@ -6825,6 +6815,28 @@

+ +

+ GetIterator ( + _obj_: an ECMAScript language value, + optional _hint_: ~sync~ or ~async~, + ): either a normal completion containing an Iterator Record or a throw completion +

+
+
+ + 1. If _hint_ is not present, set _hint_ to ~sync~. + 1. If _hint_ is ~async~, then + 1. Let _method_ be ? GetMethod(_obj_, @@asyncIterator). + 1. If _method_ is *undefined*, then + 1. Let _syncMethod_ be ? GetMethod(_obj_, @@iterator). + 1. Let _syncIteratorRecord_ be ? GetIteratorFromMethod(_obj_, _syncMethod_). + 1. Return CreateAsyncFromSyncIterator(_syncIteratorRecord_). + 1. Otherwise, let _method_ be ? GetMethod(_obj_, @@iterator). + 1. Return ? GetIteratorFromMethod(_obj_, _method_). + +
+

IteratorNext ( @@ -7008,7 +7020,7 @@

1. If _method_ is present, then - 1. Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~, _method_). + 1. Let _iteratorRecord_ be ? GetIteratorFromMethod(_items_, _method_). 1. Else, 1. Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~). 1. Let _values_ be a new empty List. @@ -37258,7 +37270,7 @@

Array.from ( _items_ [ , _mapfn_ [ , _thisArg_ ] ] )

1. Let _A_ be ? Construct(_C_). 1. Else, 1. Let _A_ be ! ArrayCreate(0). - 1. Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~, _usingIterator_). + 1. Let _iteratorRecord_ be ? GetIteratorFromMethod(_items_, _usingIterator_). 1. Let _k_ be 0. 1. Repeat, 1. If _k_ ≥ 253 - 1, then From 256281144059d4137389468f4b093a51eea12678 Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Thu, 30 Mar 2023 16:17:54 -0700 Subject: [PATCH 2/4] Editorial: Make GetIterator's hint parameter required (#3021) --- spec.html | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/spec.html b/spec.html index 791fbc21f4..4fdd1818b9 100644 --- a/spec.html +++ b/spec.html @@ -6819,14 +6819,13 @@

GetIterator ( _obj_: an ECMAScript language value, - optional _hint_: ~sync~ or ~async~, + _kind_: ~sync~ or ~async~, ): either a normal completion containing an Iterator Record or a throw completion

- 1. If _hint_ is not present, set _hint_ to ~sync~. - 1. If _hint_ is ~async~, then + 1. If _kind_ is ~async~, then 1. Let _method_ be ? GetMethod(_obj_, @@asyncIterator). 1. If _method_ is *undefined*, then 1. Let _syncMethod_ be ? GetMethod(_obj_, @@iterator). @@ -9363,7 +9362,7 @@

BindingPattern : ArrayBindingPattern - 1. Let _iteratorRecord_ be ? GetIterator(_value_). + 1. Let _iteratorRecord_ be ? GetIterator(_value_, ~sync~). 1. Let _result_ be Completion(IteratorBindingInitialization of |ArrayBindingPattern| with arguments _iteratorRecord_ and _environment_). 1. If _iteratorRecord_.[[Done]] is *false*, return ? IteratorClose(_iteratorRecord_, _result_). 1. Return ? _result_. @@ -18058,7 +18057,7 @@

1. Let _spreadRef_ be ? Evaluation of |AssignmentExpression|. 1. Let _spreadObj_ be ? GetValue(_spreadRef_). - 1. Let _iteratorRecord_ be ? GetIterator(_spreadObj_). + 1. Let _iteratorRecord_ be ? GetIterator(_spreadObj_, ~sync~). 1. Repeat, 1. Let _next_ be ? IteratorStep(_iteratorRecord_). 1. If _next_ is *false*, return _nextIndex_. @@ -19099,7 +19098,7 @@

Runtime Semantics: ArgumentListEvaluation ( ): either a normal completion co 1. Let _list_ be a new empty List. 1. Let _spreadRef_ be ? Evaluation of |AssignmentExpression|. 1. Let _spreadObj_ be ? GetValue(_spreadRef_). - 1. Let _iteratorRecord_ be ? GetIterator(_spreadObj_). + 1. Let _iteratorRecord_ be ? GetIterator(_spreadObj_, ~sync~). 1. Repeat, 1. Let _next_ be ? IteratorStep(_iteratorRecord_). 1. If _next_ is *false*, return _list_. @@ -19117,7 +19116,7 @@

Runtime Semantics: ArgumentListEvaluation ( ): either a normal completion co 1. Let _precedingArgs_ be ? ArgumentListEvaluation of |ArgumentList|. 1. Let _spreadRef_ be ? Evaluation of |AssignmentExpression|. - 1. Let _iteratorRecord_ be ? GetIterator(? GetValue(_spreadRef_)). + 1. Let _iteratorRecord_ be ? GetIterator(? GetValue(_spreadRef_), ~sync~). 1. Repeat, 1. Let _next_ be ? IteratorStep(_iteratorRecord_). 1. If _next_ is *false*, return _precedingArgs_. @@ -20541,19 +20540,19 @@

ArrayAssignmentPattern : `[` `]` - 1. Let _iteratorRecord_ be ? GetIterator(_value_). + 1. Let _iteratorRecord_ be ? GetIterator(_value_, ~sync~). 1. Return ? IteratorClose(_iteratorRecord_, NormalCompletion(~unused~)). ArrayAssignmentPattern : `[` Elision `]` - 1. Let _iteratorRecord_ be ? GetIterator(_value_). + 1. Let _iteratorRecord_ be ? GetIterator(_value_, ~sync~). 1. Let _result_ be Completion(IteratorDestructuringAssignmentEvaluation of |Elision| with argument _iteratorRecord_). 1. If _iteratorRecord_.[[Done]] is *false*, return ? IteratorClose(_iteratorRecord_, _result_). 1. Return _result_. ArrayAssignmentPattern : `[` Elision? AssignmentRestElement `]` - 1. Let _iteratorRecord_ be ? GetIterator(_value_). + 1. Let _iteratorRecord_ be ? GetIterator(_value_, ~sync~). 1. If |Elision| is present, then 1. Let _status_ be Completion(IteratorDestructuringAssignmentEvaluation of |Elision| with argument _iteratorRecord_). 1. If _status_ is an abrupt completion, then @@ -20565,14 +20564,14 @@

ArrayAssignmentPattern : `[` AssignmentElementList `]` - 1. Let _iteratorRecord_ be ? GetIterator(_value_). + 1. Let _iteratorRecord_ be ? GetIterator(_value_, ~sync~). 1. Let _result_ be Completion(IteratorDestructuringAssignmentEvaluation of |AssignmentElementList| with argument _iteratorRecord_). 1. If _iteratorRecord_.[[Done]] is *false*, return ? IteratorClose(_iteratorRecord_, _result_). 1. Return _result_. ArrayAssignmentPattern : `[` AssignmentElementList `,` Elision? AssignmentRestElement? `]` - 1. Let _iteratorRecord_ be ? GetIterator(_value_). + 1. Let _iteratorRecord_ be ? GetIterator(_value_, ~sync~). 1. Let _status_ be Completion(IteratorDestructuringAssignmentEvaluation of |AssignmentElementList| with argument _iteratorRecord_). 1. If _status_ is an abrupt completion, then 1. If _iteratorRecord_.[[Done]] is *false*, return ? IteratorClose(_iteratorRecord_, _status_). @@ -21903,9 +21902,9 @@

1. Return the Iterator Record { [[Iterator]]: _iterator_, [[NextMethod]]: _nextMethod_, [[Done]]: *false* }. 1. Else, 1. Assert: _iterationKind_ is either ~iterate~ or ~async-iterate~. - 1. If _iterationKind_ is ~async-iterate~, let _iteratorHint_ be ~async~. - 1. Else, let _iteratorHint_ be ~sync~. - 1. Return ? GetIterator(_exprValue_, _iteratorHint_). + 1. If _iterationKind_ is ~async-iterate~, let _iteratorKind_ be ~async~. + 1. Else, let _iteratorKind_ be ~sync~. + 1. Return ? GetIterator(_exprValue_, _iteratorKind_). @@ -40402,7 +40401,7 @@

_adder_ will be invoked, with _target_ as the receiver.
- 1. Let _iteratorRecord_ be ? GetIterator(_iterable_). + 1. Let _iteratorRecord_ be ? GetIterator(_iterable_, ~sync~). 1. Repeat, 1. Let _next_ be ? IteratorStep(_iteratorRecord_). 1. If _next_ is *false*, return _target_. @@ -40714,7 +40713,7 @@

Set ( [ _iterable_ ] )

1. If _iterable_ is either *undefined* or *null*, return _set_. 1. Let _adder_ be ? Get(_set_, *"add"*). 1. If IsCallable(_adder_) is *false*, throw a *TypeError* exception. - 1. Let _iteratorRecord_ be ? GetIterator(_iterable_). + 1. Let _iteratorRecord_ be ? GetIterator(_iterable_, ~sync~). 1. Repeat, 1. Let _next_ be ? IteratorStep(_iteratorRecord_). 1. If _next_ is *false*, return _set_. @@ -41153,7 +41152,7 @@

WeakSet ( [ _iterable_ ] )

1. If _iterable_ is either *undefined* or *null*, return _set_. 1. Let _adder_ be ? Get(_set_, *"add"*). 1. If IsCallable(_adder_) is *false*, throw a *TypeError* exception. - 1. Let _iteratorRecord_ be ? GetIterator(_iterable_). + 1. Let _iteratorRecord_ be ? GetIterator(_iterable_, ~sync~). 1. Repeat, 1. Let _next_ be ? IteratorStep(_iteratorRecord_). 1. If _next_ is *false*, return _set_. @@ -44505,7 +44504,7 @@

Promise.all ( _iterable_ )

1. Let _promiseCapability_ be ? NewPromiseCapability(_C_). 1. Let _promiseResolve_ be Completion(GetPromiseResolve(_C_)). 1. IfAbruptRejectPromise(_promiseResolve_, _promiseCapability_). - 1. Let _iteratorRecord_ be Completion(GetIterator(_iterable_)). + 1. Let _iteratorRecord_ be Completion(GetIterator(_iterable_, ~sync~)). 1. IfAbruptRejectPromise(_iteratorRecord_, _promiseCapability_). 1. Let _result_ be Completion(PerformPromiseAll(_iteratorRecord_, _C_, _promiseCapability_, _promiseResolve_)). 1. If _result_ is an abrupt completion, then @@ -44608,7 +44607,7 @@

Promise.allSettled ( _iterable_ )

1. Let _promiseCapability_ be ? NewPromiseCapability(_C_). 1. Let _promiseResolve_ be Completion(GetPromiseResolve(_C_)). 1. IfAbruptRejectPromise(_promiseResolve_, _promiseCapability_). - 1. Let _iteratorRecord_ be Completion(GetIterator(_iterable_)). + 1. Let _iteratorRecord_ be Completion(GetIterator(_iterable_, ~sync~)). 1. IfAbruptRejectPromise(_iteratorRecord_, _promiseCapability_). 1. Let _result_ be Completion(PerformPromiseAllSettled(_iteratorRecord_, _C_, _promiseCapability_, _promiseResolve_)). 1. If _result_ is an abrupt completion, then @@ -44735,7 +44734,7 @@

Promise.any ( _iterable_ )

1. Let _promiseCapability_ be ? NewPromiseCapability(_C_). 1. Let _promiseResolve_ be Completion(GetPromiseResolve(_C_)). 1. IfAbruptRejectPromise(_promiseResolve_, _promiseCapability_). - 1. Let _iteratorRecord_ be Completion(GetIterator(_iterable_)). + 1. Let _iteratorRecord_ be Completion(GetIterator(_iterable_, ~sync~)). 1. IfAbruptRejectPromise(_iteratorRecord_, _promiseCapability_). 1. Let _result_ be Completion(PerformPromiseAny(_iteratorRecord_, _C_, _promiseCapability_, _promiseResolve_)). 1. If _result_ is an abrupt completion, then @@ -44831,7 +44830,7 @@

Promise.race ( _iterable_ )

1. Let _promiseCapability_ be ? NewPromiseCapability(_C_). 1. Let _promiseResolve_ be Completion(GetPromiseResolve(_C_)). 1. IfAbruptRejectPromise(_promiseResolve_, _promiseCapability_). - 1. Let _iteratorRecord_ be Completion(GetIterator(_iterable_)). + 1. Let _iteratorRecord_ be Completion(GetIterator(_iterable_, ~sync~)). 1. IfAbruptRejectPromise(_iteratorRecord_, _promiseCapability_). 1. Let _result_ be Completion(PerformPromiseRace(_iteratorRecord_, _C_, _promiseCapability_, _promiseResolve_)). 1. If _result_ is an abrupt completion, then From ff601405d8813cb980482b5f91144979da41670b Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Thu, 30 Mar 2023 16:17:58 -0700 Subject: [PATCH 3/4] Editorial: IterableToList -> IteratorToList (#3021) Also remove the the optional method parameter and change the callsites to explicitly get the iterator. --- spec.html | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/spec.html b/spec.html index 4fdd1818b9..c143d8ce35 100644 --- a/spec.html +++ b/spec.html @@ -7008,20 +7008,15 @@

- +

- IterableToList ( - _items_: an ECMAScript language value, - optional _method_: a function object, + IteratorToList ( + _iteratorRecord_: an Iterator Record, ): either a normal completion containing a List of ECMAScript language values or a throw completion

- 1. If _method_ is present, then - 1. Let _iteratorRecord_ be ? GetIteratorFromMethod(_items_, _method_). - 1. Else, - 1. Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~). 1. Let _values_ be a new empty List. 1. Let _next_ be *true*. 1. Repeat, while _next_ is not *false*, @@ -30789,7 +30784,7 @@

AggregateError ( _errors_, _message_ [ , _options_ ] )

1. Let _msg_ be ? ToString(_message_). 1. Perform CreateNonEnumerableDataPropertyOrThrow(_O_, *"message"*, _msg_). 1. Perform ? InstallErrorCause(_O_, _options_). - 1. Let _errorsList_ be ? IterableToList(_errors_). + 1. Let _errorsList_ be ? IteratorToList(? GetIterator(_errors_, ~sync~)). 1. Perform ! DefinePropertyOrThrow(_O_, *"errors"*, PropertyDescriptor { [[Configurable]]: *true*, [[Enumerable]]: *false*, [[Writable]]: *true*, [[Value]]: CreateArrayFromList(_errorsList_) }). 1. Return _O_.
@@ -39022,7 +39017,7 @@

%TypedArray%.from ( _source_ [ , _mapfn_ [ , _thisArg_ ] ] )

1. Let _mapping_ be *true*. 1. Let _usingIterator_ be ? GetMethod(_source_, @@iterator). 1. If _usingIterator_ is not *undefined*, then - 1. Let _values_ be ? IterableToList(_source_, _usingIterator_). + 1. Let _values_ be ? IteratorToList(? GetIteratorFromMethod(_source_, _usingIterator_)). 1. Let _len_ be the number of elements in _values_. 1. Let _targetObj_ be ? TypedArrayCreate(_C_, « 𝔽(_len_) »). 1. Let _k_ be 0. @@ -40113,7 +40108,7 @@

_TypedArray_ ( ..._args_ )

1. Assert: _firstArgument_ is an Object and _firstArgument_ does not have either a [[TypedArrayName]] or an [[ArrayBufferData]] internal slot. 1. Let _usingIterator_ be ? GetMethod(_firstArgument_, @@iterator). 1. If _usingIterator_ is not *undefined*, then - 1. Let _values_ be ? IterableToList(_firstArgument_, _usingIterator_). + 1. Let _values_ be ? IteratorToList(? GetIteratorFromMethod(_firstArgument_, _usingIterator_)). 1. Perform ? InitializeTypedArrayFromList(_O_, _values_). 1. Else, 1. NOTE: _firstArgument_ is not an Iterable so assume it is already an array-like object. From 784fc65c455f037b14c28ce56ed70dc93852dc1e Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Thu, 30 Mar 2023 16:18:01 -0700 Subject: [PATCH 4/4] Editorial: Throw on undefined early in GetIterator (#3021) This is editorial because Call inside GetIteratorFromMethod would throw on undefined anyways, and this keeps GetIteratorFromMethod cleaner in only accepting function objects. --- spec.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec.html b/spec.html index c143d8ce35..d7eb430fc1 100644 --- a/spec.html +++ b/spec.html @@ -6829,9 +6829,11 @@

1. Let _method_ be ? GetMethod(_obj_, @@asyncIterator). 1. If _method_ is *undefined*, then 1. Let _syncMethod_ be ? GetMethod(_obj_, @@iterator). + 1. If _syncMethod_ is *undefined*, throw a *TypeError* exception. 1. Let _syncIteratorRecord_ be ? GetIteratorFromMethod(_obj_, _syncMethod_). 1. Return CreateAsyncFromSyncIterator(_syncIteratorRecord_). 1. Otherwise, let _method_ be ? GetMethod(_obj_, @@iterator). + 1. If _method_ is *undefined*, throw a *TypeError* exception. 1. Return ? GetIteratorFromMethod(_obj_, _method_).