Skip to content

Commit

Permalink
Layering: Rephrase as HostEnqueuePromiseJob
Browse files Browse the repository at this point in the history
Rather than using a string queue name, this patch uses separate hooks
for separate things that may be scheduled, in order to permit the
clear expression of invariants which differ based on the particular
type of job. For example, Promise Jobs are required to be served in
FIFO order, whereas WeakRef Jobs are unordered.
  • Loading branch information
littledan committed Sep 2, 2019
1 parent 2d9ca04 commit c7adb05
Showing 1 changed file with 24 additions and 34 deletions.
58 changes: 24 additions & 34 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -6499,42 +6499,32 @@ <h1>GetGlobalObject ( )</h1>
</emu-clause>

<emu-clause id="sec-jobs-and-job-queues">
<h1>Jobs and Job Queues</h1>
<p>Each agent has its own set of named Job Queues. All references to a named job queue in this specification denote the named job queue of the surrounding agent.</p>

<h1>Jobs and Host Operations to Enqueue Jobs</h1>
<p>A <dfn>Job</dfn> is an abstract operation that initiates an ECMAScript computation when no other ECMAScript computation is currently in progress. A Job abstract operation may be defined to accept an arbitrary set of job parameters.</p>

<p>The exact normative requirements of evaluating Jobs are governed by the requirements on the HostEnqueueJob abstract operation. Here we explain the conceptual background and intuition in a non-normative fashion.</p>

<p>A <dfn>Job Queue</dfn> is a FIFO queue of PendingJob records, denoted by a String passed as the first argument to HostEnqueueJob. (The FIFO nature of a Job Queue is enforced by the requirements on HostEnqueueJob.) Each Job Queue has such a String name, and the full set of available Job Queues are defined by an ECMAScript implementation.</p>

<p>Every ECMAScript implementation has at least the Job Queue `"PromiseJobs"`, which are responses to the settlement of a Promise (see <emu-xref href="#sec-promise-objects"></emu-xref>).</p>
<p>Jobs are scheduled for execution by ECMAScript host environments with abstract operations such as HostEnqueuePromiseJob. Such operations accept two parameters: _job_, an abstract operation, and _arguments_, a list of ECMAScript values. These abstract operations schedule _job_ to be performed with _arguments_ at some future time. Their implementations must conform to the following requirements:</p>

<p>A request for the future execution of a Job is made by performing HostEnqueueJob, giving a Job Queue name, a Job abstract operation, and any necessary argument values. At some time when there is no running execution context and the execution context stack is empty, the ECMAScript implementation will perform the given Job abstract operation and evaluate it with the given arguments.</p>

<p>The Jobs enqueued on a single Job Queue are always required to be initiated in FIFO order. This specification does not impose requirements on the order in which multiple Job Queues are serviced. An ECMAScript implementation might interweave the FIFO evaluation of the Jobs on a Job Queue with the evaluation of Jobs on one or more other Job Queues. An implementation will define what occurs when there is no running execution context and all Job Queues are empty.</p>

<emu-clause id="sec-enqueuejob" aoid="HostEnqueueJob">
<h1>HostEnqueueJob ( _queueName_, _job_, _arguments_ )</h1>
<ul>
<li>At some future point in time, when there is no running execution context and the execution context stack is empty, the implementation must:
<ol>
<li>Push an execution context onto the execution context stack.</li>
<li>Perform any implementation-defined preparation steps.</li>
<li>Perform the abstract operation given by _job_, passing the arguments _arguments_.</li>
<li>Perform any implementation-defined cleanup steps.</li>
<li>Pop the previously-pushed execution context from the execution context stack.</li>
</ol>
</li>
<li>Only one Job may be actively undergoing evaluation at any point in time.</li>
<li>Once evaluation of a Job starts, it must run to completion before evaluation of any other Job starts.</li>
<li>The evaluation of any Jobs enqueueed via this or other host job scheduling algorithms must complete before evaluation of the Job starts.</li>
</ul>

<p>HostEnqueueJob is an implementation defined abstract operation that schedules the abstract operation indicated by _job_ to be performed, with the arguments _arguments_, at some future time. The String _queueName_ is used to enforce certain ordering guarantees among enqueued Jobs.</p>
<emu-clause id="sec-hostenqueuepromisejob" aoid="HostEnqueuePromiseJob">
<h1>HostEnqueuePromiseJob ( _job_, _arguments_ )</h1>

<p>The implementation of HostEnqueueJob must conform to the following requirements, all of which are scoped to each agent:</p>
<p>HostEnqueuePromiseJob is a host-defined abstract operation that schedules the abstract operation indicated by _job_ to be performed, with the arguments _arguments_, at some future time. The Jobs used with this algorithm are intended to be related to the handling of Promises, or otherwise, to be scheduled with equal priority to Promise handling operations.</p>

<ul>
<li>At some future point in time, when there is no running execution context and the execution context stack is empty, the implementation must:
<ol>
<li>Push an execution context onto the execution context stack.</li>
<li>Perform any implementation-defined preparation steps.</li>
<li>Perform the abstract operation given by _job_, passing the arguments _arguments_.</li>
<li>Perform any implementation-defined cleanup steps.</li>
<li>Pop the previously-pushed execution context from the execution context stack.</li>
</ol>
</li>
<li>Only one Job may be actively undergoing evaluation at any point in time.</li>
<li>Once evaluation of a Job starts, it must run to completion before evaluation of any other Job starts.</li>
<li>The evaluation of any Jobs enqueued via previous calls to HostEnqueueJob with the same _queueName_ argument must complete before evaluation of the Job starts.</li>
</ul>
<p>The implementation of HostEnqueuePromiseJob must conform to the requirements in <emu-xref href="#sec-jobs-and-job-queues"></emu-xref>. Additionally, Jobs must be scheduled in FIFO order, with Jobs running in the same order as the HostEnqueuePromiseJob invocations which scheduled them.</p>
</emu-clause>
</emu-clause>

Expand Down Expand Up @@ -37973,7 +37963,7 @@ <h1>Promise Resolve Functions</h1>
1. Let _thenAction_ be _then_.[[Value]].
1. If IsCallable(_thenAction_) is *false*, then
1. Return FulfillPromise(_promise_, _resolution_).
1. Perform HostEnqueueJob(`"PromiseJobs"`, PromiseResolveThenableJob, &laquo; _promise_, _resolution_, _thenAction_ &raquo;).
1. Perform HostEnqueuePromiseJob(PromiseResolveThenableJob, &laquo; _promise_, _resolution_, _thenAction_ &raquo;).
1. Return *undefined*.
</emu-alg>
<p>The `"length"` property of a promise resolve function is 1.</p>
Expand Down Expand Up @@ -38062,7 +38052,7 @@ <h1>TriggerPromiseReactions ( _reactions_, _argument_ )</h1>
<p>The abstract operation TriggerPromiseReactions takes a collection of PromiseReactionRecords and enqueues a new Job for each record. Each such Job processes the [[Type]] and [[Handler]] of the PromiseReactionRecord, and if the [[Handler]] is a function, calls it passing the given argument. If the [[Handler]] is *undefined*, the behaviour is determined by the [[Type]].</p>
<emu-alg>
1. For each _reaction_ in _reactions_, in original insertion order, do
1. Perform HostEnqueueJob(`"PromiseJobs"`, PromiseReactionJob, &laquo; _reaction_, _argument_ &raquo;).
1. Perform HostEnqueuePromiseJob(PromiseReactionJob, &laquo; _reaction_, _argument_ &raquo;).
1. Return *undefined*.
</emu-alg>
</emu-clause>
Expand Down Expand Up @@ -38487,12 +38477,12 @@ <h1>PerformPromiseThen ( _promise_, _onFulfilled_, _onRejected_ [ , _resultCapab
1. Append _rejectReaction_ as the last element of the List that is _promise_.[[PromiseRejectReactions]].
1. Else if _promise_.[[PromiseState]] is `"fulfilled"`, then
1. Let _value_ be _promise_.[[PromiseResult]].
1. Perform HostEnqueueJob(`"PromiseJobs"`, PromiseReactionJob, &laquo; _fulfillReaction_, _value_ &raquo;).
1. Perform HostEnqueuePromiseJob(PromiseReactionJob, &laquo; _fulfillReaction_, _value_ &raquo;).
1. Else,
1. Assert: The value of _promise_.[[PromiseState]] is `"rejected"`.
1. Let _reason_ be _promise_.[[PromiseResult]].
1. If _promise_.[[PromiseIsHandled]] is *false*, perform HostPromiseRejectionTracker(_promise_, `"handle"`).
1. Perform HostEnqueueJob(`"PromiseJobs"`, PromiseReactionJob, &laquo; _rejectReaction_, _reason_ &raquo;).
1. Perform HostEnqueuePromiseJob(PromiseReactionJob, &laquo; _rejectReaction_, _reason_ &raquo;).
1. Set _promise_.[[PromiseIsHandled]] to *true*.
1. If _resultCapability_ is *undefined*, then
1. Return *undefined*.
Expand Down

0 comments on commit c7adb05

Please sign in to comment.