Bug 8844105 - Handlify JS_WrapObject. r=terrence
authorTom Schuster <evilpies@gmail.com>
Tue, 15 Oct 2013 20:02:23 -0400
changeset 151150 5126b48adf91390db142ee55bc9c19cc1b9ae801
parent 151149 95b04871f4ae527ce51a07aeb761f90db1e0d24f
child 151151 f03cd4cd9cf6c60baa5b7910763d41ba94e3145f
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersterrence
bugs8844105
milestone27.0a1
Bug 8844105 - Handlify JS_WrapObject. r=terrence
content/base/src/nsDocument.cpp
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsFrameMessageManager.h
content/base/src/nsObjectLoadingContent.cpp
content/html/content/src/HTMLUnknownElement.cpp
content/xbl/src/nsXBLProtoImplField.cpp
content/xbl/src/nsXBLProtoImplMethod.cpp
content/xbl/src/nsXBLProtoImplProperty.cpp
content/xbl/src/nsXBLPrototypeHandler.cpp
dom/base/MessagePort.cpp
dom/base/Navigator.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/Codegen.py
dom/bindings/TypedArray.h
dom/plugins/base/nsJSNPRuntime.cpp
js/ipc/JavaScriptParent.cpp
js/ipc/JavaScriptShared.cpp
js/ipc/JavaScriptShared.h
js/src/jsapi-tests/testBug604087.cpp
js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
js/src/jsapi-tests/testDebugger.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsweakmap.cpp
js/src/shell/js.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCJSWeakReference.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/wrappers/WrapperFactory.cpp
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -5214,17 +5214,17 @@ nsDocument::Register(JSContext* aCx, con
     if (!protoObject) {
       rv.Throw(NS_ERROR_UNEXPECTED);
       return nullptr;
     }
   } else {
     // If a prototype is provided, we must check to ensure that it inherits
     // from HTMLElement.
     protoObject = aOptions.mPrototype;
-    if (!JS_WrapObject(aCx, protoObject.address())) {
+    if (!JS_WrapObject(aCx, &protoObject)) {
       rv.Throw(NS_ERROR_UNEXPECTED);
       return nullptr;
     }
 
     // Check the proto chain for HTMLElement prototype.
     JS::Rooted<JSObject*> protoProto(aCx);
     if (!JS_GetPrototype(aCx, protoObject, &protoProto)) {
       rv.Throw(NS_ERROR_UNEXPECTED);
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -225,24 +225,23 @@ mozilla::dom::ipc::UnpackClonedMessageDa
 
 StructuredCloneData
 mozilla::dom::ipc::UnpackClonedMessageDataForChild(const ClonedMessageData& aData)
 {
   return UnpackClonedMessageData<Child>(aData);
 }
 
 bool
-SameProcessCpowHolder::ToObject(JSContext* aCx, JSObject** aObjp)
+SameProcessCpowHolder::ToObject(JSContext* aCx, JS::MutableHandleObject aObjp)
 {
-  *aObjp = mObj;
-
   if (!mObj) {
     return true;
   }
 
+  aObjp.set(mObj);
   return JS_WrapObject(aCx, aObjp);
 }
 
 // nsIMessageListenerManager
 
 NS_IMETHODIMP
 nsFrameMessageManager::AddMessageListener(const nsAString& aMessage,
                                           nsIMessageListener* aListener)
@@ -833,17 +832,17 @@ nsFrameMessageManager::ReceiveMessage(ns
 
         JS::Rooted<JS::Value> targetv(ctx);
         JS::Rooted<JSObject*> global(ctx, JS_GetGlobalForObject(ctx, object));
         nsContentUtils::WrapNative(ctx, global, aTarget, targetv.address(),
                                    nullptr, true);
 
         JS::RootedObject cpows(ctx);
         if (aCpows) {
-          if (!aCpows->ToObject(ctx, cpows.address())) {
+          if (!aCpows->ToObject(ctx, &cpows)) {
             return NS_ERROR_UNEXPECTED;
           }
         }
 
         if (!cpows) {
           cpows = JS_NewObject(ctx, nullptr, nullptr, nullptr);
           if (!cpows) {
             return NS_ERROR_UNEXPECTED;
--- a/content/base/src/nsFrameMessageManager.h
+++ b/content/base/src/nsFrameMessageManager.h
@@ -117,28 +117,28 @@ struct nsMessageListenerInfo
   nsCOMPtr<nsIMessageListener> mStrongListener;
   nsWeakPtr mWeakListener;
   nsCOMPtr<nsIAtom> mMessage;
 };
 
 class CpowHolder
 {
   public:
-    virtual bool ToObject(JSContext* cx, JSObject** objp) = 0;
+    virtual bool ToObject(JSContext* cx, JS::MutableHandleObject objp) = 0;
 };
 
 class MOZ_STACK_CLASS SameProcessCpowHolder : public CpowHolder
 {
   public:
     SameProcessCpowHolder(JSRuntime *aRuntime, JS::Handle<JSObject *> aObj)
       : mObj(aRuntime, aObj)
     {
     }
 
-    bool ToObject(JSContext* aCx, JSObject** aObjp);
+    bool ToObject(JSContext* aCx, JS::MutableHandleObject aObjp);
 
   private:
     JS::Rooted<JSObject*> mObj;
 };
 
 class nsFrameMessageManager MOZ_FINAL : public nsIContentFrameMessageManager,
                                         public nsIMessageBroadcaster,
                                         public nsIFrameScriptLoader,
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -3120,17 +3120,17 @@ nsObjectLoadingContent::LegacyCall(JSCon
     do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
   JS::Rooted<JSObject*> obj(aCx, thisContent->GetWrapper());
   MOZ_ASSERT(obj, "How did we get called?");
 
   // Make sure we're not dealing with an Xray.  Our DoCall code can't handle
   // random cross-compartment wrappers, so we're going to have to wrap
   // everything up into our compartment, but that means we need to check that
   // this is not an Xray situation by hand.
-  if (!JS_WrapObject(aCx, obj.address())) {
+  if (!JS_WrapObject(aCx, &obj)) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return JS::UndefinedValue();
   }
 
   if (nsDOMClassInfo::ObjectIsNativeWrapper(aCx, obj)) {
     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
     return JS::UndefinedValue();
   }
--- a/content/html/content/src/HTMLUnknownElement.cpp
+++ b/content/html/content/src/HTMLUnknownElement.cpp
@@ -19,17 +19,17 @@ HTMLUnknownElement::WrapNode(JSContext *
     HTMLUnknownElementBinding::Wrap(aCx, aScope, this));
   if (obj && Substring(NodeName(), 0, 2).LowerCaseEqualsLiteral("x-")) {
     // If we have a registered x-tag then we fix the prototype.
     JSAutoCompartment ac(aCx, obj);
     nsDocument* document = static_cast<nsDocument*>(OwnerDoc());
     JS::Rooted<JSObject*> prototype(aCx);
     document->GetCustomPrototype(LocalName(), &prototype);
     if (prototype) {
-      NS_ENSURE_TRUE(JS_WrapObject(aCx, prototype.address()), nullptr);
+      NS_ENSURE_TRUE(JS_WrapObject(aCx, &prototype), nullptr);
       NS_ENSURE_TRUE(JS_SetPrototype(aCx, obj, prototype), nullptr);
     }
   }
   return obj;
 }
 
 NS_IMPL_ELEMENT_CLONE(HTMLUnknownElement)
 
--- a/content/xbl/src/nsXBLProtoImplField.cpp
+++ b/content/xbl/src/nsXBLProtoImplField.cpp
@@ -366,17 +366,17 @@ nsXBLProtoImplField::InstallAccessors(JS
   }
   js::SetFunctionNativeReserved(set, XBLPROTO_SLOT, wrappedClassObj);
   js::SetFunctionNativeReserved(set, FIELD_SLOT,
                                 JS::StringValue(JSID_TO_STRING(id)));
 
   // Now, re-enter the class object's scope, wrap the getters/setters, and define
   // them there.
   JSAutoCompartment ac2(aCx, aTargetClassObject);
-  if (!JS_WrapObject(aCx, get.address()) || !JS_WrapObject(aCx, set.address()) ||
+  if (!JS_WrapObject(aCx, &get) || !JS_WrapObject(aCx, &set) ||
       !JS_WrapId(aCx, id.address()))
   {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   if (!::JS_DefinePropertyById(aCx, aTargetClassObject, id, JS::UndefinedValue(),
                                JS_DATA_TO_FUNC_PTR(JSPropertyOp, get.get()),
                                JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, set.get()),
@@ -419,17 +419,17 @@ nsXBLProtoImplField::InstallField(nsIScr
 
   // First, enter the xbl scope, wrap the node, and use that as the scope for
   // the evaluation.
   JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScope(cx, aBoundNode));
   NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
   JSAutoCompartment ac(cx, scopeObject);
 
   JS::Rooted<JSObject*> wrappedNode(cx, aBoundNode);
-  if (!JS_WrapObject(cx, wrappedNode.address()))
+  if (!JS_WrapObject(cx, &wrappedNode))
       return NS_ERROR_OUT_OF_MEMORY;
 
   JS::Rooted<JS::Value> result(cx);
   JS::CompileOptions options(cx);
   options.setFileAndLine(uriSpec.get(), mLineNumber)
          .setVersion(JSVERSION_LATEST);
   rv = aContext->EvaluateString(nsDependentString(mFieldText,
                                                   mFieldTextLength),
--- a/content/xbl/src/nsXBLProtoImplMethod.cpp
+++ b/content/xbl/src/nsXBLProtoImplMethod.cpp
@@ -116,17 +116,17 @@ nsXBLProtoImplMethod::InstallMember(JSCo
     JS::Rooted<JSObject*> method(aCx, ::JS_CloneFunctionObject(aCx, jsMethodObject, scopeObject));
     if (!method) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     // Then, enter the content compartment, wrap the method pointer, and define
     // the wrapped version on the class object.
     JSAutoCompartment ac2(aCx, aTargetClassObject);
-    if (!JS_WrapObject(aCx, method.address()))
+    if (!JS_WrapObject(aCx, &method))
       return NS_ERROR_OUT_OF_MEMORY;
 
     JS::Rooted<JS::Value> value(aCx, JS::ObjectValue(*method));
     if (!::JS_DefineUCProperty(aCx, aTargetClassObject,
                                static_cast<const jschar*>(mName),
                                name.Length(), value,
                                nullptr, nullptr, JSPROP_ENUMERATE)) {
       return NS_ERROR_OUT_OF_MEMORY;
@@ -322,17 +322,17 @@ nsXBLProtoImplAnonymousMethod::Execute(n
     return NS_ERROR_UNEXPECTED;
   MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
 
   JS::Rooted<JSObject*> thisObject(cx, &v.toObject());
   JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScope(cx, globalObject));
   NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
 
   JSAutoCompartment ac(cx, scopeObject);
-  if (!JS_WrapObject(cx, thisObject.address()))
+  if (!JS_WrapObject(cx, &thisObject))
       return NS_ERROR_OUT_OF_MEMORY;
 
   // Clone the function object, using thisObject as the parent so "this" is in
   // the scope chain of the resulting function (for backwards compat to the
   // days when this was an event handler).
   JS::Rooted<JSObject*> method(cx, ::JS_CloneFunctionObject(cx, GetCompiledMethod(), thisObject));
   if (!method)
     return NS_ERROR_OUT_OF_MEMORY;
--- a/content/xbl/src/nsXBLProtoImplProperty.cpp
+++ b/content/xbl/src/nsXBLProtoImplProperty.cpp
@@ -147,18 +147,18 @@ nsXBLProtoImplProperty::InstallMember(JS
       if (!(setter = ::JS_CloneFunctionObject(aCx, mSetter.GetJSFunction(), scopeObject)))
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     // Now, enter the content compartment, wrap the getter/setter, and define
     // them on the class object.
     JSAutoCompartment ac2(aCx, aTargetClassObject);
     nsDependentString name(mName);
-    if (!JS_WrapObject(aCx, getter.address()) ||
-        !JS_WrapObject(aCx, setter.address()) ||
+    if (!JS_WrapObject(aCx, &getter) ||
+        !JS_WrapObject(aCx, &setter) ||
         !::JS_DefineUCProperty(aCx, aTargetClassObject,
                                static_cast<const jschar*>(mName),
                                name.Length(), JSVAL_VOID,
                                JS_DATA_TO_FUNC_PTR(JSPropertyOp, getter.get()),
                                JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, setter.get()),
                                mJSAttributes))
       return NS_ERROR_OUT_OF_MEMORY;
   }
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -294,17 +294,17 @@ nsXBLPrototypeHandler::ExecuteHandler(Ev
   // Bind it to the bound element. Note that if we're using a separate XBL scope,
   // we'll actually be binding the event handler to a cross-compartment wrapper
   // to the bound element's reflector.
 
   // First, enter our XBL scope. This is where the generic handler should have
   // been compiled, above.
   JSAutoCompartment ac(cx, scopeObject);
   JS::Rooted<JSObject*> genericHandler(cx, handler.get());
-  bool ok = JS_WrapObject(cx, genericHandler.address());
+  bool ok = JS_WrapObject(cx, &genericHandler);
   NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
   MOZ_ASSERT(!js::IsCrossCompartmentWrapper(genericHandler));
 
   // Wrap the native into the XBL scope. This creates a reflector in the document
   // scope if one doesn't already exist, and potentially wraps it cross-
   // compartment into our scope (via aAllowWrapping=true).
   JS::Rooted<JS::Value> targetV(cx, JS::UndefinedValue());
   rv = nsContentUtils::WrapNative(cx, scopeObject, scriptTarget, targetV.address(), nullptr,
@@ -312,17 +312,17 @@ nsXBLPrototypeHandler::ExecuteHandler(Ev
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Next, clone the generic handler to be parented to the target.
   JS::Rooted<JSObject*> bound(cx, JS_CloneFunctionObject(cx, genericHandler, &targetV.toObject()));
   NS_ENSURE_TRUE(bound, NS_ERROR_FAILURE);
 
   // Now, wrap the bound handler into the content compartment and use it.
   JSAutoCompartment ac2(cx, globalObject);
-  if (!JS_WrapObject(cx, bound.address())) {
+  if (!JS_WrapObject(cx, &bound)) {
     return NS_ERROR_FAILURE;
   }
 
   nsRefPtr<EventHandlerNonNull> handlerCallback =
     new EventHandlerNonNull(bound);
 
   nsEventHandler eventHandler(handlerCallback);
 
@@ -388,17 +388,17 @@ nsXBLPrototypeHandler::EnsureEventHandle
                                            nsAtomCString(aName), argCount,
                                            argNames, handlerText, handlerFun.address());
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(handlerFun, NS_ERROR_FAILURE);
 
   // Wrap the handler into the content scope, since we're about to stash it
   // on the DOM window and such.
   JSAutoCompartment ac2(cx, globalObject);
-  bool ok = JS_WrapObject(cx, handlerFun.address());
+  bool ok = JS_WrapObject(cx, &handlerFun);
   NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
   aHandler.set(handlerFun);
   NS_ENSURE_TRUE(aHandler, NS_ERROR_FAILURE);
 
   if (pWindow) {
     pWindow->CacheXBLPrototypeHandler(this, aHandler);
   }
 
--- a/dom/base/MessagePort.cpp
+++ b/dom/base/MessagePort.cpp
@@ -134,17 +134,17 @@ PostMessageReadStructuredClone(JSContext
   if (tag == SCTAG_DOM_MESSAGEPORT) {
     NS_ASSERTION(!data, "Data should be empty");
 
     MessagePort* port;
     if (JS_ReadBytes(reader, &port, sizeof(port))) {
       JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
       if (global) {
         JS::Rooted<JSObject*> obj(cx, port->WrapObject(cx, global));
-        if (JS_WrapObject(cx, obj.address())) {
+        if (JS_WrapObject(cx, &obj)) {
           port->BindToOwner(scInfo->mPort->GetOwner());
           return obj;
         }
       }
     }
   }
 
   const JSStructuredCloneCallbacks* runtimeCallbacks =
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1549,17 +1549,17 @@ Navigator::DoNewResolve(JSContext* aCx, 
       }
 
       domObject = construct(aCx, naviObj);
       if (!domObject) {
         return Throw(aCx, NS_ERROR_FAILURE);
       }
     }
 
-    if (!JS_WrapObject(aCx, domObject.address())) {
+    if (!JS_WrapObject(aCx, &domObject)) {
       return false;
     }
 
     aValue.setObject(*domObject);
     return true;
   }
 
   NS_ASSERTION(name_struct->mType == nsGlobalNameStruct::eTypeNavigatorProperty,
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -2780,17 +2780,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());
-  if (!JS_WrapObject(cx, proto_obj.address())) {
+  if (!JS_WrapObject(cx, &proto_obj)) {
     return NS_ERROR_FAILURE;
   }
 
   NS_IF_RELEASE(*aProto);
   return aXPConnect->HoldObject(cx, proto_obj, aProto);
 }
 
 // Either ci_data must be non-null or name_struct must be non-null and of type
@@ -2917,17 +2917,17 @@ ResolvePrototype(nsIXPConnect *aXPConnec
       JS::Rooted<JSObject*> xpc_proto_proto(cx);
       if (!::JS_GetPrototype(cx, dot_prototype, &xpc_proto_proto)) {
         return NS_ERROR_UNEXPECTED;
       }
 
       if (proto &&
           (!xpc_proto_proto ||
            JS_GetClass(xpc_proto_proto) == sObjectClass)) {
-        if (!JS_WrapObject(cx, proto.address()) ||
+        if (!JS_WrapObject(cx, &proto) ||
             !JS_SetPrototype(cx, dot_prototype, proto)) {
           return NS_ERROR_UNEXPECTED;
         }
       }
     } else {
       JSAutoCompartment ac(cx, winobj);
       if (!proto) {
         proto = JS_GetObjectPrototype(cx, winobj);
@@ -3066,17 +3066,17 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
                                                        defineOnGlobal));
       if (!interfaceObject) {
         return NS_ERROR_FAILURE;
       }
 
       if (defineOnXray) {
         // This really should be handled by the Xray for the window.
         ac.destroy();
-        if (!JS_WrapObject(cx, interfaceObject.address()) ||
+        if (!JS_WrapObject(cx, &interfaceObject) ||
             !JS_DefinePropertyById(cx, obj, id,
                                    JS::ObjectValue(*interfaceObject), JS_PropertyStub,
                                    JS_StrictPropertyStub, 0)) {
           return NS_ERROR_FAILURE;
         }
 
       }
 
@@ -3639,17 +3639,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     JS::Rooted<JSObject*> funObj(cx);
     JSFunction *fun = ::JS_NewFunction(cx, ContentWindowGetter, 0, 0,
                                        obj, "_content");
     if (!fun) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     funObj = ::JS_GetFunctionObject(fun);
 
-    if (!JS_WrapObject(cx, funObj.address()) ||
+    if (!JS_WrapObject(cx, &funObj) ||
         !JS_DefinePropertyById(cx, obj, id, JSVAL_VOID,
                                JS_DATA_TO_FUNC_PTR(JSPropertyOp, funObj.get()),
                                JS_StrictPropertyStub,
                                JSPROP_ENUMERATE | JSPROP_GETTER |
                                JSPROP_SHARED)) {
       return NS_ERROR_FAILURE;
     }
 
@@ -3740,17 +3740,17 @@ nsWindowSH::OuterObject(nsIXPConnectWrap
 
   JS::Rooted<JSObject*> winObj(cx, win->FastGetGlobalJSObject());
   MOZ_ASSERT(winObj);
 
   // Note that while |wrapper| is same-compartment with cx, the outer window
   // might not be. If we're running script in an inactive scope and evalute
   // |this|, the outer window is actually a cross-compartment wrapper. So we
   // need to wrap here.
-  if (!JS_WrapObject(cx, winObj.address())) {
+  if (!JS_WrapObject(cx, &winObj)) {
     *_retval = nullptr;
     return NS_ERROR_UNEXPECTED;
   }
 
   *_retval = winObj;
   return NS_OK;
 }
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -4000,18 +4000,18 @@ nsGlobalWindow::SetOpener(nsIDOMWindow* 
     // expandos on Xrays as needed.
 
     JS::Rooted<JSObject*> otherObj(cx, glob->GetGlobalJSObject());
     NS_ENSURE_STATE(otherObj);
 
     JS::Rooted<JSObject*> thisObj(cx, mJSObject);
     NS_ENSURE_STATE(mJSObject);
 
-    if (!JS_WrapObject(cx, otherObj.address()) ||
-        !JS_WrapObject(cx, thisObj.address()) ||
+    if (!JS_WrapObject(cx, &otherObj) ||
+        !JS_WrapObject(cx, &thisObj) ||
         !JS_DefineProperty(cx, thisObj, "opener", JS::ObjectValue(*otherObj),
                            JS_PropertyStub, JS_StrictPropertyStub,
                            JSPROP_ENUMERATE)) {
       return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
   }
@@ -6817,17 +6817,17 @@ PostMessageReadStructuredClone(JSContext
   if (MessageChannel::PrefEnabled() && tag == SCTAG_DOM_MESSAGEPORT) {
     NS_ASSERTION(!data, "Data should be empty");
 
     MessagePort* port;
     if (JS_ReadBytes(reader, &port, sizeof(port))) {
       JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
       if (global) {
         JS::Rooted<JSObject*> obj(cx, port->WrapObject(cx, global));
-        if (JS_WrapObject(cx, obj.address())) {
+        if (JS_WrapObject(cx, &obj)) {
           port->BindToOwner(scInfo->window);
           return obj;
         }
       }
     }
   }
 
   const JSStructuredCloneCallbacks* runtimeCallbacks =
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -684,17 +684,17 @@ NativeInterface2JSObjectAndThrowIfFailed
   nsWrapperCache *cache = aHelper.GetWrapperCache();
 
   if (cache && cache->IsDOMBinding()) {
       JS::RootedObject obj(aCx, cache->GetWrapper());
       if (!obj) {
           obj = cache->WrapObject(aCx, aScope);
       }
 
-      if (obj && aAllowNativeWrapper && !JS_WrapObject(aCx, obj.address())) {
+      if (obj && aAllowNativeWrapper && !JS_WrapObject(aCx, &obj)) {
         return false;
       }
 
       if (obj) {
         *aRetval = JS::ObjectValue(*obj);
         return true;
       }
   }
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1263,17 +1263,17 @@ WrapCallThisObject(JSContext* cx, JS::Ha
     // wrap anything for us.
     obj = WrapNativeParent(cx, scope, p);
     if (!obj) {
       return nullptr;
     }
   }
 
   // But all that won't necessarily put things in the compartment of cx.
-  if (!JS_WrapObject(cx, obj.address())) {
+  if (!JS_WrapObject(cx, &obj)) {
     return nullptr;
   }
 
   return obj;
 }
 
 // Helper for calling WrapNewBindingObject with smart pointers
 // (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -4606,19 +4606,19 @@ def wrapTypeIntoCurrentCompartment(type,
         else:
             value = value + ".address()"
         return CGGeneric("if (!JS_WrapValue(cx, %s)) {\n"
                          "  return false;\n"
                          "}" % value)
 
     if type.isObject():
         if isMember:
-            value = "&%s" % value
-        else:
-            value = value + ".address()"
+            value = "JS::MutableHandleObject::fromMarkedLocation(&%s)" % value
+        else:
+            value = "&" + value
         return CGGeneric("if (!JS_WrapObject(cx, %s)) {\n"
                          "  return false;\n"
                          "}" % value)
 
     if type.isSpiderMonkeyInterface():
         origValue = value
         if type.nullable():
             value = "%s.Value()" % value
@@ -9900,17 +9900,17 @@ class CGJSImplClass(CGBindingImplClass):
     def getWrapObjectBody(self):
         return ("JS::Rooted<JSObject*> obj(aCx, %sBinding::Wrap(aCx, aScope, this));\n"
                 "if (!obj) {\n"
                 "  return nullptr;\n"
                 "}\n"
                 "\n"
                 "// Now define it on our chrome object\n"
                 "JSAutoCompartment ac(aCx, mImpl->Callback());\n"
-                "if (!JS_WrapObject(aCx, obj.address())) {\n"
+                "if (!JS_WrapObject(aCx, &obj)) {\n"
                 "  return nullptr;\n"
                 "}\n"
                 'if (!JS_DefineProperty(aCx, mImpl->Callback(), "__DOM_IMPL__", JS::ObjectValue(*obj), nullptr, nullptr, 0)) {\n'
                 "  return nullptr;\n"
                 "}\n"
                 "return obj;" % self.descriptor.name)
 
     def getGetParentObjectReturnType(self):
--- a/dom/bindings/TypedArray.h
+++ b/dom/bindings/TypedArray.h
@@ -87,17 +87,17 @@ public:
 
   inline JSObject *Obj() const {
     MOZ_ASSERT(inited());
     return mObj;
   }
 
   inline bool WrapIntoNewCompartment(JSContext* cx)
   {
-    return JS_WrapObject(cx, &mObj);
+    return JS_WrapObject(cx, JS::MutableHandleObject::fromMarkedLocation(&mObj));
   }
 
 protected:
   inline void DoInit(JSObject* obj)
   {
     mObj = UnboxArray(obj, &mLength, &mData);
   }
 
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -1070,17 +1070,17 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS
 // compartment for callers that plan to hold onto the result or do anything
 // substantial with it.
 static JSObject *
 GetNPObjectWrapper(JSContext *cx, JSObject *aObj, bool wrapResult = true)
 {
   JS::Rooted<JSObject*> obj(cx, aObj);
   while (obj && (obj = js::CheckedUnwrap(obj))) {
     if (JS_GetClass(obj) == &sNPObjectJSWrapperClass) {
-      if (wrapResult && !JS_WrapObject(cx, obj.address())) {
+      if (wrapResult && !JS_WrapObject(cx, &obj)) {
         return NULL;
       }
       return obj;
     }
     if (!::JS_GetPrototype(cx, obj, &obj)) {
       return NULL;
     }
   }
@@ -1725,17 +1725,17 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JS
 
     return nullptr;
   }
 
   if (npobj->_class == &nsJSObjWrapper::sJSObjWrapperNPClass) {
     // npobj is one of our own, return its existing JSObject.
 
     JS::Rooted<JSObject*> obj(cx, ((nsJSObjWrapper *)npobj)->mJSObj);
-    if (!JS_WrapObject(cx, obj.address())) {
+    if (!JS_WrapObject(cx, &obj)) {
       return NULL;
     }
     return obj;
   }
 
   if (!npp) {
     NS_ERROR("No npp passed to nsNPObjWrapper::GetNewOrUsed()!");
 
@@ -1762,17 +1762,17 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JS
 
     return nullptr;
   }
 
   if (PL_DHASH_ENTRY_IS_BUSY(entry) && entry->mJSObj) {
     // Found a live NPObject wrapper. It may not be in the same compartment
     // as cx, so we need to wrap it before returning it.
     JS::Rooted<JSObject*> obj(cx, entry->mJSObj);
-    if (!JS_WrapObject(cx, obj.address())) {
+    if (!JS_WrapObject(cx, &obj)) {
       return NULL;
     }
     return obj;
   }
 
   entry->mNPObj = npobj;
   entry->mNpp = npp;
 
--- a/js/ipc/JavaScriptParent.cpp
+++ b/js/ipc/JavaScriptParent.cpp
@@ -552,17 +552,17 @@ JavaScriptParent::getPropertyNames(JSCon
     return true;
 }
 
 JSObject *
 JavaScriptParent::unwrap(JSContext *cx, ObjectId objId)
 {
     RootedObject obj(cx, findObject(objId));
     if (obj) {
-        if (!JS_WrapObject(cx, obj.address()))
+        if (!JS_WrapObject(cx, &obj))
             return nullptr;
         return obj;
     }
 
     if (objId > MAX_CPOW_IDS) {
         JS_ReportError(cx, "unusable CPOW id");
         return nullptr;
     }
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -411,25 +411,26 @@ JavaScriptShared::toDescriptor(JSContext
         else
             out.setSetter(UnknownStrictPropertyStub);
     }
 
     return true;
 }
 
 bool
-CpowIdHolder::ToObject(JSContext *cx, JSObject **objp)
+CpowIdHolder::ToObject(JSContext *cx, JS::MutableHandleObject objp)
 {
     return js_->Unwrap(cx, cpows_, objp);
 }
 
 bool
-JavaScriptShared::Unwrap(JSContext *cx, const InfallibleTArray<CpowEntry> &aCpows, JSObject **objp)
+JavaScriptShared::Unwrap(JSContext *cx, const InfallibleTArray<CpowEntry> &aCpows,
+                         JS::MutableHandleObject objp)
 {
-    *objp = nullptr;
+    objp.set(nullptr);
 
     if (!aCpows.Length())
         return true;
 
     RootedObject obj(cx, JS_NewObject(cx, nullptr, nullptr, nullptr));
     if (!obj)
         return false;
 
@@ -449,17 +450,17 @@ JavaScriptShared::Unwrap(JSContext *cx, 
                                  nullptr,
                                  nullptr,
                                  JSPROP_ENUMERATE))
         {
             return false;
         }
     }
 
-    *objp = obj;
+    objp.set(obj);
     return true;
 }
 
 bool
 JavaScriptShared::Wrap(JSContext *cx, HandleObject aObj, InfallibleTArray<CpowEntry> *outCpows)
 {
     if (!aObj)
         return true;
--- a/js/ipc/JavaScriptShared.h
+++ b/js/ipc/JavaScriptShared.h
@@ -24,17 +24,17 @@ class CpowIdHolder : public CpowHolder
 {
   public:
     CpowIdHolder(JavaScriptShared *js, const InfallibleTArray<CpowEntry> &cpows)
       : js_(js),
         cpows_(cpows)
     {
     }
 
-    bool ToObject(JSContext *cx, JSObject **objp);
+    bool ToObject(JSContext *cx, JS::MutableHandleObject objp);
 
   private:
     JavaScriptShared *js_;
     const InfallibleTArray<CpowEntry> &cpows_;
 };
 
 // Map ids -> JSObjects
 class ObjectStore
@@ -82,17 +82,17 @@ class ObjectIdCache
 class JavaScriptShared
 {
   public:
     bool init();
 
     static const uint32_t OBJECT_EXTRA_BITS  = 1;
     static const uint32_t OBJECT_IS_CALLABLE = (1 << 0);
 
-    bool Unwrap(JSContext *cx, const InfallibleTArray<CpowEntry> &aCpows, JSObject **objp);
+    bool Unwrap(JSContext *cx, const InfallibleTArray<CpowEntry> &aCpows, JS::MutableHandleObject objp);
     bool Wrap(JSContext *cx, JS::HandleObject aObj, InfallibleTArray<CpowEntry> *outCpows);
 
   protected:
     bool toVariant(JSContext *cx, JS::HandleValue from, JSVariant *to);
     bool toValue(JSContext *cx, const JSVariant &from, JS::MutableHandleValue to);
     bool fromDescriptor(JSContext *cx, JS::Handle<JSPropertyDescriptor> desc, PPropertyDescriptor *out);
     bool toDescriptor(JSContext *cx, const PPropertyDescriptor &in,
                       JS::MutableHandle<JSPropertyDescriptor> out);
--- a/js/src/jsapi-tests/testBug604087.cpp
+++ b/js/src/jsapi-tests/testBug604087.cpp
@@ -32,17 +32,17 @@ struct OuterWrapper : js::Wrapper
 OuterWrapper
 OuterWrapper::singleton;
 
 static JSObject *
 wrap(JSContext *cx, JS::HandleObject toWrap, JS::HandleObject target)
 {
     JSAutoCompartment ac(cx, target);
     JS::RootedObject wrapper(cx, toWrap);
-    if (!JS_WrapObject(cx, wrapper.address()))
+    if (!JS_WrapObject(cx, &wrapper))
         return nullptr;
     return wrapper;
 }
 
 static JSObject *
 SameCompartmentWrap(JSContext *cx, JS::HandleObject obj)
 {
     JS_GC(JS_GetRuntime(cx));
--- a/js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
+++ b/js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
@@ -72,17 +72,17 @@ BEGIN_TEST(test_CallNonGenericMethodOnPr
     JS::RootedFunction customMethodB(cx, JS_NewFunction(cx, CustomMethod, 0, 0, customB, "customMethodB"));
     CHECK(customMethodB);
 
     JS::RootedValue rval(cx);
     CHECK(JS_CallFunction(cx, customB, customMethodB, 0, nullptr, rval.address()));
     CHECK_SAME(rval, Int32Value(42));
 
     JS::RootedObject wrappedCustomA(cx, customA);
-    CHECK(JS_WrapObject(cx, wrappedCustomA.address()));
+    CHECK(JS_WrapObject(cx, &wrappedCustomA));
 
     JS::RootedValue rval2(cx);
     CHECK(JS_CallFunction(cx, wrappedCustomA, customMethodB, 0, nullptr, rval2.address()));
     CHECK_SAME(rval, Int32Value(42));
   }
 
   return true;
 }
--- a/js/src/jsapi-tests/testDebugger.cpp
+++ b/js/src/jsapi-tests/testDebugger.cpp
@@ -154,17 +154,17 @@ BEGIN_TEST(testDebugger_debuggerObjectVs
 
     {
         JSAutoCompartment ae(cx, debuggee);
         CHECK(JS_SetDebugMode(cx, true));
         CHECK(JS_InitStandardClasses(cx, debuggee));
     }
 
     JS::RootedObject debuggeeWrapper(cx, debuggee);
-    CHECK(JS_WrapObject(cx, debuggeeWrapper.address()));
+    CHECK(JS_WrapObject(cx, &debuggeeWrapper));
     JS::RootedValue v(cx, JS::ObjectValue(*debuggeeWrapper));
     CHECK(JS_SetProperty(cx, global, "debuggee", v));
 
     EVAL("var dbg = new Debugger(debuggee);\n"
          "var hits = 0;\n"
          "dbg.onDebuggerStatement = function () { hits++; };\n"
          "debuggee.eval('debugger;');\n"
          "hits;\n",
@@ -192,17 +192,17 @@ BEGIN_TEST(testDebugger_newScriptHook)
     JS::RootedObject g(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook));
     CHECK(g);
     {
         JSAutoCompartment ae(cx, g);
         CHECK(JS_InitStandardClasses(cx, g));
     }
 
     JS::RootedObject gWrapper(cx, g);
-    CHECK(JS_WrapObject(cx, gWrapper.address()));
+    CHECK(JS_WrapObject(cx, &gWrapper));
     JS::RootedValue v(cx, JS::ObjectValue(*gWrapper));
     CHECK(JS_SetProperty(cx, global, "g", v));
 
     EXEC("var dbg = Debugger(g);\n"
          "var hits = 0;\n"
          "dbg.onNewScript = function (s) {\n"
          "    hits += Number(s instanceof Debugger.Script);\n"
          "};\n");
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1131,27 +1131,23 @@ JS_SetCompartmentPrivate(JSCompartment *
 
 JS_PUBLIC_API(void *)
 JS_GetCompartmentPrivate(JSCompartment *compartment)
 {
     return compartment->data;
 }
 
 JS_PUBLIC_API(bool)
-JS_WrapObject(JSContext *cx, JSObject **objp)
+JS_WrapObject(JSContext *cx, MutableHandleObject objp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
-    RootedObject obj(cx, *objp);
-    if (obj)
-        JS::ExposeGCThingToActiveJS(obj, JSTRACE_OBJECT);
-    if (!cx->compartment()->wrap(cx, &obj))
-        return false;
-    *objp = obj;
-    return true;
+    if (objp)
+        JS::ExposeGCThingToActiveJS(objp, JSTRACE_OBJECT);
+    return cx->compartment()->wrap(cx, objp);
 }
 
 JS_PUBLIC_API(bool)
 JS_WrapValue(JSContext *cx, jsval *vp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     if (vp)
@@ -1253,17 +1249,17 @@ JS_TransplantObject(JSContext *cx, Handl
     // old object, and update the relevant cross-compartment wrappers.
     if (!RemapAllWrappersForObject(cx, origobj, newIdentity))
         MOZ_CRASH();
 
     // Lastly, update the original object to point to the new one.
     if (origobj->compartment() != destination) {
         RootedObject newIdentityWrapper(cx, newIdentity);
         AutoCompartment ac(cx, origobj);
-        if (!JS_WrapObject(cx, newIdentityWrapper.address()))
+        if (!JS_WrapObject(cx, &newIdentityWrapper))
             MOZ_CRASH();
         JS_ASSERT(Wrapper::wrappedObject(newIdentityWrapper) == newIdentity);
         if (!JSObject::swap(cx, origobj, newIdentityWrapper))
             MOZ_CRASH();
         origobj->compartment()->putWrapper(ObjectValue(*newIdentity), origv);
     }
 
     // The new identity object might be one of several things. Return it to avoid
@@ -1344,17 +1340,17 @@ js_TransplantObjectWithWrapper(JSContext
             options.setForceForegroundFinalization(true);
         RootedObject reflectorGuts(cx, NewDeadProxyObject(cx, JS_GetGlobalForObject(cx, origobj),
                                                           options));
         if (!reflectorGuts || !JSObject::swap(cx, origobj, reflectorGuts))
             MOZ_CRASH();
 
         // Turn origwrapper into a CCW to the new object.
         RootedObject wrapperGuts(cx, targetobj);
-        if (!JS_WrapObject(cx, wrapperGuts.address()))
+        if (!JS_WrapObject(cx, &wrapperGuts))
             MOZ_CRASH();
         JS_ASSERT(Wrapper::wrappedObject(wrapperGuts) == targetobj);
         if (!JSObject::swap(cx, origwrapper, wrapperGuts))
             MOZ_CRASH();
         origwrapper->compartment()->putWrapper(ObjectValue(*targetobj),
                                                ObjectValue(*origwrapper));
     }
 
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1752,17 +1752,17 @@ JS_SetWrapObjectCallbacks(JSRuntime *rt,
 
 extern JS_PUBLIC_API(void)
 JS_SetCompartmentPrivate(JSCompartment *compartment, void *data);
 
 extern JS_PUBLIC_API(void *)
 JS_GetCompartmentPrivate(JSCompartment *compartment);
 
 extern JS_PUBLIC_API(bool)
-JS_WrapObject(JSContext *cx, JSObject **objp);
+JS_WrapObject(JSContext *cx, JS::MutableHandleObject objp);
 
 extern JS_PUBLIC_API(bool)
 JS_WrapValue(JSContext *cx, jsval *vp);
 
 extern JS_PUBLIC_API(bool)
 JS_WrapId(JSContext *cx, jsid *idp);
 
 extern JS_PUBLIC_API(JSObject *)
--- a/js/src/jsweakmap.cpp
+++ b/js/src/jsweakmap.cpp
@@ -338,17 +338,17 @@ JS_NondeterministicGetWeakMapKeys(JSCont
     if (!arr)
         return false;
     ObjectValueMap *map = obj->as<WeakMapObject>().getMap();
     if (map) {
         // Prevent GC from mutating the weakmap while iterating.
         gc::AutoSuppressGC suppress(cx);
         for (ObjectValueMap::Base::Range r = map->all(); !r.empty(); r.popFront()) {
             RootedObject key(cx, r.front().key);
-            if (!JS_WrapObject(cx, key.address()))
+            if (!cx->compartment()->wrap(cx, &key))
                 return false;
             if (!js_NewbornArrayPush(cx, arr, ObjectValue(*key)))
                 return false;
         }
     }
     *ret = arr;
     return true;
 }
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -3729,17 +3729,17 @@ NewGlobalObject(JSContext *cx, JS::Compa
 
 static bool
 NewGlobal(JSContext *cx, unsigned argc, jsval *vp)
 {
     JS::CompartmentOptions options;
     options.setVersion(JSVERSION_LATEST);
 
     CallArgs args = CallArgsFromVp(argc, vp);
-    if (argc == 1 && args[0].isObject()) {
+    if (args.length() == 1 && args[0].isObject()) {
         RootedObject opts(cx, &args[0].toObject());
         RootedValue v(cx);
 
         if (!JS_GetProperty(cx, opts, "sameZoneAs", &v))
             return false;
         if (v.isObject())
             options.setSameZoneAs(UncheckedUnwrap(&v.toObject()));
 
@@ -3748,20 +3748,20 @@ NewGlobal(JSContext *cx, unsigned argc, 
         if (v.isBoolean())
             options.setInvisibleToDebugger(v.toBoolean());
     }
 
     RootedObject global(cx, NewGlobalObject(cx, options));
     if (!global)
         return false;
 
-    if (!JS_WrapObject(cx, global.address()))
+    if (!JS_WrapObject(cx, &global))
         return false;
 
-    JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(global));
+    args.rval().setObject(*global);
     return true;
 }
 
 static bool
 EnableStackWalkingAssertion(JSContext *cx, unsigned argc, jsval *vp)
 {
     if (argc == 0 || !JSVAL_IS_BOOLEAN(JS_ARGV(cx, vp)[0])) {
         JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS,
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -1094,17 +1094,17 @@ mozJSComponentLoader::Import(const nsACS
     if (targetObject) {
         ac.construct(cx, targetObject);
     }
 
     RootedObject global(cx);
     nsresult rv = ImportInto(registryLocation, targetObject, cx, &global);
 
     if (global) {
-        if (!JS_WrapObject(cx, global.address())) {
+        if (!JS_WrapObject(cx, &global)) {
             NS_ERROR("can't wrap return value");
             return NS_ERROR_FAILURE;
         }
 
         *retval = ObjectValue(*global);
     }
     return rv;
 }
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -275,17 +275,17 @@ ExportFunction(JSContext *cx, unsigned a
         if (!JS_ObjectIsCallable(cx, funObj)) {
             JS_ReportError(cx, "First argument must be a function");
             return false;
         }
 
         // The function forwarder will live in the target compartment. Since
         // this function will be referenced from its private slot, to avoid a
         // GC hazard, we must wrap it to the same compartment.
-        if (!JS_WrapObject(cx, funObj.address()))
+        if (!JS_WrapObject(cx, &funObj))
             return false;
 
         RootedId id(cx);
         if (!JS_ValueToId(cx, args[2], id.address()))
             return false;
 
         // And now, let's create the forwarder function in the target compartment
         // for the function the be exported.
@@ -343,17 +343,18 @@ CloneNonReflectorsRead(JSContext *cx, JS
         MOZ_ASSERT(!data);
 
         size_t idx;
         if (JS_ReadBytes(reader, &idx, sizeof(size_t))) {
             RootedObject reflector(cx, reflectors->handleAt(idx));
             MOZ_ASSERT(reflector, "No object pointer?");
             MOZ_ASSERT(IsReflector(reflector), "Object pointer must be a reflector!");
 
-            JS_WrapObject(cx, reflector.address());
+            if (!JS_WrapObject(cx, &reflector))
+                return nullptr;
             JS_ASSERT(WrapperFactory::IsXrayWrapper(reflector) ||
                       IsReflector(reflector));
 
             return reflector;
         }
     }
 
     JS_ReportError(cx, "CloneNonReflectorsRead error");
@@ -1001,17 +1002,17 @@ xpc::CreateSandboxObject(JSContext *cx, 
     // benefit. So we just switch it off here.
     xpc::GetCompartmentPrivate(sandbox)->wantXrays =
       AccessCheck::isChrome(sandbox) ? false : options.wantXrays;
 
     {
         JSAutoCompartment ac(cx, sandbox);
 
         if (options.proto) {
-            bool ok = JS_WrapObject(cx, options.proto.address());
+            bool ok = JS_WrapObject(cx, &options.proto);
             if (!ok)
                 return NS_ERROR_XPC_UNEXPECTED;
 
             if (xpc::WrapperFactory::IsXrayWrapper(options.proto) && !options.wantXrays) {
                 RootedValue v(cx, ObjectValue(*options.proto));
                 if (!xpc::WrapperFactory::WaiveXrayAndWrap(cx, v.address()))
                     return NS_ERROR_FAILURE;
                 options.proto = &v.toObject();
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2977,39 +2977,42 @@ nsXPCComponents_Utils::GetJSTestingFunct
 }
 
 /* void getGlobalForObject(); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::GetGlobalForObject(const Value& object,
                                           JSContext *cx,
                                           Value *retval)
 {
-  // First argument must be an object.
-  if (JSVAL_IS_PRIMITIVE(object))
-    return NS_ERROR_XPC_BAD_CONVERT_JS;
-
-  // Wrappers are parented to their the global in their home compartment. But
-  // when getting the global for a cross-compartment wrapper, we really want
-  // a wrapper for the foreign global. So we need to unwrap before getting the
-  // parent, enter the compartment for the duration of the call, and wrap the
-  // result.
-  Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(object));
-  obj = js::UncheckedUnwrap(obj);
-  {
-    JSAutoCompartment ac(cx, obj);
-    obj = JS_GetGlobalForObject(cx, obj);
-  }
-  JS_WrapObject(cx, obj.address());
-  *retval = OBJECT_TO_JSVAL(obj);
-
-  // Outerize if necessary.
-  if (JSObjectOp outerize = js::GetObjectClass(obj)->ext.outerObject)
+    // First argument must be an object.
+    if (JSVAL_IS_PRIMITIVE(object))
+        return NS_ERROR_XPC_BAD_CONVERT_JS;
+
+    // Wrappers are parented to their the global in their home compartment. But
+    // when getting the global for a cross-compartment wrapper, we really want
+    // a wrapper for the foreign global. So we need to unwrap before getting the
+    // parent, enter the compartment for the duration of the call, and wrap the
+    // result.
+    Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(object));
+    obj = js::UncheckedUnwrap(obj);
+    {
+        JSAutoCompartment ac(cx, obj);
+        obj = JS_GetGlobalForObject(cx, obj);
+    }
+
+    if (!JS_WrapObject(cx, &obj))
+        return NS_ERROR_FAILURE;
+
+    *retval = OBJECT_TO_JSVAL(obj);
+
+    // Outerize if necessary.
+    if (JSObjectOp outerize = js::GetObjectClass(obj)->ext.outerObject)
       *retval = OBJECT_TO_JSVAL(outerize(cx, obj));
 
-  return NS_OK;
+    return NS_OK;
 }
 
 /* jsval createObjectIn(in jsval vobj); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::CreateObjectIn(const Value &vobj, JSContext *cx, Value *rval)
 {
     if (!cx)
         return NS_ERROR_FAILURE;
@@ -3022,17 +3025,17 @@ nsXPCComponents_Utils::CreateObjectIn(co
     RootedObject obj(cx);
     {
         JSAutoCompartment ac(cx, scope);
         obj = JS_NewObject(cx, nullptr, nullptr, scope);
         if (!obj)
             return NS_ERROR_FAILURE;
     }
 
-    if (!JS_WrapObject(cx, obj.address()))
+    if (!JS_WrapObject(cx, &obj))
         return NS_ERROR_FAILURE;
 
     *rval = ObjectValue(*obj);
     return NS_OK;
 }
 
 /* jsval createObjectIn(in jsval vobj); */
 NS_IMETHODIMP
@@ -3049,17 +3052,17 @@ nsXPCComponents_Utils::CreateArrayIn(con
     RootedObject obj(cx);
     {
         JSAutoCompartment ac(cx, scope);
         obj =  JS_NewArrayObject(cx, 0, nullptr);
         if (!obj)
             return NS_ERROR_FAILURE;
     }
 
-    if (!JS_WrapObject(cx, obj.address()))
+    if (!JS_WrapObject(cx, &obj))
         return NS_ERROR_FAILURE;
 
     *rval = ObjectValue(*obj);
     return NS_OK;
 }
 
 /* jsval createDateIn(in jsval vobj, in long long msec); */
 NS_IMETHODIMP
@@ -3076,18 +3079,19 @@ nsXPCComponents_Utils::CreateDateIn(cons
     {
         JSObject *scope = js::UncheckedUnwrap(&vobj.toObject());
         JSAutoCompartment ac(cx, scope);
         obj =  JS_NewDateObjectMsec(cx, msec);
         if (!obj)
             return NS_ERROR_FAILURE;
     }
 
-    if (!JS_WrapObject(cx, obj.address()))
+    if (!JS_WrapObject(cx, &obj))
         return NS_ERROR_FAILURE;
+
     *rval = ObjectValue(*obj);
     return NS_OK;
 }
 
 /* void makeObjectPropsNormal(jsval vobj); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::MakeObjectPropsNormal(const Value &vobj, JSContext *cx)
 {
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -836,32 +836,32 @@ XPCConvert::NativeInterface2JSObject(jsv
         if (cache->IsDOMBinding()) {
             if (!flat) {
                 JS::Rooted<JSObject*> global(cx, xpcscope->GetGlobalJSObject());
                 flat = cache->WrapObject(cx, global);
                 if (!flat)
                     return false;
             }
 
-            if (allowNativeWrapper && !JS_WrapObject(cx, flat.address()))
+            if (allowNativeWrapper && !JS_WrapObject(cx, &flat))
                 return false;
 
             return CreateHolderIfNeeded(flat, d, dest);
         }
     } else {
         flat = nullptr;
     }
 
     // Don't double wrap CPOWs. This is a temporary measure for compatibility
     // with objects that don't provide necessary QIs (such as objects under
     // the new DOM bindings). We expect the other side of the CPOW to have
     // the appropriate wrappers in place.
     RootedObject cpow(cx, UnwrapNativeCPOW(aHelper.Object()));
     if (cpow) {
-        if (!JS_WrapObject(cx, cpow.address()))
+        if (!JS_WrapObject(cx, &cpow))
             return false;
         *d = JS::ObjectValue(*cpow);
         return true;
     }
 
     // We can't simply construct a slim wrapper. Go ahead and create an
     // XPCWrappedNative for this object. At this point, |flat| could be
     // non-null, meaning that either we already have a wrapped native from
@@ -926,17 +926,17 @@ XPCConvert::NativeInterface2JSObject(jsv
         if (pErr)
             *pErr = NS_OK;
         return true;
     }
 
     // The call to wrap here handles both cross-compartment and same-compartment
     // security wrappers.
     RootedObject original(cx, flat);
-    if (!JS_WrapObject(cx, flat.address()))
+    if (!JS_WrapObject(cx, &flat))
         return false;
 
     *d = OBJECT_TO_JSVAL(flat);
 
     if (dest) {
         // The strongWrapper still holds the original flat object.
         if (flat == original) {
             *dest = strongWrapper.forget().get();
--- a/js/xpconnect/src/XPCJSWeakReference.cpp
+++ b/js/xpconnect/src/XPCJSWeakReference.cpp
@@ -80,15 +80,15 @@ xpcJSWeakReference::Get(JSContext* aCx, 
         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
     // JS_WrapObject().
-    if (!JS_WrapObject(aCx, obj.address())) {
+    if (!JS_WrapObject(aCx, &obj)) {
         return NS_ERROR_FAILURE;
     }
 
     *aRetval = OBJECT_TO_JSVAL(obj);
     return NS_OK;
 }
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -1231,17 +1231,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
                                 bool ok =
                                   XPCConvert::NativeInterface2JSObject(
                                       v.address(), nullptr, helper, nullptr,
                                       nullptr, false, nullptr);
                                 if (!ok) {
                                     goto pre_call_clean_up;
                                 }
                                 thisObj = JSVAL_TO_OBJECT(v);
-                                if (!JS_WrapObject(cx, thisObj.address()))
+                                if (!JS_WrapObject(cx, &thisObj))
                                     goto pre_call_clean_up;
                             }
                         }
                     }
                 }
             }
         } else {
             if (!JS_GetProperty(cx, obj, name, &fval))
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -210,17 +210,17 @@ XPCWrappedNativeScope::GetComponentsJSOb
     nsCOMPtr<XPCWrappedNative> wrapper;
     XPCWrappedNative::GetNewOrUsed(helper, this, iface, getter_AddRefs(wrapper));
     if (!wrapper)
         return nullptr;
 
     // The call to wrap() here is necessary even though the object is same-
     // compartment, because it applies our security wrapper.
     JS::RootedObject obj(cx, wrapper->GetFlatJSObject());
-    if (!JS_WrapObject(cx, obj.address()))
+    if (!JS_WrapObject(cx, &obj))
         return nullptr;
     return obj;
 }
 
 JSObject*
 XPCWrappedNativeScope::EnsureXBLScope(JSContext *cx)
 {
     JS::RootedObject global(cx, GetGlobalJSObject());
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -79,17 +79,17 @@ WrapperFactory::CreateXrayWaiver(JSConte
     RootedObject proto(cx);
     if (!js::GetObjectProto(cx, obj, &proto))
         return nullptr;
     if (proto && !(proto = WaiveXray(cx, proto)))
         return nullptr;
 
     // Create the waiver.
     JSAutoCompartment ac(cx, obj);
-    if (!JS_WrapObject(cx, proto.address()))
+    if (!JS_WrapObject(cx, &proto))
         return nullptr;
     JSObject *waiver = Wrapper::New(cx, obj, proto,
                                     JS_GetGlobalForObject(cx, obj),
                                     &XrayWaiver);
     if (!waiver)
         return nullptr;
 
     // Add the new waiver to the map. It's important that we only ever have
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -374,17 +374,17 @@ JSObject *
 XrayTraits::getExpandoObjectInternal(JSContext *cx, HandleObject target,
                                      nsIPrincipal *origin,
                                      JSObject *exclusiveGlobalArg)
 {
     // The expando object lives in the compartment of the target, so all our
     // work needs to happen there.
     RootedObject exclusiveGlobal(cx, exclusiveGlobalArg);
     JSAutoCompartment ac(cx, target);
-    if (!JS_WrapObject(cx, exclusiveGlobal.address()))
+    if (!JS_WrapObject(cx, &exclusiveGlobal))
         return nullptr;
 
     // Iterate through the chain, looking for a same-origin object.
     RootedObject head(cx, getExpandoChain(target));
     while (head) {
         if (expandoObjectMatchesConsumer(cx, head, origin, exclusiveGlobal))
             return head;
         head = JS_GetReservedSlot(head, JSSLOT_EXPANDO_NEXT).toObjectOrNull();
@@ -452,17 +452,17 @@ XrayTraits::ensureExpandoObject(JSContex
     if (!expandoObject) {
         // If the object is a sandbox, we don't want it to share expandos with
         // anyone else, so we tag it with the sandbox global.
         //
         // NB: We first need to check the class, _then_ wrap for the target's
         // compartment.
         RootedObject consumerGlobal(cx, js::GetGlobalForObjectCrossCompartment(wrapper));
         bool isSandbox = !strcmp(js::GetObjectJSClass(consumerGlobal)->name, "Sandbox");
-        if (!JS_WrapObject(cx, consumerGlobal.address()))
+        if (!JS_WrapObject(cx, &consumerGlobal))
             return nullptr;
         expandoObject = attachExpandoObject(cx, target, ObjectPrincipal(wrapper),
                                             isSandbox ? (HandleObject)consumerGlobal : NullPtr());
     }
     return expandoObject;
 }
 
 bool
@@ -471,17 +471,17 @@ XrayTraits::cloneExpandoChain(JSContext 
     MOZ_ASSERT(js::IsObjectInContextCompartment(dst, cx));
     MOZ_ASSERT(getExpandoChain(dst) == nullptr);
 
     RootedObject oldHead(cx, getExpandoChain(src));
     while (oldHead) {
         RootedObject exclusive(cx, JS_GetReservedSlot(oldHead,
                                                       JSSLOT_EXPANDO_EXCLUSIVE_GLOBAL)
                                                      .toObjectOrNull());
-        if (!JS_WrapObject(cx, exclusive.address()))
+        if (!JS_WrapObject(cx, &exclusive))
             return false;
         JSObject *newHead = attachExpandoObject(cx, dst, GetExpandoObjectPrincipal(oldHead),
                                                 exclusive);
         if (!JS_CopyPropertiesFrom(cx, newHead, oldHead))
             return false;
         oldHead = JS_GetReservedSlot(oldHead, JSSLOT_EXPANDO_NEXT).toObjectOrNull();
     }
     return true;