Bug 939294 - Handlify XPConnect. r=gabor
☠☠ backed out by 61692f603cc4 ☠ ☠
authorTom Schuster <evilpies@gmail.com>
Thu, 09 Jan 2014 18:39:36 +0100
changeset 162715 89e9d3fa16fcb1aa4d32169710559b9fe4d04d95
parent 162714 c97e58ebc5f4d346255121a597911cd0ffb4deae
child 162716 fed59539afc136c4c5ffdc07636d013e2872bcce
push id25969
push userkwierso@gmail.com
push dateFri, 10 Jan 2014 00:12:26 +0000
treeherdermozilla-central@653ba6ed853b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgabor
bugs939294
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 939294 - Handlify XPConnect. r=gabor
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/loader/mozJSSubScriptLoader.cpp
js/xpconnect/loader/mozJSSubScriptLoader.h
js/xpconnect/public/xpc_map_end.h
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/XPCJSWeakReference.cpp
js/xpconnect/src/XPCShellImpl.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/qsgen.py
js/xpconnect/tests/components/native/xpctest_params.cpp
js/xpconnect/wrappers/WrapperFactory.cpp
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -172,17 +172,17 @@ File(JSContext *cx, unsigned argc, Value
     }
 
     nsXPConnect* xpc = nsXPConnect::XPConnect();
     JSObject* glob = CurrentGlobalOrNull(cx);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
                                 &NS_GET_IID(nsISupports),
-                                true, args.rval().address());
+                                true, args.rval());
     if (NS_FAILED(rv)) {
         XPCThrower::Throw(rv, cx);
         return false;
     }
     return true;
 }
 
 static bool
@@ -207,17 +207,17 @@ Blob(JSContext *cx, unsigned argc, Value
     }
 
     nsXPConnect* xpc = nsXPConnect::XPConnect();
     JSObject* glob = CurrentGlobalOrNull(cx);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
                                 &NS_GET_IID(nsISupports),
-                                true, args.rval().address());
+                                true, args.rval());
     if (NS_FAILED(rv)) {
         XPCThrower::Throw(rv, cx);
         return false;
     }
     return true;
 }
 
 static const JSFunctionSpec gGlobalFun[] = {
@@ -1079,20 +1079,20 @@ mozJSComponentLoader::UnloadModules()
     JS_DestroyContextNoGC(mContext);
     mContext = nullptr;
 
     mRuntimeService = nullptr;
 }
 
 NS_IMETHODIMP
 mozJSComponentLoader::Import(const nsACString& registryLocation,
-                             const Value& targetValArg,
-                             JSContext* cx,
+                             HandleValue targetValArg,
+                             JSContext *cx,
                              uint8_t optionalArgc,
-                             Value* retval)
+                             MutableHandleValue retval)
 {
     MOZ_ASSERT(nsContentUtils::IsCallerChrome());
 
     RootedValue targetVal(cx, targetValArg);
     RootedObject targetObject(cx, nullptr);
     if (optionalArgc) {
         // The caller passed in the optional second argument. Get it.
         if (targetVal.isObject()) {
@@ -1128,17 +1128,17 @@ mozJSComponentLoader::Import(const nsACS
     nsresult rv = ImportInto(registryLocation, targetObject, cx, &global);
 
     if (global) {
         if (!JS_WrapObject(cx, &global)) {
             NS_ERROR("can't wrap return value");
             return NS_ERROR_FAILURE;
         }
 
-        *retval = ObjectValue(*global);
+        retval.setObject(*global);
     }
     return rv;
 }
 
 /* [noscript] JSObjectPtr importInto(in AUTF8String registryLocation,
                                      in JSObjectPtr targetObj); */
 NS_IMETHODIMP
 mozJSComponentLoader::ImportInto(const nsACString & aLocation,
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -179,55 +179,58 @@ mozJSSubScriptLoader::ReadScript(nsIURI 
     /* repent for our evil deeds */
     JS_SetErrorReporter(cx, er);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
-                                    const Value& targetArg,
+                                    HandleValue target,
                                     const nsAString& charset,
-                                    JSContext* cx,
-                                    Value* retval)
+                                    JSContext *cx,
+                                    MutableHandleValue retval)
 {
     /*
      * Loads a local url and evals it into the current cx
      * Synchronous (an async version would be cool too.)
      *   url: The url to load.  Must be local so that it can be loaded
      *        synchronously.
      *   target_obj: Optional object to eval the script onto (defaults to context
      *               global)
      *   charset: Optional character set to use for reading
      *   returns: Whatever jsval the script pointed to by the url returns.
      * Should ONLY (O N L Y !) be called from JavaScript code.
      */
     LoadSubScriptOptions options(cx);
     options.charset = charset;
-    options.target = targetArg.isObject() ? &targetArg.toObject() : nullptr;
+    options.target = target.isObject() ? &target.toObject() : nullptr;
     return DoLoadSubScriptWithOptions(url, options, cx, retval);
 }
 
 
 NS_IMETHODIMP
-mozJSSubScriptLoader::LoadSubScriptWithOptions(const nsAString& url, const Value& optionsVal,
-                                               JSContext* cx, Value* retval)
+mozJSSubScriptLoader::LoadSubScriptWithOptions(const nsAString& url,
+                                               HandleValue optionsVal,
+                                               JSContext *cx,
+                                               MutableHandleValue retval)
 {
     if (!optionsVal.isObject())
         return NS_ERROR_INVALID_ARG;
     LoadSubScriptOptions options(cx, &optionsVal.toObject());
     if (!options.Parse())
         return NS_ERROR_INVALID_ARG;
     return DoLoadSubScriptWithOptions(url, options, cx, retval);
 }
 
 nsresult
 mozJSSubScriptLoader::DoLoadSubScriptWithOptions(const nsAString& url,
                                                  LoadSubScriptOptions& options,
-                                                 JSContext* cx, Value* retval)
+                                                 JSContext *cx,
+                                                 MutableHandleValue retval)
 {
     nsresult rv = NS_OK;
 
     /* set the system principal if it's not here already */
     if (!mSystemPrincipal) {
         nsCOMPtr<nsIScriptSecurityManager> secman =
             do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
         if (!secman)
@@ -341,29 +344,28 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
         return rv;
 
     if (function) {
         script = JS_GetFunctionScript(cx, function);
     }
 
     loader->NoteSubScript(script, targetObj);
 
-    RootedValue rval(cx);
+
     bool ok = false;
     if (function) {
-        ok = JS_CallFunction(cx, targetObj, function, 0, nullptr, rval.address());
+        ok = JS_CallFunction(cx, targetObj, function, 0, nullptr, retval.address());
     } else {
-        ok = JS_ExecuteScriptVersion(cx, targetObj, script, rval.address(), version);
+        ok = JS_ExecuteScriptVersion(cx, targetObj, script, retval.address(), version);
     }
 
     if (ok) {
         JSAutoCompartment rac(cx, result_obj);
-        if (!JS_WrapValue(cx, &rval))
+        if (!JS_WrapValue(cx, retval))
             return NS_ERROR_UNEXPECTED;
-        *retval = rval;
     }
 
     if (cache && ok && writeScript) {
         WriteCachedScript(cache, cachePath, cx, mSystemPrincipal, script);
     }
 
     return NS_OK;
 }
--- a/js/xpconnect/loader/mozJSSubScriptLoader.h
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.h
@@ -35,12 +35,13 @@ private:
     nsresult ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_obj,
                         const nsAString& charset, const char *uriStr,
                         nsIIOService *serv, nsIPrincipal *principal,
                         bool reuseGlobal, JSScript **scriptp,
                         JSFunction **functionp);
 
     nsresult DoLoadSubScriptWithOptions(const nsAString& url,
                                         LoadSubScriptOptions& options,
-                                        JSContext* cx, JS::Value* retval);
+                                        JSContext* cx,
+                                        JS::MutableHandle<JS::Value> retval);
 
     nsCOMPtr<nsIPrincipal> mSystemPrincipal;
 };
--- a/js/xpconnect/public/xpc_map_end.h
+++ b/js/xpconnect/public/xpc_map_end.h
@@ -165,17 +165,17 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::Call(ns
 #endif
 
 #ifndef XPC_MAP_WANT_CONSTRUCT
 NS_IMETHODIMP XPC_MAP_CLASSNAME::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, const JS::CallArgs &args, bool *_retval)
     {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
 #endif
 
 #ifndef XPC_MAP_WANT_HASINSTANCE
-NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, const JS::Value &val, bool *bp, bool *_retval)
+NS_IMETHODIMP XPC_MAP_CLASSNAME::HasInstance(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JS::HandleValue val, bool *bp, bool *_retval)
     {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
 #endif
 
 #ifndef XPC_MAP_WANT_OUTER_OBJECT
 NS_IMETHODIMP XPC_MAP_CLASSNAME::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JSObject * *_retval)
     {NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
 #endif
 
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -1591,21 +1591,20 @@ nsXPCComponents_ID::CallOrConstruct(nsIX
     args.rval().setObject(*newobj);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsXPCComponents_ID::HasInstance(nsIXPConnectWrappedNative *wrapper,
                                 JSContext *cx, JSObject *obj,
-                                const jsval &val, bool *bp, bool *_retval)
+                                HandleValue val, bool *bp, bool *_retval)
 {
-    RootedValue v(cx, val);
     if (bp)
-        *bp = JSValIsInterfaceOfType(cx, v, NS_GET_IID(nsIJSID));
+        *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIJSID));
     return NS_OK;
 }
 
 /***************************************************************************/
 // JavaScript Constructor for nsIXPCException objects (Components.Exception)
 
 class nsXPCComponents_Exception :
   public nsIXPCComponents_Exception,
@@ -1957,17 +1956,17 @@ nsXPCComponents_Exception::CallOrConstru
     args.rval().setObject(*newObj);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsXPCComponents_Exception::HasInstance(nsIXPConnectWrappedNative *wrapper,
                                        JSContext * cx, JSObject * obj,
-                                       const jsval &val, bool *bp,
+                                       HandleValue val, bool *bp,
                                        bool *_retval)
 {
     using namespace mozilla::dom;
 
     RootedValue v(cx, val);
     if (bp) {
         Exception* e;
         *bp = NS_SUCCEEDED(UNWRAP_OBJECT(Exception, v.toObjectOrNull(), e)) ||
@@ -2560,23 +2559,22 @@ nsXPCComponents_Constructor::CallOrConst
 
     args.rval().setObject(*newObj);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsXPCComponents_Constructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
-                                         JSContext * cx, JSObject * obj,
-                                         const jsval &val, bool *bp,
+                                         JSContext *cx, JSObject *obj,
+                                         HandleValue val, bool *bp,
                                          bool *_retval)
 {
-    RootedValue v(cx, val);
     if (bp)
-        *bp = JSValIsInterfaceOfType(cx, v, NS_GET_IID(nsIXPCConstructor));
+        *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIXPCConstructor));
     return NS_OK;
 }
 
 class nsXPCComponents_Utils :
             public nsIXPCComponents_Utils,
             public nsIXPCScriptable,
             public nsISecurityCheckedComponent
 {
@@ -2619,20 +2617,18 @@ nsXPCComponents_Utils::GetSandbox(nsIXPC
         mSandbox = NewSandboxConstructor();
 
     NS_ADDREF(*aSandbox = mSandbox);
     return NS_OK;
 }
 
 /* void reportError (); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::ReportError(const Value &errorArg, JSContext *cx)
+nsXPCComponents_Utils::ReportError(HandleValue error, JSContext *cx)
 {
-    RootedValue error(cx, errorArg);
-
     // This function shall never fail! Silently eat any failure conditions.
 
     nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
 
     nsCOMPtr<nsIScriptError> scripterr(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
 
     if (!scripterr || !console)
         return NS_OK;
@@ -2692,26 +2688,24 @@ nsXPCComponents_Utils::ReportError(const
 
     console->LogMessage(scripterr);
     return NS_OK;
 }
 
 /* void evalInSandbox(in AString source, in nativeobj sandbox); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::EvalInSandbox(const nsAString& source,
-                                     const Value& sandboxValArg,
-                                     const Value& versionArg,
-                                     const Value& filenameVal,
+                                     HandleValue sandboxVal,
+                                     HandleValue version,
+                                     HandleValue filenameVal,
                                      int32_t lineNumber,
                                      JSContext *cx,
                                      uint8_t optionalArgc,
-                                     Value *retval)
+                                     MutableHandleValue retval)
 {
-    RootedValue sandboxVal(cx, sandboxValArg);
-    RootedValue version(cx, versionArg);
     RootedObject sandbox(cx);
     if (!JS_ValueToObject(cx, sandboxVal, &sandbox) || !sandbox)
         return NS_ERROR_INVALID_ARG;
 
     // Optional third argument: JS version, as a string.
     JSVersion jsVersion = JSVERSION_DEFAULT;
     if (optionalArgc >= 1) {
         JSString *jsVersionStr = ToString(cx, version);
@@ -2733,18 +2727,17 @@ nsXPCComponents_Utils::EvalInSandbox(con
         if (jsVersion == JSVERSION_UNKNOWN)
             return NS_ERROR_INVALID_ARG;
     }
 
     // Optional fourth and fifth arguments: filename and line number.
     nsXPIDLCString filename;
     int32_t lineNo = (optionalArgc >= 3) ? lineNumber : 1;
     if (optionalArgc >= 2) {
-        RootedValue value(cx, filenameVal);
-        JSString *filenameStr = ToString(cx, value);
+        JSString *filenameStr = ToString(cx, filenameVal);
         if (!filenameStr)
             return NS_ERROR_INVALID_ARG;
 
         JSAutoByteString filenameBytes;
         if (!filenameBytes.encodeLatin1(cx, filenameStr))
             return NS_ERROR_INVALID_ARG;
         filename = filenameBytes.ptr();
     } else {
@@ -2756,73 +2749,63 @@ nsXPCComponents_Utils::EvalInSandbox(con
         nsCOMPtr<nsIStackFrame> frame;
         xpc->GetCurrentJSStack(getter_AddRefs(frame));
         if (frame) {
             frame->GetFilename(getter_Copies(filename));
             frame->GetLineNumber(&lineNo);
         }
     }
 
-    RootedValue rval(cx);
-    nsresult rv = xpc::EvalInSandbox(cx, sandbox, source, filename.get(), lineNo,
-                                     jsVersion, false, &rval);
-    NS_ENSURE_SUCCESS(rv, rv);
-    *retval = rval;
-    return NS_OK;
+    return xpc::EvalInSandbox(cx, sandbox, source, filename.get(), lineNo,
+                              jsVersion, false, retval);
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetSandboxMetadata(const Value &sandboxVal,
-                                          JSContext *cx, Value *rval)
+nsXPCComponents_Utils::GetSandboxMetadata(HandleValue sandboxVal,
+                                          JSContext *cx, MutableHandleValue rval)
 {
     if (!sandboxVal.isObject())
         return NS_ERROR_INVALID_ARG;
 
     RootedObject sandbox(cx, &sandboxVal.toObject());
     sandbox = js::CheckedUnwrap(sandbox);
     if (!sandbox || !xpc::IsSandbox(sandbox))
         return NS_ERROR_INVALID_ARG;
 
-    RootedValue metadata(cx);
-    nsresult rv = xpc::GetSandboxMetadata(cx, sandbox, &metadata);
-    NS_ENSURE_SUCCESS(rv, rv);
-    *rval = metadata;
-
-    return NS_OK;
+    return xpc::GetSandboxMetadata(cx, sandbox, rval);
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::SetSandboxMetadata(const Value &sandboxVal,
-                                          const Value &metadataVal,
+nsXPCComponents_Utils::SetSandboxMetadata(HandleValue sandboxVal,
+                                          HandleValue metadataVal,
                                           JSContext *cx)
 {
     if (!sandboxVal.isObject())
         return NS_ERROR_INVALID_ARG;
 
     RootedObject sandbox(cx, &sandboxVal.toObject());
     sandbox = js::CheckedUnwrap(sandbox);
     if (!sandbox || !xpc::IsSandbox(sandbox))
         return NS_ERROR_INVALID_ARG;
 
-    RootedValue metadata(cx, metadataVal);
-    nsresult rv = xpc::SetSandboxMetadata(cx, sandbox, metadata);
+    nsresult rv = xpc::SetSandboxMetadata(cx, sandbox, metadataVal);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
 /* JSObject import (in AUTF8String registryLocation,
  *                  [optional] in JSObject targetObj);
  */
 NS_IMETHODIMP
 nsXPCComponents_Utils::Import(const nsACString& registryLocation,
-                              const Value& targetObj,
+                              HandleValue targetObj,
                               JSContext* cx,
                               uint8_t optionalArgc,
-                              Value* retval)
+                              MutableHandleValue retval)
 {
     nsCOMPtr<xpcIJSModuleLoader> moduleloader =
         do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
     if (!moduleloader)
         return NS_ERROR_FAILURE;
     return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval);
 }
 
@@ -2837,17 +2820,17 @@ nsXPCComponents_Utils::Unload(const nsAC
         return NS_ERROR_FAILURE;
     return moduleloader->Unload(registryLocation);
 }
 
 /*
  * JSObject importGlobalProperties (in jsval aPropertyList);
  */
 NS_IMETHODIMP
-nsXPCComponents_Utils::ImportGlobalProperties(const JS::Value& aPropertyList,
+nsXPCComponents_Utils::ImportGlobalProperties(HandleValue aPropertyList,
                                               JSContext* cx)
 {
     RootedObject global(cx, CurrentGlobalOrNull(cx));
     MOZ_ASSERT(global);
     GlobalProperties options;
     NS_ENSURE_TRUE(aPropertyList.isObject(), NS_ERROR_INVALID_ARG);
     RootedObject propertyList(cx, &aPropertyList.toObject());
     NS_ENSURE_TRUE(JS_IsArrayObject(cx, propertyList), NS_ERROR_INVALID_ARG);
@@ -2857,17 +2840,17 @@ nsXPCComponents_Utils::ImportGlobalPrope
         return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
 }
 
 /* xpcIJSWeakReference getWeakReference (); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetWeakReference(const Value &object, JSContext *cx,
+nsXPCComponents_Utils::GetWeakReference(HandleValue object, JSContext *cx,
                                         xpcIJSWeakReference **_retval)
 {
     nsRefPtr<xpcJSWeakReference> ref = new xpcJSWeakReference();
     nsresult rv = ref->Init(cx, object);
     NS_ENSURE_SUCCESS(rv, rv);
     ref.forget(_retval);
     return NS_OK;
 }
@@ -2946,74 +2929,73 @@ NS_IMETHODIMP
 nsXPCComponents_Utils::SchedulePreciseShrinkingGC(ScheduledGCCallback* aCallback)
 {
     nsRefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCallback, true);
     return NS_DispatchToMainThread(event);
 }
 
 /* [implicit_jscontext] jsval nondeterministicGetWeakMapKeys(in jsval aMap); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(const Value &aMap,
+nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(HandleValue aMap,
                                                       JSContext *aCx,
-                                                      Value *aKeys)
+                                                      MutableHandleValue aKeys)
 {
     if (!aMap.isObject()) {
-        aKeys->setUndefined();
+        aKeys.setUndefined();
         return NS_OK;
     }
     RootedObject objRet(aCx);
     if (!JS_NondeterministicGetWeakMapKeys(aCx, &aMap.toObject(), objRet.address()))
         return NS_ERROR_OUT_OF_MEMORY;
-    *aKeys = objRet ? ObjectValue(*objRet) : UndefinedValue();
+     aKeys.set(objRet ? ObjectValue(*objRet) : UndefinedValue());
     return NS_OK;
 }
 
 /* void getDebugObject(); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::GetJSTestingFunctions(JSContext *cx,
-                                             Value *retval)
+                                             MutableHandleValue retval)
 {
     JSObject *obj = js::GetTestingFunctions(cx);
     if (!obj)
         return NS_ERROR_XPC_JAVASCRIPT_ERROR;
-    *retval = OBJECT_TO_JSVAL(obj);
+    retval.setObject(*obj);
     return NS_OK;
 }
 
 /* void getGlobalForObject(); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetGlobalForObject(const Value& object,
+nsXPCComponents_Utils::GetGlobalForObject(HandleValue object,
                                           JSContext *cx,
-                                          Value *retval)
+                                          MutableHandleValue retval)
 {
     // First argument must be an object.
-    if (JSVAL_IS_PRIMITIVE(object))
+    if (object.isPrimitive())
         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));
+    Rooted<JSObject*> obj(cx, &object.toObject());
     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));
-
+      obj = outerize(cx, obj);
+
+    retval.setObject(*obj);
     return NS_OK;
 }
 
 /* jsval createObjectIn(in jsval vobj); */
 bool
 xpc::CreateObjectIn(JSContext *cx, HandleValue vobj, CreateObjectInOptions &options,
                     MutableHandleValue rval)
 {
@@ -3054,89 +3036,79 @@ xpc::CreateObjectIn(JSContext *cx, Handl
     if (!WrapperFactory::WaiveXrayAndWrap(cx, rval))
         return false;
 
     return true;
 }
 
 /* boolean isProxy(in value vobj); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::IsProxy(const Value &vobj, JSContext *cx, bool *rval)
+nsXPCComponents_Utils::IsProxy(HandleValue vobj, JSContext *cx, bool *rval)
 {
     if (!vobj.isObject()) {
         *rval = false;
         return NS_OK;
     }
 
     RootedObject obj(cx, &vobj.toObject());
     obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
     NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
 
     *rval = js::IsScriptedProxy(obj);
     return NS_OK;
 }
 
 /* jsval evalInWindow(in string source, in jsval window); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::EvalInWindow(const nsAString &source, const Value &window,
-                                    JSContext *cx, Value *rval)
+nsXPCComponents_Utils::EvalInWindow(const nsAString &source, HandleValue window,
+                                    JSContext *cx, MutableHandleValue rval)
 {
     if (!window.isObject())
         return NS_ERROR_INVALID_ARG;
 
     RootedObject rwindow(cx, &window.toObject());
-    RootedValue res(cx);
-    if (!xpc::EvalInWindow(cx, source, rwindow, &res))
+    if (!xpc::EvalInWindow(cx, source, rwindow, rval))
         return NS_ERROR_FAILURE;
-
-    *rval = res;
     return NS_OK;
 }
 
 /* jsval exportFunction(in jsval vfunction, in jsval vscope, in jsval vname); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::ExportFunction(const Value &vfunction, const Value &vscope,
-                                      const Value &voptions, JSContext *cx, Value *rval)
+nsXPCComponents_Utils::ExportFunction(HandleValue vfunction, HandleValue vscope,
+                                      HandleValue voptions, JSContext *cx,
+                                      MutableHandleValue rval)
 {
-    RootedValue rfunction(cx, vfunction);
-    RootedValue rscope(cx, vscope);
-    RootedValue roptions(cx, voptions);
-    RootedValue res(cx);
-    if (!xpc::ExportFunction(cx, rfunction, rscope, roptions, &res))
+    if (!xpc::ExportFunction(cx, vfunction, vscope, voptions, rval))
         return NS_ERROR_FAILURE;
-    *rval = res;
     return NS_OK;
 }
 
 /* jsval createObjectIn(in jsval vobj, [optional] in jsval voptions); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::CreateObjectIn(const Value &vobj, const Value &voptions,
-                                      JSContext *cx, Value *rval)
+nsXPCComponents_Utils::CreateObjectIn(HandleValue vobj, HandleValue voptions,
+                                      JSContext *cx, MutableHandleValue rval)
 {
     RootedObject optionsObject(cx, voptions.isObject() ? &voptions.toObject()
                                                        : nullptr);
     CreateObjectInOptions options(cx, optionsObject);
     if (voptions.isObject() &&
         !options.Parse())
     {
         return NS_ERROR_FAILURE;
     }
 
-    RootedValue rvobj(cx, vobj);
-    RootedValue res(cx);
-    if (!xpc::CreateObjectIn(cx, rvobj, options, &res))
+    if (!xpc::CreateObjectIn(cx, vobj, options, rval))
         return NS_ERROR_FAILURE;
-
-    *rval = res;
     return NS_OK;
 }
 
 /* jsval createObjectIn(in jsval vobj); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::CreateArrayIn(const Value &vobj, JSContext *cx, Value *rval)
+nsXPCComponents_Utils::CreateArrayIn(HandleValue vobj, JSContext *cx,
+                                     MutableHandleValue rval)
 {
     if (!cx)
         return NS_ERROR_FAILURE;
 
     // first argument must be an object
     if (vobj.isPrimitive())
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
@@ -3147,23 +3119,24 @@ nsXPCComponents_Utils::CreateArrayIn(con
         obj =  JS_NewArrayObject(cx, 0, nullptr);
         if (!obj)
             return NS_ERROR_FAILURE;
     }
 
     if (!JS_WrapObject(cx, &obj))
         return NS_ERROR_FAILURE;
 
-    *rval = ObjectValue(*obj);
+    rval.setObject(*obj);
     return NS_OK;
 }
 
 /* jsval createDateIn(in jsval vobj, in long long msec); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::CreateDateIn(const Value &vobj, int64_t msec, JSContext *cx, Value *rval)
+nsXPCComponents_Utils::CreateDateIn(HandleValue vobj, int64_t msec, JSContext *cx,
+                                    MutableHandleValue rval)
 {
     if (!cx)
         return NS_ERROR_FAILURE;
 
     // first argument must be an object
     if (!vobj.isObject())
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
@@ -3174,23 +3147,23 @@ nsXPCComponents_Utils::CreateDateIn(cons
         obj =  JS_NewDateObjectMsec(cx, msec);
         if (!obj)
             return NS_ERROR_FAILURE;
     }
 
     if (!JS_WrapObject(cx, &obj))
         return NS_ERROR_FAILURE;
 
-    *rval = ObjectValue(*obj);
+    rval.setObject(*obj);
     return NS_OK;
 }
 
 /* void makeObjectPropsNormal(jsval vobj); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::MakeObjectPropsNormal(const Value &vobj, JSContext *cx)
+nsXPCComponents_Utils::MakeObjectPropsNormal(HandleValue vobj, JSContext *cx)
 {
     if (!cx)
         return NS_ERROR_FAILURE;
 
     // first argument must be an object
     if (vobj.isPrimitive())
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
@@ -3220,32 +3193,32 @@ nsXPCComponents_Utils::MakeObjectPropsNo
             !JS_SetPropertyById(cx, obj, id, v))
             return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::IsDeadWrapper(const jsval &obj, bool *out)
+nsXPCComponents_Utils::IsDeadWrapper(HandleValue obj, bool *out)
 {
     *out = false;
-    if (JSVAL_IS_PRIMITIVE(obj))
+    if (obj.isPrimitive())
         return NS_ERROR_INVALID_ARG;
 
     // Make sure to unwrap first. Once a proxy is nuked, it ceases to be a
     // wrapper, meaning that, if passed to another compartment, we'll generate
     // a CCW for it. Make sure that IsDeadWrapper sees through the confusion.
-    *out = JS_IsDeadWrapper(js::CheckedUnwrap(JSVAL_TO_OBJECT(obj)));
+    *out = JS_IsDeadWrapper(js::CheckedUnwrap(&obj.toObject()));
     return NS_OK;
 }
 
 /* void recomputerWrappers(jsval vobj); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::RecomputeWrappers(const jsval &vobj, JSContext *cx)
+nsXPCComponents_Utils::RecomputeWrappers(HandleValue vobj, JSContext *cx)
 {
     // Determine the compartment of the given object, if any.
     JSCompartment *c = vobj.isObject()
                        ? js::GetObjectCompartment(js::UncheckedUnwrap(&vobj.toObject()))
                        : nullptr;
 
     // If no compartment was given, recompute all.
     if (!c)
@@ -3255,54 +3228,54 @@ nsXPCComponents_Utils::RecomputeWrappers
         js::RecomputeWrappers(cx, js::SingleCompartment(c), js::AllCompartments()) &&
         js::RecomputeWrappers(cx, js::AllCompartments(), js::SingleCompartment(c));
 
     return NS_OK;
 }
 
 /* jsval setWantXrays(jsval vscope); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::SetWantXrays(const jsval &vscope, JSContext *cx)
+nsXPCComponents_Utils::SetWantXrays(HandleValue vscope, JSContext *cx)
 {
     if (!vscope.isObject())
         return NS_ERROR_INVALID_ARG;
     JSObject *scopeObj = js::UncheckedUnwrap(&vscope.toObject());
     JSCompartment *compartment = js::GetObjectCompartment(scopeObj);
     EnsureCompartmentPrivate(scopeObj)->wantXrays = true;
     bool ok = js::RecomputeWrappers(cx, js::SingleCompartment(compartment),
                                     js::AllCompartments());
     NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
     return NS_OK;
 }
 
 /* jsval getComponentsForScope(jsval vscope); */
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetComponentsForScope(const jsval &vscope, JSContext *cx,
-                                             jsval *rval)
+nsXPCComponents_Utils::GetComponentsForScope(HandleValue vscope, JSContext *cx,
+                                             MutableHandleValue rval)
 {
     if (!vscope.isObject())
         return NS_ERROR_INVALID_ARG;
     JSObject *scopeObj = js::UncheckedUnwrap(&vscope.toObject());
     XPCWrappedNativeScope *scope = GetObjectScope(scopeObj);
     RootedObject components(cx, scope->GetComponentsJSObject());
     if (!components)
         return NS_ERROR_FAILURE;
     if (!JS_WrapObject(cx, &components))
         return NS_ERROR_FAILURE;
-    *rval = ObjectValue(*components);
+    rval.setObject(*components);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::Dispatch(const jsval &runnableArg, const jsval &scope,
+nsXPCComponents_Utils::Dispatch(HandleValue runnableArg, HandleValue scope,
                                 JSContext *cx)
 {
     // Enter the given compartment, if any, and rewrap runnable.
+    RootedValue runnable(cx, runnableArg);
     Maybe<JSAutoCompartment> ac;
-    RootedValue runnable(cx, runnableArg);
     if (scope.isObject()) {
         JSObject *scopeObj = js::UncheckedUnwrap(&scope.toObject());
         if (!scopeObj)
             return NS_ERROR_FAILURE;
         ac.construct(cx, scopeObj);
         if (!JS_WrapValue(cx, &runnable))
             return NS_ERROR_FAILURE;
     }
@@ -3383,96 +3356,96 @@ nsXPCComponents_Utils::SetGCZeal(int32_t
 {
 #ifdef JS_GC_ZEAL
     JS_SetGCZeal(cx, uint8_t(aValue), JS_DEFAULT_ZEAL_FREQ);
 #endif
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::NukeSandbox(const Value &obj, JSContext *cx)
+nsXPCComponents_Utils::NukeSandbox(HandleValue obj, JSContext *cx)
 {
     NS_ENSURE_TRUE(obj.isObject(), NS_ERROR_INVALID_ARG);
     JSObject *wrapper = &obj.toObject();
     NS_ENSURE_TRUE(IsWrapper(wrapper), NS_ERROR_INVALID_ARG);
     JSObject *sb = UncheckedUnwrap(wrapper);
     NS_ENSURE_TRUE(IsSandbox(sb), NS_ERROR_INVALID_ARG);
     NukeCrossCompartmentWrappers(cx, AllCompartments(),
                                  SingleCompartment(GetObjectCompartment(sb)),
                                  NukeWindowReferences);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::BlockScriptForGlobal(const JS::Value &globalArg,
+nsXPCComponents_Utils::BlockScriptForGlobal(HandleValue globalArg,
                                             JSContext *cx)
 {
     NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG);
     RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(),
                                             /* stopAtOuter = */ false));
     NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG);
     if (nsContentUtils::IsSystemPrincipal(GetObjectPrincipal(global))) {
         JS_ReportError(cx, "Script may not be disabled for system globals");
         return NS_ERROR_FAILURE;
     }
     Scriptability::Get(global).Block();
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::UnblockScriptForGlobal(const JS::Value &globalArg,
+nsXPCComponents_Utils::UnblockScriptForGlobal(HandleValue globalArg,
                                               JSContext *cx)
 {
     NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG);
     RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(),
                                             /* stopAtOuter = */ false));
     NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG);
     if (nsContentUtils::IsSystemPrincipal(GetObjectPrincipal(global))) {
         JS_ReportError(cx, "Script may not be disabled for system globals");
         return NS_ERROR_FAILURE;
     }
     Scriptability::Get(global).Unblock();
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::IsXrayWrapper(const Value &obj, bool* aRetval)
+nsXPCComponents_Utils::IsXrayWrapper(HandleValue obj, bool* aRetval)
 {
     *aRetval =
         obj.isObject() && xpc::WrapperFactory::IsXrayWrapper(&obj.toObject());
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::WaiveXrays(const Value &aVal, JSContext *aCx, jsval *aRetval)
+nsXPCComponents_Utils::WaiveXrays(HandleValue aVal, JSContext *aCx, MutableHandleValue aRetval)
 {
     RootedValue value(aCx, aVal);
     if (!xpc::WrapperFactory::WaiveXrayAndWrap(aCx, &value))
         return NS_ERROR_FAILURE;
-    *aRetval = value;
+    aRetval.set(value);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::UnwaiveXrays(const Value &aVal, JSContext *aCx, jsval *aRetval)
+nsXPCComponents_Utils::UnwaiveXrays(HandleValue aVal, JSContext *aCx, MutableHandleValue aRetval)
 {
     if (!aVal.isObject()) {
-        *aRetval = aVal;
+        aRetval.set(aVal);
         return NS_OK;
     }
 
     RootedObject obj(aCx, js::UncheckedUnwrap(&aVal.toObject()));
     if (!JS_WrapObject(aCx, &obj))
         return NS_ERROR_FAILURE;
-    *aRetval = ObjectValue(*obj);
+    aRetval.setObject(*obj);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetClassName(const Value &aObj, bool aUnwrap, JSContext *aCx, char **aRv)
+nsXPCComponents_Utils::GetClassName(HandleValue aObj, bool aUnwrap, JSContext *aCx, char **aRv)
 {
     if (!aObj.isObject())
         return NS_ERROR_INVALID_ARG;
     RootedObject obj(aCx, &aObj.toObject());
     if (aUnwrap)
         obj = js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);
     *aRv = NS_strdup(js::GetObjectClass(obj)->name);
     NS_ENSURE_TRUE(*aRv, NS_ERROR_OUT_OF_MEMORY);
@@ -3483,18 +3456,18 @@ NS_IMETHODIMP
 nsXPCComponents_Utils::GetDOMClassInfo(const nsAString& aClassName,
                                        nsIClassInfo** aClassInfo)
 {
     *aClassInfo = nullptr;
     return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::GetIncumbentGlobal(const Value &aCallback,
-                                          JSContext *aCx, Value *aOut)
+nsXPCComponents_Utils::GetIncumbentGlobal(HandleValue aCallback,
+                                          JSContext *aCx, MutableHandleValue aOut)
 {
     nsCOMPtr<nsIGlobalObject> global = mozilla::dom::GetIncumbentGlobal();
     RootedValue globalVal(aCx);
 
     if (!global) {
         globalVal = NullValue();
     } else {
         // Note: We rely on the wrap call for outerization.
@@ -3505,17 +3478,17 @@ nsXPCComponents_Utils::GetIncumbentGloba
 
     // Invoke the callback, if passed.
     if (aCallback.isObject()) {
         Value ignored;
         if (!JS_CallFunctionValue(aCx, nullptr, aCallback, 1, globalVal.address(), &ignored))
             return NS_ERROR_FAILURE;
     }
 
-    *aOut = globalVal;
+    aOut.set(globalVal);
     return NS_OK;
 }
 
 /*
  * Below is a bunch of awkward junk to allow JS test code to trigger the
  * creation of an XPCWrappedJS, such that it ends up in the map. We need to
  * hand the caller some sort of reference to hold onto (to prevent the
  * refcount from dropping to zero as soon as the function returns), but trying
@@ -3530,17 +3503,17 @@ class WrappedJSHolder : public nsISuppor
     WrappedJSHolder() {}
     virtual ~WrappedJSHolder() {}
 
     nsRefPtr<nsXPCWrappedJS> mWrappedJS;
 };
 NS_IMPL_ISUPPORTS0(WrappedJSHolder);
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::GenerateXPCWrappedJS(const Value &aObj, const Value &aScope,
+nsXPCComponents_Utils::GenerateXPCWrappedJS(HandleValue aObj, HandleValue aScope,
                                             JSContext *aCx, nsISupports **aOut)
 {
     if (!aObj.isObject())
         return NS_ERROR_INVALID_ARG;
     RootedObject obj(aCx, &aObj.toObject());
     RootedObject scope(aCx, aScope.isObject() ? js::UncheckedUnwrap(&aScope.toObject())
                                               : CurrentGlobalOrNull(aCx));
     JSAutoCompartment ac(aCx, scope);
@@ -3881,17 +3854,17 @@ nsXPCComponents::AttachComponentsObject(
     MOZ_ASSERT(js::IsObjectInContextCompartment(global, aCx));
 
     RootedId id(aCx, XPCJSRuntime::Get()->GetStringID(XPCJSRuntime::IDX_COMPONENTS));
     return JS_DefinePropertyById(aCx, global, id, ObjectValue(*components),
                                  nullptr, nullptr, JSPROP_PERMANENT | JSPROP_READONLY);
 }
 
 /* void reportError (); */
-NS_IMETHODIMP nsXPCComponents::ReportError(const Value &error, JSContext *cx)
+NS_IMETHODIMP nsXPCComponents::ReportError(HandleValue error, JSContext *cx)
 {
     NS_WARNING("Components.reportError deprecated, use Components.utils.reportError");
 
     nsCOMPtr<nsIXPCComponents_Utils> utils;
     nsresult rv = GetUtils(getter_AddRefs(utils));
     if (NS_FAILED(rv))
         return rv;
 
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -541,25 +541,25 @@ xpc::HasInstance(JSContext *cx, HandleOb
 
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsJSIID::HasInstance(nsIXPConnectWrappedNative *wrapper,
                      JSContext * cx, JSObject * /* unused */,
-                     const jsval &val, bool *bp, bool *_retval)
+                     HandleValue val, bool *bp, bool *_retval)
 {
     *bp = false;
 
-    if (JSVAL_IS_PRIMITIVE(val))
+    if (val.isPrimitive())
         return NS_OK;
 
     // we have a JSObject
-    RootedObject obj(cx, JSVAL_TO_OBJECT(val));
+    RootedObject obj(cx, &val.toObject());
 
     const nsIID* iid;
     mInfo->GetIIDShared(&iid);
     return xpc::HasInstance(cx, obj, iid, bp);
 }
 
 /* string canCreateWrapper (in nsIIDPtr iid); */
 NS_IMETHODIMP
@@ -716,18 +716,18 @@ GetWrapperObject(MutableHandleObject obj
 
     nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
     ccxp->GetCalleeWrapper(getter_AddRefs(wrapper));
     obj.set(wrapper->GetJSObject());
 }
 
 /* nsISupports createInstance (); */
 NS_IMETHODIMP
-nsJSCID::CreateInstance(const JS::Value& iidval, JSContext* cx,
-                        uint8_t optionalArgc, JS::Value* retval)
+nsJSCID::CreateInstance(HandleValue iidval, JSContext* cx,
+                        uint8_t optionalArgc, MutableHandleValue retval)
 {
     if (!mDetails.IsValid())
         return NS_ERROR_XPC_BAD_CID;
 
     RootedObject obj(cx);
     GetWrapperObject(&obj);
     if (!obj) {
         return NS_ERROR_UNEXPECTED;
@@ -752,25 +752,25 @@ nsJSCID::CreateInstance(const JS::Value&
     nsCOMPtr<nsISupports> inst;
     rv = compMgr->CreateInstance(mDetails.ID(), nullptr, *iid, getter_AddRefs(inst));
     MOZ_ASSERT(NS_FAILED(rv) || inst, "component manager returned success, but instance is null!");
 
     if (NS_FAILED(rv) || !inst)
         return NS_ERROR_XPC_CI_RETURNED_FAILURE;
 
     rv = nsXPConnect::XPConnect()->WrapNativeToJSVal(cx, obj, inst, nullptr, iid, true, retval);
-    if (NS_FAILED(rv) || JSVAL_IS_PRIMITIVE(*retval))
+    if (NS_FAILED(rv) || retval.isPrimitive())
         return NS_ERROR_XPC_CANT_CREATE_WN;
     return NS_OK;
 }
 
 /* nsISupports getService (); */
 NS_IMETHODIMP
-nsJSCID::GetService(const JS::Value& iidval, JSContext* cx,
-                    uint8_t optionalArgc, JS::Value* retval)
+nsJSCID::GetService(HandleValue iidval, JSContext* cx,
+                    uint8_t optionalArgc, MutableHandleValue retval)
 {
     if (!mDetails.IsValid())
         return NS_ERROR_XPC_BAD_CID;
 
     RootedObject obj(cx);
     GetWrapperObject(&obj);
     if (!obj) {
         return NS_ERROR_UNEXPECTED;
@@ -803,17 +803,17 @@ nsJSCID::GetService(const JS::Value& iid
     RootedObject instJSObj(cx);
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = nsXPConnect::XPConnect()->WrapNative(cx, obj, srvc, *iid, getter_AddRefs(holder));
     if (NS_FAILED(rv) || !holder ||
         // Assign, not compare
         !(instJSObj = holder->GetJSObject()))
         return NS_ERROR_XPC_CANT_CREATE_WN;
 
-    *retval = OBJECT_TO_JSVAL(instJSObj);
+    retval.setObject(*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
 nsJSCID::Construct(nsIXPConnectWrappedNative *wrapper,
                    JSContext * cx, JSObject * objArg,
                    const CallArgs &args, bool *_retval)
@@ -831,17 +831,17 @@ nsJSCID::Construct(nsIXPConnectWrappedNa
     *_retval = XPCWrappedNative::CallMethod(ccx);
     return NS_OK;
 }
 
 /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
 NS_IMETHODIMP
 nsJSCID::HasInstance(nsIXPConnectWrappedNative *wrapper,
                      JSContext * cx, JSObject * /* unused */,
-                     const jsval &val, bool *bp, bool *_retval)
+                     HandleValue val, bool *bp, bool *_retval)
 {
     *bp = false;
     nsresult rv = NS_OK;
 
     if (!JSVAL_IS_PRIMITIVE(val)) {
         // we have a JSObject
         RootedObject obj(cx, &val.toObject());
 
--- a/js/xpconnect/src/XPCJSWeakReference.cpp
+++ b/js/xpconnect/src/XPCJSWeakReference.cpp
@@ -48,51 +48,48 @@ nsresult xpcJSWeakReference::Init(JSCont
         NS_ERROR("can't get nsISupportsWeakReference wrapper for obj");
         return rv;
     }
 
     return wrapped->GetWeakReference(getter_AddRefs(mReferent));
 }
 
 NS_IMETHODIMP
-xpcJSWeakReference::Get(JSContext* aCx, JS::Value* aRetval)
+xpcJSWeakReference::Get(JSContext* aCx, MutableHandleValue aRetval)
 {
-    *aRetval = JSVAL_NULL;
+    aRetval.setNull();
 
     if (!mReferent) {
         return NS_OK;
     }
 
     nsCOMPtr<nsISupports> supports = do_QueryReferent(mReferent);
     if (!supports) {
         return NS_OK;
     }
 
     nsCOMPtr<nsIXPConnectWrappedJS> wrappedObj = do_QueryInterface(supports);
     if (!wrappedObj) {
         // We have a generic XPCOM object that supports weak references here.
         // Wrap it and pass it out.
         RootedObject global(aCx, CurrentGlobalOrNull(aCx));
-        RootedValue rval(aCx);
-        nsresult rv = nsContentUtils::WrapNative(aCx, global,
-                                                 supports, &NS_GET_IID(nsISupports),
-                                                 &rval);
-        *aRetval = rval;
-        return rv;
+        return nsContentUtils::WrapNative(aCx, global,
+                                          supports, &NS_GET_IID(nsISupports),
+                                          aRetval);
     }
 
     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
     // JS_WrapObject().
     if (!JS_WrapObject(aCx, &obj)) {
         return NS_ERROR_FAILURE;
     }
 
-    *aRetval = OBJECT_TO_JSVAL(obj);
+    aRetval.setObject(*obj);
     return NS_OK;
 }
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -581,17 +581,17 @@ Blob(JSContext *cx, unsigned argc, jsval
   if (NS_FAILED(rv)) {
     JS_ReportError(cx, "Could not get XPConnent service!");
     return false;
   }
 
   JSObject* global = JS::CurrentGlobalOrNull(cx);
   rv = xpc->WrapNativeToJSVal(cx, global, native, nullptr,
                               &NS_GET_IID(nsISupports), true,
-                              args.rval().address());
+                              args.rval());
   if (NS_FAILED(rv)) {
     JS_ReportError(cx, "Could not wrap native object!");
     return false;
   }
 
   return true;
 }
 
@@ -620,17 +620,17 @@ File(JSContext *cx, unsigned argc, jsval
   if (NS_FAILED(rv)) {
     JS_ReportError(cx, "Could not get XPConnent service!");
     return false;
   }
 
   JSObject* global = JS::CurrentGlobalOrNull(cx);
   rv = xpc->WrapNativeToJSVal(cx, global, native, nullptr,
                               &NS_GET_IID(nsISupports), true,
-                              args.rval().address());
+                              args.rval());
   if (NS_FAILED(rv)) {
     JS_ReportError(cx, "Could not wrap native object!");
     return false;
   }
 
   return true;
 }
 
--- a/js/xpconnect/src/XPCVariant.cpp
+++ b/js/xpconnect/src/XPCVariant.cpp
@@ -360,36 +360,35 @@ bool XPCVariant::InitializeData(JSContex
     const nsIID& iid = NS_GET_IID(nsISupports);
 
     return NS_SUCCEEDED(xpc->WrapJS(cx, jsobj,
                                     iid, getter_AddRefs(wrapper))) &&
            NS_SUCCEEDED(nsVariant::SetFromInterface(&mData, iid, wrapper));
 }
 
 NS_IMETHODIMP
-XPCVariant::GetAsJSVal(jsval* result)
+XPCVariant::GetAsJSVal(MutableHandleValue result)
 {
-  NS_PRECONDITION(result, "null result arg.");
-  *result = GetJSVal();
+  result.set(GetJSVal());
   return NS_OK;
 }
 
 // static
 bool
 XPCVariant::VariantDataToJS(nsIVariant* variant,
                             nsresult* pErr, MutableHandleValue pJSVal)
 {
     // Get the type early because we might need to spoof it below.
     uint16_t type;
     if (NS_FAILED(variant->GetDataType(&type)))
         return false;
 
     AutoJSContext cx;
     RootedValue realVal(cx);
-    nsresult rv = variant->GetAsJSVal(realVal.address());
+    nsresult rv = variant->GetAsJSVal(&realVal);
 
     if (NS_SUCCEEDED(rv) &&
         (JSVAL_IS_PRIMITIVE(realVal) ||
          type == nsIDataType::VTYPE_ARRAY ||
          type == nsIDataType::VTYPE_EMPTY_ARRAY ||
          type == nsIDataType::VTYPE_ID)) {
         if (!JS_WrapValue(cx, &realVal))
             return false;
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -574,29 +574,25 @@ nsXPConnect::WrapNative(JSContext * aJSC
 /* void wrapNativeToJSVal (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDPtr aIID, out jsval aVal, out nsIXPConnectJSObjectHolder aHolder); */
 NS_IMETHODIMP
 nsXPConnect::WrapNativeToJSVal(JSContext * aJSContext,
                                JSObject * aScopeArg,
                                nsISupports *aCOMObj,
                                nsWrapperCache *aCache,
                                const nsIID * aIID,
                                bool aAllowWrapping,
-                               jsval *aVal)
+                               MutableHandleValue aVal)
 {
     MOZ_ASSERT(aJSContext, "bad param");
     MOZ_ASSERT(aScopeArg, "bad param");
     MOZ_ASSERT(aCOMObj, "bad param");
 
     RootedObject aScope(aJSContext, aScopeArg);
-
-    RootedValue rval(aJSContext);
-    nsresult rv = NativeInterface2JSObject(aScope, aCOMObj, aCache, aIID,
-                                           aAllowWrapping, &rval, nullptr);
-    *aVal = rval;
-    return rv;
+    return NativeInterface2JSObject(aScope, aCOMObj, aCache, aIID,
+                                    aAllowWrapping, aVal, nullptr);
 }
 
 /* void wrapJS (in JSContextPtr aJSContext, in JSObjectPtr aJSObj, in nsIIDRef aIID, [iid_is (aIID), retval] out nsQIResult result); */
 NS_IMETHODIMP
 nsXPConnect::WrapJS(JSContext * aJSContext,
                     JSObject * aJSObjArg,
                     const nsIID & aIID,
                     void * *result)
@@ -614,23 +610,22 @@ nsXPConnect::WrapJS(JSContext * aJSConte
     if (!XPCConvert::JSObject2NativeInterface(result, aJSObj,
                                               &aIID, nullptr, &rv))
         return rv;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPConnect::JSValToVariant(JSContext *cx,
-                            jsval *aJSVal,
+                            HandleValue aJSVal,
                             nsIVariant ** aResult)
 {
-    NS_PRECONDITION(aJSVal, "bad param");
     NS_PRECONDITION(aResult, "bad param");
 
-    *aResult = XPCVariant::newVariant(cx, *aJSVal);
+    *aResult = XPCVariant::newVariant(cx, aJSVal);
     NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
 
     return NS_OK;
 }
 
 /* void wrapJSAggregatedToNative (in nsISupports aOuter, in JSContextPtr aJSContext, in JSObjectPtr aJSObj, in nsIIDRef aIID, [iid_is (aIID), retval] out nsQIResult result); */
 NS_IMETHODIMP
 nsXPConnect::WrapJSAggregatedToNative(nsISupports *aOuter,
@@ -892,29 +887,25 @@ nsXPConnect::CreateSandbox(JSContext *cx
     }
 
     return rv;
 }
 
 NS_IMETHODIMP
 nsXPConnect::EvalInSandboxObject(const nsAString& source, const char *filename,
                                  JSContext *cx, JSObject *sandboxArg,
-                                 bool returnStringOnly, JS::Value *rvalArg)
+                                 bool returnStringOnly, MutableHandleValue rval)
 {
     if (!sandboxArg)
         return NS_ERROR_INVALID_ARG;
 
     RootedObject sandbox(cx, sandboxArg);
-    RootedValue rval(cx);
-    nsresult rv = EvalInSandbox(cx, sandbox, source, filename ? filename :
-                                "x-bogus://XPConnect/Sandbox", 1, JSVERSION_DEFAULT,
-                                returnStringOnly, &rval);
-    NS_ENSURE_SUCCESS(rv, rv);
-    *rvalArg = rval;
-    return NS_OK;
+    return EvalInSandbox(cx, sandbox, source, filename ? filename :
+                         "x-bogus://XPConnect/Sandbox", 1, JSVERSION_DEFAULT,
+                         returnStringOnly, rval);
 }
 
 /* nsIXPConnectJSObjectHolder getWrappedNativePrototype (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsIClassInfo aClassInfo); */
 NS_IMETHODIMP
 nsXPConnect::GetWrappedNativePrototype(JSContext * aJSContext,
                                        JSObject * aScopeArg,
                                        nsIClassInfo *aClassInfo,
                                        nsIXPConnectJSObjectHolder **_retval)
@@ -1050,42 +1041,38 @@ nsXPConnect::DebugDumpEvalInJSStackFrame
         xpc_DumpEvalInJSStackFrame(cx, aFrameNumber, aSourceText);
 
     return NS_OK;
 }
 
 /* jsval variantToJS (in JSContextPtr ctx, in JSObjectPtr scope, in nsIVariant value); */
 NS_IMETHODIMP
 nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scopeArg, nsIVariant* value,
-                         jsval* _retval)
+                         MutableHandleValue _retval)
 {
     NS_PRECONDITION(ctx, "bad param");
     NS_PRECONDITION(scopeArg, "bad param");
     NS_PRECONDITION(value, "bad param");
-    NS_PRECONDITION(_retval, "bad param");
 
     RootedObject scope(ctx, scopeArg);
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, ctx));
 
     nsresult rv = NS_OK;
-    RootedValue rval(ctx);
-    if (!XPCVariant::VariantDataToJS(value, &rv, &rval)) {
+    if (!XPCVariant::VariantDataToJS(value, &rv, _retval)) {
         if (NS_FAILED(rv))
             return rv;
 
         return NS_ERROR_FAILURE;
     }
-
-    *_retval = rval;
     return NS_OK;
 }
 
 /* nsIVariant JSToVariant (in JSContextPtr ctx, in jsval value); */
 NS_IMETHODIMP
-nsXPConnect::JSToVariant(JSContext* ctx, const jsval &value, nsIVariant** _retval)
+nsXPConnect::JSToVariant(JSContext* ctx, HandleValue value, nsIVariant** _retval)
 {
     NS_PRECONDITION(ctx, "bad param");
     NS_PRECONDITION(_retval, "bad param");
 
     *_retval = XPCVariant::newVariant(ctx, value);
     if (!(*_retval))
         return NS_ERROR_FAILURE;
 
@@ -1413,17 +1400,17 @@ nsXPConnect::SetDebugModeWhenPossible(bo
 {
     gDesiredDebugMode = mode;
     if (!mode && allowSyncDisable)
         CheckForDebugMode(mRuntime->Runtime());
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXPConnect::GetTelemetryValue(JSContext *cx, jsval *rval)
+nsXPConnect::GetTelemetryValue(JSContext *cx, MutableHandleValue rval)
 {
     RootedObject obj(cx, JS_NewObject(cx, nullptr, nullptr, nullptr));
     if (!obj)
         return NS_ERROR_OUT_OF_MEMORY;
 
     unsigned attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
 
     size_t i = JS_SetProtoCalled(cx);
@@ -1431,17 +1418,17 @@ nsXPConnect::GetTelemetryValue(JSContext
     if (!JS_DefineProperty(cx, obj, "setProto", v, nullptr, nullptr, attrs))
         return NS_ERROR_OUT_OF_MEMORY;
 
     i = JS_GetCustomIteratorCount(cx);
     v = DOUBLE_TO_JSVAL(i);
     if (!JS_DefineProperty(cx, obj, "customIter", v, nullptr, nullptr, attrs))
         return NS_ERROR_OUT_OF_MEMORY;
 
-    *rval = OBJECT_TO_JSVAL(obj);
+    rval.setObject(*obj);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPConnect::NotifyDidPaint()
 {
     JS::NotifyDidPaint(GetRuntime()->Runtime());
     return NS_OK;
--- a/js/xpconnect/src/qsgen.py
+++ b/js/xpconnect/src/qsgen.py
@@ -608,18 +608,18 @@ def writeResultDecl(f, type, varname):
     f.write("    !; // TODO - Declare out parameter `%s`.\n" % varname)
 
 def outParamForm(name, type):
     type = unaliasType(type)
     if type.kind == 'builtin':
         return '&' + name
     elif type.kind == 'native':
         if getBuiltinOrNativeTypeName(type) == '[jsval]':
-            return name + '.address()'
-        elif type.modifier == 'ref':
+            return '&' + name
+        if type.modifier == 'ref':
             return name
         else:
             return '&' + name
     else:
         return 'getter_AddRefs(%s)' % name
 
 # From NativeData2JS.
 resultConvTemplates = {
--- a/js/xpconnect/tests/components/native/xpctest_params.cpp
+++ b/js/xpconnect/tests/components/native/xpctest_params.cpp
@@ -192,21 +192,23 @@ NS_IMETHODIMP nsXPCTestParams::TestAUTF8
 }
 
 /* ACString testACString (in ACString a, inout ACString b); */
 NS_IMETHODIMP nsXPCTestParams::TestACString(const nsACString & a, nsACString & b, nsACString & _retval)
 {
     STRING_METHOD_IMPL;
 }
 
-/* jsval testJsval (in jsval a, inout jsval b); */
-NS_IMETHODIMP nsXPCTestParams::TestJsval(const jsval & a, jsval & b, jsval *_retval)
+/* jsval testJsval (in jsval a, in jsval b); */
+NS_IMETHODIMP nsXPCTestParams::TestJsval(JS::Handle<JS::Value> a,
+                                         JS::MutableHandle<JS::Value> b,
+                                         JS::MutableHandle<JS::Value> _retval)
 {
-    *_retval = b;
-    b = a;
+    _retval.set(b);
+    b.set(a);
     return NS_OK;
 }
 
 /* void testShortArray (in unsigned long aLength, [array, size_is (aLength)] in short a,
  *                      inout unsigned long bLength, [array, size_is (bLength)] inout short b,
  *                      out unsigned long rvLength, [array, size_is (rvLength), retval] out short rv); */
 NS_IMETHODIMP nsXPCTestParams::TestShortArray(uint32_t aLength, int16_t *a,
                                               uint32_t *bLength, int16_t **b,
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -277,18 +277,17 @@ WrapperFactory::PrepareForWrapping(JSCon
         }
     }
 
     // This public WrapNativeToJSVal API enters the compartment of 'wrapScope'
     // so we don't have to.
     RootedValue v(cx);
     nsresult rv =
         nsXPConnect::XPConnect()->WrapNativeToJSVal(cx, wrapScope, wn->Native(), nullptr,
-                                                    &NS_GET_IID(nsISupports), false,
-                                                    v.address());
+                                                    &NS_GET_IID(nsISupports), false, &v);
     NS_ENSURE_SUCCESS(rv, nullptr);
 
     obj = JSVAL_TO_OBJECT(v);
     MOZ_ASSERT(IS_WN_REFLECTOR(obj), "bad object");
 
     // Because the underlying native didn't have a PreCreate hook, we had
     // to a new (or possibly pre-existing) XPCWN in our compartment.
     // This could be a problem for chrome code that passes XPCOM objects