Bug 952650 (part 12) - Remove JSVAL_TO_OBJECT. r=till.
authorNicholas Nethercote <nnethercote@mozilla.com>
Sun, 27 Apr 2014 19:58:52 -0700
changeset 180920 a61fdeb956a6320950735cd4efc1c743f378d402
parent 180919 d5711e3806d056664938d62ef58f2c54eeff6cf0
child 180921 7cdc75f1615bce66f71c58742d01ed888e2ad038
push id26686
push usercbook@mozilla.com
push dateWed, 30 Apr 2014 13:00:57 +0000
treeherdermozilla-central@c8b374bf936b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs952650
milestone32.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 952650 (part 12) - Remove JSVAL_TO_OBJECT. r=till.
content/base/src/nsDocument.cpp
content/base/src/nsXMLHttpRequest.cpp
content/canvas/src/CanvasUtils.h
content/xul/templates/src/nsXULTemplateBuilder.cpp
dom/base/MessagePort.cpp
dom/base/nsDOMWindowUtils.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/IndexedDatabaseManager.cpp
dom/indexedDB/KeyPath.cpp
dom/plugins/base/nsJSNPRuntime.cpp
dom/workers/ChromeWorkerScope.cpp
ipc/nfc/Nfc.cpp
ipc/ril/Ril.cpp
js/jsd/jsd_obj.cpp
js/jsd/jsd_step.cpp
js/jsd/jsd_val.cpp
js/public/CallArgs.h
js/public/Value.h
js/src/ctypes/CTypes.cpp
js/src/jsapi-tests/testAddPropertyPropcache.cpp
js/src/jsapi-tests/testArgumentsObject.cpp
js/src/jsapi-tests/testBindCallable.cpp
js/src/jsapi-tests/testConservativeGC.cpp
js/src/jsapi-tests/testDeepFreeze.cpp
js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp
js/src/jsapi-tests/testDefineProperty.cpp
js/src/jsapi-tests/testFunctionProperties.cpp
js/src/jsapi-tests/testLookup.cpp
js/src/jsapi-tests/testMappedArrayBuffer.cpp
js/src/jsapi-tests/testNewObject.cpp
js/src/jsapi-tests/testParseJSON.cpp
js/src/jsapi-tests/testRegExp.cpp
js/src/jsapi-tests/testRegExpInstanceProperties.cpp
js/src/jsexn.cpp
js/src/jsopcode.cpp
js/src/perf/jsperf.cpp
js/src/shell/js.cpp
js/src/tests/js1_5/Regress/regress-457065-03.js
js/src/tests/js1_8/regress/regress-457065-01.js
js/src/tests/js1_8/regress/regress-457065-02.js
js/src/tests/js1_8_1/regress/regress-452498-123.js
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/XPCQuickStubs.h
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/qsgen.py
toolkit/components/ctypes/ctypes.cpp
toolkit/components/places/History.cpp
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -12150,17 +12150,17 @@ nsIDocument::WrapObject(JSContext *aCx)
                                            false);
   if (NS_FAILED(rv)) {
     Throw(aCx, rv);
     return nullptr;
   }
 
   NS_NAMED_LITERAL_STRING(doc_str, "document");
 
-  if (!JS_DefineUCProperty(aCx, JSVAL_TO_OBJECT(winVal), doc_str.get(),
+  if (!JS_DefineUCProperty(aCx, winVal.toObjectOrNull(), doc_str.get(),
                            doc_str.Length(), JS::ObjectValue(*obj),
                            JS_PropertyStub, JS_StrictPropertyStub,
                            JSPROP_READONLY | JSPROP_ENUMERATE)) {
     return nullptr;
   }
 
   return obj;
 }
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -2446,17 +2446,17 @@ GetRequestBody(nsIVariant* aBody, nsIInp
     }
 
     // ArrayBuffer?
     AutoSafeJSContext cx;
     JS::Rooted<JS::Value> realVal(cx);
 
     nsresult rv = aBody->GetAsJSVal(&realVal);
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal)) {
-      JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(realVal));
+      JS::Rooted<JSObject*> obj(cx, realVal.toObjectOrNull());
       if (JS_IsArrayBufferObject(obj)) {
           ArrayBuffer buf(obj);
           return GetRequestBody(buf.Data(), buf.Length(), aResult,
                                 aContentLength, aContentType, aCharset);
       }
     }
   }
   else if (dataType == nsIDataType::VTYPE_VOID ||
--- a/content/canvas/src/CanvasUtils.h
+++ b/content/canvas/src/CanvasUtils.h
@@ -102,17 +102,17 @@ nsresult
 JSValToDashArray(JSContext* cx, const JS::Value& patternArray,
                  FallibleTArray<T>& dashes)
 {
     // The cap is pretty arbitrary.  16k should be enough for
     // anybody...
     static const uint32_t MAX_NUM_DASHES = 1 << 14;
 
     if (!JSVAL_IS_PRIMITIVE(patternArray)) {
-        JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(patternArray));
+        JS::Rooted<JSObject*> obj(cx, patternArray.toObjectOrNull());
         uint32_t length;
         if (!JS_GetArrayLength(cx, obj, &length)) {
             // Not an array-like thing
             return NS_ERROR_INVALID_ARG;
         } else if (length > MAX_NUM_DASHES) {
             // Too many dashes in the pattern
             return NS_ERROR_ILLEGAL_VALUE;
         }
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -1387,17 +1387,17 @@ nsXULTemplateBuilder::InitHTMLTemplateRo
     // point, but as this is XUL related it does not appear in the HTML spec.
     AutoEntryScript entryScript(innerWin, true);
     JSContext* jscontext = entryScript.cx();
 
     JS::Rooted<JS::Value> v(jscontext);
     rv = nsContentUtils::WrapNative(jscontext, mRoot, mRoot, &v);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    JS::Rooted<JSObject*> jselement(jscontext, JSVAL_TO_OBJECT(v));
+    JS::Rooted<JSObject*> jselement(jscontext, v.toObjectOrNull());
 
     if (mDB) {
         // database
         JS::Rooted<JS::Value> jsdatabase(jscontext);
         rv = nsContentUtils::WrapNative(jscontext, mDB,
                                         &NS_GET_IID(nsIRDFCompositeDataSource),
                                         &jsdatabase);
         NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/base/MessagePort.cpp
+++ b/dom/base/MessagePort.cpp
@@ -104,17 +104,17 @@ PostMessageReadStructuredClone(JSContext
 {
   if (tag == SCTAG_DOM_BLOB || tag == SCTAG_DOM_FILELIST) {
     NS_ASSERTION(!data, "Data should be empty");
 
     nsISupports* supports;
     if (JS_ReadBytes(reader, &supports, sizeof(supports))) {
       JS::Rooted<JS::Value> val(cx);
       if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, supports, &val))) {
-        return JSVAL_TO_OBJECT(val);
+        return val.toObjectOrNull();
       }
     }
   }
 
   const JSStructuredCloneCallbacks* runtimeCallbacks =
     js::GetContextStructuredCloneCallbacks(cx);
 
   if (runtimeCallbacks) {
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2385,17 +2385,17 @@ nsDOMWindowUtils::GetClassName(JS::Handl
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // Our argument must be a non-null object.
   if (JSVAL_IS_PRIMITIVE(aObject)) {
     return NS_ERROR_XPC_BAD_CONVERT_JS;
   }
 
-  *aName = NS_strdup(JS_GetClass(JSVAL_TO_OBJECT(aObject))->name);
+  *aName = NS_strdup(JS_GetClass(aObject.toObjectOrNull())->name);
   NS_ABORT_IF_FALSE(*aName, "NS_strdup should be infallible.");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetVisitedDependentComputedStyle(
                     nsIDOMElement *aElement, const nsAString& aPseudoElement,
                     const nsAString& aPropertyName, nsAString& aResult)
@@ -3208,17 +3208,17 @@ NS_IMETHODIMP
 nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
                             int64_t* aResult)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   if (!JSVAL_IS_PRIMITIVE(aFile)) {
-    JSObject* obj = JSVAL_TO_OBJECT(aFile);
+    JSObject* obj = aFile.toObjectOrNull();
 
     file::FileHandle* fileHandle;
     if (NS_SUCCEEDED(UNWRAP_OBJECT(FileHandle, obj, fileHandle))) {
       *aResult = fileHandle->GetFileId();
       return NS_OK;
     }
 
     nsISupports* nativeObj =
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -832,17 +832,17 @@ public:
       JS::Rooted<JS::Value> wrappedBlob(aCx);
       rv = nsContentUtils::WrapNative(aCx, domBlob, &NS_GET_IID(nsIDOMBlob),
                                       &wrappedBlob);
       if (NS_FAILED(rv)) {
         NS_WARNING("Failed to wrap native!");
         return nullptr;
       }
 
-      return JSVAL_TO_OBJECT(wrappedBlob);
+      return wrappedBlob.toObjectOrNull();
     }
 
     nsCOMPtr<nsIDOMFile> domFile;
     if (aFile.mFile) {
       if (!ResolveMysteryFile(aFile.mFile, aData.name, aData.type, aData.size,
                               aData.lastModifiedDate)) {
         return nullptr;
       }
@@ -857,17 +857,17 @@ public:
     JS::Rooted<JS::Value> wrappedFile(aCx);
     rv = nsContentUtils::WrapNative(aCx, domFile, &NS_GET_IID(nsIDOMFile),
                                     &wrappedFile);
     if (NS_FAILED(rv)) {
       NS_WARNING("Failed to wrap native!");
       return nullptr;
     }
 
-    return JSVAL_TO_OBJECT(wrappedFile);
+    return wrappedFile.toObjectOrNull();
   }
 };
 
 
 class CreateIndexDeserializationTraits
 {
 public:
   static JSObject* CreateAndWrapFileHandle(JSContext* aCx,
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -650,17 +650,17 @@ NS_IMPL_RELEASE_WITH_DESTROY(IndexedData
 NS_IMPL_QUERY_INTERFACE(IndexedDatabaseManager, nsIIndexedDatabaseManager,
                         nsIObserver)
 
 NS_IMETHODIMP
 IndexedDatabaseManager::InitWindowless(JS::Handle<JS::Value> aGlobal, JSContext* aCx)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
-  JS::Rooted<JSObject*> global(aCx, JSVAL_TO_OBJECT(aGlobal));
+  JS::Rooted<JSObject*> global(aCx, aGlobal.toObjectOrNull());
   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
     NS_WARNING("Passed object is not a global object!");
     return NS_ERROR_FAILURE;
   }
 
   bool hasIndexedDB;
   if (!JS_HasProperty(aCx, global, IDB_STR, &hasIndexedDB)) {
     return NS_ERROR_FAILURE;
--- a/dom/indexedDB/KeyPath.cpp
+++ b/dom/indexedDB/KeyPath.cpp
@@ -91,17 +91,17 @@ GetJSValFromKeyPathString(JSContext* aCx
   nsresult rv = NS_OK;
   *aKeyJSVal = aValue;
 
   KeyPathTokenizer tokenizer(aKeyPathString, '.');
 
   nsString targetObjectPropName;
   JS::Rooted<JSObject*> targetObject(aCx, nullptr);
   JS::Rooted<JSObject*> obj(aCx,
-    JSVAL_IS_PRIMITIVE(aValue) ? nullptr : JSVAL_TO_OBJECT(aValue));
+    JSVAL_IS_PRIMITIVE(aValue) ? nullptr : aValue.toObjectOrNull());
 
   while (tokenizer.hasMoreTokens()) {
     const nsDependentSubstring& token = tokenizer.nextToken();
 
     NS_ASSERTION(!token.IsEmpty(), "Should be a valid keypath");
 
     const jschar* keyPathChars = token.BeginReading();
     const size_t keyPathLen = token.Length();
@@ -127,17 +127,17 @@ GetJSValFromKeyPathString(JSContext* aCx
         if (intermediate == JSVAL_VOID) {
           return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
         }
         if (tokenizer.hasMoreTokens()) {
           // ...and walk to it if there are more steps...
           if (JSVAL_IS_PRIMITIVE(intermediate)) {
             return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
           }
-          obj = JSVAL_TO_OBJECT(intermediate);
+          obj = intermediate.toObjectOrNull();
         }
         else {
           // ...otherwise use it as key
           *aKeyJSVal = intermediate;
         }
       }
       else {
         // If the property doesn't exist, fall into below path of starting
@@ -267,17 +267,17 @@ KeyPath::Parse(JSContext* aCx, const JS:
   JS::Rooted<JS::Value> aValue(aCx, aValue_);
   KeyPath keyPath(0);
 
   aKeyPath->SetType(NONEXISTENT);
 
   // See if this is a JS array.
   if (JS_IsArrayObject(aCx, aValue)) {
 
-    JS::Rooted<JSObject*> obj(aCx, JSVAL_TO_OBJECT(aValue));
+    JS::Rooted<JSObject*> obj(aCx, aValue.toObjectOrNull());
 
     uint32_t length;
     if (!JS_GetArrayLength(aCx, obj, &length)) {
       return NS_ERROR_FAILURE;
     }
 
     if (!length) {
       return NS_ERROR_FAILURE;
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -430,17 +430,17 @@ JSValToNPVariant(NPP npp, JSContext *cx,
   // transplanting the plugin objects, and just do a unwrap with security
   // checks if we encounter one of them as an argument. If the unwrap fails,
   // we run with the original wrapped object, since sometimes there are
   // legitimate cases where a security wrapper ends up here (for example,
   // Location objects, which are _always_ behind security wrappers).
   JS::Rooted<JSObject*> obj(cx, val.toObjectOrNull());
   obj = js::CheckedUnwrap(obj);
   if (!obj) {
-    obj = JSVAL_TO_OBJECT(val);
+    obj = val.toObjectOrNull();
   }
 
   NPObject *npobj = nsJSObjWrapper::GetNewOrUsed(npp, cx, obj);
   if (!npobj) {
     return false;
   }
 
   // Pass over ownership of npobj to *variant
@@ -589,17 +589,17 @@ nsJSObjWrapper::NP_HasMethod(NPObject *n
   JSAutoCompartment ac(cx, npjsobj->mJSObj);
 
   AutoJSExceptionReporter reporter(cx);
 
   JS::Rooted<JS::Value> v(cx);
   bool ok = GetProperty(cx, npjsobj->mJSObj, id, &v);
 
   return ok && !JSVAL_IS_PRIMITIVE(v) &&
-    ::JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(v));
+    ::JS_ObjectIsFunction(cx, v.toObjectOrNull());
 }
 
 static bool
 doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args,
          uint32_t argCount, bool ctorCall, NPVariant *result)
 {
   NPP npp = NPPStack::Peek();
   JSContext *cx = GetJSContext(npp);
@@ -1347,17 +1347,17 @@ CallNPMethodInternal(JSContext *cx, JS::
 
       return false;
     }
   }
 
   NPVariant v;
   VOID_TO_NPVARIANT(v);
 
-  JSObject *funobj = JSVAL_TO_OBJECT(argv[-2]);
+  JSObject *funobj = argv[-2].toObjectOrNull();
   bool ok;
   const char *msg = "Error calling method on NPObject!";
 
   if (ctorCall) {
     // construct a new NPObject based on the NPClass in npobj. Fail if
     // no construct method is available.
 
     if (NP_CLASS_STRUCT_VERSION_HAS_CTOR(npobj->_class) &&
@@ -1589,17 +1589,17 @@ NPObjWrapper_Convert(JSContext *cx, JS::
   // specifically java.lang.Integer.  The Integer class has static valueOf
   // methods, none of which are nullary, so the JS-reflected method will behave
   // poorly when called with no arguments.  We work around this problem by
   // giving plugins a [[DefaultValue]] which uses only toString and not valueOf.
 
   JS::Rooted<JS::Value> v(cx, JSVAL_VOID);
   if (!JS_GetProperty(cx, obj, "toString", &v))
     return false;
-  if (!JSVAL_IS_PRIMITIVE(v) && JS_ObjectIsCallable(cx, JSVAL_TO_OBJECT(v))) {
+  if (!JSVAL_IS_PRIMITIVE(v) && JS_ObjectIsCallable(cx, v.toObjectOrNull())) {
     if (!JS_CallFunctionValue(cx, obj, v, JS::HandleValueArray::empty(), vp))
       return false;
     if (JSVAL_IS_PRIMITIVE(vp))
       return true;
   }
 
   JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CONVERT_TO,
                        JS_GetClass(obj)->name,
--- a/dom/workers/ChromeWorkerScope.cpp
+++ b/dom/workers/ChromeWorkerScope.cpp
@@ -58,16 +58,16 @@ DefineChromeWorkerFunctions(JSContext* a
         !JS_GetProperty(aCx, aGlobal, "ctypes", &ctypes)) {
       return false;
     }
 
     static JSCTypesCallbacks callbacks = {
       UnicodeToNative
     };
 
-    JS_SetCTypesCallbacks(JSVAL_TO_OBJECT(ctypes), &callbacks);
+    JS_SetCTypesCallbacks(ctypes.toObjectOrNull(), &callbacks);
   }
 #endif // BUILD_CTYPES
 
   return true;
 }
 
 END_WORKERS_NAMESPACE
--- a/ipc/nfc/Nfc.cpp
+++ b/ipc/nfc/Nfc.cpp
@@ -94,17 +94,17 @@ PostToNFC(JSContext* aCx,
         JS::Rooted<JSString*> str(aCx, v.toString());
         if (!abs.encodeUtf8(aCx, str)) {
             return false;
         }
 
         data = abs.ptr();
         size = abs.length();
     } else if (!JSVAL_IS_PRIMITIVE(v)) {
-        JSObject* obj = JSVAL_TO_OBJECT(v);
+        JSObject* obj = v.toObjectOrNull();
         if (!JS_IsTypedArrayObject(obj)) {
             JS_ReportError(aCx, "Object passed in wasn't a typed array");
             return false;
         }
 
         uint32_t type = JS_GetArrayBufferViewType(obj);
         if (type != js::ArrayBufferView::TYPE_INT8 &&
             type != js::ArrayBufferView::TYPE_UINT8 &&
--- a/ipc/ril/Ril.cpp
+++ b/ipc/ril/Ril.cpp
@@ -99,17 +99,17 @@ PostToRIL(JSContext *aCx,
         JS::Rooted<JSString*> str(aCx, v.toString());
         if (!abs.encodeUtf8(aCx, str)) {
             return false;
         }
 
         data = abs.ptr();
         size = abs.length();
     } else if (!JSVAL_IS_PRIMITIVE(v)) {
-        JSObject *obj = JSVAL_TO_OBJECT(v);
+        JSObject *obj = v.toObjectOrNull();
         if (!JS_IsTypedArrayObject(obj)) {
             JS_ReportError(aCx, "Object passed in wasn't a typed array");
             return false;
         }
 
         uint32_t type = JS_GetArrayBufferViewType(obj);
         if (type != js::ArrayBufferView::TYPE_INT8 &&
             type != js::ArrayBufferView::TYPE_UINT8 &&
--- a/js/jsd/jsd_obj.cpp
+++ b/js/jsd/jsd_obj.cpp
@@ -217,17 +217,17 @@ jsd_GetJSDObjectForJSObject(JSDContext* 
     jsdobj = (JSDObject*) JS_HashTableLookup(jsdc->objectsTable, jsobj);
     JSD_UNLOCK_OBJECTS(jsdc);
     return jsdobj;
 }
 
 JSDObject*
 jsd_GetObjectForValue(JSDContext* jsdc, JSDValue* jsdval)
 {
-    return jsd_GetJSDObjectForJSObject(jsdc, JSVAL_TO_OBJECT(jsdval->val));
+    return jsd_GetJSDObjectForJSObject(jsdc, jsdval->val.toObjectOrNull());
 }
 
 JSDValue*
 jsd_GetValueForObject(JSDContext* jsdc, JSDObject* jsdobj)
 {
     return jsd_NewValue(jsdc, OBJECT_TO_JSVAL(jsdobj->obj));
 }
 
--- a/js/jsd/jsd_step.cpp
+++ b/js/jsd/jsd_step.cpp
@@ -94,17 +94,17 @@ bool
          */
         return hookresult;
     }
 
     if (before && isConstructing) {
         JS::RootedValue newObj(cx);
         if (!frame.getThisValue(cx, &newObj))
             return false;
-        jsd_Constructing(jsdc, cx, JSVAL_TO_OBJECT(newObj), frame);
+        jsd_Constructing(jsdc, cx, newObj.toObjectOrNull(), frame);
     }
 
     jsscript = frame.script();
     if (jsscript)
     {
         JSD_LOCK_SCRIPTS(jsdc);
         jsdscript = jsd_FindOrCreateJSDScript(jsdc, cx, jsscript, frame);
         JSD_UNLOCK_SCRIPTS(jsdc);
--- a/js/jsd/jsd_val.cpp
+++ b/js/jsd/jsd_val.cpp
@@ -111,28 +111,28 @@ jsd_IsValuePrimitive(JSDContext* jsdc, J
     return JSVAL_IS_PRIMITIVE(jsdval->val);
 }
 
 bool
 jsd_IsValueFunction(JSDContext* jsdc, JSDValue* jsdval)
 {
     AutoSafeJSContext cx; // NB: Actually unused.
     return !JSVAL_IS_PRIMITIVE(jsdval->val) &&
-           JS_ObjectIsCallable(cx, JSVAL_TO_OBJECT(jsdval->val));
+           JS_ObjectIsCallable(cx, jsdval->val.toObjectOrNull());
 }
 
 bool
 jsd_IsValueNative(JSDContext* jsdc, JSDValue* jsdval)
 {
     AutoSafeJSContext cx;
     JS::RootedFunction fun(cx);
 
     if(jsd_IsValueFunction(jsdc, jsdval))
     {
-        JSAutoCompartment ac(cx, JSVAL_TO_OBJECT(jsdval->val));
+        JSAutoCompartment ac(cx, jsdval->val.toObjectOrNull());
         AutoSaveExceptionState as(cx);
         bool ok = false;
         fun = JSD_GetValueFunction(jsdc, jsdval);
         if(fun)
             ok = JS_GetFunctionScript(cx, fun) ? false : true;
         MOZ_ASSERT(fun);
         return ok;
     }
@@ -180,17 +180,17 @@ jsd_GetValueString(JSDContext* jsdc, JSD
 
     /* Reuse the string without copying or re-rooting it */
     if(jsdval->val.isString()) {
         jsdval->string = jsdval->val.toString();
         return jsdval->string;
     }
 
     /* Objects call JS_ValueToString in their own compartment. */
-    scopeObj = !JSVAL_IS_PRIMITIVE(jsdval->val) ? JSVAL_TO_OBJECT(jsdval->val) : jsdc->glob;
+    scopeObj = !JSVAL_IS_PRIMITIVE(jsdval->val) ? jsdval->val.toObjectOrNull() : jsdc->glob;
     {
         JSAutoCompartment ac(cx, scopeObj);
         AutoSaveExceptionState as(cx);
         JS::RootedValue v(cx, jsdval->val);
         string = JS::ToString(cx, v);
     }
 
     JSAutoCompartment ac2(cx, jsdc->glob);
@@ -211,17 +211,17 @@ jsd_GetValueString(JSDContext* jsdc, JSD
 JSString*
 jsd_GetValueFunctionId(JSDContext* jsdc, JSDValue* jsdval)
 {
     AutoSafeJSContext cx;
     JS::RootedFunction fun(cx);
 
     if(!jsdval->funName && jsd_IsValueFunction(jsdc, jsdval))
     {
-        JSAutoCompartment ac(cx, JSVAL_TO_OBJECT(jsdval->val));
+        JSAutoCompartment ac(cx, jsdval->val.toObjectOrNull());
         AutoSaveExceptionState as(cx);
         fun = JSD_GetValueFunction(jsdc, jsdval);
         if(!fun)
             return nullptr;
         jsdval->funName = JS_GetFunctionId(fun);
 
         /* For compatibility we return "anonymous", not an empty string here. */
         if (!jsdval->funName)
@@ -362,17 +362,17 @@ static bool _buildProps(JSDContext* jsdc
 
     MOZ_ASSERT(JS_CLIST_IS_EMPTY(&jsdval->props));
     MOZ_ASSERT(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROPS)));
     MOZ_ASSERT(!JSVAL_IS_PRIMITIVE(jsdval->val));
 
     if(JSVAL_IS_PRIMITIVE(jsdval->val))
         return false;
 
-    obj = JSVAL_TO_OBJECT(jsdval->val);
+    obj = jsdval->val.toObjectOrNull();
 
     JSAutoCompartment ac(cx, obj);
 
     if(!JS_GetPropertyDescArray(cx, obj, &pda))
     {
         return false;
     }
 
@@ -500,17 +500,17 @@ jsd_GetValueProperty(JSDContext* jsdc, J
         JSD_DropProperty(jsdc, jsdprop);
     }
     /* Not found in property list, look it up explicitly */
 
     nameval = STRING_TO_JSVAL(name);
     if(!JS_ValueToId(cx, nameval, &nameid))
         return nullptr;
 
-    if(!(obj = JSVAL_TO_OBJECT(jsdval->val)))
+    if(!(obj = jsdval->val.toObjectOrNull()))
         return nullptr;
 
     JS::Rooted<JSPropertyDescriptor> desc(cx);
     {
         JSAutoCompartment ac(cx, obj);
         JS::RootedId id(cx, nameid);
 
         if(!JS_WrapId(cx, &id))
@@ -565,17 +565,17 @@ jsd_GetValueFunction(JSDContext* jsdc, J
     AutoSafeJSContext cx;
 
     JS::RootedObject obj(cx);
     JS::RootedFunction fun(cx);
 
     if (JSVAL_IS_PRIMITIVE(jsdval->val))
         return nullptr;
 
-    obj = js::UncheckedUnwrap(JSVAL_TO_OBJECT(jsdval->val));
+    obj = js::UncheckedUnwrap(jsdval->val.toObjectOrNull());
     JSAutoCompartment ac(cx, obj);
     JS::RootedValue funval(cx, JS::ObjectValue(*obj));
     fun = JS_ValueToFunction(cx, funval);
 
     return fun;
 }
 
 JSDValue*
@@ -585,17 +585,17 @@ jsd_GetValuePrototype(JSDContext* jsdc, 
     if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROTO)))
     {
         JS::RootedObject obj(cx);
         JS::RootedObject proto(cx);
         MOZ_ASSERT(!jsdval->proto);
         SET_BIT_FLAG(jsdval->flags, GOT_PROTO);
         if(JSVAL_IS_PRIMITIVE(jsdval->val))
             return nullptr;
-        obj = JSVAL_TO_OBJECT(jsdval->val);
+        obj = jsdval->val.toObjectOrNull();
         if(!JS_GetPrototype(cx, obj, &proto))
             return nullptr;
         if(!proto)
             return nullptr;
         jsdval->proto = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(proto));
     }
     if(jsdval->proto)
         jsdval->proto->nref++;
@@ -609,17 +609,17 @@ jsd_GetValueParent(JSDContext* jsdc, JSD
     {
         AutoSafeJSContext cx;
         JS::RootedObject obj(cx);
         JS::RootedObject parent(cx);
         MOZ_ASSERT(!jsdval->parent);
         SET_BIT_FLAG(jsdval->flags, GOT_PARENT);
         if(JSVAL_IS_PRIMITIVE(jsdval->val))
             return nullptr;
-        obj = JSVAL_TO_OBJECT(jsdval->val);
+        obj = jsdval->val.toObjectOrNull();
         {
             JSAutoCompartment ac(cx, obj);
             parent = JS_GetParentOrScopeChain(cx, obj);
         }
         if(!parent)
             return nullptr;
         jsdval->parent = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(parent));
     }
@@ -636,17 +636,17 @@ jsd_GetValueConstructor(JSDContext* jsdc
         AutoSafeJSContext cx;
         JS::RootedObject obj(cx);
         JS::RootedObject proto(cx);
         JS::RootedObject ctor(cx);
         MOZ_ASSERT(!jsdval->ctor);
         SET_BIT_FLAG(jsdval->flags, GOT_CTOR);
         if(JSVAL_IS_PRIMITIVE(jsdval->val))
             return nullptr;
-        obj = JSVAL_TO_OBJECT(jsdval->val);
+        obj = jsdval->val.toObjectOrNull();
         if(!JS_GetPrototype(cx, obj, &proto))
             return nullptr;
         if(!proto)
             return nullptr;
         {
             JSAutoCompartment ac(cx, obj);
             ctor = JS_GetConstructor(cx, proto);
         }
@@ -660,17 +660,17 @@ jsd_GetValueConstructor(JSDContext* jsdc
 }
 
 const char*
 jsd_GetValueClassName(JSDContext* jsdc, JSDValue* jsdval)
 {
     jsval val = jsdval->val;
     if(!jsdval->className && !JSVAL_IS_PRIMITIVE(val))
     {
-        JS::RootedObject obj(jsdc->jsrt, JSVAL_TO_OBJECT(val));
+        JS::RootedObject obj(jsdc->jsrt, val.toObjectOrNull());
         AutoSafeJSContext cx;
         JSAutoCompartment ac(cx, obj);
         jsdval->className = JS_GetDebugClassName(obj);
     }
     return jsdval->className;
 }
 
 JSDScript*
@@ -680,17 +680,17 @@ jsd_GetScriptForValue(JSDContext* jsdc, 
     JS::RootedValue val(cx, jsdval->val);
     JS::RootedScript script(cx);
     JSDScript* jsdscript;
 
     if (!jsd_IsValueFunction(jsdc, jsdval))
         return nullptr;
 
     {
-        JSAutoCompartment ac(cx, JSVAL_TO_OBJECT(val));
+        JSAutoCompartment ac(cx, val.toObjectOrNull());
         AutoSaveExceptionState as(cx);
         JS::RootedFunction fun(cx, JSD_GetValueFunction(jsdc, jsdval));
         if (fun)
             script = JS_GetFunctionScript(cx, fun);
     }
 
     if (!script)
         return nullptr;
--- a/js/public/CallArgs.h
+++ b/js/public/CallArgs.h
@@ -383,17 +383,17 @@ CallArgsFromSp(unsigned argc, Value *sp)
 
 /*
  * Macros to hide interpreter stack layout details from a JSNative using its
  * JS::Value *vp parameter.  DO NOT USE THESE!  Instead use JS::CallArgs and
  * friends, above.  These macros will be removed when we change JSNative to
  * take a const JS::CallArgs&.
  */
 
-#define JS_THIS_OBJECT(cx,vp)   (JSVAL_TO_OBJECT(JS_THIS(cx,vp)))
+#define JS_THIS_OBJECT(cx,vp)   (JS_THIS(cx,vp).toObjectOrNull())
 
 /*
  * Note: if this method returns null, an error has occurred and must be
  * propagated or caught.
  */
 MOZ_ALWAYS_INLINE JS::Value
 JS_THIS(JSContext *cx, JS::Value *vp)
 {
--- a/js/public/Value.h
+++ b/js/public/Value.h
@@ -911,17 +911,16 @@ CanonicalizeNaN(double d)
  *   particular value. For example, if cx->exception has a magic value, the
  *   reason must be JS_GENERATOR_CLOSING.
  *
  * - The JS::Value operations are preferred.  The JSVAL_* operations remain for
  *   compatibility; they may be removed at some point.  These operations mostly
  *   provide similar functionality.  But there are a few key differences.  One
  *   is that JS::Value gives null a separate type. Thus
  *
- *           JSVAL_IS_OBJECT(v) === v.isObjectOrNull()
  *       !JSVAL_IS_PRIMITIVE(v) === v.isObject()
  *
  *   Also, to help prevent mistakenly boxing a nullable JSObject* as an object,
  *   Value::setObject takes a JSObject&. (Conversely, Value::toObject returns a
  *   JSObject&.)  A convenience member Value::setObjectOrNull is provided.
  *
  * - JSVAL_VOID is the same as the singleton value of the Undefined type.
  *
@@ -1859,23 +1858,16 @@ UINT_TO_JSVAL(uint32_t i)
 }
 
 static inline jsval
 STRING_TO_JSVAL(JSString *str)
 {
     return IMPL_TO_JSVAL(STRING_TO_JSVAL_IMPL(str));
 }
 
-static inline JSObject *
-JSVAL_TO_OBJECT(jsval v)
-{
-    MOZ_ASSERT(JSVAL_IS_OBJECT_OR_NULL_IMPL(JSVAL_TO_IMPL(v)));
-    return JSVAL_TO_OBJECT_IMPL(JSVAL_TO_IMPL(v));
-}
-
 static inline jsval
 OBJECT_TO_JSVAL(JSObject *obj)
 {
     if (obj)
         return IMPL_TO_JSVAL(OBJECT_TO_JSVAL_IMPL(obj));
     return IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_NULL, 0));
 }
 
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -1303,17 +1303,17 @@ static bool GetObjectProperty(JSContext 
     return false;
   }
 
   if (JSVAL_IS_PRIMITIVE(val)) {
     JS_ReportError(cx, "missing or non-object field");
     return false;
   }
 
-  result.set(JSVAL_TO_OBJECT(val));
+  result.set(val.toObjectOrNull());
   return true;
 }
 
 } /* namespace ctypes */
 } /* namespace js */
 
 using namespace js;
 using namespace js::ctypes;
@@ -1611,17 +1611,17 @@ jsvalToInteger(JSContext* cx, jsval val,
   }
   if (val.isDouble()) {
     // Don't silently lose bits here -- check that val really is an
     // integer value, and has the right sign.
     double d = val.toDouble();
     return ConvertExact(d, result);
   }
   if (!JSVAL_IS_PRIMITIVE(val)) {
-    JSObject* obj = JSVAL_TO_OBJECT(val);
+    JSObject* obj = val.toObjectOrNull();
     if (CData::IsCData(obj)) {
       JSObject* typeObj = CData::GetCType(obj);
       void* data = CData::GetData(obj);
 
       // Check whether the source type is always representable, with exact
       // precision, by the target type. If it is, convert the value.
       switch (CType::GetTypeCode(typeObj)) {
 #define DEFINE_INT_TYPE(name, fromType, ffiType)                               \
@@ -1700,17 +1700,17 @@ jsvalToFloat(JSContext *cx, jsval val, F
     *result = FloatType(val.toInt32());
     return true;
   }
   if (val.isDouble()) {
     *result = FloatType(val.toDouble());
     return true;
   }
   if (!JSVAL_IS_PRIMITIVE(val)) {
-    JSObject* obj = JSVAL_TO_OBJECT(val);
+    JSObject* obj = val.toObjectOrNull();
     if (CData::IsCData(obj)) {
       JSObject* typeObj = CData::GetCType(obj);
       void* data = CData::GetData(obj);
 
       // Check whether the source type is always representable, with exact
       // precision, by the target type. If it is, convert the value.
       switch (CType::GetTypeCode(typeObj)) {
 #define DEFINE_FLOAT_TYPE(name, fromType, ffiType)                             \
@@ -1824,17 +1824,17 @@ jsvalToBigInteger(JSContext* cx,
     // Allow conversion from base-10 or base-16 strings, provided the result
     // fits in IntegerType. (This allows an Int64 or UInt64 object to be passed
     // to the JS array element operator, which will automatically call
     // toString() on the object for us.)
     return StringToInteger(cx, val.toString(), result);
   }
   if (!JSVAL_IS_PRIMITIVE(val)) {
     // Allow conversion from an Int64 or UInt64 object directly.
-    JSObject* obj = JSVAL_TO_OBJECT(val);
+    JSObject* obj = val.toObjectOrNull();
 
     if (UInt64::IsUInt64(obj)) {
       // Make sure the integer fits in IntegerType.
       uint64_t i = Int64Base::GetInt(obj);
       return ConvertExact(i, result);
     }
 
     if (Int64::IsInt64(obj)) {
@@ -1947,17 +1947,17 @@ jsvalToIntegerExplicit(jsval val, Intege
   if (val.isDouble()) {
     // Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
     double d = val.toDouble();
     *result = mozilla::IsFinite(d) ? IntegerType(d) : 0;
     return true;
   }
   if (!JSVAL_IS_PRIMITIVE(val)) {
     // Convert Int64 and UInt64 values by C-style cast.
-    JSObject* obj = JSVAL_TO_OBJECT(val);
+    JSObject* obj = val.toObjectOrNull();
     if (Int64::IsInt64(obj)) {
       int64_t i = Int64Base::GetInt(obj);
       *result = IntegerType(i);
       return true;
     }
     if (UInt64::IsUInt64(obj)) {
       uint64_t i = Int64Base::GetInt(obj);
       *result = IntegerType(i);
@@ -1991,17 +1991,17 @@ jsvalToPtrExplicit(JSContext* cx, jsval 
     }
 
     // Don't silently lose bits here -- check that val really is an
     // integer value, and has the right sign.
     *result = Convert<uintptr_t>(d);
     return double(*result) == d;
   }
   if (!JSVAL_IS_PRIMITIVE(val)) {
-    JSObject* obj = JSVAL_TO_OBJECT(val);
+    JSObject* obj = val.toObjectOrNull();
     if (Int64::IsInt64(obj)) {
       int64_t i = Int64Base::GetInt(obj);
       intptr_t p = intptr_t(i);
 
       // Make sure the integer fits in the alotted precision.
       if (int64_t(p) != i)
         return false;
       *result = uintptr_t(p);
@@ -2238,17 +2238,17 @@ ImplicitConvert(JSContext* cx,
   JS_ASSERT(CType::IsSizeDefined(targetType));
 
   // First, check if val is either a CData object or a CDataFinalizer
   // of type targetType.
   JSObject* sourceData = nullptr;
   JSObject* sourceType = nullptr;
   RootedObject valObj(cx, nullptr);
   if (!JSVAL_IS_PRIMITIVE(val)) {
-    valObj = JSVAL_TO_OBJECT(val);
+    valObj = val.toObjectOrNull();
     if (CData::IsCData(valObj)) {
       sourceData = valObj;
       sourceType = CData::GetCType(sourceData);
 
       // If the types are equal, copy the buffer contained within the CData.
       // (Note that the buffers may overlap partially or completely.)
       if (CType::TypesEqual(sourceType, targetType)) {
         size_t size = CType::GetSize(sourceType);
@@ -3607,17 +3607,17 @@ CType::GetProtoFromType(JSContext* cx, J
   if (!JS_GetPrototype(cx, obj, &proto))
     return nullptr;
   JS_ASSERT(proto);
   JS_ASSERT(CType::IsCTypeProto(proto));
 
   // Get the requested ctypes.{Pointer,Array,Struct,Function}Type.prototype.
   jsval result = JS_GetReservedSlot(proto, slot);
   JS_ASSERT(!JSVAL_IS_PRIMITIVE(result));
-  return JSVAL_TO_OBJECT(result);
+  return result.toObjectOrNull();
 }
 
 bool
 CType::IsCTypeOrProto(HandleValue v)
 {
   if (!v.isObject())
     return false;
   JSObject* obj = &v.toObject();
@@ -4634,17 +4634,17 @@ ArrayType::AddressOfElement(JSContext* c
 static JSFlatString*
 ExtractStructField(JSContext* cx, jsval val, JSObject** typeObj)
 {
   if (JSVAL_IS_PRIMITIVE(val)) {
     JS_ReportError(cx, "struct field descriptors require a valid name and type");
     return nullptr;
   }
 
-  RootedObject obj(cx, JSVAL_TO_OBJECT(val));
+  RootedObject obj(cx, val.toObjectOrNull());
   RootedObject iter(cx, JS_NewPropertyIterator(cx, obj));
   if (!iter)
     return nullptr;
 
   RootedId nameid(cx);
   if (!JS_NextProperty(cx, iter, nameid.address()))
     return nullptr;
   if (JSID_IS_VOID(nameid)) {
@@ -4998,17 +4998,17 @@ StructType::Define(JSContext* cx, unsign
     return false;
   }
 
   jsval arg = args[0];
   if (JSVAL_IS_PRIMITIVE(arg)) {
     JS_ReportError(cx, "argument must be an array");
     return false;
   }
-  RootedObject arr(cx, JSVAL_TO_OBJECT(arg));
+  RootedObject arr(cx, arg.toObjectOrNull());
   if (!JS_IsArrayObject(cx, arr)) {
     JS_ReportError(cx, "argument must be an array");
     return false;
   }
 
   return DefineInternal(cx, obj, arr);
 }
 
@@ -5309,17 +5309,17 @@ struct AutoValue
 };
 
 static bool
 GetABI(JSContext* cx, jsval abiType, ffi_abi* result)
 {
   if (JSVAL_IS_PRIMITIVE(abiType))
     return false;
 
-  ABICode abi = GetABICode(JSVAL_TO_OBJECT(abiType));
+  ABICode abi = GetABICode(abiType.toObjectOrNull());
 
   // determine the ABI from the subset of those available on the
   // given platform. ABI_DEFAULT specifies the default
   // C calling convention (cdecl) on each platform.
   switch (abi) {
   case ABI_DEFAULT:
     *result = FFI_DEFAULT_ABI;
     return true;
@@ -5338,23 +5338,22 @@ GetABI(JSContext* cx, jsval abiType, ffi
     break;
   }
   return false;
 }
 
 static JSObject*
 PrepareType(JSContext* cx, jsval type)
 {
-  if (JSVAL_IS_PRIMITIVE(type) ||
-      !CType::IsCType(JSVAL_TO_OBJECT(type))) {
+  if (JSVAL_IS_PRIMITIVE(type) || !CType::IsCType(type.toObjectOrNull())) {
     JS_ReportError(cx, "not a ctypes type");
     return nullptr;
   }
 
-  JSObject* result = JSVAL_TO_OBJECT(type);
+  JSObject* result = type.toObjectOrNull();
   TypeCode typeCode = CType::GetTypeCode(result);
 
   if (typeCode == TYPE_array) {
     // convert array argument types to pointers, just like C.
     // ImplicitConvert will do the same, when passing an array as data.
     RootedObject baseType(cx, ArrayType::GetBaseType(result));
     result = PointerType::CreateInternal(cx, baseType);
     if (!result)
@@ -5375,23 +5374,22 @@ PrepareType(JSContext* cx, jsval type)
   JS_ASSERT(CType::GetSize(result) != 0);
 
   return result;
 }
 
 static JSObject*
 PrepareReturnType(JSContext* cx, jsval type)
 {
-  if (JSVAL_IS_PRIMITIVE(type) ||
-      !CType::IsCType(JSVAL_TO_OBJECT(type))) {
+  if (JSVAL_IS_PRIMITIVE(type) || !CType::IsCType(type.toObjectOrNull())) {
     JS_ReportError(cx, "not a ctypes type");
     return nullptr;
   }
 
-  JSObject* result = JSVAL_TO_OBJECT(type);
+  JSObject* result = type.toObjectOrNull();
   TypeCode typeCode = CType::GetTypeCode(result);
 
   // Arrays and functions can never be return types.
   if (typeCode == TYPE_array || typeCode == TYPE_function) {
     JS_ReportError(cx, "Return type cannot be an array or function");
     return nullptr;
   }
 
@@ -5519,17 +5517,17 @@ NewFunctionInfo(JSContext* cx,
     return nullptr;
   }
 
   ffi_abi abi;
   if (!GetABI(cx, abiType, &abi)) {
     JS_ReportError(cx, "Invalid ABI specification");
     return nullptr;
   }
-  fninfo->mABI = JSVAL_TO_OBJECT(abiType);
+  fninfo->mABI = abiType.toObjectOrNull();
 
   // prepare the result type
   fninfo->mReturnType = PrepareReturnType(cx, returnType);
   if (!fninfo->mReturnType)
     return nullptr;
 
   // prepare the argument types
   if (!fninfo->mArgTypes.reserve(argLength) ||
@@ -6292,17 +6290,17 @@ CData::Create(JSContext* cx,
   JS_ASSERT(CType::IsSizeDefined(typeObj));
   JS_ASSERT(ownResult || source);
   JS_ASSERT_IF(refObj && CData::IsCData(refObj), !ownResult);
 
   // Get the 'prototype' property from the type.
   jsval slot = JS_GetReservedSlot(typeObj, SLOT_PROTO);
   JS_ASSERT(!JSVAL_IS_PRIMITIVE(slot));
 
-  RootedObject proto(cx, JSVAL_TO_OBJECT(slot));
+  RootedObject proto(cx, slot.toObjectOrNull());
   RootedObject parent(cx, JS_GetParent(typeObj));
   JS_ASSERT(parent);
 
   RootedObject dataObj(cx, JS_NewObject(cx, &sCDataClass, proto, parent));
   if (!dataObj)
     return nullptr;
 
   // set the CData's associated type
@@ -6370,17 +6368,17 @@ CData::Finalize(JSFreeOp *fop, JSObject*
 }
 
 JSObject*
 CData::GetCType(JSObject* dataObj)
 {
   JS_ASSERT(CData::IsCData(dataObj));
 
   jsval slot = JS_GetReservedSlot(dataObj, SLOT_CTYPE);
-  JSObject* typeObj = JSVAL_TO_OBJECT(slot);
+  JSObject* typeObj = slot.toObjectOrNull();
   JS_ASSERT(CType::IsCType(typeObj));
   return typeObj;
 }
 
 void*
 CData::GetData(JSObject* dataObj)
 {
   JS_ASSERT(CData::IsCData(dataObj));
@@ -6741,17 +6739,17 @@ CDataFinalizer::Methods::ToSource(JSCont
     AppendString(source, srcValue);
     AppendString(source, ", ");
     jsval valCodePtrType = JS_GetReservedSlot(objThis,
                                               SLOT_DATAFINALIZER_CODETYPE);
     if (JSVAL_IS_PRIMITIVE(valCodePtrType)) {
       return false;
     }
 
-    RootedObject typeObj(cx, JSVAL_TO_OBJECT(valCodePtrType));
+    RootedObject typeObj(cx, valCodePtrType.toObjectOrNull());
     JSString *srcDispose = CData::GetSourceString(cx, typeObj, &(p->code));
     if (!srcDispose) {
       return false;
     }
 
     AppendString(source, srcDispose);
     AppendString(source, ")");
     strMessage = NewUCString(cx, source);
@@ -6812,17 +6810,17 @@ CDataFinalizer::GetCType(JSContext *cx, 
   MOZ_ASSERT(IsCDataFinalizer(obj));
 
   jsval valData = JS_GetReservedSlot(obj,
                                      SLOT_DATAFINALIZER_VALTYPE);
   if (valData.isUndefined()) {
     return nullptr;
   }
 
-  return JSVAL_TO_OBJECT(valData);
+  return valData.toObjectOrNull();
 }
 
 JSObject*
 CDataFinalizer::GetCData(JSContext *cx, JSObject *obj)
 {
   if (!obj) {
     JS_ReportError(cx, "No C data");
     return nullptr;
@@ -6834,17 +6832,17 @@ CDataFinalizer::GetCData(JSContext *cx, 
     JS_ReportError(cx, "Not C data");
     return nullptr;
   }
   RootedValue val(cx);
   if (!CDataFinalizer::GetValue(cx, obj, val.address()) || JSVAL_IS_PRIMITIVE(val)) {
     JS_ReportError(cx, "Empty CDataFinalizer");
     return nullptr;
   }
-  return JSVAL_TO_OBJECT(val);
+  return val.toObjectOrNull();
 }
 
 bool
 CDataFinalizer::GetValue(JSContext *cx, JSObject *obj, jsval *aResult)
 {
   MOZ_ASSERT(IsCDataFinalizer(obj));
 
   CDataFinalizer::Private *p = (CDataFinalizer::Private *)
@@ -7403,17 +7401,17 @@ Int64::Construct(JSContext* cx,
   int64_t i = 0;
   if (!jsvalToBigInteger(cx, args[0], true, &i))
     return TypeError(cx, "int64", args[0]);
 
   // Get ctypes.Int64.prototype from the 'prototype' property of the ctor.
   RootedValue slot(cx);
   RootedObject callee(cx, &args.callee());
   ASSERT_OK(JS_GetProperty(cx, callee, "prototype", &slot));
-  RootedObject proto(cx, JSVAL_TO_OBJECT(slot));
+  RootedObject proto(cx, slot.toObjectOrNull());
   JS_ASSERT(JS_GetClass(proto) == &sInt64ProtoClass);
 
   JSObject* result = Int64Base::Construct(cx, proto, i, false);
   if (!result)
     return false;
 
   args.rval().setObject(*result);
   return true;
--- a/js/src/jsapi-tests/testAddPropertyPropcache.cpp
+++ b/js/src/jsapi-tests/testAddPropertyPropcache.cpp
@@ -48,17 +48,17 @@ BEGIN_TEST(testAddPropertyHook)
 
     CHECK(JS_DefineProperty(cx, global, "arr", arr, JSPROP_ENUMERATE,
                             JS_PropertyStub, JS_StrictPropertyStub));
 
     for (int i = 0; i < ExpectedCount; ++i) {
         obj = JS_NewObject(cx, &AddPropertyClass, JS::NullPtr(), JS::NullPtr());
         CHECK(obj);
         JS::RootedValue vobj(cx, OBJECT_TO_JSVAL(obj));
-        JS::RootedObject arrObj(cx, JSVAL_TO_OBJECT(arr));
+        JS::RootedObject arrObj(cx, arr.toObjectOrNull());
         CHECK(JS_DefineElement(cx, arrObj, i, vobj,
                                JS_PropertyStub, JS_StrictPropertyStub,
                                JSPROP_ENUMERATE));
     }
 
     // Now add a prop to each of the objects, but make sure to do
     // so at the same bytecode location so we can hit the propcache.
     EXEC("'use strict';                                     \n"
--- a/js/src/jsapi-tests/testArgumentsObject.cpp
+++ b/js/src/jsapi-tests/testArgumentsObject.cpp
@@ -78,17 +78,17 @@ static const size_t MAX_ELEMS = 6;
 
 template<size_t ArgCount> bool
 ExhaustiveTest(const char funcode[])
 {
     RootedValue v(cx);
     EVAL(funcode, &v);
 
     EVAL(CALL_CODES[ArgCount], &v);
-    Rooted<ArgumentsObject*> argsobj(cx, &JSVAL_TO_OBJECT(v)->as<ArgumentsObject>());
+    Rooted<ArgumentsObject*> argsobj(cx, &v.toObjectOrNull()->as<ArgumentsObject>());
 
     JS::AutoValueArray<MAX_ELEMS> elems(cx);
 
     for (size_t i = 0; i <= ArgCount; i++) {
         for (size_t j = 0; j <= ArgCount - i; j++) {
             ClearElements(elems);
             CHECK(argsobj->maybeGetElements(i, j, elems.begin()));
             for (size_t k = 0; k < j; k++)
--- a/js/src/jsapi-tests/testBindCallable.cpp
+++ b/js/src/jsapi-tests/testBindCallable.cpp
@@ -9,18 +9,18 @@ BEGIN_TEST(test_BindCallable)
   JS::RootedValue v(cx);
   EVAL("({ somename : 1717 })", &v);
   CHECK(v.isObject());
 
   JS::RootedValue func(cx);
   EVAL("(function() { return this.somename; })", &func);
   CHECK(func.isObject());
 
-  JS::RootedObject funcObj(cx, JSVAL_TO_OBJECT(func));
-  JS::RootedObject vObj(cx, JSVAL_TO_OBJECT(v));
+  JS::RootedObject funcObj(cx, func.toObjectOrNull());
+  JS::RootedObject vObj(cx, v.toObjectOrNull());
   JSObject* newCallable = JS_BindCallable(cx, funcObj, vObj);
   CHECK(newCallable);
 
   JS::RootedValue retval(cx);
   JS::RootedValue fun(cx, JS::ObjectValue(*newCallable));
   bool called = JS_CallFunctionValue(cx, JS::NullPtr(), fun, JS::HandleValueArray::empty(), &retval);
   CHECK(called);
 
--- a/js/src/jsapi-tests/testConservativeGC.cpp
+++ b/js/src/jsapi-tests/testConservativeGC.cpp
@@ -10,28 +10,28 @@
 #include "vm/String.h"
 
 BEGIN_TEST(testConservativeGC)
 {
     JS::RootedValue v2(cx);
     EVAL("({foo: 'bar'});", &v2);
     CHECK(v2.isObject());
     char objCopy[sizeof(JSObject)];
-    js_memcpy(&objCopy, JSVAL_TO_OBJECT(v2), sizeof(JSObject));
+    js_memcpy(&objCopy, v2.toObjectOrNull(), sizeof(JSObject));
 
     JS::RootedValue v3(cx);
     EVAL("String(Math.PI);", &v3);
     CHECK(v3.isString());
     char strCopy[sizeof(JSString)];
     js_memcpy(&strCopy, v3.toString(), sizeof(JSString));
 
     JS::RootedValue tmp(cx);
     EVAL("({foo2: 'bar2'});", &tmp);
     CHECK(tmp.isObject());
-    JS::RootedObject obj2(cx, JSVAL_TO_OBJECT(tmp));
+    JS::RootedObject obj2(cx, tmp.toObjectOrNull());
     char obj2Copy[sizeof(JSObject)];
     js_memcpy(&obj2Copy, obj2, sizeof(JSObject));
 
     EVAL("String(Math.sqrt(3));", &tmp);
     CHECK(tmp.isString());
     JS::RootedString str2(cx, tmp.toString());
     char str2Copy[sizeof(JSString)];
     js_memcpy(&str2Copy, str2, sizeof(JSString));
@@ -42,17 +42,17 @@ BEGIN_TEST(testConservativeGC)
 
     EVAL("var a = [];\n"
          "for (var i = 0; i != 10000; ++i) {\n"
          "a.push(i + 0.1, [1, 2], String(Math.sqrt(i)), {a: i});\n"
          "}", &tmp);
 
     JS_GC(rt);
 
-    checkObjectFields((JSObject *)objCopy, JSVAL_TO_OBJECT(v2));
+    checkObjectFields((JSObject *)objCopy, v2.toObjectOrNull());
     CHECK(!memcmp(strCopy, v3.toString(), sizeof(strCopy)));
 
     checkObjectFields((JSObject *)obj2Copy, obj2);
     CHECK(!memcmp(str2Copy, str2, sizeof(str2Copy)));
 
     return true;
 }
 
--- a/js/src/jsapi-tests/testDeepFreeze.cpp
+++ b/js/src/jsapi-tests/testDeepFreeze.cpp
@@ -6,34 +6,34 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testDeepFreeze_bug535703)
 {
     JS::RootedValue v(cx);
     EVAL("var x = {}; x;", &v);
-    JS::RootedObject obj(cx, JSVAL_TO_OBJECT(v));
+    JS::RootedObject obj(cx, v.toObjectOrNull());
     CHECK(JS_DeepFreezeObject(cx, obj));  // don't crash
     EVAL("Object.isFrozen(x)", &v);
     CHECK_SAME(v, JSVAL_TRUE);
     return true;
 }
 END_TEST(testDeepFreeze_bug535703)
 
 BEGIN_TEST(testDeepFreeze_deep)
 {
     JS::RootedValue a(cx), o(cx);
     EXEC("var a = {}, o = a;\n"
          "for (var i = 0; i < 5000; i++)\n"
          "    a = {x: a, y: a};\n");
     EVAL("a", &a);
     EVAL("o", &o);
 
-    JS::RootedObject aobj(cx, JSVAL_TO_OBJECT(a));
+    JS::RootedObject aobj(cx, a.toObjectOrNull());
     CHECK(JS_DeepFreezeObject(cx, aobj));
 
     JS::RootedValue b(cx);
     EVAL("Object.isFrozen(a)", &b);
     CHECK_SAME(b, JSVAL_TRUE);
     EVAL("Object.isFrozen(o)", &b);
     CHECK_SAME(b, JSVAL_TRUE);
     return true;
@@ -42,17 +42,17 @@ END_TEST(testDeepFreeze_deep)
 
 BEGIN_TEST(testDeepFreeze_loop)
 {
     JS::RootedValue x(cx), y(cx);
     EXEC("var x = [], y = {x: x}; y.y = y; x.push(x, y);");
     EVAL("x", &x);
     EVAL("y", &y);
 
-    JS::RootedObject xobj(cx, JSVAL_TO_OBJECT(x));
+    JS::RootedObject xobj(cx, x.toObjectOrNull());
     CHECK(JS_DeepFreezeObject(cx, xobj));
 
     JS::RootedValue b(cx);
     EVAL("Object.isFrozen(x)", &b);
     CHECK_SAME(b, JSVAL_TRUE);
     EVAL("Object.isFrozen(y)", &b);
     CHECK_SAME(b, JSVAL_TRUE);
     return true;
--- a/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp
+++ b/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp
@@ -27,17 +27,17 @@ BEGIN_TEST(testDefineGetterSetterNonEnum
     JS::RootedObject funGetObj(cx, JS_GetFunctionObject(funGet));
     JS::RootedValue vget(cx, OBJECT_TO_JSVAL(funGetObj));
 
     JSFunction *funSet = JS_NewFunction(cx, NativeGetterSetter, 1, 0, JS::NullPtr(), "set");
     CHECK(funSet);
     JS::RootedObject funSetObj(cx, JS_GetFunctionObject(funSet));
     JS::RootedValue vset(cx, OBJECT_TO_JSVAL(funSetObj));
 
-    JS::RootedObject vObject(cx, JSVAL_TO_OBJECT(vobj));
+    JS::RootedObject vObject(cx, vobj.toObjectOrNull());
     CHECK(JS_DefineProperty(cx, vObject, PROPERTY_NAME,
                             JS::UndefinedHandleValue,
                             JSPROP_GETTER | JSPROP_SETTER | JSPROP_ENUMERATE,
                             JS_DATA_TO_FUNC_PTR(JSPropertyOp, (JSObject*) funGetObj),
                             JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, (JSObject*) funSetObj)));
 
     CHECK(JS_DefineProperty(cx, vObject, PROPERTY_NAME,
                             JS::UndefinedHandleValue,
--- a/js/src/jsapi-tests/testDefineProperty.cpp
+++ b/js/src/jsapi-tests/testDefineProperty.cpp
@@ -10,14 +10,14 @@
 BEGIN_TEST(testDefineProperty_bug564344)
 {
     JS::RootedValue x(cx);
     EVAL("function f() {}\n"
          "var x = {p: f};\n"
          "x.p();  // brand x's scope\n"
          "x;", &x);
 
-    JS::RootedObject obj(cx, JSVAL_TO_OBJECT(x));
+    JS::RootedObject obj(cx, x.toObjectOrNull());
     for (int i = 0; i < 2; i++)
         CHECK(JS_DefineProperty(cx, obj, "q", JS::UndefinedHandleValue, JSPROP_SHARED));
     return true;
 }
 END_TEST(testDefineProperty_bug564344)
--- a/js/src/jsapi-tests/testFunctionProperties.cpp
+++ b/js/src/jsapi-tests/testFunctionProperties.cpp
@@ -7,17 +7,17 @@
 
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testFunctionProperties)
 {
     JS::RootedValue x(cx);
     EVAL("(function f() {})", &x);
 
-    JS::RootedObject obj(cx, JSVAL_TO_OBJECT(x));
+    JS::RootedObject obj(cx, x.toObjectOrNull());
 
     JS::RootedValue y(cx);
     CHECK(JS_GetProperty(cx, obj, "arguments", &y));
     CHECK_SAME(y, JSVAL_NULL);
 
     CHECK(JS_GetProperty(cx, obj, "caller", &y));
     CHECK_SAME(y, JSVAL_NULL);
 
--- a/js/src/jsapi-tests/testLookup.cpp
+++ b/js/src/jsapi-tests/testLookup.cpp
@@ -18,17 +18,17 @@ BEGIN_TEST(testLookup_bug522590)
     EXEC("function mkobj() { return {f: function () {return 2;}} }");
 
     // Calling mkobj() multiple times must create multiple functions in ES5.
     EVAL("mkobj().f !== mkobj().f", &x);
     CHECK_SAME(x, JSVAL_TRUE);
 
     // Now make x.f a method.
     EVAL("mkobj()", &x);
-    JS::RootedObject xobj(cx, JSVAL_TO_OBJECT(x));
+    JS::RootedObject xobj(cx, x.toObjectOrNull());
 
     // This lookup must not return an internal function object.
     JS::RootedValue r(cx);
     CHECK(JS_LookupProperty(cx, xobj, "f", &r));
     CHECK(r.isObject());
     JSObject *funobj = &r.toObject();
     CHECK(funobj->is<JSFunction>());
     CHECK(!js::IsInternalFunctionObject(funobj));
--- a/js/src/jsapi-tests/testMappedArrayBuffer.cpp
+++ b/js/src/jsapi-tests/testMappedArrayBuffer.cpp
@@ -123,17 +123,17 @@ bool TestCloneObject()
     JS::RootedObject obj1(cx, CreateNewObject(8, 12));
     CHECK(obj1);
     JSAutoStructuredCloneBuffer cloned_buffer;
     JS::RootedValue v1(cx, OBJECT_TO_JSVAL(obj1));
     const JSStructuredCloneCallbacks *callbacks = js::GetContextStructuredCloneCallbacks(cx);
     CHECK(cloned_buffer.write(cx, v1, callbacks, nullptr));
     JS::RootedValue v2(cx);
     CHECK(cloned_buffer.read(cx, &v2, callbacks, nullptr));
-    JS::RootedObject obj2(cx, JSVAL_TO_OBJECT(v2));
+    JS::RootedObject obj2(cx, v2.toObjectOrNull());
     CHECK(VerifyObject(obj2, 8, 12, false));
 
     return true;
 }
 
 bool TestStealContents()
 {
     JS::RootedObject obj(cx, CreateNewObject(8, 12));
@@ -159,17 +159,17 @@ bool TestTransferObject()
     CHECK(obj);
     JS::RootedValue transferable(cx, OBJECT_TO_JSVAL(obj));
 
     JSAutoStructuredCloneBuffer cloned_buffer;
     const JSStructuredCloneCallbacks *callbacks = js::GetContextStructuredCloneCallbacks(cx);
     CHECK(cloned_buffer.write(cx, v1, transferable, callbacks, nullptr));
     JS::RootedValue v2(cx);
     CHECK(cloned_buffer.read(cx, &v2, callbacks, nullptr));
-    JS::RootedObject obj2(cx, JSVAL_TO_OBJECT(v2));
+    JS::RootedObject obj2(cx, v2.toObjectOrNull());
     CHECK(VerifyObject(obj2, 8, 12, true));
     CHECK(isNeutered(obj1));
 
     return true;
 }
 
 bool isNeutered(JS::HandleObject obj)
 {
--- a/js/src/jsapi-tests/testNewObject.cpp
+++ b/js/src/jsapi-tests/testNewObject.cpp
@@ -55,17 +55,17 @@ constructHook(JSContext *cx, unsigned ar
 BEGIN_TEST(testNewObject_1)
 {
     static const size_t N = 1000;
     JS::AutoValueVector argv(cx);
     CHECK(argv.resize(N));
 
     JS::RootedValue v(cx);
     EVAL("Array", &v);
-    JS::RootedObject Array(cx, JSVAL_TO_OBJECT(v));
+    JS::RootedObject Array(cx, v.toObjectOrNull());
 
     // With no arguments.
     JS::RootedObject obj(cx, JS_New(cx, Array, JS::HandleValueArray::empty()));
     CHECK(obj);
     JS::RootedValue rt(cx, JS::ObjectValue(*obj));
     CHECK(JS_IsArrayObject(cx, obj));
     uint32_t len;
     CHECK(JS_GetArrayLength(cx, obj, &len));
--- a/js/src/jsapi-tests/testParseJSON.cpp
+++ b/js/src/jsapi-tests/testParseJSON.cpp
@@ -99,40 +99,40 @@ BEGIN_TEST(testParseJSON_success)
 
 
     // Arrays
     JS::RootedValue v(cx), v2(cx);
     JS::RootedObject obj(cx);
 
     CHECK(Parse(cx, "[]", &v));
     CHECK(!JSVAL_IS_PRIMITIVE(v));
-    obj = JSVAL_TO_OBJECT(v);
+    obj = v.toObjectOrNull();
     CHECK(JS_IsArrayObject(cx, obj));
     CHECK(JS_GetProperty(cx, obj, "length", &v2));
     CHECK_SAME(v2, JSVAL_ZERO);
 
     CHECK(Parse(cx, "[1]", &v));
     CHECK(!JSVAL_IS_PRIMITIVE(v));
-    obj = JSVAL_TO_OBJECT(v);
+    obj = v.toObjectOrNull();
     CHECK(JS_IsArrayObject(cx, obj));
     CHECK(JS_GetProperty(cx, obj, "0", &v2));
     CHECK_SAME(v2, JSVAL_ONE);
     CHECK(JS_GetProperty(cx, obj, "length", &v2));
     CHECK_SAME(v2, JSVAL_ONE);
 
 
     // Objects
     CHECK(Parse(cx, "{}", &v));
     CHECK(!JSVAL_IS_PRIMITIVE(v));
-    obj = JSVAL_TO_OBJECT(v);
+    obj = v.toObjectOrNull();
     CHECK(!JS_IsArrayObject(cx, obj));
 
     CHECK(Parse(cx, "{ \"f\": 17 }", &v));
     CHECK(!JSVAL_IS_PRIMITIVE(v));
-    obj = JSVAL_TO_OBJECT(v);
+    obj = v.toObjectOrNull();
     CHECK(!JS_IsArrayObject(cx, obj));
     CHECK(JS_GetProperty(cx, obj, "f", &v2));
     CHECK_SAME(v2, INT_TO_JSVAL(17));
 
     return true;
 }
 
 template<size_t N> static JSFlatString *
--- a/js/src/jsapi-tests/testRegExp.cpp
+++ b/js/src/jsapi-tests/testRegExp.cpp
@@ -4,53 +4,53 @@
 
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testObjectIsRegExp)
 {
     JS::RootedValue val(cx);
 
     EVAL("new Object", &val);
-    JS::RootedObject obj(cx, JSVAL_TO_OBJECT(val));
+    JS::RootedObject obj(cx, val.toObjectOrNull());
     CHECK(!JS_ObjectIsRegExp(cx, obj));
 
     EVAL("/foopy/", &val);
-    obj = JSVAL_TO_OBJECT(val);
+    obj = val.toObjectOrNull();
     CHECK(JS_ObjectIsRegExp(cx, obj));
 
     return true;
 }
 END_TEST(testObjectIsRegExp)
 
 BEGIN_TEST(testGetRegExpFlags)
 {
     JS::RootedValue val(cx);
     JS::RootedObject obj(cx);
 
     EVAL("/foopy/", &val);
-    obj = JSVAL_TO_OBJECT(val);
+    obj = val.toObjectOrNull();
     CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), 0);
 
     EVAL("/foopy/g", &val);
-    obj = JSVAL_TO_OBJECT(val);
+    obj = val.toObjectOrNull();
     CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), JSREG_GLOB);
 
     EVAL("/foopy/gi", &val);
-    obj = JSVAL_TO_OBJECT(val);
+    obj = val.toObjectOrNull();
     CHECK_EQUAL(JS_GetRegExpFlags(cx, obj), (JSREG_FOLD | JSREG_GLOB));
 
     return true;
 }
 END_TEST(testGetRegExpFlags)
 
 BEGIN_TEST(testGetRegExpSource)
 {
     JS::RootedValue val(cx);
     JS::RootedObject obj(cx);
 
     EVAL("/foopy/", &val);
-    obj = JSVAL_TO_OBJECT(val);
+    obj = val.toObjectOrNull();
     JSString *source = JS_GetRegExpSource(cx, obj);
     CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(source), "foopy"));
 
     return true;
 }
 END_TEST(testGetRegExpSource)
--- a/js/src/jsapi-tests/testRegExpInstanceProperties.cpp
+++ b/js/src/jsapi-tests/testRegExpInstanceProperties.cpp
@@ -11,28 +11,28 @@
 #include "jsapi-tests/tests.h"
 #include "vm/Shape.h"
 
 BEGIN_TEST(testRegExpInstanceProperties)
 {
     jsval regexpProtoVal;
     EVAL("RegExp.prototype", &regexpProtoVal);
 
-    JSObject *regexpProto = JSVAL_TO_OBJECT(regexpProtoVal);
+    JSObject *regexpProto = regexpProtoVal.toObjectOrNull();
 
     if (!helper(regexpProto))
         return false;
 
     JS_GC(cx);
 
     CHECK_EQUAL(regexpProto->compartment()->initialRegExpShape, nullptr);
 
     jsval regexp;
     EVAL("/foopy/", &regexp);
-    JSObject *robj = JSVAL_TO_OBJECT(regexp);
+    JSObject *robj = regexp.toObjectOrNull();
 
     CHECK(robj->lastProperty());
     CHECK_EQUAL(robj->compartment()->initialRegExpShape, robj->lastProperty());
 
     return true;
 }
 
 /*
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -753,17 +753,17 @@ js_ReportUncaughtException(JSContext *cx
      * unrooted, we must root exnObject.  Later, if exnObject is non-null, we
      * need to root other intermediates, so allocate an operand stack segment
      * to protect all of these values.
      */
     RootedObject exnObject(cx);
     if (JSVAL_IS_PRIMITIVE(exn)) {
         exnObject = nullptr;
     } else {
-        exnObject = JSVAL_TO_OBJECT(exn);
+        exnObject = exn.toObjectOrNull();
     }
 
     JS_ClearPendingException(cx);
     JSErrorReport *reportp = exnObject ? js_ErrorFromException(cx, exnObject)
                                        : nullptr;
 
     // Be careful not to invoke ToString if we've already successfully extracted
     // an error report, since the exception might be wrapped in a security
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -818,17 +818,17 @@ ToDisassemblySource(JSContext *cx, Handl
         char *source = JS_sprintf_append(nullptr, "<value>");
         if (!source)
             return false;
         bytes->initBytes(source);
         return true;
     }
 
     if (!JSVAL_IS_PRIMITIVE(v)) {
-        JSObject *obj = JSVAL_TO_OBJECT(v);
+        JSObject *obj = v.toObjectOrNull();
         if (obj->is<StaticBlockObject>()) {
             Rooted<StaticBlockObject*> block(cx, &obj->as<StaticBlockObject>());
             char *source = JS_sprintf_append(nullptr, "depth %d {", block->localOffset());
             if (!source)
                 return false;
 
             Shape::Range<CanGC> r(cx, block->lastProperty());
 
--- a/js/src/perf/jsperf.cpp
+++ b/js/src/perf/jsperf.cpp
@@ -262,16 +262,16 @@ RegisterPerfMeasurement(JSContext *cx, H
 PerfMeasurement*
 ExtractPerfMeasurement(jsval wrapper)
 {
     if (JSVAL_IS_PRIMITIVE(wrapper))
         return 0;
 
     // This is what JS_GetInstancePrivate does internally.  We can't
     // call JS_anything from here, because we don't have a JSContext.
-    JSObject *obj = JSVAL_TO_OBJECT(wrapper);
+    JSObject *obj = wrapper.toObjectOrNull();
     if (obj->getClass() != js::Valueify(&pm_class))
         return 0;
 
     return (PerfMeasurement*) obj->getPrivate();
 }
 
 } // namespace JS
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -3066,17 +3066,17 @@ resolver_resolve(JSContext *cx, HandleOb
     Rooted<JSObject*> vobj(cx, &v.toObject());
     return CopyProperty(cx, obj, vobj, id, objp);
 }
 
 static bool
 resolver_enumerate(JSContext *cx, HandleObject obj)
 {
     jsval v = JS_GetReservedSlot(obj, 0);
-    RootedObject referent(cx, JSVAL_TO_OBJECT(v));
+    RootedObject referent(cx, v.toObjectOrNull());
 
     AutoIdArray ida(cx, JS_Enumerate(cx, referent));
     bool ok = !!ida;
     RootedObject ignore(cx);
     for (size_t i = 0; ok && i < ida.length(); i++) {
         Rooted<jsid> id(cx, ida[i]);
         ok = CopyProperty(cx, obj, referent, id, &ignore);
     }
@@ -4196,17 +4196,17 @@ Wrap(JSContext *cx, unsigned argc, jsval
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     Value v = args.get(0);
     if (JSVAL_IS_PRIMITIVE(v)) {
         args.rval().set(v);
         return true;
     }
 
-    RootedObject obj(cx, JSVAL_TO_OBJECT(v));
+    RootedObject obj(cx, v.toObjectOrNull());
     JSObject *wrapped = Wrapper::New(cx, obj, &obj->global(),
                                      &Wrapper::singleton);
     if (!wrapped)
         return false;
 
     args.rval().setObject(*wrapped);
     return true;
 }
@@ -4978,17 +4978,17 @@ Help(JSContext *cx, unsigned argc, jsval
             RootedValue v(cx);
             RootedId id(cx, ida[i]);
             if (!JS_LookupPropertyById(cx, global, id, &v))
                 return false;
             if (JSVAL_IS_PRIMITIVE(v)) {
                 JS_ReportError(cx, "primitive arg");
                 return false;
             }
-            obj = JSVAL_TO_OBJECT(v);
+            obj = v.toObjectOrNull();
             if (!PrintHelp(cx, obj))
                 return false;
         }
     } else {
         for (unsigned i = 0; i < args.length(); i++) {
             if (args[i].isPrimitive()) {
                 JS_ReportError(cx, "primitive arg");
                 return false;
--- a/js/src/tests/js1_5/Regress/regress-457065-03.js
+++ b/js/src/tests/js1_5/Regress/regress-457065-03.js
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //-----------------------------------------------------------------------------
 var BUGNUMBER = 457065;
-var summary = 'Do not assert: !fp->callee || fp->thisp == JSVAL_TO_OBJECT(fp->argv[-1])';
+var summary = 'Do not assert: !fp->callee || fp->thisp == fp->argv[-1].toObjectOrNull()';
 var actual = '';
 var expect = '';
 
 
 //-----------------------------------------------------------------------------
 test();
 //-----------------------------------------------------------------------------
 
--- a/js/src/tests/js1_8/regress/regress-457065-01.js
+++ b/js/src/tests/js1_8/regress/regress-457065-01.js
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //-----------------------------------------------------------------------------
 var BUGNUMBER = 457065;
-var summary = 'Do not assert: !fp->callee || fp->thisp == JSVAL_TO_OBJECT(fp->argv[-1])';
+var summary = 'Do not assert: !fp->callee || fp->thisp == fp->argv[-1].toObjectOrNull()';
 var actual = '';
 var expect = '';
 
 
 //-----------------------------------------------------------------------------
 test();
 //-----------------------------------------------------------------------------
 
--- a/js/src/tests/js1_8/regress/regress-457065-02.js
+++ b/js/src/tests/js1_8/regress/regress-457065-02.js
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //-----------------------------------------------------------------------------
 var BUGNUMBER = 457065;
-var summary = 'Do not assert: !fp->callee || fp->thisp == JSVAL_TO_OBJECT(fp->argv[-1])';
+var summary = 'Do not assert: !fp->callee || fp->thisp == fp->argv[-1].toObjectOrNull()';
 var actual = '';
 var expect = '';
 
 
 //-----------------------------------------------------------------------------
 test();
 //-----------------------------------------------------------------------------
 
--- a/js/src/tests/js1_8_1/regress/regress-452498-123.js
+++ b/js/src/tests/js1_8_1/regress/regress-452498-123.js
@@ -40,17 +40,17 @@ function test()
 // Assertion failure: dn->pn_defn, at ../jsemit.cpp:1873
 // =====
 
 
 // Requires -j:
 // =====
   (function(){ eval("for (x in ['', {}, '', {}]) { this; }" )})();
 
-// Assertion failure: fp->thisp == JSVAL_TO_OBJECT(fp->argv[-1]), at ../jstracer.cpp:4172
+// Assertion failure: fp->thisp == fp->argv[-1].toObjectOrNull(), at ../jstracer.cpp:4172
 // =====
   for each (let x in ['', '', '']) { (new function(){} )}
 
 // Assertion failure: scope->object == ctor, at ../jsbuiltins.cpp:236
 // Opt crash [@ js_FastNewObject] near null
 // =====
 
   reportCompare(expect, actual, summary);
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2464,17 +2464,17 @@ nsXPCComponents_Constructor::CallOrConst
         if (!str || !JS_StringToId(cx, str, &id))
             return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
 
         RootedValue val(cx);
         if (!JS_GetPropertyById(cx, classesObj, id, &val) || val.isPrimitive())
             return ThrowAndFail(NS_ERROR_XPC_BAD_CID, cx, _retval);
 
         nsCOMPtr<nsIXPConnectWrappedNative> wn;
-        if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(val),
+        if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, val.toObjectOrNull(),
                                                       getter_AddRefs(wn))) || !wn ||
             !(cClassID = do_QueryWrappedNative(wn))) {
             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
         }
     }
 
     nsCOMPtr<nsIXPCConstructor> ctor = new nsXPCConstructor(cClassID, cInterfaceID, cInitializer);
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder2;
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -1119,17 +1119,17 @@ XPCConvert::JSValToXPCException(MutableH
                                 const char* methodName,
                                 nsIException** exceptn)
 {
     AutoJSContext cx;
     AutoExceptionRestorer aer(cx, s);
 
     if (!JSVAL_IS_PRIMITIVE(s)) {
         // we have a JSObject
-        RootedObject obj(cx, JSVAL_TO_OBJECT(s));
+        RootedObject obj(cx, s.toObjectOrNull());
 
         if (!obj) {
             NS_ERROR("when is an object not an object?");
             return NS_ERROR_FAILURE;
         }
 
         // is this really a native xpcom object with a wrapper?
         JSObject *unwrapped = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -640,17 +640,17 @@ static const nsID*
 GetIIDArg(uint32_t argc, const JS::Value& val, JSContext* cx)
 {
     const nsID* iid;
 
     // If an IID was passed in then use it
     if (argc) {
         JSObject* iidobj;
         if (JSVAL_IS_PRIMITIVE(val) ||
-            !(iidobj = JSVAL_TO_OBJECT(val)) ||
+            !(iidobj = val.toObjectOrNull()) ||
             !(iid = xpc_JSObjectToID(cx, iidobj))) {
             return nullptr;
         }
     } else
         iid = &NS_GET_IID(nsISupports);
 
     return iid;
 }
--- a/js/xpconnect/src/XPCQuickStubs.h
+++ b/js/xpconnect/src/XPCQuickStubs.h
@@ -592,17 +592,17 @@ PropertyOpForwarder(JSContext *cx, unsig
 
     JS::RootedObject callee(cx, &args.callee());
     JS::RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));
     if (!obj)
         return false;
 
     JS::RootedValue v(cx, js::GetFunctionNativeReserved(callee, 0));
 
-    JSObject *ptrobj = JSVAL_TO_OBJECT(v);
+    JSObject *ptrobj = v.toObjectOrNull();
     Op *popp = static_cast<Op *>(JS_GetPrivate(ptrobj));
 
     v = js::GetFunctionNativeReserved(callee, 1);
 
     JS::RootedValue argval(cx, args.get(0));
     JS::RootedId id(cx);
     if (!JS_ValueToId(cx, v, &id))
         return false;
--- a/js/xpconnect/src/XPCVariant.cpp
+++ b/js/xpconnect/src/XPCVariant.cpp
@@ -82,17 +82,17 @@ XPCTraceableVariant::GetTraceName(JSTrac
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(XPCVariant)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XPCVariant)
     JS::Value val = tmp->GetJSValPreserveColor();
     if (val.isObjectOrNull()) {
         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mJSVal");
-        cb.NoteJSChild(JSVAL_TO_OBJECT(val));
+        cb.NoteJSChild(val.toObjectOrNull());
     }
 
     nsVariant::Traverse(tmp->mData, cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPCVariant)
     JS::Value val = tmp->GetJSValPreserveColor();
 
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -1079,17 +1079,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
                                 xpcObjectHelper helper(newThis);
                                 bool ok =
                                   XPCConvert::NativeInterface2JSObject(
                                       &v, nullptr, helper, nullptr,
                                       nullptr, false, nullptr);
                                 if (!ok) {
                                     goto pre_call_clean_up;
                                 }
-                                thisObj = JSVAL_TO_OBJECT(v);
+                                thisObj = v.toObjectOrNull();
                                 if (!JS_WrapObject(cx, &thisObj))
                                     goto pre_call_clean_up;
                             }
                         }
                     }
                 }
             }
         } else {
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -117,17 +117,17 @@ GetDoubleWrappedJSObject(XPCCallContext&
             RootedId id(ccx, ccx.GetRuntime()->
                             GetStringID(XPCJSRuntime::IDX_WRAPPED_JSOBJECT));
 
             JSAutoCompartment ac(ccx, mainObj);
 
             RootedValue val(ccx);
             if (JS_GetPropertyById(ccx, mainObj, id, &val) &&
                 !JSVAL_IS_PRIMITIVE(val)) {
-                obj = JSVAL_TO_OBJECT(val);
+                obj = val.toObjectOrNull();
             }
         }
     }
     return obj;
 }
 
 // This is the getter native function we use to handle 'wrappedJSObject' for
 // double wrapped JSObjects.
@@ -376,17 +376,17 @@ DefinePropertyIfFound(XPCCallContext& cc
                                      propFlags);
     }
 
     // else...
 
     MOZ_ASSERT(member->IsAttribute(), "way broken!");
 
     propFlags |= JSPROP_GETTER | JSPROP_SHARED;
-    JSObject* funobj = JSVAL_TO_OBJECT(funval);
+    JSObject* funobj = funval.toObjectOrNull();
     JSPropertyOp getter = JS_DATA_TO_FUNC_PTR(JSPropertyOp, funobj);
     JSStrictPropertyOp setter;
     if (member->IsWritableAttribute()) {
         propFlags |= JSPROP_SETTER;
         propFlags &= ~JSPROP_READONLY;
         setter = JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, funobj);
     } else {
         setter = js_GetterOnlyPropertyStub;
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -830,17 +830,17 @@ nsXPConnect::CreateSandbox(JSContext *cx
 
     RootedValue rval(cx);
     SandboxOptions options;
     nsresult rv = CreateSandboxObject(cx, &rval, principal, options);
     MOZ_ASSERT(NS_FAILED(rv) || !JSVAL_IS_PRIMITIVE(rval),
                "Bad return value from xpc_CreateSandboxObject()!");
 
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(rval)) {
-        *_retval = XPCJSObjectHolder::newHolder(JSVAL_TO_OBJECT(rval));
+        *_retval = XPCJSObjectHolder::newHolder(rval.toObjectOrNull());
         NS_ENSURE_TRUE(*_retval, NS_ERROR_OUT_OF_MEMORY);
 
         NS_ADDREF(*_retval);
     }
 
     return rv;
 }
 
--- a/js/xpconnect/src/qsgen.py
+++ b/js/xpconnect/src/qsgen.py
@@ -558,17 +558,17 @@ def writeArgumentUnboxing(f, i, name, ty
             f.write("    %s *%s;\n" % (type.name, name))
             f.write("    xpc_qsSelfRef %sref;\n" % name)
             f.write("    rv = xpc_qsUnwrapArg<%s>("
                     "cx, %s, &%s, &%sref.ptr, %s);\n"
                     % (type.name, argVal, name, name, argPtr))
             f.write("    if (NS_FAILED(rv)) {\n")
             if isSetter:
                 assert(propIndex is not None)
-                f.write("        xpc_qsThrowBadSetterValue(cx, rv, JSVAL_TO_OBJECT(vp[1]), (uint16_t)%s);\n" %
+                f.write("        xpc_qsThrowBadSetterValue(cx, rv, vp[1].toObjectOrNull(), (uint16_t)%s);\n" %
                         propIndex)
             else:
                 f.write("        xpc_qsThrowBadArg(cx, rv, vp, %d);\n" % i)
             f.write("        return false;\n"
                     "    }\n")
             return True
 
     warn("Unable to unbox argument of type %s (native type %s)" % (type.name, typeName))
@@ -981,17 +981,17 @@ def writeQuickStub(f, customMethodCalls,
     if canFail:
         # Check for errors.
         f.write("    if (NS_FAILED(rv))\n")
         if isMethod:
             f.write("        return xpc_qsThrowMethodFailed("
                     "cx, rv, vp);\n")
         else:
             f.write("        return xpc_qsThrowGetterSetterFailed(cx, rv, " +
-                    "JSVAL_TO_OBJECT(vp[1]), (uint16_t)%d);\n" %
+                    "vp[1].toObjectOrNull(), (uint16_t)%d);\n" %
                     stringtable.stringIndex(member.name))
 
     # Convert the return value.
     if isMethod or isGetter:
         writeResultConv(f, member.realtype, 'args.rval()', '*vp')
     else:
         f.write("    return true;\n")
 
--- a/toolkit/components/ctypes/ctypes.cpp
+++ b/toolkit/components/ctypes/ctypes.cpp
@@ -91,17 +91,17 @@ InitAndSealCTypesClass(JSContext* cx, JS
   if (!JS_InitCTypesClass(cx, global))
     return false;
 
   // Set callbacks for charset conversion and such.
   JS::Rooted<JS::Value> ctypes(cx);
   if (!JS_GetProperty(cx, global, "ctypes", &ctypes))
     return false;
 
-  JS_SetCTypesCallbacks(JSVAL_TO_OBJECT(ctypes), &sCallbacks);
+  JS_SetCTypesCallbacks(ctypes.toObjectOrNull(), &sCallbacks);
 
   // Seal up Object, Function, Array and Error and their prototypes.  (This
   // single object instance is shared amongst everyone who imports the ctypes
   // module.)
   if (!SealObjectAndPrototype(cx, global, "Object") ||
       !SealObjectAndPrototype(cx, global, "Function") ||
       !SealObjectAndPrototype(cx, global, "Array") ||
       !SealObjectAndPrototype(cx, global, "Error"))
--- a/toolkit/components/places/History.cpp
+++ b/toolkit/components/places/History.cpp
@@ -266,17 +266,17 @@ GetJSArrayFromJSValue(JS::Handle<JS::Val
  */
 already_AddRefed<nsIURI>
 GetJSValueAsURI(JSContext* aCtx,
                 const JS::Value& aValue) {
   if (!JSVAL_IS_PRIMITIVE(aValue)) {
     nsCOMPtr<nsIXPConnect> xpc = mozilla::services::GetXPConnect();
 
     nsCOMPtr<nsIXPConnectWrappedNative> wrappedObj;
-    nsresult rv = xpc->GetWrappedNativeOfJSObject(aCtx, JSVAL_TO_OBJECT(aValue),
+    nsresult rv = xpc->GetWrappedNativeOfJSObject(aCtx, aValue.toObjectOrNull(),
                                                   getter_AddRefs(wrappedObj));
     NS_ENSURE_SUCCESS(rv, nullptr);
     nsCOMPtr<nsIURI> uri = do_QueryWrappedNative(wrappedObj);
     return uri.forget();
   }
   return nullptr;
 }
 
@@ -2806,17 +2806,17 @@ History::UpdatePlaces(JS::Handle<JS::Val
     GetStringFromJSObject(aCtx, info, "title", title);
 
     JS::Rooted<JSObject*> visits(aCtx, nullptr);
     {
       JS::Rooted<JS::Value> visitsVal(aCtx);
       bool rc = JS_GetProperty(aCtx, info, "visits", &visitsVal);
       NS_ENSURE_TRUE(rc, NS_ERROR_UNEXPECTED);
       if (!JSVAL_IS_PRIMITIVE(visitsVal)) {
-        visits = JSVAL_TO_OBJECT(visitsVal);
+        visits = visitsVal.toObjectOrNull();
         NS_ENSURE_ARG(JS_IsArrayObject(aCtx, visits));
       }
     }
     NS_ENSURE_ARG(visits);
 
     uint32_t visitsLength = 0;
     if (visits) {
       (void)JS_GetArrayLength(aCtx, visits, &visitsLength);