Bug 873735 part 2. Change nsIXPConnectJSObjectHolder::GetJSObject to return a JSObject*. r=bholley
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 20 May 2013 08:44:18 -0400
changeset 139515 908f7d92b2acf71556567dad0b7ad6351f6b7b2b
parent 139514 6bc3ac8a681e5644b986cf68cc7a9fd03b155ac1
child 139516 1caf7322f9189b287a2a7cf917ea332226cf846c
push id3911
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 20:17:26 +0000
treeherdermozilla-aurora@7e26ca8db92b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs873735
milestone24.0a1
Bug 873735 part 2. Change nsIXPConnectJSObjectHolder::GetJSObject to return a JSObject*. r=bholley
caps/src/nsScriptSecurityManager.cpp
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsInProcessTabChildGlobal.h
content/events/src/nsEventListenerService.cpp
content/xbl/src/nsXBLProtoImpl.cpp
content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/bindings/CallbackObject.h
dom/bindings/Codegen.py
dom/indexedDB/IDBFactory.cpp
dom/indexedDB/IDBKeyRange.cpp
dom/plugins/base/nsNPAPIPlugin.cpp
dom/src/jsurl/nsJSProtocolHandler.cpp
extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
ipc/testshell/XPCShellEnvironment.cpp
js/xpconnect/idl/nsIXPConnect.idl
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/XPCJSWeakReference.cpp
js/xpconnect/src/XPCThrower.cpp
js/xpconnect/src/XPCWrappedJS.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/xpcprivate.h
security/manager/ssl/src/nsCrypto.cpp
storage/src/mozStorageAsyncStatementJSHelper.cpp
storage/src/mozStorageStatementJSHelper.cpp
toolkit/components/places/PlaceInfo.cpp
xpfe/components/directory/nsDirectoryViewer.cpp
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -2289,18 +2289,18 @@ nsScriptSecurityManager::CheckXPCPermiss
         {
             nsresult rv;
             if (!jsObject)
             {
                 nsCOMPtr<nsIXPConnectWrappedJS> xpcwrappedjs =
                     do_QueryInterface(aObj);
                 if (xpcwrappedjs)
                 {
-                    rv = xpcwrappedjs->GetJSObject(jsObject.address());
-                    NS_ENSURE_SUCCESS(rv, rv);
+                    jsObject = xpcwrappedjs->GetJSObject();
+                    NS_ENSURE_STATE(jsObject);
                 }
             }
 
             if (!aSubjectPrincipal)
             {
                 // No subject principal passed in. Compute it.
                 aSubjectPrincipal = GetSubjectPrincipal(cx, &rv);
                 NS_ENSURE_SUCCESS(rv, rv);
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -641,18 +641,17 @@ nsFrameMessageManager::ReceiveMessage(ns
 
     for (uint32_t i = 0; i < mListeners.Length(); ++i) {
       if (mListeners[i].mMessage == name) {
         nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS =
           do_QueryInterface(mListeners[i].mListener);
         if (!wrappedJS) {
           continue;
         }
-        JS::Rooted<JSObject*> object(ctx);
-        wrappedJS->GetJSObject(object.address());
+        JS::Rooted<JSObject*> object(ctx, wrappedJS->GetJSObject());
         if (!object) {
           continue;
         }
         nsCxPusher pusher;
         pusher.Push(ctx);
 
         JSAutoRequest ar(ctx);
         JSAutoCompartment ac(ctx, object);
@@ -1004,18 +1003,17 @@ nsFrameScriptExecutor::LoadFrameScriptIn
 
   if (holder) {
     nsCxPusher pusher;
     pusher.Push(mCx);
     {
       // Need to scope JSAutoRequest to happen after Push but before Pop,
       // at least for now. See bug 584673.
       JSAutoRequest ar(mCx);
-      JS::Rooted<JSObject*> global(mCx);
-      mGlobal->GetJSObject(global.address());
+      JS::Rooted<JSObject*> global(mCx, mGlobal->GetJSObject());
       if (global) {
         (void) JS_ExecuteScript(mCx, global, holder->mScript, nullptr);
       }
     }
   }
 }
 
 void
@@ -1063,18 +1061,17 @@ nsFrameScriptExecutor::TryCacheLoadAndCo
 
   if (!dataString.IsEmpty()) {
     nsCxPusher pusher;
     pusher.Push(mCx);
     {
       // Need to scope JSAutoRequest to happen after Push but before Pop,
       // at least for now. See bug 584673.
       JSAutoRequest ar(mCx);
-      JS::Rooted<JSObject*> global(mCx);
-      mGlobal->GetJSObject(global.address());
+      JS::Rooted<JSObject*> global(mCx, mGlobal->GetJSObject());
       if (global) {
         JSAutoCompartment ac(mCx, global);
         JS::CompileOptions options(mCx);
         options.setNoScriptRval(true)
                .setFileAndLine(url.get(), 1)
                .setPrincipals(nsJSPrincipals::get(mPrincipal));
         JS::RootedObject empty(mCx, nullptr);
         JS::Rooted<JSScript*> script(mCx,
@@ -1133,19 +1130,18 @@ nsFrameScriptExecutor::InitTabChildGloba
   JS_SetContextPrivate(cx, aScope);
 
   nsresult rv =
     xpc->InitClassesWithNewWrappedGlobal(cx, aScope, mPrincipal,
                                          flags, JS::SystemZone, getter_AddRefs(mGlobal));
   NS_ENSURE_SUCCESS(rv, false);
 
 
-  JS::Rooted<JSObject*> global(cx);
-  rv = mGlobal->GetJSObject(global.address());
-  NS_ENSURE_SUCCESS(rv, false);
+  JS::Rooted<JSObject*> global(cx, mGlobal->GetJSObject());
+  NS_ENSURE_TRUE(global, false);
 
   JS_SetGlobalObject(cx, global);
 
   // Set the location information for the new global, so that tools like
   // about:memory may use that information.
   xpc::SetLocationForGlobal(global, aID);
 
   DidCreateCx();
--- a/content/base/src/nsInProcessTabChildGlobal.h
+++ b/content/base/src/nsInProcessTabChildGlobal.h
@@ -116,20 +116,17 @@ public:
 
   void DelayedDisconnect();
 
   virtual JSObject* GetGlobalJSObject() {
     if (!mGlobal) {
       return nullptr;
     }
 
-    JSObject* global;
-    mGlobal->GetJSObject(&global);
-
-    return global;
+    return mGlobal->GetJSObject();
   }
 protected:
   nsresult Init();
   nsresult InitTabChildGlobal();
   nsCOMPtr<nsIContentFrameMessageManager> mMessageManager;
   nsCOMPtr<nsIDocShell> mDocShell;
   bool mInitialized;
   bool mLoadingScript;
--- a/content/events/src/nsEventListenerService.cpp
+++ b/content/events/src/nsEventListenerService.cpp
@@ -79,18 +79,18 @@ NS_IMPL_ISUPPORTS1(nsEventListenerServic
 bool
 nsEventListenerInfo::GetJSVal(JSContext* aCx,
                               mozilla::Maybe<JSAutoCompartment>& aAc,
                               JS::Value* aJSVal)
 {
   *aJSVal = JSVAL_NULL;
   nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(mListener);
   if (wrappedJS) {
-    JS::Rooted<JSObject*> object(aCx, nullptr);
-    if (NS_FAILED(wrappedJS->GetJSObject(object.address()))) {
+    JS::Rooted<JSObject*> object(aCx, wrappedJS->GetJSObject());
+    if (!object) {
       return false;
     }
     aAc.construct(aCx, object);
     *aJSVal = OBJECT_TO_JSVAL(object);
     return true;
   }
 
   nsCOMPtr<nsIJSEventListener> jsl = do_QueryInterface(mListener);
--- a/content/xbl/src/nsXBLProtoImpl.cpp
+++ b/content/xbl/src/nsXBLProtoImpl.cpp
@@ -78,18 +78,18 @@ nsXBLProtoImpl::InstallImplementation(ns
 
   // Stash a strong reference to the JSClass in the binding.
   aBinding->SetJSClass(static_cast<nsXBLJSClass*>(JS_GetClass(targetClassObject)));
 
   // If the prototype already existed, we don't need to install anything. return early.
   if (!targetObjectIsNew)
     return NS_OK;
 
-  JS::Rooted<JSObject*> targetScriptObject(context->GetNativeContext());
-  holder->GetJSObject(targetScriptObject.address());
+  JS::Rooted<JSObject*> targetScriptObject(context->GetNativeContext(),
+                                           holder->GetJSObject());
 
   AutoPushJSContext cx(context->GetNativeContext());
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, targetClassObject);
   AutoVersionChecker avc(cx);
 
   // Walk our member list and install each one in turn.
   for (nsXBLProtoImplMember* curr = mMembers;
--- a/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
+++ b/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
@@ -1433,19 +1433,18 @@ txVariable::Convert(nsIVariant *aValue, 
 
             // Convert random JS Objects to a string.
             nsCOMPtr<nsIXPConnectJSObjectHolder> holder =
                 do_QueryInterface(supports);
             if (holder) {
                 JSContext* cx = nsContentUtils::GetCurrentJSContext();
                 NS_ENSURE_TRUE(cx, NS_ERROR_NOT_AVAILABLE);
 
-                JS::RootedObject jsobj(cx);
-                rv = holder->GetJSObject(jsobj.address());
-                NS_ENSURE_SUCCESS(rv, rv);
+                JS::RootedObject jsobj(cx, holder->GetJSObject());
+                NS_ENSURE_STATE(jsobj);
 
                 JS::RootedString str(cx, JS_ValueToString(cx, OBJECT_TO_JSVAL(jsobj)));
                 NS_ENSURE_TRUE(str, NS_ERROR_FAILURE);
 
                 nsDependentJSString value;
                 NS_ENSURE_TRUE(value.init(cx, str), NS_ERROR_FAILURE);
 
                 *aResult = new StringResult(value, nullptr);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -2644,18 +2644,18 @@ nsDOMClassInfo::CheckAccess(nsIXPConnect
 {
   JS::Rooted<jsid> id(cx, aId);
   uint32_t mode_type = mode & JSACC_TYPEMASK;
 
   if ((mode_type == JSACC_WATCH || mode_type == JSACC_PROTO) && sSecMan) {
     nsresult rv;
     JS::Rooted<JSObject*> real_obj(cx);
     if (wrapper) {
-      rv = wrapper->GetJSObject(real_obj.address());
-      NS_ENSURE_SUCCESS(rv, rv);
+      real_obj = wrapper->GetJSObject();
+      NS_ENSURE_STATE(real_obj);
     }
     else {
       real_obj = obj;
     }
 
     rv =
       sSecMan->CheckPropertyAccess(cx, real_obj, mData->mName, id,
                                    nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
@@ -3355,18 +3355,17 @@ BaseStubConstructor(nsIWeakReference* aW
     if (initializer) {
       rv = initializer->Initialize(currentInner, cx, obj, args);
       if (NS_FAILED(rv)) {
         return rv;
       }
     } else {
       nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(native);
 
-      JS::Rooted<JSObject*> thisObject(cx);
-      wrappedJS->GetJSObject(thisObject.address());
+      JS::Rooted<JSObject*> thisObject(cx, wrappedJS->GetJSObject());
       if (!thisObject) {
         return NS_ERROR_UNEXPECTED;
       }
 
       nsCxPusher pusher;
       pusher.Push(cx);
 
       JSAutoRequest ar(cx);
@@ -4101,18 +4100,17 @@ 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);
 
-  JS::Rooted<JSObject*> proto_obj(cx);
-  (*aProto)->GetJSObject(proto_obj.address());
+  JS::Rooted<JSObject*> proto_obj(cx, (*aProto)->GetJSObject());
   if (!JS_WrapObject(cx, proto_obj.address())) {
     return NS_ERROR_FAILURE;
   }
 
   NS_IF_RELEASE(*aProto);
   return aXPConnect->HoldObject(cx, proto_obj, aProto);
 }
 
@@ -4144,18 +4142,17 @@ ResolvePrototype(nsIXPConnect *aXPConnec
                   false, v.address(), getter_AddRefs(holder));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (install) {
     rv = constructor->Install(cx, obj, v);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  JS::Rooted<JSObject*> class_obj(cx);
-  holder->GetJSObject(class_obj.address());
+  JS::Rooted<JSObject*> class_obj(cx, holder->GetJSObject());
   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) {
@@ -4422,18 +4419,17 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
     JS::Rooted<JS::Value> v(cx);
     rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor),
                     false, v.address(), getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = constructor->Install(cx, obj, v);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    JS::Rooted<JSObject*> class_obj(cx);
-    holder->GetJSObject(class_obj.address());
+    JS::Rooted<JSObject*> class_obj(cx, holder->GetJSObject());
     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);
@@ -4451,19 +4447,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()) {
-      JS::Rooted<JSObject*> dot_prototype(cx);
-      rv = proto_holder->GetJSObject(dot_prototype.address());
-      NS_ENSURE_SUCCESS(rv, rv);
+      JS::Rooted<JSObject*> dot_prototype(cx, proto_holder->GetJSObject());
+      NS_ENSURE_STATE(dot_prototype);
 
       const nsDOMClassInfoData *ci_data;
       if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
         ci_data = &sClassInfoData[name_struct->mDOMClassInfoID];
       } else {
         ci_data = name_struct->mData;
       }
 
@@ -4493,19 +4488,18 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
     // We need to use the XPConnect prototype for the DOM class that this
     // constructor is an alias for (for example for Image we need the prototype
     // for HTMLImageElement).
     nsCOMPtr<nsIXPConnectJSObjectHolder> proto_holder;
     rv = GetXPCProto(sXPConnect, cx, aWin, alias_struct,
                      getter_AddRefs(proto_holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    JSObject* dot_prototype;
-    rv = proto_holder->GetJSObject(&dot_prototype);
-    NS_ENSURE_SUCCESS(rv, rv);
+    JSObject* dot_prototype = proto_holder->GetJSObject();
+    NS_ENSURE_STATE(dot_prototype);
 
     const nsDOMClassInfoData *ci_data;
     if (alias_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
       ci_data = &sClassInfoData[alias_struct->mDOMClassInfoID];
     } else if (alias_struct->mType == nsGlobalNameStruct::eTypeExternalClassInfo) {
       ci_data = alias_struct->mData;
     } else {
       return NS_ERROR_UNEXPECTED;
@@ -4527,19 +4521,17 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor),
                     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?");
+    NS_ASSERTION(holder->GetJSObject(), "Why didn't we get a JSObject?");
 
     *did_resolve = true;
 
     return NS_OK;
   }
 
   if (name_struct->mType == nsGlobalNameStruct::eTypeProperty) {
     if (name_struct->mChromeOnly && !nsContentUtils::IsCallerChrome())
@@ -4874,18 +4866,17 @@ 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.
-    JS::Rooted<JSObject*> scope(cx);
-    wrapper->GetJSObject(scope.address());
+    JS::Rooted<JSObject*> scope(cx, wrapper->GetJSObject());
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     JS::Rooted<JS::Value> v(cx);
     rv = WrapNative(cx, scope, location, &NS_GET_IID(nsIDOMLocation), true,
                     v.address(), getter_AddRefs(holder));
     NS_ENSURE_SUCCESS(rv, rv);
 
     JSBool ok = JS_WrapValue(cx, v.address()) &&
@@ -5058,18 +5049,17 @@ 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) {
-    JS::Rooted<JSObject*> realObj(cx);
-    wrapper->GetJSObject(realObj.address());
+    JS::Rooted<JSObject*> realObj(cx, wrapper->GetJSObject());
 
     if (obj == realObj) {
       JS::Rooted<JSObject*> proto(cx);
       if (!js::GetObjectProto(cx, obj, &proto)) {
           *_retval = JS_FALSE;
           return NS_OK;
       }
       if (proto) {
@@ -5904,23 +5894,17 @@ nsNamedArraySH::NewResolve(nsIXPConnectW
                            JSObject **objp, bool *_retval)
 {
   JS::Rooted<JSObject*> obj(cx, aObj);
   JS::Rooted<jsid> id(cx, aId);
   if ((!(JSRESOLVE_ASSIGNING & flags)) && JSID_IS_STRING(id) &&
       !ObjectIsNativeWrapper(cx, obj)) {
 
     {
-      JS::Rooted<JSObject*> realObj(cx);
-
-      if (wrapper) {
-        wrapper->GetJSObject(realObj.address());
-      } else {
-        realObj = obj;
-      }
+      JS::Rooted<JSObject*> realObj(cx, wrapper ? wrapper->GetJSObject() : obj);
 
       JSAutoCompartment ac(cx, realObj);
       JS::Rooted<JSObject*> proto(cx);
       if (!::JS_GetPrototype(cx, realObj, proto.address())) {
         return NS_ERROR_FAILURE;
       }
 
       if (proto) {
@@ -6900,18 +6884,17 @@ nsStorage2SH::NewResolve(nsIXPConnectWra
                          JSObject *obj, jsid aId, uint32_t flags,
                          JSObject **objp, bool *_retval)
 {
   JS::Rooted<jsid> id(cx, aId);
   if (ObjectIsNativeWrapper(cx, obj)) {
     return NS_OK;
   }
 
-  JS::Rooted<JSObject*> realObj(cx);
-  wrapper->GetJSObject(realObj.address());
+  JS::Rooted<JSObject*> realObj(cx, wrapper->GetJSObject());
 
   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.
 
   JS::Rooted<JSString*> jsstr(cx, IdToString(cx, id));
   if (!jsstr) {
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2125,17 +2125,17 @@ CreateNativeGlobalForInner(JSContext* aC
 
   nsRefPtr<nsIXPConnectJSObjectHolder> jsholder;
   nsresult rv = xpc->InitClassesWithNewWrappedGlobal(
     aCx, ToSupports(aNewInner),
     aPrincipal, flags, zoneSpec, getter_AddRefs(jsholder));
   NS_ENSURE_SUCCESS(rv, rv);
 
   MOZ_ASSERT(jsholder);
-  jsholder->GetJSObject(aNativeGlobal);
+  *aNativeGlobal = jsholder->GetJSObject();
   jsholder.forget(aHolder);
 
   // Set the location information for the new global, so that tools like
   // about:memory may use that information
   MOZ_ASSERT(*aNativeGlobal);
   xpc::SetLocationForGlobal(*aNativeGlobal, aURI);
 
   return NS_OK;
--- a/dom/bindings/CallbackObject.h
+++ b/dom/bindings/CallbackObject.h
@@ -338,18 +338,18 @@ public:
 
     nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(callback);
     if (!wrappedJS) {
       return nullptr;
     }
 
     AutoSafeJSContext cx;
 
-    JS::Rooted<JSObject*> obj(cx);
-    if (NS_FAILED(wrappedJS->GetJSObject(obj.address())) || !obj) {
+    JS::Rooted<JSObject*> obj(cx, wrappedJS->GetJSObject());
+    if (!obj) {
       return nullptr;
     }
 
     JSAutoCompartment ac(cx, obj);
 
     nsRefPtr<WebIDLCallbackT> newCallback = new WebIDLCallbackT(obj);
     return newCallback.forget();
   }
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -8992,17 +8992,18 @@ def genConstructorBody(descriptor, initC
     }
     // Extract the JS implementation from the XPCOM object.
     nsCOMPtr<nsIXPConnectWrappedJS> implWrapped = do_QueryInterface(implISupports);
     MOZ_ASSERT(implWrapped, "Failed to get wrapped JS from XPCOM component.");
     if (!implWrapped) {
       aRv.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
-    if (NS_FAILED(implWrapped->GetJSObject(jsImplObj.address()))) {
+    jsImplObj = implWrapped->GetJSObject();
+    if (!jsImplObj) {
       aRv.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
   }
   // Build the C++ implementation.
   nsRefPtr<${implClass}> impl = new ${implClass}(jsImplObj, window);${initCall}
   return impl.forget();""").substitute({"implClass" : descriptor.name,
                  "contractId" : descriptor.interface.getJSImplementation(),
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -213,19 +213,18 @@ IDBFactory::Create(ContentParent* aConte
 
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
   NS_ASSERTION(xpc, "This should never be null!");
 
   nsCOMPtr<nsIXPConnectJSObjectHolder> globalHolder;
   nsresult rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(globalHolder));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  JS::Rooted<JSObject*> global(cx);
-  rv = globalHolder->GetJSObject(global.address());
-  NS_ENSURE_SUCCESS(rv, rv);
+  JS::Rooted<JSObject*> global(cx, globalHolder->GetJSObject());
+  NS_ENSURE_STATE(global);
 
   // The CreateSandbox call returns a proxy to the actual sandbox object. We
   // don't need a proxy here.
   global = js::UncheckedUnwrap(global);
 
   JSAutoCompartment ac(cx, global);
 
   nsRefPtr<IDBFactory> factory;
--- a/dom/indexedDB/IDBKeyRange.cpp
+++ b/dom/indexedDB/IDBKeyRange.cpp
@@ -47,18 +47,18 @@ ReturnKeyRange(JSContext* aCx,
   nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
   if (NS_FAILED(xpc->WrapNative(aCx, global, aKeyRange,
                                 NS_GET_IID(nsIIDBKeyRange),
                                 getter_AddRefs(holder)))) {
     JS_ReportError(aCx, "Couldn't wrap IDBKeyRange object.");
     return false;
   }
 
-  JS::Rooted<JSObject*> result(aCx);
-  if (NS_FAILED(holder->GetJSObject(result.address()))) {
+  JS::Rooted<JSObject*> result(aCx, holder->GetJSObject());
+  if (!result) {
     JS_ReportError(aCx, "Couldn't get JSObject from wrapper.");
     return false;
   }
 
   JS_SET_RVAL(aCx, aVp, OBJECT_TO_JSVAL(result));
   return true;
 }
 
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -1240,18 +1240,17 @@ NPObject* NP_CALLBACK
   NS_ENSURE_TRUE(xpc, nullptr);
 
   nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
   xpc->WrapNative(cx, ::JS_GetGlobalObject(cx), element,
                   NS_GET_IID(nsIDOMElement),
                   getter_AddRefs(holder));
   NS_ENSURE_TRUE(holder, nullptr);
 
-  JS::Rooted<JSObject*> obj(cx);
-  holder->GetJSObject(obj.address());
+  JS::Rooted<JSObject*> obj(cx, holder->GetJSObject());
   NS_ENSURE_TRUE(obj, nullptr);
 
   return nsJSObjWrapper::GetNewOrUsed(npp, cx, obj);
 }
 
 NPIdentifier NP_CALLBACK
 _getstringidentifier(const NPUTF8* name)
 {
--- a/dom/src/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/src/jsurl/nsJSProtocolHandler.cpp
@@ -285,19 +285,18 @@ nsresult nsJSThunk::EvaluateScript(nsICh
         nsCOMPtr<nsIXPConnectJSObjectHolder> sandbox;
         rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(sandbox));
         NS_ENSURE_SUCCESS(rv, rv);
 
         // The nsXPConnect sandbox API gives us a wrapper to the sandbox for
         // our current compartment. Because our current context doesn't necessarily
         // subsume that of the sandbox, we want to unwrap and enter the sandbox's
         // compartment. It's a shame that the APIs here are so clunkly. :-(
-        JS::Rooted<JSObject*> sandboxObj(cx);
-        rv = sandbox->GetJSObject(sandboxObj.address());
-        NS_ENSURE_SUCCESS(rv, rv);
+        JS::Rooted<JSObject*> sandboxObj(cx, sandbox->GetJSObject());
+        NS_ENSURE_STATE(sandboxObj);
         sandboxObj = js::UncheckedUnwrap(sandboxObj);
         JSAutoCompartment ac(cx, sandboxObj);
 
         // Push our JSContext on the context stack so the JS_ValueToString call (and
         // JS_ReportPendingException, if relevant) will use the principal of cx.
         nsCxPusher pusher;
         pusher.Push(cx);
         rv = xpc->EvalInSandboxObject(NS_ConvertUTF8toUTF16(script),
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -52,18 +52,18 @@ nsresult CentralizedAdminPrefManagerInit
     // Create a sandbox.
     AutoSafeJSContext cx;
     JSAutoRequest ar(cx);
     nsCOMPtr<nsIXPConnectJSObjectHolder> sandbox;
     rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(sandbox));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Unwrap, store and root the sandbox.
-    rv = sandbox->GetJSObject(&autoconfigSb);
-    NS_ENSURE_SUCCESS(rv, rv);
+    autoconfigSb = sandbox->GetJSObject();
+    NS_ENSURE_STATE(autoconfigSb);
     autoconfigSb = js::UncheckedUnwrap(autoconfigSb);
     JSAutoCompartment ac(cx, autoconfigSb);
     if (!JS_AddNamedObjectRoot(cx, &autoconfigSb, "AutoConfig Sandbox"))
         return NS_ERROR_FAILURE;
 
     return NS_OK;
 }
 
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -1021,19 +1021,18 @@ XPCShellEnvironment::Init()
                                               principal, 0,
                                               JS::SystemZone,
                                               getter_AddRefs(holder));
     if (NS_FAILED(rv)) {
         NS_ERROR("InitClassesWithNewWrappedGlobal failed!");
         return false;
     }
 
-    JS::Rooted<JSObject*> globalObj(cx);
-    rv = holder->GetJSObject(globalObj.address());
-    if (NS_FAILED(rv)) {
+    JS::Rooted<JSObject*> globalObj(cx, holder->GetJSObject());
+    if (!globalObj) {
         NS_ERROR("Failed to get global JSObject!");
         return false;
     }
 
     backstagePass->SetGlobalObject(globalObj);
 
     {
         JSAutoRequest ar(cx);
--- a/js/xpconnect/idl/nsIXPConnect.idl
+++ b/js/xpconnect/idl/nsIXPConnect.idl
@@ -58,20 +58,20 @@ interface nsIXPCSecurityManager;
 interface nsIPrincipal;
 
 %{C++
 class nsCycleCollectionTraversalCallback;
 class nsScriptObjectTracer;
 %}
 
 /***************************************************************************/
-[uuid(8916a320-d118-11d3-8f3a-0010a4e73d9a)]
+[uuid(909e8641-7c54-4dff-9b94-ba631f057b33)]
 interface nsIXPConnectJSObjectHolder : nsISupports
 {
-    readonly attribute JSObjectPtr      JSObject;
+    [notxpcom, nostdcall] JSObjectPtr GetJSObject();
 };
 
 [uuid(92e98688-0154-4b65-971b-0d4afe8fd7cb)]
 interface nsIXPConnectWrappedNative : nsIXPConnectJSObjectHolder
 {
     /* attribute 'JSObject' inherited from nsIXPConnectJSObjectHolder */
     readonly attribute nsISupports      Native;
     readonly attribute JSObjectPtr      JSObjectPrototype;
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -541,50 +541,48 @@ mozJSComponentLoader::LoadModule(FileLoc
     nsCOMPtr<nsIComponentManager> cm;
     rv = NS_GetComponentManager(getter_AddRefs(cm));
     if (NS_FAILED(rv))
         return NULL;
 
     JSCLContextHelper cx(mContext);
     JSAutoCompartment ac(cx, entry->obj);
 
-    JSObject* cm_jsobj;
     nsCOMPtr<nsIXPConnectJSObjectHolder> cm_holder;
     rv = xpc->WrapNative(cx, entry->obj, cm,
                          NS_GET_IID(nsIComponentManager),
                          getter_AddRefs(cm_holder));
 
     if (NS_FAILED(rv)) {
 #ifdef DEBUG_shaver
         fprintf(stderr, "WrapNative(%p,%p,nsIComponentManager) failed: %x\n",
                 (void *)(JSContext*)cx, (void *)mCompMgr, rv);
 #endif
         return NULL;
     }
 
-    rv = cm_holder->GetJSObject(&cm_jsobj);
-    if (NS_FAILED(rv)) {
+    JSObject* cm_jsobj = cm_holder->GetJSObject();
+    if (!cm_jsobj) {
 #ifdef DEBUG_shaver
         fprintf(stderr, "GetJSObject of ComponentManager failed\n");
 #endif
         return NULL;
     }
 
-    JSObject* file_jsobj;
     nsCOMPtr<nsIXPConnectJSObjectHolder> file_holder;
     rv = xpc->WrapNative(cx, entry->obj, file,
                          NS_GET_IID(nsIFile),
                          getter_AddRefs(file_holder));
 
     if (NS_FAILED(rv)) {
         return NULL;
     }
 
-    rv = file_holder->GetJSObject(&file_jsobj);
-    if (NS_FAILED(rv)) {
+    JSObject* file_jsobj = file_holder->GetJSObject();
+    if (!file_jsobj) {
         return NULL;
     }
 
     JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter);
 
     RootedValue NSGetFactory_val(cx);
     if (!JS_GetProperty(cx, entry->obj, "NSGetFactory", NSGetFactory_val.address()) ||
         JSVAL_IS_VOID(NSGetFactory_val)) {
@@ -657,17 +655,17 @@ mozJSComponentLoader::FindTargetObject(J
         nsAXPCNativeCallContext *cc = nullptr;
         rv = xpc->GetCurrentNativeCallContext(&cc);
         NS_ENSURE_SUCCESS(rv, rv);
 
         nsCOMPtr<nsIXPConnectWrappedNative> wn;
         rv = cc->GetCalleeWrapper(getter_AddRefs(wn));
         NS_ENSURE_SUCCESS(rv, rv);
 
-        wn->GetJSObject(targetObject.address());
+        targetObject = wn->GetJSObject();
         if (!targetObject) {
             NS_ERROR("null calling object");
             return NS_ERROR_FAILURE;
         }
 
         targetObject = JS_GetGlobalForObject(aCx, targetObject);
     }
 
@@ -740,36 +738,34 @@ mozJSComponentLoader::PrepareObjectForLo
         rv = xpc->InitClassesWithNewWrappedGlobal(aCx,
                                                   static_cast<nsIGlobalObject *>(backstagePass),
                                                   mSystemPrincipal,
                                                   0,
                                                   JS::SystemZone,
                                                   getter_AddRefs(holder));
         NS_ENSURE_SUCCESS(rv, nullptr);
 
-        RootedObject global(aCx);
-        rv = holder->GetJSObject(global.address());
-        NS_ENSURE_SUCCESS(rv, nullptr);
+        RootedObject global(aCx, holder->GetJSObject());
+        NS_ENSURE_TRUE(global, nullptr);
 
         backstagePass->SetGlobalObject(global);
 
         JSAutoCompartment ac(aCx, global);
         if (!JS_DefineFunctions(aCx, global, gGlobalFun) ||
             !JS_DefineProfilingFunctions(aCx, global)) {
             return nullptr;
         }
 
         if (aReuseLoaderGlobal) {
             mLoaderGlobal = holder;
         }
     }
 
-    RootedObject obj(aCx);
-    rv = holder->GetJSObject(obj.address());
-    NS_ENSURE_SUCCESS(rv, nullptr);
+    RootedObject obj(aCx, holder->GetJSObject());
+    NS_ENSURE_TRUE(obj, nullptr);
 
     JSAutoCompartment ac(aCx, obj);
 
     if (aReuseLoaderGlobal) {
         // If we're reusing the loader global, we don't actually use the
         // global, but rather we use a different object as the 'this' object.
         obj = JS_NewObject(aCx, &kFakeBackstagePassJSClass, nullptr, nullptr);
         NS_ENSURE_TRUE(obj, nullptr);
@@ -790,19 +786,18 @@ mozJSComponentLoader::PrepareObjectForLo
         *aRealFile = true;
 
         nsCOMPtr<nsIXPConnectJSObjectHolder> locationHolder;
         rv = xpc->WrapNative(aCx, obj, aComponentFile,
                              NS_GET_IID(nsIFile),
                              getter_AddRefs(locationHolder));
         NS_ENSURE_SUCCESS(rv, nullptr);
 
-        RootedObject locationObj(aCx);
-        rv = locationHolder->GetJSObject(locationObj.address());
-        NS_ENSURE_SUCCESS(rv, nullptr);
+        RootedObject locationObj(aCx, locationHolder->GetJSObject());
+        NS_ENSURE_TRUE(locationObj, nullptr);
 
         if (!JS_DefineProperty(aCx, obj, "__LOCATION__",
                                JS::ObjectValue(*locationObj),
                                nullptr, nullptr, 0)) {
             return nullptr;
         }
     }
 
@@ -1135,18 +1130,18 @@ mozJSComponentLoader::ClearModules(const
 void
 mozJSComponentLoader::UnloadModules()
 {
     mInitialized = false;
 
     if (mLoaderGlobal) {
         MOZ_ASSERT(mReuseLoaderGlobal, "How did this happen?");
 
-        RootedObject global(mContext);
-        if (NS_SUCCEEDED(mLoaderGlobal->GetJSObject(global.address()))) {
+        RootedObject global(mContext, mLoaderGlobal->GetJSObject());
+        if (global) {
             JSAutoRequest ar(mContext);
             JS_SetAllNonReservedSlotsToUndefined(mContext, global);
         } else {
             NS_WARNING("Going to leak!");
         }
 
         mLoaderGlobal = nullptr;
     }
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -199,30 +199,29 @@ GetLocationProperty(JSContext *cx, JSHan
             absolutePath.Append(filenameString);
 
             rv = NS_NewLocalFile(absolutePath,
                                  false, getter_AddRefs(location));
         }
 
         if (location) {
             nsCOMPtr<nsIXPConnectJSObjectHolder> locationHolder;
-            JS::Rooted<JSObject*> locationObj(cx, nullptr);
 
             bool symlink;
             // don't normalize symlinks, because that's kind of confusing
             if (NS_SUCCEEDED(location->IsSymlink(&symlink)) &&
                 !symlink)
                 location->Normalize();
             rv = xpc->WrapNative(cx, obj, location,
                                  NS_GET_IID(nsIFile),
                                  getter_AddRefs(locationHolder));
 
             if (NS_SUCCEEDED(rv) &&
-                NS_SUCCEEDED(locationHolder->GetJSObject(locationObj.address()))) {
-                vp.set(OBJECT_TO_JSVAL(locationObj));
+                locationHolder->GetJSObject()) {
+                vp.set(OBJECT_TO_JSVAL(locationHolder->GetJSObject()));
             }
         }
     }
 
     return true;
 #endif
 }
 
@@ -1687,17 +1686,16 @@ static JSSecurityCallbacks shellSecurity
 int
 main(int argc, char **argv, char **envp)
 {
 #ifdef XP_MACOSX
     InitAutoreleasePool();
 #endif
     JSRuntime *rt;
     JSContext *cx;
-    JSObject *glob, *envobj;
     int result;
     nsresult rv;
 
 #ifdef HAVE_SETBUF
     // unbuffer stdout so that output is in the correct order; note that stderr
     // is unbuffered by default
     setbuf(stdout, 0);
 #endif
@@ -1815,16 +1813,19 @@ main(int argc, char **argv, char **envp)
         gOldJSContextCallback = JS_SetContextCallback(rt, ContextCallback);
 
         cx = JS_NewContext(rt, 8192);
         if (!cx) {
             printf("JS_NewContext failed!\n");
             return 1;
         }
 
+        JS::Rooted<JSObject*> glob(cx);
+        JS::Rooted<JSObject*> envobj(cx);
+
         argc--;
         argv++;
         ProcessArgsForCompartment(cx, argv, argc);
 
         nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
         if (!xpc) {
             printf("failed to get nsXPConnect service!\n");
             return 1;
@@ -1888,19 +1889,18 @@ main(int argc, char **argv, char **envp)
                                                   static_cast<nsIGlobalObject *>(backstagePass),
                                                   systemprincipal,
                                                   0,
                                                   JS::SystemZone,
                                                   getter_AddRefs(holder));
         if (NS_FAILED(rv))
             return 1;
 
-        rv = holder->GetJSObject(&glob);
-        if (NS_FAILED(rv)) {
-            NS_ASSERTION(glob == nullptr, "bad GetJSObject?");
+        glob = holder->GetJSObject();
+        if (!glob) {
             return 1;
         }
 
         backstagePass->SetGlobalObject(glob);
 
         JS_BeginRequest(cx);
         {
             JSAutoCompartment ac(cx, glob);
@@ -1926,18 +1926,17 @@ main(int argc, char **argv, char **envp)
 
             nsAutoString workingDirectory;
             if (GetCurrentWorkingDirectory(workingDirectory))
                 gWorkingDirectory = &workingDirectory;
 
             JS_DefineProperty(cx, glob, "__LOCATION__", JSVAL_VOID,
                               GetLocationProperty, NULL, 0);
 
-            JS::Rooted<JSObject*> rootedGlob(cx, glob);
-            result = ProcessArgs(cx, rootedGlob, argv, argc, &dirprovider);
+            result = ProcessArgs(cx, glob, argv, argc, &dirprovider);
 
             JS_DropPrincipals(rt, gJSPrincipals);
             JS_SetAllNonReservedSlotsToUndefined(cx, glob);
             JS_GC(rt);
             xpc::danger::PopJSContext();
             JS_GC(rt);
         } //this scopes the JSAutoCrossCompartmentCall
         JS_EndRequest(cx);
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -328,17 +328,19 @@ nsXPCComponents_Interfaces::NewResolve(n
             wrapper->GetXPConnect(getter_AddRefs(xpc));
             if (xpc) {
                 nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
                 if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                                  static_cast<nsIJSIID*>(nsid),
                                                  NS_GET_IID(nsIJSIID),
                                                  getter_AddRefs(holder)))) {
                     RootedObject idobj(cx);
-                    if (holder && NS_SUCCEEDED(holder->GetJSObject(idobj.address()))) {
+                    if (holder &&
+                        // Assign, not compare
+                        (idobj = holder->GetJSObject())) {
                         *objp = obj;
                         *_retval = JS_DefinePropertyById(cx, obj, id,
                                                          OBJECT_TO_JSVAL(idobj),
                                                          nullptr, nullptr,
                                                          JSPROP_ENUMERATE |
                                                          JSPROP_READONLY |
                                                          JSPROP_PERMANENT);
                     }
@@ -618,17 +620,19 @@ nsXPCComponents_InterfacesByID::NewResol
         wrapper->GetXPConnect(getter_AddRefs(xpc));
         if (xpc) {
             nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
             if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                              static_cast<nsIJSIID*>(nsid),
                                              NS_GET_IID(nsIJSIID),
                                              getter_AddRefs(holder)))) {
                 RootedObject idobj(cx);
-                if (holder && NS_SUCCEEDED(holder->GetJSObject(idobj.address()))) {
+                if (holder &&
+                    // Assign, not compare
+                    (idobj = holder->GetJSObject())) {
                     *objp = obj;
                     *_retval =
                         JS_DefinePropertyById(cx, obj, id,
                                               OBJECT_TO_JSVAL(idobj),
                                               nullptr, nullptr,
                                               JSPROP_ENUMERATE |
                                               JSPROP_READONLY |
                                               JSPROP_PERMANENT);
@@ -898,17 +902,19 @@ nsXPCComponents_Classes::NewResolve(nsIX
             wrapper->GetXPConnect(getter_AddRefs(xpc));
             if (xpc) {
                 nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
                 if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                                  static_cast<nsIJSCID*>(nsid),
                                                  NS_GET_IID(nsIJSCID),
                                                  getter_AddRefs(holder)))) {
                     RootedObject idobj(cx);
-                    if (holder && NS_SUCCEEDED(holder->GetJSObject(idobj.address()))) {
+                    if (holder &&
+                        // Assign, not compare
+                        (idobj = holder->GetJSObject())) {
                         *objp = obj;
                         *_retval = JS_DefinePropertyById(cx, obj, id,
                                                          OBJECT_TO_JSVAL(idobj),
                                                          nullptr, nullptr,
                                                          JSPROP_ENUMERATE |
                                                          JSPROP_READONLY |
                                                          JSPROP_PERMANENT);
                     }
@@ -1160,17 +1166,19 @@ nsXPCComponents_ClassesByID::NewResolve(
             wrapper->GetXPConnect(getter_AddRefs(xpc));
             if (xpc) {
                 nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
                 if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
                                                  static_cast<nsIJSCID*>(nsid),
                                                  NS_GET_IID(nsIJSCID),
                                                  getter_AddRefs(holder)))) {
                     RootedObject idobj(cx);
-                    if (holder && NS_SUCCEEDED(holder->GetJSObject(idobj.address()))) {
+                    if (holder &&
+                        // Assign, not compare
+                        (idobj = holder->GetJSObject())) {
                         *objp = obj;
                         *_retval = JS_DefinePropertyById(cx, obj, id,
                                                          ObjectValue(*idobj),
                                                          nullptr, nullptr,
                                                          JSPROP_ENUMERATE |
                                                          JSPROP_READONLY |
                                                          JSPROP_PERMANENT);
                     }
@@ -1974,17 +1982,18 @@ nsXPCComponents_Exception::CallOrConstru
     if (!e)
         return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     RootedObject newObj(cx);
 
     if (NS_FAILED(xpc->WrapNative(cx, obj, e, NS_GET_IID(nsIXPCException),
                                   getter_AddRefs(holder))) || !holder ||
-        NS_FAILED(holder->GetJSObject(newObj.address())) || !newObj) {
+        // Assign, not compare
+        !(newObj = holder->GetJSObject())) {
         return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
     }
 
     args.rval().setObject(*newObj);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
@@ -2231,20 +2240,22 @@ nsXPCConstructor::CallOrConstruct(nsIXPC
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> cidHolder;
     nsCOMPtr<nsIXPConnectJSObjectHolder> iidHolder;
     RootedObject cidObj(cx);
     RootedObject iidObj(cx);
 
     if (NS_FAILED(xpc->WrapNative(cx, obj, mClassID, NS_GET_IID(nsIJSCID),
                                   getter_AddRefs(cidHolder))) || !cidHolder ||
-        NS_FAILED(cidHolder->GetJSObject(cidObj.address())) || !cidObj ||
+        // Assign, not compare
+        !(cidObj = cidHolder->GetJSObject()) ||
         NS_FAILED(xpc->WrapNative(cx, obj, mInterfaceID, NS_GET_IID(nsIJSIID),
                                   getter_AddRefs(iidHolder))) || !iidHolder ||
-        NS_FAILED(iidHolder->GetJSObject(iidObj.address())) || !iidObj) {
+        // Assign, not compare
+        !(iidObj = iidHolder->GetJSObject())) {
         return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
     }
 
     Value argv[1] = {ObjectValue(*iidObj)};
     RootedValue rval(cx);
     if (!JS_CallFunctionName(cx, cidObj, "createInstance", 1, argv, rval.address()) ||
         rval.isPrimitive()) {
         // createInstance will have thrown an exception
@@ -2498,17 +2509,18 @@ nsXPCComponents_Constructor::CallOrConst
         // we do the lookup by asking the Components.interfaces object
         // for the property with this name - i.e. we let its caching of these
         // nsIJSIID objects work for us.
 
         if (NS_FAILED(comp->GetInterfaces(getter_AddRefs(ifaces))) ||
             NS_FAILED(xpc->WrapNative(cx, obj, ifaces,
                                       NS_GET_IID(nsIXPCComponents_Interfaces),
                                       getter_AddRefs(holder))) || !holder ||
-            NS_FAILED(holder->GetJSObject(ifacesObj.address())) || !ifacesObj) {
+            // Assign, not compare
+            !(ifacesObj = holder->GetJSObject())) {
             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
         }
 
         RootedString str(cx, JS_ValueToString(cx, args[1]));
         RootedId id(cx);
         if (!str || !JS_ValueToId(cx, StringValue(str), id.address()))
             return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
 
@@ -2546,17 +2558,18 @@ nsXPCComponents_Constructor::CallOrConst
         nsCOMPtr<nsIXPCComponents_Classes> classes;
         nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
         RootedObject classesObj(cx);
 
         if (NS_FAILED(comp->GetClasses(getter_AddRefs(classes))) ||
             NS_FAILED(xpc->WrapNative(cx, obj, classes,
                                       NS_GET_IID(nsIXPCComponents_Classes),
                                       getter_AddRefs(holder))) || !holder ||
-            NS_FAILED(holder->GetJSObject(classesObj.address())) || !classesObj) {
+            // Assign, not compare
+            !(classesObj = holder->GetJSObject())) {
             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
         }
 
         RootedString str(cx, JS_ValueToString(cx, args[0]));
         RootedId id(cx);
         if (!str || !JS_ValueToId(cx, StringValue(str), id.address()))
             return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
 
@@ -2578,17 +2591,18 @@ nsXPCComponents_Constructor::CallOrConst
     if (!ctor)
         return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder2;
     RootedObject newObj(cx);
 
     if (NS_FAILED(xpc->WrapNative(cx, obj, ctor, NS_GET_IID(nsIXPCConstructor),
                                   getter_AddRefs(holder2))) || !holder2 ||
-        NS_FAILED(holder2->GetJSObject(newObj.address())) || !newObj) {
+        // Assign, not compare
+        !(newObj = holder2->GetJSObject())) {
         return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
     }
 
     args.rval().setObject(*newObj);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -720,17 +720,17 @@ GetWrapperObject(MutableHandleObject obj
 
     nsAXPCNativeCallContext *ccxp = NULL;
     xpc->GetCurrentNativeCallContext(&ccxp);
     if (!ccxp)
         return;
 
     nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
     ccxp->GetCalleeWrapper(getter_AddRefs(wrapper));
-    wrapper->GetJSObject(obj.address());
+    obj.set(wrapper->GetJSObject());
 }
 
 /* nsISupports createInstance (); */
 NS_IMETHODIMP
 nsJSCID::CreateInstance(const JS::Value& iidval, JSContext* cx,
                         uint8_t optionalArgc, JS::Value* retval)
 {
     if (!mDetails.IsValid())
@@ -814,17 +814,19 @@ nsJSCID::GetService(const JS::Value& iid
     rv = svcMgr->GetService(mDetails.ID(), *iid, getter_AddRefs(srvc));
     NS_ASSERTION(NS_FAILED(rv) || srvc, "service manager returned success, but service is null!");
     if (NS_FAILED(rv) || !srvc)
         return NS_ERROR_XPC_GS_RETURNED_FAILURE;
 
     RootedObject instJSObj(cx);
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = nsXPConnect::GetXPConnect()->WrapNative(cx, obj, srvc, *iid, getter_AddRefs(holder));
-    if (NS_FAILED(rv) || !holder || NS_FAILED(holder->GetJSObject(instJSObj.address())))
+    if (NS_FAILED(rv) || !holder ||
+        // Assign, not compare
+        !(instJSObj = holder->GetJSObject()))
         return NS_ERROR_XPC_CANT_CREATE_WN;
 
     *retval = OBJECT_TO_JSVAL(instJSObj);
     return NS_OK;
 }
 
 /* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t argc, in JSValPtr argv, in JSValPtr vp); */
 NS_IMETHODIMP
@@ -896,17 +898,17 @@ xpc_NewIDObject(JSContext *cx, HandleObj
         nsXPConnect* xpc = nsXPConnect::GetXPConnect();
         if (xpc) {
             nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
             nsresult rv = xpc->WrapNative(cx, jsobj,
                                           static_cast<nsISupports*>(iid),
                                           NS_GET_IID(nsIJSID),
                                           getter_AddRefs(holder));
             if (NS_SUCCEEDED(rv) && holder) {
-                holder->GetJSObject(obj.address());
+                obj = holder->GetJSObject();
             }
         }
     }
     return obj;
 }
 
 // note: returned pointer is only valid while |obj| remains alive!
 const nsID*
--- a/js/xpconnect/src/XPCJSWeakReference.cpp
+++ b/js/xpconnect/src/XPCJSWeakReference.cpp
@@ -73,18 +73,17 @@ xpcJSWeakReference::Get(JSContext* aCx, 
         // We have a generic XPCOM object that supports weak references here.
         // Wrap it and pass it out.
         JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForScopeChain(aCx));
         return nsContentUtils::WrapNative(aCx, global,
                                           supports, &NS_GET_IID(nsISupports),
                                           aRetval);
     }
 
-    JS::RootedObject obj(aCx);
-    wrappedObj->GetJSObject(obj.address());
+    JS::RootedObject obj(aCx, wrappedObj->GetJSObject());
     if (!obj) {
         return NS_OK;
     }
 
     // Most users of XPCWrappedJS don't need to worry about
     // re-wrapping because things are implicitly rewrapped by
     // xpcconvert. However, because we're doing this directly
     // through the native call context, we need to call
--- a/js/xpconnect/src/XPCThrower.cpp
+++ b/js/xpconnect/src/XPCThrower.cpp
@@ -246,18 +246,18 @@ XPCThrower::ThrowExceptionObject(JSConte
             if (!glob)
                 return false;
 
             nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
             nsresult rv = xpc->WrapNative(cx, glob, e,
                                           NS_GET_IID(nsIException),
                                           getter_AddRefs(holder));
             if (NS_SUCCEEDED(rv) && holder) {
-                JS::RootedObject obj(cx);
-                if (NS_SUCCEEDED(holder->GetJSObject(obj.address()))) {
+                JS::RootedObject obj(cx, holder->GetJSObject());
+                if (obj) {
                     JS_SetPendingException(cx, OBJECT_TO_JSVAL(obj));
                     success = true;
                 }
             }
         }
     }
     return success;
 }
--- a/js/xpconnect/src/XPCWrappedJS.cpp
+++ b/js/xpconnect/src/XPCWrappedJS.cpp
@@ -231,25 +231,20 @@ NS_IMETHODIMP
 nsXPCWrappedJS::GetWeakReference(nsIWeakReference** aInstancePtr)
 {
     if (mRoot != this)
         return mRoot->GetWeakReference(aInstancePtr);
 
     return nsSupportsWeakReference::GetWeakReference(aInstancePtr);
 }
 
-NS_IMETHODIMP
-nsXPCWrappedJS::GetJSObject(JSObject** aJSObj)
+JSObject*
+nsXPCWrappedJS::GetJSObject()
 {
-    NS_PRECONDITION(aJSObj, "bad param");
-    NS_PRECONDITION(IsValid(), "bad wrapper");
-
-    if (!(*aJSObj = GetJSObject()))
-        return NS_ERROR_OUT_OF_MEMORY;
-    return NS_OK;
+    return xpc_UnmarkGrayObject(mJSObj);
 }
 
 static bool
 CheckMainThreadOnly(nsXPCWrappedJS *aWrapper)
 {
     if(aWrapper->IsMainThreadOnly())
         return NS_IsMainThread();
 
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -558,19 +558,17 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
             return NS_OK;
         }
     } else {
         ac.construct(ccx, parent);
 
         nsISupports *Object = helper.Object();
         if (nsXPCWrappedJSClass::IsWrappedJS(Object)) {
             nsCOMPtr<nsIXPConnectWrappedJS> wrappedjs(do_QueryInterface(Object));
-            RootedObject obj(ccx);
-            wrappedjs->GetJSObject(obj.address());
-            if (xpc::AccessCheck::isChrome(js::GetObjectCompartment(obj)) &&
+            if (xpc::AccessCheck::isChrome(js::GetObjectCompartment(wrappedjs->GetJSObject())) &&
                 !xpc::AccessCheck::isChrome(js::GetObjectCompartment(Scope->GetGlobalJSObject()))) {
                 needsCOW = true;
             }
         }
     }
 
     AutoMarkingWrappedNativeProtoPtr proto(ccx);
 
@@ -1913,19 +1911,18 @@ XPCWrappedNative::InitTearOff(XPCCallCon
         // into an infinite loop.
         // see: http://bugzilla.mozilla.org/show_bug.cgi?id=96725
 
         // The code in this block also does a check for the double wrapped
         // nsIPropertyBag case.
 
         nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS(do_QueryInterface(obj));
         if (wrappedJS) {
-            RootedObject jso(ccx);
-            if (NS_SUCCEEDED(wrappedJS->GetJSObject(jso.address())) &&
-                jso == mFlatJSObject) {
+            RootedObject jso(ccx, wrappedJS->GetJSObject());
+            if (jso == mFlatJSObject) {
                 // The implementing JSObject is the same as ours! Just say OK
                 // without actually extending the set.
                 //
                 // XXX It is a little cheesy to have FindTearOff return an
                 // 'empty' tearoff. But this is the centralized place to do the
                 // QI activities on the underlying object. *And* most caller to
                 // FindTearOff only look for a non-null result and ignore the
                 // actual tearoff returned. The only callers that do use the
@@ -2938,21 +2935,21 @@ CallMethodHelper::Invoke()
     nsXPTCVariant* argv = mDispatchParams.Elements();
 
     return NS_InvokeByIndex(mCallee, mVTableIndex, argc, argv);
 }
 
 /***************************************************************************/
 // interface methods
 
-/* readonly attribute JSObjectPtr JSObject; */
-NS_IMETHODIMP XPCWrappedNative::GetJSObject(JSObject * *aJSObject)
+/* JSObjectPtr GetJSObject(); */
+JSObject*
+XPCWrappedNative::GetJSObject()
 {
-    *aJSObject = GetFlatJSObject();
-    return NS_OK;
+    return GetFlatJSObject();
 }
 
 /* readonly attribute nsISupports Native; */
 NS_IMETHODIMP XPCWrappedNative::GetNative(nsISupports * *aNative)
 {
     // No need to QI here, we already have the correct nsISupports
     // vtable.
     *aNative = mIdentity;
@@ -3544,23 +3541,21 @@ void DEBUG_ReportShadowedMembers(XPCNati
             }
         }
     }
 }
 #endif
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(XPCJSObjectHolder, nsIXPConnectJSObjectHolder)
 
-NS_IMETHODIMP
-XPCJSObjectHolder::GetJSObject(JSObject** aJSObj)
+JSObject*
+XPCJSObjectHolder::GetJSObject()
 {
-    NS_PRECONDITION(aJSObj, "bad param");
     NS_PRECONDITION(mJSObj, "bad object state");
-    *aJSObj = mJSObj;
-    return NS_OK;
+    return mJSObj;
 }
 
 XPCJSObjectHolder::XPCJSObjectHolder(XPCCallContext& ccx, JSObject* obj)
     : mJSObj(obj)
 {
     ccx.GetRuntime()->AddObjectHolderRoot(this);
 }
 
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -141,18 +141,18 @@ XPC_WN_Shared_ToSource(JSContext *cx, un
 
 static JSObject*
 GetDoubleWrappedJSObject(XPCCallContext& ccx, XPCWrappedNative* wrapper)
 {
     RootedObject obj(ccx);
     nsCOMPtr<nsIXPConnectWrappedJS>
         underware = do_QueryInterface(wrapper->GetIdentityObject());
     if (underware) {
-        RootedObject mainObj(ccx);
-        if (NS_SUCCEEDED(underware->GetJSObject(mainObj.address())) && mainObj) {
+        RootedObject mainObj(ccx, underware->GetJSObject());
+        if (mainObj) {
             RootedId id(ccx, ccx.GetRuntime()->
                             GetStringID(XPCJSRuntime::IDX_WRAPPED_JSOBJECT));
 
             JSAutoCompartment ac(ccx, mainObj);
 
             RootedValue val(ccx);
             if (JS_GetPropertyById(ccx, mainObj, id, val.address()) &&
                 !JSVAL_IS_PRIMITIVE(val)) {
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3142,22 +3142,16 @@ public:
                  JSObject* aJSObj,
                  REFNSIID aIID,
                  nsISupports* aOuter,
                  nsXPCWrappedJS** wrapper);
 
     nsISomeInterface* GetXPTCStub() { return mXPTCStub; }
 
     /**
-     * This getter clears the gray bit before handing out the JSObject which
-     * means that the object is guaranteed to be kept alive past the next CC.
-     */
-    JSObject* GetJSObject() const {return xpc_UnmarkGrayObject(mJSObj);}
-
-    /**
      * This getter does not change the color of the JSObject meaning that the
      * object returned is not guaranteed to be kept alive past the next CC.
      *
      * This should only be called if you are certain that the return value won't
      * be passed into a JS API function and that it won't be stored without
      * being rooted (or otherwise signaling the stored value to the CC).
      */
     JSObject* GetJSObjectPreserveColor() const {return mJSObj;}
--- a/security/manager/ssl/src/nsCrypto.cpp
+++ b/security/manager/ssl/src/nsCrypto.cpp
@@ -1851,17 +1851,16 @@ nsCrypto::GenerateCRMFRequest(nsIDOMCRMF
   nrv = ncc->GetArgvPtr(&argv);
   NS_ENSURE_SUCCESS(nrv, nrv);
 
   JSContext *cx;
 
   nrv = ncc->GetJSContext(&cx);
   NS_ENSURE_SUCCESS(nrv, nrv);
 
-  JS::RootedObject script_obj(cx);
   nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
 
   JSAutoRequest ar(cx);
 
   /*
    * Get all of the parameters.
    */
   if (argc < 5 || ((argc-5) % 3) != 0) {
@@ -1916,18 +1915,18 @@ nsCrypto::GenerateCRMFRequest(nsIDOMCRMF
   JSAutoByteString jsCallback(cx, jsString);
   NS_ENSURE_TRUE(!!jsCallback, NS_ERROR_OUT_OF_MEMORY);
 
   nrv = xpc->WrapNative(cx, JS_GetGlobalForScopeChain(cx),
                         static_cast<nsIDOMCrypto *>(this),
                         NS_GET_IID(nsIDOMCrypto), getter_AddRefs(holder));
   NS_ENSURE_SUCCESS(nrv, nrv);
 
-  nrv = holder->GetJSObject(script_obj.address());
-  NS_ENSURE_SUCCESS(nrv, nrv);
+  JS::RootedObject script_obj(cx, holder->GetJSObject());
+  NS_ENSURE_STATE(script_obj);
 
   //Put up some UI warning that someone is trying to 
   //escrow the private key.
   //Don't addref this copy.  That way ths reference goes away
   //at the same the nsIX09Cert ref goes away.
   nsNSSCertificate *escrowCert = nullptr;
   nsCOMPtr<nsIX509Cert> nssCert;
   bool willEscrow = false;
--- a/storage/src/mozStorageAsyncStatementJSHelper.cpp
+++ b/storage/src/mozStorageAsyncStatementJSHelper.cpp
@@ -52,18 +52,18 @@ AsyncStatementJSHelper::getParams(AsyncS
       params,
       NS_GET_IID(mozIStorageStatementParams),
       getter_AddRefs(aStatement->mStatementParamsHolder)
     );
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   JS::Rooted<JSObject*> obj(aCtx);
-  rv = aStatement->mStatementParamsHolder->GetJSObject(obj.address());
-  NS_ENSURE_SUCCESS(rv, rv);
+  obj = aStatement->mStatementParamsHolder->GetJSObject();
+  NS_ENSURE_STATE(obj);
 
   *_params = OBJECT_TO_JSVAL(obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP_(nsrefcnt) AsyncStatementJSHelper::AddRef() { return 2; }
 NS_IMETHODIMP_(nsrefcnt) AsyncStatementJSHelper::Release() { return 1; }
 NS_INTERFACE_MAP_BEGIN(AsyncStatementJSHelper)
--- a/storage/src/mozStorageStatementJSHelper.cpp
+++ b/storage/src/mozStorageStatementJSHelper.cpp
@@ -105,18 +105,18 @@ StatementJSHelper::getRow(Statement *aSt
       row,
       NS_GET_IID(mozIStorageStatementRow),
       getter_AddRefs(aStatement->mStatementRowHolder)
     );
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   JS::Rooted<JSObject*> obj(aCtx);
-  rv = aStatement->mStatementRowHolder->GetJSObject(obj.address());
-  NS_ENSURE_SUCCESS(rv, rv);
+  obj = aStatement->mStatementRowHolder->GetJSObject();
+  NS_ENSURE_STATE(obj);
 
   *_row = OBJECT_TO_JSVAL(obj);
   return NS_OK;
 }
 
 nsresult
 StatementJSHelper::getParams(Statement *aStatement,
                              JSContext *aCtx,
@@ -145,18 +145,18 @@ StatementJSHelper::getParams(Statement *
       params,
       NS_GET_IID(mozIStorageStatementParams),
       getter_AddRefs(aStatement->mStatementParamsHolder)
     );
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   JS::Rooted<JSObject*> obj(aCtx);
-  rv = aStatement->mStatementParamsHolder->GetJSObject(obj.address());
-  NS_ENSURE_SUCCESS(rv, rv);
+  obj = aStatement->mStatementParamsHolder->GetJSObject();
+  NS_ENSURE_STATE(obj);
 
   *_params = OBJECT_TO_JSVAL(obj);
   return NS_OK;
 }
 
 NS_IMETHODIMP_(nsrefcnt) StatementJSHelper::AddRef() { return 2; }
 NS_IMETHODIMP_(nsrefcnt) StatementJSHelper::Release() { return 1; }
 NS_INTERFACE_MAP_BEGIN(StatementJSHelper)
--- a/toolkit/components/places/PlaceInfo.cpp
+++ b/toolkit/components/places/PlaceInfo.cpp
@@ -85,19 +85,18 @@ PlaceInfo::GetVisits(JSContext* aContext
 
   for (VisitsArray::size_type idx = 0; idx < mVisits.Length(); idx++) {
     nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
     nsresult rv = xpc->WrapNative(aContext, global, mVisits[idx],
                                   NS_GET_IID(mozIVisitInfo),
                                   getter_AddRefs(wrapper));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    JS::Rooted<JSObject*> jsobj(aContext);
-    rv = wrapper->GetJSObject(jsobj.address());
-    NS_ENSURE_SUCCESS(rv, rv);
+    JS::Rooted<JSObject*> jsobj(aContext, wrapper->GetJSObject());
+    NS_ENSURE_STATE(jsobj);
     JS::Value wrappedVisit = OBJECT_TO_JSVAL(jsobj);
 
     JSBool rc = JS_SetElement(aContext, visits, idx, &wrappedVisit);
     NS_ENSURE_TRUE(rc, NS_ERROR_UNEXPECTED);
   }
 
   *_visits = OBJECT_TO_JSVAL(visits);
 
--- a/xpfe/components/directory/nsDirectoryViewer.cpp
+++ b/xpfe/components/directory/nsDirectoryViewer.cpp
@@ -248,21 +248,20 @@ nsHTTPIndex::OnStartRequest(nsIRequest *
                          global,
                          static_cast<nsIHTTPIndex*>(this),
                          NS_GET_IID(nsIHTTPIndex),
                          getter_AddRefs(wrapper));
 
     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap http-index");
     if (NS_FAILED(rv)) return rv;
 
-    JS::Rooted<JSObject*> jsobj(cx);
-    rv = wrapper->GetJSObject(jsobj.address());
-    NS_ASSERTION(NS_SUCCEEDED(rv),
+    JS::Rooted<JSObject*> jsobj(cx, wrapper->GetJSObject());
+    NS_ASSERTION(jsobj,
                  "unable to get jsobj from xpconnect wrapper");
-    if (NS_FAILED(rv)) return rv;
+    if (!jsobj) return NS_ERROR_UNEXPECTED;
 
     JS::Rooted<JS::Value> jslistener(cx, OBJECT_TO_JSVAL(jsobj));
 
     // ...and stuff it into the global context
     JSAutoRequest ar(cx);
     bool ok = JS_SetProperty(cx, global, "HTTPIndex", jslistener.address());
     NS_ASSERTION(ok, "unable to set Listener property");
     if (!ok)