Bug 1289318 - Part 1: Store contents of spec-defined `capabilities` struct in Promise reaction jobs directly. r?efaust draft
authorTill Schneidereit <till@tillschneidereit.net>
Wed, 27 Jul 2016 14:19:08 +0200
changeset 400694 0ee9448a059bc0c0f74a28ebfc56a0c39e1451fb
parent 400693 fe562e66e9b9235bc77ba5f982e0fa3206522e90
child 400695 e6681331ef9d56cba16468697bc837dabdb22439
push id26245
push userbmo:till@tillschneidereit.net
push dateMon, 15 Aug 2016 14:02:13 +0000
reviewersefaust
bugs1289318
milestone51.0a1
Bug 1289318 - Part 1: Store contents of spec-defined `capabilities` struct in Promise reaction jobs directly. r?efaust No need to keep create an additional object for this. MozReview-Commit-ID: Hj8kpaBe6fL
js/src/builtin/Promise.cpp
js/src/builtin/Promise.js
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -262,42 +262,32 @@ PromiseObject::dependentPromises(JSConte
         return false;
 
     if (keys.length() == 0)
         return true;
 
     if (!values.growBy(keys.length()))
         return false;
 
-    RootedAtom capabilitiesAtom(cx, Atomize(cx, "capabilities", strlen("capabilities")));
-    if (!capabilitiesAtom)
-        return false;
-    RootedId capabilitiesId(cx, AtomToId(capabilitiesAtom));
-
     // Each reaction is an internally-created object with the structure:
     // {
-    //   capabilities: {
-    //     promise: [the promise this reaction resolves],
-    //     resolve: [the `resolve` callback content code provided],
-    //     reject:  [the `reject` callback content code provided],
-    //    },
-    //    handler: [the internal handler that fulfills/rejects the promise]
-    //  }
+    //   promise: [the promise this reaction resolves],
+    //   resolve: [the `resolve` callback content code provided],
+    //   reject:  [the `reject` callback content code provided],
+    //   handler: [the internal handler that fulfills/rejects the promise]
+    // }
     //
     // In the following loop we collect the `capabilities.promise` values for
     // each reaction.
     for (size_t i = 0; i < keys.length(); i++) {
         MutableHandleValue val = values[i];
         if (!GetProperty(cx, rejectReactions, rejectReactions, keys[i], val))
             return false;
         RootedObject reaction(cx, &val.toObject());
-        if (!GetProperty(cx, reaction, reaction, capabilitiesId, val))
-            return false;
-        RootedObject capabilities(cx, &val.toObject());
-        if (!GetProperty(cx, capabilities, capabilities, cx->runtime()->commonNames->promise, val))
+        if (!GetProperty(cx, reaction, reaction, cx->runtime()->commonNames->promise, val))
             return false;
     }
 
     return true;
 }
 
 namespace js {
 
--- a/js/src/builtin/Promise.js
+++ b/js/src/builtin/Promise.js
@@ -221,22 +221,21 @@ function TriggerPromiseReactions(reactio
         EnqueuePromiseReactionJob(reactions[i], argument);
     // Step 2 (implicit).
 }
 
 // ES2016, February 12 draft 25.4.1.9, implemented in SelfHosting.cpp.
 
 // ES6, 25.4.2.1.
 function EnqueuePromiseReactionJob(reaction, argument) {
-    let capabilities = reaction.capabilities;
     _EnqueuePromiseReactionJob(reaction.handler,
                                argument,
-                               capabilities.resolve,
-                               capabilities.reject,
-                               capabilities.promise,
+                               reaction.resolve,
+                               reaction.reject,
+                               reaction.promise,
                                reaction.incumbentGlobal || null);
 }
 
 // ES6, 25.4.2.2. (Implemented in C++).
 
 // ES6, 25.4.3.1. (Implemented in C++).
 
 // ES7 2016-01-21 draft, 25.4.4.1.
@@ -645,22 +644,19 @@ function AddPromiseReaction(slot, depend
     // The reactions slot might've been reset because the Promise was resolved.
     if (!reactions) {
         assert(GetPromiseState(this) !== PROMISE_STATE_PENDING,
                "Pending promises must have reactions lists.");
         return;
     }
     _DefineDataProperty(reactions, reactions.length, {
                             __proto__: PromiseReactionRecordProto,
-                            capabilities: {
-                                __proto__: PromiseCapabilityRecordProto,
-                                promise: dependentPromise,
-                                reject: onReject,
-                                resolve: onResolve
-                            },
+                            promise: dependentPromise,
+                            reject: onReject,
+                            resolve: onResolve,
                             handler: handler
                         });
 }
 
 // ES6, 25.4.4.4.
 function Promise_static_reject(r) {
     // Step 1.
     let C = this;
@@ -748,19 +744,19 @@ function Promise_then(onFulfilled, onRej
 }
 
 /**
  * Enqueues resolve/reject reactions in the given Promise's reactions lists
  * in a content-invisible way.
  *
  * Used internally to implement DOM functionality.
  *
- * Note: the reactions pushed using this function contain a `capabilities`
- * object whose `promise` field can contain null. That field is only ever used
- * by devtools, which have to treat these reactions specially.
+ * Note: the reactions pushed using this function contain a `promise` field
+ * that can contain null. That field is only ever used by devtools, which have
+ * to treat these reactions specially.
  */
 function EnqueuePromiseReactions(promise, dependentPromise, onFulfilled, onRejected) {
     let isWrappedPromise = false;
     if (!IsPromise(promise)) {
         assert(IsWrappedPromise(promise),
                "EnqueuePromiseReactions must be provided with a possibly wrapped promise");
         isWrappedPromise = true;
     }
@@ -886,25 +882,29 @@ function PerformPromiseThen(promise, onF
     // Step 4.
     if (!IsCallable(onRejected))
         onRejected = PROMISE_HANDLER_THROWER;
 
     let incumbentGlobal = _GetObjectFromIncumbentGlobal();
     // Step 5.
     let fulfillReaction = {
         __proto__: PromiseReactionRecordProto,
-        capabilities: resultCapability,
+        resolve: resultCapability.resolve,
+        reject: resultCapability.reject,
+        promise: resultCapability.promise,
         handler: onFulfilled,
         incumbentGlobal
     };
 
     // Step 6.
     let rejectReaction = {
         __proto__: PromiseReactionRecordProto,
-        capabilities: resultCapability,
+        resolve: resultCapability.resolve,
+        reject: resultCapability.reject,
+        promise: resultCapability.promise,
         handler: onRejected,
         incumbentGlobal
     };
 
     // Step 7.
     let state = GetPromiseState(promise);
     if (state === PROMISE_STATE_PENDING) {
         // Step 7.a.