Bug 959787 - Handlify remaining JS APIs r=sfink r=bholley r=smaug
authorJon Coppeard <jcoppeard@mozilla.com>
Wed, 02 Apr 2014 15:28:03 +0100
changeset 195217 695622cd84e1494f5e4bfa64e181b0aa404c599d
parent 195216 d1efe20d0350ae6ea4c941d3f1c3168b5a5582c4
child 195218 3b1f882ca91602d404726f5bf3925b6835b92a39
push idunknown
push userunknown
push dateunknown
reviewerssfink, bholley, smaug
bugs959787
milestone31.0a1
Bug 959787 - Handlify remaining JS APIs r=sfink r=bholley r=smaug
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/plugins/base/nsJSNPRuntime.cpp
dom/workers/WorkerPrivate.cpp
ipc/nfc/Nfc.cpp
ipc/ril/Ril.cpp
js/ipc/JavaScriptShared.cpp
js/jsd/jsd_scpt.cpp
js/public/OldDebugAPI.h
js/public/StructuredClone.h
js/src/jsapi-tests/testDebugger.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/shell/js.cpp
js/src/vm/ArrayBufferObject.cpp
js/src/vm/OldDebugAPI.cpp
js/src/vm/StructuredClone.cpp
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCMaps.h
js/xpconnect/src/XPCQuickStubs.h
js/xpconnect/src/XPCWrappedNative.cpp
storage/src/mozStorageStatementParams.cpp
xpcom/io/nsBinaryStream.cpp
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -3907,22 +3907,21 @@ nsStorage2SH::NewEnumerate(nsIXPConnectW
     return NS_OK;
   }
 
   nsTArray<nsString> *keys =
     (nsTArray<nsString> *)JSVAL_TO_PRIVATE(*statep);
 
   if (enum_op == JSENUMERATE_NEXT && keys->Length() != 0) {
     nsString& key = keys->ElementAt(0);
-    JSString *str =
-      JS_NewUCStringCopyN(cx, key.get(), key.Length());
+    JS::Rooted<JSString*> str(cx, JS_NewUCStringCopyN(cx, key.get(), key.Length()));
     NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
 
     JS::Rooted<jsid> id(cx);
-    JS_ValueToId(cx, JS::StringValue(str), &id);
+    JS_StringToId(cx, str, &id);
     *idp = id;
 
     keys->RemoveElementAt(0);
 
     return NS_OK;
   }
 
   // destroy the keys array if we have no keys or if we're done
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2482,28 +2482,28 @@ nsGlobalWindow::SetNewDocument(nsIDocume
       js::SetProxyExtra(outerObject, 0, js::PrivateValue(ToSupports(this)));
 
       mJSObject = outerObject;
       SetWrapper(mJSObject);
 
       {
         JSAutoCompartment ac(cx, mJSObject);
 
-        JS_SetParent(cx, mJSObject, newInnerWindow->mJSObject);
-
         JS::Rooted<JSObject*> obj(cx, mJSObject);
+        JS::Rooted<JSObject*> newParent(cx, newInnerWindow->mJSObject);
+        JS_SetParent(cx, obj, newParent);
 
         // Inform the nsJSContext, which is the canonical holder of the outer.
         mContext->SetWindowProxy(obj);
 
         NS_ASSERTION(!JS_IsExceptionPending(cx),
                      "We might overwrite a pending exception!");
-        XPCWrappedNativeScope* scope = xpc::GetObjectScope(mJSObject);
+        XPCWrappedNativeScope* scope = xpc::GetObjectScope(obj);
         if (scope->mWaiverWrapperMap) {
-          scope->mWaiverWrapperMap->Reparent(cx, newInnerWindow->mJSObject);
+          scope->mWaiverWrapperMap->Reparent(cx, newParent);
         }
       }
     }
 
     // Enter the new global's compartment.
     JSAutoCompartment ac(cx, mJSObject);
 
     // Set scriptability based on the state of the docshell.
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2788,19 +2788,20 @@ NS_DOMWriteStructuredClone(JSContext* cx
 
   // Prepare the ImageData internals.
   uint32_t width = imageData->Width();
   uint32_t height = imageData->Height();
   JS::Rooted<JSObject*> dataArray(cx, imageData->GetDataObject());
 
   // Write the internals to the stream.
   JSAutoCompartment ac(cx, dataArray);
+  JS::Rooted<JS::Value> arrayValue(cx, JS::ObjectValue(*dataArray));
   return JS_WriteUint32Pair(writer, SCTAG_DOM_IMAGEDATA, 0) &&
          JS_WriteUint32Pair(writer, width, height) &&
-         JS_WriteTypedArray(writer, JS::ObjectValue(*dataArray));
+         JS_WriteTypedArray(writer, arrayValue);
 }
 
 void
 NS_DOMStructuredCloneError(JSContext* cx,
                            uint32_t errorid)
 {
   // We don't currently support any extensions to structured cloning.
   xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -866,19 +866,20 @@ nsJSObjWrapper::NP_Enumerate(NPObject *n
     return false;
   }
 
   nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
 
   nsCxPusher pusher;
   pusher.Push(cx);
   AutoJSExceptionReporter reporter(cx);
-  JSAutoCompartment ac(cx, npjsobj->mJSObj);
+  JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
+  JSAutoCompartment ac(cx, jsobj);
 
-  JS::AutoIdArray ida(cx, JS_Enumerate(cx, npjsobj->mJSObj));
+  JS::AutoIdArray ida(cx, JS_Enumerate(cx, jsobj));
   if (!ida) {
     return false;
   }
 
   *count = ida.length();
   *idarray = (NPIdentifier *)PR_Malloc(*count * sizeof(NPIdentifier));
   if (!*idarray) {
     ThrowJSException(cx, "Memory allocation failed for NPIdentifier!");
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -421,19 +421,20 @@ struct WorkerStructuredCloneCallbacks
       if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageData, aObj, imageData))) {
         // Prepare the ImageData internals.
         uint32_t width = imageData->Width();
         uint32_t height = imageData->Height();
         JS::Rooted<JSObject*> dataArray(aCx, imageData->GetDataObject());
 
         // Write the internals to the stream.
         JSAutoCompartment ac(aCx, dataArray);
+        JS::Rooted<JS::Value> arrayValue(aCx, JS::ObjectValue(*dataArray));
         return JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEDATA, 0) &&
                JS_WriteUint32Pair(aWriter, width, height) &&
-               JS_WriteTypedArray(aWriter, JS::ObjectValue(*dataArray));
+               JS_WriteTypedArray(aWriter, arrayValue);
       }
     }
 
     Error(aCx, 0);
     return false;
   }
 
   static void
--- a/ipc/nfc/Nfc.cpp
+++ b/ipc/nfc/Nfc.cpp
@@ -86,17 +86,17 @@ PostToNFC(JSContext* aCx,
     }
 
     JS::Value v = args[0];
 
     JSAutoByteString abs;
     void* data;
     size_t size;
     if (JSVAL_IS_STRING(v)) {
-        JSString* str = JSVAL_TO_STRING(v);
+        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);
--- a/ipc/ril/Ril.cpp
+++ b/ipc/ril/Ril.cpp
@@ -91,17 +91,17 @@ PostToRIL(JSContext *aCx,
 
     int clientId = args[0].toInt32();
     JS::Value v = args[1];
 
     JSAutoByteString abs;
     void *data;
     size_t size;
     if (JSVAL_IS_STRING(v)) {
-        JSString *str = JSVAL_TO_STRING(v);
+        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);
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -153,17 +153,17 @@ JavaScriptShared::convertIdToGeckoString
 
 bool
 JavaScriptShared::convertGeckoStringToId(JSContext *cx, const nsString &from, JS::MutableHandleId to)
 {
     RootedString str(cx, JS_NewUCStringCopyN(cx, from.BeginReading(), from.Length()));
     if (!str)
         return false;
 
-    return JS_ValueToId(cx, StringValue(str), to);
+    return JS_StringToId(cx, str, to);
 }
 
 bool
 JavaScriptShared::toVariant(JSContext *cx, JS::HandleValue from, JSVariant *to)
 {
     switch (JS_TypeOfValue(cx, from)) {
       case JSTYPE_VOID:
         *to = void_t();
--- a/js/jsd/jsd_scpt.cpp
+++ b/js/jsd/jsd_scpt.cpp
@@ -537,19 +537,20 @@ jsd_GetScriptHook(JSDContext* jsdc, JSD_
     return true;
 }    
 
 bool
 jsd_EnableSingleStepInterrupts(JSDContext* jsdc, JSDScript* jsdscript, bool enable)
 {
     bool rv;
     AutoSafeJSContext cx;
-    JSAutoCompartment ac(cx, jsdscript->script);
+    JS::RootedScript script(cx, jsdscript->script);
+    JSAutoCompartment ac(cx, script);
     JSD_LOCK();
-    rv = JS_SetSingleStepMode(cx, jsdscript->script, enable);
+    rv = JS_SetSingleStepMode(cx, script, enable);
     JSD_UNLOCK();
     return rv;
 }
 
 
 /***************************************************************************/
 
 void
--- a/js/public/OldDebugAPI.h
+++ b/js/public/OldDebugAPI.h
@@ -194,17 +194,17 @@ JS_SetDebugModeForCompartment(JSContext 
 /*
  * Turn on/off debugging mode for a context's compartment.
  */
 JS_FRIEND_API(bool)
 JS_SetDebugMode(JSContext *cx, bool debug);
 
 /* Turn on single step mode. */
 extern JS_PUBLIC_API(bool)
-JS_SetSingleStepMode(JSContext *cx, JSScript *script, bool singleStep);
+JS_SetSingleStepMode(JSContext *cx, JS::HandleScript script, bool singleStep);
 
 /* The closure argument will be marked. */
 extern JS_PUBLIC_API(bool)
 JS_SetTrap(JSContext *cx, JS::HandleScript script, jsbytecode *pc,
            JSTrapHandler handler, JS::HandleValue closure);
 
 extern JS_PUBLIC_API(void)
 JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
@@ -527,17 +527,17 @@ JS_GetGlobalDebugHooks(JSRuntime *rt);
 extern JS_PUBLIC_API(bool)
 JS_DefineProfilingFunctions(JSContext *cx, JSObject *obj);
 
 /* Defined in vm/Debugger.cpp. */
 extern JS_PUBLIC_API(bool)
 JS_DefineDebuggerObject(JSContext *cx, JS::HandleObject obj);
 
 extern JS_PUBLIC_API(void)
-JS_DumpPCCounts(JSContext *cx, JSScript *script);
+JS_DumpPCCounts(JSContext *cx, JS::HandleScript script);
 
 extern JS_PUBLIC_API(void)
 JS_DumpCompartmentPCCounts(JSContext *cx);
 
 namespace js {
 extern JS_FRIEND_API(bool)
 CanCallContextDebugHandler(JSContext *cx);
 }
--- a/js/public/StructuredClone.h
+++ b/js/public/StructuredClone.h
@@ -153,11 +153,11 @@ JS_ReadTypedArray(JSStructuredCloneReade
 
 JS_PUBLIC_API(bool)
 JS_WriteUint32Pair(JSStructuredCloneWriter *w, uint32_t tag, uint32_t data);
 
 JS_PUBLIC_API(bool)
 JS_WriteBytes(JSStructuredCloneWriter *w, const void *p, size_t len);
 
 JS_PUBLIC_API(bool)
-JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::Value v);
+JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::HandleValue v);
 
 #endif  /* js_StructuredClone_h */
--- a/js/src/jsapi-tests/testDebugger.cpp
+++ b/js/src/jsapi-tests/testDebugger.cpp
@@ -253,17 +253,18 @@ BEGIN_TEST(testDebugger_singleStepThrow)
     }
 
     static bool
     setStepMode(JSContext *cx, unsigned argc, jsval *vp)
     {
         CallArgs args = CallArgsFromVp(argc, vp);
 
         NonBuiltinScriptFrameIter iter(cx);
-        if (!JS_SetSingleStepMode(cx, iter.script(), true))
+        JS::RootedScript script(cx, iter.script());
+        if (!JS_SetSingleStepMode(cx, script, true))
             return false;
 
         args.rval().set(UndefinedValue());
         return true;
     }
 
     static JSTrapStatus
     onStep(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, void *closure)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -2170,26 +2170,35 @@ JS_IdArrayGet(JSContext *cx, JSIdArray *
 
 JS_PUBLIC_API(void)
 JS_DestroyIdArray(JSContext *cx, JSIdArray *ida)
 {
     cx->runtime()->defaultFreeOp()->free_(ida);
 }
 
 JS_PUBLIC_API(bool)
-JS_ValueToId(JSContext *cx, jsval valueArg, MutableHandleId idp)
-{
-    RootedValue value(cx, valueArg);
+JS_ValueToId(JSContext *cx, HandleValue value, MutableHandleId idp)
+{
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, value);
     return ValueToId<CanGC>(cx, value, idp);
 }
 
 JS_PUBLIC_API(bool)
+JS_StringToId(JSContext *cx, HandleString string, MutableHandleId idp)
+{
+    AssertHeapIsIdle(cx);
+    CHECK_REQUEST(cx);
+    assertSameCompartment(cx, string);
+    RootedValue value(cx, StringValue(string));
+    return ValueToId<CanGC>(cx, value, idp);
+}
+
+JS_PUBLIC_API(bool)
 JS_IdToValue(JSContext *cx, jsid id, MutableHandleValue vp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     vp.set(IdToValue(id));
     assertSameCompartment(cx, vp);
     return true;
 }
@@ -2346,20 +2355,18 @@ JS_SetPrototype(JSContext *cx, JS::Handl
 JS_PUBLIC_API(JSObject *)
 JS_GetParent(JSObject *obj)
 {
     JS_ASSERT(!obj->is<ScopeObject>());
     return obj->getParent();
 }
 
 JS_PUBLIC_API(bool)
-JS_SetParent(JSContext *cx, JSObject *objArg, JSObject *parentArg)
-{
-    RootedObject obj(cx, objArg);
-    RootedObject parent(cx, parentArg);
+JS_SetParent(JSContext *cx, HandleObject obj, HandleObject parent)
+{
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     JS_ASSERT(!obj->is<ScopeObject>());
     JS_ASSERT(parent || !obj->getParent());
     assertSameCompartment(cx, obj, parent);
 
     return JSObject::setParent(cx, obj, parent);
 }
@@ -3305,21 +3312,19 @@ JS_ForwardGetPropertyTo(JSContext *cx, J
 
 JS_PUBLIC_API(bool)
 JS_GetElement(JSContext *cx, HandleObject objArg, uint32_t index, MutableHandleValue vp)
 {
     return JS_ForwardGetElementTo(cx, objArg, index, objArg, vp);
 }
 
 JS_PUBLIC_API(bool)
-JS_ForwardGetElementTo(JSContext *cx, JSObject *objArg, uint32_t index, JSObject *onBehalfOfArg,
+JS_ForwardGetElementTo(JSContext *cx, HandleObject obj, uint32_t index, HandleObject onBehalfOf,
                        MutableHandleValue vp)
 {
-    RootedObject obj(cx, objArg);
-    RootedObject onBehalfOf(cx, onBehalfOfArg);
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     JSAutoResolveFlags rf(cx, 0);
 
     return JSObject::getElement(cx, obj, onBehalfOf, index, vp);
 }
 
@@ -3507,19 +3512,18 @@ LastConfigurableShape(JSObject *obj)
         Shape *shape = &r.front();
         if (shape->configurable())
             return shape;
     }
     return nullptr;
 }
 
 JS_PUBLIC_API(void)
-JS_ClearNonGlobalObject(JSContext *cx, JSObject *objArg)
-{
-    RootedObject obj(cx, objArg);
+JS_ClearNonGlobalObject(JSContext *cx, HandleObject obj)
+{
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
 
     JS_ASSERT(!obj->is<GlobalObject>());
 
     if (!obj->isNative())
         return;
@@ -3558,19 +3562,18 @@ JS_SetAllNonReservedSlotsToUndefined(JSC
     const Class *clasp = obj->getClass();
     unsigned numReserved = JSCLASS_RESERVED_SLOTS(clasp);
     unsigned numSlots = obj->slotSpan();
     for (unsigned i = numReserved; i < numSlots; i++)
         obj->setSlot(i, UndefinedValue());
 }
 
 JS_PUBLIC_API(JSIdArray *)
-JS_Enumerate(JSContext *cx, JSObject *objArg)
-{
-    RootedObject obj(cx, objArg);
+JS_Enumerate(JSContext *cx, HandleObject obj)
+{
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
 
     AutoIdVector props(cx);
     JSIdArray *ida;
     if (!GetPropertyNames(cx, obj, JSITER_OWNONLY, &props) || !VectorToIdArray(cx, props, &ida))
         return nullptr;
@@ -4973,19 +4976,18 @@ JS::Call(JSContext *cx, HandleValue this
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, thisv, fval, args);
     AutoLastFrameCheck lfc(cx);
 
     return Invoke(cx, thisv, fval, args.length(), args.begin(), rval);
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_New(JSContext *cx, JSObject *ctorArg, const JS::HandleValueArray& inputArgs)
-{
-    RootedObject ctor(cx, ctorArg);
+JS_New(JSContext *cx, HandleObject ctor, const JS::HandleValueArray& inputArgs)
+{
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, ctor, inputArgs);
     AutoLastFrameCheck lfc(cx);
 
     // This is not a simple variation of JS_CallFunctionValue because JSOP_NEW
     // is not a simple variation of JSOP_CALL. We have to determine what class
     // of object to create, create it, and clamp the return value to an object,
@@ -5382,17 +5384,17 @@ JS_EncodeString(JSContext *cx, JSString 
     JSLinearString *linear = str->ensureLinear(cx);
     if (!linear)
         return nullptr;
 
     return LossyTwoByteCharsToNewLatin1CharsZ(cx, linear->range()).c_str();
 }
 
 JS_PUBLIC_API(char *)
-JS_EncodeStringToUTF8(JSContext *cx, JSString *str)
+JS_EncodeStringToUTF8(JSContext *cx, HandleString str)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
     JSLinearString *linear = str->ensureLinear(cx);
     if (!linear)
         return nullptr;
 
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2268,17 +2268,20 @@ class AutoIdArray : private AutoGCRooter
     /* No copy or assignment semantics. */
     AutoIdArray(AutoIdArray &ida) MOZ_DELETE;
     void operator=(AutoIdArray &ida) MOZ_DELETE;
 };
 
 } /* namespace JS */
 
 extern JS_PUBLIC_API(bool)
-JS_ValueToId(JSContext *cx, jsval v, JS::MutableHandle<jsid> idp);
+JS_ValueToId(JSContext *cx, JS::HandleValue v, JS::MutableHandleId idp);
+
+extern JS_PUBLIC_API(bool)
+JS_StringToId(JSContext *cx, JS::HandleString s, JS::MutableHandleId idp);
 
 extern JS_PUBLIC_API(bool)
 JS_IdToValue(JSContext *cx, jsid id, JS::MutableHandle<JS::Value> vp);
 
 /*
  * JSNewResolveOp flag bits.
  */
 #define JSRESOLVE_ASSIGNING     0x01    /* resolve on the left of assignment */
@@ -2515,17 +2518,17 @@ JS_GetPrototype(JSContext *cx, JS::Handl
 
 extern JS_PUBLIC_API(bool)
 JS_SetPrototype(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_GetParent(JSObject *obj);
 
 extern JS_PUBLIC_API(bool)
-JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent);
+JS_SetParent(JSContext *cx, JS::HandleObject obj, JS::HandleObject parent);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_GetConstructor(JSContext *cx, JS::Handle<JSObject*> proto);
 
 /*
  * Get a unique identifier for obj, good for the lifetime of obj (even if it
  * is moved by a copying GC).  Return false on failure (likely out of memory),
  * and true with *idp containing the unique id on success.
@@ -2717,17 +2720,17 @@ JS_DeepFreezeObject(JSContext *cx, JS::H
  */
 extern JS_PUBLIC_API(bool)
 JS_FreezeObject(JSContext *cx, JS::Handle<JSObject*> obj);
 
 extern JS_PUBLIC_API(bool)
 JS_PreventExtensions(JSContext *cx, JS::HandleObject obj);
 
 extern JS_PUBLIC_API(JSObject *)
-JS_New(JSContext *cx, JSObject *ctor, const JS::HandleValueArray& args);
+JS_New(JSContext *cx, JS::HandleObject ctor, const JS::HandleValueArray& args);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, const JSClass *clasp,
                 JSObject *proto, unsigned attrs);
 
 extern JS_PUBLIC_API(bool)
 JS_DefineConstDoubles(JSContext *cx, JS::HandleObject obj, const JSConstDoubleSpec *cds);
 
@@ -3032,18 +3035,18 @@ JS_HasElement(JSContext *cx, JS::HandleO
 
 extern JS_PUBLIC_API(bool)
 JS_LookupElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(bool)
 JS_GetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(bool)
-JS_ForwardGetElementTo(JSContext *cx, JSObject *obj, uint32_t index, JSObject *onBehalfOf,
-                       JS::MutableHandleValue vp);
+JS_ForwardGetElementTo(JSContext *cx, JS::HandleObject obj, uint32_t index,
+                       JS::HandleObject onBehalfOf, JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(bool)
 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v);
 
 extern JS_PUBLIC_API(bool)
 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleObject v);
 
 extern JS_PUBLIC_API(bool)
@@ -3064,17 +3067,17 @@ JS_DeleteElement(JSContext *cx, JS::Hand
 extern JS_PUBLIC_API(bool)
 JS_DeleteElement2(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded);
 
 /*
  * Remove all configurable properties from the given (non-global) object and
  * assign undefined to all writable data properties.
  */
 JS_PUBLIC_API(void)
-JS_ClearNonGlobalObject(JSContext *cx, JSObject *objArg);
+JS_ClearNonGlobalObject(JSContext *cx, JS::HandleObject obj);
 
 /*
  * Assign 'undefined' to all of the object's non-reserved slots. Note: this is
  * done for all slots, regardless of the associated property descriptor.
  */
 JS_PUBLIC_API(void)
 JS_SetAllNonReservedSlotsToUndefined(JSContext *cx, JSObject *objArg);
 
@@ -3108,17 +3111,17 @@ JS_AllocateArrayBufferContents(JSContext
  * Reallocate memory allocated by JS_AllocateArrayBufferContents, growing or
  * shrinking it as appropriate. If oldContents is null then this behaves like
  * JS_AllocateArrayBufferContents.
  */
 extern JS_PUBLIC_API(void *)
 JS_ReallocateArrayBufferContents(JSContext *cx, uint32_t nbytes, void *oldContents, uint32_t oldNbytes);
 
 extern JS_PUBLIC_API(JSIdArray *)
-JS_Enumerate(JSContext *cx, JSObject *obj);
+JS_Enumerate(JSContext *cx, JS::HandleObject obj);
 
 /*
  * Create an object to iterate over enumerable properties of obj, in arbitrary
  * property definition order.  NB: This differs from longstanding for..in loop
  * order, which uses order of property definition in obj.
  */
 extern JS_PUBLIC_API(JSObject *)
 JS_NewPropertyIterator(JSContext *cx, JS::Handle<JSObject*> obj);
@@ -4050,17 +4053,17 @@ JS_DecodeBytes(JSContext *cx, const char
  */
 JS_PUBLIC_API(char *)
 JS_EncodeString(JSContext *cx, JSString *str);
 
 /*
  * Same behavior as JS_EncodeString(), but encode into UTF-8 string
  */
 JS_PUBLIC_API(char *)
-JS_EncodeStringToUTF8(JSContext *cx, JSString *str);
+JS_EncodeStringToUTF8(JSContext *cx, JS::HandleString str);
 
 /*
  * Get number of bytes in the string encoding (without accounting for a
  * terminating zero bytes. The function returns (size_t) -1 if the string
  * can not be encoded into bytes and reports an error using cx accordingly.
  */
 JS_PUBLIC_API(size_t)
 JS_GetStringEncodingLength(JSContext *cx, JSString *str);
@@ -4107,17 +4110,17 @@ class JSAutoByteString
         JS_ASSERT(!mBytes);
         JS_ASSERT(cx);
         mBytes = JS_EncodeString(cx, str);
         return mBytes;
     }
 
     char *encodeLatin1(js::ExclusiveContext *cx, JSString *str);
 
-    char *encodeUtf8(JSContext *cx, JSString *str) {
+    char *encodeUtf8(JSContext *cx, JS::HandleString str) {
         JS_ASSERT(!mBytes);
         JS_ASSERT(cx);
         mBytes = JS_EncodeStringToUTF8(cx, str);
         return mBytes;
     }
 
     void clear() {
         js_free(mBytes);
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -678,21 +678,19 @@ js::GetWeakmapKeyDelegate(JSObject *key)
 
 JS_FRIEND_API(void)
 JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback)
 {
     rt->telemetryCallback = callback;
 }
 
 JS_FRIEND_API(JSObject *)
-JS_CloneObject(JSContext *cx, JSObject *obj_, JSObject *proto_, JSObject *parent_)
+JS_CloneObject(JSContext *cx, HandleObject obj, HandleObject protoArg, HandleObject parent)
 {
-    RootedObject obj(cx, obj_);
-    Rooted<js::TaggedProto> proto(cx, proto_);
-    RootedObject parent(cx, parent_);
+    Rooted<js::TaggedProto> proto(cx, protoArg.get());
     return CloneObject(cx, obj, proto, parent);
 }
 
 #ifdef DEBUG
 JS_FRIEND_API(void)
 js_DumpString(JSString *str)
 {
     str->dump();
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -128,17 +128,18 @@ JS_SetCompartmentPrincipals(JSCompartmen
 extern JS_FRIEND_API(JSObject *)
 JS_ObjectToInnerObject(JSContext *cx, JS::HandleObject obj);
 
 /* Requires obj != nullptr. */
 extern JS_FRIEND_API(JSObject *)
 JS_ObjectToOuterObject(JSContext *cx, JS::HandleObject obj);
 
 extern JS_FRIEND_API(JSObject *)
-JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent);
+JS_CloneObject(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto,
+               JS::HandleObject parent);
 
 extern JS_FRIEND_API(JSString *)
 JS_BasicObjectToString(JSContext *cx, JS::HandleObject obj);
 
 extern JS_FRIEND_API(bool)
 js_GetterOnlyPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool strict,
                           JS::MutableHandleValue vp);
 
@@ -1411,17 +1412,17 @@ JS_GetFloat32ArrayData(JSObject *obj);
 extern JS_FRIEND_API(double *)
 JS_GetFloat64ArrayData(JSObject *obj);
 
 /*
  * Stable versions of the above functions where the buffer remains valid as long
  * as the object is live.
  */
 extern JS_FRIEND_API(uint8_t *)
-JS_GetStableArrayBufferData(JSContext *cx, JSObject *obj);
+JS_GetStableArrayBufferData(JSContext *cx, JS::HandleObject obj);
 
 /*
  * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific
  * versions when possible.
  */
 extern JS_FRIEND_API(void *)
 JS_GetArrayBufferViewData(JSObject *obj);
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -867,17 +867,17 @@ ParseCompileOptions(JSContext *cx, Compi
         if (!ToUint32(cx, v, &u))
             return false;
         options.setLine(u);
     }
 
     if (!JS_GetProperty(cx, opts, "sourcePolicy", &v))
         return false;
     if (!v.isUndefined()) {
-        JSString *s = ToString(cx, v);
+        RootedString s(cx, ToString(cx, v));
         if (!s)
             return false;
 
         JSAutoByteString bytes;
         char *policy = bytes.encodeUtf8(cx, s);
         if (!policy)
             return false;
         if (strcmp(policy, "NO_SOURCE") == 0) {
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -950,19 +950,19 @@ JS_GetArrayBufferData(JSObject *obj)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     return AsArrayBuffer(obj).dataPointer();
 }
 
 JS_FRIEND_API(uint8_t *)
-JS_GetStableArrayBufferData(JSContext *cx, JSObject *obj)
+JS_GetStableArrayBufferData(JSContext *cx, HandleObject objArg)
 {
-    obj = CheckedUnwrap(obj);
+    JSObject *obj = CheckedUnwrap(objArg);
     if (!obj)
         return nullptr;
 
     Rooted<ArrayBufferObject*> buffer(cx, &AsArrayBuffer(obj));
     if (!ArrayBufferObject::ensureNonInline(cx, buffer))
         return nullptr;
 
     return buffer->dataPointer();
--- a/js/src/vm/OldDebugAPI.cpp
+++ b/js/src/vm/OldDebugAPI.cpp
@@ -206,19 +206,18 @@ CheckDebugMode(JSContext *cx)
     if (!debugMode) {
         JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage,
                                      nullptr, JSMSG_NEED_DEBUG_MODE);
     }
     return debugMode;
 }
 
 JS_PUBLIC_API(bool)
-JS_SetSingleStepMode(JSContext *cx, JSScript *scriptArg, bool singleStep)
+JS_SetSingleStepMode(JSContext *cx, HandleScript script, bool singleStep)
 {
-    RootedScript script(cx, scriptArg);
     assertSameCompartment(cx, script);
 
     if (!CheckDebugMode(cx))
         return false;
 
     return script->setStepModeFlag(cx, singleStep);
 }
 
@@ -814,36 +813,35 @@ JS_PUBLIC_API(const JSDebugHooks *)
 JS_GetGlobalDebugHooks(JSRuntime *rt)
 {
     return &rt->debugHooks;
 }
 
 /************************************************************************/
 
 extern JS_PUBLIC_API(void)
-JS_DumpPCCounts(JSContext *cx, JSScript *scriptArg)
+JS_DumpPCCounts(JSContext *cx, HandleScript script)
 {
-    Rooted<JSScript*> script(cx, scriptArg);
     JS_ASSERT(script->hasScriptCounts());
 
     Sprinter sprinter(cx);
     if (!sprinter.init())
         return;
 
     fprintf(stdout, "--- SCRIPT %s:%d ---\n", script->filename(), (int) script->lineno());
     js_DumpPCCounts(cx, script, &sprinter);
     fputs(sprinter.string(), stdout);
     fprintf(stdout, "--- END SCRIPT %s:%d ---\n", script->filename(), (int) script->lineno());
 }
 
 JS_PUBLIC_API(void)
 JS_DumpCompartmentPCCounts(JSContext *cx)
 {
     for (CellIter i(cx->zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
-        JSScript *script = i.get<JSScript>();
+        RootedScript script(cx, i.get<JSScript>());
         if (script->compartment() != cx->compartment())
             continue;
 
         if (script->hasScriptCounts())
             JS_DumpPCCounts(cx, script);
     }
 
 #if defined(JS_ION)
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -295,17 +295,17 @@ struct JSStructuredCloneWriter {
 
     // Any value passed to JS_WriteStructuredClone.
     void *closure;
 
     // List of transferable objects
     JS::RootedValue transferable;
     JS::AutoObjectVector transferableObjects;
 
-    friend bool JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::Value v);
+    friend bool JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::HandleValue v);
 };
 
 JS_FRIEND_API(uint64_t)
 js_GetSCOffset(JSStructuredCloneWriter* writer)
 {
     JS_ASSERT(writer);
     return writer->output().count() * sizeof(uint64_t);
 }
@@ -1835,25 +1835,24 @@ JS_WriteUint32Pair(JSStructuredCloneWrit
 
 JS_PUBLIC_API(bool)
 JS_WriteBytes(JSStructuredCloneWriter *w, const void *p, size_t len)
 {
     return w->output().writeBytes(p, len);
 }
 
 JS_PUBLIC_API(bool)
-JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::Value v)
+JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::HandleValue v)
 {
     JS_ASSERT(v.isObject());
     assertSameCompartment(w->context(), v);
     RootedObject obj(w->context(), &v.toObject());
 
     // If the object is a security wrapper, see if we're allowed to unwrap it.
     // If we aren't, throw.
     if (obj->is<WrapperObject>())
         obj = CheckedUnwrap(obj);
     if (!obj) {
         JS_ReportError(w->context(), "Permission denied to access object");
         return false;
     }
     return w->writeTypedArray(obj);
 }
-
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -172,17 +172,17 @@ SandboxImport(JSContext *cx, unsigned ar
         funname = JS_GetFunctionId(fun);
         if (!funname) {
             XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
             return false;
         }
     }
 
     RootedId id(cx);
-    if (!JS_ValueToId(cx, StringValue(funname), &id))
+    if (!JS_StringToId(cx, funname, &id))
         return false;
 
     // We need to resolve the this object, because this function is used
     // unbound and should still work and act on the original sandbox.
     RootedObject thisObject(cx, JS_THIS_OBJECT(cx, vp));
     if (!thisObject) {
         XPCThrower::Throw(NS_ERROR_UNEXPECTED, cx);
         return false;
@@ -294,19 +294,17 @@ ExportFunction(JSContext *cx, HandleValu
         if (JSID_IS_VOID(id)) {
             // If there wasn't any function name specified,
             // copy the name from the function being imported.
             JSFunction *fun = JS_GetObjectFunction(funObj);
             RootedString funName(cx, JS_GetFunctionId(fun));
             if (!funName)
                 funName = JS_InternString(cx, "");
 
-            RootedValue vname(cx);
-            vname.setString(funName);
-            if (!JS_ValueToId(cx, vname, &id))
+            if (!JS_StringToId(cx, funName, &id))
                 return false;
         }
         MOZ_ASSERT(JSID_IS_STRING(id));
 
         // The function forwarder will live in the target compartment. Since
         // this function will be referenced from its private slot, to avoid a
         // GC hazard, we must wrap it to the same compartment.
         if (!JS_WrapObject(cx, &funObj))
@@ -1836,17 +1834,18 @@ xpc::NewFunctionForwarder(JSContext *cx,
     return true;
 }
 
 bool
 xpc::NewFunctionForwarder(JSContext *cx, HandleObject callable, bool doclone,
                           MutableHandleValue vp)
 {
     RootedId emptyId(cx);
-    if (!JS_ValueToId(cx, JS_GetEmptyStringValue(cx), &emptyId))
+    RootedValue emptyStringValue(cx, JS_GetEmptyStringValue(cx));
+    if (!JS_ValueToId(cx, emptyStringValue, &emptyId))
         return false;
 
     return NewFunctionForwarder(cx, emptyId, callable, doclone, vp);
 }
 
 
 nsresult
 xpc::GetSandboxMetadata(JSContext *cx, HandleObject sandbox, MutableHandleValue rval)
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -260,25 +260,25 @@ nsXPCComponents_Interfaces::NewEnumerate
         }
         case JSENUMERATE_NEXT:
         {
             uint32_t idx = JSVAL_TO_INT(*statep);
             nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(idx);
             *statep = UINT_TO_JSVAL(idx + 1);
 
             if (interface) {
-                JSString* idstr;
                 const char* name;
 
-                JS::Rooted<jsid> id(cx);
-                if (NS_SUCCEEDED(interface->GetNameShared(&name)) && name &&
-                        nullptr != (idstr = JS_NewStringCopyZ(cx, name)) &&
-                        JS_ValueToId(cx, StringValue(idstr), &id)) {
-                    *idp = id;
-                    return NS_OK;
+                RootedId id(cx);
+                if (NS_SUCCEEDED(interface->GetNameShared(&name)) && name) {
+                    RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
+                    if (idstr && JS_StringToId(cx, idstr, &id)) {
+                        *idp = id;
+                        return NS_OK;
+                    }
                 }
             }
             // fall through
         }
 
         case JSENUMERATE_DESTROY:
         default:
             *statep = JSVAL_NULL;
@@ -509,23 +509,22 @@ nsXPCComponents_InterfacesByID::NewEnume
         case JSENUMERATE_NEXT:
         {
             uint32_t idx = JSVAL_TO_INT(*statep);
             nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(idx);
             *statep = UINT_TO_JSVAL(idx + 1);
             if (interface) {
                 nsIID const *iid;
                 char idstr[NSID_LENGTH];
-                JSString* jsstr;
 
                 if (NS_SUCCEEDED(interface->GetIIDShared(&iid))) {
                     iid->ToProvidedString(idstr);
-                    jsstr = JS_NewStringCopyZ(cx, idstr);
-                    JS::Rooted<jsid> id(cx);
-                    if (jsstr && JS_ValueToId(cx, StringValue(jsstr), &id)) {
+                    RootedString jsstr(cx, JS_NewStringCopyZ(cx, idstr));
+                    RootedId id(cx);
+                    if (jsstr && JS_StringToId(cx, jsstr, &id)) {
                         *idp = id;
                         return NS_OK;
                     }
                 }
             }
             // FALL THROUGH
         }
 
@@ -769,20 +768,19 @@ nsXPCComponents_Classes::NewEnumerate(ns
             e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep);
 
             if (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
                 NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
                 nsCOMPtr<nsISupportsCString> holder(do_QueryInterface(isup));
                 if (holder) {
                     nsAutoCString name;
                     if (NS_SUCCEEDED(holder->GetData(name))) {
-                        JSString* idstr = JS_NewStringCopyN(cx, name.get(), name.Length());
-                        JS::Rooted<jsid> id(cx);
-                        if (idstr &&
-                            JS_ValueToId(cx, StringValue(idstr), &id)) {
+                        RootedString idstr(cx, JS_NewStringCopyN(cx, name.get(), name.Length()));
+                        RootedId id(cx);
+                        if (idstr && JS_StringToId(cx, idstr, &id)) {
                             *idp = id;
                             return NS_OK;
                         }
                     }
                 }
             }
             // else... FALL THROUGH
         }
@@ -1010,21 +1008,20 @@ nsXPCComponents_ClassesByID::NewEnumerat
             e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep);
 
             if (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
                 NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
                 nsCOMPtr<nsISupportsID> holder(do_QueryInterface(isup));
                 if (holder) {
                     char* name;
                     if (NS_SUCCEEDED(holder->ToString(&name)) && name) {
-                        JSString* idstr = JS_NewStringCopyZ(cx, name);
+                        RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
                         nsMemory::Free(name);
-                        JS::Rooted<jsid> id(cx);
-                        if (idstr &&
-                            JS_ValueToId(cx, StringValue(idstr), &id)) {
+                        RootedId id(cx);
+                        if (idstr && JS_StringToId(cx, idstr, &id)) {
                             *idp = id;
                             return NS_OK;
                         }
                     }
                 }
             }
             // else... FALL THROUGH
         }
@@ -1265,19 +1262,19 @@ nsXPCComponents_Results::NewEnumerate(ns
             *statep = PRIVATE_TO_JSVAL(space);
             return NS_OK;
         }
         case JSENUMERATE_NEXT:
         {
             const char* name;
             iter = (const void**) JSVAL_TO_PRIVATE(*statep);
             if (nsXPCException::IterateNSResults(nullptr, &name, nullptr, iter)) {
-                JSString* idstr = JS_NewStringCopyZ(cx, name);
-                JS::Rooted<jsid> id(cx);
-                if (idstr && JS_ValueToId(cx, StringValue(idstr), &id)) {
+                RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
+                JS::RootedId id(cx);
+                if (idstr && JS_StringToId(cx, idstr, &id)) {
                     *idp = id;
                     return NS_OK;
                 }
             }
             // else... FALL THROUGH
         }
 
         case JSENUMERATE_DESTROY:
@@ -2412,17 +2409,17 @@ nsXPCComponents_Constructor::CallOrConst
                                       getter_AddRefs(holder))) || !holder ||
             // Assign, not compare
             !(ifacesObj = holder->GetJSObject())) {
             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
         }
 
         RootedString str(cx, ToString(cx, args[1]));
         RootedId id(cx);
-        if (!str || !JS_ValueToId(cx, StringValue(str), &id))
+        if (!str || !JS_StringToId(cx, str, &id))
             return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
 
         RootedValue val(cx);
         if (!JS_GetPropertyById(cx, ifacesObj, id, &val) || val.isPrimitive())
             return ThrowAndFail(NS_ERROR_XPC_BAD_IID, cx, _retval);
 
         nsCOMPtr<nsIXPConnectWrappedNative> wn;
         if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, &val.toObject(),
@@ -2460,17 +2457,17 @@ nsXPCComponents_Constructor::CallOrConst
                                       getter_AddRefs(holder))) || !holder ||
             // Assign, not compare
             !(classesObj = holder->GetJSObject())) {
             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
         }
 
         RootedString str(cx, ToString(cx, args[0]));
         RootedId id(cx);
-        if (!str || !JS_ValueToId(cx, StringValue(str), &id))
+        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),
--- a/js/xpconnect/src/XPCMaps.h
+++ b/js/xpconnect/src/XPCMaps.h
@@ -667,22 +667,23 @@ public:
 
     void Reparent(JSContext *aCx, JSObject *aNewInnerArg) {
         JS::RootedObject aNewInner(aCx, aNewInnerArg);
         for (Map::Enum e(mTable); !e.empty(); e.popFront()) {
             /*
              * We reparent wrappers that have as their parent an inner window
              * whose outer has the new inner window as its current inner.
              */
-            JS::RootedObject parent(aCx, JS_GetParent(e.front().value()));
+            JS::RootedObject wrapper(aCx, e.front().value());
+            JS::RootedObject parent(aCx, JS_GetParent(wrapper));
             JS::RootedObject outer(aCx, JS_ObjectToOuterObject(aCx, parent));
             if (outer) {
                 JSObject *inner = JS_ObjectToInnerObject(aCx, outer);
                 if (inner == aNewInner && inner != parent)
-                    JS_SetParent(aCx, e.front().value(), aNewInner);
+                    JS_SetParent(aCx, wrapper, aNewInner);
             } else {
                 JS_ClearPendingException(aCx);
             }
         }
     }
 
 private:
     JSObject2JSObjectMap() {}
--- a/js/xpconnect/src/XPCQuickStubs.h
+++ b/js/xpconnect/src/XPCQuickStubs.h
@@ -596,17 +596,17 @@ PropertyOpForwarder(JSContext *cx, unsig
 
     JS::CallArgs args = CallArgsFromVp(argc, vp);
 
     JS::RootedObject callee(cx, &args.callee());
     JS::RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));
     if (!obj)
         return false;
 
-    jsval v = js::GetFunctionNativeReserved(callee, 0);
+    JS::RootedValue v(cx, js::GetFunctionNativeReserved(callee, 0));
 
     JSObject *ptrobj = JSVAL_TO_OBJECT(v);
     Op *popp = static_cast<Op *>(JS_GetPrivate(ptrobj));
 
     v = js::GetFunctionNativeReserved(callee, 1);
 
     JS::RootedValue argval(cx, args.get(0));
     JS::RootedId id(cx);
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -1155,19 +1155,18 @@ XPCWrappedNative::ReparentWrapperIfFound
         }
 
         // First, the clone of the reflector, get a copy of its
         // properties and clone its expando chain. The only part that is
         // dangerous here if we have to return early is that we must avoid
         // ending up with two reflectors pointing to the same WN. Other than
         // that, the objects we create will just go away if we return early.
 
-        RootedObject newobj(cx, JS_CloneObject(cx, flat,
-                                               newProto->GetJSProtoObject(),
-                                               aNewParent));
+        RootedObject proto(cx, newProto->GetJSProtoObject());
+        RootedObject newobj(cx, JS_CloneObject(cx, flat, proto, aNewParent));
         if (!newobj)
             return NS_ERROR_FAILURE;
 
         // At this point, both |flat| and |newobj| point to the same wrapped
         // native, which is bad, because one of them will end up finalizing
         // a wrapped native it does not own. |cloneGuard| ensures that if we
         // exit before calling clearing |flat|'s private the private of
         // |newobj| will be set to nullptr. |flat| will go away soon, because
--- a/storage/src/mozStorageStatementParams.cpp
+++ b/storage/src/mozStorageStatementParams.cpp
@@ -118,23 +118,23 @@ StatementParams::NewEnumerate(nsIXPConne
       }
 
       // Get the name of our parameter.
       nsAutoCString name;
       nsresult rv = mStatement->GetParameterName(index, name);
       NS_ENSURE_SUCCESS(rv, rv);
 
       // But drop the first character, which is going to be a ':'.
-      JSString *jsname = ::JS_NewStringCopyN(aCtx, &(name.get()[1]),
-                                             name.Length() - 1);
+      JS::RootedString jsname(aCtx, ::JS_NewStringCopyN(aCtx, &(name.get()[1]),
+                                                        name.Length() - 1));
       NS_ENSURE_TRUE(jsname, NS_ERROR_OUT_OF_MEMORY);
 
       // Set our name.
       JS::Rooted<jsid> id(aCtx);
-      if (!::JS_ValueToId(aCtx, JS::StringValue(jsname), &id)) {
+      if (!::JS_StringToId(aCtx, jsname, &id)) {
         *_retval = false;
         return NS_OK;
       }
       *_idp = id;
 
       // And increment our index.
       *_statep = INT_TO_JSVAL(++index);
 
--- a/xpcom/io/nsBinaryStream.cpp
+++ b/xpcom/io/nsBinaryStream.cpp
@@ -747,17 +747,17 @@ nsBinaryInputStream::ReadArrayBuffer(uin
     if (!aBuffer.isObject()) {
         return NS_ERROR_FAILURE;
     }
     JS::RootedObject buffer(cx, &aBuffer.toObject());
     if (!JS_IsArrayBufferObject(buffer) ||
         JS_GetArrayBufferByteLength(buffer) < aLength) {
         return NS_ERROR_FAILURE;
     }
-    uint8_t* data = JS_GetStableArrayBufferData(cx, &aBuffer.toObject());
+    uint8_t* data = JS_GetStableArrayBufferData(cx, buffer);
     if (!data) {
         return NS_ERROR_FAILURE;
     }
 
     uint32_t bytesRead;
     nsresult rv = Read(reinterpret_cast<char*>(data), aLength, &bytesRead);
     if (NS_WARN_IF(NS_FAILED(rv)))
         return rv;