From f1250681ef9a2c98f17c15c131f52d2d127d66aa Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Sun, 27 Feb 2022 12:58:54 -0800 Subject: [PATCH] Editorial: completion reform for JavaScript AOs As part of the https://github.com/tc39/ecma262/pull/2547 the JavaScript specification has reformed how it deals with Completion Records, and thus what abstract operations can return. See https://github.com/tc39/ecma262/issues/253#issuecomment-1050160672 for a brief description of when to use ? vs. ! vs. nothing at all. Additional minor fixes: * Replace uses of ObjectCreate (which no longer exists) with OrdinaryObjectCreate. * Replace "Rethrow any exceptions" with the ? syntax. * Use ? with GetFunctionRealm, which can throw due to revoked proxies. --- source | 137 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 72 insertions(+), 65 deletions(-) diff --git a/source b/source index 56c271daff3..fa36f321b07 100644 --- a/source +++ b/source @@ -2783,7 +2783,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • The Script production
  • The Type notation
  • -
  • The Completion Record specification type
  • +
  • The Completion Record specification type
  • The List and Record specification types
  • The Property Descriptor specification type
  • @@ -2837,7 +2837,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • The OrdinarySet abstract operation
  • The OrdinaryDelete abstract operation
  • The OrdinaryOwnPropertyKeys abstract operation
  • -
  • The ObjectCreate abstract operation
  • +
  • The OrdinaryObjectCreate abstract operation
  • The ParseModule abstract operation
  • The ParseScript abstract operation
  • The NewPromiseReactionJob abstract operation
  • @@ -8305,7 +8305,7 @@ interface DOMStringList {
  • Let size be value.[[ArrayBufferByteLength]].

  • -

    If ! IsSharedArrayBuffer(value) is true, then: +

    If IsSharedArrayBuffer(value) is true, then:

    1. @@ -8333,7 +8333,7 @@ interface DOMStringList {

      Otherwise:

        -
      1. If ! IsDetachedBuffer(value) is true, then throw a +

      2. If IsDetachedBuffer(value) is true, then throw a "DataCloneError" DOMException.

      3. @@ -8343,7 +8343,7 @@ interface DOMStringList { upon allocation failure.

      4. -
      5. Perform ! CopyDataBlockBytes(dataCopy, 0, +

      6. Perform CopyDataBlockBytes(dataCopy, 0, value.[[ArrayBufferData]], 0, size).

      7. Set serialized to { [[Type]]: "ArrayBuffer", [[ArrayBufferData]]: @@ -8853,7 +8853,7 @@ o.myself = o;

      8. Let message be serialized.[[Message]].

      9. -
      10. Set value to ! ObjectCreate(prototype, « +

      11. Set value to OrdinaryObjectCreate(prototype, « [[ErrorData]] »).

      12. Let messageDesc be PropertyDescriptor{ [[Value]]: @@ -9004,7 +9004,7 @@ o.myself = o; [[Detached]] internal slot, then throw a "DataCloneError" DOMException.

      13. -
      14. If transferable has an [[ArrayBufferData]] internal slot and ! +

      15. If transferable has an [[ArrayBufferData]] internal slot and IsSharedArrayBuffer(transferable) is true, then throw a "DataCloneError" DOMException.

      16. @@ -9032,7 +9032,7 @@ o.myself = o; transferList:

          -
        1. If transferable has an [[ArrayBufferData]] internal slot and ! +

        2. If transferable has an [[ArrayBufferData]] internal slot and IsDetachedBuffer(transferable) is true, then throw a "DataCloneError" DOMException.

        3. @@ -10650,14 +10650,14 @@ document.createElement("bad-1"); // (2) via new MyCustomElement().

          -
        4. Let prototype be Get(NewTarget, - "prototype"). Rethrow any exceptions.

        5. +
        6. Let prototype be ? Get(NewTarget, + "prototype").

        7. If Type(prototype) is not Object, then:

            -
          1. Let realm be GetFunctionRealm(NewTarget).

          2. +
          3. Let realm be ? GetFunctionRealm(NewTarget).

          4. Set prototype to the interface prototype object of realm whose interface is the same as the interface of the active function @@ -10720,8 +10720,7 @@ class DontDoThis extends HTMLElement {

          5. -
          6. Perform element.[[SetPrototypeOf]](prototype). Rethrow any - exceptions.

          7. +
          8. Perform ? element.[[SetPrototypeOf]](prototype).

          9. Replace the last entry in definition's construction stack with an @@ -49536,8 +49535,9 @@ ldh-str = < as defined in u").

          10. -

            If regexpCompletion is an abrupt completion, then return nothing. The - element has no compiled pattern regular expression.

            +

            If regexpCompletion is an abrupt + completion, then return nothing. The element has no compiled pattern regular + expression.

            User agents are encouraged to log this error in a developer console, to aid debugging.

            @@ -69224,8 +69224,8 @@ dictionary ElementDefinitionOptions {

            Run the following substeps while catching any exceptions:

              -
            1. Let prototype be Get(constructor, - "prototype"). Rethrow any exceptions.

            2. +
            3. Let prototype be ? Get(constructor, + "prototype").

            4. If Type(prototype) is not Object, then throw a TypeError exception.

            5. @@ -69240,8 +69240,8 @@ dictionary ElementDefinitionOptions { order listed in the previous step:

                -
              1. Let callbackValue be Get(prototype, - callbackName). Rethrow any exceptions.

                +
              2. Let callbackValue be ? Get(prototype, + callbackName).

              3. If callbackValue is not undefined, then set the value of the entry in lifecycleCallbacks with key callbackName to the result of ElementDefinitionOptions { data-x="">attributeChangedCallback" is not null, then:

                  -
                1. Let observedAttributesIterable be Get(constructor, "observedAttributes"). Rethrow any - exceptions.

                2. +
                3. Let observedAttributesIterable be ? Get(constructor, "observedAttributes").

                4. If observedAttributesIterable is not undefined, then set observedAttributes to the result of ElementDefinitionOptions {

                5. Let disabledFeatures be an empty sequence<DOMString>.

                6. -
                7. Let disabledFeaturesIterable be Get(constructor, "disabledFeatures"). Rethrow any - exceptions.

                8. +
                9. Let disabledFeaturesIterable be ? Get(constructor, "disabledFeatures").

                10. If disabledFeaturesIterable is not undefined, then set disabledFeatures to the result of ElementDefinitionOptions {

                11. Set disableShadow to true if disabledFeatures contains "shadow".

                12. -
                13. Let formAssociatedValue be Get( - constructor, "formAssociated"). Rethrow any exceptions.

                14. +
                15. Let formAssociatedValue be ? Get( + constructor, "formAssociated").

                16. Set formAssociated to the result of converting formAssociatedValue to a @@ -69299,8 +69297,8 @@ dictionary ElementDefinitionOptions { "formStateRestoreCallback" callbackName:

                    -
                  1. Let callbackValue be Get(prototype, - callbackName). Rethrow any exceptions.

                  2. +
                  3. Let callbackValue be ? Get(prototype, + callbackName).

                  4. If callbackValue is not undefined, then set the value of the entry in lifecycleCallbacks with key callbackName to the result of

                  5. -

                    For each e of ! CrossOriginProperties(platformObject):

                    +

                    For each e of CrossOriginProperties(platformObject):

                    1. @@ -81375,7 +81373,7 @@ console.assert(iframeWindow.frameElement === null);
                  6. -
                  7. If ! IsPlatformObjectSameOrigin(platformObject) is false, then +

                  8. If IsPlatformObjectSameOrigin(platformObject) is false, then throw a "SecurityError" DOMException.

                  @@ -81439,6 +81437,8 @@ console.assert(iframeWindow.frameElement === null); { [[Property]]: "postMessage" } ».

                +

                This abstract operation does not return a Completion Record.

                +

                Indexed properties do not need to be safelisted in this algorithm, as they are handled directly by the WindowProxy object.

                @@ -81473,6 +81473,8 @@ console.assert(iframeWindow.frameElement === null); data-x="concept-settings-object-origin">origin, and false otherwise.

              +

              This abstract operation does not return a Completion Record.

              +

              Here the current settings object roughly corresponds to the "caller", because this check occurs before the execution context for the getter/setter/method in question makes its way onto the JavaScript @@ -81492,7 +81494,7 @@ console.assert(iframeWindow.frameElement === null); object, O's relevant settings object, and P.

            6. -

              For each e of ! CrossOriginProperties(O):

              +

              For each e of CrossOriginProperties(O):

              1. @@ -81514,7 +81516,7 @@ console.assert(iframeWindow.frameElement === null);
                1. Let value be originalDesc.[[Value]].

                2. -
                3. If ! IsCallable(value) is true, then set value to +

                4. If IsCallable(value) is true, then set value to an anonymous built-in function, created in the current Realm Record, that performs the same steps as the IDL operation P on object O.

                5. @@ -81565,6 +81567,8 @@ console.assert(iframeWindow.frameElement === null);
                6. Return undefined.

                +

                This abstract operation does not return a Completion Record.

                +

                The reason that the property descriptors produced here are configurable is to preserve the invariants of the essential internal methods required by the JavaScript specification. In particular, since the value of the property can change as a consequence of @@ -81584,7 +81588,7 @@ console.assert(iframeWindow.frameElement === null);

              2. Assert: desc is not undefined.

              3. -
              4. If ! IsDataDescriptor(desc) is true, then return +

              5. If IsDataDescriptor(desc) is true, then return desc.[[Value]].

              6. Assert: IsAccessorDescriptor(desc) is true.

              7. @@ -81624,7 +81628,7 @@ console.assert(iframeWindow.frameElement === null);
                1. Let keys be a new empty List.

                2. -
                3. For each e of ! CrossOriginProperties(O),

                  For each e of CrossOriginProperties(O), append e.[[Property]] to keys.

                4. Return the concatenation of keys and « "then", @@ -81632,6 +81636,8 @@ console.assert(iframeWindow.frameElement === null); ».

                +

                This abstract operation does not return a Completion Record.

                + @@ -82748,7 +82754,7 @@ interface BarProp { [[Window]] internal slot of this.

                -
              8. If ! IsPlatformObjectSameOrigin(W) is true, then return ! +

              9. If IsPlatformObjectSameOrigin(W) is true, then return ! OrdinaryGetPrototypeOf(W).

              10. Return null.

              11. @@ -82805,7 +82811,7 @@ interface BarProp {

                If value is undefined, then:

                  -
                1. If ! IsPlatformObjectSameOrigin(W) is true, then return +

                2. If IsPlatformObjectSameOrigin(W) is true, then return undefined.

                3. Throw a "SecurityError" DOMException.

                4. @@ -82821,7 +82827,7 @@ interface BarProp {
                5. -

                  If ! IsPlatformObjectSameOrigin(W) is true, then return ! +

                  If IsPlatformObjectSameOrigin(W) is true, then return ! OrdinaryGetOwnProperty(W, P).

                  This is a willful violation of the JavaScript specification's @@ -82830,7 +82836,7 @@ interface BarProp { issue #672 for more information.

                6. -
                7. Let property be ! CrossOriginGetOwnPropertyHelper(W, +

                8. Let property be CrossOriginGetOwnPropertyHelper(W, P).

                9. If property is not undefined, then return property.

                10. @@ -82869,7 +82875,7 @@ interface BarProp { this.

                11. -

                  If ! IsPlatformObjectSameOrigin(W) is true, then: +

                  If IsPlatformObjectSameOrigin(W) is true, then:

                  1. If P is an array index property name, return false.

                  2. @@ -82901,7 +82907,7 @@ interface BarProp { data-x="window bc">browsing context, P, and the current settings object.

                    -
                  3. If ! IsPlatformObjectSameOrigin(W) is true, then return ? +

                  4. If IsPlatformObjectSameOrigin(W) is true, then return ? OrdinaryGet(this, P, Receiver).

                  5. Return ? CrossOriginGet(this, P, @@ -82925,7 +82931,7 @@ interface BarProp { and the current settings object.

                  6. -

                    If ! IsPlatformObjectSameOrigin(W) is true, then:

                    +

                    If IsPlatformObjectSameOrigin(W) is true, then:

                    1. If P is an array index property name, @@ -82954,7 +82960,7 @@ interface BarProp { this.

                    2. -

                      If ! IsPlatformObjectSameOrigin(W) is true, then: +

                      If IsPlatformObjectSameOrigin(W) is true, then:

                      1. @@ -83000,8 +83006,8 @@ interface BarProp {
                    3. -
                    4. If ! IsPlatformObjectSameOrigin(W) is true, then return the - concatenation of keys and ! +

                    5. If IsPlatformObjectSameOrigin(W) is true, then return the + concatenation of keys and OrdinaryOwnPropertyKeys(W).

                    6. Return the concatenation of keys and ! @@ -86299,8 +86305,8 @@ interface History { methods that are invoked on a timer, or from event listeners that are not triggered in response to a clear user action, or that are invoked in rapid succession.)

                    7. -
                    8. Let serializedData be - StructuredSerializeForStorage(data). Rethrow any exceptions.

                    9. +
                    10. Let serializedData be ? + StructuredSerializeForStorage(data).

                    11. Let newURL be the session history's current entry's URL.

                    12. @@ -87357,7 +87363,7 @@ interface Location { // but see also [[GetPrototypeOf]] ( )
                        -
                      1. If ! IsPlatformObjectSameOrigin(this) is true, then return ! +

                      2. If IsPlatformObjectSameOrigin(this) is true, then return ! OrdinaryGetPrototypeOf(this).

                      3. Return null.

                      4. @@ -87385,10 +87391,10 @@ interface Location { // but see also
                        -
                      5. Let property be ! CrossOriginGetOwnPropertyHelper(this, +

                      6. Let property be CrossOriginGetOwnPropertyHelper(this, P).

                      7. If property is not undefined, then return property.

                      8. @@ -87410,7 +87416,7 @@ interface Location { // but see also
                        [[Get]] ( P, Receiver )
                          -
                        1. If ! IsPlatformObjectSameOrigin(this) is true, then return ? +

                        2. If IsPlatformObjectSameOrigin(this) is true, then return ? OrdinaryGet(this, P, Receiver).

                        3. Return ? CrossOriginGet(this, P, @@ -87437,7 +87443,7 @@ interface Location { // but see also [[Set]] ( P, V, Receiver )

                            -
                          1. If ! IsPlatformObjectSameOrigin(this) is true, then return ? +

                          2. If IsPlatformObjectSameOrigin(this) is true, then return ? OrdinarySet(this, P, V, Receiver).

                          3. Return ? CrossOriginSet(this, P, V, @@ -87447,7 +87453,7 @@ interface Location { // but see also [[Delete]] ( P )

                              -
                            1. If ! IsPlatformObjectSameOrigin(this) is true, then return ? +

                            2. If IsPlatformObjectSameOrigin(this) is true, then return ? OrdinaryDelete(this, P).

                            3. Throw a "SecurityError" DOMException.

                            4. @@ -87456,10 +87462,10 @@ interface Location { // but see also
                              [[OwnPropertyKeys]] ( )
                                -
                              1. If ! IsPlatformObjectSameOrigin(this) is true, then return ! +

                              2. If IsPlatformObjectSameOrigin(this) is true, then return OrdinaryOwnPropertyKeys(this).

                              3. -
                              4. Return ! CrossOriginOwnPropertyKeys(this).

                              5. +
                              6. Return CrossOriginOwnPropertyKeys(this).

                              @@ -88561,9 +88567,9 @@ interface Location { // but see also
                              running the classic script script.

                              -
                            5. Let result be undefined if evaluationStatus is an abrupt - completion or evaluationStatus.[[Value]] is empty, or - evaluationStatus.[[Value]] otherwise.

                            6. +
                            7. Let result be undefined if evaluationStatus is an abrupt completion or evaluationStatus.[[Value]] is + empty, or evaluationStatus.[[Value]] otherwise.

                            8. If Type(result) is String, then set @@ -93243,7 +93249,8 @@ document.querySelector("button").addEventListener("click", bound);

                            9. -

                              If evaluationStatus is an abrupt completion, then:

                              +

                              If evaluationStatus is an abrupt + completion, then:

                              1. @@ -93856,8 +93863,8 @@ dictionary PromiseRejectionEventInit : EventInit

                                Clean up after running script with entry.

                              2. -
                              3. If result is an abrupt completion, then report the - exception given by result.[[Value]].

                              4. +
                              5. If result is an abrupt completion, + then report the exception given by result.[[Value]].

                            @@ -93925,8 +93932,8 @@ dictionary PromiseRejectionEventInit : EventInit

                            If job settings is not null, then clean up after running script with job settings.

                          4. -
                          5. If result is an abrupt completion, then report the - exception given by result.[[Value]].

                          6. +
                          7. If result is an abrupt completion, + then report the exception given by result.[[Value]].