Bug 1138059 - Tweak XPCOMUtils.defineLazyGetter behavior to avoid weird behavior in weird cases. r=mak.
authorJason Orendorff <jorendorff@mozilla.com>
Sat, 28 Feb 2015 09:17:43 -0600
changeset 232346 0d1127d31f4ee7a68b353aabca2d3e1942dc8420
parent 232345 c0d21f2affd6182e729628d952a664ab39438b1b
child 232347 3f6b1ead121aaf4f0154457392b0af3e10c4bda2
push id56523
push userjorendorff@mozilla.com
push dateSat, 07 Mar 2015 02:06:55 +0000
treeherdermozilla-inbound@41df9affe00f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs1138059
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1138059 - Tweak XPCOMUtils.defineLazyGetter behavior to avoid weird behavior in weird cases. r=mak.
js/xpconnect/loader/XPCOMUtils.jsm
--- a/js/xpconnect/loader/XPCOMUtils.jsm
+++ b/js/xpconnect/loader/XPCOMUtils.jsm
@@ -184,18 +184,29 @@ this.XPCOMUtils = {
    * @param aLambda
    *        A function that returns what the getter should return.  This will
    *        only ever be called once.
    */
   defineLazyGetter: function XPCU_defineLazyGetter(aObject, aName, aLambda)
   {
     Object.defineProperty(aObject, aName, {
       get: function () {
+        // Redefine this accessor property as a data property.
+        // Delete it first, to rule out "too much recursion" in case aObject is
+        // a proxy whose defineProperty handler might unwittingly trigger this
+        // getter again.
         delete aObject[aName];
-        return aObject[aName] = aLambda.apply(aObject);
+        let value = aLambda.apply(aObject);
+        Object.defineProperty(aObject, aName, {
+          value,
+          writable: true,
+          configurable: true,
+          enumerable: true
+        });
+        return value;
       },
       configurable: true,
       enumerable: true
     });
   },
 
   /**
    * Defines a getter on a specified object for a service.  The service will not