Skip to content

Commit

Permalink
Normative: close underlying iterators when return is called before ne…
Browse files Browse the repository at this point in the history
…xt (#267)

Co-authored-by: Michael Ficarra <m.ficarra@f5.com>
  • Loading branch information
bakkot and michaelficarra committed Mar 30, 2023
1 parent 830784d commit 5a57b6b
Showing 1 changed file with 59 additions and 6 deletions.
65 changes: 59 additions & 6 deletions spec.html
Expand Up @@ -271,8 +271,16 @@ <h1>%IteratorHelperPrototype%.next ( )</h1>
<emu-clause id="sec-%iteratorhelperprototype%.return">
<h1>%IteratorHelperPrototype%.return ( )</h1>
<emu-alg>
1. Let _O_ be *this* value.
1. Perform ? RequireInternalSlot(_O_, [[UnderlyingIterator]]).
1. Assert: _O_ has a [[GeneratorState]] slot.
1. If _O_.[[GeneratorState]] is ~suspendedStart~, then
1. Set _O_.[[GeneratorState]] to ~completed~.
1. NOTE: Once a generator enters the completed state it never leaves it and its associated execution context is never resumed. Any execution state associated with _O_ can be discarded at this point.
1. Perform ? IteratorClose(_O_.[[UnderlyingIterator]], NormalCompletion(~unused~)).
1. Return CreateIterResultObject(*undefined*, *true*).
1. Let _C_ be Completion { [[Type]]: ~return~, [[Value]]: *undefined*, [[Target]]: ~empty~ }.
1. Return ? GeneratorResumeAbrupt(*this* value, _C_, *"Iterator Helper"*).
1. Return ? GeneratorResumeAbrupt(_O_, _C_, *"Iterator Helper"*).
</emu-alg>
</emu-clause>

Expand Down Expand Up @@ -317,7 +325,9 @@ <h1>Iterator.prototype.map ( _mapper_ )</h1>
1. Let _completion_ be Completion(Yield(_mapped_)).
1. IfAbruptCloseIterator(_completion_, _iterated_).
1. Set _counter_ to _counter_ + 1.
1. Return CreateIteratorFromClosure(_closure_, *"Iterator Helper"*, %IteratorHelperPrototype%).
1. Let _result_ be CreateIteratorFromClosure(_closure_, *"Iterator Helper"*, %IteratorHelperPrototype%, « [[UnderlyingIterator]] »).
1. Set _result_.[[UnderlyingIterator]] to _iterated_.
1. Return _result_.
</emu-alg>
</emu-clause>

Expand All @@ -341,7 +351,9 @@ <h1>Iterator.prototype.filter ( _predicate_ )</h1>
1. Let _completion_ be Completion(Yield(_value_)).
1. IfAbruptCloseIterator(_completion_, _iterated_).
1. Set _counter_ to _counter_ + 1.
1. Return CreateIteratorFromClosure(_closure_, *"Iterator Helper"*, %IteratorHelperPrototype%).
1. Let _result_ be CreateIteratorFromClosure(_closure_, *"Iterator Helper"*, %IteratorHelperPrototype%, « [[UnderlyingIterator]] »).
1. Set _result_.[[UnderlyingIterator]] to _iterated_.
1. Return _result_.
</emu-alg>
</emu-clause>

Expand All @@ -367,7 +379,9 @@ <h1>Iterator.prototype.take ( _limit_ )</h1>
1. If _next_ is *false*, return *undefined*.
1. Let _completion_ be Completion(Yield(? IteratorValue(_next_))).
1. IfAbruptCloseIterator(_completion_, _iterated_).
1. Return CreateIteratorFromClosure(_closure_, *"Iterator Helper"*, %IteratorHelperPrototype%).
1. Let _result_ be CreateIteratorFromClosure(_closure_, *"Iterator Helper"*, %IteratorHelperPrototype%, « [[UnderlyingIterator]] »).
1. Set _result_.[[UnderlyingIterator]] to _iterated_.
1. Return _result_.
</emu-alg>
</emu-clause>

Expand All @@ -394,7 +408,9 @@ <h1>Iterator.prototype.drop ( _limit_ )</h1>
1. If _next_ is *false*, return *undefined*.
1. Let _completion_ be Completion(Yield(? IteratorValue(_next_))).
1. IfAbruptCloseIterator(_completion_, _iterated_).
1. Return CreateIteratorFromClosure(_closure_, *"Iterator Helper"*, %IteratorHelperPrototype%).
1. Let _result_ be CreateIteratorFromClosure(_closure_, *"Iterator Helper"*, %IteratorHelperPrototype%, « [[UnderlyingIterator]] »).
1. Set _result_.[[UnderlyingIterator]] to _iterated_.
1. Return _result_.
</emu-alg>
</emu-clause>

Expand Down Expand Up @@ -431,7 +447,9 @@ <h1>Iterator.prototype.flatMap ( _mapper_ )</h1>
1. IfAbruptCloseIterator(_backupCompletion_, _iterated_).
1. Return ? IteratorClose(_completion_, _iterated_).
1. Set _counter_ to _counter_ + 1.
1. Return CreateIteratorFromClosure(_closure_, *"Iterator Helper"*, %IteratorHelperPrototype%).
1. Let _result_ be CreateIteratorFromClosure(_closure_, *"Iterator Helper"*, %IteratorHelperPrototype%, « [[UnderlyingIterator]] »).
1. Set _result_.[[UnderlyingIterator]] to _iterated_.
1. Return _result_.
</emu-alg>
</emu-clause>

Expand Down Expand Up @@ -567,3 +585,38 @@ <h1>Iterator.prototype [ @@toStringTag ]</h1>
</emu-clause>
</emu-clause>
</emu-clause>

<emu-clause id="updated-abstract-operations">
<h1>Updated Abstract Operations</h1>

<emu-clause id="sec-createiteratorfromclosure" type="abstract operation">
<h1>
CreateIteratorFromClosure (
_closure_: an Abstract Closure with no parameters,
_generatorBrand_: a String or ~empty~,
_generatorPrototype_: an Object,
<ins>optional _extraSlots_: a List of names of internal slots,</ins>
): a Generator
</h1>
<dl class="header">
</dl>
<emu-alg>
1. NOTE: _closure_ can contain uses of the Yield operation to yield an IteratorResult object.
1. <ins>If _extraSlots_ is not present, set _extraSlots_ to a new empty List.</ins>
1. Let _internalSlotsList_ be <ins>the list-concatenation of _extraSlots_ and</ins> « [[GeneratorState]], [[GeneratorContext]], [[GeneratorBrand]] ».
1. Let _generator_ be OrdinaryObjectCreate(_generatorPrototype_, _internalSlotsList_).
1. Set _generator_.[[GeneratorBrand]] to _generatorBrand_.
1. Set _generator_.[[GeneratorState]] to *undefined*.
1. Let _callerContext_ be the running execution context.
1. Let _calleeContext_ be a new execution context.
1. Set the Function of _calleeContext_ to *null*.
1. Set the Realm of _calleeContext_ to the current Realm Record.
1. Set the ScriptOrModule of _calleeContext_ to _callerContext_'s ScriptOrModule.
1. If _callerContext_ is not already suspended, suspend _callerContext_.
1. Push _calleeContext_ onto the execution context stack; _calleeContext_ is now the running execution context.
1. Perform GeneratorStart(_generator_, _closure_).
1. Remove _calleeContext_ from the execution context stack and restore _callerContext_ as the running execution context.
1. Return _generator_.
</emu-alg>
</emu-clause>
</emu-clause>

0 comments on commit 5a57b6b

Please sign in to comment.