Bug 1096328 - Remove nativeOwnership from Bindings.conf, make rooting analysis happy. r=bz.
☠☠ backed out by a7f64e53893e ☠ ☠
authorPeter Van der Beken <peterv@propagandism.org>
Thu, 08 Jan 2015 22:56:42 +0100
changeset 249160 12dd1ad43923ac63fa00cdf1484991d5624c4daf
parent 249159 4a067de94f2256ba11041b6e7102a349c5b57e1b
child 249161 2b06fff97d12ed5c456795f3214a807a36e3de7f
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1096328
milestone37.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 1096328 - Remove nativeOwnership from Bindings.conf, make rooting analysis happy. r=bz.
dom/base/AnonymousContent.cpp
dom/base/AnonymousContent.h
dom/base/NodeIterator.cpp
dom/base/NodeIterator.h
dom/base/TreeWalker.cpp
dom/base/TreeWalker.h
dom/base/URL.cpp
dom/base/URL.h
dom/base/nsGlobalWindow.cpp
dom/bindings/BindingUtils.h
dom/bindings/Codegen.py
dom/bindings/StructuredClone.cpp
dom/bindings/test/TestBindingHeader.h
dom/canvas/ImageData.cpp
dom/canvas/ImageData.h
dom/canvas/TextMetrics.h
dom/canvas/WebGLActiveInfo.cpp
dom/canvas/WebGLActiveInfo.h
dom/canvas/WebGLShaderPrecisionFormat.cpp
dom/canvas/WebGLShaderPrecisionFormat.h
dom/canvas/WebGLUniformLocation.cpp
dom/canvas/WebGLUniformLocation.h
dom/datastore/DataStoreCursor.cpp
dom/datastore/DataStoreCursor.h
dom/encoding/TextDecoder.h
dom/encoding/TextEncoder.h
dom/html/TimeRanges.cpp
dom/html/TimeRanges.h
dom/indexedDB/IDBKeyRange.cpp
dom/indexedDB/IDBKeyRange.h
dom/vr/VRDevice.cpp
dom/vr/VRDevice.h
dom/workers/DataStoreCursor.cpp
dom/workers/DataStoreCursor.h
dom/workers/FileReaderSync.cpp
dom/workers/FileReaderSync.h
dom/workers/URL.cpp
dom/workers/URL.h
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerScope.cpp
dom/workers/WorkerScope.h
dom/xslt/xpath/XPathEvaluator.cpp
dom/xslt/xpath/XPathEvaluator.h
dom/xslt/xpath/XPathExpression.h
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
--- a/dom/base/AnonymousContent.cpp
+++ b/dom/base/AnonymousContent.cpp
@@ -124,16 +124,17 @@ AnonymousContent::GetElementById(const n
     nsIAtom* id = kid->AsElement()->GetID();
     if (id && id == elementId) {
       return kid->AsElement();
     }
   }
   return nullptr;
 }
 
-JSObject*
-AnonymousContent::WrapObject(JSContext* aCx)
+bool
+AnonymousContent::WrapObject(JSContext* aCx,
+                             JS::MutableHandle<JSObject*> aReflector)
 {
-  return AnonymousContentBinding::Wrap(aCx, this);
+  return AnonymousContentBinding::Wrap(aCx, this, aReflector);
 }
 
 } // dom namespace
 } // mozilla namespace
--- a/dom/base/AnonymousContent.h
+++ b/dom/base/AnonymousContent.h
@@ -22,17 +22,17 @@ class AnonymousContent MOZ_FINAL
 public:
   // Ref counting and cycle collection
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnonymousContent)
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AnonymousContent)
 
   explicit AnonymousContent(Element* aContentNode);
   nsCOMPtr<Element> GetContentNode();
   void SetContentNode(Element* aContentNode);
-  JSObject* WrapObject(JSContext* aCx);
+  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 
   // WebIDL methods
   void SetTextContentForElement(const nsAString& aElementId,
                                 const nsAString& aText,
                                 ErrorResult& aRv);
 
   void GetTextContentForElement(const nsAString& aElementId,
                                 DOMString& aText,
--- a/dom/base/NodeIterator.cpp
+++ b/dom/base/NodeIterator.cpp
@@ -283,16 +283,16 @@ void NodeIterator::ContentRemoved(nsIDoc
                                   nsIContent *aPreviousSibling)
 {
     nsINode *container = NODE_FROM(aContainer, aDocument);
 
     mPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
     mWorkingPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
 }
 
-JSObject*
-NodeIterator::WrapObject(JSContext *cx)
+bool
+NodeIterator::WrapObject(JSContext *cx, JS::MutableHandle<JSObject*> aReflector)
 {
-    return NodeIteratorBinding::Wrap(cx, this);
+    return NodeIteratorBinding::Wrap(cx, this, aReflector);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/NodeIterator.h
+++ b/dom/base/NodeIterator.h
@@ -64,17 +64,17 @@ public:
         return NextOrPrevNode(&NodePointer::MoveToNext, aResult);
     }
     already_AddRefed<nsINode> PreviousNode(ErrorResult& aResult)
     {
         return NextOrPrevNode(&NodePointer::MoveToPrevious, aResult);
     }
     // The XPCOM Detach() is fine for our purposes
 
-    JSObject* WrapObject(JSContext *cx);
+    bool WrapObject(JSContext *cx, JS::MutableHandle<JSObject*> aReflector);
 
 private:
     virtual ~NodeIterator();
 
     struct NodePointer {
         NodePointer() : mNode(nullptr) {}
         NodePointer(nsINode *aNode, bool aBeforeNode);
 
--- a/dom/base/TreeWalker.cpp
+++ b/dom/base/TreeWalker.cpp
@@ -445,16 +445,16 @@ TreeWalker::NextSiblingInternal(bool aRe
             return nullptr;
         }
         if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
             return nullptr;
         }
     }
 }
 
-JSObject*
-TreeWalker::WrapObject(JSContext *cx)
+bool
+TreeWalker::WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector)
 {
-    return TreeWalkerBinding::Wrap(cx, this);
+    return TreeWalkerBinding::Wrap(aCx, this, aReflector);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/TreeWalker.h
+++ b/dom/base/TreeWalker.h
@@ -60,17 +60,17 @@ public:
     already_AddRefed<nsINode> ParentNode(ErrorResult& aResult);
     already_AddRefed<nsINode> FirstChild(ErrorResult& aResult);
     already_AddRefed<nsINode> LastChild(ErrorResult& aResult);
     already_AddRefed<nsINode> PreviousSibling(ErrorResult& aResult);
     already_AddRefed<nsINode> NextSibling(ErrorResult& aResult);
     already_AddRefed<nsINode> PreviousNode(ErrorResult& aResult);
     already_AddRefed<nsINode> NextNode(ErrorResult& aResult);
 
-    JSObject* WrapObject(JSContext *cx);
+    bool WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector);
 
 private:
     nsCOMPtr<nsINode> mCurrentNode;
 
     /*
      * Implements FirstChild and LastChild which only vary in which direction
      * they search.
      * @param aReversed Controls whether we search forwards or backwards
--- a/dom/base/URL.cpp
+++ b/dom/base/URL.cpp
@@ -41,20 +41,20 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 URL::URL(nsIURI* aURI)
   : mURI(aURI)
 {
 }
 
-JSObject*
-URL::WrapObject(JSContext* aCx)
+bool
+URL::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
 {
-  return URLBinding::Wrap(aCx, this);
+  return URLBinding::Wrap(aCx, this, aReflector);
 }
 
 /* static */ already_AddRefed<URL>
 URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
                  URL& aBase, ErrorResult& aRv)
 {
   nsresult rv;
   nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
--- a/dom/base/URL.h
+++ b/dom/base/URL.h
@@ -38,18 +38,18 @@ class URL MOZ_FINAL : public URLSearchPa
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(URL)
 
   explicit URL(nsIURI* aURI);
 
   // WebIDL methods
-  JSObject*
-  WrapObject(JSContext* aCx);
+  bool
+  WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
               URL& aBase, ErrorResult& aRv);
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
               const nsAString& aBase, ErrorResult& aRv);
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2294,19 +2294,19 @@ CreateNativeGlobalForInner(JSContext* aC
   }
 
   // Determine if we need the Components object.
   bool needComponents = nsContentUtils::IsSystemPrincipal(aPrincipal) ||
                         TreatAsRemoteXUL(aPrincipal);
   uint32_t flags = needComponents ? 0 : nsIXPConnect::OMIT_COMPONENTS_OBJECT;
   flags |= nsIXPConnect::DONT_FIRE_ONNEWGLOBALHOOK;
 
-  aGlobal.set(WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
-                                  nsJSPrincipals::get(aPrincipal), false));
-  if (!aGlobal || !xpc::InitGlobalObject(aCx, aGlobal, flags)) {
+  if (!WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
+                           nsJSPrincipals::get(aPrincipal), false, aGlobal) ||
+      !xpc::InitGlobalObject(aCx, aGlobal, flags)) {
     return NS_ERROR_FAILURE;
   }
 
   MOZ_ASSERT(aNewInner->GetWrapperPreserveColor() == aGlobal);
 
   // Set the location information for the new global, so that tools like
   // about:memory may use that information
   xpc::SetLocationForGlobal(aGlobal, aURI);
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1014,21 +1014,19 @@ WrapNewBindingNonWrapperCachedObject(JSC
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
       if (!scope)
         return false;
       ac.emplace(cx, scope);
     }
 
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
-    obj = value->WrapObject(cx);
-  }
-
-  if (!obj) {
-    return false;
+    if (!value->WrapObject(cx, &obj)) {
+      return false;
+    }
   }
 
   // We can end up here in all sorts of compartments, per above.  Make
   // sure to JS_WrapValue!
   rval.set(JS::ObjectValue(*obj));
   return JS_WrapValue(cx, rval);
 }
 
@@ -1062,24 +1060,21 @@ WrapNewBindingNonWrapperCachedObject(JSC
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
       if (!scope)
         return false;
       ac.emplace(cx, scope);
     }
 
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
-    obj = value->WrapObject(cx);
-    if (obj) {
-      value.forget();
+    if (!value->WrapObject(cx, &obj)) {
+      return false;
     }
-  }
-
-  if (!obj) {
-    return false;
+
+    value.forget();
   }
 
   // We can end up here in all sorts of compartments, per above.  Make
   // sure to JS_WrapValue!
   rval.set(JS::ObjectValue(*obj));
   return JS_WrapValue(cx, rval);
 }
 
@@ -2762,67 +2757,65 @@ ToSupportsIsOnPrimaryInheritanceChain(T*
 // the BindingJSObjectCreator object is destroyed and ForgetObject() was never
 // called on it then the JSObject's slot holding the native will be set to
 // undefined, and for a refcounted native the strong reference will be released.
 template<class T>
 class MOZ_STACK_CLASS BindingJSObjectCreator
 {
 public:
   explicit BindingJSObjectCreator(JSContext* aCx)
-    : mObject(aCx)
+    : mReflector(aCx)
   {
   }
 
   ~BindingJSObjectCreator()
   {
-    if (mObject) {
-      js::SetReservedOrProxyPrivateSlot(mObject, DOM_OBJECT_SLOT,
+    if (mReflector) {
+      js::SetReservedOrProxyPrivateSlot(mReflector, DOM_OBJECT_SLOT,
                                         JS::UndefinedValue());
     }
   }
 
-  JS::Rooted<JSObject*>&
+  void
   CreateProxyObject(JSContext* aCx, const js::Class* aClass,
                     const DOMProxyHandler* aHandler,
                     JS::Handle<JSObject*> aProto,
-                    JS::Handle<JSObject*> aParent, T* aNative)
+                    JS::Handle<JSObject*> aParent, T* aNative,
+                    JS::MutableHandle<JSObject*> aReflector)
   {
     js::ProxyOptions options;
     options.setClass(aClass);
     JS::Rooted<JS::Value> proxyPrivateVal(aCx, JS::PrivateValue(aNative));
-    mObject = js::NewProxyObject(aCx, aHandler, proxyPrivateVal, aProto,
-                                 aParent, options);
-    if (mObject) {
+    aReflector.set(js::NewProxyObject(aCx, aHandler, proxyPrivateVal, aProto,
+                                      aParent, options));
+    if (aReflector) {
       mNative = aNative;
+      mReflector = aReflector;
     }
-    return mObject;
   }
 
-  JS::Rooted<JSObject*>&
+  void
   CreateObject(JSContext* aCx, const JSClass* aClass,
                JS::Handle<JSObject*> aProto, JS::Handle<JSObject*> aParent,
-               T* aNative)
+               T* aNative, JS::MutableHandle<JSObject*> aReflector)
   {
-    mObject = JS_NewObject(aCx, aClass, aProto, aParent);
-    if (mObject) {
-      js::SetReservedSlot(mObject, DOM_OBJECT_SLOT, JS::PrivateValue(aNative));
+    aReflector.set(JS_NewObject(aCx, aClass, aProto, aParent));
+    if (aReflector) {
+      js::SetReservedSlot(aReflector, DOM_OBJECT_SLOT, JS::PrivateValue(aNative));
       mNative = aNative;
+      mReflector = aReflector;
     }
-    return mObject;
   }
 
-  JSObject*
-  ForgetObject()
+  void
+  InitializationSucceeded()
   {
     void* dummy;
     mNative.forget(&dummy);
-
-    JSObject* obj = mObject;
-    mObject = nullptr;
-    return obj;
+    mReflector = nullptr;
   }
 
 private:
   struct OwnedNative
   {
     // Make sure the native objects inherit from NonRefcountedDOMObject so
     // that we log their ctor and dtor.
     static_assert(IsBaseOf<NonRefcountedDOMObject, T>::value,
@@ -2838,17 +2831,17 @@ private:
     // This signature sucks, but it's the only one that will make a nsRefPtr
     // just forget about its pointer without warning.
     void
     forget(void**)
     {
     }
   };
 
-  JS::Rooted<JSObject*> mObject;
+  JS::Rooted<JSObject*> mReflector;
   typename Conditional<IsRefcounted<T>::value, nsRefPtr<T>, OwnedNative>::Type mNative;
 };
 
 template<class T,
          bool isISupports=IsBaseOf<nsISupports, T>::value>
 class DeferredFinalizer
 {
   typedef typename Conditional<IsRefcounted<T>::value,
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3059,37 +3059,35 @@ class CGConstructorEnabled(CGAbstractMet
 def CreateBindingJSObject(descriptor, properties):
     objDecl = "BindingJSObjectCreator<%s> creator(aCx);\n" % descriptor.nativeType
 
     # We don't always need to root obj, but there are a variety
     # of cases where we do, so for simplicity, just always root it.
     if descriptor.proxy:
         create = dedent(
             """
-            const JS::Rooted<JSObject*>& obj =
-              creator.CreateProxyObject(aCx, &Class.mBase, DOMProxyHandler::getInstance(),
-                                        proto, global, aObject);
-            if (!obj) {
-              return nullptr;
+            creator.CreateProxyObject(aCx, &Class.mBase, DOMProxyHandler::getInstance(),
+                                      proto, global, aObject, aReflector);
+            if (!aReflector) {
+              return false;
             }
 
             """)
         if descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
             create += dedent("""
-                js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO,
+                js::SetProxyExtra(aReflector, JSPROXYSLOT_EXPANDO,
                                   JS::PrivateValue(&aObject->mExpandoAndGeneration));
 
                 """)
     else:
         create = dedent(
             """
-            const JS::Rooted<JSObject*>& obj =
-              creator.CreateObject(aCx, Class.ToJSClass(), proto, global, aObject);
-            if (!obj) {
-              return nullptr;
+            creator.CreateObject(aCx, Class.ToJSClass(), proto, global, aObject, aReflector);
+            if (!aReflector) {
+              return false;
             }
             """)
     return objDecl + create
 
 
 def InitUnforgeablePropertiesOnObject(descriptor, obj, properties, failureReturnValue=""):
     """
     properties is a PropertyArrays instance
@@ -3155,17 +3153,17 @@ def InitUnforgeableProperties(descriptor
         return ""
 
     if descriptor.proxy:
         unforgeableProperties = CGGeneric(
             "// Unforgeable properties on proxy-based bindings are stored in an object held\n"
             "// by the interface prototype object.\n")
     else:
         unforgeableProperties = CGWrapper(
-            InitUnforgeablePropertiesOnObject(descriptor, "obj", properties, "nullptr"),
+            InitUnforgeablePropertiesOnObject(descriptor, "aReflector", properties, "false"),
             pre=(
                 "// Important: do unforgeable property setup after we have handed\n"
                 "// over ownership of the C++ object to obj as needed, so that if\n"
                 "// we fail and it ends up GCed it won't have problems in the\n"
                 "// finalizer trying to drop its ownership of the C++ object.\n"))
     return CGWrapper(unforgeableProperties, pre="\n").define()
 
 
@@ -3193,73 +3191,72 @@ def InitMemberSlots(descriptor, wrapperC
     ClearWrapper.
     """
     if not descriptor.interface.hasMembersInSlots():
         return ""
     if wrapperCache:
         clearWrapper = "  aCache->ClearWrapper();\n"
     else:
         clearWrapper = ""
-    return ("if (!UpdateMemberSlots(aCx, obj, aObject)) {\n"
+    return ("if (!UpdateMemberSlots(aCx, aReflector, aObject)) {\n"
             "%s"
-            "  return nullptr;\n"
+            "  return false;\n"
             "}\n" % clearWrapper)
 
 
 class CGWrapWithCacheMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a given native that implements nsWrapperCache.
 
     properties should be a PropertyArrays instance.
     """
     def __init__(self, descriptor, properties):
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument(descriptor.nativeType + '*', 'aObject'),
-                Argument('nsWrapperCache*', 'aCache')]
-        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
+                Argument('nsWrapperCache*', 'aCache'),
+                Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
+        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
         self.properties = properties
 
     def definition_body(self):
         return fill(
             """
             $*{assertion}
 
             MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
                        "nsISupports must be on our primary inheritance chain");
 
             JS::Rooted<JSObject*> parent(aCx, WrapNativeParent(aCx, aObject->GetParentObject()));
             if (!parent) {
-              return nullptr;
+              return false;
             }
 
             // That might have ended up wrapping us already, due to the wonders
-            // of XBL.  Check for that, and bail out as needed.  Scope so we don't
-            // collide with the "obj" we declare in CreateBindingJSObject.
-            {
-              JSObject* obj = aCache->GetWrapper();
-              if (obj) {
-                return obj;
-              }
+            // of XBL.  Check for that, and bail out as needed.
+            aReflector.set(aCache->GetWrapper());
+            if (aReflector) {
+              return true;
             }
 
             JSAutoCompartment ac(aCx, parent);
             JS::Rooted<JSObject*> global(aCx, js::GetGlobalForObjectCrossCompartment(parent));
             JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
             if (!proto) {
-              return nullptr;
+              return false;
             }
 
             $*{createObject}
 
             $*{unforgeable}
 
-            aCache->SetWrapper(obj);
+            aCache->SetWrapper(aReflector);
             $*{slots}
-            return creator.ForgetObject();
+            creator.InitializationSucceeded();
+            return true;
             """,
             assertion=AssertInheritanceChain(self.descriptor),
             createObject=CreateBindingJSObject(self.descriptor, self.properties),
             unforgeable=InitUnforgeableProperties(self.descriptor, self.properties),
             slots=InitMemberSlots(self.descriptor, True))
 
 
 class CGWrapMethod(CGAbstractMethod):
@@ -3267,51 +3264,56 @@ class CGWrapMethod(CGAbstractMethod):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument('T*', 'aObject')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args,
                                   inline=True, templateArgs=["class T"])
 
     def definition_body(self):
-        return "return Wrap(aCx, aObject, aObject);\n"
+        return dedent("""
+            JS::Rooted<JSObject*> reflector(aCx);
+            return Wrap(aCx, aObject, aObject, &reflector) ? reflector.get() : nullptr;
+            """)
 
 
 class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a given native that does not implement
     nsWrapperCache.
 
     properties should be a PropertyArrays instance.
     """
     def __init__(self, descriptor, properties):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
-                Argument(descriptor.nativeType + '*', 'aObject')]
-        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
+                Argument(descriptor.nativeType + '*', 'aObject'),
+                Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
+        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
         self.properties = properties
 
     def definition_body(self):
         return fill(
             """
             $*{assertions}
 
             JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
             JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
             if (!proto) {
-              return nullptr;
+              return false;
             }
 
             $*{createObject}
 
             $*{unforgeable}
 
             $*{slots}
-            return creator.ForgetObject();
+            creator.InitializationSucceeded();
+            return true;
             """,
             assertions=AssertInheritanceChain(self.descriptor),
             createObject=CreateBindingJSObject(self.descriptor, self.properties),
             unforgeable=InitUnforgeableProperties(self.descriptor, self.properties),
             slots=InitMemberSlots(self.descriptor, False))
 
 
 class CGWrapGlobalMethod(CGAbstractMethod):
@@ -3323,70 +3325,70 @@ class CGWrapGlobalMethod(CGAbstractMetho
     """
     def __init__(self, descriptor, properties):
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument(descriptor.nativeType + '*', 'aObject'),
                 Argument('nsWrapperCache*', 'aCache'),
                 Argument('JS::CompartmentOptions&', 'aOptions'),
                 Argument('JSPrincipals*', 'aPrincipal'),
-                Argument('bool', 'aInitStandardClasses')]
-        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
+                Argument('bool', 'aInitStandardClasses'),
+                Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
+        CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
         self.descriptor = descriptor
         self.properties = properties
 
     def definition_body(self):
         if self.properties.hasNonChromeOnly():
             properties = "GlobalPropertiesAreOwn() ? &sNativeProperties : nullptr"
         else:
             properties = "nullptr"
         if self.properties.hasChromeOnly():
             chromeProperties = "GlobalPropertiesAreOwn() && nsContentUtils::ThreadsafeIsCallerChrome() ? &sChromeOnlyNativeProperties : nullptr"
         else:
             chromeProperties = "nullptr"
 
         if self.descriptor.workers:
             fireOnNewGlobal = """// XXXkhuey can't do this yet until workers can lazy resolve.
-// JS_FireOnNewGlobalObject(aCx, obj);
+// JS_FireOnNewGlobalObject(aCx, aReflector);
 """
         else:
             fireOnNewGlobal = ""
 
         return fill(
             """
             $*{assertions}
             MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
                        "nsISupports must be on our primary inheritance chain");
 
-            JS::Rooted<JSObject*> obj(aCx);
             CreateGlobal<${nativeType}, GetProtoObjectHandle>(aCx,
                                              aObject,
                                              aCache,
                                              Class.ToJSClass(),
                                              aOptions,
                                              aPrincipal,
                                              aInitStandardClasses,
-                                             &obj);
-            if (!obj) {
-              return nullptr;
-            }
-
-            // obj is a new global, so has a new compartment.  Enter it
+                                             aReflector);
+            if (!aReflector) {
+              return false;
+            }
+
+            // aReflector is a new global, so has a new compartment.  Enter it
             // before doing anything with it.
-            JSAutoCompartment ac(aCx, obj);
-
-            if (!DefineProperties(aCx, obj, ${properties}, ${chromeProperties})) {
-              return nullptr;
+            JSAutoCompartment ac(aCx, aReflector);
+
+            if (!DefineProperties(aCx, aReflector, ${properties}, ${chromeProperties})) {
+              return false;
             }
             $*{unforgeable}
 
             $*{slots}
             $*{fireOnNewGlobal}
 
-            return obj;
+            return true;
             """,
             assertions=AssertInheritanceChain(self.descriptor),
             nativeType=self.descriptor.nativeType,
             properties=properties,
             chromeProperties=chromeProperties,
             unforgeable=InitUnforgeableProperties(self.descriptor, self.properties),
             slots=InitMemberSlots(self.descriptor, True),
             fireOnNewGlobal=fireOnNewGlobal)
--- a/dom/bindings/StructuredClone.cpp
+++ b/dom/bindings/StructuredClone.cpp
@@ -27,17 +27,19 @@ ReadStructuredCloneImageData(JSContext* 
 
   // Protect the result from a moving GC in ~nsRefPtr.
   JS::Rooted<JSObject*> result(aCx);
   {
     // Construct the ImageData.
     nsRefPtr<ImageData> imageData = new ImageData(width, height,
                                                   dataArray.toObject());
     // Wrap it in a JS::Value.
-    result = imageData->WrapObject(aCx);
+    if (!imageData->WrapObject(aCx, &result)) {
+      return nullptr;
+    }
   }
   return result;
 }
 
 bool
 WriteStructuredCloneImageData(JSContext* aCx, JSStructuredCloneWriter* aWriter,
                               ImageData* aImageData)
 {
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -85,17 +85,17 @@ public:
 
 NS_DEFINE_STATIC_IID_ACCESSOR(TestExternalInterface, NS_TEST_EXTERNAL_INTERFACE_IID)
 
 class TestNonWrapperCacheInterface : public nsISupports
 {
 public:
   NS_DECL_ISUPPORTS
 
-  virtual JSObject* WrapObject(JSContext* cx);
+  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 };
 
 class OnlyForUseInConstructor : public nsISupports,
                                 public nsWrapperCache
 {
 public:
   NS_DECL_ISUPPORTS
   // We need a GetParentObject to make binding codegen happy
--- a/dom/canvas/ImageData.cpp
+++ b/dom/canvas/ImageData.cpp
@@ -103,16 +103,16 @@ void
 ImageData::DropData()
 {
   if (mData) {
     mData = nullptr;
     mozilla::DropJSObjects(this);
   }
 }
 
-JSObject*
-ImageData::WrapObject(JSContext* cx)
+bool
+ImageData::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
 {
-  return ImageDataBinding::Wrap(cx, this);
+  return ImageDataBinding::Wrap(aCx, this, aReflector);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/canvas/ImageData.h
+++ b/dom/canvas/ImageData.h
@@ -68,17 +68,17 @@ public:
     aData.set(GetDataObject());
   }
   JSObject* GetDataObject() const
   {
     JS::ExposeObjectToActiveJS(mData);
     return mData;
   }
 
-  JSObject* WrapObject(JSContext* cx);
+  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 
 private:
   void HoldData();
   void DropData();
 
   ImageData() = delete;
 
   uint32_t mWidth, mHeight;
--- a/dom/canvas/TextMetrics.h
+++ b/dom/canvas/TextMetrics.h
@@ -25,19 +25,19 @@ public:
     MOZ_COUNT_DTOR(TextMetrics);
   }
 
   float Width() const
   {
     return width;
   }
 
-  JSObject* WrapObject(JSContext* aCx)
+  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
   {
-    return TextMetricsBinding::Wrap(aCx, this);
+    return TextMetricsBinding::Wrap(aCx, this, aReflector);
   }
 
 private:
   float width;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/canvas/WebGLActiveInfo.cpp
+++ b/dom/canvas/WebGLActiveInfo.cpp
@@ -6,15 +6,16 @@
 #include "WebGLActiveInfo.h"
 
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
 #include "WebGLTexture.h"
 
 namespace mozilla {
 
-JSObject*
-WebGLActiveInfo::WrapObject(JSContext* cx)
+bool
+WebGLActiveInfo::WrapObject(JSContext* aCx,
+                            JS::MutableHandle<JSObject*> aReflector)
 {
-    return dom::WebGLActiveInfoBinding::Wrap(cx, this);
+    return dom::WebGLActiveInfoBinding::Wrap(aCx, this, aReflector);
 }
 
 } // namespace mozilla
--- a/dom/canvas/WebGLActiveInfo.h
+++ b/dom/canvas/WebGLActiveInfo.h
@@ -30,17 +30,17 @@ public:
     GLenum Type() const {
         return mType;
     }
 
     void GetName(nsString& retval) const {
         retval = mName;
     }
 
-    JSObject* WrapObject(JSContext* cx);
+    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 
    NS_INLINE_DECL_REFCOUNTING(WebGLActiveInfo)
 
 private:
     // Private destructor, to discourage deletion outside of Release():
     ~WebGLActiveInfo()
     {
     }
--- a/dom/canvas/WebGLShaderPrecisionFormat.cpp
+++ b/dom/canvas/WebGLShaderPrecisionFormat.cpp
@@ -5,15 +5,16 @@
 
 #include "WebGLShaderPrecisionFormat.h"
 
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
 
 namespace mozilla {
 
-JSObject*
-WebGLShaderPrecisionFormat::WrapObject(JSContext* cx)
+bool
+WebGLShaderPrecisionFormat::WrapObject(JSContext* aCx,
+                                       JS::MutableHandle<JSObject*> aReflector)
 {
-    return dom::WebGLShaderPrecisionFormatBinding::Wrap(cx, this);
+    return dom::WebGLShaderPrecisionFormatBinding::Wrap(aCx, this, aReflector);
 }
 
 } // namespace mozilla
--- a/dom/canvas/WebGLShaderPrecisionFormat.h
+++ b/dom/canvas/WebGLShaderPrecisionFormat.h
@@ -19,17 +19,17 @@ public:
     WebGLShaderPrecisionFormat(WebGLContext* context, GLint rangeMin,
                                GLint rangeMax, GLint precision)
         : WebGLContextBoundObject(context)
         , mRangeMin(rangeMin)
         , mRangeMax(rangeMax)
         , mPrecision(precision)
     { }
 
-    JSObject* WrapObject(JSContext* cx);
+    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 
     // WebIDL WebGLShaderPrecisionFormat API
     GLint RangeMin() const {
         return mRangeMin;
     }
 
     GLint RangeMax() const {
         return mRangeMax;
--- a/dom/canvas/WebGLUniformLocation.cpp
+++ b/dom/canvas/WebGLUniformLocation.cpp
@@ -7,20 +7,21 @@
 
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
 #include "WebGLProgram.h"
 #include "WebGLShader.h"
 
 namespace mozilla {
 
-JSObject*
-WebGLUniformLocation::WrapObject(JSContext* cx)
+bool
+WebGLUniformLocation::WrapObject(JSContext* aCx,
+                                 JS::MutableHandle<JSObject*> aReflector)
 {
-    return dom::WebGLUniformLocationBinding::Wrap(cx, this);
+    return dom::WebGLUniformLocationBinding::Wrap(aCx, this, aReflector);
 }
 
 WebGLUniformLocation::WebGLUniformLocation(WebGLContext* context,
                                            WebGLProgram* program,
                                            GLint location,
                                            const WebGLUniformInfo& info)
     : WebGLContextBoundObject(context)
     , mProgram(program)
--- a/dom/canvas/WebGLUniformLocation.h
+++ b/dom/canvas/WebGLUniformLocation.h
@@ -26,17 +26,17 @@ public:
 
     const WebGLUniformInfo& Info() const { return mInfo; }
 
     WebGLProgram* Program() const { return mProgram; }
     GLint Location() const { return mLocation; }
     uint32_t ProgramGeneration() const { return mProgramGeneration; }
     int ElementSize() const { return mElementSize; }
 
-    JSObject* WrapObject(JSContext* cx);
+    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLUniformLocation)
     NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(WebGLUniformLocation)
 
 protected:
     ~WebGLUniformLocation() { }
 
     // nsRefPtr, not WebGLRefPtr, so that we don't prevent the program from being explicitly deleted.
--- a/dom/datastore/DataStoreCursor.cpp
+++ b/dom/datastore/DataStoreCursor.cpp
@@ -24,20 +24,21 @@ NS_IMPL_CYCLE_COLLECTION(DataStoreCursor
 
 already_AddRefed<DataStoreCursor>
 DataStoreCursor::Constructor(GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<DataStoreCursor> cursor = new DataStoreCursor();
   return cursor.forget();
 }
 
-JSObject*
-DataStoreCursor::WrapObject(JSContext* aCx)
+bool
+DataStoreCursor::WrapObject(JSContext* aCx,
+                            JS::MutableHandle<JSObject*> aReflector)
 {
-  return DataStoreCursorBinding::Wrap(aCx, this);
+  return DataStoreCursorBinding::Wrap(aCx, this, aReflector);
 }
 
 already_AddRefed<DataStore>
 DataStoreCursor::GetStore(ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mCursor);
 
@@ -67,9 +68,9 @@ DataStoreCursor::SetDataStoreCursorImpl(
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mCursor);
 
   mCursor = &aCursor;
 }
 
 } //namespace dom
-} //namespace mozilla
\ No newline at end of file
+} //namespace mozilla
--- a/dom/datastore/DataStoreCursor.h
+++ b/dom/datastore/DataStoreCursor.h
@@ -28,17 +28,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(DataStoreCursor)
 
   // WebIDL (internal functions)
 
   static already_AddRefed<DataStoreCursor> Constructor(GlobalObject& aGlobal,
                                                        ErrorResult& aRv);
 
-  JSObject* WrapObject(JSContext *aCx);
+  bool WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector);
 
   // WebIDL (public APIs)
 
   already_AddRefed<DataStore> GetStore(ErrorResult& aRv);
 
   already_AddRefed<Promise> Next(ErrorResult& aRv);
 
   void Close(ErrorResult& aRv);
@@ -51,9 +51,9 @@ public:
 private:
   ~DataStoreCursor() {}
   nsRefPtr<DataStoreCursorImpl> mCursor;
 };
 
 } //namespace dom
 } //namespace mozilla
 
-#endif
\ No newline at end of file
+#endif
--- a/dom/encoding/TextDecoder.h
+++ b/dom/encoding/TextDecoder.h
@@ -44,19 +44,19 @@ public:
     MOZ_COUNT_CTOR(TextDecoder);
   }
 
   ~TextDecoder()
   {
     MOZ_COUNT_DTOR(TextDecoder);
   }
 
-  JSObject* WrapObject(JSContext* aCx)
+  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
   {
-    return TextDecoderBinding::Wrap(aCx, this);
+    return TextDecoderBinding::Wrap(aCx, this, aReflector);
   }
 
   /**
    * Validates provided label and throws an exception if invalid label.
    *
    * @param aLabel       The encoding label (case insensitive) provided.
    * @param aFatal       indicates whether to throw an 'EncodingError'
    *                     exception or not when decoding.
--- a/dom/encoding/TextEncoder.h
+++ b/dom/encoding/TextEncoder.h
@@ -37,19 +37,19 @@ public:
   TextEncoder()
   {
   }
 
   virtual
   ~TextEncoder()
   {}
 
-  JSObject* WrapObject(JSContext* aCx)
+  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
   {
-    return TextEncoderBinding::Wrap(aCx, this);
+    return TextEncoderBinding::Wrap(aCx, this, aReflector);
   }
 
 protected:
 
   /**
    * Validates provided encoding and throws an exception if invalid encoding.
    * If no encoding is provided then mEncoding is default initialised to "utf-8".
    *
--- a/dom/html/TimeRanges.cpp
+++ b/dom/html/TimeRanges.cpp
@@ -161,16 +161,16 @@ TimeRanges::Find(double aTime, double aE
   for (index_type i = 0; i < mRanges.Length(); ++i) {
     if (aTime < mRanges[i].mEnd && (aTime + aError) >= mRanges[i].mStart) {
       return i;
     }
   }
   return NoIndex;
 }
 
-JSObject*
-TimeRanges::WrapObject(JSContext* aCx)
+bool
+TimeRanges::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
 {
-  return TimeRangesBinding::Wrap(aCx, this);
+  return TimeRangesBinding::Wrap(aCx, this, aReflector);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/TimeRanges.h
+++ b/dom/html/TimeRanges.h
@@ -45,17 +45,17 @@ public:
   void Normalize(double aError = 0.0);
 
   // Mutate this TimeRange to be the union of this and aOtherRanges.
   void Union(const TimeRanges* aOtherRanges, double aError);
 
   // Mutate this TimeRange to be the intersection of this and aOtherRanges.
   void Intersection(const TimeRanges* aOtherRanges);
 
-  JSObject* WrapObject(JSContext* aCx);
+  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 
   uint32_t Length() const
   {
     return mRanges.Length();
   }
 
   virtual double Start(uint32_t aIndex, ErrorResult& aRv);
 
--- a/dom/indexedDB/IDBKeyRange.cpp
+++ b/dom/indexedDB/IDBKeyRange.cpp
@@ -242,20 +242,20 @@ IDBKeyRange::DropJSObjects()
   mCachedLowerVal.setUndefined();
   mCachedUpperVal.setUndefined();
   mHaveCachedLowerVal = false;
   mHaveCachedUpperVal = false;
   mRooted = false;
   mozilla::DropJSObjects(this);
 }
 
-JSObject*
-IDBKeyRange::WrapObject(JSContext* aCx)
+bool
+IDBKeyRange::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
 {
-  return IDBKeyRangeBinding::Wrap(aCx, this);
+  return IDBKeyRangeBinding::Wrap(aCx, this, aReflector);
 }
 
 void
 IDBKeyRange::GetLower(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
                       ErrorResult& aRv)
 {
   AssertIsOnOwningThread();
 
--- a/dom/indexedDB/IDBKeyRange.h
+++ b/dom/indexedDB/IDBKeyRange.h
@@ -135,18 +135,18 @@ public:
 
   nsresult
   BindToStatement(mozIStorageStatement* aStatement) const;
 
   void
   DropJSObjects();
 
   // WebIDL
-  JSObject*
-  WrapObject(JSContext* aCx);
+  bool
+  WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 
   nsISupports*
   GetParentObject() const
   {
     return mGlobal;
   }
 
   void
--- a/dom/vr/VRDevice.cpp
+++ b/dom/vr/VRDevice.cpp
@@ -30,20 +30,21 @@ VRFieldOfView::Constructor(const GlobalO
                            double aUpDegrees, double aRightDegrees,
                            double aDownDegrees, double aLeftDegrees,
                            ErrorResult& aRV)
 {
   return new VRFieldOfView(aUpDegrees, aRightDegrees, aDownDegrees,
                            aLeftDegrees);
 }
 
-JSObject*
-VRFieldOfView::WrapObject(JSContext* aCx)
+bool
+VRFieldOfView::WrapObject(JSContext* aCx,
+                          JS::MutableHandle<JSObject*> aReflector)
 {
-  return VRFieldOfViewBinding::Wrap(aCx, this);
+  return VRFieldOfViewBinding::Wrap(aCx, this, aReflector);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRPositionState, mParent)
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRPositionState, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRPositionState, Release)
 
 VRPositionState::VRPositionState(nsISupports* aParent, const gfx::VRHMDSensorState& aState)
   : mParent(aParent)
--- a/dom/vr/VRDevice.h
+++ b/dom/vr/VRDevice.h
@@ -63,17 +63,17 @@ public:
               ErrorResult& aRv);
 
   static VRFieldOfView*
   Constructor(const GlobalObject& aGlobal,
               double aUpDegrees, double aRightDegrees,
               double aDownDegrees, double aLeftDegrees,
               ErrorResult& aRv);
 
-  JSObject* WrapObject(JSContext* aCx);
+  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 
   void SetUpDegrees(double aVal) { mUpDegrees = aVal; }
   void SetRightDegrees(double aVal) { mRightDegrees = aVal; }
   void SetDownDegrees(double aVal) { mDownDegrees = aVal; }
   void SetLeftDegrees(double aVal) { mLeftDegrees = aVal; }
 };
 
 class VRPositionState MOZ_FINAL : public nsWrapperCache
--- a/dom/workers/DataStoreCursor.cpp
+++ b/dom/workers/DataStoreCursor.cpp
@@ -35,20 +35,21 @@ already_AddRefed<WorkerDataStoreCursor>
 WorkerDataStoreCursor::Constructor(GlobalObject& aGlobal, ErrorResult& aRv)
 {
   // We don't allow Gecko to create WorkerDataStoreCursor through JS codes like
   // window.DataStoreCursor() on the worker, so disable this for now.
   NS_NOTREACHED("Cannot use the chrome constructor on the worker!");
   return nullptr;
 }
 
-JSObject*
-WorkerDataStoreCursor::WrapObject(JSContext* aCx)
+bool
+WorkerDataStoreCursor::WrapObject(JSContext* aCx,
+                                  JS::MutableHandle<JSObject*> aReflector)
 {
-  return DataStoreCursorBinding_workers::Wrap(aCx, this);
+  return DataStoreCursorBinding_workers::Wrap(aCx, this, aReflector);
 }
 
 // A WorkerMainThreadRunnable which holds a reference to DataStoreCursor.
 class DataStoreCursorRunnable : public WorkerMainThreadRunnable
 {
 protected:
   nsMainThreadPtrHandle<DataStoreCursor> mBackingCursor;
 
--- a/dom/workers/DataStoreCursor.h
+++ b/dom/workers/DataStoreCursor.h
@@ -30,17 +30,17 @@ public:
 
   explicit WorkerDataStoreCursor(WorkerDataStore* aWorkerStore);
 
   // WebIDL (internal functions)
 
   static already_AddRefed<WorkerDataStoreCursor> Constructor(GlobalObject& aGlobal,
                                                              ErrorResult& aRv);
 
-  JSObject* WrapObject(JSContext *aCx);
+  bool WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector);
 
   // WebIDL (public APIs)
 
   already_AddRefed<WorkerDataStore> GetStore(JSContext *aCx, ErrorResult& aRv);
 
   already_AddRefed<Promise> Next(JSContext *aCx, ErrorResult& aRv);
 
   void Close(JSContext *aCx, ErrorResult& aRv);
--- a/dom/workers/FileReaderSync.cpp
+++ b/dom/workers/FileReaderSync.cpp
@@ -36,20 +36,21 @@ using mozilla::dom::GlobalObject;
 already_AddRefed<FileReaderSync>
 FileReaderSync::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<FileReaderSync> frs = new FileReaderSync();
 
   return frs.forget();
 }
 
-JSObject*
-FileReaderSync::WrapObject(JSContext* aCx)
+bool
+FileReaderSync::WrapObject(JSContext* aCx,
+                           JS::MutableHandle<JSObject*> aReflector)
 {
-  return FileReaderSyncBinding_workers::Wrap(aCx, this);
+  return FileReaderSyncBinding_workers::Wrap(aCx, this, aReflector);
 }
 
 void
 FileReaderSync::ReadAsArrayBuffer(JSContext* aCx,
                                   JS::Handle<JSObject*> aScopeObj,
                                   File& aBlob,
                                   JS::MutableHandle<JSObject*> aRetval,
                                   ErrorResult& aRv)
--- a/dom/workers/FileReaderSync.h
+++ b/dom/workers/FileReaderSync.h
@@ -36,17 +36,17 @@ private:
 
   nsresult ConvertStream(nsIInputStream *aStream, const char *aCharset,
                          nsAString &aResult);
 
 public:
   static already_AddRefed<FileReaderSync>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
 
-  JSObject* WrapObject(JSContext* aCx);
+  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 
   void ReadAsArrayBuffer(JSContext* aCx, JS::Handle<JSObject*> aScopeObj,
                          File& aBlob, JS::MutableHandle<JSObject*> aRetval,
                          ErrorResult& aRv);
   void ReadAsBinaryString(File& aBlob, nsAString& aResult, ErrorResult& aRv);
   void ReadAsText(File& aBlob, const Optional<nsAString>& aEncoding,
                   nsAString& aResult, ErrorResult& aRv);
   void ReadAsDataURL(File& aBlob, nsAString& aResult, ErrorResult& aRv);
--- a/dom/workers/URL.cpp
+++ b/dom/workers/URL.cpp
@@ -567,20 +567,20 @@ URL::~URL()
     mURLProxy = nullptr;
 
     if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
       NS_ERROR("Failed to dispatch teardown runnable!");
     }
   }
 }
 
-JSObject*
-URL::WrapObject(JSContext* aCx)
+bool
+URL::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
 {
-  return URLBinding_workers::Wrap(aCx, this);
+  return URLBinding_workers::Wrap(aCx, this, aReflector);
 }
 
 void
 URL::GetHref(nsString& aHref, ErrorResult& aRv) const
 {
   nsRefPtr<GetterRunnable> runnable =
     new GetterRunnable(mWorkerPrivate, GetterRunnable::GetterHref, aHref,
                        mURLProxy);
--- a/dom/workers/URL.h
+++ b/dom/workers/URL.h
@@ -40,18 +40,18 @@ public:
 
   nsISupports*
   GetParentObject() const
   {
     // There's only one global on a worker, so we don't need to specify.
     return nullptr;
   }
 
-  JSObject*
-  WrapObject(JSContext* aCx);
+  bool
+  WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 
   // Methods for WebIDL
 
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
               URL& aBase, ErrorResult& aRv);
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -6248,18 +6248,20 @@ WorkerPrivate::CreateGlobalScope(JSConte
   if (IsSharedWorker()) {
     globalScope = new SharedWorkerGlobalScope(this, SharedWorkerName());
   } else if (IsServiceWorker()) {
     globalScope = new ServiceWorkerGlobalScope(this, SharedWorkerName());
   } else {
     globalScope = new DedicatedWorkerGlobalScope(this);
   }
 
-  JS::Rooted<JSObject*> global(aCx, globalScope->WrapGlobalObject(aCx));
-  NS_ENSURE_TRUE(global, nullptr);
+  JS::Rooted<JSObject*> global(aCx);
+  if (!globalScope->WrapGlobalObject(aCx, &global)) {
+    return nullptr;
+  }
 
   JSAutoCompartment ac(aCx, global);
 
   if (!RegisterBindings(aCx, global)) {
     return nullptr;
   }
 
   mScope = globalScope.forget();
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -357,29 +357,30 @@ WorkerGlobalScope::GetIndexedDB(ErrorRes
   return indexedDB.forget();
 }
 
 DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
 : WorkerGlobalScope(aWorkerPrivate)
 {
 }
 
-JSObject*
-DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
+bool
+DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
+                                             JS::MutableHandle<JSObject*> aReflector)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(!mWorkerPrivate->IsSharedWorker());
 
   JS::CompartmentOptions options;
   mWorkerPrivate->CopyJSCompartmentOptions(options);
 
   return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this,
                                                          options,
                                                          GetWorkerPrincipal(),
-                                                         true);
+                                                         true, aReflector);
 }
 
 void
 DedicatedWorkerGlobalScope::PostMessage(JSContext* aCx,
                                         JS::Handle<JS::Value> aMessage,
                                         const Optional<Sequence<JS::Value>>& aTransferable,
                                         ErrorResult& aRv)
 {
@@ -388,28 +389,29 @@ DedicatedWorkerGlobalScope::PostMessage(
 }
 
 SharedWorkerGlobalScope::SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
                                                  const nsCString& aName)
 : WorkerGlobalScope(aWorkerPrivate), mName(aName)
 {
 }
 
-JSObject*
-SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
+bool
+SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
+                                          JS::MutableHandle<JSObject*> aReflector)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(mWorkerPrivate->IsSharedWorker());
 
   JS::CompartmentOptions options;
   mWorkerPrivate->CopyJSCompartmentOptions(options);
 
   return SharedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this, options,
                                                       GetWorkerPrincipal(),
-                                                      true);
+                                                      true, aReflector);
 }
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope,
                                    mClients)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope)
 NS_INTERFACE_MAP_END_INHERITING(WorkerGlobalScope)
 
 NS_IMPL_ADDREF_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope)
@@ -421,28 +423,29 @@ ServiceWorkerGlobalScope::ServiceWorkerG
     mScope(NS_ConvertUTF8toUTF16(aScope))
 {
 }
 
 ServiceWorkerGlobalScope::~ServiceWorkerGlobalScope()
 {
 }
 
-JSObject*
-ServiceWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
+bool
+ServiceWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
+                                           JS::MutableHandle<JSObject*> aReflector)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(mWorkerPrivate->IsServiceWorker());
 
   JS::CompartmentOptions options;
   mWorkerPrivate->CopyJSCompartmentOptions(options);
 
   return ServiceWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this, options,
                                                        GetWorkerPrincipal(),
-                                                       true);
+                                                       true, aReflector);
 }
 
 ServiceWorkerClients*
 ServiceWorkerGlobalScope::Clients()
 {
   if (!mClients) {
     mClients = new ServiceWorkerClients(this);
   }
--- a/dom/workers/WorkerScope.h
+++ b/dom/workers/WorkerScope.h
@@ -52,18 +52,18 @@ protected:
 
   explicit WorkerGlobalScope(WorkerPrivate* aWorkerPrivate);
   virtual ~WorkerGlobalScope();
 
 public:
   virtual JSObject*
   WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
-  virtual JSObject*
-  WrapGlobalObject(JSContext* aCx) = 0;
+  virtual bool
+  WrapGlobalObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector) = 0;
 
   virtual JSObject*
   GetGlobalJSObject(void) MOZ_OVERRIDE
   {
     return GetWrapper();
   }
 
   NS_DECL_ISUPPORTS_INHERITED
@@ -143,18 +143,19 @@ public:
 
 class DedicatedWorkerGlobalScope MOZ_FINAL : public WorkerGlobalScope
 {
   ~DedicatedWorkerGlobalScope() { }
 
 public:
   explicit DedicatedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate);
 
-  virtual JSObject*
-  WrapGlobalObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual bool
+  WrapGlobalObject(JSContext* aCx,
+                   JS::MutableHandle<JSObject*> aReflector) MOZ_OVERRIDE;
 
   void
   PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
               const Optional<Sequence<JS::Value>>& aTransferable,
               ErrorResult& aRv);
 
   IMPL_EVENT_HANDLER(message)
 };
@@ -164,18 +165,19 @@ class SharedWorkerGlobalScope MOZ_FINAL 
   const nsCString mName;
 
   ~SharedWorkerGlobalScope() { }
 
 public:
   SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
                           const nsCString& aName);
 
-  virtual JSObject*
-  WrapGlobalObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual bool
+  WrapGlobalObject(JSContext* aCx,
+                   JS::MutableHandle<JSObject*> aReflector) MOZ_OVERRIDE;
 
   void GetName(DOMString& aName) const
   {
     aName.AsAString() = NS_ConvertUTF8toUTF16(mName);
   }
 
   IMPL_EVENT_HANDLER(connect)
 };
@@ -189,18 +191,19 @@ class ServiceWorkerGlobalScope MOZ_FINAL
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerGlobalScope,
                                            WorkerGlobalScope)
 
   ServiceWorkerGlobalScope(WorkerPrivate* aWorkerPrivate, const nsACString& aScope);
 
-  virtual JSObject*
-  WrapGlobalObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual bool
+  WrapGlobalObject(JSContext* aCx,
+                   JS::MutableHandle<JSObject*> aReflector) MOZ_OVERRIDE;
 
   void
   GetScope(DOMString& aScope) const
   {
     aScope.AsAString() = mScope;
   }
 
   void
--- a/dom/xslt/xpath/XPathEvaluator.cpp
+++ b/dom/xslt/xpath/XPathEvaluator.cpp
@@ -153,20 +153,21 @@ XPathEvaluator::CreateExpression(const n
         }
 
         return nullptr;
     }
 
     return new XPathExpression(Move(expression), mRecycler, aDocument);
 }
 
-JSObject*
-XPathEvaluator::WrapObject(JSContext* aCx)
+bool
+XPathEvaluator::WrapObject(JSContext* aCx,
+                           JS::MutableHandle<JSObject*> aReflector)
 {
-    return dom::XPathEvaluatorBinding::Wrap(aCx, this);
+    return dom::XPathEvaluatorBinding::Wrap(aCx, this, aReflector);
 }
 
 /* static */
 already_AddRefed<XPathEvaluator>
 XPathEvaluator::Constructor(const GlobalObject& aGlobal,
                             ErrorResult& rv)
 {
     nsRefPtr<XPathEvaluator> newObj = new XPathEvaluator(nullptr);
--- a/dom/xslt/xpath/XPathEvaluator.h
+++ b/dom/xslt/xpath/XPathEvaluator.h
@@ -37,17 +37,17 @@ public:
     explicit XPathEvaluator(nsIDocument* aDocument = nullptr);
 
     NS_DECL_ISUPPORTS
 
     // nsIDOMXPathEvaluator interface
     NS_DECL_NSIDOMXPATHEVALUATOR
 
     // WebIDL API
-    JSObject* WrapObject(JSContext* aCx);
+    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
     nsIDocument* GetParentObject()
     {
         nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
         return doc;
     }
     static already_AddRefed<XPathEvaluator>
         Constructor(const GlobalObject& aGlobal, ErrorResult& rv);
     XPathExpression*
--- a/dom/xslt/xpath/XPathExpression.h
+++ b/dom/xslt/xpath/XPathExpression.h
@@ -29,19 +29,19 @@ class XPathResult;
  */
 class XPathExpression MOZ_FINAL : public NonRefcountedDOMObject
 {
 public:
     XPathExpression(nsAutoPtr<Expr>&& aExpression, txResultRecycler* aRecycler,
                     nsIDocument *aDocument);
     ~XPathExpression();
 
-    JSObject* WrapObject(JSContext* aCx)
+    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
     {
-        return XPathExpressionBinding::Wrap(aCx, this);
+        return XPathExpressionBinding::Wrap(aCx, this, aReflector);
     }
 
     already_AddRefed<XPathResult>
         Evaluate(JSContext* aCx, nsINode& aContextNode, uint16_t aType,
                  JS::Handle<JSObject*> aInResult, ErrorResult& aRv)
     {
         return EvaluateWithContext(aCx, aContextNode, 1, 1, aType, aInResult,
                                    aRv);
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -284,20 +284,21 @@ RTCStatsQuery::~RTCStatsQuery() {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 #endif
 
 NS_IMPL_ISUPPORTS0(PeerConnectionImpl)
 
 #ifdef MOZILLA_INTERNAL_API
-JSObject*
-PeerConnectionImpl::WrapObject(JSContext* aCx)
+bool
+PeerConnectionImpl::WrapObject(JSContext* aCx,
+                               JS::MutableHandle<JSObject*> aReflector)
 {
-  return PeerConnectionImplBinding::Wrap(aCx, this);
+  return PeerConnectionImplBinding::Wrap(aCx, this, aReflector);
 }
 #endif
 
 bool PCUuidGenerator::Generate(std::string* idp) {
   nsresult rv;
 
   if(!mGenerator) {
     mGenerator = do_GetService("@mozilla.org/uuid-generator;1", &rv);
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -246,17 +246,17 @@ public:
     kIncompatibleSessionDescription   = 6,
     kIncompatibleMediaStreamTrack     = 8,
     kInternalError                    = 9
   };
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
 #ifdef MOZILLA_INTERNAL_API
-  virtual JSObject* WrapObject(JSContext* cx);
+  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
 #endif
 
   static already_AddRefed<PeerConnectionImpl>
       Constructor(const mozilla::dom::GlobalObject& aGlobal, ErrorResult& rv);
   static PeerConnectionImpl* CreatePeerConnection();
   static nsresult ConvertRTCConfiguration(const RTCConfiguration& aSrc,
                                           IceConfiguration *aDst);
   already_AddRefed<DOMMediaStream> MakeMediaStream(uint32_t aHint);