Bug 1464548: Part 1a - Add defineLazyGlobalGetters helper. r=mccr8
authorKris Maglione <maglione.k@gmail.com>
Fri, 25 May 2018 22:28:27 -0700
changeset 805613 f738942056e19cbe90efdd8a455e149008ef2deb
parent 805612 fbb3ac47702ca89c99162a9cb9ad74b58a1c8395
child 805614 4a8cd93316d6785a593b204bc204d6004449d76a
push id112718
push usermaglione.k@gmail.com
push dateFri, 08 Jun 2018 05:36:45 +0000
reviewersmccr8
bugs1464548
milestone62.0a1
Bug 1464548: Part 1a - Add defineLazyGlobalGetters helper. r=mccr8 This allows us to lazily import global properties using Cu.importGlobalProperties. Aside from making it easier to avoid lazily importing these properties, it also defines them all in the shared JSM global so that we don't risk re-creating them in Sandboxes or frameloader globals. MozReview-Commit-ID: GV6shguUlIG
js/xpconnect/loader/XPCOMUtils.jsm
--- a/js/xpconnect/loader/XPCOMUtils.jsm
+++ b/js/xpconnect/loader/XPCOMUtils.jsm
@@ -85,16 +85,18 @@
  *
  * 3. Define the NSGetFactory entry point:
  *  this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
  */
 
 
 var EXPORTED_SYMBOLS = [ "XPCOMUtils" ];
 
+let global = Cu.getGlobalForObject({});
+
 var XPCOMUtils = {
   /**
    * Generate a QueryInterface implementation. The returned function must be
    * assigned to the 'QueryInterface' property of a JS object. When invoked on
    * that object, it checks if the given iid is listed in the |interfaces|
    * param, and if it is, returns |this| (the object it was called on).
    * If the JS object has a classInfo property it'll be returned for the
    * nsIClassInfo IID, generateCI can be used to generate the classInfo
@@ -225,16 +227,39 @@ var XPCOMUtils = {
         },
         configurable: true,
         enumerable: true
       });
     }
   },
 
   /**
+   * Defines a getter property on the given object for each of the given
+   * global names as accepted by Cu.importGlobalProperties. These
+   * properties are imported into the shared JSM module global, and then
+   * copied onto the given object, no matter which global the object
+   * belongs to.
+   *
+   * @param {object} aObject
+   *        The object on which to define the properties.
+   * @param {string[]} aNames
+   *        The list of global properties to define.
+   */
+  defineLazyGlobalGetters(aObject, aNames) {
+    for (let name of aNames) {
+      this.defineLazyGetter(aObject, name, () => {
+        if (!(name in global)) {
+          Cu.importGlobalProperties([name]);
+        }
+        return global[name];
+      });
+    }
+  },
+
+  /**
    * Defines a getter on a specified object for a service.  The service will not
    * be obtained until first use.
    *
    * @param aObject
    *        The object to define the lazy getter on.
    * @param aName
    *        The name of the getter to define on aObject for the service.
    * @param aContract