From 4406f95a95408d06dd206e6cf5882ed5bd4b05a5 Mon Sep 17 00:00:00 2001 From: Daniel Ehrenberg Date: Thu, 20 Jun 2019 15:54:38 +0200 Subject: [PATCH 1/2] Layering: Implement HostEnqueuePromiseJob The JavaScript specification is changing to make a HostEnqueuePromiseJob hook to be implemented by embedders. This allows HTML to avoid its willful violation, and delete an explanation of the motivation for this violation. --- source | 45 +++++++++++---------------------------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/source b/source index aab7fb01790..1badd67b217 100644 --- a/source +++ b/source @@ -3048,13 +3048,13 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • The CreateByteDataBlock abstract operation
  • The CreateDataProperty abstract operation
  • The DetachArrayBuffer abstract operation
  • -
  • The EnqueueJob abstract operation
  • The EnumerableOwnProperties abstract operation
  • The FunctionCreate abstract operation
  • The Get abstract operation
  • The GetActiveScriptOrModule abstract operation
  • The GetFunctionRealm abstract operation
  • The HasOwnProperty abstract operation
  • +
  • The HostEnqueuePromiseJob abstract operation
  • The HostEnsureCanCompileStrings abstract operation
  • The HostPromiseRejectionTracker abstract operation
  • The HostResolveImportedModule abstract operation
  • @@ -89156,8 +89156,8 @@ interface ApplicationCache : EventTarget { spec="WEBIDL">

    When Web IDL is used to invoke author - code, or when EnqueueJob invokes a promise job, they use the following algorithms to - track relevant data for determining the incumbent settings object:

    + code, or when HostEnqueuePromiseJob invokes a promise job, they use the following + algorithms to track relevant data for determining the incumbent settings object:

    To prepare to run a callback with an environment settings object settings:

    @@ -89466,39 +89466,15 @@ document.querySelector("button").addEventListener("click", bound); user with a mechanism to just close the page entirely, without running any unload event handlers.

    -
    Integration with the JavaScript job queue
    +
    HostEnqueuePromiseJob(job, arguments)
    -

    The JavaScript specification defines the JavaScript job and job queue abstractions in order to - specify certain invariants about how promise operations execute with a clean JavaScript - execution context stack and in a certain order. However, as of the time of this writing - the definition of EnqueueJob in that specification is not - sufficiently flexible to integrate with HTML as a host environment.

    - -

    This is not strictly true. It is in fact possible, by taking liberal advantage of - the many "implementation defined" sections of the algorithm, to contort it to our purposes. - However, the end result is a mass of messy indirection and workarounds that essentially bypasses - the job queue infrastructure entirely, albeit in a way that is technically sanctioned within the - bounds of implementation-defined behavior. We do not take this path, and instead introduce the - following willful violation.

    - -

    As such, user agents must instead use the following definition in place of that in the - JavaScript specification. These ensure that the promise jobs enqueued by the JavaScript - specification are properly integrated into the user agent's event - loops.

    - -

    The RunJobs abstract operation from the JavaScript specification must - not be used by user agents.

    - -
    EnqueueJob(queueName, job, arguments)
    - -

    When the JavaScript specification says to call the EnqueueJob abstract operation, the - following algorithm must be used in place of JavaScript's EnqueueJob:

    +

    JavaScript contains an implementation-defined HostEnqueuePromiseJob(job, + arguments) abstract operation to schedule Promise-related operations. HTML schedules + these operations in the microtask queue. User agents must use the following implementation: +

      -
    1. Assert: queueName is "PromiseJobs". ("ScriptJobs" must not be used by user agents.)

    2. -
    3. Let job settings be some appropriate environment settings object.

      @@ -89551,7 +89527,8 @@ document.querySelector("button").addEventListener("click", bound); handler will be created by the get the current value of the event handler algorithm, which creates a function with null [[ScriptOrModule]] value. Thus, when the promise machinery calls - EnqueueJob, there will be no active script to pass along.

      + HostEnqueuePromiseJob, there will be no active script to pass + along.

      As a consequence, this means that when the import() expression is evaluated, there will still be no active script. Fortunately that is handled by our From e8bae1b9110448ae209f6363170462791ac0a92b Mon Sep 17 00:00:00 2001 From: Daniel Ehrenberg Date: Tue, 19 Nov 2019 07:35:05 +0100 Subject: [PATCH 2/2] Layering: HostEnqueuePromiseJob uses PendingJob records --- source | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source b/source index 1badd67b217..1d6fc9eca39 100644 --- a/source +++ b/source @@ -89466,13 +89466,12 @@ document.querySelector("button").addEventListener("click", bound); user with a mechanism to just close the page entirely, without running any unload event handlers.

      -
      HostEnqueuePromiseJob(job, arguments)
      +
      HostEnqueuePromiseJob(pending)

      JavaScript contains an implementation-defined HostEnqueuePromiseJob(job, - arguments) abstract operation to schedule Promise-related operations. HTML schedules - these operations in the microtask queue. User agents must use the following implementation: -

      + data-x="js-HostEnqueuePromiseJob">HostEnqueuePromiseJob(pending) abstract + operation to schedule Promise-related operations. HTML schedules these operations in the microtask + queue. User agents must use the following implementation:

      1. @@ -89570,7 +89569,8 @@ document.querySelector("button").addEventListener("click", bound);
      2. Let result be the result of performing the abstract operation specified by - job, using the elements of arguments as its arguments.

      3. + pending.[[Job]], using the elements of pending.[[Arguments]] as its + arguments.

      4. If script execution context is not null, then pop script execution context from the JavaScript execution context