Bug 952650 (part 12) - Remove JSVAL_TO_OBJECT. r=till.
authorNicholas Nethercote <nnethercote@mozilla.com>
Sun, 27 Apr 2014 19:58:52 -0700
changeset 200142 a61fdeb956a6320950735cd4efc1c743f378d402
parent 200141 d5711e3806d056664938d62ef58f2c54eeff6cf0
child 200143 7cdc75f1615bce66f71c58742d01ed888e2ad038
push idunknown
push userunknown
push dateunknown
reviewerstill
bugs952650
milestone32.0a1
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);