Bug 868312: Root part of nsDOMClassInfo.cpp r=bz
authorDavid Zbarsky <dzbarsky@gmail.com>
Fri, 03 May 2013 14:53:32 -0400
changeset 141704 1e00967c5786041e818dc1478de2f1df2ec1e0ae
parent 141703 ba4cdf4a1b514900027d2cd53ee58ea00f3deaa2
child 141727 69008b1fd6eba1ed5041c8d8796800ced916d1a3
child 141730 7ded7165ab8747234c14a5bb0a6c5b66c8f7522e
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs868312
milestone23.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 868312: Root part of nsDOMClassInfo.cpp r=bz
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsGlobalWindow.cpp
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1058,20 +1058,20 @@ static const JSClass *sObjectClass = nul
 /**
  * Set our JSClass pointer for the Object class
  */
 static void
 FindObjectClass(JSContext* cx, JSObject* aGlobalObject)
 {
   NS_ASSERTION(!sObjectClass,
                "Double set of sObjectClass");
-  JSObject *obj, *proto = aGlobalObject;
+  JS::Rooted<JSObject*> obj(cx), proto(cx, aGlobalObject);
   do {
     obj = proto;
-    js::GetObjectProto(cx, obj, &proto);
+    js::GetObjectProto(cx, obj, proto.address());
   } while (proto);
 
   sObjectClass = js::GetObjectJSClass(obj);
 }
 
 static void
 PrintWarningOnConsole(JSContext *cx, const char *stringBundleProperty)
 {
@@ -1201,50 +1201,50 @@ WrapNative(JSContext *cx, JSObject *scop
                     aAllowWrapping);
 }
 
 // Used for cases where PreCreate needs to wrap the native parent, and the
 // native parent is likely to have been wrapped already.  |native| must
 // implement nsWrapperCache, and nativeWrapperCache must be |native|'s
 // nsWrapperCache.
 static inline nsresult
-WrapNativeParent(JSContext *cx, JSObject *scope, nsISupports *native,
+WrapNativeParent(JSContext *cx, JS::Handle<JSObject*> scope, nsISupports *native,
                  nsWrapperCache *nativeWrapperCache, JSObject **parentObj)
 {
   // In the common case, |native| is a wrapper cache with an existing wrapper
 #ifdef DEBUG
   nsWrapperCache* cache = nullptr;
   CallQueryInterface(native, &cache);
   NS_PRECONDITION(nativeWrapperCache &&
                   cache == nativeWrapperCache, "What happened here?");
 #endif
 
-  JSObject* obj = nativeWrapperCache->GetWrapper();
+  JS::Rooted<JSObject*> obj(cx, nativeWrapperCache->GetWrapper());
   if (obj) {
 #ifdef DEBUG
     jsval debugVal;
     nsresult rv = WrapNative(cx, scope, native, nativeWrapperCache, false,
                              &debugVal);
     NS_ASSERTION(NS_SUCCEEDED(rv) && JSVAL_TO_OBJECT(debugVal) == obj,
                  "Unexpected object in nsWrapperCache");
 #endif
     *parentObj = obj;
     return NS_OK;
   }
 
-  jsval v;
-  nsresult rv = WrapNative(cx, scope, native, nativeWrapperCache, false, &v);
+  JS::Rooted<JS::Value> v(cx);
+  nsresult rv = WrapNative(cx, scope, native, nativeWrapperCache, false, v.address());
   NS_ENSURE_SUCCESS(rv, rv);
-  *parentObj = JSVAL_TO_OBJECT(v);
+  *parentObj = v.toObjectOrNull();
   return NS_OK;
 }
 
 template<class P>
 static inline nsresult
-WrapNativeParent(JSContext *cx, JSObject *scope, P *parent,
+WrapNativeParent(JSContext *cx, JS::Handle<JSObject*> scope, P *parent,
                  JSObject **parentObj)
 {
   return WrapNativeParent(cx, scope, ToSupports(parent), parent, parentObj);
 }
 
 // Helper to handle torn-down inner windows.
 static inline nsresult
 SetParentToWindow(nsGlobalWindow *win, JSObject **parent)
@@ -2653,21 +2653,21 @@ nsDOMClassInfo::NewEnumerate(nsIXPConnec
 
   return NS_ERROR_UNEXPECTED;
 }
 
 nsresult
 nsDOMClassInfo::ResolveConstructor(JSContext *cx, JSObject *obj,
                                    JSObject **objp)
 {
-  JSObject *global = ::JS_GetGlobalForObject(cx, obj);
-
-  jsval val;
+  JS::Rooted<JSObject*> global(cx, ::JS_GetGlobalForObject(cx, obj));
+
+  JS::Rooted<JS::Value> val(cx);
   JSAutoRequest ar(cx);
-  if (!::JS_LookupProperty(cx, global, mData->mName, &val)) {
+  if (!::JS_LookupProperty(cx, global, mData->mName, val.address())) {
     return NS_ERROR_UNEXPECTED;
   }
 
   if (!JSVAL_IS_PRIMITIVE(val)) {
     // If val is not an (non-null) object there either is no
     // constructor for this class, or someone messed with
     // window.classname, just fall through and let the JS engine
     // return the Object constructor.
@@ -2726,19 +2726,19 @@ NS_IMETHODIMP
 nsDOMClassInfo::CheckAccess(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                             JSObject *obj, jsid id, uint32_t mode,
                             jsval *vp, bool *_retval)
 {
   uint32_t mode_type = mode & JSACC_TYPEMASK;
 
   if ((mode_type == JSACC_WATCH || mode_type == JSACC_PROTO) && sSecMan) {
     nsresult rv;
-    JSObject *real_obj;
+    JS::Rooted<JSObject*> real_obj(cx);
     if (wrapper) {
-      rv = wrapper->GetJSObject(&real_obj);
+      rv = wrapper->GetJSObject(real_obj.address());
       NS_ENSURE_SUCCESS(rv, rv);
     }
     else {
       real_obj = obj;
     }
 
     rv =
       sSecMan->CheckPropertyAccess(cx, real_obj, mData->mName, id,
@@ -2832,27 +2832,28 @@ ResolvePrototype(nsIXPConnect *aXPConnec
                  JSObject *obj, const PRUnichar *name,
                  const nsDOMClassInfoData *ci_data,
                  const nsGlobalNameStruct *name_struct,
                  nsScriptNameSpaceManager *nameSpaceManager,
                  JSObject *dot_prototype, bool install, bool *did_resolve);
 
 
 NS_IMETHODIMP
-nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * proto)
+nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * aProto)
 {
   uint32_t flags = (mData->mScriptableFlags & DONT_ENUM_STATIC_PROPS)
                    ? 0
                    : JSPROP_ENUMERATE;
 
   uint32_t count = 0;
   while (mData->mInterfaces[count]) {
     count++;
   }
 
+  JS::Rooted<JSObject*> proto(cx, aProto);
   if (!xpc::DOM_DefineQuickStubs(cx, proto, flags, count, mData->mInterfaces)) {
     JS_ClearPendingException(cx);
   }
 
   // This is called before any other location that requires
   // sObjectClass, so compute it here. We assume that nobody has had a
   // chance to monkey around with proto's prototype chain before this.
   if (!sObjectClass) {
@@ -2888,17 +2889,17 @@ nsDOMClassInfo::PostCreatePrototype(JSCo
     }
   }
 #endif
 
   // Make prototype delegation work correctly. Consider if a site sets
   // HTMLElement.prototype.foopy = function () { ... } Now, calling
   // document.body.foopy() needs to ensure that looking up foopy on
   // document.body's prototype will find the right function.
-  JSObject *global = ::JS_GetGlobalForObject(cx, proto);
+  JS::Rooted<JSObject*> global(cx, ::JS_GetGlobalForObject(cx, proto));
 
   // Only do this if the global object is a window.
   // XXX Is there a better way to check this?
   nsISupports *globalNative = XPConnect()->GetNativeOfWrapper(cx, global);
   nsCOMPtr<nsPIDOMWindow> piwin = do_QueryInterface(globalNative);
   if (!piwin) {
     return NS_OK;
   }
@@ -3136,19 +3137,19 @@ ChildWindowGetter(JSContext *cx, JSHandl
   nsGlobalWindow *win = nsGlobalWindow::FromSupports(winSupports);
 
   // Find the child, if it exists.
   nsCOMPtr<nsIDOMWindow> child = win->GetChildWindow(id);
   if (!child)
     return true;
 
   // Wrap the child for JS.
-  jsval v;
+  JS::Rooted<JS::Value> v(cx);
   nsresult rv = WrapNative(cx, JS_GetGlobalForScopeChain(cx), child,
-                           /* aAllowWrapping = */ true, &v);
+                           /* aAllowWrapping = */ true, v.address());
   NS_ENSURE_SUCCESS(rv, false);
   vp.set(v);
   return true;
 }
 
 static nsHTMLDocument*
 GetDocument(JSObject *obj)
 {
@@ -3193,18 +3194,18 @@ nsWindowSH::GlobalScopePolluterNewResolv
         return false;
       }
 
       objp.set(obj);
       return true;
     }
   }
 
-  JSObject *proto;
-  if (!::JS_GetPrototype(cx, obj, &proto)) {
+  JS::Rooted<JSObject*> proto(cx);
+  if (!::JS_GetPrototype(cx, obj, proto.address())) {
     return JS_FALSE;
   }
   JSBool hasProp;
 
   if (!proto || !::JS_HasPropertyById(cx, proto, id, &hasProp) ||
       hasProp) {
     // No prototype, or the property exists on the prototype. Do
     // nothing.
@@ -3230,53 +3231,53 @@ nsWindowSH::GlobalScopePolluterNewResolv
     cache = element;
   }
 
   if (!result) {
     result = document->ResolveName(str, &cache);
   }
 
   if (result) {
-    jsval v;
+    JS::Rooted<JS::Value> v(cx);
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-    nsresult rv = WrapNative(cx, obj, result, cache, true, &v,
+    nsresult rv = WrapNative(cx, obj, result, cache, true, v.address(),
                              getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, JS_FALSE);
 
-    if (!JS_WrapValue(cx, &v) ||
+    if (!JS_WrapValue(cx, v.address()) ||
         !JS_DefinePropertyById(cx, obj, id, v, JS_PropertyStub, JS_StrictPropertyStub, 0)) {
       return JS_FALSE;
     }
 
     objp.set(obj);
   }
 
   return JS_TRUE;
 }
 
 // static
 JSBool
 nsWindowSH::InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj)
 {
-  JSObject *proto;
+  JS::Rooted<JSObject*> proto(cx);
 
   JSAutoRequest ar(cx);
 
   for (;;) {
-    if (!::JS_GetPrototype(cx, obj, &proto)) {
+    if (!::JS_GetPrototype(cx, obj, proto.address())) {
       return JS_FALSE;
     }
     if (!proto) {
       break;
     }
 
     if (JS_GetClass(proto) == &sGlobalScopePolluterClass) {
 
-      JSObject *proto_proto;
-      if (!::JS_GetPrototype(cx, proto, &proto_proto)) {
+      JS::Rooted<JSObject*> proto_proto(cx);
+      if (!::JS_GetPrototype(cx, proto, proto_proto.address())) {
         return JS_FALSE;
       }
 
       // Pull the global scope polluter out of the prototype chain so
       // that it can be freed.
       ::JS_SplicePrototype(cx, obj, proto_proto);
 
       break;
@@ -3285,32 +3286,32 @@ nsWindowSH::InvalidateGlobalScopePollute
     obj = proto;
   }
 
   return JS_TRUE;
 }
 
 // static
 nsresult
-nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JSObject *obj)
+nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JS::Handle<JSObject*> obj)
 {
   JSAutoRequest ar(cx);
 
-  JSObject *gsp = ::JS_NewObjectWithUniqueType(cx, &sGlobalScopePolluterClass, nullptr, obj);
+  JS::Rooted<JSObject*> gsp(cx, ::JS_NewObjectWithUniqueType(cx, &sGlobalScopePolluterClass, nullptr, obj));
   if (!gsp) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  JSObject *o = obj, *proto;
+  JS::Rooted<JSObject*> o(cx, obj), proto(cx);
 
   // Find the place in the prototype chain where we want this global
   // scope polluter (right before Object.prototype).
 
   for (;;) {
-    if (!::JS_GetPrototype(cx, o, &proto)) {
+    if (!::JS_GetPrototype(cx, o, proto.address())) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     if (!proto) {
       break;
     }
     if (JS_GetClass(proto) == sObjectClass) {
       // Set the global scope polluters prototype to Object.prototype
       ::JS_SplicePrototype(cx, gsp, proto);
@@ -3348,18 +3349,19 @@ ResolveGlobalName(const nsAString& aName
     *closure->retval = false;
     return PL_DHASH_STOP;
   }
   return PL_DHASH_NEXT;
 }
 
 NS_IMETHODIMP
 nsWindowSH::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                      JSObject *obj, bool *_retval)
-{
+                      JSObject *aObj, bool *_retval)
+{
+  JS::Rooted<JSObject*> obj(cx, aObj);
   if (!xpc::WrapperFactory::IsXrayWrapper(obj)) {
     *_retval = JS_EnumerateStandardClasses(cx, obj);
     if (!*_retval) {
       return NS_OK;
     }
 
     // Now resolve everything from the namespace manager
     nsScriptNameSpaceManager *nameSpaceManager =
@@ -3385,18 +3387,19 @@ FindConstructorFunc(const nsDOMClassInfo
     }
   }
   return nullptr;
 }
 
 static nsresult
 BaseStubConstructor(nsIWeakReference* aWeakOwner,
                     const nsGlobalNameStruct *name_struct, JSContext *cx,
-                    JSObject *obj, unsigned argc, jsval *argv, jsval *rval)
-{
+                    JSObject *aObj, unsigned argc, jsval *argv, jsval *rval)
+{
+  JS::Rooted<JSObject*> obj(cx, aObj);
   MOZ_ASSERT(obj);
 
   nsresult rv;
   nsCOMPtr<nsISupports> native;
   if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
     const nsDOMClassInfoData* ci_data =
       &sClassInfoData[name_struct->mDOMClassInfoID];
     nsDOMConstructorFunc func = FindConstructorFunc(ci_data);
@@ -3435,40 +3438,40 @@ BaseStubConstructor(nsIWeakReference* aW
     if (initializer) {
       rv = initializer->Initialize(currentInner, cx, obj, argc, argv);
       if (NS_FAILED(rv)) {
         return rv;
       }
     } else {
       nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(native);
 
-      JSObject* object = nullptr;
-      wrappedJS->GetJSObject(&object);
+      JS::Rooted<JSObject*> object(cx);
+      wrappedJS->GetJSObject(object.address());
       if (!object) {
         return NS_ERROR_UNEXPECTED;
       }
 
       nsCxPusher pusher;
       pusher.Push(cx);
 
       JSAutoRequest ar(cx);
       JSAutoCompartment ac(cx, object);
 
-      JS::Value thisValue = JSVAL_VOID;
-      JS::Value funval;
-      if (!JS_GetProperty(cx, object, "constructor", &funval) || !funval.isObject()) {
+      JS::Rooted<JS::Value> thisValue(cx, JS::UndefinedValue());
+      JS::Rooted<JS::Value> funval(cx);
+      if (!JS_GetProperty(cx, object, "constructor", funval.address()) || !funval.isObject()) {
         return NS_ERROR_UNEXPECTED;
       }
 
       // Check if the object is even callable.
       NS_ENSURE_STATE(JS_ObjectIsCallable(cx, &funval.toObject()));
       thisValue.setObject(*object);
 
       {
-        JSObject* thisObject = &thisValue.toObject();
+        JS::Rooted<JSObject*> thisObject(cx, &thisValue.toObject());
 
         // wrap parameters in the target compartment
         // we also pass in the calling window as the first argument
         ++argc;
         nsAutoArrayPtr<JS::Value> args(new JS::Value[argc]);
         JS::AutoArrayRooter rooter(cx, 0, args);
 
         nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
@@ -3495,17 +3498,17 @@ BaseStubConstructor(nsIWeakReference* aW
       }
     }
   }
 
   return WrapNative(cx, obj, native, true, rval);
 }
 
 static nsresult
-DefineInterfaceConstants(JSContext *cx, JSObject *obj, const nsIID *aIID)
+DefineInterfaceConstants(JSContext *cx, JS::Handle<JSObject*> obj, const nsIID *aIID)
 {
   nsCOMPtr<nsIInterfaceInfoManager>
     iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
   NS_ENSURE_TRUE(iim, NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<nsIInterfaceInfo> if_info;
 
   nsresult rv = iim->GetInfoForIID(aIID, getter_AddRefs(if_info));
@@ -3762,17 +3765,17 @@ public:
       ::JS_DefineUCProperty(cx, target,
                             reinterpret_cast<const jschar *>(mClassName),
                             NS_strlen(mClassName), thisAsVal, JS_PropertyStub,
                             JS_StrictPropertyStub, 0);
 
     return ok ? NS_OK : NS_ERROR_UNEXPECTED;
   }
 
-  nsresult ResolveInterfaceConstants(JSContext *cx, JSObject *obj);
+  nsresult ResolveInterfaceConstants(JSContext *cx, JS::Handle<JSObject*> obj);
 
 private:
   const nsGlobalNameStruct *GetNameStruct()
   {
     if (!mClassName) {
       NS_ERROR("Can't get name");
       return nullptr;
     }
@@ -3929,17 +3932,17 @@ nsDOMConstructor::HasInstance(nsIXPConne
 
 {
   // No need to look these up in the hash.
   *bp = false;
   if (JSVAL_IS_PRIMITIVE(v)) {
     return NS_OK;
   }
 
-  JSObject *dom_obj = JSVAL_TO_OBJECT(v);
+  JS::Rooted<JSObject*> dom_obj(cx, v.toObjectOrNull());
   NS_ASSERTION(dom_obj, "nsDOMConstructor::HasInstance couldn't get object");
 
   // This might not be the right object, if there are wrappers. Unwrap if we can.
   JSObject *wrapped_obj = js::CheckedUnwrap(dom_obj, /* stopAtOuter = */ false);
   if (wrapped_obj)
       dom_obj = wrapped_obj;
 
   JSClass *dom_class = JS_GetClass(dom_obj);
@@ -3952,30 +3955,30 @@ nsDOMConstructor::HasInstance(nsIXPConne
   nsresult rv = GetNameStruct(NS_ConvertASCIItoUTF16(dom_class->name), &name_struct);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   if (!name_struct) {
     // This isn't a normal DOM object, see if this constructor lives on its
     // prototype chain.
-    jsval val;
-    if (!JS_GetProperty(cx, obj, "prototype", &val)) {
+    JS::Rooted<JS::Value> val(cx);
+    if (!JS_GetProperty(cx, obj, "prototype", val.address())) {
       return NS_ERROR_UNEXPECTED;
     }
 
     if (JSVAL_IS_PRIMITIVE(val)) {
       return NS_OK;
     }
 
-    JSObject *dot_prototype = JSVAL_TO_OBJECT(val);
-
-    JSObject *proto = dom_obj;
+    JS::Rooted<JSObject*> dot_prototype(cx, val.toObjectOrNull());
+
+    JS::Rooted<JSObject*> proto(cx, dom_obj);
     for (;;) {
-      if (!JS_GetPrototype(cx, proto, &proto)) {
+      if (!JS_GetPrototype(cx, proto, proto.address())) {
         return NS_ERROR_UNEXPECTED;
       }
       if (!proto) {
         break;
       }
       if (proto == dot_prototype) {
         *bp = true;
         break;
@@ -4086,17 +4089,17 @@ nsDOMConstructor::HasInstance(nsIXPConne
       return NS_OK;
     }
   }
 
   return NS_OK;
 }
 
 nsresult
-nsDOMConstructor::ResolveInterfaceConstants(JSContext *cx, JSObject *obj)
+nsDOMConstructor::ResolveInterfaceConstants(JSContext *cx, JS::Handle<JSObject*> obj)
 {
   const nsGlobalNameStruct *class_name_struct = GetNameStruct();
   if (!class_name_struct)
     return NS_ERROR_UNEXPECTED;
 
   const nsIID *class_iid;
   if (class_name_struct->mType == nsGlobalNameStruct::eTypeInterface ||
       class_name_struct->mType == nsGlobalNameStruct::eTypeClassProto) {
@@ -4183,19 +4186,19 @@ GetXPCProto(nsIXPConnect *aXPConnect, JS
   }
   NS_ENSURE_TRUE(ci, NS_ERROR_UNEXPECTED);
 
   nsresult rv =
     aXPConnect->GetWrappedNativePrototype(cx, aWin->GetGlobalJSObject(), ci,
                                           aProto);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  JSObject *proto_obj;
-  (*aProto)->GetJSObject(&proto_obj);
-  if (!JS_WrapObject(cx, &proto_obj)) {
+  JS::Rooted<JSObject*> proto_obj(cx);
+  (*aProto)->GetJSObject(proto_obj.address());
+  if (!JS_WrapObject(cx, proto_obj.address())) {
     return NS_ERROR_FAILURE;
   }
 
   NS_IF_RELEASE(*aProto);
   return aXPConnect->HoldObject(cx, proto_obj, aProto);
 }
 
 // Either ci_data must be non-null or name_struct must be non-null and of type
@@ -4214,29 +4217,29 @@ ResolvePrototype(nsIXPConnect *aXPConnec
                "Wrong type or missing ci_data!");
 
   nsRefPtr<nsDOMConstructor> constructor;
   nsresult rv = nsDOMConstructor::Create(name, ci_data, name_struct, aWin,
                                          getter_AddRefs(constructor));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-  jsval v;
+  JS::Rooted<JS::Value> v(cx);
 
   rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor),
-                  false, &v, getter_AddRefs(holder));
+                  false, v.address(), getter_AddRefs(holder));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (install) {
     rv = constructor->Install(cx, obj, v);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  JSObject *class_obj;
-  holder->GetJSObject(&class_obj);
+  JS::Rooted<JSObject*> class_obj(cx);
+  holder->GetJSObject(class_obj.address());
   NS_ASSERTION(class_obj, "The return value lied");
 
   const nsIID *primary_iid = &NS_GET_IID(nsISupports);
 
   if (!ci_data) {
     primary_iid = &name_struct->mIID;
   }
   else if (ci_data->mProtoChainInterface) {
@@ -4304,50 +4307,50 @@ ResolvePrototype(nsIXPConnect *aXPConnec
 
           parent->GetNameShared(&class_parent_name);
         }
       }
     }
   }
 
   {
-    JSObject *winobj = aWin->FastGetGlobalJSObject();
-
-    JSObject *proto = nullptr;
+    JS::Rooted<JSObject*> winobj(cx, aWin->FastGetGlobalJSObject());
+
+    JS::Rooted<JSObject*> proto(cx);
 
     if (class_parent_name) {
       JSAutoCompartment ac(cx, winobj);
 
-      JS::Value val;
-      if (!JS_LookupProperty(cx, winobj, CutPrefix(class_parent_name), &val)) {
+      JS::Rooted<JS::Value> val(cx);
+      if (!JS_LookupProperty(cx, winobj, CutPrefix(class_parent_name), val.address())) {
         return NS_ERROR_UNEXPECTED;
       }
 
       if (val.isObject()) {
-        if (!JS_LookupProperty(cx, &val.toObject(), "prototype", &val)) {
+        if (!JS_LookupProperty(cx, &val.toObject(), "prototype", val.address())) {
           return NS_ERROR_UNEXPECTED;
         }
 
         if (val.isObject()) {
           proto = &val.toObject();
         }
       }
     }
 
     if (dot_prototype) {
       JSAutoCompartment ac(cx, dot_prototype);
-      JSObject *xpc_proto_proto;
-      if (!::JS_GetPrototype(cx, dot_prototype, &xpc_proto_proto)) {
+      JS::Rooted<JSObject*> xpc_proto_proto(cx);
+      if (!::JS_GetPrototype(cx, dot_prototype, xpc_proto_proto.address())) {
         return NS_ERROR_UNEXPECTED;
       }
 
       if (proto &&
           (!xpc_proto_proto ||
            JS_GetClass(xpc_proto_proto) == sObjectClass)) {
-        if (!JS_WrapObject(cx, &proto) ||
+        if (!JS_WrapObject(cx, proto.address()) ||
             !JS_SetPrototype(cx, dot_prototype, proto)) {
           return NS_ERROR_UNEXPECTED;
         }
       }
     } else {
       JSAutoCompartment ac(cx, winobj);
       if (!proto) {
         proto = JS_GetObjectPrototype(cx, winobj);
@@ -4360,17 +4363,17 @@ ResolvePrototype(nsIXPConnect *aXPConnec
     }
   }
 
   v = OBJECT_TO_JSVAL(dot_prototype);
 
   JSAutoCompartment ac(cx, class_obj);
 
   // Per ECMA, the prototype property is {DontEnum, DontDelete, ReadOnly}
-  if (!JS_WrapValue(cx, &v) ||
+  if (!JS_WrapValue(cx, v.address()) ||
       !JS_DefineProperty(cx, class_obj, "prototype", v,
                          JS_PropertyStub, JS_StrictPropertyStub,
                          JSPROP_PERMANENT | JSPROP_READONLY)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   *did_resolve = true;
 
@@ -4458,26 +4461,26 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
           return NS_ERROR_DOM_SECURITY_ERR;
         }
         ac.construct(cx, global);
       } else {
         global = obj;
       }
 
       bool enabled;
-      JSObject* interfaceObject = define(cx, global, id, &enabled);
+      JS::Rooted<JSObject*> interfaceObject(cx, define(cx, global, id, &enabled));
       if (enabled) {
         if (!interfaceObject) {
           return NS_ERROR_FAILURE;
         }
 
         if (defineOnXray) {
           // This really should be handled by the Xray for the window.
           ac.destroy();
-          if (!JS_WrapObject(cx, &interfaceObject) ||
+          if (!JS_WrapObject(cx, interfaceObject.address()) ||
               !JS_DefinePropertyById(cx, obj, id,
                                      JS::ObjectValue(*interfaceObject), JS_PropertyStub,
                                      JS_StrictPropertyStub, 0)) {
             return NS_ERROR_FAILURE;
           }
         }
 
         *did_resolve = true;
@@ -4494,26 +4497,26 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
     rv = nsDOMConstructor::Create(class_name,
                                   nullptr,
                                   name_struct,
                                   static_cast<nsPIDOMWindow*>(aWin),
                                   getter_AddRefs(constructor));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-    jsval v;
+    JS::Rooted<JS::Value> v(cx);
     rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor),
-                    false, &v, getter_AddRefs(holder));
+                    false, v.address(), getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = constructor->Install(cx, obj, v);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    JSObject *class_obj;
-    holder->GetJSObject(&class_obj);
+    JS::Rooted<JSObject*> class_obj(cx);
+    holder->GetJSObject(class_obj.address());
     NS_ASSERTION(class_obj, "The return value lied");
 
     // ... and define the constants from the DOM interface on that
     // constructor object.
 
     JSAutoCompartment ac(cx, class_obj);
     rv = DefineInterfaceConstants(cx, class_obj, &name_struct->mIID);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -4531,18 +4534,18 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
 
     // Create the XPConnect prototype for our classinfo, PostCreateProto will
     // set up the prototype chain.
     nsCOMPtr<nsIXPConnectJSObjectHolder> proto_holder;
     rv = GetXPCProto(sXPConnect, cx, aWin, name_struct,
                      getter_AddRefs(proto_holder));
 
     if (NS_SUCCEEDED(rv) && obj != aWin->GetGlobalJSObject()) {
-      JSObject* dot_prototype;
-      rv = proto_holder->GetJSObject(&dot_prototype);
+      JS::Rooted<JSObject*> dot_prototype(cx);
+      rv = proto_holder->GetJSObject(dot_prototype.address());
       NS_ENSURE_SUCCESS(rv, rv);
 
       const nsDOMClassInfoData *ci_data;
       if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
         ci_data = &sClassInfoData[name_struct->mDOMClassInfoID];
       } else {
         ci_data = name_struct->mData;
       }
@@ -4598,20 +4601,20 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
 
   if (name_struct->mType == nsGlobalNameStruct::eTypeExternalConstructor) {
     nsRefPtr<nsDOMConstructor> constructor;
     rv = nsDOMConstructor::Create(class_name, nullptr, name_struct,
                                   static_cast<nsPIDOMWindow*>(aWin),
                                   getter_AddRefs(constructor));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    jsval val;
+    JS::Rooted<JS::Value> val(cx);
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor),
-                    false, &val, getter_AddRefs(holder));
+                    false, val.address(), getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = constructor->Install(cx, obj, val);
     NS_ENSURE_SUCCESS(rv, rv);
 
     JSObject* class_obj;
     holder->GetJSObject(&class_obj);
     NS_ASSERTION(class_obj, "Why didn't we get a JSObject?");
@@ -4623,44 +4626,44 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
 
   if (name_struct->mType == nsGlobalNameStruct::eTypeProperty) {
     if (name_struct->mChromeOnly && !nsContentUtils::IsCallerChrome())
       return NS_OK;
 
     nsCOMPtr<nsISupports> native(do_CreateInstance(name_struct->mCID, &rv));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    jsval prop_val = JSVAL_VOID; // Property value.
+    JS::Rooted<JS::Value> prop_val(cx, JS::UndefinedValue()); // Property value.
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi(do_QueryInterface(native));
     if (gpi) {
-      rv = gpi->Init(aWin, &prop_val);
+      rv = gpi->Init(aWin, prop_val.address());
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     if (JSVAL_IS_PRIMITIVE(prop_val) && !JSVAL_IS_NULL(prop_val)) {
       JSObject *scope;
 
       if (aWin->IsOuterWindow()) {
         nsGlobalWindow *inner = aWin->GetCurrentInnerWindowInternal();
         NS_ENSURE_TRUE(inner, NS_ERROR_UNEXPECTED);
 
         scope = inner->GetGlobalJSObject();
       } else {
         scope = aWin->GetGlobalJSObject();
       }
 
-      rv = WrapNative(cx, scope, native, true, &prop_val,
+      rv = WrapNative(cx, scope, native, true, prop_val.address(),
                       getter_AddRefs(holder));
     }
 
     NS_ENSURE_SUCCESS(rv, rv);
 
-    if (!JS_WrapValue(cx, &prop_val)) {
+    if (!JS_WrapValue(cx, prop_val.address())) {
       return NS_ERROR_UNEXPECTED;
     }
 
     JSBool ok = ::JS_DefinePropertyById(cx, obj, id, prop_val,
                                         JS_PropertyStub, JS_StrictPropertyStub,
                                         JSPROP_ENUMERATE);
 
     *did_resolve = true;
@@ -4712,17 +4715,17 @@ LocationSetterGuts(JSContext *cx, JSObje
   nsCOMPtr<Interface> xpcomObj = do_QueryWrappedNative(wrapper, obj);
   NS_ENSURE_TRUE(xpcomObj, NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<nsIDOMLocation> location;
   nsresult rv = xpcomObj->GetLocation(getter_AddRefs(location));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Grab the value we're being set to before we stomp on |vp|
-  JSString *val = ::JS_ValueToString(cx, *vp);
+  JS::Rooted<JSString*> val(cx, ::JS_ValueToString(cx, *vp));
   NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED);
 
   // Make sure |val| stays alive below
   JS::Anchor<JSString *> anchor(val);
 
   // We have to wrap location into vp before null-checking location, to
   // avoid assigning the wrong thing into the slot.
   nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
@@ -4816,41 +4819,41 @@ const InterfaceShimEntry kInterfaceShimM
 
 static nsresult
 DefineComponentsShim(JSContext *cx, JS::HandleObject global)
 {
   // Keep track of how often this happens.
   Telemetry::Accumulate(Telemetry::COMPONENTS_SHIM_ACCESSED_BY_CONTENT, true);
 
   // Create a fake Components object.
-  JSObject *components = JS_NewObject(cx, nullptr, nullptr, global);
+  JS::Rooted<JSObject*> components(cx, JS_NewObject(cx, nullptr, nullptr, global));
   NS_ENSURE_TRUE(components, NS_ERROR_OUT_OF_MEMORY);
   bool ok = JS_DefineProperty(cx, global, "Components", JS::ObjectValue(*components),
                               JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE);
   NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
 
   // Create a fake interfaces object.
-  JSObject *interfaces = JS_NewObject(cx, nullptr, nullptr, global);
+  JS::Rooted<JSObject*> interfaces(cx, JS_NewObject(cx, nullptr, nullptr, global));
   NS_ENSURE_TRUE(interfaces, NS_ERROR_OUT_OF_MEMORY);
   ok = JS_DefineProperty(cx, components, "interfaces", JS::ObjectValue(*interfaces),
                          JS_PropertyStub, JS_StrictPropertyStub,
                          JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
   NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
 
   // Define a bunch of shims from the Ci.nsIDOMFoo to window.Foo for DOM
   // interfaces with constants.
   for (uint32_t i = 0; i < ArrayLength(kInterfaceShimMap); ++i) {
 
     // Grab the names from the table.
     const char *geckoName = kInterfaceShimMap[i].geckoName;
     const char *domName = kInterfaceShimMap[i].domName;
 
     // Look up the appopriate interface object on the global.
-    JS::Value v = JS::UndefinedValue();
-    ok = JS_GetProperty(cx, global, domName, &v);
+    JS::Rooted<JS::Value> v(cx, JS::UndefinedValue());
+    ok = JS_GetProperty(cx, global, domName, v.address());
     NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
     if (!v.isObject()) {
       NS_WARNING("Unable to find interface object on global");
       continue;
     }
 
     // Define the shim on the interfaces object.
     ok = JS_DefineProperty(cx, interfaces, geckoName, v,
@@ -4885,17 +4888,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
 
   nsIScriptContext *my_context = win->GetContextInternal();
 
   // Don't resolve standard classes on XrayWrappers, only resolve them if we're
   // resolving on the real global object.
   if (!xpc::WrapperFactory::IsXrayWrapper(obj)) {
     JSBool did_resolve = JS_FALSE;
     JSBool ok = JS_TRUE;
-    JS::Value exn = JSVAL_VOID;
+    JS::Rooted<JS::Value> exn(cx, JSVAL_VOID);
 
     {
       // Resolve standard classes on my_context's JSContext (or on cx,
       // if we don't have a my_context yet), in case the two contexts
       // have different origins.  We want lazy standard class
       // initialization to behave as if it were done eagerly, on each
       // window's own context (not on some other window-caller's
       // context).
@@ -4904,17 +4907,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       JSAutoCompartment ac(my_cx, obj);
 
       ok = JS_ResolveStandardClass(my_cx, obj, id, &did_resolve);
 
       if (!ok) {
         // Trust the JS engine (or the script security manager) to set
         // the exception in the JS engine.
 
-        if (!JS_GetPendingException(my_cx, &exn)) {
+        if (!JS_GetPendingException(my_cx, exn.address())) {
           return NS_ERROR_UNEXPECTED;
         }
 
         // Return NS_OK to avoid stomping over the exception that was passed
         // down from the ResolveStandardClass call.
         // Note that the order of the JS_ClearPendingException and
         // JS_SetPendingException is important in the case that my_cx == cx.
 
@@ -4954,26 +4957,26 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     // here) since we must define window.location to prevent the
     // getter from being overriden (for security reasons).
 
     nsCOMPtr<nsIDOMLocation> location;
     nsresult rv = win->GetLocation(getter_AddRefs(location));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Make sure we wrap the location object in the window's scope.
-    JSObject *scope = nullptr;
-    wrapper->GetJSObject(&scope);
+    JS::Rooted<JSObject*> scope(cx);
+    wrapper->GetJSObject(scope.address());
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-    jsval v;
+    JS::Rooted<JS::Value> v(cx);
     rv = WrapNative(cx, scope, location, &NS_GET_IID(nsIDOMLocation), true,
-                    &v, getter_AddRefs(holder));
+                    v.address(), getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    JSBool ok = JS_WrapValue(cx, &v) &&
+    JSBool ok = JS_WrapValue(cx, v.address()) &&
                 JS_DefinePropertyById(cx, obj, id, v, JS_PropertyStub,
                                       LocationSetterUnwrapper,
                                       JSPROP_PERMANENT | JSPROP_ENUMERATE);
 
     if (!ok) {
       return NS_ERROR_FAILURE;
     }
 
@@ -4982,20 +4985,20 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     return NS_OK;
   }
 
   if (sTop_id == id) {
     nsCOMPtr<nsIDOMWindow> top;
     nsresult rv = win->GetScriptableTop(getter_AddRefs(top));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    jsval v;
+    JS::Rooted<JS::Value> v(cx);
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = WrapNative(cx, obj, top, &NS_GET_IID(nsIDOMWindow), true,
-                    &v, getter_AddRefs(holder));
+                    v.address(), getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Hold on to the top window object as a global property so we
     // don't need to worry about losing expando properties etc.
     if (!JS_DefinePropertyById(cx, obj, id, v, JS_PropertyStub, JS_StrictPropertyStub,
                                JSPROP_READONLY | JSPROP_PERMANENT |
                                JSPROP_ENUMERATE)) {
       return NS_ERROR_FAILURE;
@@ -5029,20 +5032,20 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     return NS_OK;
   }
 
   if (s_content_id == id) {
     // Map window._content to window.content for backwards
     // compatibility, this should spit out an message on the JS
     // console.
 
-    JSObject* windowObj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
+    JS::Rooted<JSObject*> windowObj(cx, js::CheckedUnwrap(obj, /* stopAtOuter = */ false));
     NS_ENSURE_TRUE(windowObj, NS_ERROR_DOM_SECURITY_ERR);
 
-    JSObject *funObj;
+    JSObject* funObj = nullptr;
     {
       JSAutoCompartment ac(cx, windowObj);
       JSFunction *fun = ::JS_NewFunction(cx, ContentWindowGetter, 0, 0,
                                          windowObj, "_content");
       if (!fun) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
       funObj = ::JS_GetFunctionObject(fun);
@@ -5079,20 +5082,20 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       return NS_OK;
     }
   } else {
     if (sNavigator_id == id) {
       nsCOMPtr<nsIDOMNavigator> navigator;
       rv = win->GetNavigator(getter_AddRefs(navigator));
       NS_ENSURE_SUCCESS(rv, rv);
 
-      jsval v;
+      JS::Rooted<JS::Value> v(cx);
       nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
       rv = WrapNative(cx, obj, navigator, &NS_GET_IID(nsIDOMNavigator), true,
-                      &v, getter_AddRefs(holder));
+                      v.address(), getter_AddRefs(holder));
       NS_ENSURE_SUCCESS(rv, rv);
 
       // Hold on to the navigator object as a global property so we
       // don't need to worry about losing expando properties etc.
       if (!::JS_DefinePropertyById(cx, obj, id, v,
                                    JS_PropertyStub, JS_StrictPropertyStub,
                                    JSPROP_READONLY | JSPROP_PERMANENT |
                                    JSPROP_ENUMERATE)) {
@@ -5100,33 +5103,33 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       }
       *objp = obj;
 
       return NS_OK;
     }
 
     if (sDocument_id == id) {
       nsCOMPtr<nsIDocument> document = win->GetDoc();
-      JS::Value v;
+      JS::Rooted<JS::Value> v(cx);
       nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
       rv = WrapNative(cx, JS_GetGlobalForScopeChain(cx), document, document,
-                      &NS_GET_IID(nsIDOMDocument), &v, getter_AddRefs(holder),
+                      &NS_GET_IID(nsIDOMDocument), v.address(), getter_AddRefs(holder),
                       false);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // The PostCreate hook for the document will handle defining the
       // property
       *objp = obj;
 
       // NB: We need to do this for any Xray wrapper.
       if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
         // Unless our object is a native wrapper, in which case we have to
         // define it ourselves.
 
-        *_retval = JS_WrapValue(cx, &v) &&
+        *_retval = JS_WrapValue(cx, v.address()) &&
                    JS_DefineProperty(cx, obj, "document", v,
                                      JS_PropertyStub, JS_StrictPropertyStub,
                                      JSPROP_READONLY | JSPROP_ENUMERATE);
         if (!*_retval) {
           return NS_ERROR_UNEXPECTED;
         }
       }
 
@@ -5159,31 +5162,31 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     return rv;
   }
 
   // Make a fast expando if we're assigning to (not declaring or
   // binding a name) a new undefined property that's not already
   // defined on our prototype chain. This way we can access this
   // expando w/o ever getting back into XPConnect.
   if (flags & JSRESOLVE_ASSIGNING) {
-    JSObject *realObj;
-    wrapper->GetJSObject(&realObj);
+    JS::Rooted<JSObject*> realObj(cx);
+    wrapper->GetJSObject(realObj.address());
 
     if (obj == realObj) {
-      JSObject *proto;
-      if (!js::GetObjectProto(cx, obj, &proto)) {
+      JS::Rooted<JSObject*> proto(cx);
+      if (!js::GetObjectProto(cx, obj, proto.address())) {
           *_retval = JS_FALSE;
           return NS_OK;
       }
       if (proto) {
-        JSObject *pobj = NULL;
+        JS::Rooted<JSObject*> pobj(cx);
         jsval val;
 
         if (!::JS_LookupPropertyWithFlagsById(cx, proto, id, flags,
-                                              &pobj, &val)) {
+                                              pobj.address(), &val)) {
           *_retval = JS_FALSE;
 
           return NS_OK;
         }
 
         if (pobj) {
           // A property was found on the prototype chain.
           *objp = pobj;
@@ -5241,24 +5244,24 @@ nsWindowSH::OuterObject(nsIXPConnectWrap
     // running on a window w/o an outer, which means this hook should
     // never be called when we have no outer. But just in case, return
     // null to prevent leaking an inner window to code in a different
     // window.
     *_retval = nullptr;
     return NS_ERROR_UNEXPECTED;
   }
 
-  JSObject *winObj = win->FastGetGlobalJSObject();
+  JS::Rooted<JSObject*> winObj(cx, win->FastGetGlobalJSObject());
   MOZ_ASSERT(winObj);
 
   // Note that while |wrapper| is same-compartment with cx, the outer window
   // might not be. If we're running script in an inactive scope and evalute
   // |this|, the outer window is actually a cross-compartment wrapper. So we
   // need to wrap here.
-  if (!JS_WrapObject(cx, &winObj)) {
+  if (!JS_WrapObject(cx, winObj.address())) {
     *_retval = nullptr;
     return NS_ERROR_UNEXPECTED;
   }
 
   *_retval = winObj;
   return NS_OK;
 }
 
@@ -5390,38 +5393,38 @@ nsNavigatorSH::NewResolve(nsIXPConnectWr
   NS_ASSERTION(name_struct->mType == nsGlobalNameStruct::eTypeNavigatorProperty,
                "unexpected type");
 
   nsresult rv = NS_OK;
 
   nsCOMPtr<nsISupports> native(do_CreateInstance(name_struct->mCID, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  jsval prop_val = JSVAL_VOID; // Property value.
+  JS::Rooted<JS::Value> prop_val(cx, JS::UndefinedValue()); // Property value.
 
   nsCOMPtr<nsIDOMGlobalPropertyInitializer> gpi(do_QueryInterface(native));
 
   if (gpi) {
     nsCOMPtr<nsIDOMNavigator> navigator = do_QueryWrappedNative(wrapper);
     nsIDOMWindow *window = static_cast<Navigator*>(navigator.get())->GetWindow();
     NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
 
-    rv = gpi->Init(window, &prop_val);
+    rv = gpi->Init(window, prop_val.address());
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (JSVAL_IS_PRIMITIVE(prop_val) && !JSVAL_IS_NULL(prop_val)) {
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
-    rv = WrapNative(cx, obj, native, true, &prop_val,
+    rv = WrapNative(cx, obj, native, true, prop_val.address(),
                     getter_AddRefs(holder));
 
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  if (!JS_WrapValue(cx, &prop_val)) {
+  if (!JS_WrapValue(cx, prop_val.address())) {
     return NS_ERROR_UNEXPECTED;
   }
 
   JSBool ok = ::JS_DefinePropertyById(cx, obj, id, prop_val,
                                       JS_PropertyStub, JS_StrictPropertyStub,
                                       JSPROP_ENUMERATE);
 
   *_retval = true;
@@ -5456,19 +5459,20 @@ nsNavigatorSH::PreCreate(nsISupports *na
     return NS_ERROR_UNEXPECTED;
   }
   return SetParentToWindow(win, parentObj);
 }
 
 // DOM Node helper
 
 NS_IMETHODIMP
-nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj,
+nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *aGlobalObj,
                     JSObject **parentObj)
 {
+  JS::Rooted<JSObject*> globalObj(cx, aGlobalObj);
   nsINode *node = static_cast<nsINode*>(nativeObj);
 
 #ifdef DEBUG
   {
     nsCOMPtr<nsINode> node_qi(do_QueryInterface(nativeObj));
 
     // If this assertion fires the QI implementation for the object in
     // question doesn't use the nsINode pointer as the nsISupports
@@ -5567,19 +5571,20 @@ nsNodeSH::AddProperty(nsIXPConnectWrappe
                       JSObject *obj, jsid id, jsval *vp, bool *_retval)
 {
   nsNodeSH::PreserveWrapper(GetNative(wrapper, obj));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNodeSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                     JSObject *obj, jsid id, uint32_t flags,
+                     JSObject *aObj, jsid id, uint32_t flags,
                      JSObject **objp, bool *_retval)
 {
+  JS::Rooted<JSObject*> obj(cx, aObj);
   if (id == sOnload_id || id == sOnerror_id) {
     // Make sure that this node can't go away while waiting for a
     // network load that could fire an event handler.
     // XXXbz won't this fail if the listener is added using
     // addEventListener?  On the other hand, even if I comment this
     // code out I can't seem to reproduce the bug it was trying to
     // fix....
     nsNodeSH::PreserveWrapper(GetNative(wrapper, obj));
@@ -5865,18 +5870,18 @@ nsGenericArraySH::NewResolve(nsIXPConnec
 }
 
 nsresult
 nsGenericArraySH::GetLength(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                              JSObject *obj, uint32_t *length)
 {
   *length = 0;
 
-  jsval lenval;
-  if (!JS_GetProperty(cx, obj, "length", &lenval)) {
+  JS::Rooted<JS::Value> lenval(cx);
+  if (!JS_GetProperty(cx, obj, "length", lenval.address())) {
     return NS_ERROR_UNEXPECTED;
   }
 
   if (!JSVAL_IS_INT(lenval)) {
     // This can apparently happen with some sparse array impls falling back
     // onto this code.
     return NS_OK;
   }
@@ -5903,19 +5908,19 @@ nsGenericArraySH::Enumerate(nsIXPConnect
 
   if (sCurrentlyEnumerating) {
     // Don't recurse to death.
     return NS_OK;
   }
 
   sCurrentlyEnumerating = true;
 
-  jsval len_val;
+  JS::Rooted<JS::Value> len_val(cx);
   JSAutoRequest ar(cx);
-  JSBool ok = ::JS_GetProperty(cx, obj, "length", &len_val);
+  JSBool ok = ::JS_GetProperty(cx, obj, "length", len_val.address());
 
   if (ok && JSVAL_IS_INT(len_val)) {
     int32_t length = JSVAL_TO_INT(len_val);
 
     for (int32_t i = 0; ok && i < length; ++i) {
       ok = ::JS_DefineElement(cx, obj, i, JSVAL_VOID, nullptr, nullptr,
                               JSPROP_ENUMERATE | JSPROP_SHARED);
     }
@@ -5990,20 +5995,20 @@ NS_IMETHODIMP
 nsNamedArraySH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                            JSObject *obj, jsid id, uint32_t flags,
                            JSObject **objp, bool *_retval)
 {
   if ((!(JSRESOLVE_ASSIGNING & flags)) && JSID_IS_STRING(id) &&
       !ObjectIsNativeWrapper(cx, obj)) {
 
     {
-      JSObject *realObj;
+      JS::Rooted<JSObject*> realObj(cx);
 
       if (wrapper) {
-        wrapper->GetJSObject(&realObj);
+        wrapper->GetJSObject(realObj.address());
       } else {
         realObj = obj;
       }
 
       JSAutoCompartment ac(cx, realObj);
       JSObject *proto;
       if (!::JS_GetPrototype(cx, realObj, &proto)) {
         return NS_ERROR_FAILURE;
@@ -6087,21 +6092,21 @@ nsDocumentSH::NewResolve(nsIXPConnectWra
 
     nsCOMPtr<nsIDOMDocument> doc = do_QueryWrappedNative(wrapper, obj);
     NS_ENSURE_TRUE(doc, NS_ERROR_UNEXPECTED);
 
     nsCOMPtr<nsIDOMLocation> location;
     rv = doc->GetLocation(getter_AddRefs(location));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    jsval v;
+    JS::Rooted<JS::Value> v(cx);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = WrapNative(cx, JS_GetGlobalForScopeChain(cx), location,
-                    &NS_GET_IID(nsIDOMLocation), true, &v,
+                    &NS_GET_IID(nsIDOMLocation), true, v.address(),
                     getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     JSBool ok = ::JS_DefinePropertyById(cx, obj, id, v, JS_PropertyStub,
                                         LocationSetter<nsIDOMDocument>,
                                         JSPROP_PERMANENT | JSPROP_ENUMERATE);
 
     if (!ok) {
@@ -6142,21 +6147,21 @@ nsDocumentSH::PostCreate(nsIXPConnectWra
   if (!win) {
     // No window, nothing else to do here
     return NS_OK;
   }
 
   nsIDocument* currentDoc = win->GetExtantDoc();
 
   if (SameCOMIdentity(doc, currentDoc)) {
-    jsval winVal;
+    JS::Rooted<JS::Value> winVal(cx);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     nsresult rv = WrapNative(cx, obj, win, &NS_GET_IID(nsIDOMWindow), false,
-                             &winVal, getter_AddRefs(holder));
+                             winVal.address(), getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     NS_NAMED_LITERAL_STRING(doc_str, "document");
 
     if (!::JS_DefineUCProperty(cx, JSVAL_TO_OBJECT(winVal),
                                reinterpret_cast<const jschar *>
                                                (doc_str.get()),
                                doc_str.Length(), OBJECT_TO_JSVAL(obj),
@@ -6253,21 +6258,21 @@ nsHTMLDocumentSH::GetDocumentAllNodeList
   // The document.all object is a mix of the node list returned by
   // document.getElementsByTagName("*") and a map of elements in the
   // document exposed by their id and/or name. To make access to the
   // node list part (i.e. access to elements by index) not walk the
   // document each time, we create a nsContentList and hold on to it
   // in a reserved slot (0) on the document.all JSObject.
   nsresult rv = NS_OK;
 
-  jsval collection = JS_GetReservedSlot(obj, 0);
+  JS::Rooted<JS::Value> collection(cx, JS_GetReservedSlot(obj, 0));
 
   if (!JSVAL_IS_PRIMITIVE(collection)) {
     // We already have a node list in our reserved slot, use it.
-    JSObject *obj = JSVAL_TO_OBJECT(collection);
+    JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(collection));
     nsIHTMLCollection* htmlCollection;
     rv = mozilla::dom::UnwrapObject<nsIHTMLCollection>(cx, obj, htmlCollection);
     if (NS_SUCCEEDED(rv)) {
       NS_ADDREF(*nodeList = static_cast<nsContentList*>(htmlCollection));
     }
     else {
       nsISupports *native = sXPConnect->GetNativeOfWrapper(cx, obj);
       if (native) {
@@ -6285,17 +6290,17 @@ nsHTMLDocumentSH::GetDocumentAllNodeList
       domdoc->GetElementsByTagName(NS_LITERAL_STRING("*"));
     if (!list) {
       rv = NS_ERROR_OUT_OF_MEMORY;
     }
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     nsresult tmp = WrapNative(cx, JS_GetGlobalForScopeChain(cx),
                               static_cast<nsINodeList*>(list), list, false,
-                              &collection, getter_AddRefs(holder));
+                              collection.address(), getter_AddRefs(holder));
     if (NS_FAILED(tmp)) {
       rv = tmp;
     }
 
     list.forget(nodeList);
 
     // ... and store it in our reserved slot.
     JS_SetReservedSlot(obj, 0, collection);
@@ -6309,28 +6314,28 @@ nsHTMLDocumentSH::GetDocumentAllNodeList
 
   return *nodeList != nullptr;
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllGetProperty(JSContext *cx, JSHandleObject obj_,
                                          JSHandleId id, JSMutableHandleValue vp)
 {
-  JSObject *obj = obj_;
+  JS::Rooted<JSObject*> obj(cx, obj_);
 
   // document.all.item and .namedItem get their value in the
   // newResolve hook, so nothing to do for those properties here. And
   // we need to return early to prevent <div id="item"> from shadowing
   // document.all.item(), etc.
   if (sItem_id == id || sNamedItem_id == id) {
     return JS_TRUE;
   }
 
   while (js::GetObjectJSClass(obj) != &sHTMLDocumentAllClass) {
-    if (!js::GetObjectProto(cx, obj, &obj)) {
+    if (!js::GetObjectProto(cx, obj, obj.address())) {
       return JS_FALSE;
     }
 
     if (!obj) {
       NS_ERROR("The JS engine lies!");
 
       return JS_TRUE;
     }
@@ -6487,17 +6492,17 @@ nsHTMLDocumentSH::CallToGetPropMapper(JS
     // and create a new NS_ERROR_XPC_TOO_MANY_ARGS for argc > 1? IE
     // accepts nothing other than one arg.
     xpc::Throw(cx, NS_ERROR_INVALID_ARG);
 
     return JS_FALSE;
   }
 
   // Convert all types to string.
-  JSString *str = ::JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
+  JS::Rooted<JSString*> str(cx, ::JS_ValueToString(cx, JS_ARGV(cx, vp)[0]));
   if (!str) {
     return JS_FALSE;
   }
 
   // If we are called via document.all(id) instead of document.all.item(i) or
   // another method, use the document.all callee object as self.
   JSObject *self;
   JS::Value callee = JS_CALLEE(cx, vp);
@@ -6570,18 +6575,18 @@ nsHTMLDocumentSH::DocumentAllHelperGetPr
 
 JSBool
 nsHTMLDocumentSH::DocumentAllHelperNewResolve(JSContext *cx, JSHandleObject obj,
                                               JSHandleId id, unsigned flags,
                                               JS::MutableHandle<JSObject*> objp)
 {
   if (nsDOMClassInfo::sAll_id == id) {
     // document.all is resolved for the first time. Define it.
-    JSObject *helper;
-    if (!GetDocumentAllHelper(cx, obj, &helper)) {
+    JS::Rooted<JSObject*> helper(cx);
+    if (!GetDocumentAllHelper(cx, obj, helper.address())) {
       return JS_FALSE;
     }
 
     if (helper) {
       if (!::JS_DefineProperty(cx, helper, "all", JSVAL_VOID, nullptr, nullptr,
                                JSPROP_ENUMERATE)) {
         return JS_FALSE;
       }
@@ -6597,18 +6602,18 @@ nsHTMLDocumentSH::DocumentAllHelperNewRe
 JSBool
 nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSHandleObject obj,
                                             JSHandleId id, unsigned flags,
                                             JS::MutableHandle<JSObject*> objp)
 {
   if (JSID_IS_STRING(id)) {
     nsDocument *doc = GetDocument(obj);
 
-    JSObject *proto;
-    if (!::JS_GetPrototype(cx, obj, &proto)) {
+    JS::Rooted<JSObject*> proto(cx);
+    if (!::JS_GetPrototype(cx, obj, proto.address())) {
       return JS_FALSE;
     }
     if (MOZ_UNLIKELY(!proto)) {
       return JS_TRUE;
     }
 
     JSBool found;
     if (!::JS_HasPropertyById(cx, proto, id, &found)) {
@@ -6618,21 +6623,21 @@ nsHTMLDocumentSH::DocumentAllTagsNewReso
     if (found) {
       return JS_TRUE;
     }
 
     nsRefPtr<nsContentList> tags =
       doc->GetElementsByTagName(nsDependentJSString(id));
 
     if (tags) {
-      jsval v;
+      JS::Rooted<JS::Value> v(cx);
       nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
       nsresult rv = WrapNative(cx, JS_GetGlobalForScopeChain(cx),
                                static_cast<nsINodeList*>(tags), tags, true,
-                               &v, getter_AddRefs(holder));
+                               v.address(), getter_AddRefs(holder));
       if (NS_FAILED(rv)) {
         xpc::Throw(cx, rv);
 
         return JS_FALSE;
       }
 
       if (!::JS_DefinePropertyById(cx, obj, id, v, nullptr, nullptr, 0)) {
         return JS_FALSE;
@@ -6671,21 +6676,21 @@ ResolveAll(JSContext* cx, nsIDocument* d
   if (proto && !JS_HasProperty(cx, proto, "all", &hasAll)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   if (hasAll && helper) {
     // Our helper's prototype now has an "all" property, remove
     // the helper out of the prototype chain to prevent
     // shadowing of the now defined "all" property.
-    JSObject *tmp = obj, *tmpProto = tmp;
+    JS::Rooted<JSObject*> tmp(cx, obj), tmpProto(cx, tmp);
 
     do {
       tmp = tmpProto;
-      if (!::JS_GetPrototype(cx, tmp, &tmpProto)) {
+      if (!::JS_GetPrototype(cx, tmp, tmpProto.address())) {
         return NS_ERROR_UNEXPECTED;
       }
     } while (tmpProto != helper);
 
     ::JS_SetPrototype(cx, tmp, proto);
   }
 
   // If we don't already have a helper and "all" isn't already defined on
@@ -6770,19 +6775,20 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnec
     }
   }
 
   return nsDocumentSH::NewResolve(wrapper, cx, obj, id, flags, objp, _retval);
 }
 
 NS_IMETHODIMP
 nsHTMLDocumentSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
-                              JSContext *cx, JSObject *obj, jsid id,
+                              JSContext *cx, JSObject *aObj, jsid id,
                               jsval *vp, bool *_retval)
 {
+  JS::Rooted<JSObject*> obj(cx, aObj);
   nsCOMPtr<nsISupports> result;
 
   JSAutoRequest ar(cx);
 
   nsWrapperCache *cache;
   nsresult rv = ResolveImpl(cx, wrapper, id, getter_AddRefs(result), &cache);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -6796,20 +6802,21 @@ nsHTMLDocumentSH::GetProperty(nsIXPConne
 
   return NS_OK;
 }
 
 // HTMLFormElement helper
 
 NS_IMETHODIMP
 nsHTMLFormElementSH::NewResolve(nsIXPConnectWrappedNative *wrapper,
-                                JSContext *cx, JSObject *obj, jsid id,
+                                JSContext *cx, JSObject *aObj, jsid id,
                                 uint32_t flags, JSObject **objp,
                                 bool *_retval)
 {
+  JS::Rooted<JSObject*> obj(cx, aObj);
   // For native wrappers, do not resolve random names on form
   if ((!(JSRESOLVE_ASSIGNING & flags)) && JSID_IS_STRING(id) &&
       (!ObjectIsNativeWrapper(cx, obj) ||
        xpc::WrapperFactory::XrayWrapperNotShadowing(obj, id))) {
     nsCOMPtr<nsIForm> form(do_QueryWrappedNative(wrapper, obj));
 
     nsDependentJSString name(id);
     nsWrapperCache* cache;
@@ -7164,31 +7171,31 @@ NS_IMETHODIMP
 nsStorage2SH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                          JSObject *obj, jsid id, uint32_t flags,
                          JSObject **objp, bool *_retval)
 {
   if (ObjectIsNativeWrapper(cx, obj)) {
     return NS_OK;
   }
 
-  JSObject *realObj;
-  wrapper->GetJSObject(&realObj);
+  JS::Rooted<JSObject*> realObj(cx);
+  wrapper->GetJSObject(realObj.address());
 
   JSAutoCompartment ac(cx, realObj);
 
   // First check to see if the property is defined on our prototype,
   // after converting id to a string if it's an integer.
 
-  JSString *jsstr = IdToString(cx, id);
+  JS::Rooted<JSString*> jsstr(cx, IdToString(cx, id));
   if (!jsstr) {
     return NS_OK;
   }
 
-  JSObject *proto;
-  if (!::JS_GetPrototype(cx, realObj, &proto)) {
+  JS::Rooted<JSObject*> proto(cx);
+  if (!::JS_GetPrototype(cx, realObj, proto.address())) {
     return NS_ERROR_FAILURE;
   }
   JSBool hasProp;
 
   if (proto &&
       (::JS_HasPropertyById(cx, proto, id, &hasProp) &&
        hasProp)) {
     // We found the property we're resolving on the prototype,
@@ -7412,17 +7419,17 @@ nsDOMConstructorSH::NewResolve(nsIXPConn
   // For regular DOM constructors, we have our interface constants defined on
   // us by nsWindowSH::GlobalResolve. However, XrayWrappers can't see these
   // interface constants (as they look like expando properties) so we have to
   // specially resolve those constants here, but only for Xray wrappers.
   if (!ObjectIsNativeWrapper(cx, obj)) {
     return NS_OK;
   }
 
-  JSObject *nativePropsObj = xpc::XrayUtils::GetNativePropertiesObject(cx, obj);
+  JS::Rooted<JSObject*> nativePropsObj(cx, xpc::XrayUtils::GetNativePropertiesObject(cx, obj));
   nsDOMConstructor *wrapped =
     static_cast<nsDOMConstructor *>(wrapper->Native());
   nsresult rv = wrapped->ResolveInterfaceConstants(cx, nativePropsObj);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Now re-lookup the ID to see if we should report back that we resolved the
   // looked-for constant. Note that we don't have to worry about infinitely
   // recurring back here because the Xray wrapper's holder object doesn't call
@@ -7436,19 +7443,20 @@ nsDOMConstructorSH::NewResolve(nsIXPConn
   if (found) {
     *objp = obj;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMConstructorSH::Call(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
-                         JSObject *obj, uint32_t argc, jsval *argv, jsval *vp,
+                         JSObject *aObj, uint32_t argc, jsval *argv, jsval *vp,
                          bool *_retval)
 {
+  JS::Rooted<JSObject*> obj(cx, aObj);
   MOZ_ASSERT(obj);
 
   nsDOMConstructor *wrapped =
     static_cast<nsDOMConstructor *>(wrapper->Native());
 
 #ifdef DEBUG
   {
     nsCOMPtr<nsIDOMDOMConstructor> is_constructor =
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -370,18 +370,19 @@ public:
   NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
                          JSObject * obj, JSObject * *_retval);
 
   static JSBool GlobalScopePolluterNewResolve(JSContext *cx, JSHandleObject obj,
                                               JSHandleId id, unsigned flags,
                                               JS::MutableHandle<JSObject*> objp);
   static JSBool GlobalScopePolluterGetProperty(JSContext *cx, JSHandleObject obj,
                                                JSHandleId id, JSMutableHandleValue vp);
-  static JSBool InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj);
-  static nsresult InstallGlobalScopePolluter(JSContext *cx, JSObject *obj);
+  static JSBool InvalidateGlobalScopePolluter(JSContext *cx, JSObject* obj);
+  static nsresult InstallGlobalScopePolluter(JSContext *cx,
+                                             JS::Handle<JSObject*> obj);
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsWindowSH(aData);
   }
 };
 
 // Location scriptable helper
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2462,17 +2462,18 @@ nsGlobalWindow::SetNewDocument(nsIDocume
   // fixup above) we would end up holding the GSP alive (through
   // XPConnect's internal marking of wrapper prototypes) as long as
   // the inner window was around, and if the GSP had properties on
   // it that held an element alive we'd hold the document alive,
   // which could hold event handlers alive, which hold the context
   // alive etc.
 
   if ((!reUseInnerWindow || aDocument != oldDoc) && !aState) {
-    nsWindowSH::InstallGlobalScopePolluter(cx, newInnerWindow->mJSObject);
+    JS::Rooted<JSObject*> obj(cx, newInnerWindow->mJSObject);
+    nsWindowSH::InstallGlobalScopePolluter(cx, obj);
   }
 
   aDocument->SetScriptGlobalObject(newInnerWindow);
 
   if (!aState) {
     if (reUseInnerWindow) {
       if (newInnerWindow->mDoc != aDocument) {
         newInnerWindow->mDoc = aDocument;