Skip to content

Commit

Permalink
Normative: guard against reentrancy in AsyncGenerator.prototype.return
Browse files Browse the repository at this point in the history
  • Loading branch information
bakkot committed Aug 10, 2024
1 parent bf2e2fe commit 4cb5a69
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -48461,7 +48461,7 @@ <h1>
1. Let _result_ be Completion(_generatorBody_()).
1. Assert: If we return here, the async generator either threw an exception or performed either an implicit or explicit return.
1. Remove _acGenContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
1. Set _acGenerator_.[[AsyncGeneratorState]] to ~completed~.
1. Set _acGenerator_.[[AsyncGeneratorState]] to ~awaiting-return~.
1. If _result_ is a normal completion, set _result_ to NormalCompletion(*undefined*).
1. If _result_ is a return completion, set _result_ to NormalCompletion(_result_.[[Value]]).
1. Perform AsyncGeneratorCompleteStep(_acGenerator_, _result_, *true*).
Expand Down Expand Up @@ -48626,28 +48626,28 @@ <h1>
<dl class="header">
</dl>
<emu-alg>
1. Assert: _generator_.[[AsyncGeneratorState]] is ~awaiting-return~.
1. Let _queue_ be _generator_.[[AsyncGeneratorQueue]].
1. Assert: _queue_ is not empty.
1. Let _next_ be the first element of _queue_.
1. Let _completion_ be Completion(_next_.[[Completion]]).
1. Assert: _completion_ is a return completion.
1. Let _promiseCompletion_ be Completion(PromiseResolve(%Promise%, _completion_.[[Value]])).
1. If _promiseCompletion_ is an abrupt completion, then
1. Set _generator_.[[AsyncGeneratorState]] to ~completed~.
1. Perform AsyncGeneratorCompleteStep(_generator_, _promiseCompletion_, *true*).
1. Perform AsyncGeneratorDrainQueue(_generator_).
1. Return ~unused~.
1. Assert: _promiseCompletion_ is a normal completion.
1. Let _promise_ be _promiseCompletion_.[[Value]].
1. Let _fulfilledClosure_ be a new Abstract Closure with parameters (_value_) that captures _generator_ and performs the following steps when called:
1. Set _generator_.[[AsyncGeneratorState]] to ~completed~.
1. Assert: _generator_.[[AsyncGeneratorState]] is ~awaiting-return~.
1. Let _result_ be NormalCompletion(_value_).
1. Perform AsyncGeneratorCompleteStep(_generator_, _result_, *true*).
1. Perform AsyncGeneratorDrainQueue(_generator_).
1. Return *undefined*.
1. Let _onFulfilled_ be CreateBuiltinFunction(_fulfilledClosure_, 1, *""*, « »).
1. Let _rejectedClosure_ be a new Abstract Closure with parameters (_reason_) that captures _generator_ and performs the following steps when called:
1. Set _generator_.[[AsyncGeneratorState]] to ~completed~.
1. Assert: _generator_.[[AsyncGeneratorState]] is ~awaiting-return~.
1. Let _result_ be ThrowCompletion(_reason_).
1. Perform AsyncGeneratorCompleteStep(_generator_, _result_, *true*).
1. Perform AsyncGeneratorDrainQueue(_generator_).
Expand All @@ -48669,22 +48669,25 @@ <h1>
<dd>It drains the generator's AsyncGeneratorQueue until it encounters an AsyncGeneratorRequest which holds a return completion.</dd>
</dl>
<emu-alg>
1. Assert: _generator_.[[AsyncGeneratorState]] is ~completed~.
1. Assert: _generator_.[[AsyncGeneratorState]] is ~awaiting-return~.
1. Let _queue_ be _generator_.[[AsyncGeneratorQueue]].
1. If _queue_ is empty, return ~unused~.
1. If _queue_ is empty, then
1. Set _generator_.[[AsyncGeneratorState]] to ~completed~.
1. Return ~unused~.
1. Let _done_ be *false*.
1. Repeat, while _done_ is *false*,
1. Let _next_ be the first element of _queue_.
1. Let _completion_ be Completion(_next_.[[Completion]]).
1. If _completion_ is a return completion, then
1. Set _generator_.[[AsyncGeneratorState]] to ~awaiting-return~.
1. Perform AsyncGeneratorAwaitReturn(_generator_).
1. Set _done_ to *true*.
1. Else,
1. If _completion_ is a normal completion, then
1. Set _completion_ to NormalCompletion(*undefined*).
1. Perform AsyncGeneratorCompleteStep(_generator_, _completion_, *true*).
1. If _queue_ is empty, set _done_ to *true*.
1. If _queue_ is empty, then
1. Set _generator_.[[AsyncGeneratorState]] to ~completed~.
1. Set _done_ to *true*.
1. Return ~unused~.
</emu-alg>
</emu-clause>
Expand Down

0 comments on commit 4cb5a69

Please sign in to comment.