Bug 868312: Root dom/workers r=bz
authorDavid Zbarsky <dzbarsky@gmail.com>
Thu, 09 May 2013 03:27:40 -0400
changeset 138124 22dffe8154e556c658bb58e01bec587870e573cf
parent 138123 5a5e13148f9da4739b5b29cdbf05097202256761
child 138125 83459f51f50095e2eaa864d8e355904f0cc7aa1c
push id3752
push userlsblakk@mozilla.com
push dateMon, 13 May 2013 17:21:10 +0000
treeherdermozilla-aurora@1580544aef0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs868312
milestone23.0a1
Bug 868312: Root dom/workers r=bz
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/IDBObjectStore.h
dom/ipc/StructuredCloneUtils.cpp
dom/workers/EventListenerManager.cpp
dom/workers/Events.cpp
dom/workers/Events.h
dom/workers/Location.cpp
dom/workers/Location.h
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
dom/workers/WorkerScope.cpp
dom/workers/XMLHttpRequest.cpp
dom/workers/XMLHttpRequest.h
js/src/jsapi.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -6621,17 +6621,17 @@ PostMessageReadStructuredClone(JSContext
   }
 
   return nullptr;
 }
 
 static JSBool
 PostMessageWriteStructuredClone(JSContext* cx,
                                 JSStructuredCloneWriter* writer,
-                                JSObject* obj,
+                                JS::Handle<JSObject*> obj,
                                 void *closure)
 {
   StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(closure);
   NS_ASSERTION(scInfo, "Must have scInfo!");
 
   nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative;
   nsContentUtils::XPConnect()->
     GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wrappedNative));
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -3418,17 +3418,17 @@ NS_DOMReadStructuredClone(JSContext* cx,
   // Don't know what this is. Bail.
   xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
   return nullptr;
 }
 
 JSBool
 NS_DOMWriteStructuredClone(JSContext* cx,
                            JSStructuredCloneWriter* writer,
-                           JSObject* obj,
+                           JS::Handle<JSObject*> obj,
                            void *closure)
 {
   ImageData* imageData;
   nsresult rv = UnwrapObject<ImageData>(cx, obj, imageData);
   if (NS_FAILED(rv)) {
     // Don't know what this is. Bail.
     xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
     return JS_FALSE;
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -321,13 +321,13 @@ nsresult NS_CreateJSRuntime(nsIScriptRun
 void NS_ScriptErrorReporter(JSContext *cx, const char *message, JSErrorReport *report);
 
 JSObject* NS_DOMReadStructuredClone(JSContext* cx,
                                     JSStructuredCloneReader* reader, uint32_t tag,
                                     uint32_t data, void* closure);
 
 JSBool NS_DOMWriteStructuredClone(JSContext* cx,
                                   JSStructuredCloneWriter* writer,
-                                  JSObject* obj, void *closure);
+                                  JS::Handle<JSObject*> obj, void *closure);
 
 void NS_DOMStructuredCloneError(JSContext* cx, uint32_t errorid);
 
 #endif /* nsJSEnvironment_h */
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -1456,17 +1456,17 @@ IDBObjectStore::StructuredCloneReadCallb
 
   return nullptr;
 }
 
 // static
 JSBool
 IDBObjectStore::StructuredCloneWriteCallback(JSContext* aCx,
                                              JSStructuredCloneWriter* aWriter,
-                                             JSObject* aObj,
+                                             JS::Handle<JSObject*> aObj,
                                              void* aClosure)
 {
   StructuredCloneWriteInfo* cloneWriteInfo =
     reinterpret_cast<StructuredCloneWriteInfo*>(aClosure);
 
   if (JS_GetClass(aObj) == &sDummyPropJSClass) {
     NS_ASSERTION(cloneWriteInfo->mOffsetToKeyProp == 0,
                  "We should not have been here before!");
--- a/dom/indexedDB/IDBObjectStore.h
+++ b/dom/indexedDB/IDBObjectStore.h
@@ -106,17 +106,17 @@ public:
   StructuredCloneReadCallback(JSContext* aCx,
                               JSStructuredCloneReader* aReader,
                               uint32_t aTag,
                               uint32_t aData,
                               void* aClosure);
   static JSBool
   StructuredCloneWriteCallback(JSContext* aCx,
                                JSStructuredCloneWriter* aWriter,
-                               JSObject* aObj,
+                               JS::Handle<JSObject*> aObj,
                                void* aClosure);
 
   static nsresult
   ConvertFileIdsToArray(const nsAString& aFileIds,
                         nsTArray<int64_t>& aResult);
 
   // Called only in the main process.
   static nsresult
--- a/dom/ipc/StructuredCloneUtils.cpp
+++ b/dom/ipc/StructuredCloneUtils.cpp
@@ -102,18 +102,18 @@ Read(JSContext* aCx, JSStructuredCloneRe
 
     return &wrappedBlob.toObject();
   }
 
   return NS_DOMReadStructuredClone(aCx, aReader, aTag, aData, nullptr);
 }
 
 JSBool
-Write(JSContext* aCx, JSStructuredCloneWriter* aWriter, JSObject* aObj,
-      void* aClosure)
+Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
+      JS::Handle<JSObject*> aObj, void* aClosure)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aClosure);
 
   StructuredCloneClosure* closure =
     static_cast<StructuredCloneClosure*>(aClosure);
 
   // See if this is a wrapped native.
--- a/dom/workers/EventListenerManager.cpp
+++ b/dom/workers/EventListenerManager.cpp
@@ -282,54 +282,55 @@ EventListenerManager::GetEventListener(c
     }
   }
 
   return NULL;
 }
 
 bool
 EventListenerManager::DispatchEvent(JSContext* aCx, const EventTarget& aTarget,
-                                    JSObject* aEvent, ErrorResult& aRv) const
+                                    JSObject* event, ErrorResult& aRv) const
 {
+  JS::Rooted<JSObject*> aEvent(aCx, event);
   using namespace mozilla::dom::workers::events;
 
   if (!IsSupportedEventClass(aEvent)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
-  jsval val;
-  if (!JS_GetProperty(aCx, aEvent, "target", &val)) {
+  JS::Rooted<JS::Value> val(aCx);
+  if (!JS_GetProperty(aCx, aEvent, "target", val.address())) {
     aRv.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
   if (!JSVAL_IS_NULL(val)) {
     // Already has a target, must be recursively dispatched. Throw.
     aRv.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
   if (mCollections.isEmpty()) {
     return false;
   }
 
-  JSString* eventType;
+  JS::Rooted<JSString*> eventType(aCx);
   JSBool eventIsTrusted;
 
-  if (!JS_GetProperty(aCx, aEvent, "type", &val) ||
+  if (!JS_GetProperty(aCx, aEvent, "type", val.address()) ||
       !(eventType = JS_ValueToString(aCx, val)) ||
       !(eventType = JS_InternJSString(aCx, eventType))) {
     aRv.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
   // We have already ensure that the event is one of our types of events so
   // there is no need to worry about this property being faked.
-  if (!JS_GetProperty(aCx, aEvent, "isTrusted", &val) ||
+  if (!JS_GetProperty(aCx, aEvent, "isTrusted", val.address()) ||
       !JS_ValueToBoolean(aCx, val, &eventIsTrusted)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
   ListenerCollection* collection =
     GetCollectionForType(mCollections, INTERNED_STRING_TO_JSID(aCx, eventType));
   if (!collection) {
@@ -377,42 +378,42 @@ EventListenerManager::DispatchEvent(JSCo
     }
 
     // If anything fails in here we want to report the exception and continue on
     // to the next listener rather than bailing out. If something fails and
     // does not set an exception then we bail out entirely as we've either run
     // out of memory or the operation callback has indicated that we should
     // stop running.
 
-    jsval listenerVal = listeners[index];
+    JS::Rooted<JS::Value> listenerVal(aCx, listeners[index]);
 
-    JSObject* listenerObj;
-    if (!JS_ValueToObject(aCx, listenerVal, &listenerObj)) {
+    JS::Rooted<JSObject*> listenerObj(aCx);
+    if (!JS_ValueToObject(aCx, listenerVal, listenerObj.address())) {
       if (!JS_ReportPendingException(aCx)) {
         aRv.Throw(NS_ERROR_FAILURE);
         return false;
       }
       continue;
     }
 
     static const char sHandleEventChars[] = "handleEvent";
 
-    JSObject* thisObj = aTarget.GetJSObject();
+    JS::Rooted<JSObject*> thisObj(aCx, aTarget.GetJSObject());
 
     JSBool hasHandleEvent;
     if (!JS_HasProperty(aCx, listenerObj, sHandleEventChars, &hasHandleEvent)) {
       if (!JS_ReportPendingException(aCx)) {
         aRv.Throw(NS_ERROR_FAILURE);
         return false;
       }
       continue;
     }
 
     if (hasHandleEvent) {
-      if (!JS_GetProperty(aCx, listenerObj, sHandleEventChars, &listenerVal)) {
+      if (!JS_GetProperty(aCx, listenerObj, sHandleEventChars, listenerVal.address())) {
         if (!JS_ReportPendingException(aCx)) {
           aRv.Throw(NS_ERROR_FAILURE);
           return false;
         }
         continue;
       }
 
       thisObj = listenerObj;
--- a/dom/workers/Events.cpp
+++ b/dom/workers/Events.cpp
@@ -82,18 +82,18 @@ public:
     if (proto && !JS_DefineProperties(aCx, proto, sStaticProperties)) {
       return NULL;
     }
 
     return proto;
   }
 
   static JSObject*
-  Create(JSContext* aCx, JSObject* aParent, JSString* aType, bool aBubbles,
-         bool aCancelable, bool aMainRuntime)
+  Create(JSContext* aCx, JS::Handle<JSObject*> aParent, JS::Handle<JSString*> aType,
+         bool aBubbles, bool aCancelable, bool aMainRuntime)
   {
     JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
 
     JSObject* obj = JS_NewObject(aCx, clasp, NULL, aParent);
     if (obj) {
       Event* priv = new Event();
       SetJSPrivateSafeish(obj, priv);
       InitEventCommon(obj, priv, aType, aBubbles, aCancelable, true);
@@ -406,17 +406,17 @@ public:
   {
     JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
 
     return JS_InitClass(aCx, aObj, aParentProto, clasp, Construct, 0,
                         sProperties, sFunctions, NULL, NULL);
   }
 
   static JSObject*
-  Create(JSContext* aCx, JSObject* aParent, JSAutoStructuredCloneBuffer& aData,
+  Create(JSContext* aCx, JS::Handle<JSObject*> aParent, JSAutoStructuredCloneBuffer& aData,
          nsTArray<nsCOMPtr<nsISupports> >& aClonedObjects, bool aMainRuntime)
   {
     JS::Rooted<JSString*> type(aCx, JS_InternString(aCx, "message"));
     if (!type) {
       return NULL;
     }
 
     JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
@@ -632,18 +632,18 @@ public:
   {
     JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
 
     return JS_InitClass(aCx, aObj, aParentProto, clasp, Construct, 0,
                         sProperties, sFunctions, NULL, NULL);
   }
 
   static JSObject*
-  Create(JSContext* aCx, JSObject* aParent, JSString* aMessage,
-         JSString* aFilename, uint32_t aLineNumber, bool aMainRuntime)
+  Create(JSContext* aCx, JS::Handle<JSObject*> aParent, JS::Handle<JSString*> aMessage,
+         JS::Handle<JSString*> aFilename, uint32_t aLineNumber, bool aMainRuntime)
   {
     JS::Rooted<JSString*> type(aCx, JS_InternString(aCx, "error"));
     if (!type) {
       return NULL;
     }
 
     JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
 
@@ -813,17 +813,17 @@ public:
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto)
   {
     return JS_InitClass(aCx, aObj, aParentProto, &sClass, Construct, 0,
                         sProperties, sFunctions, NULL, NULL);
   }
 
   static JSObject*
-  Create(JSContext* aCx, JSObject* aParent, JSString* aType,
+  Create(JSContext* aCx, JS::Handle<JSObject*> aParent, JSString* aType,
          bool aLengthComputable, double aLoaded, double aTotal)
   {
     JS::Rooted<JSString*> type(aCx, JS_InternJSString(aCx, aType));
     if (!type) {
       return NULL;
     }
 
     JS::Rooted<JSObject*> obj(aCx, JS_NewObject(aCx, &sClass, NULL, aParent));
@@ -919,17 +919,17 @@ private:
 
     aVp.set(JS_GetReservedSlot(aObj, slot));
     return true;
   }
 
   static JSBool
   InitProgressEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
-    JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
+    JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
     if (!obj) {
       return false;
     }
 
     ProgressEvent* event = GetInstancePrivate(aCx, obj, sFunctions[0].name);
     if (!event) {
       return false;
     }
@@ -1001,46 +1001,47 @@ InitClasses(JSContext* aCx, JS::Handle<J
   }
 
   return MessageEvent::InitClass(aCx, aGlobal, eventProto, aMainRuntime) &&
          ErrorEvent::InitClass(aCx, aGlobal, eventProto, aMainRuntime) &&
          ProgressEvent::InitClass(aCx, aGlobal, eventProto);
 }
 
 JSObject*
-CreateGenericEvent(JSContext* aCx, JSString* aType, bool aBubbles,
+CreateGenericEvent(JSContext* aCx, JS::Handle<JSString*> aType, bool aBubbles,
                    bool aCancelable, bool aMainRuntime)
 {
-  JSObject* global = JS_GetGlobalForScopeChain(aCx);
+  JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForScopeChain(aCx));
   return Event::Create(aCx, global, aType, aBubbles, aCancelable, aMainRuntime);
 }
 
 JSObject*
 CreateMessageEvent(JSContext* aCx, JSAutoStructuredCloneBuffer& aData,
                    nsTArray<nsCOMPtr<nsISupports> >& aClonedObjects,
                    bool aMainRuntime)
 {
-  JSObject* global = JS_GetGlobalForScopeChain(aCx);
+  JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForScopeChain(aCx));
   return MessageEvent::Create(aCx, global, aData, aClonedObjects, aMainRuntime);
 }
 
 JSObject*
-CreateErrorEvent(JSContext* aCx, JSString* aMessage, JSString* aFilename,
-                 uint32_t aLineNumber, bool aMainRuntime)
+CreateErrorEvent(JSContext* aCx, JS::Handle<JSString*> aMessage,
+                 JS::Handle<JSString*> aFilename, uint32_t aLineNumber,
+                 bool aMainRuntime)
 {
-  JSObject* global = JS_GetGlobalForScopeChain(aCx);
+  JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForScopeChain(aCx));
   return ErrorEvent::Create(aCx, global, aMessage, aFilename, aLineNumber,
                             aMainRuntime);
 }
 
 JSObject*
 CreateProgressEvent(JSContext* aCx, JSString* aType, bool aLengthComputable,
                     double aLoaded, double aTotal)
 {
-  JSObject* global = JS_GetGlobalForScopeChain(aCx);
+  JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForScopeChain(aCx));
   return ProgressEvent::Create(aCx, global, aType, aLengthComputable, aLoaded,
                                aTotal);
 }
 
 bool
 IsSupportedEventClass(JSObject* aEvent)
 {
   return Event::IsSupportedClass(aEvent);
@@ -1060,18 +1061,18 @@ EventWasCanceled(JSObject* aEvent)
 
 bool
 EventImmediatePropagationStopped(JSObject* aEvent)
 {
   return Event::ImmediatePropagationStopped(aEvent);
 }
 
 bool
-DispatchEventToTarget(JSContext* aCx, JSObject* aTarget, JSObject* aEvent,
-                      bool* aPreventDefaultCalled)
+DispatchEventToTarget(JSContext* aCx, JS::Handle<JSObject*> aTarget,
+                      JS::Handle<JSObject*> aEvent, bool* aPreventDefaultCalled)
 {
   static const char kFunctionName[] = "dispatchEvent";
   JSBool hasProperty;
   if (!JS_HasProperty(aCx, aTarget, kFunctionName, &hasProperty)) {
     return false;
   }
 
   JSBool preventDefaultCalled = false;
--- a/dom/workers/Events.h
+++ b/dom/workers/Events.h
@@ -13,26 +13,27 @@ class JSAutoStructuredCloneBuffer;
 BEGIN_WORKERS_NAMESPACE
 
 namespace events {
 
 bool
 InitClasses(JSContext* aCx, JS::Handle<JSObject*> aGlobal, bool aMainRuntime);
 
 JSObject*
-CreateGenericEvent(JSContext* aCx, JSString* aType, bool aBubbles,
+CreateGenericEvent(JSContext* aCx, JS::Handle<JSString*> aType, bool aBubbles,
                    bool aCancelable, bool aMainRuntime);
 
 JSObject*
 CreateMessageEvent(JSContext* aCx, JSAutoStructuredCloneBuffer& aData,
                    nsTArray<nsCOMPtr<nsISupports> >& aClonedObjects,
                    bool aMainRuntime);
 
 JSObject*
-CreateErrorEvent(JSContext* aCx, JSString* aMessage, JSString* aFilename,
+CreateErrorEvent(JSContext* aCx, JS::Handle<JSString*> aMessage,
+                 JS::Handle<JSString*> aFilename,
                  uint32_t aLineNumber, bool aMainRuntime);
 
 JSObject*
 CreateProgressEvent(JSContext* aCx, JSString* aType, bool aLengthComputable,
                     double aLoaded, double aTotal);
 
 bool
 IsSupportedEventClass(JSObject* aEvent);
@@ -42,16 +43,16 @@ SetEventTarget(JSObject* aEvent, JSObjec
 
 bool
 EventWasCanceled(JSObject* aEvent);
 
 bool
 EventImmediatePropagationStopped(JSObject* aEvent);
 
 bool
-DispatchEventToTarget(JSContext* aCx, JSObject* aTarget, JSObject* aEvent,
-                      bool* aPreventDefaultCalled);
+DispatchEventToTarget(JSContext* aCx, JS::Handle<JSObject*> aTarget,
+                      JS::Handle<JSObject*> aEvent, bool* aPreventDefaultCalled);
 
 } // namespace events
 
 END_WORKERS_NAMESPACE
 
 #endif // mozilla_dom_workers_events_h__
--- a/dom/workers/Location.cpp
+++ b/dom/workers/Location.cpp
@@ -40,19 +40,20 @@ public:
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj)
   {
     return JS_InitClass(aCx, aObj, NULL, &sClass, Construct, 0, sProperties,
                         sFunctions, NULL, NULL);
   }
 
   static JSObject*
-  Create(JSContext* aCx, JSString* aHref, JSString* aProtocol, JSString* aHost,
-         JSString* aHostname, JSString* aPort, JSString* aPathname,
-         JSString* aSearch, JSString* aHash)
+  Create(JSContext* aCx, JS::Handle<JSString*> aHref, JS::Handle<JSString*> aProtocol,
+         JS::Handle<JSString*> aHost, JS::Handle<JSString*> aHostname,
+         JS::Handle<JSString*> aPort, JS::Handle<JSString*> aPathname,
+         JS::Handle<JSString*> aSearch, JS::Handle<JSString*> aHash)
   {
     JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
     if (!obj) {
       return NULL;
     }
 
     jsval empty = JS_GetEmptyStringValue(aCx);
 
@@ -186,19 +187,21 @@ namespace location {
 
 bool
 InitClass(JSContext* aCx, JSObject* aGlobal)
 {
   return !!Location::InitClass(aCx, aGlobal);
 }
 
 JSObject*
-Create(JSContext* aCx, JSString* aHref, JSString* aProtocol, JSString* aHost,
-       JSString* aHostname, JSString* aPort, JSString* aPathname,
-       JSString* aSearch, JSString* aHash)
+Create(JSContext* aCx,
+       JS::Handle<JSString*> aHref, JS::Handle<JSString*> aProtocol,
+       JS::Handle<JSString*> aHost, JS::Handle<JSString*> aHostname,
+       JS::Handle<JSString*> aPort, JS::Handle<JSString*> aPathname,
+       JS::Handle<JSString*> aSearch, JS::Handle<JSString*> aHash)
 {
   return Location::Create(aCx, aHref, aProtocol, aHost, aHostname, aPort,
                           aPathname, aSearch, aHash);
 }
 
 } // namespace location
 
 END_WORKERS_NAMESPACE
--- a/dom/workers/Location.h
+++ b/dom/workers/Location.h
@@ -13,17 +13,18 @@
 BEGIN_WORKERS_NAMESPACE
 
 namespace location {
 
 bool
 InitClass(JSContext* aCx, JSObject* aGlobal);
 
 JSObject*
-Create(JSContext* aCx, JSString* aHref, JSString* aProtocol, JSString* aHost,
-       JSString* aHostname, JSString* aPort, JSString* aPathname,
-       JSString* aSearch, JSString* aHash);
+Create(JSContext* aCx, JS::Handle<JSString*> aHref, JS::Handle<JSString*> aProtocol,
+       JS::Handle<JSString*> aHost, JS::Handle<JSString*> aHostname,
+       JS::Handle<JSString*> aPort, JS::Handle<JSString*> aPathname,
+       JS::Handle<JSString*> aSearch, JS::Handle<JSString*> aHash);
 
 } // namespace location
 
 END_WORKERS_NAMESPACE
 
 #endif // mozilla_dom_workers_location_h__
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -209,18 +209,18 @@ struct WorkerStructuredCloneCallbacks
       return obj;
     }
 
     Error(aCx, 0);
     return nullptr;
   }
 
   static JSBool
-  Write(JSContext* aCx, JSStructuredCloneWriter* aWriter, JSObject* aObj,
-        void* aClosure)
+  Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
+        JS::Handle<JSObject*> aObj, void* aClosure)
   {
     NS_ASSERTION(aClosure, "Null pointer!");
 
     // We'll stash any nsISupports pointers that need to be AddRef'd here.
     nsTArray<nsCOMPtr<nsISupports> >* clonedObjects =
       static_cast<nsTArray<nsCOMPtr<nsISupports> >*>(aClosure);
 
     // See if this is a File object.
@@ -356,18 +356,18 @@ struct MainThreadWorkerStructuredCloneCa
       }
     }
 
     JS_ClearPendingException(aCx);
     return NS_DOMReadStructuredClone(aCx, aReader, aTag, aData, nullptr);
   }
 
   static JSBool
-  Write(JSContext* aCx, JSStructuredCloneWriter* aWriter, JSObject* aObj,
-        void* aClosure)
+  Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
+        JS::Handle<JSObject*> aObj, void* aClosure)
   {
     AssertIsOnMainThread();
 
     NS_ASSERTION(aClosure, "Null pointer!");
 
     // We'll stash any nsISupports pointers that need to be AddRef'd here.
     nsTArray<nsCOMPtr<nsISupports> >* clonedObjects =
       static_cast<nsTArray<nsCOMPtr<nsISupports> >*>(aClosure);
@@ -444,18 +444,18 @@ struct ChromeWorkerStructuredCloneCallba
   Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
        uint32_t aData, void* aClosure)
   {
     return WorkerStructuredCloneCallbacks::Read(aCx, aReader, aTag, aData,
                                                 aClosure);
   }
 
   static JSBool
-  Write(JSContext* aCx, JSStructuredCloneWriter* aWriter, JSObject* aObj,
-        void* aClosure)
+  Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
+        JS::Handle<JSObject*> aObj, void* aClosure)
   {
     return WorkerStructuredCloneCallbacks::Write(aCx, aWriter, aObj, aClosure);
   }
 
   static void
   Error(JSContext* aCx, uint32_t aErrorId)
   {
     return WorkerStructuredCloneCallbacks::Error(aCx, aErrorId);
@@ -490,18 +490,18 @@ struct MainThreadChromeWorkerStructuredC
       return clone;
     }
 
     JS_ClearPendingException(aCx);
     return NS_DOMReadStructuredClone(aCx, aReader, aTag, aData, nullptr);
   }
 
   static JSBool
-  Write(JSContext* aCx, JSStructuredCloneWriter* aWriter, JSObject* aObj,
-        void* aClosure)
+  Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
+        JS::Handle<JSObject*> aObj, void* aClosure)
   {
     AssertIsOnMainThread();
 
     if (MainThreadWorkerStructuredCloneCallbacks::Write(aCx, aWriter, aObj,
                                                         aClosure) ||
         ChromeWorkerStructuredCloneCallbacks::Write(aCx, aWriter, aObj,
                                                     aClosure) ||
         NS_DOMWriteStructuredClone(aCx, aWriter, aObj, nullptr)) {
@@ -719,22 +719,22 @@ public:
   bool
   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
   {
     JS::Rooted<JSObject*> target(aCx, JS_GetGlobalForScopeChain(aCx));
     NS_ASSERTION(target, "This must never be null!");
 
     aWorkerPrivate->CloseHandlerStarted();
 
-    JSString* type = JS_InternString(aCx, "close");
+    JS::Rooted<JSString*> type(aCx, JS_InternString(aCx, "close"));
     if (!type) {
       return false;
     }
 
-    JSObject* event = CreateGenericEvent(aCx, type, false, false, false);
+    JS::Rooted<JSObject*> event(aCx, CreateGenericEvent(aCx, type, false, false, false));
     if (!event) {
       return false;
     }
 
     bool ignored;
     return DispatchEventToTarget(aCx, target, event, &ignored);
   }
 
@@ -808,18 +808,18 @@ public:
       NS_ASSERTION(aWorkerPrivate == GetWorkerPrivateFromContext(aCx),
                    "Badness!");
       mainRuntime = false;
       target = JS_GetGlobalForScopeChain(aCx);
     }
 
     NS_ASSERTION(target, "This should never be null!");
 
-    JSObject* event =
-      CreateMessageEvent(aCx, buffer, mClonedObjects, mainRuntime);
+    JS::Rooted<JSObject*> event(aCx,
+      CreateMessageEvent(aCx, buffer, mClonedObjects, mainRuntime));
     if (!event) {
       return false;
     }
 
     bool dummy;
     return DispatchEventToTarget(aCx, target, event, &dummy);
   }
 
@@ -975,21 +975,22 @@ public:
   {
     // Notify before WorkerRunnable::PostRun, since that can kill aWorkerPrivate
     NotifyScriptExecutedIfNeeded();
     WorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult);
   }
 
   static bool
   ReportError(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
-              bool aFireAtScope, JSObject* aTarget, const nsString& aMessage,
+              bool aFireAtScope, JSObject* target, const nsString& aMessage,
               const nsString& aFilename, const nsString& aLine,
               uint32_t aLineNumber, uint32_t aColumnNumber, uint32_t aFlags,
               uint32_t aErrorNumber, uint64_t aInnerWindowId)
   {
+    JS::Rooted<JSObject*> aTarget(aCx, target);
     if (aWorkerPrivate) {
       aWorkerPrivate->AssertIsOnWorkerThread();
     }
     else {
       AssertIsOnMainThread();
     }
 
     JS::Rooted<JSString*> message(aCx, JS_NewUCStringCopyN(aCx, aMessage.get(),
@@ -1004,18 +1005,18 @@ public:
       return false;
     }
 
     // We should not fire error events for warnings but instead make sure that
     // they show up in the error console.
     if (!JSREPORT_IS_WARNING(aFlags)) {
       // First fire an ErrorEvent at the worker.
       if (aTarget) {
-        JSObject* event =
-          CreateErrorEvent(aCx, message, filename, aLineNumber, !aWorkerPrivate);
+        JS::Rooted<JSObject*> event(aCx,
+          CreateErrorEvent(aCx, message, filename, aLineNumber, !aWorkerPrivate));
         if (!event) {
           return false;
         }
 
         bool preventDefaultCalled;
         if (!DispatchEventToTarget(aCx, aTarget, event, &preventDefaultCalled)) {
           return false;
         }
@@ -1032,18 +1033,18 @@ public:
         NS_ASSERTION(aTarget, "This should never be null!");
 
         bool preventDefaultCalled;
         nsIScriptGlobalObject* sgo;
 
         if (aWorkerPrivate ||
             !(sgo = nsJSUtils::GetStaticScriptGlobal(aTarget))) {
           // Fire a normal ErrorEvent if we're running on a worker thread.
-          JSObject* event =
-            CreateErrorEvent(aCx, message, filename, aLineNumber, false);
+          JS::Rooted<JSObject*> event(aCx,
+            CreateErrorEvent(aCx, message, filename, aLineNumber, false));
           if (!event) {
             return false;
           }
 
           if (!DispatchEventToTarget(aCx, aTarget, event,
                                      &preventDefaultCalled)) {
             return false;
           }
@@ -1785,17 +1786,18 @@ private:
   }
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(WorkerPrivate::MemoryReporter,
                               nsIMemoryMultiReporter)
 
 template <class Derived>
 WorkerPrivateParent<Derived>::WorkerPrivateParent(
-                                     JSContext* aCx, JSObject* aObject,
+                                     JSContext* aCx,
+                                     JS::Handle<JSObject*> aObject,
                                      WorkerPrivate* aParent,
                                      JSContext* aParentJSContext,
                                      const nsAString& aScriptURL,
                                      bool aIsChromeWorker,
                                      const nsACString& aDomain,
                                      nsCOMPtr<nsPIDOMWindow>& aWindow,
                                      nsCOMPtr<nsIScriptContext>& aScriptContext,
                                      nsCOMPtr<nsIURI>& aBaseURI,
@@ -2375,17 +2377,17 @@ WorkerPrivateParent<Derived>::ParentJSCo
 
     NS_ASSERTION(mParentJSContext == mScriptContext->GetNativeContext(),
                  "Native context has changed!");
   }
 
   return mParentJSContext;
 }
 
-WorkerPrivate::WorkerPrivate(JSContext* aCx, JSObject* aObject,
+WorkerPrivate::WorkerPrivate(JSContext* aCx, JS::Handle<JSObject*> aObject,
                              WorkerPrivate* aParent,
                              JSContext* aParentJSContext,
                              const nsAString& aScriptURL, bool aIsChromeWorker,
                              const nsACString& aDomain,
                              nsCOMPtr<nsPIDOMWindow>& aWindow,
                              nsCOMPtr<nsIScriptContext>& aParentScriptContext,
                              nsCOMPtr<nsIURI>& aBaseURI,
                              nsCOMPtr<nsIPrincipal>& aPrincipal,
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -283,17 +283,17 @@ private:
   bool mParentSuspended;
   bool mIsChromeWorker;
   bool mPrincipalIsSystem;
   bool mMainThreadObjectsForgotten;
   bool mEvalAllowed;
   bool mReportCSPViolations;
 
 protected:
-  WorkerPrivateParent(JSContext* aCx, JSObject* aObject, WorkerPrivate* aParent,
+  WorkerPrivateParent(JSContext* aCx, JS::Handle<JSObject*> aObject, WorkerPrivate* aParent,
                       JSContext* aParentJSContext, const nsAString& aScriptURL,
                       bool aIsChromeWorker, const nsACString& aDomain,
                       nsCOMPtr<nsPIDOMWindow>& aWindow,
                       nsCOMPtr<nsIScriptContext>& aScriptContext,
                       nsCOMPtr<nsIURI>& aBaseURI,
                       nsCOMPtr<nsIPrincipal>& aPrincipal,
                       nsCOMPtr<nsIChannel>& aChannel,
                       nsCOMPtr<nsIContentSecurityPolicy>& aCSP,
@@ -891,17 +891,17 @@ public:
   EndCTypesCallback()
   {
     // If a callback is ending then we need to do the exact same thing as
     // when a ctypes call begins.
     BeginCTypesCall();
   }
 
 private:
-  WorkerPrivate(JSContext* aCx, JSObject* aObject, WorkerPrivate* aParent,
+  WorkerPrivate(JSContext* aCx, JS::Handle<JSObject*> aObject, WorkerPrivate* aParent,
                 JSContext* aParentJSContext, const nsAString& aScriptURL,
                 bool aIsChromeWorker, const nsACString& aDomain,
                 nsCOMPtr<nsPIDOMWindow>& aWindow,
                 nsCOMPtr<nsIScriptContext>& aScriptContext,
                 nsCOMPtr<nsIURI>& aBaseURI, nsCOMPtr<nsIPrincipal>& aPrincipal,
                 nsCOMPtr<nsIChannel>& aChannel,
                 nsCOMPtr<nsIContentSecurityPolicy>& aCSP, bool aEvalAllowed,
                 bool aReportCSPViolations, bool aXHRParamsAllowed);
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -223,18 +223,18 @@ private:
   {
     WorkerGlobalScope* scope =
       GetInstancePrivate(aCx, aObj, sProperties[SLOT_location].name);
     if (!scope) {
       return false;
     }
 
     if (JSVAL_IS_VOID(scope->mSlots[SLOT_location])) {
-      JSString* href, *protocol, *host, *hostname;
-      JSString* port, *pathname, *search, *hash;
+      JS::Rooted<JSString*> href(aCx), protocol(aCx), host(aCx), hostname(aCx);
+      JS::Rooted<JSString*> port(aCx), pathname(aCx), search(aCx), hash(aCx);
 
       WorkerPrivate::LocationInfo& info = scope->mWorker->GetLocationInfo();
 
 #define COPY_STRING(_jsstr, _cstr)                                             \
   if (info. _cstr .IsEmpty()) {                                                \
     _jsstr = NULL;                                                             \
   }                                                                            \
   else {                                                                       \
@@ -273,22 +273,22 @@ private:
   UnwrapErrorEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ASSERT(aArgc == 1);
     JS_ASSERT((JS_ARGV(aCx, aVp)[0]).isObject());
 
     JSObject* wrapper = &JS_CALLEE(aCx, aVp).toObject();
     JS_ASSERT(JS_ObjectIsFunction(aCx, wrapper));
 
-    jsval scope = js::GetFunctionNativeReserved(wrapper, SLOT_wrappedScope);
-    jsval listener = js::GetFunctionNativeReserved(wrapper, SLOT_wrappedFunction);
+    JS::Rooted<JS::Value> scope(aCx, js::GetFunctionNativeReserved(wrapper, SLOT_wrappedScope));
+    JS::Rooted<JS::Value> listener(aCx, js::GetFunctionNativeReserved(wrapper, SLOT_wrappedFunction));
 
     JS_ASSERT(scope.isObject());
 
-    JSObject* event = &JS_ARGV(aCx, aVp)[0].toObject();
+    JS::Rooted<JSObject*> event(aCx, &JS_ARGV(aCx, aVp)[0].toObject());
 
     jsval argv[3] = { JSVAL_VOID, JSVAL_VOID, JSVAL_VOID };
     if (!JS_GetProperty(aCx, event, "message", &argv[0]) ||
         !JS_GetProperty(aCx, event, "filename", &argv[1]) ||
         !JS_GetProperty(aCx, event, "lineno", &argv[2])) {
       return false;
     }
 
@@ -563,23 +563,23 @@ private:
     if (!obj) {
       return false;
     }
 
     if (!GetInstancePrivate(aCx, obj, sFunctions[7].name)) {
       return false;
     }
 
-    jsval string;
-    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", &string)) {
+    JS::Rooted<JS::Value> string(aCx);
+    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", string.address())) {
       return false;
     }
 
-    jsval result;
-    if (!xpc::Base64Decode(aCx, string, &result)) {
+    JS::Rooted<JS::Value> result(aCx);
+    if (!xpc::Base64Decode(aCx, string, result.address())) {
       return false;
     }
 
     JS_SET_RVAL(aCx, aVp, result);
     return true;
   }
 
   static JSBool
@@ -589,23 +589,23 @@ private:
     if (!obj) {
       return false;
     }
 
     if (!GetInstancePrivate(aCx, obj, sFunctions[8].name)) {
       return false;
     }
 
-    jsval binary;
-    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", &binary)) {
+    JS::Rooted<JS::Value> binary(aCx);
+    if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", binary.address())) {
       return false;
     }
 
-    jsval result;
-    if (!xpc::Base64Encode(aCx, binary, &result)) {
+    JS::Rooted<JS::Value> result(aCx);
+    if (!xpc::Base64Encode(aCx, binary, result.address())) {
       return false;
     }
 
     JS_SET_RVAL(aCx, aVp, result);
     return true;
   }
 };
 
@@ -980,18 +980,18 @@ CreateDedicatedWorkerGlobalScope(JSConte
   }
 
   // Proto chain should be:
   //   global -> DedicatedWorkerGlobalScope
   //          -> WorkerGlobalScope
   //          -> EventTarget
   //          -> Object
 
-  JSObject* eventTargetProto =
-    EventTargetBinding_workers::GetProtoObject(aCx, global);
+  JS::Rooted<JSObject*> eventTargetProto(aCx,
+    EventTargetBinding_workers::GetProtoObject(aCx, global));
   if (!eventTargetProto) {
     return NULL;
   }
 
   JSObject* scopeProto =
     WorkerGlobalScope::InitClass(aCx, global, eventTargetProto);
   if (!scopeProto) {
     return NULL;
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -714,33 +714,33 @@ public:
 
     XMLHttpRequest* xhr = mProxy->mXMLHttpRequestPrivate;
     xhr->UpdateState(state);
 
     if (mUploadEvent && !xhr->GetUploadObjectNoCreate()) {
       return true;
     }
 
-    JSString* type = JS_NewUCStringCopyN(aCx, mType.get(), mType.Length());
+    JS::Rooted<JSString*> type(aCx, JS_NewUCStringCopyN(aCx, mType.get(), mType.Length()));
     if (!type) {
       return false;
     }
 
-    JSObject* event = mProgressEvent ?
+    JS::Rooted<JSObject*> event(aCx, mProgressEvent ?
                       events::CreateProgressEvent(aCx, type, mLengthComputable,
                                                   mLoaded, mTotal) :
                       events::CreateGenericEvent(aCx, type, false, false,
-                                                 false);
+                                                 false));
     if (!event) {
       return false;
     }
 
-    JSObject* target = mUploadEvent ?
+    JS::Rooted<JSObject*> target(aCx, mUploadEvent ?
                        xhr->GetUploadObjectNoCreate()->GetJSObject() :
-                       xhr->GetJSObject();
+                       xhr->GetJSObject());
     MOZ_ASSERT(target);
 
     bool dummy;
     if (!events::DispatchEventToTarget(aCx, target, event, &dummy)) {
       JS_ReportPendingException(aCx);
     }
 
     // After firing the event set mResponse to JSVAL_NULL for chunked response
@@ -1528,34 +1528,34 @@ XMLHttpRequest::MaybeDispatchPrematureAb
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(mProxy);
 
   mStateData.mReadyState = 4;
 
   if (mProxy->mSeenUploadLoadStart) {
     MOZ_ASSERT(mUpload);
 
-    JSObject* target = mUpload->GetJSObject();
+    JS::Rooted<JSObject*> target(GetJSContext(), mUpload->GetJSObject());
     MOZ_ASSERT(target);
 
     DispatchPrematureAbortEvent(target, STRING_abort, true, aRv);
     if (aRv.Failed()) {
       return;
     }
 
     DispatchPrematureAbortEvent(target, STRING_loadend, true, aRv);
     if (aRv.Failed()) {
       return;
     }
 
     mProxy->mSeenUploadLoadStart = false;
   }
 
   if (mProxy->mSeenLoadStart) {
-    JSObject* target = GetJSObject();
+    JS::Rooted<JSObject*> target(GetJSContext(), GetJSObject());
     MOZ_ASSERT(target);
 
     DispatchPrematureAbortEvent(target, STRING_readystatechange, false, aRv);
     if (aRv.Failed()) {
       return;
     }
 
     DispatchPrematureAbortEvent(target, STRING_abort, false, aRv);
@@ -1568,39 +1568,39 @@ XMLHttpRequest::MaybeDispatchPrematureAb
       return;
     }
 
     mProxy->mSeenLoadStart = false;
   }
 }
 
 void
-XMLHttpRequest::DispatchPrematureAbortEvent(JSObject* aTarget,
+XMLHttpRequest::DispatchPrematureAbortEvent(JS::Handle<JSObject*> aTarget,
                                             uint8_t aEventType,
                                             bool aUploadTarget,
                                             ErrorResult& aRv)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(aTarget);
   MOZ_ASSERT(aEventType <= STRING_COUNT);
 
   if (!mProxy) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   JSContext* cx = GetJSContext();
 
-  JSString* type = JS_NewStringCopyZ(cx, sEventStrings[aEventType]);
+  JS::Rooted<JSString*> type(cx, JS_NewStringCopyZ(cx, sEventStrings[aEventType]));
   if (!type) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
-  JSObject* event;
+  JS::Rooted<JSObject*> event(cx);
   if (aEventType == STRING_readystatechange) {
     event = events::CreateGenericEvent(cx, type, false, false, false);
   }
   else if (aUploadTarget) {
     event = events::CreateProgressEvent(cx, type,
                                         mProxy->mLastUploadLengthComputable,
                                         mProxy->mLastUploadLoaded,
                                         mProxy->mLastUploadTotal);
--- a/dom/workers/XMLHttpRequest.h
+++ b/dom/workers/XMLHttpRequest.h
@@ -284,17 +284,17 @@ private:
 
   void
   MaybePin(ErrorResult& aRv);
 
   void
   MaybeDispatchPrematureAbortEvents(ErrorResult& aRv);
 
   void
-  DispatchPrematureAbortEvent(JSObject* aTarget, uint8_t aEventType,
+  DispatchPrematureAbortEvent(JS::Handle<JSObject*> aTarget, uint8_t aEventType,
                               bool aUploadTarget, ErrorResult& aRv);
 
   bool
   SendInProgress() const
   {
     return mJSObjectRooted;
   }
 
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1130,17 +1130,17 @@ typedef JSObject *(*ReadStructuredCloneO
  * the JS_WriteUint32Pair API to write an object header, passing a value
  * greater than JS_SCTAG_USER to the tag parameter. Then it can use the
  * JS_Write* APIs to write any other relevant parts of the value v to the
  * writer w. closure is any value passed to the JS_WriteStructuredCLone function.
  *
  * Return true on success, false on error/exception.
  */
 typedef JSBool (*WriteStructuredCloneOp)(JSContext *cx, JSStructuredCloneWriter *w,
-                                         JSObject *obj, void *closure);
+                                         JS::Handle<JSObject*> obj, void *closure);
 
 /*
  * This is called when JS_WriteStructuredClone is given an invalid transferable.
  * To follow HTML5, the application must throw a DATA_CLONE_ERR DOMException
  * with error set to one of the JS_SCERR_* values.
  */
 typedef void (*StructuredCloneErrorOp)(JSContext *cx, uint32_t errorid);