Skip to content

Correct specification of parallel operations #1431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 103 additions & 79 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6066,12 +6066,13 @@ <h3>Executing Script</h3>
and <var>arguments</var>.
</ol>

<p>The rules to <dfn>execute a function body</dfn> are as follows.
The algorithm returns <a data-lt="completion">an ECMASCript completion record</a>.
<p>When required to <dfn>execute a function body</dfn> with arguments
<var>body</var>, <var>arguments</var>, and <var>async</var>, the
implementation must:

<p>If at any point during the algorithm a <a>user prompt</a> appears,
abort all subsequent substeps of this algorithm, and return
<a>Completion</a> { [[\Type]]: <code>normal</code>, [[\Value]]: <a><code>null</code></a>, [[\Target]]: <code>empty</code> }.
<a>success</a> with data <a><code>null</code></a>.

<ol>
<li><p>Let <var>window</var> be the <a>associated window</a>
Expand All @@ -6086,8 +6087,7 @@ <h3>Executing Script</h3>

<li><p>If <var>body</var> is not parsable as a <a>FunctionBody</a>
or if parsing detects an <a>early error</a>,
return
<a>Completion</a> { [[\Type]]: <code>normal</code>, [[\Value]]: <a><code>null</code></a>, [[\Target]]: <code>empty</code> }.
return <a>error</a> with <a>error code</a> <a>javascript error</a>.

<li><p>If <var>body</var> begins with a <a>directive prologue</a>
that contains a <a>use strict directive</a>
Expand All @@ -6098,6 +6098,17 @@ <h3>Executing Script</h3>

<li><p><a>Prepare to run a callback</a> with <var>environment settings</var>.

<li><p>Let <var>promise</var> be <a>a new Promise</a>.

<li><p>If <var>async</var> is <code>true</code>:

<ol>
<li><p>Let <var>resolvingFunctions</var> be <a>CreateResolvingFunctions</a>(<var>promise</var>).

<li><p>Append <var>resolvingFunctions</var><code>.[[\Resolve]]</code></var>
to <var>arguments</var>.
</ol>

<li><p>Let <var>function</var> be the result of
calling <a>FunctionCreate</a>, with arguments:

Expand All @@ -6121,15 +6132,58 @@ <h3>Executing Script</h3>
<li><p>Let <var>completion</var> be
<a>Call</a>(<var>function</var>,
<var>window</var>,
<var>parameters</var>).
<var>arguments</var>).

<li><p>If <var>completion</var>.[[\Type]] is <code>throw</code>,
<a>reject</a> <var>promise</var> with <var>completion</var>.[[\Value]].

<li><p>Otherwise, if <var>async</var> is <code>false</code>,
<a>resolve</a> <var>promise</var> with <var>completion</var>.[[\Value]].

<li><p>Otherwise,

<ol>
<p class=note>Prior revisions of this specification did not recognize the
return value of the provided script. In order to preserve legacy behavior,
the return value only influences this algorithm if it is a "thenable" object or
if determining this produces an exception.

<li><p>If <a data-lt="ecmascript type">Type</a>(<var>completion</var>.[[\Value]])
is <a>Object</a>:

<ol>
<li><p>Let <var>then</var> be <a>Get</a>(<var>completion</var>.[[\Value]], "then").

<li><p>If <var>then</var>.[[\Type]] is not <code>normal</code>, then <a>reject</a>
<var>promise</var> with value <var>then</var>.[[\Value]].

<li><p>Otherwise, if <a>IsCallable</a>(<var>then</var>.[[\Value]]) is
<code>true</code>, then <a>resolve</a> <var>promise</var> with <var>completion</var>.[[\Value]].
</ol>
</ol>

<li><p>Wait for <var>promise</var> to settle.

<li><p><a>Clean up after running a callback</a>
with <var>environment settings</var>.

<li><p><a>Clean up after running a script</a>
with <var>environment settings</var>.

<li><p>Return <var>completion</var>.
<li><p>If <var>promise</var> rejected:

<ol>
<li><p>Let <var>result</var> be the result of <a>trying</a> to
<a>JSON clone</a> the rejection value of <var>promise</var>.

<li><p>Return <a>error</a> with <a>error code</a> <a>javascript error</a>
and data <var>result</var>.
</ol>

<li><p>Let <var>result</var> be the result of <a>trying</a> to
<a>JSON clone</a> the fulfillment value of <var>promise</var>.

<li><p>Return <a>success</a> with data <var>result</var>.
</ol>

<p class="note">The above algorithm is not associated
Expand Down Expand Up @@ -6162,33 +6216,32 @@ <h3><dfn>Execute Script</dfn></h3>

<li><p><a>Handle any user prompts</a>, and return its value if it is an <a>error</a>.

<li><p>Let <var>promise</var> be <a>a new Promise</a>.
<li><p>Let <var>results</var> be a new <a>queue</a>.

<li><p>Run the following substeps <a>in parallel</a>:
<ol>
<li><p>Let <var>scriptPromise</var> be the result of <a>promise-calling</a>
<a>execute a function body</a>, with arguments
<var>body</var> and <var>arguments</var>.

<li><p>Upon fulfillment of <var>scriptPromise</var> with value <var>v</var>,
<a>resolve</a> <var>promise</var> with value <var>v</var>.
<ol>
<li><p>Let <var>script result</var> be the result of calling
<a>execute a function body</a>, with arguments
<var>body</var>, <var>arguments</var>, and <code>false</code>.

<li><p>Upon rejection of <var>scriptPromise</var> with value <var>r</var>,
<a>reject</a> <var>promise</var> with value <var>r</var>.
</ol>
<li><p>Enqueue <var>script result</var> in <var>results</var>.
</ol>

<li><p>Run the following substeps <a>in parallel</a>:

<ol>
<li><p>Wait <a>session script timeout</a> milliseconds.

<li><p>Enqueue <a>error</a> with <a>error code</a>
<a data-lt="script timeout error">script timeout</a> in <var>results</var>.
</ol>

<li><p>If <var>promise</var> is still pending and
the <a>session script timeout</a> is reached,
return <a>error</a> with <a>error code</a> <a data-lt="script timeout error">script timeout</a>.
<li><p>Wait for the size of <var>results</var> to be greater than 0.

<li><p>Upon fulfillment of <var>promise</var> with value <var>v</var>,
let <var>result</var> be a <a>JSON clone</a> of <var>v</var>, and
return <a>success</a> with data <var>result</var>.
<li><p>Dequeue <var>result</var> from <var>results</var>.

<li><p>Upon rejection of <var>promise</var> with reason <var>r</var>,
let <var>result</var> be a <a>JSON clone</a> of <var>r</var>, and
return <a>error</a> with <a>error code</a> <a>javascript error</a>
and data <var>result</var>.
<li><p>Return <var>result</var>.
</ol>
</section> <!-- /Execute Script -->

Expand Down Expand Up @@ -6216,69 +6269,41 @@ <h3><dfn>Execute Async Script</dfn></h3>
<p>The <a>remote end steps</a> are:

<ol>
<li><p>Let <var>body</var> and <var>arguments</var> by the result of <a>trying</a> to
<a>extract the script arguments from a request</a> with
argument <var>parameters</var>.

<li><p>If the <a>current browsing context</a> is <a>no longer open</a>,
return <a>error</a> with <a>error code</a> <a>no such window</a>.

<li><p><a>Handle any user prompts</a>, and return its value if it is an <a>error</a>.

<li><p>Let <var>promise</var> be <a>a new Promise</a>.

<li><p>Run the following substeps <a>in parallel</a>:
<ol>
<li><p>Let <var>resolvingFunctions</var> be <a>CreateResolvingFunctions</a>(<var>promise</var>).

<li><p>Append <var>resolvingFunctions</var><code>.[[\Resolve]]</code> to
<var>arguments</var>.

<li><p>Let <var>result</var> be the result of calling
<a>execute a function body</a>, with arguments
<var>body</var> and <var>arguments</var>.
<li><p>Let <var>body</var> and <var>arguments</var> be the result of
<a>trying</a> to <a>extract the script arguments from a request</a>
with argument <var>parameters</var>.

<li><p>If <var>scriptResult</var>.[[\Type]] is not <code>normal</code>, then <a>reject</a>
<var>promise</var> with value <var>scriptResult</var>.[[\Value]], and abort these steps.
<li><p>If the <a>current browsing context</a> is <a>no longer open</a>,
return <a>error</a> with <a>error code</a> <a>no such window</a>.

<p class=note>Prior revisions of this specification did not recognize the
return value of the provided script. In order to preserve legacy behavior,
the return value only influences the command if it is a "thenable" object or
if determining this produces an exception.
<li><p><a>Handle any user prompts</a>, and return its value if it is an <a>error</a>.

<li><p>If <a data-lt="ecmascript type">Type</a>(<var>scriptResult</var>.[[\Value]])
is not <a>Object</a>, then abort these steps.
<li><p>Let <var>results</var> be a new <a>queue</a>.

<li><p>Let <var>then</var> be <a>Get</a>(<var>scriptResult</var>.[[\Value]], "then").
<li><p>Run the following substeps <a>in parallel</a>:

<li><p>If <var>then</var>.[[\Type]] is not <code>normal</code>, then <a>reject</a>
<var>promise</var> with value <var>then</var>.[[\Value]], and abort these steps.
<ol>
<li><p>Let <var>script result</var> be the result of calling
<a>execute a function body</a>, with arguments
<var>body</var>, <var>arguments</var>, and <code>true</code>.

<li><p>If <a>IsCallable</a>(<var>then</var>.[[\Type]]) is <code>false</code>,
then abort these steps.
<li><p>Enqueue <var>script result</var> in <var>results</var>.
</ol>

<li><p>Let <var>scriptPromise</var> be <a>PromiseResolve</a>(<a>Promise</a>,
<var>scriptResult</var>.[[\Value]]).
<li><p>Run the following substeps <a>in parallel</a>:

<li><p>Upon fulfillment of <var>scriptPromise</var> with value <var>v</var>,
<a>resolve</a> <var>promise</var> with value <var>v</var>.
<ol>
<li><p>Wait <a>session script timeout</a> milliseconds.

<li><p>Upon rejection of <var>scriptPromise</var> with value <var>r</var>,
<a>reject</a> <var>promise</var> with value <var>r</var>.
</ol>
<li><p>Enqueue <a>error</a> with <a>error code</a>
<a data-lt="script timeout error">script timeout</a> in <var>results</var>.
</ol>

<li><p>If <var>promise</var> is still pending and
<a>session script timeout</a> milliseconds is reached,
return <a>error</a> with <a>error code</a> <a data-lt="script timeout error">script timeout</a>.
<li><p>Wait for the size of <var>results</var> to be greater than 0.

<li><p>Upon fulfillment of <var>promise</var> with value <var>v</var>,
let <var>result</var> be a <a>JSON clone</a> of <var>v</var>, and
return <a>success</a> with data <var>result</var>.
<li><p>Dequeue <var>result</var> from <var>results</var>.

<li><p>Upon rejection of <var>promise</var> with reason <var>r</var>,
let <var>result</var> be a <a>JSON clone</a> of <var>r</var>, and
return <a>error</a> with <a>error code</a> <a>javascript error</a>
and data <var>result</var>.
<li><p>Return <var>result</var>.
</ol>
</section> <!-- /Execute Async Script -->
</section> <!-- /Executing Script -->
Expand Down Expand Up @@ -9299,7 +9324,6 @@ <h2>Index</h2>
<dd><p>The following terms are defined in the ECMAScript Language Specification: [[ECMA-262]]
<ul>
<!-- Iterable --> <li><dfn><a href=https://tc39.github.io/ecma262/#sec-iterable-interface>Iterable</a></dfn>
<!-- Completion --> <li><dfn><a href="https://tc39.github.io/ecma262/#sec-completion-record-specification-type">Completion</a></dfn>
<!-- CreateResolvingFunctions --> <li><dfn><a href=https://tc39.github.io/ecma262/#sec-createresolvingfunctions>CreateResolvingFunctions</a></dfn>
<!-- Directive prologue --> <li><dfn><a href=https://www.ecma-international.org/ecma-262/5.1/#sec-14.1>Directive prologue</a></dfn>
<!-- Early error --> <li><dfn><a href=https://www.ecma-international.org/ecma-262/5.1/#sec-16>Early error</a></dfn>
Expand Down