Backout changesets ded0d64f6786:03f041d03f24 and 30cbd1abde1a (bug 935696, bug 933834 and bug 939194) for build bustage.
authorMs2ger <ms2ger@gmail.com>
Sun, 17 Nov 2013 16:39:25 +0100
changeset 155037 1bc46d4abd0de021392599a926a6a59e78e7f4f5
parent 155032 03f041d03f24bad434e3c68656eb9119bbbe5994
child 155038 fa66c9f42ff46ce077e15aeefb71ee1a06c06d97
push id25662
push useremorley@mozilla.com
push dateMon, 18 Nov 2013 10:53:03 +0000
treeherdermozilla-central@59f6274ce8f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs935696, 933834, 939194
milestone28.0a1
backs outded0d64f6786994791e8ffd7d8c1b3557e14af68
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backout changesets ded0d64f6786:03f041d03f24 and 30cbd1abde1a (bug 935696, bug 933834 and bug 939194) for build bustage.
caps/src/nsScriptSecurityManager.cpp
content/base/public/Element.h
content/base/public/nsINode.h
content/base/public/nsIXMLHttpRequest.idl
content/base/src/nsDOMBlobBuilder.cpp
content/base/src/nsINode.cpp
content/base/src/nsXMLHttpRequest.cpp
content/html/content/src/HTMLBodyElement.cpp
content/html/content/src/HTMLBodyElement.h
content/html/content/src/HTMLFrameSetElement.cpp
content/html/content/src/HTMLFrameSetElement.h
content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
dom/audiochannel/AudioChannelService.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSTimeoutHandler.cpp
dom/base/nsJSUtils.cpp
dom/base/nsScreen.cpp
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/file/LockedFile.cpp
dom/indexedDB/KeyPath.cpp
dom/interfaces/base/nsIDOMScreen.idl
dom/interfaces/core/nsIDOMElement.idl
dom/interfaces/html/nsIDOMHTMLBodyElement.idl
dom/interfaces/html/nsIDOMHTMLFrameSetElement.idl
dom/media/MediaManager.cpp
dom/src/jsurl/nsJSProtocolHandler.cpp
dom/system/gonk/AutoMounterSetting.cpp
dom/workers/XMLHttpRequest.cpp
ipc/testshell/XPCShellEnvironment.cpp
js/ipc/JavaScriptShared.cpp
js/jsd/jsd_stak.cpp
js/jsd/jsd_val.cpp
js/src/builtin/TestingFunctions.cpp
js/src/builtin/TypeRepresentation.cpp
js/src/ctypes/CTypes.cpp
js/src/jsapi-tests/testOOM.cpp
js/src/jsapi-tests/tests.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsstr.cpp
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCDebug.cpp
js/xpconnect/src/XPCQuickStubs.cpp
js/xpconnect/src/XPCQuickStubs.h
js/xpconnect/src/XPCShellImpl.cpp
js/xpconnect/src/XPCString.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/qsgen.py
js/xpconnect/src/xpcpublic.h
security/manager/ssl/src/nsCrypto.cpp
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -107,20 +107,20 @@ nsScriptSecurityManager::SubjectIsPrivil
 // Result of this function should not be freed.
 static inline const PRUnichar *
 IDToString(JSContext *cx, jsid id_)
 {
     JS::RootedId id(cx, id_);
     if (JSID_IS_STRING(id))
         return JS_GetInternedStringChars(JSID_TO_STRING(id));
 
-    JS::Rooted<JS::Value> idval(cx);
-    if (!JS_IdToValue(cx, id, idval.address()))
+    JS::Value idval;
+    if (!JS_IdToValue(cx, id, &idval))
         return nullptr;
-    JSString *str = JS::ToString(cx, idval);
+    JSString *str = JS_ValueToString(cx, idval);
     if(!str)
         return nullptr;
     return JS_GetStringCharsZ(cx, str);
 }
 
 class nsAutoInPrincipalDomainOriginSetter {
 public:
     nsAutoInPrincipalDomainOriginSetter() {
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -1466,16 +1466,38 @@ NS_IMETHOD GetChildElementCount(uint32_t
   *aChildElementCount = Element::ChildElementCount();                         \
   return NS_OK;                                                               \
 }                                                                             \
 NS_IMETHOD MozRemove() MOZ_FINAL                                              \
 {                                                                             \
   nsINode::Remove();                                                          \
   return NS_OK;                                                               \
 }                                                                             \
+using nsINode::GetOnmouseenter;                                               \
+using nsINode::SetOnmouseenter;                                               \
+NS_IMETHOD GetOnmouseenter(JSContext* cx, JS::Value* aOnmouseenter) MOZ_FINAL \
+{                                                                             \
+  return Element::GetOnmouseenter(cx, aOnmouseenter);                         \
+}                                                                             \
+NS_IMETHOD SetOnmouseenter(JSContext* cx,                                     \
+                           const JS::Value& aOnmouseenter) MOZ_FINAL          \
+{                                                                             \
+  return Element::SetOnmouseenter(cx, aOnmouseenter);                         \
+}                                                                             \
+using nsINode::GetOnmouseleave;                                               \
+using nsINode::SetOnmouseleave;                                               \
+NS_IMETHOD GetOnmouseleave(JSContext* cx, JS::Value* aOnmouseleave) MOZ_FINAL \
+{                                                                             \
+  return Element::GetOnmouseleave(cx, aOnmouseleave);                         \
+}                                                                             \
+NS_IMETHOD SetOnmouseleave(JSContext* cx,                                     \
+                           const JS::Value& aOnmouseleave) MOZ_FINAL          \
+{                                                                             \
+  return Element::SetOnmouseleave(cx, aOnmouseleave);                         \
+}                                                                             \
 NS_IMETHOD GetClientRects(nsIDOMClientRectList** _retval) MOZ_FINAL           \
 {                                                                             \
   *_retval = Element::GetClientRects().get();                                 \
   return NS_OK;                                                               \
 }                                                                             \
 NS_IMETHOD GetBoundingClientRect(nsIDOMClientRect** _retval) MOZ_FINAL        \
 {                                                                             \
   *_retval = Element::GetBoundingClientRect().get();                          \
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -1704,17 +1704,19 @@ public:
      this exact name and signature and then the calling convention
      needs to match.
 
      Note that we include DOCUMENT_ONLY_EVENT events here so that we
      can forward all the document stuff to this implementation.
   */
 #define EVENT(name_, id_, type_, struct_)                             \
   mozilla::dom::EventHandlerNonNull* GetOn##name_();                  \
-  void SetOn##name_(mozilla::dom::EventHandlerNonNull* listener);
+  void SetOn##name_(mozilla::dom::EventHandlerNonNull* listener);     \
+  NS_IMETHOD GetOn##name_(JSContext *cx, JS::Value *vp);              \
+  NS_IMETHOD SetOn##name_(JSContext *cx, const JS::Value &v);
 #define TOUCH_EVENT EVENT
 #define DOCUMENT_ONLY_EVENT EVENT
 #include "nsEventNameList.h"
 #undef DOCUMENT_ONLY_EVENT
 #undef TOUCH_EVENT
 #undef EVENT
 
 protected:
--- a/content/base/public/nsIXMLHttpRequest.idl
+++ b/content/base/public/nsIXMLHttpRequest.idl
@@ -14,16 +14,23 @@ interface nsIURI;
 interface nsIVariant;
 interface nsIGlobalObject;
 interface nsIInputStream;
 interface nsIDOMBlob;
 
 [scriptable, builtinclass, uuid(ac97e161-9f1d-4163-adc9-e9a59e18682c)]
 interface nsIXMLHttpRequestEventTarget : nsIDOMEventTarget {
   // event handler attributes
+  [implicit_jscontext] attribute jsval onabort;
+  [implicit_jscontext] attribute jsval onerror;
+  [implicit_jscontext] attribute jsval onload;
+  [implicit_jscontext] attribute jsval onloadstart;
+  [implicit_jscontext] attribute jsval onprogress;
+  [implicit_jscontext] attribute jsval ontimeout;
+  [implicit_jscontext] attribute jsval onloadend;
 };
 
 [scriptable, builtinclass, uuid(df3796fa-d98a-4185-9dda-d2f2b56a5d38)]
 interface nsIXMLHttpRequestUpload : nsIXMLHttpRequestEventTarget {
   // for future use
 };
 
 /**
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -263,17 +263,17 @@ nsDOMMultipartFile::ParseBlobArrayArgume
       }
       if (JS_IsArrayBufferObject(obj)) {
         blobSet.AppendArrayBuffer(obj);
         continue;
       }
     }
 
     // coerce it to a string
-    JSString* str = JS::ToString(aCx, element);
+    JSString* str = JS_ValueToString(aCx, element);
     NS_ENSURE_TRUE(str, NS_ERROR_TYPE_ERR);
     blobSet.AppendString(str, aNativeEOL, aCx);
   }
 
   mBlobs = blobSet.GetBlobs();
   return NS_OK;
 }
 
@@ -337,17 +337,17 @@ nsDOMMultipartFile::InitChromeFile(JSCon
     file = do_QueryInterface(supports);
     if (!blob && !file) {
       return NS_ERROR_UNEXPECTED;
     }
 
     mIsFromNsiFile = true;
   } else {
     // It's a string
-    JSString* str = JS::ToString(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[0]));
+    JSString* str = JS_ValueToString(aCx, aArgv[0]);
     NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
 
     nsDependentJSString xpcomStr;
     if (!xpcomStr.init(aCx, str)) {
       return NS_ERROR_XPC_BAD_CONVERT_JS;
     }
 
     rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(file));
@@ -392,17 +392,17 @@ nsDOMMultipartFile::InitFile(JSContext* 
   NS_ASSERTION(!mImmutable, "Something went wrong ...");
   NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
 
   if (aArgc < 2) {
     return NS_ERROR_TYPE_ERR;
   }
 
   // File name
-  JSString* str = JS::ToString(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[1]));
+  JSString* str = JS_ValueToString(aCx, aArgv[1]);
   NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
 
   nsDependentJSString xpcomStr;
   if (!xpcomStr.init(aCx, str)) {
     return NS_ERROR_XPC_BAD_CONVERT_JS;
   }
 
   mName = xpcomStr;
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -2193,16 +2193,31 @@ nsINode::SizeOfExcludingThis(MallocSizeO
                : nullptr;                                                    \
   }                                                                          \
   void nsINode::SetOn##name_(EventHandlerNonNull* handler)                   \
   {                                                                          \
     nsEventListenerManager *elm = GetOrCreateListenerManager();              \
     if (elm) {                                                               \
       elm->SetEventHandler(nsGkAtoms::on##name_, EmptyString(), handler);    \
     }                                                                        \
+  }                                                                          \
+  NS_IMETHODIMP nsINode::GetOn##name_(JSContext *cx, JS::Value *vp) {        \
+    EventHandlerNonNull* h = GetOn##name_();                                 \
+    vp->setObjectOrNull(h ? h->Callable().get() : nullptr);                  \
+    return NS_OK;                                                            \
+  }                                                                          \
+  NS_IMETHODIMP nsINode::SetOn##name_(JSContext *cx, const JS::Value &v) {   \
+    nsRefPtr<EventHandlerNonNull> handler;                                   \
+    JSObject *callable;                                                      \
+    if (v.isObject() &&                                                      \
+        JS_ObjectIsCallable(cx, callable = &v.toObject())) {                 \
+      handler = new EventHandlerNonNull(callable);                           \
+    }                                                                        \
+    SetOn##name_(handler);                                                   \
+    return NS_OK;                                                            \
   }
 #define TOUCH_EVENT EVENT
 #define DOCUMENT_ONLY_EVENT EVENT
 #include "nsEventNameList.h"
 #undef DOCUMENT_ONLY_EVENT
 #undef TOUCH_EVENT
 #undef EVENT
 
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -242,16 +242,24 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXHREventTarget)
   NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestEventTarget)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(nsXHREventTarget, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsXHREventTarget, nsDOMEventTargetHelper)
 
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, loadstart)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, progress)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, abort)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, error)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, load)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, timeout)
+NS_IMPL_EVENT_HANDLER(nsXHREventTarget, loadend)
+
 void
 nsXHREventTarget::DisconnectFromOwner()
 {
   nsDOMEventTargetHelper::DisconnectFromOwner();
 }
 
 /////////////////////////////////////////////
 
--- a/content/html/content/src/HTMLBodyElement.cpp
+++ b/content/html/content/src/HTMLBodyElement.cpp
@@ -480,16 +480,42 @@ HTMLBodyElement::IsEventAttributeName(ns
                                               EventNameType_HTML |
                                               EventNameType_HTMLBodyOrFramesetOnly);
 }
 
 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the superclass */
 // nsGenericHTMLElement::GetOnError returns
 // already_AddRefed<EventHandlerNonNull> while other getters return
 // EventHandlerNonNull*, so allow passing in the type to use here.
+#define FORWARDED_EVENT_HELPER(name_, forwardto_, type_, getter_type_)         \
+  NS_IMETHODIMP                                                                \
+  HTMLBodyElement::GetOn##name_(JSContext *cx, JS::Value *vp)                  \
+  {                                                                            \
+    getter_type_ h = forwardto_::GetOn##name_();                               \
+    vp->setObjectOrNull(h ? h->Callable().get() : nullptr);                    \
+    return NS_OK;                                                              \
+  }                                                                            \
+  NS_IMETHODIMP                                                                \
+  HTMLBodyElement::SetOn##name_(JSContext *cx, const JS::Value &v)             \
+  {                                                                            \
+    nsRefPtr<type_> handler;                                                   \
+    JSObject *callable;                                                        \
+    if (v.isObject() &&                                                        \
+        JS_ObjectIsCallable(cx, callable = &v.toObject())) {                   \
+      handler = new type_(callable);                                           \
+    }                                                                          \
+    forwardto_::SetOn##name_(handler);                                         \
+    return NS_OK;                                                              \
+  }
+#define FORWARDED_EVENT(name_, id_, type_, struct_)                            \
+  FORWARDED_EVENT_HELPER(name_, nsGenericHTMLElement, EventHandlerNonNull,     \
+                         EventHandlerNonNull*)
+#define ERROR_EVENT(name_, id_, type_, struct_)                                \
+  FORWARDED_EVENT_HELPER(name_, nsGenericHTMLElement,                          \
+                         EventHandlerNonNull, nsCOMPtr<EventHandlerNonNull>)
 #define WINDOW_EVENT_HELPER(name_, type_)                                      \
   type_*                                                                       \
   HTMLBodyElement::GetOn##name_()                                              \
   {                                                                            \
     nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();                         \
     if (win) {                                                                 \
       nsCOMPtr<nsISupports> supports = do_QueryInterface(win);                 \
       nsGlobalWindow* globalWin = nsGlobalWindow::FromSupports(supports);      \
@@ -503,21 +529,25 @@ HTMLBodyElement::IsEventAttributeName(ns
     nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();                         \
     if (!win) {                                                                \
       return;                                                                  \
     }                                                                          \
                                                                                \
     nsCOMPtr<nsISupports> supports = do_QueryInterface(win);                   \
     nsGlobalWindow* globalWin = nsGlobalWindow::FromSupports(supports);        \
     return globalWin->SetOn##name_(handler);                                   \
-  }
+  }                                                                            \
+  FORWARDED_EVENT_HELPER(name_, HTMLBodyElement, type_, type_*)
 #define WINDOW_EVENT(name_, id_, type_, struct_)                               \
   WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                         \
   WINDOW_EVENT_HELPER(name_, OnBeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h" // IWYU pragma: keep
 #undef BEFOREUNLOAD_EVENT
 #undef WINDOW_EVENT
 #undef WINDOW_EVENT_HELPER
+#undef ERROR_EVENT
+#undef FORWARDED_EVENT
+#undef FORWARDED_EVENT_HELPER
 #undef EVENT
 
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLBodyElement.h
+++ b/content/html/content/src/HTMLBodyElement.h
@@ -50,27 +50,31 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMHTMLBodyElement
   NS_DECL_NSIDOMHTMLBODYELEMENT
 
   // Event listener stuff; we need to declare only the ones we need to
   // forward to window that don't come from nsIDOMHTMLBodyElement.
 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the shim */
+#define FORWARDED_EVENT(name_, id_, type_, struct_)                     \
+  NS_IMETHOD GetOn##name_(JSContext *cx, JS::Value *vp);                \
+  NS_IMETHOD SetOn##name_(JSContext *cx, const JS::Value &v);
 #define WINDOW_EVENT_HELPER(name_, type_)                               \
   type_* GetOn##name_();                                                \
   void SetOn##name_(type_* handler);
 #define WINDOW_EVENT(name_, id_, type_, struct_)                        \
   WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                  \
   WINDOW_EVENT_HELPER(name_, OnBeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h" // IWYU pragma: keep
 #undef BEFOREUNLOAD_EVENT
 #undef WINDOW_EVENT
 #undef WINDOW_EVENT_HELPER
+#undef FORWARDED_EVENT
 #undef EVENT
 
   void GetText(nsString& aText)
   {
     GetHTMLAttr(nsGkAtoms::text, aText);
   }
   void SetText(const nsAString& aText, ErrorResult& aError)
   {
--- a/content/html/content/src/HTMLFrameSetElement.cpp
+++ b/content/html/content/src/HTMLFrameSetElement.cpp
@@ -340,16 +340,42 @@ HTMLFrameSetElement::IsEventAttributeNam
                                               EventNameType_HTMLBodyOrFramesetOnly);
 }
 
 
 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the shim */
 // nsGenericHTMLElement::GetOnError returns
 // already_AddRefed<EventHandlerNonNull> while other getters return
 // EventHandlerNonNull*, so allow passing in the type to use here.
+#define FORWARDED_EVENT_HELPER(name_, forwardto_, type_, getter_type_)         \
+  NS_IMETHODIMP                                                                \
+  HTMLFrameSetElement::GetOn##name_(JSContext *cx, JS::Value *vp)              \
+  {                                                                            \
+    getter_type_ h = forwardto_::GetOn##name_();                               \
+    vp->setObjectOrNull(h ? h->Callable().get() : nullptr);                    \
+    return NS_OK;                                                              \
+  }                                                                            \
+  NS_IMETHODIMP                                                                \
+  HTMLFrameSetElement::SetOn##name_(JSContext *cx, const JS::Value &v)         \
+  {                                                                            \
+    nsRefPtr<type_> handler;                                                   \
+    JSObject *callable;                                                        \
+    if (v.isObject() &&                                                        \
+        JS_ObjectIsCallable(cx, callable = &v.toObject())) {                   \
+      handler = new type_(callable);                                           \
+    }                                                                          \
+    forwardto_::SetOn##name_(handler);                                         \
+    return NS_OK;                                                              \
+  }
+#define FORWARDED_EVENT(name_, id_, type_, struct_)                            \
+  FORWARDED_EVENT_HELPER(name_, nsGenericHTMLElement, EventHandlerNonNull,     \
+                         EventHandlerNonNull*)
+#define ERROR_EVENT(name_, id_, type_, struct_)                                \
+  FORWARDED_EVENT_HELPER(name_, nsGenericHTMLElement,                          \
+                         EventHandlerNonNull, nsCOMPtr<EventHandlerNonNull>)
 #define WINDOW_EVENT_HELPER(name_, type_)                                      \
   type_*                                                                       \
   HTMLFrameSetElement::GetOn##name_()                                          \
   {                                                                            \
     nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();                         \
     if (win) {                                                                 \
       nsCOMPtr<nsISupports> supports = do_QueryInterface(win);                 \
       nsGlobalWindow* globalWin = nsGlobalWindow::FromSupports(supports);      \
@@ -363,21 +389,25 @@ HTMLFrameSetElement::IsEventAttributeNam
     nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();                         \
     if (!win) {                                                                \
       return;                                                                  \
     }                                                                          \
                                                                                \
     nsCOMPtr<nsISupports> supports = do_QueryInterface(win);                   \
     nsGlobalWindow* globalWin = nsGlobalWindow::FromSupports(supports);        \
     return globalWin->SetOn##name_(handler);                                   \
-  }
+  }                                                                            \
+  FORWARDED_EVENT_HELPER(name_, HTMLFrameSetElement, type_, type_*)
 #define WINDOW_EVENT(name_, id_, type_, struct_)                               \
   WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                         \
   WINDOW_EVENT_HELPER(name_, OnBeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h" // IWYU pragma: keep
 #undef BEFOREUNLOAD_EVENT
 #undef WINDOW_EVENT
 #undef WINDOW_EVENT_HELPER
+#undef ERROR_EVENT
+#undef FORWARDED_EVENT
+#undef FORWARDED_EVENT_HELPER
 #undef EVENT
 
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLFrameSetElement.h
+++ b/content/html/content/src/HTMLFrameSetElement.h
@@ -80,27 +80,31 @@ public:
     SetHTMLAttr(nsGkAtoms::rows, aRows, aError);
   }
 
   virtual bool IsEventAttributeName(nsIAtom *aName) MOZ_OVERRIDE;
 
   // Event listener stuff; we need to declare only the ones we need to
   // forward to window that don't come from nsIDOMHTMLFrameSetElement.
 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the superclass */
+#define FORWARDED_EVENT(name_, id_, type_, struct_)                     \
+  NS_IMETHOD GetOn##name_(JSContext *cx, JS::Value *vp);                \
+  NS_IMETHOD SetOn##name_(JSContext *cx, const JS::Value &v);
 #define WINDOW_EVENT_HELPER(name_, type_)                               \
   type_* GetOn##name_();                                                \
   void SetOn##name_(type_* handler);
 #define WINDOW_EVENT(name_, id_, type_, struct_)                        \
   WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
 #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                  \
   WINDOW_EVENT_HELPER(name_, OnBeforeUnloadEventHandlerNonNull)
 #include "nsEventNameList.h" // IWYU pragma: keep
 #undef BEFOREUNLOAD_EVENT
 #undef WINDOW_EVENT
 #undef WINDOW_EVENT_HELPER
+#undef FORWARDED_EVENT
 #undef EVENT
 
   // These override the SetAttr methods in nsGenericHTMLElement (need
   // both here to silence compiler warnings).
   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
--- a/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
+++ b/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
@@ -1439,18 +1439,18 @@ txVariable::Convert(nsIVariant *aValue, 
                 do_QueryInterface(supports);
             if (holder) {
                 JSContext* cx = nsContentUtils::GetCurrentJSContext();
                 NS_ENSURE_TRUE(cx, NS_ERROR_NOT_AVAILABLE);
 
                 JS::Rooted<JSObject*> jsobj(cx, holder->GetJSObject());
                 NS_ENSURE_STATE(jsobj);
 
-                JS::Rooted<JS::Value> v(cx, JS::ObjectValue(*jsobj));
-                JS::Rooted<JSString*> str(cx, JS::ToString(cx, v));
+                JS::Rooted<JSString*> str(cx,
+                    JS_ValueToString(cx, OBJECT_TO_JSVAL(jsobj)));
                 NS_ENSURE_TRUE(str, NS_ERROR_FAILURE);
 
                 nsDependentJSString value;
                 NS_ENSURE_TRUE(value.init(cx, str), NS_ERROR_FAILURE);
 
                 *aResult = new StringResult(value, nullptr);
                 if (!*aResult) {
                     return NS_ERROR_OUT_OF_MEMORY;
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -672,17 +672,17 @@ AudioChannelService::Observe(nsISupports
 
     JS::Rooted<JSObject*> obj(cx, &val.toObject());
     JS::Rooted<JS::Value> key(cx);
     if (!JS_GetProperty(cx, obj, "key", &key) ||
         !key.isString()) {
       return NS_OK;
     }
 
-    JS::Rooted<JSString*> jsKey(cx, JS::ToString(cx, key));
+    JS::Rooted<JSString*> jsKey(cx, JS_ValueToString(cx, key));
     if (!jsKey) {
       return NS_OK;
     }
     nsDependentJSString keyStr;
     if (!keyStr.init(cx, jsKey) || keyStr.Find("audio.volume.", 0, false)) {
       return NS_OK;
     }
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -611,20 +611,20 @@ FindObjectClass(JSContext* cx, JSObject*
   sObjectClass = js::GetObjectJSClass(obj);
 }
 
 static inline JSString *
 IdToString(JSContext *cx, jsid id)
 {
   if (JSID_IS_STRING(id))
     return JSID_TO_STRING(id);
-  JS::Rooted<JS::Value> idval(cx);
-  if (!::JS_IdToValue(cx, id, idval.address()))
+  jsval idval;
+  if (!::JS_IdToValue(cx, id, &idval))
     return nullptr;
-  return JS::ToString(cx, idval);
+  return JS_ValueToString(cx, idval);
 }
 
 static inline nsresult
 WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
            nsWrapperCache *cache, const nsIID* aIID, JS::MutableHandle<JS::Value> vp,
            nsIXPConnectJSObjectHolder** aHolder, bool aAllowWrapping)
 {
   if (!native) {
@@ -3287,17 +3287,17 @@ LocationSetterGuts(JSContext *cx, JSObje
   nsCOMPtr<Interface> xpcomObj = do_QueryWrappedNative(wrapper, obj);
   NS_ENSURE_TRUE(xpcomObj, NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<nsIDOMLocation> location;
   nsresult rv = xpcomObj->GetLocation(getter_AddRefs(location));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Grab the value we're being set to before we stomp on |vp|
-  JS::Rooted<JSString*> val(cx, JS::ToString(cx, vp));
+  JS::Rooted<JSString*> val(cx, ::JS_ValueToString(cx, vp));
   NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED);
 
   // Make sure |val| stays alive below
   JS::Anchor<JSString *> anchor(val);
 
   // We have to wrap location into vp before null-checking location, to
   // avoid assigning the wrong thing into the slot.
   nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
@@ -4193,54 +4193,60 @@ nsHTMLDocumentSH::ReleaseDocument(JSFree
   if (doc) {
     nsContentUtils::DeferredFinalize(doc);
   }
 }
 
 bool
 nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp)
 {
-  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
   // Handle document.all("foo") style access to document.all.
 
-  if (args.length() != 1) {
+  if (argc != 1) {
     // XXX: Should throw NS_ERROR_XPC_NOT_ENOUGH_ARGS for argc < 1,
     // and create a new NS_ERROR_XPC_TOO_MANY_ARGS for argc > 1? IE
     // accepts nothing other than one arg.
     xpc::Throw(cx, NS_ERROR_INVALID_ARG);
 
     return false;
   }
 
   // Convert all types to string.
-  JS::Rooted<JSString*> str(cx, JS::ToString(cx, args[0]));
+  JS::Rooted<JSString*> str(cx, ::JS_ValueToString(cx, JS_ARGV(cx, vp)[0]));
   if (!str) {
     return false;
   }
 
   // If we are called via document.all(id) instead of document.all.item(i) or
   // another method, use the document.all callee object as self.
   JSObject *self;
-  if (args.calleev().isObject() &&
-      JS_GetClass(&args.calleev().toObject()) == &sHTMLDocumentAllClass) {
-    self = &args.calleev().toObject();
+  JS::Value callee = JS_CALLEE(cx, vp);
+  if (callee.isObject() &&
+      JS_GetClass(&callee.toObject()) == &sHTMLDocumentAllClass) {
+    self = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
   } else {
     self = JS_THIS_OBJECT(cx, vp);
     if (!self)
       return false;
   }
 
   size_t length;
   JS::Anchor<JSString *> anchor(str);
   const jschar *chars = ::JS_GetStringCharsAndLength(cx, str, &length);
   if (!chars) {
     return false;
   }
 
-  return ::JS_GetUCProperty(cx, self, chars, length, args.rval());
+  JS::Rooted<JS::Value> value(cx);
+  if (!::JS_GetUCProperty(cx, self, chars, length, &value)) {
+    return false;
+  }
+
+  *vp = value;
+  return true;
 }
 
 // StringArray helper
 
 NS_IMETHODIMP
 nsStringArraySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                              JSObject *aObj, jsid aId, jsval *vp,
                              bool *_retval)
@@ -4425,18 +4431,17 @@ nsStorage2SH::SetProperty(nsIXPConnectWr
   NS_ENSURE_TRUE(storage, NS_ERROR_UNEXPECTED);
 
   JSString *key = IdToString(cx, id);
   NS_ENSURE_TRUE(key, NS_ERROR_UNEXPECTED);
 
   nsDependentJSString keyStr;
   NS_ENSURE_TRUE(keyStr.init(cx, key), NS_ERROR_UNEXPECTED);
 
-  JS::Rooted<JS::Value> val(cx, *vp);
-  JSString *value = JS::ToString(cx, val);
+  JSString *value = ::JS_ValueToString(cx, *vp);
   NS_ENSURE_TRUE(value, NS_ERROR_UNEXPECTED);
 
   nsDependentJSString valueStr;
   NS_ENSURE_TRUE(valueStr.init(cx, value), NS_ERROR_UNEXPECTED);
 
   nsresult rv = storage->SetItem(keyStr, valueStr);
   if (NS_SUCCEEDED(rv)) {
     rv = NS_SUCCESS_I_DID_SOMETHING;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1531,38 +1531,38 @@ TraceMallocEnable(JSContext *cx, unsigne
     NS_TraceMallocEnable();
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 static bool
 TraceMallocOpenLogFile(JSContext *cx, unsigned argc, JS::Value *vp)
 {
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+    int fd;
+    JSString *str;
 
     if (!CheckUniversalXPConnectForTraceMalloc(cx))
         return false;
 
-    int fd;
     if (argc == 0) {
         fd = -1;
     } else {
-        JSString *str = JS::ToString(cx, args[0]);
+        str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
         if (!str)
             return false;
         JSAutoByteString filename(cx, str);
         if (!filename)
             return false;
         fd = open(filename.ptr(), O_CREAT | O_WRONLY | O_TRUNC, 0644);
         if (fd < 0) {
             JS_ReportError(cx, "can't open %s: %s", filename.ptr(), strerror(errno));
             return false;
         }
     }
-    args.rva().setInt32(fd);
+    JS_SET_RVAL(cx, vp, INT_TO_JSVAL(fd));
     return true;
 }
 
 static bool
 TraceMallocChangeLogFD(JSContext *cx, unsigned argc, JS::Value *vp)
 {
     JS::CallArgs args = CallArgsFromVp(argc, vp);
 
@@ -1603,49 +1603,47 @@ TraceMallocCloseLogFD(JSContext *cx, uns
     NS_TraceMallocCloseLogFD((int) fd);
     args.rval().setInt32(fd);
     return true;
 }
 
 static bool
 TraceMallocLogTimestamp(JSContext *cx, unsigned argc, JS::Value *vp)
 {
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     if (!CheckUniversalXPConnectForTraceMalloc(cx))
         return false;
 
-    JSString *str = JS::ToString(cx, args.get(0));
+    JSString *str = JS_ValueToString(cx, argc ? JS_ARGV(cx, vp)[0] : JSVAL_VOID);
     if (!str)
         return false;
     JSAutoByteString caption(cx, str);
     if (!caption)
         return false;
     NS_TraceMallocLogTimestamp(caption.ptr());
-    args.rval().setUndefined();
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 static bool
 TraceMallocDumpAllocations(JSContext *cx, unsigned argc, JS::Value *vp)
 {
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     if (!CheckUniversalXPConnectForTraceMalloc(cx))
         return false;
 
-    JSString *str = JS::ToString(cx, args.get(0));
+    JSString *str = JS_ValueToString(cx, argc ? JS_ARGV(cx, vp)[0] : JSVAL_VOID);
     if (!str)
         return false;
     JSAutoByteString pathname(cx, str);
     if (!pathname)
         return false;
     if (NS_TraceMallocDumpAllocations(pathname.ptr()) < 0) {
         JS_ReportError(cx, "can't dump to %s: %s", pathname.ptr(), strerror(errno));
         return false;
     }
-    args.rval().setUndefined();
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 static const JSFunctionSpec TraceMallocFunctions[] = {
     JS_FS("TraceMallocDisable",         TraceMallocDisable,         0, 0),
     JS_FS("TraceMallocEnable",          TraceMallocEnable,          0, 0),
     JS_FS("TraceMallocOpenLogFile",     TraceMallocOpenLogFile,     1, 0),
     JS_FS("TraceMallocChangeLogFD",     TraceMallocChangeLogFD,     1, 0),
@@ -1665,18 +1663,17 @@ namespace mozilla {
 namespace dmd {
 
 // See https://wiki.mozilla.org/Performance/MemShrink/DMD for instructions on
 // how to use DMD.
 
 static bool
 ReportAndDump(JSContext *cx, unsigned argc, JS::Value *vp)
 {
-  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-  JSString *str = JS::ToString(cx, args.get(0));
+  JSString *str = JS_ValueToString(cx, argc ? JS_ARGV(cx, vp)[0] : JSVAL_VOID);
   if (!str)
     return false;
   JSAutoByteString pathname(cx, str);
   if (!pathname)
     return false;
 
   FILE* fp = fopen(pathname.ptr(), "w");
   if (!fp) {
@@ -1688,17 +1685,17 @@ ReportAndDump(JSContext *cx, unsigned ar
   dmd::ClearReports();
   fprintf(stderr, "DMD: running reporters...\n");
   dmd::RunReporters();
   dmd::Writer writer(FpWrite, fp);
   dmd::Dump(writer);
 
   fclose(fp);
 
-  args.rval().setUndefined();
+  JS_SET_RVAL(cx, vp, JSVAL_VOID);
   return true;
 }
 
 } // namespace dmd
 } // namespace mozilla
 
 static const JSFunctionSpec DMDFunctions[] = {
     JS_FS("DMDReportAndDump", dmd::ReportAndDump, 1, 0),
--- a/dom/base/nsJSTimeoutHandler.cpp
+++ b/dom/base/nsJSTimeoutHandler.cpp
@@ -312,18 +312,17 @@ nsJSScriptTimeoutHandler::Init(nsGlobalW
   switch (::JS_TypeOfValue(cx, argv[0])) {
   case JSTYPE_FUNCTION:
     funobj = JSVAL_TO_OBJECT(argv[0]);
     break;
 
   case JSTYPE_STRING:
   case JSTYPE_OBJECT:
     {
-      JS::Rooted<JS::Value> arg(cx, argv[0]);
-      JSString *str = JS::ToString(cx, arg);
+      JSString *str = ::JS_ValueToString(cx, argv[0]);
       if (!str)
         return NS_ERROR_OUT_OF_MEMORY;
 
       expr = ::JS_FlattenString(cx, str);
       if (!expr)
           return NS_ERROR_OUT_OF_MEMORY;
 
       argv[0] = STRING_TO_JSVAL(str);
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -273,18 +273,17 @@ nsJSUtils::EvaluateString(JSContext* aCx
       }
     } else {
       ok = JS::Evaluate(aCx, rootedScope, aCompileOptions,
                         PromiseFlatString(aScript).get(),
                         aScript.Length(), aRetValue);
     }
 
     if (ok && aEvaluateOptions.coerceToString && !aRetValue->isUndefined()) {
-      JS::Rooted<JS::Value> value(aCx, *aRetValue);
-      JSString* str = JS::ToString(aCx, value);
+      JSString* str = JS_ValueToString(aCx, *aRetValue);
       ok = !!str;
       *aRetValue = ok ? JS::StringValue(str) : JS::UndefinedValue();
     }
   }
 
   if (!ok) {
     if (aEvaluateOptions.reportUncaught) {
       ReportPendingException(aCx);
--- a/dom/base/nsScreen.cpp
+++ b/dom/base/nsScreen.cpp
@@ -76,16 +76,18 @@ nsScreen::~nsScreen()
 // QueryInterface implementation for nsScreen
 NS_INTERFACE_MAP_BEGIN(nsScreen)
   NS_INTERFACE_MAP_ENTRY(nsIDOMScreen)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(nsScreen, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsScreen, nsDOMEventTargetHelper)
 
+NS_IMPL_EVENT_HANDLER(nsScreen, mozorientationchange)
+
 int32_t
 nsScreen::GetPixelDepth(ErrorResult& aRv)
 {
   nsDeviceContext* context = GetDeviceContext();
 
   if (!context) {
     aRv.Throw(NS_ERROR_FAILURE);
     return -1;
@@ -234,21 +236,19 @@ nsScreen::GetLockOrientationPermission()
     return LOCK_ALLOWED;
   }
 
   // Other content must be full-screen in order to lock orientation.
   return doc->MozFullScreen() ? FULLSCREEN_LOCK_ALLOWED : LOCK_DENIED;
 }
 
 NS_IMETHODIMP
-nsScreen::MozLockOrientation(const JS::Value& aOrientation_, JSContext* aCx,
+nsScreen::MozLockOrientation(const JS::Value& aOrientation, JSContext* aCx,
                              bool* aReturn)
 {
-  JS::Rooted<JS::Value> aOrientation(aCx, aOrientation_);
-
   if (aOrientation.isObject()) {
     JS::Rooted<JSObject*> seq(aCx, &aOrientation.toObject());
     if (IsArrayLike(aCx, seq)) {
       uint32_t length;
       // JS_GetArrayLength actually works on all objects
       if (!JS_GetArrayLength(aCx, seq, &length)) {
         return NS_ERROR_FAILURE;
       }
@@ -259,17 +259,17 @@ nsScreen::MozLockOrientation(const JS::V
       }
 
       for (uint32_t i = 0; i < length; ++i) {
         JS::Rooted<JS::Value> temp(aCx);
         if (!JS_GetElement(aCx, seq, i, &temp)) {
           return NS_ERROR_FAILURE;
         }
 
-        JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, temp));
+        JS::Rooted<JSString*> jsString(aCx, JS_ValueToString(aCx, temp));
         if (!jsString) {
           return NS_ERROR_FAILURE;
         }
 
         nsDependentJSString str;
         if (!str.init(aCx, jsString)) {
           return NS_ERROR_FAILURE;
         }
@@ -278,17 +278,17 @@ nsScreen::MozLockOrientation(const JS::V
       }
 
       ErrorResult rv;
       *aReturn = MozLockOrientation(orientations, rv);
       return rv.ErrorCode();
     }
   }
 
-  JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, aOrientation));
+  JS::Rooted<JSString*> jsString(aCx, JS_ValueToString(aCx, aOrientation));
   if (!jsString) {
     return NS_ERROR_FAILURE;
   }
 
   nsDependentJSString orientation;
   if (!orientation.init(aCx, jsString)) {
     return NS_ERROR_FAILURE;
   }
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -2103,17 +2103,17 @@ ConvertJSValueToByteString(JSContext* cx
     s = v.toString();
   } else {
 
     if (nullable && v.isNullOrUndefined()) {
       result.SetIsVoid(true);
       return true;
     }
 
-    s = JS::ToString(cx, v);
+    s = JS_ValueToString(cx, v);
     if (!s) {
       return false;
     }
     pval.set(JS::StringValue(s));  // Root the new string.
   }
 
   size_t length;
   const jschar *chars = JS_GetStringCharsZAndLength(cx, s, &length);
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -895,21 +895,21 @@ EnumValueNotFound<true>(JSContext* cx, c
                                        length);
   return ThrowErrorMessage(cx, MSG_INVALID_ENUM_VALUE, sourceDescription,
                            deflated.get(), type);
 }
 
 
 template<bool InvalidValueFatal>
 inline int
-FindEnumStringIndex(JSContext* cx, JS::Handle<JS::Value> v, const EnumEntry* values,
+FindEnumStringIndex(JSContext* cx, JS::Value v, const EnumEntry* values,
                     const char* type, const char* sourceDescription, bool* ok)
 {
   // JS_StringEqualsAscii is slow as molasses, so don't use it here.
-  JSString* str = JS::ToString(cx, v);
+  JSString* str = JS_ValueToString(cx, v);
   if (!str) {
     *ok = false;
     return 0;
   }
   JS::Anchor<JSString*> anchor(str);
   size_t length;
   const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
   if (!chars) {
@@ -1545,17 +1545,17 @@ ConvertJSValueToString(JSContext* cx, JS
       if (behavior == eEmpty) {
         result.Truncate();
       } else {
         result.SetNull();
       }
       return true;
     }
 
-    s = JS::ToString(cx, v);
+    s = JS_ValueToString(cx, v);
     if (!s) {
       return false;
     }
     pval.set(JS::StringValue(s));  // Root the new string.
   }
 
   size_t len;
   const jschar *chars = JS_GetStringCharsZAndLength(cx, s, &len);
--- a/dom/file/LockedFile.cpp
+++ b/dom/file/LockedFile.cpp
@@ -208,22 +208,22 @@ CreateGenericEvent(mozilla::dom::EventTa
   NS_ENSURE_SUCCESS(rv, nullptr);
 
   event->SetTrusted(true);
 
   return event.forget();
 }
 
 inline nsresult
-GetInputStreamForJSVal(JS::Handle<JS::Value> aValue, JSContext* aCx,
+GetInputStreamForJSVal(const JS::Value& aValue, JSContext* aCx,
                        nsIInputStream** aInputStream, uint64_t* aInputLength)
 {
   nsresult rv;
 
-  if (aValue.isObject()) {
+  if (!JSVAL_IS_PRIMITIVE(aValue)) {
     JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
     if (JS_IsArrayBufferObject(obj)) {
       char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj));
       uint32_t length = JS_GetArrayBufferByteLength(obj);
 
       rv = NS_NewByteInputStream(aInputStream, data, length,
                                  NS_ASSIGNMENT_COPY);
       NS_ENSURE_SUCCESS(rv, rv);
@@ -241,18 +241,24 @@ GetInputStreamForJSVal(JS::Handle<JS::Va
 
       rv = blob->GetInternalStream(aInputStream);
       NS_ENSURE_SUCCESS(rv, rv);
 
       return NS_OK;
     }
   }
 
-  JSString* jsstr = JS::ToString(aCx, aValue);
-  NS_ENSURE_TRUE(jsstr, NS_ERROR_XPC_BAD_CONVERT_JS);
+  JSString* jsstr;
+  if (JSVAL_IS_STRING(aValue)) {
+    jsstr = JSVAL_TO_STRING(aValue);
+  }
+  else {
+    jsstr = JS_ValueToString(aCx, aValue);
+    NS_ENSURE_TRUE(jsstr, NS_ERROR_XPC_BAD_CONVERT_JS);
+  }
 
   nsDependentJSString str;
   if (!str.init(aCx, jsstr)) {
     return NS_ERROR_FAILURE;
   }
 
   nsCString cstr;
   CopyUTF16toUTF8(str, cstr);
@@ -853,21 +859,20 @@ LockedFile::WriteOrAppend(const JS::Valu
     return NS_ERROR_DOM_FILEHANDLE_NOT_ALLOWED_ERR;
   }
 
   // Do nothing if the window is closed
   if (!GetOwner()) {
     return NS_OK;
   }
 
-  JS::Rooted<JS::Value> val(aCx, aValue);
   nsCOMPtr<nsIInputStream> inputStream;
   uint64_t inputLength;
   nsresult rv =
-    GetInputStreamForJSVal(val, aCx, getter_AddRefs(inputStream),
+    GetInputStreamForJSVal(aValue, aCx, getter_AddRefs(inputStream),
                            &inputLength);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!inputLength) {
     return NS_OK;
   }
 
   nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
--- a/dom/indexedDB/KeyPath.cpp
+++ b/dom/indexedDB/KeyPath.cpp
@@ -250,19 +250,18 @@ KeyPath::Parse(JSContext* aCx, const moz
   }
 
   *aKeyPath = keyPath;
   return NS_OK;
 }
 
 // static
 nsresult
-KeyPath::Parse(JSContext* aCx, const JS::Value& aValue_, KeyPath* aKeyPath)
+KeyPath::Parse(JSContext* aCx, const JS::Value& aValue, KeyPath* aKeyPath)
 {
-  JS::Rooted<JS::Value> aValue(aCx, aValue_);
   KeyPath keyPath(0);
 
   aKeyPath->SetType(NONEXISTENT);
 
   // See if this is a JS array.
   if (!JSVAL_IS_PRIMITIVE(aValue) &&
       JS_IsArrayObject(aCx, JSVAL_TO_OBJECT(aValue))) {
 
@@ -279,31 +278,31 @@ KeyPath::Parse(JSContext* aCx, const JS:
 
     keyPath.SetType(ARRAY);
 
     for (uint32_t index = 0; index < length; index++) {
       JS::Rooted<JS::Value> val(aCx);
       JSString* jsstr;
       nsDependentJSString str;
       if (!JS_GetElement(aCx, obj, index, &val) ||
-          !(jsstr = JS::ToString(aCx, val)) ||
+          !(jsstr = JS_ValueToString(aCx, val)) ||
           !str.init(aCx, jsstr)) {
         return NS_ERROR_FAILURE;
       }
 
       if (!keyPath.AppendStringWithValidation(aCx, str)) {
         return NS_ERROR_FAILURE;
       }
     }
   }
   // Otherwise convert it to a string.
   else if (!JSVAL_IS_NULL(aValue) && !JSVAL_IS_VOID(aValue)) {
     JSString* jsstr;
     nsDependentJSString str;
-    if (!(jsstr = JS::ToString(aCx, aValue)) ||
+    if (!(jsstr = JS_ValueToString(aCx, aValue)) ||
         !str.init(aCx, jsstr)) {
       return NS_ERROR_FAILURE;
     }
 
     keyPath.SetType(STRING);
 
     if (!keyPath.AppendStringWithValidation(aCx, str)) {
       return NS_ERROR_FAILURE;
--- a/dom/interfaces/base/nsIDOMScreen.idl
+++ b/dom/interfaces/base/nsIDOMScreen.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; 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/. */
 
 #include "nsIDOMEventTarget.idl"
 
-[scriptable, builtinclass, uuid(bcdf4ce4-9785-4e31-a851-1d51ea16da20)]
+[scriptable, builtinclass, uuid(310a1d9a-4271-4d85-9e35-9dae6683b2c1)]
 interface nsIDOMScreen : nsIDOMEventTarget
 {
   readonly attribute long             top;
   readonly attribute long             left;
   readonly attribute long             width;
   readonly attribute long             height;
   readonly attribute long             pixelDepth;
   readonly attribute long             colorDepth;
@@ -22,16 +22,18 @@ interface nsIDOMScreen : nsIDOMEventTarg
   /**
    * Returns the current screen orientation.
    * Can be: landscape-primary, landscape-secondary,
    *         portrait-primary or portrait-secondary.
    */
   [binaryname(SlowMozOrientation)]
   readonly attribute DOMString       mozOrientation;
 
+  [implicit_jscontext] attribute jsval      onmozorientationchange;
+
   /**
    * Lock the screen to the specified orientations(s).  This method returns true
    * if the lock was acquired successfully, and false otherwise.
    *
    * The parameter can be a DOMString or an Array of DOMStrings.  If you pass a
    * string, we lock the screen to that one orientation.  If you pass an Array,
    * we ensure that the screen is always in one of the given orientations.
    *
--- a/dom/interfaces/core/nsIDOMElement.idl
+++ b/dom/interfaces/core/nsIDOMElement.idl
@@ -10,17 +10,17 @@ interface nsIDOMMozNamedAttrMap;
 /**
  * The nsIDOMElement interface represents an element in an HTML or 
  * XML document. 
  *
  * For more information on this interface please see 
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-element
  */
 
-[scriptable, uuid(989422ef-120d-4d29-8a56-6aa2505a8b02)]
+[scriptable, uuid(c3646b5d-a07d-470a-8e40-784459833c9f)]
 interface nsIDOMElement : nsIDOMNode
 {
   readonly attribute DOMString        tagName;
 
   /**
    * Returns a DOMTokenList object reflecting the class attribute.
    */
   readonly attribute nsISupports classList;
@@ -75,16 +75,22 @@ interface nsIDOMElement : nsIDOMNode
   /**
    * Returns the number of child nodes that are nsIDOMElements.
    */
   readonly attribute unsigned long childElementCount;
 
   [binaryname(MozRemove)]
   void remove();
 
+
+  // HTML
+  [implicit_jscontext] attribute jsval onmouseenter;
+  [implicit_jscontext] attribute jsval onmouseleave;
+
+
   // CSSOM View
   /**
    * Retrieve a list of rectangles, one for each CSS border-box associated with
    * the element. The coordinates are in CSS pixels, and relative to
    * the top-left of the document's viewport, unless the document
    * has an SVG foreignobject ancestor, in which case the coordinates are
    * relative to the top-left of the content box of the nearest SVG foreignobject
    * ancestor. The coordinates are calculated as if every scrollable element
--- a/dom/interfaces/html/nsIDOMHTMLBodyElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLBodyElement.idl
@@ -15,18 +15,37 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(068630db-2c00-43dd-b167-495757a88236)]
+[scriptable, uuid(cc19f3c8-82fe-4337-8174-d4cde5bedcee)]
 interface nsIDOMHTMLBodyElement : nsISupports
 {
            attribute DOMString        aLink;
            attribute DOMString        background;
            attribute DOMString        bgColor;
            attribute DOMString        link;
            attribute DOMString        text;
            attribute DOMString        vLink;
+
+           [implicit_jscontext] attribute jsval            onafterprint;
+           [implicit_jscontext] attribute jsval            onbeforeprint;
+           [implicit_jscontext] attribute jsval            onbeforeunload;
+           [implicit_jscontext] attribute jsval            onhashchange;
+           [implicit_jscontext] attribute jsval            onmessage;
+           [implicit_jscontext] attribute jsval            onoffline;
+           [implicit_jscontext] attribute jsval            ononline;
+           [implicit_jscontext] attribute jsval            onpagehide;
+           [implicit_jscontext] attribute jsval            onpageshow;
+           [implicit_jscontext] attribute jsval            onpopstate;
+           // Not supported yet
+           // [implicit_jscontext] attribute jsval            onredo;
+           [implicit_jscontext] attribute jsval            onresize;
+           // Not supported yet
+           // [implicit_jscontext] attribute jsval            onstorage;
+           // Not supported yet
+           // [implicit_jscontext] attribute jsval            onundo;
+           [implicit_jscontext] attribute jsval            onunload;
 };
--- a/dom/interfaces/html/nsIDOMHTMLFrameSetElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLFrameSetElement.idl
@@ -15,14 +15,33 @@
  *
  * This interface is trying to follow the DOM Level 2 HTML specification:
  * http://www.w3.org/TR/DOM-Level-2-HTML/
  *
  * with changes from the work-in-progress WHATWG HTML specification:
  * http://www.whatwg.org/specs/web-apps/current-work/
  */
 
-[scriptable, uuid(14b29269-c387-4cff-8463-b0871ca0be3a)]
+[scriptable, uuid(aea59d1c-ff6f-4b26-88dc-2f9b4be1a138)]
 interface nsIDOMHTMLFrameSetElement : nsISupports
 {
            attribute DOMString        cols;
            attribute DOMString        rows;
+
+           [implicit_jscontext] attribute jsval            onafterprint;
+           [implicit_jscontext] attribute jsval            onbeforeprint;
+           [implicit_jscontext] attribute jsval            onbeforeunload;
+           [implicit_jscontext] attribute jsval            onhashchange;
+           [implicit_jscontext] attribute jsval            onmessage;
+           [implicit_jscontext] attribute jsval            onoffline;
+           [implicit_jscontext] attribute jsval            ononline;
+           [implicit_jscontext] attribute jsval            onpagehide;
+           [implicit_jscontext] attribute jsval            onpageshow;
+           [implicit_jscontext] attribute jsval            onpopstate;
+           // Not supported yet
+           // [implicit_jscontext] attribute jsval            onredo;
+           [implicit_jscontext] attribute jsval            onresize;
+           // Not supported yet
+           // [implicit_jscontext] attribute jsval            onstorage;
+           // Not supported yet
+           // [implicit_jscontext] attribute jsval            onundo;
+           [implicit_jscontext] attribute jsval            onunload;
 };
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -105,17 +105,17 @@ static nsresult CompareDictionaries(JSCo
       return NS_ERROR_UNEXPECTED;
     }
     if (bprop.isUndefined()) {
       // Unknown property found in A. Bail with name
       JS::Rooted<JS::Value> nameval(aCx);
       bool success = JS_IdToValue(aCx, props[i], nameval.address());
       NS_ENSURE_TRUE(success, NS_ERROR_UNEXPECTED);
 
-      JS::Rooted<JSString*> namestr(aCx, JS::ToString(aCx, nameval));
+      JS::Rooted<JSString*> namestr(aCx, JS_ValueToString(aCx, nameval));
       NS_ENSURE_TRUE(namestr, NS_ERROR_UNEXPECTED);
       aDifference->Assign(JS_GetStringCharsZ(aCx, namestr));
       return NS_OK;
     }
   }
   aDifference->Truncate();
   return NS_OK;
 }
--- a/dom/src/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/src/jsurl/nsJSProtocolHandler.cpp
@@ -281,17 +281,17 @@ nsresult nsJSThunk::EvaluateScript(nsICh
         // our current compartment. Because our current context doesn't necessarily
         // subsume that of the sandbox, we want to unwrap and enter the sandbox's
         // compartment. It's a shame that the APIs here are so clunkly. :-(
         JS::Rooted<JSObject*> sandboxObj(cx, sandbox->GetJSObject());
         NS_ENSURE_STATE(sandboxObj);
         sandboxObj = js::UncheckedUnwrap(sandboxObj);
         JSAutoCompartment ac(cx, sandboxObj);
 
-        // Push our JSContext on the context stack so the EvalInSandboxObject call (and
+        // Push our JSContext on the context stack so the JS_ValueToString call (and
         // JS_ReportPendingException, if relevant) will use the principal of cx.
         nsCxPusher pusher;
         pusher.Push(cx);
         rv = xpc->EvalInSandboxObject(NS_ConvertUTF8toUTF16(script),
                                       /* filename = */ nullptr, cx,
                                       sandboxObj, true, v.address());
 
         // Propagate and report exceptions that happened in the
--- a/dom/system/gonk/AutoMounterSetting.cpp
+++ b/dom/system/gonk/AutoMounterSetting.cpp
@@ -238,17 +238,17 @@ AutoMounterSetting::Observe(nsISupports*
   }
   JSObject& obj(val.toObject());
   JS::Rooted<JS::Value> key(cx);
   if (!JS_GetProperty(cx, &obj, "key", &key) ||
       !key.isString()) {
     return NS_OK;
   }
 
-  JSString *jsKey = JS::ToString(cx, key);
+  JSString *jsKey = JS_ValueToString(cx, key);
   nsDependentJSString keyStr;
   if (!keyStr.init(cx, jsKey)) {
     return NS_OK;
   }
 
   JS::Rooted<JS::Value> value(cx);
   if (!JS_GetProperty(cx, &obj, "value", &value)) {
     return NS_OK;
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1986,18 +1986,17 @@ XMLHttpRequest::Send(JSObject* aBody, Er
   JSContext* cx = mWorkerPrivate->GetJSContext();
 
   JS::Rooted<JS::Value> valToClone(cx);
   if (JS_IsArrayBufferObject(aBody) || JS_IsArrayBufferViewObject(aBody) ||
       file::GetDOMBlobFromJSObject(aBody)) {
     valToClone.setObject(*aBody);
   }
   else {
-    JS::Rooted<JS::Value> obj(cx, JS::ObjectValue(*aBody));
-    JSString* bodyStr = JS::ToString(cx, obj);
+    JSString* bodyStr = JS_ValueToString(cx, OBJECT_TO_JSVAL(aBody));
     if (!bodyStr) {
       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
       return;
     }
     valToClone.setString(bodyStr);
   }
 
   JSStructuredCloneCallbacks* callbacks =
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -80,32 +80,38 @@ Environment(Handle<JSObject*> global)
         !v.get().isDouble())
     {
         return nullptr;
     }
     return static_cast<XPCShellEnvironment*>(v.get().toPrivate());
 }
 
 static bool
-Print(JSContext *cx, unsigned argc, JS::Value *vp)
+Print(JSContext *cx,
+      unsigned argc,
+      JS::Value *vp)
 {
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+    unsigned i, n;
+    JSString *str;
 
-    for (unsigned i = 0; i < args.length(); i++) {
-        JSString *str = JS::ToString(cx, args[i]);
+    JS::Value *argv = JS_ARGV(cx, vp);
+    for (i = n = 0; i < argc; i++) {
+        str = JS_ValueToString(cx, argv[i]);
         if (!str)
             return false;
         JSAutoByteString bytes(cx, str);
         if (!bytes)
             return false;
         fprintf(stdout, "%s%s", i ? " " : "", bytes.ptr());
         fflush(stdout);
     }
-    fputc('\n', stdout);
-    args.rval().setUndefined();
+    n++;
+    if (n)
+        fputc('\n', stdout);
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 static bool
 GetLine(char *bufp,
         FILE *file,
         const char *prompt)
 {
@@ -114,50 +120,55 @@ GetLine(char *bufp,
     fflush(stdout);
     if (!fgets(line, sizeof line, file))
         return false;
     strcpy(bufp, line);
     return true;
 }
 
 static bool
-Dump(JSContext *cx, unsigned argc, JS::Value *vp)
+Dump(JSContext *cx,
+     unsigned argc,
+     JS::Value *vp)
 {
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
 
-    if (!args.length())
+    JSString *str;
+    if (!argc)
         return true;
 
-    JSString *str = JS::ToString(cx, args[0]);
+    str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
     if (!str)
         return false;
     JSAutoByteString bytes(cx, str);
     if (!bytes)
       return false;
 
     fputs(bytes.ptr(), stdout);
     fflush(stdout);
     return true;
 }
 
 static bool
 Load(JSContext *cx,
      unsigned argc,
      JS::Value *vp)
 {
-    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+    JS::Rooted<JS::Value> result(cx);
 
     JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp));
     if (!obj)
         return false;
 
-    for (unsigned i = 0; i < args.length(); i++) {
-        JS::Rooted<JSString*> str(cx, JS::ToString(cx, args[i]));
+    JS::Value *argv = JS_ARGV(cx, vp);
+    for (unsigned i = 0; i < argc; i++) {
+        JSString *str = JS_ValueToString(cx, argv[i]);
         if (!str)
             return false;
+        argv[i] = STRING_TO_JSVAL(str);
         JSAutoByteString filename(cx, str);
         if (!filename)
             return false;
         FILE *file = fopen(filename.ptr(), "r");
         if (!file) {
             JS_ReportError(cx, "cannot open file '%s' for reading", filename.ptr());
             return false;
         }
@@ -167,22 +178,21 @@ Load(JSContext *cx,
                .setFileAndLine(filename.ptr(), 1)
                .setPrincipals(Environment(global)->GetPrincipal());
         JS::RootedObject rootedObj(cx, obj);
         JSScript *script = JS::Compile(cx, rootedObj, options, file);
         fclose(file);
         if (!script)
             return false;
 
-        JS::Rooted<JS::Value> result(cx);
         if (!JS_ExecuteScript(cx, obj, script, result.address())) {
             return false;
         }
     }
-    args.rval().setUndefined();
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 static bool
 Version(JSContext *cx,
         unsigned argc,
         JS::Value *vp)
 {
@@ -376,19 +386,19 @@ XPCShellEnvironment::ProcessFile(JSConte
         script =
             JS_CompileScriptForPrincipals(cx, obj, env->GetPrincipal(), buffer,
                                           strlen(buffer), "typein", startline);
         if (script) {
             JSErrorReporter older;
 
             ok = JS_ExecuteScript(cx, obj, script, result.address());
             if (ok && result != JSVAL_VOID) {
-                /* Suppress error reports from JS::ToString(). */
+                /* Suppress error reports from JS_ValueToString(). */
                 older = JS_SetErrorReporter(cx, nullptr);
-                str = JS::ToString(cx, result);
+                str = JS_ValueToString(cx, result);
                 JSAutoByteString bytes;
                 if (str)
                     bytes.encodeLatin1(cx, str);
                 JS_SetErrorReporter(cx, older);
 
                 if (!!bytes)
                     fprintf(stdout, "%s\n", bytes.ptr());
                 else
@@ -594,17 +604,17 @@ XPCShellEnvironment::EvaluateString(cons
   if (aResult) {
       aResult->Truncate();
   }
 
   JS::Rooted<JS::Value> result(cx);
   bool ok = JS_ExecuteScript(cx, global, script, result.address());
   if (ok && result != JSVAL_VOID) {
       JSErrorReporter old = JS_SetErrorReporter(cx, nullptr);
-      JSString* str = JS::ToString(cx, result);
+      JSString* str = JS_ValueToString(cx, result);
       nsDependentJSString depStr;
       if (str)
           depStr.init(cx, str);
       JS_SetErrorReporter(cx, old);
 
       if (!depStr.IsEmpty() && aResult) {
           aResult->Assign(depStr);
       }
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -124,17 +124,17 @@ JavaScriptShared::init()
 
 bool
 JavaScriptShared::convertIdToGeckoString(JSContext *cx, JS::HandleId id, nsString *to)
 {
     RootedValue idval(cx);
     if (!JS_IdToValue(cx, id, idval.address()))
         return false;
 
-    RootedString str(cx, ToString(cx, idval));
+    RootedString str(cx, JS_ValueToString(cx, idval));
     if (!str)
         return false;
 
     const jschar *chars = JS_GetStringCharsZ(cx, str);
     if (!chars)
         return false;
 
     *to = chars;
--- a/js/jsd/jsd_stak.cpp
+++ b/js/jsd/jsd_stak.cpp
@@ -481,18 +481,17 @@ jsd_ValToStringInStackFrame(JSDContext* 
 
     if( ! valid )
         return nullptr;
 
     cx = jsdthreadstate->context;
     JS_ASSERT(cx);
 
     exceptionState = JS_SaveExceptionState(cx);
-    JS::RootedValue v(cx, val);
-    retval = JS::ToString(cx, v);
+    retval = JS_ValueToString(cx, val);
     JS_RestoreExceptionState(cx, exceptionState);
 
     return retval;
 }
 
 bool
 jsd_IsValidThreadState(JSDContext*        jsdc, 
                        JSDThreadState*    jsdthreadstate)
--- a/js/jsd/jsd_val.cpp
+++ b/js/jsd/jsd_val.cpp
@@ -184,18 +184,17 @@ jsd_GetValueString(JSDContext* jsdc, JSD
         return jsdval->string;
     }
 
     /* Objects call JS_ValueToString in their own compartment. */
     scopeObj = !JSVAL_IS_PRIMITIVE(jsdval->val) ? JSVAL_TO_OBJECT(jsdval->val) : jsdc->glob;
     {
         JSAutoCompartment ac(cx, scopeObj);
         AutoSaveExceptionState as(cx);
-        JS::RootedValue v(cx, jsdval->val);
-        string = JS::ToString(cx, v);
+        string = JS_ValueToString(cx, jsdval->val);
     }
 
     JSAutoCompartment ac2(cx, jsdc->glob);
     if(string) {
         stringval = STRING_TO_JSVAL(string);
     }
     if(!string || !JS_WrapValue(cx, &stringval)) {
         return nullptr;
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -268,17 +268,17 @@ static const struct ParamPair {
     {"markStackLimit",      JSGC_MARK_STACK_LIMIT}
 };
 
 static bool
 GCParameter(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
-    JSString *str = ToString(cx, args.get(0));
+    JSString *str = JS_ValueToString(cx, args.get(0));
     if (!str)
         return false;
 
     JSFlatString *flatStr = JS_FlattenString(cx, str);
     if (!flatStr)
         return false;
 
     size_t paramIndex = 0;
@@ -345,23 +345,22 @@ IsProxy(JSContext *cx, unsigned argc, Va
     }
     args.rval().setBoolean(args[0].toObject().is<ProxyObject>());
     return true;
 }
 
 static bool
 InternalConst(JSContext *cx, unsigned argc, jsval *vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() == 0) {
+    if (argc != 1) {
         JS_ReportError(cx, "the function takes exactly one argument");
         return false;
     }
 
-    JSString *str = ToString(cx, args[0]);
+    JSString *str = JS_ValueToString(cx, vp[2]);
     if (!str)
         return false;
     JSFlatString *flat = JS_FlattenString(cx, str);
     if (!flat)
         return false;
 
     if (JS_FlatStringEqualsAscii(flat, "MARK_STACK_LENGTH")) {
         vp[0] = UINT_TO_JSVAL(js::MARK_STACK_LENGTH);
@@ -680,41 +679,39 @@ static const struct TraceKindPair {
     { "all",        -1                  },
     { "object",     JSTRACE_OBJECT      },
     { "string",     JSTRACE_STRING      },
 };
 
 static bool
 CountHeap(JSContext *cx, unsigned argc, jsval *vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-
     jsval v;
     int32_t traceKind;
     JSString *str;
     JSCountHeapTracer countTracer;
     JSCountHeapNode *node;
     size_t counter;
 
     RootedValue startValue(cx, UndefinedValue());
-    if (args.length() > 0) {
-        v = args[0];
+    if (argc > 0) {
+        v = JS_ARGV(cx, vp)[0];
         if (JSVAL_IS_TRACEABLE(v)) {
             startValue = v;
         } else if (!JSVAL_IS_NULL(v)) {
             JS_ReportError(cx,
                            "the first argument is not null or a heap-allocated "
                            "thing");
             return false;
         }
     }
 
     traceKind = -1;
-    if (args.length() > 1) {
-        str = ToString(cx, args[0]);
+    if (argc > 1) {
+        str = JS_ValueToString(cx, JS_ARGV(cx, vp)[1]);
         if (!str)
             return false;
         JSFlatString *flatStr = JS_FlattenString(cx, str);
         if (!flatStr)
             return false;
         for (size_t i = 0; ;) {
             if (JS_FlatStringEqualsAscii(flatStr, traceKindNames[i].name)) {
                 traceKind = traceKindNames[i].kind;
--- a/js/src/builtin/TypeRepresentation.cpp
+++ b/js/src/builtin/TypeRepresentation.cpp
@@ -512,17 +512,18 @@ ArrayTypeRepresentation::appendStringArr
         return false;
 
     if (!element()->appendString(cx, contents))
         return false;
 
     if (!contents.append(", "))
         return false;
 
-    if (!NumberValueToStringBuffer(cx, NumberValue(length()), contents))
+    Value len = NumberValue(length());
+    if (!contents.append(JS_ValueToString(cx, len)))
         return false;
 
     if (!contents.append(")"))
         return false;
 
     return true;
 }
 
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -6787,17 +6787,17 @@ CDataFinalizer::Methods::ToString(JSCont
     // to avoid reporting an error when not appropriate.
     strMessage = JS_NewStringCopyZ(cx, "[CDataFinalizer - empty]");
     if (!strMessage) {
       return false;
     }
   } else if (!CDataFinalizer::GetValue(cx, objThis, value.address())) {
     MOZ_ASSUME_UNREACHABLE("Could not convert an empty CDataFinalizer");
   } else {
-    strMessage = ToString(cx, value);
+    strMessage = JS_ValueToString(cx, value);
     if (!strMessage) {
       return false;
     }
   }
   args.rval().setString(strMessage);
   return true;
 }
 
--- a/js/src/jsapi-tests/testOOM.cpp
+++ b/js/src/jsapi-tests/testOOM.cpp
@@ -3,18 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/DebugOnly.h"
 
 #include "jsapi-tests/tests.h"
 
 BEGIN_TEST(testOOM)
 {
-    JS::RootedValue v(cx, JS::Int32Value(9));
-    JS::RootedString jsstr(cx, JS::ToString(cx, v));
+    JS::RootedString jsstr(cx, JS_ValueToString(cx, INT_TO_JSVAL(9)));
     mozilla::DebugOnly<const jschar *> s = JS_GetStringCharsZ(cx, jsstr);
     JS_ASSERT(s[0] == '9' && s[1] == '\0');
     return true;
 }
 
 virtual JSRuntime * createRuntime()
 {
     JSRuntime *rt = JS_NewRuntime(0, JS_USE_HELPER_THREADS);
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -205,17 +205,17 @@ class JSAPITest
     } while (false)
 
     bool fail(JSAPITestString msg = JSAPITestString(), const char *filename = "-", int lineno = 0) {
         if (JS_IsExceptionPending(cx)) {
             js::gc::AutoSuppressGC gcoff(cx);
             JS::RootedValue v(cx);
             JS_GetPendingException(cx, &v);
             JS_ClearPendingException(cx);
-            JSString *s = JS::ToString(cx, v);
+            JSString *s = JS_ValueToString(cx, v);
             if (s) {
                 JSAutoByteString bytes(cx, s);
                 if (!!bytes)
                     msg += bytes.ptr();
             }
         }
         fprintf(stderr, "%s:%d:%.*s\n", filename, lineno, (int) msg.length(), msg.begin());
         msgs += msg;
@@ -232,32 +232,31 @@ class JSAPITest
         };
         return &c;
     }
 
   protected:
     static bool
     print(JSContext *cx, unsigned argc, jsval *vp)
     {
-        JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-
-        for (unsigned i = 0; i < args.length(); i++) {
-            JSString *str = JS::ToString(cx, args[i]);
+        jsval *argv = JS_ARGV(cx, vp);
+        for (unsigned i = 0; i < argc; i++) {
+            JSString *str = JS_ValueToString(cx, argv[i]);
             if (!str)
                 return false;
             char *bytes = JS_EncodeString(cx, str);
             if (!bytes)
                 return false;
             printf("%s%s", i ? " " : "", bytes);
             JS_free(cx, bytes);
         }
 
         putchar('\n');
         fflush(stdout);
-        args.rval().setUndefined();
+        JS_SET_RVAL(cx, vp, JSVAL_VOID);
         return true;
     }
 
     bool definePrint();
 
     static void setNativeStackQuota(JSRuntime *rt)
     {
         const size_t MAX_STACK_SIZE =
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -402,16 +402,26 @@ JS_ValueToConstructor(JSContext *cx, Han
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, value);
     return ReportIfNotFunction(cx, value);
 }
 
 JS_PUBLIC_API(JSString *)
+JS_ValueToString(JSContext *cx, jsval valueArg)
+{
+    RootedValue value(cx, valueArg);
+    AssertHeapIsIdle(cx);
+    CHECK_REQUEST(cx);
+    assertSameCompartment(cx, value);
+    return ToString<CanGC>(cx, value);
+}
+
+JS_PUBLIC_API(JSString *)
 JS_ValueToSource(JSContext *cx, jsval valueArg)
 {
     RootedValue value(cx, valueArg);
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, value);
     return ValueToSource(cx, value);
 }
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1038,36 +1038,33 @@ JS_ValueToObject(JSContext *cx, JS::Hand
 
 extern JS_PUBLIC_API(JSFunction *)
 JS_ValueToFunction(JSContext *cx, JS::HandleValue v);
 
 extern JS_PUBLIC_API(JSFunction *)
 JS_ValueToConstructor(JSContext *cx, JS::HandleValue v);
 
 extern JS_PUBLIC_API(JSString *)
+JS_ValueToString(JSContext *cx, jsval v);
+
+extern JS_PUBLIC_API(JSString *)
 JS_ValueToSource(JSContext *cx, jsval v);
 
 namespace js {
 /*
  * DO NOT CALL THIS.  Use JS::ToNumber
  */
 extern JS_PUBLIC_API(bool)
 ToNumberSlow(JSContext *cx, JS::Value v, double *dp);
 
 /*
  * DO NOT CALL THIS. Use JS::ToBoolean
  */
 extern JS_PUBLIC_API(bool)
 ToBooleanSlow(JS::HandleValue v);
-
-/*
- * DO NOT CALL THIS. Use JS::ToString
- */
-extern JS_PUBLIC_API(JSString*)
-ToStringSlow(JSContext *cx, JS::HandleValue v);
 } /* namespace js */
 
 namespace JS {
 
 /* ES5 9.3 ToNumber. */
 JS_ALWAYS_INLINE bool
 ToNumber(JSContext *cx, Handle<Value> v, double *out)
 {
@@ -1097,24 +1094,16 @@ ToBoolean(HandleValue v)
         double d = v.toDouble();
         return !mozilla::IsNaN(d) && d != 0;
     }
 
     /* The slow path handles strings and objects. */
     return js::ToBooleanSlow(v);
 }
 
-JS_ALWAYS_INLINE JSString*
-ToString(JSContext *cx, HandleValue v)
-{
-    if (v.isString())
-        return v.toString();
-    return js::ToStringSlow(cx, v);
-}
-
 } /* namespace JS */
 
 extern JS_PUBLIC_API(bool)
 JS_DoubleIsInt32(double d, int32_t *ip);
 
 extern JS_PUBLIC_API(int32_t)
 JS_DoubleToInt32(double d);
 
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -3984,22 +3984,16 @@ js::ToStringSlow(ExclusiveContext *cx, t
 }
 
 template JSString *
 js::ToStringSlow<CanGC>(ExclusiveContext *cx, HandleValue arg);
 
 template JSString *
 js::ToStringSlow<NoGC>(ExclusiveContext *cx, Value arg);
 
-JS_PUBLIC_API(JSString *)
-js::ToStringSlow(JSContext *cx, HandleValue v)
-{
-    return ToStringSlow<CanGC>(cx, v);
-}
-
 JSString *
 js::ValueToSource(JSContext *cx, HandleValue v)
 {
     JS_CHECK_RECURSION(cx, return nullptr);
     assertSameCompartment(cx, v);
 
     if (v.isUndefined())
         return cx->names().void0;
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -202,16 +202,53 @@ my_GetErrorMessage(void *userRef, const 
 
 #ifdef EDITLINE
 extern "C" {
 extern JS_EXPORT_API(char *) readline(const char *prompt);
 extern JS_EXPORT_API(void)   add_history(char *line);
 } // extern "C"
 #endif
 
+static void
+ReportException(JSContext *cx)
+{
+    if (JS_IsExceptionPending(cx)) {
+        if (!JS_ReportPendingException(cx))
+            JS_ClearPendingException(cx);
+    }
+}
+
+class ToStringHelper
+{
+  public:
+    ToStringHelper(JSContext *aCx, HandleValue v, bool aThrow = false)
+      : cx(aCx), mStr(cx, JS_ValueToString(cx, v))
+    {
+        if (!aThrow && !mStr)
+            ReportException(cx);
+    }
+    ToStringHelper(JSContext *aCx, HandleId id, bool aThrow = false)
+      : cx(aCx), mStr(cx, JS_ValueToString(cx, IdToValue(id)))
+    {
+        if (!aThrow && !mStr)
+            ReportException(cx);
+    }
+    bool threw() { return !mStr; }
+    jsval getJSVal() { return STRING_TO_JSVAL(mStr); }
+    const char *getBytes() {
+        if (mStr && (mBytes.ptr() || mBytes.encodeLatin1(cx, mStr)))
+            return mBytes.ptr();
+        return "(error converting value)";
+    }
+  private:
+    JSContext *cx;
+    RootedString mStr;  // Objects of this class are always stack-allocated.
+    JSAutoByteString mBytes;
+};
+
 static char *
 GetLine(FILE *file, const char * prompt)
 {
     size_t size;
     char *buffer;
 #ifdef EDITLINE
     /*
      * Use readline only if file is stdin, because there's no way to specify
@@ -651,17 +688,17 @@ ResolvePath(JSContext *cx, HandleString 
 
 static bool
 Options(JSContext *cx, unsigned argc, jsval *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     JS::ContextOptions oldOptions = JS::ContextOptionsRef(cx);
     for (unsigned i = 0; i < args.length(); i++) {
-        JSString *str = JS::ToString(cx, args[i]);
+        JSString *str = JS_ValueToString(cx, args[i]);
         if (!str)
             return false;
         args[i].setString(str);
 
         JSAutoByteString opt(cx, str);
         if (!opt)
             return false;
 
@@ -726,17 +763,17 @@ LoadScript(JSContext *cx, unsigned argc,
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     RootedObject thisobj(cx, JS_THIS_OBJECT(cx, vp));
     if (!thisobj)
         return false;
 
     RootedString str(cx);
     for (unsigned i = 0; i < args.length(); i++) {
-        str = JS::ToString(cx, args[i]);
+        str = JS_ValueToString(cx, args[i]);
         if (!str) {
             JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "load");
             return false;
         }
         str = ResolvePath(cx, str, scriptRelative);
         if (!str) {
             JS_ReportError(cx, "unable to resolve path");
             return false;
@@ -892,41 +929,41 @@ Evaluate(JSContext *cx, unsigned argc, j
         if (!v.isUndefined())
             noScriptRval = ToBoolean(v);
 
         if (!JS_GetProperty(cx, opts, "fileName", &v))
             return false;
         if (v.isNull()) {
             fileName = nullptr;
         } else if (!v.isUndefined()) {
-            JSString *s = ToString(cx, v);
+            JSString *s = JS_ValueToString(cx, v);
             if (!s)
                 return false;
             fileName = fileNameBytes.encodeLatin1(cx, s);
             if (!fileName)
                 return false;
         }
 
         if (!JS_GetProperty(cx, opts, "element", &v))
             return false;
         if (v.isObject())
             element = &v.toObject();
 
         if (!JS_GetProperty(cx, opts, "sourceURL", &v))
             return false;
         if (!v.isUndefined()) {
-            sourceURL = ToString(cx, v);
+            sourceURL = JS_ValueToString(cx, v);
             if (!sourceURL)
                 return false;
         }
 
         if (!JS_GetProperty(cx, opts, "sourceMapURL", &v))
             return false;
         if (!v.isUndefined()) {
-            sourceMapURL = ToString(cx, v);
+            sourceMapURL = JS_ValueToString(cx, v);
             if (!sourceMapURL)
                 return false;
         }
 
         if (!JS_GetProperty(cx, opts, "lineNumber", &v))
             return false;
         if (!v.isUndefined()) {
             uint32_t u;
@@ -958,17 +995,17 @@ Evaluate(JSContext *cx, unsigned argc, j
         if (!JS_GetProperty(cx, opts, "saveFrameChain", &v))
             return false;
         if (!v.isUndefined())
             saveFrameChain = ToBoolean(v);
 
         if (!JS_GetProperty(cx, opts, "sourcePolicy", &v))
             return false;
         if (!v.isUndefined()) {
-            JSString *s = ToString(cx, v);
+            JSString *s = JS_ValueToString(cx, v);
             if (!s)
                 return false;
             char *policy = JS_EncodeStringToUTF8(cx, s);
             if (!policy)
                 return false;
             if (strcmp(policy, "NO_SOURCE") == 0) {
                 sourcePolicy = CompileOptions::NO_SOURCE;
             } else if (strcmp(policy, "LAZY_SOURCE") == 0) {
@@ -1143,17 +1180,17 @@ Run(JSContext *cx, unsigned argc, jsval 
         JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "run");
         return false;
     }
 
     RootedObject thisobj(cx, JS_THIS_OBJECT(cx, vp));
     if (!thisobj)
         return false;
 
-    JSString *str = JS::ToString(cx, args[0]);
+    JSString *str = JS_ValueToString(cx, args[0]);
     if (!str)
         return false;
     args[0].setString(str);
     JSAutoByteString filename(cx, str);
     if (!filename)
         return false;
 
     const jschar *ucbuf = nullptr;
@@ -1266,17 +1303,17 @@ ReadLine(JSContext *cx, unsigned argc, j
 }
 
 static bool
 PutStr(JSContext *cx, unsigned argc, jsval *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     if (args.length() != 0) {
-        JSString *str = JS::ToString(cx, args[0]);
+        JSString *str = JS_ValueToString(cx, args[0]);
         if (!str)
             return false;
         char *bytes = JSStringToUTF8(cx, str);
         if (!bytes)
             return false;
         fputs(bytes, gOutFile);
         JS_free(cx, bytes);
         fflush(gOutFile);
@@ -1294,17 +1331,17 @@ Now(JSContext *cx, unsigned argc, jsval 
     args.rval().setDouble(now);
     return true;
 }
 
 static bool
 PrintInternal(JSContext *cx, const CallArgs &args, FILE *file)
 {
     for (unsigned i = 0; i < args.length(); i++) {
-        JSString *str = JS::ToString(cx, args[i]);
+        JSString *str = JS_ValueToString(cx, args[i]);
         if (!str)
             return false;
         char *bytes = JSStringToUTF8(cx, str);
         if (!bytes)
             return false;
         fprintf(file, "%s%s", i ? " " : "", bytes);
 #if JS_TRACE_LOGGING
         TraceLog(TraceLogging::defaultLogger(), bytes);
@@ -1523,17 +1560,17 @@ Trap(JSContext *cx, unsigned argc, jsval
     RootedScript script(cx);
     int32_t i;
 
     if (args.length() == 0) {
         JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_TRAP_USAGE);
         return false;
     }
     argc = args.length() - 1;
-    RootedString str(cx, JS::ToString(cx, args[argc]));
+    RootedString str(cx, JS_ValueToString(cx, args[argc]));
     if (!str)
         return false;
     args[argc].setString(str);
     if (!GetScriptAndPCArgs(cx, argc, args.array(), &script, &i))
         return false;
     if (uint32_t(i) >= script->length) {
         JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_TRAP_USAGE);
         return false;
@@ -1568,17 +1605,17 @@ SetDebuggerHandler(JSContext *cx, unsign
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() == 0) {
         JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                              JSSMSG_NOT_ENOUGH_ARGS, "setDebuggerHandler");
         return false;
     }
 
-    JSString *str = JS::ToString(cx, args[0]);
+    JSString *str = JS_ValueToString(cx, args[0]);
     if (!str)
         return false;
 
     JS_SetDebuggerHandler(cx->runtime(), DebuggerAndThrowHandler, str);
     args.rval().setUndefined();
     return true;
 }
 
@@ -1588,17 +1625,17 @@ SetThrowHook(JSContext *cx, unsigned arg
     CallArgs args = CallArgsFromVp(argc, vp);
     JSString *str;
     if (args.length() == 0) {
         JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
                              JSSMSG_NOT_ENOUGH_ARGS, "setThrowHook");
         return false;
     }
 
-    str = JS::ToString(cx, args[0]);
+    str = JS_ValueToString(cx, args[0]);
     if (!str)
         return false;
 
     JS_SetThrowHook(cx->runtime(), DebuggerAndThrowHandler, str);
     args.rval().setUndefined();
     return true;
 }
 
@@ -1991,18 +2028,17 @@ DisassFile(JSContext *cx, unsigned argc,
         args.rval().setUndefined();
         return true;
     }
 
     RootedObject thisobj(cx, JS_THIS_OBJECT(cx, vp));
     if (!thisobj)
         return false;
 
-    // We should change DisassembleOptionParser to store CallArgs.
-    JSString *str = JS::ToString(cx, HandleValue::fromMarkedLocation(&p.argv[0]));
+    JSString *str = JS_ValueToString(cx, p.argv[0]);
     if (!str)
         return false;
     JSAutoByteString filename(cx, str);
     if (!filename)
         return false;
     RootedScript script(cx);
 
     {
@@ -2129,17 +2165,17 @@ DisassWithSrc(JSContext *cx, unsigned ar
 
 static bool
 DumpHeap(JSContext *cx, unsigned argc, jsval *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     JSAutoByteString fileName;
     if (args.hasDefined(0)) {
-        RootedString str(cx, JS::ToString(cx, args[0]));
+        RootedString str(cx, JS_ValueToString(cx, args[0]));
         if (!str)
             return false;
 
         if (!fileName.encodeLatin1(cx, str))
             return false;
     }
 
     RootedValue startThing(cx);
@@ -2228,17 +2264,17 @@ BuildDate(JSContext *cx, unsigned argc, 
     args.rval().setUndefined();
     return true;
 }
 
 static bool
 Intern(JSContext *cx, unsigned argc, jsval *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    JSString *str = JS::ToString(cx, args.get(0));
+    JSString *str = JS_ValueToString(cx, args.length() == 0 ? UndefinedValue() : args[0]);
     if (!str)
         return false;
 
     size_t length;
     const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
     if (!chars)
         return false;
 
@@ -3372,17 +3408,17 @@ ReadFile(JSContext *cx, unsigned argc, j
 
     RootedString givenPath(cx, args[0].toString());
     RootedString str(cx, ResolvePath(cx, givenPath, scriptRelative));
     JSAutoByteString filename(cx, str);
     if (!filename)
         return false;
 
     if (args.length() > 1) {
-        JSString *opt = JS::ToString(cx, args[1]);
+        JSString *opt = JS_ValueToString(cx, args[1]);
         if (!opt)
             return false;
         bool match;
         if (!JS_StringEqualsAscii(cx, opt, "binary", &match))
             return false;
         if (match) {
             JSObject *obj;
             if (!(obj = FileAsTypedArray(cx, filename.ptr())))
@@ -3454,34 +3490,34 @@ RedirectOutput(JSContext *cx, unsigned a
 
     args.rval().setUndefined();
     return true;
 }
 
 static bool
 System(JSContext *cx, unsigned argc, jsval *vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-
-    if (args.length() == 0) {
+    JSString *str;
+
+    if (argc != 1) {
         JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS,
                              "system");
         return false;
     }
 
-    JSString *str = JS::ToString(cx, args[0]);
+    str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
     if (!str)
         return false;
-
     JSAutoByteString command(cx, str);
     if (!command)
         return false;
 
     int result = system(command.ptr());
-    args.rval().setInt32(result);
+
+    JS_SET_RVAL(cx, vp, Int32Value(result));
     return true;
 }
 
 static int sArgc;
 static char **sArgv;
 
 class AutoCStringVector
 {
@@ -3591,17 +3627,17 @@ NestedShell(JSContext *cx, unsigned argc
         char *cstr = strdup(sPropagatedFlags[i]);
         if (!cstr || !argv.append(cstr))
             return false;
     }
 
     // The arguments to nestedShell are stringified and append to argv.
     RootedString str(cx);
     for (unsigned i = 0; i < args.length(); i++) {
-        str = ToString(cx, args[i]);
+        str = JS_ValueToString(cx, args[i]);
         if (!str || !argv.append(JS_EncodeString(cx, str)))
             return false;
 
         // As a special case, if the caller passes "--js-cache", replace that
         // with "--js-cache=$(jsCacheDir)"
         if (!strcmp(argv.back(), "--js-cache")) {
             char *newArg = JS_smprintf("--js-cache=%s", jsCacheDir);
             if (!newArg)
@@ -3888,17 +3924,17 @@ class ShellSourceHook: public SourceHook
             return false;
         RootedValue filenameValue(cx, StringValue(str));
 
         RootedValue result(cx);
         if (!Call(cx, UndefinedValue(), &fun->as<JSFunction>(),
                   1, filenameValue.address(), &result))
             return false;
 
-        str = JS::ToString(cx, result);
+        str = JS_ValueToString(cx, result);
         if (!str)
             return false;
 
         *length = JS_GetStringLength(str);
         *src = cx->pod_malloc<jschar>(*length);
         if (!*src)
             return false;
 
@@ -4459,18 +4495,16 @@ my_ErrorReporter(JSContext *cx, const ch
         }
     }
 }
 
 #if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX)
 static bool
 Exec(JSContext *cx, unsigned argc, jsval *vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-
     JSFunction *fun;
     const char *name, **nargv;
     unsigned i, nargc;
     JSString *str;
     bool ok;
     pid_t pid;
     int status;
 
@@ -4488,17 +4522,17 @@ Exec(JSContext *cx, unsigned argc, jsval
     /* nargc + 1 accounts for the terminating nullptr. */
     nargv = new (char *)[nargc + 1];
     if (!nargv)
         return false;
     memset(nargv, 0, sizeof(nargv[0]) * (nargc + 1));
     nargv[0] = name;
     jsval *argv = JS_ARGV(cx, vp);
     for (i = 0; i < nargc; i++) {
-        str = (i == 0) ? fun->atom : JS::ToString(cx, args[i-1]);
+        str = (i == 0) ? fun->atom : JS_ValueToString(cx, argv[i-1]);
         if (!str) {
             ok = false;
             goto done;
         }
         nargv[i] = JSStringToUTF8(cx, str);
         if (!nargv[i]) {
             ok = false;
             goto done;
@@ -4615,31 +4649,25 @@ static const JSClass global_class = {
 
 static bool
 env_setProperty(JSContext *cx, HandleObject obj, HandleId id, bool strict, MutableHandleValue vp)
 {
 /* XXX porting may be easy, but these don't seem to supply setenv by default */
 #if !defined XP_OS2 && !defined SOLARIS
     int rv;
 
-    RootedValue idvalue(cx, IdToValue(id));
-    JSAutoByteString idstr;
-    if (!idstr.encodeLatin1(cx, idvalue.toString()))
+    ToStringHelper idstr(cx, id, true);
+    if (idstr.threw())
         return false;
-
-    RootedString value(cx, ToString(cx, vp));
-    if (!value)
+    ToStringHelper valstr(cx, vp, true);
+    if (valstr.threw())
         return false;
-    JSAutoByteString valstr;
-    if (!valstr.encodeLatin1(cx, value))
-        return false;
-
 #if defined XP_WIN || defined HPUX || defined OSF1
     {
-        char *waste = JS_smprintf("%s=%s", idstr.ptr(), valstr.ptr());
+        char *waste = JS_smprintf("%s=%s", idstr.getBytes(), valstr.getBytes());
         if (!waste) {
             JS_ReportOutOfMemory(cx);
             return false;
         }
         rv = putenv(waste);
 #ifdef XP_WIN
         /*
          * HPUX9 at least still has the bad old non-copying putenv.
@@ -4647,23 +4675,23 @@ env_setProperty(JSContext *cx, HandleObj
          * Per mail from <s.shanmuganathan@digital.com>, OSF1 also has a putenv
          * that will crash if you pass it an auto char array (so it must place
          * its argument directly in the char *environ[] array).
          */
         JS_smprintf_free(waste);
 #endif
     }
 #else
-    rv = setenv(idstr.ptr(), valstr.ptr(), 1);
+    rv = setenv(idstr.getBytes(), valstr.getBytes(), 1);
 #endif
     if (rv < 0) {
-        JS_ReportError(cx, "can't set env variable %s to %s", idstr.ptr(), valstr.ptr());
+        JS_ReportError(cx, "can't set env variable %s to %s", idstr.getBytes(), valstr.getBytes());
         return false;
     }
-    vp.set(StringValue(value));
+    vp.set(valstr.getJSVal());
 #endif /* !defined XP_OS2 && !defined SOLARIS */
     return true;
 }
 
 static bool
 env_enumerate(JSContext *cx, HandleObject obj)
 {
     static bool reflected;
@@ -4690,25 +4718,27 @@ env_enumerate(JSContext *cx, HandleObjec
     reflected = true;
     return true;
 }
 
 static bool
 env_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
             MutableHandleObject objp)
 {
-    RootedValue idvalue(cx, IdToValue(id));
-    JSAutoByteString idstr;
-    if (!idstr.encodeLatin1(cx, idvalue.toString()))
+    JSString *valstr;
+    const char *name, *value;
+
+    ToStringHelper idstr(cx, id, true);
+    if (idstr.threw())
         return false;
 
-    const char *name = idstr.ptr();
-    const char *value = getenv(name);
+    name = idstr.getBytes();
+    value = getenv(name);
     if (value) {
-        RootedString valstr(cx, JS_NewStringCopyZ(cx, value));
+        valstr = JS_NewStringCopyZ(cx, value);
         if (!valstr)
             return false;
         if (!JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
                                nullptr, nullptr, JSPROP_ENUMERATE)) {
             return false;
         }
         objp.set(obj);
     }
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -4332,17 +4332,17 @@ DebuggerGenericEval(JSContext *cx, const
 
     if (options.isObject()) {
         RootedObject opts(cx, &options.toObject());
         RootedValue v(cx);
 
         if (!JS_GetProperty(cx, opts, "url", &v))
             return false;
         if (!v.isUndefined()) {
-            RootedString url_str(cx, ToString<CanGC>(cx, v));
+            RootedString url_str(cx, JS_ValueToString(cx, v));
             if (!url_str)
                 return false;
             url = JS_EncodeString(cx, url_str);
         }
 
         if (!JS_GetProperty(cx, opts, "lineNumber", &v))
             return false;
         if (!v.isUndefined()) {
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -101,24 +101,23 @@ static PRLogModuleInfo *gJSCLLog;
 #define ERROR_NOT_PRESENT "%s - EXPORTED_SYMBOLS is not present."
 #define ERROR_NOT_AN_ARRAY "%s - EXPORTED_SYMBOLS is not an array."
 #define ERROR_GETTING_ARRAY_LENGTH "%s - Error getting array length of EXPORTED_SYMBOLS."
 #define ERROR_ARRAY_ELEMENT "%s - EXPORTED_SYMBOLS[%d] is not a string."
 #define ERROR_GETTING_SYMBOL "%s - Could not get symbol '%s'."
 #define ERROR_SETTING_SYMBOL "%s - Could not set symbol '%s' on target object."
 
 static bool
-Dump(JSContext *cx, unsigned argc, Value *vp)
+Dump(JSContext *cx, unsigned argc, jsval *vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-
-    if (args.length() == 0)
+    JSString *str;
+    if (!argc)
         return true;
 
-    JSString *str = JS::ToString(cx, args[0]);
+    str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
     if (!str)
         return false;
 
     size_t length;
     const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
     if (!chars)
         return false;
 
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -75,22 +75,21 @@ xpc::NewSandboxConstructor()
     nsCOMPtr<nsIXPCComponents_utils_Sandbox> sbConstructor =
         new nsXPCComponents_utils_Sandbox();
     return sbConstructor.forget();
 }
 
 static bool
 SandboxDump(JSContext *cx, unsigned argc, jsval *vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-
-    if (args.length() == 0)
+    JSString *str;
+    if (!argc)
         return true;
 
-    RootedString str(cx, ToString(cx, args[0]));
+    str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
     if (!str)
         return false;
 
     size_t length;
     const jschar *chars = JS_GetStringCharsZAndLength(cx, str, &length);
     if (!chars)
         return false;
 
@@ -107,17 +106,17 @@ SandboxDump(JSContext *cx, unsigned argc
             *c = '\n';
         c++;
     }
 #endif
 
     fputs(cstr, stdout);
     fflush(stdout);
     NS_Free(cstr);
-    args.rval().setBoolean(true);
+    JS_SET_RVAL(cx, vp, JSVAL_TRUE);
     return true;
 }
 
 static bool
 SandboxDebug(JSContext *cx, unsigned argc, jsval *vp)
 {
 #ifdef DEBUG
     return SandboxDump(cx, argc, vp);
@@ -134,17 +133,17 @@ SandboxImport(JSContext *cx, unsigned ar
     if (args.length() < 1 || args[0].isPrimitive()) {
         XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
         return false;
     }
 
     RootedString funname(cx);
     if (args.length() > 1) {
         // Use the second parameter as the function name.
-        funname = ToString(cx, args[1]);
+        funname = JS_ValueToString(cx, args[1]);
         if (!funname)
             return false;
     } else {
         // NB: funobj must only be used to get the JSFunction out.
         RootedObject funobj(cx, &args[0].toObject());
         if (js::IsProxy(funobj)) {
             funobj = XPCWrapper::UnsafeUnwrapSecurityWrapper(funobj);
         }
@@ -1636,29 +1635,29 @@ xpc::EvalInSandbox(JSContext *cx, Handle
                .setFileAndLine(filename, lineNo);
         if (jsVersion != JSVERSION_DEFAULT)
                options.setVersion(jsVersion);
         JS::RootedObject rootedSandbox(sandcx, sandbox);
         ok = JS::Evaluate(sandcx, rootedSandbox, options,
                           PromiseFlatString(source).get(), source.Length(),
                           v.address());
         if (ok && returnStringOnly && !v.isUndefined()) {
-            JSString *str = ToString(sandcx, v);
+            JSString *str = JS_ValueToString(sandcx, v);
             ok = !!str;
             v = ok ? JS::StringValue(str) : JS::UndefinedValue();
         }
 
         // If the sandbox threw an exception, grab it off the context.
         if (JS_GetPendingException(sandcx, &exn)) {
             MOZ_ASSERT(!ok);
             JS_ClearPendingException(sandcx);
             if (returnStringOnly) {
                 // The caller asked for strings only, convert the
                 // exception into a string.
-                JSString *str = ToString(sandcx, exn);
+                JSString *str = JS_ValueToString(sandcx, exn);
                 exn = str ? JS::StringValue(str) : JS::UndefinedValue();
             }
         }
     }
 
     //
     // Alright, we're back on the caller's cx. If an error occured, try to
     // wrap and set the exception. Otherwise, wrap the return value.
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -1571,17 +1571,17 @@ nsXPCComponents_ID::CallOrConstruct(nsIX
     }
 
     // convert the first argument into a string and see if it looks like an id
 
     JSString* jsstr;
     JSAutoByteString bytes;
     nsID id;
 
-    if (!(jsstr = ToString(cx, args[0])) ||
+    if (!(jsstr = JS_ValueToString(cx, args[0])) ||
         !bytes.encodeLatin1(cx, jsstr) ||
         !id.Parse(bytes.ptr())) {
         return ThrowAndFail(NS_ERROR_XPC_BAD_ID_STRING, cx, _retval);
     }
 
     // make the new object and return it.
 
     JSObject* newobj = xpc_NewIDObject(cx, obj, id);
@@ -1832,17 +1832,17 @@ struct MOZ_STACK_CLASS ExceptionArgParse
 
   protected:
 
     /*
      * Parsing helpers.
      */
 
     bool parseMessage(HandleValue v) {
-        JSString *str = ToString(cx, v);
+        JSString *str = JS_ValueToString(cx, v);
         if (!str)
            return false;
         eMsg = messageBytes.encodeLatin1(cx, str);
         return !!eMsg;
     }
 
     bool parseResult(HandleValue v) {
         return JS::ToUint32(cx, v, (uint32_t*) &eResult);
@@ -2445,17 +2445,17 @@ nsXPCComponents_Constructor::CallOrConst
     // initialization params for the Constructor object we will create
     nsCOMPtr<nsIJSCID> cClassID;
     nsCOMPtr<nsIJSIID> cInterfaceID;
     const char*        cInitializer = nullptr;
     JSAutoByteString  cInitializerBytes;
 
     if (args.length() >= 3) {
         // args[2] is an initializer function or property name
-        RootedString str(cx, ToString(cx, args[2]));
+        RootedString str(cx, JS_ValueToString(cx, args[2]));
         if (!str || !(cInitializer = cInitializerBytes.encodeLatin1(cx, str)))
             return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
     }
 
     if (args.length() >= 2) {
         // args[1] is an iid name string
         // XXXjband support passing "Components.interfaces.foo"?
 
@@ -2471,17 +2471,17 @@ nsXPCComponents_Constructor::CallOrConst
             NS_FAILED(xpc->WrapNative(cx, obj, ifaces,
                                       NS_GET_IID(nsIXPCComponents_Interfaces),
                                       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]));
+        RootedString str(cx, JS_ValueToString(cx, args[1]));
         RootedId id(cx);
         if (!str || !JS_ValueToId(cx, StringValue(str), id.address()))
             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);
 
@@ -2520,17 +2520,17 @@ nsXPCComponents_Constructor::CallOrConst
             NS_FAILED(xpc->WrapNative(cx, obj, classes,
                                       NS_GET_IID(nsIXPCComponents_Classes),
                                       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]));
+        RootedString str(cx, JS_ValueToString(cx, args[0]));
         RootedId id(cx);
         if (!str || !JS_ValueToId(cx, StringValue(str), id.address()))
             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);
 
@@ -2660,17 +2660,17 @@ nsXPCComponents_Utils::ReportError(const
                 column, err->flags, "XPConnect JavaScript", innerWindowID);
         NS_ENSURE_SUCCESS(rv, NS_OK);
 
         console->LogMessage(scripterr);
         return NS_OK;
     }
 
     // It's not a JS Error object, so we synthesize as best we're able.
-    RootedString msgstr(cx, ToString(cx, error));
+    RootedString msgstr(cx, JS_ValueToString(cx, error));
     if (!msgstr)
         return NS_OK;
 
     nsCOMPtr<nsIStackFrame> frame;
     nsXPConnect *xpc = nsXPConnect::XPConnect();
     xpc->GetCurrentJSStack(getter_AddRefs(frame));
 
     nsXPIDLCString fileName;
@@ -2693,33 +2693,32 @@ nsXPCComponents_Utils::ReportError(const
     console->LogMessage(scripterr);
     return NS_OK;
 }
 
 /* void evalInSandbox(in AString source, in nativeobj sandbox); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::EvalInSandbox(const nsAString& source,
                                      const Value& sandboxValArg,
-                                     const Value& versionArg,
+                                     const Value& version,
                                      const Value& filenameVal,
                                      int32_t lineNumber,
                                      JSContext *cx,
                                      uint8_t optionalArgc,
                                      Value *retval)
 {
     RootedValue sandboxVal(cx, sandboxValArg);
-    RootedValue version(cx, versionArg);
     RootedObject sandbox(cx);
     if (!JS_ValueToObject(cx, sandboxVal, &sandbox) || !sandbox)
         return NS_ERROR_INVALID_ARG;
 
     // Optional third argument: JS version, as a string.
     JSVersion jsVersion = JSVERSION_DEFAULT;
     if (optionalArgc >= 1) {
-        JSString *jsVersionStr = ToString(cx, version);
+        JSString *jsVersionStr = JS_ValueToString(cx, version);
         if (!jsVersionStr)
             return NS_ERROR_INVALID_ARG;
 
         JSAutoByteString bytes(cx, jsVersionStr);
         if (!bytes)
             return NS_ERROR_INVALID_ARG;
 
         jsVersion = JS_StringToVersion(bytes.ptr());
@@ -2733,18 +2732,17 @@ nsXPCComponents_Utils::EvalInSandbox(con
         if (jsVersion == JSVERSION_UNKNOWN)
             return NS_ERROR_INVALID_ARG;
     }
 
     // Optional fourth and fifth arguments: filename and line number.
     nsXPIDLCString filename;
     int32_t lineNo = (optionalArgc >= 3) ? lineNumber : 1;
     if (optionalArgc >= 2) {
-        RootedValue value(cx, filenameVal);
-        JSString *filenameStr = ToString(cx, value);
+        JSString *filenameStr = JS_ValueToString(cx, filenameVal);
         if (!filenameStr)
             return NS_ERROR_INVALID_ARG;
 
         JSAutoByteString filenameBytes;
         if (!filenameBytes.encodeLatin1(cx, filenameStr))
             return NS_ERROR_INVALID_ARG;
         filename = filenameBytes.ptr();
     } else {
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -189,25 +189,28 @@ XPCConvert::NativeData2JS(MutableHandleV
         case nsXPTType::T_DOMSTRING:
             {
                 const nsAString* p = *((const nsAString**)s);
                 if (!p)
                     break;
 
                 if (!p->IsVoid()) {
                     nsStringBuffer* buf;
-                    if (!XPCStringConvert::ReadableToJSVal(cx, *p, &buf, d))
+                    jsval str = XPCStringConvert::ReadableToJSVal(cx, *p, &buf);
+                    if (JSVAL_IS_NULL(str))
                         return false;
                     if (buf)
                         buf->AddRef();
+
+                    d.set(str);
                 }
 
                 // *d is defaulted to JSVAL_NULL so no need to set it
                 // again if p is a "void" string
-                MOZ_ASSERT_IF(p->IsVoid(), d.isNull());
+
                 break;
             }
 
         case nsXPTType::T_CHAR_STR:
             {
                 char* p = *((char**)s);
                 if (!p)
                     break;
@@ -405,17 +408,17 @@ XPCConvert::JSData2Native(void* d, Handl
     case nsXPTType::T_FLOAT  :
         return ConvertToPrimitive(cx, s, static_cast<float*>(d));
     case nsXPTType::T_DOUBLE :
         return ConvertToPrimitive(cx, s, static_cast<double*>(d));
     case nsXPTType::T_BOOL   :
         return ConvertToPrimitive(cx, s, static_cast<bool*>(d));
     case nsXPTType::T_CHAR   :
     {
-        JSString* str = ToString(cx, s);
+        JSString* str = JS_ValueToString(cx, s);
         if (!str) {
             return false;
         }
         size_t length;
         const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
         if (!chars) {
             return false;
         }
@@ -424,17 +427,17 @@ XPCConvert::JSData2Native(void* d, Handl
         CheckJSCharInCharRange(ch);
 #endif
         *((char*)d) = char(ch);
         break;
     }
     case nsXPTType::T_WCHAR  :
     {
         JSString* str;
-        if (!(str = ToString(cx, s))) {
+        if (!(str = JS_ValueToString(cx, s))) {
             return false;
         }
         size_t length;
         const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
         if (!chars) {
             return false;
         }
         if (length == 0) {
@@ -490,17 +493,17 @@ XPCConvert::JSData2Native(void* d, Handl
             if (isDOMString) {
                 chars  = VOID_STRING;
                 length = ArrayLength(VOID_STRING) - 1;
             } else {
                 chars = EMPTY_STRING;
                 length = 0;
             }
         } else if (!JSVAL_IS_NULL(s)) {
-            str = ToString(cx, s);
+            str = JS_ValueToString(cx, s);
             if (!str)
                 return false;
 
             length = (uint32_t) JS_GetStringLength(str);
             if (length) {
                 chars = JS_GetStringCharsZ(cx, str);
                 if (!chars)
                     return false;
@@ -554,17 +557,17 @@ XPCConvert::JSData2Native(void* d, Handl
 
     case nsXPTType::T_CHAR_STR:
     {
         if (JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s)) {
             *((char**)d) = nullptr;
             return true;
         }
 
-        JSString* str = ToString(cx, s);
+        JSString* str = JS_ValueToString(cx, s);
         if (!str) {
             return false;
         }
 #ifdef DEBUG
         const jschar* chars=nullptr;
         if (nullptr != (chars = JS_GetStringCharsZ(cx, str))) {
             bool legalRange = true;
             int len = JS_GetStringLength(str);
@@ -595,17 +598,17 @@ XPCConvert::JSData2Native(void* d, Handl
         const jschar* chars=nullptr;
         JSString* str;
 
         if (JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s)) {
             *((jschar**)d) = nullptr;
             return true;
         }
 
-        if (!(str = ToString(cx, s))) {
+        if (!(str = JS_ValueToString(cx, s))) {
             return false;
         }
         if (!(chars = JS_GetStringCharsZ(cx, str))) {
             return false;
         }
         int len = JS_GetStringLength(str);
         int byte_len = (len+1)*sizeof(jschar);
         if (!(*((void**)d) = nsMemory::Alloc(byte_len))) {
@@ -638,17 +641,17 @@ XPCConvert::JSData2Native(void* d, Handl
                 rs->Truncate();
                 rs->SetIsVoid(true);
             }
             return true;
         }
 
         // The JS val is neither null nor void...
 
-        if (!(str = ToString(cx, s))||
+        if (!(str = JS_ValueToString(cx, s))||
             !(chars = JS_GetStringCharsZ(cx, str))) {
             return false;
         }
 
         length = JS_GetStringLength(str);
 
         nsCString *rs;
         if (useAllocator) {
@@ -681,17 +684,17 @@ XPCConvert::JSData2Native(void* d, Handl
                 nsACString* rs = *((nsACString**)d);
                 rs->Truncate();
                 rs->SetIsVoid(true);
             }
             return true;
         }
 
         // The JS val is neither null nor void...
-        JSString* str = ToString(cx, s);
+        JSString* str = JS_ValueToString(cx, s);
         if (!str) {
             return false;
         }
 
         size_t length = JS_GetStringEncodingLength(cx, str);
         if (length == size_t(-1)) {
             return false;
         }
@@ -1159,17 +1162,17 @@ XPCConvert::JSValToXPCException(MutableH
             // It is a JSObject, but not a wrapped native...
 
             // If it is an engine Error with an error report then let's
             // extract the report and build an xpcexception from that
             const JSErrorReport* report;
             if (nullptr != (report = JS_ErrorFromException(cx, s))) {
                 JSAutoByteString message;
                 JSString* str;
-                if (nullptr != (str = ToString(cx, s)))
+                if (nullptr != (str = JS_ValueToString(cx, s)))
                     message.encodeLatin1(cx, str);
                 return JSErrorToXPCException(message.ptr(), ifaceName,
                                              methodName, report, exceptn);
             }
 
 
             bool found;
 
@@ -1196,17 +1199,17 @@ XPCConvert::JSValToXPCException(MutableH
 
             // XXX we should do a check against 'js_ErrorClass' here and
             // do the right thing - even though it has no JSErrorReport,
             // The fact that it is a JSError exceptions means we can extract
             // particular info and our 'result' should reflect that.
 
             // otherwise we'll just try to convert it to a string
 
-            JSString* str = ToString(cx, s);
+            JSString* str = JS_ValueToString(cx, s);
             if (!str)
                 return NS_ERROR_FAILURE;
 
             JSAutoByteString strBytes(cx, str);
             if (!strBytes)
                 return NS_ERROR_FAILURE;
 
             return ConstructException(NS_ERROR_XPC_JS_THREW_JS_OBJECT,
@@ -1267,17 +1270,17 @@ XPCConvert::JSValToXPCException(MutableH
             NS_RELEASE(data);
             return rv;
         }
     }
 
     // otherwise we'll just try to convert it to a string
     // Note: e.g., bools get converted to JSStrings by this code.
 
-    JSString* str = ToString(cx, s);
+    JSString* str = JS_ValueToString(cx, s);
     if (str) {
         JSAutoByteString strBytes(cx, str);
         if (!!strBytes) {
             return ConstructException(NS_ERROR_XPC_JS_THREW_STRING,
                                       strBytes.ptr(), ifaceName, methodName,
                                       nullptr, exceptn, cx, s.address());
         }
     }
@@ -1788,17 +1791,17 @@ XPCConvert::JSStringWithSize2Native(void
                     return true;
                 }
                 // else ...
 
                 *((char**)d) = nullptr;
                 return true;
             }
 
-            JSString* str = ToString(cx, s);
+            JSString* str = JS_ValueToString(cx, s);
             if (!str) {
                 return false;
             }
 
             size_t length = JS_GetStringEncodingLength(cx, str);
             if (length == size_t(-1)) {
                 return false;
             }
@@ -1843,17 +1846,17 @@ XPCConvert::JSStringWithSize2Native(void
                     return true;
                 }
 
                 // else ...
                 *((const jschar**)d) = nullptr;
                 return true;
             }
 
-            if (!(str = ToString(cx, s))) {
+            if (!(str = JS_ValueToString(cx, s))) {
                 return false;
             }
 
             len = JS_GetStringLength(str);
             if (len > count) {
                 if (pErr)
                     *pErr = NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING;
                 return false;
--- a/js/xpconnect/src/XPCDebug.cpp
+++ b/js/xpconnect/src/XPCDebug.cpp
@@ -101,17 +101,17 @@ xpc_DumpEvalInJSStackFrame(JSContext* cx
 
     JSExceptionState* exceptionState = JS_SaveExceptionState(cx);
     JSErrorReporter older = JS_SetErrorReporter(cx, xpcDumpEvalErrorReporter);
 
     JS::RootedValue rval(cx);
     JSString* str;
     JSAutoByteString bytes;
     if (frame.evaluateInStackFrame(cx, text, strlen(text), "eval", 1, &rval) &&
-        nullptr != (str = ToString(cx, rval)) &&
+        nullptr != (str = JS_ValueToString(cx, rval)) &&
         bytes.encodeLatin1(cx, str)) {
         DebugDump("%s\n", bytes.ptr());
     } else
         DebugDump("%s", "eval failed!\n");
     JS_SetErrorReporter(cx, older);
     JS_RestoreExceptionState(cx, exceptionState);
     return true;
 }
--- a/js/xpconnect/src/XPCQuickStubs.cpp
+++ b/js/xpconnect/src/XPCQuickStubs.cpp
@@ -743,38 +743,66 @@ xpc_qsUnwrapArgImpl(JSContext *cx,
     if (NS_SUCCEEDED(rv)) {
         *ppArgRef = static_cast<nsISupports*>(*ppArg);
         vp.setObjectOrNull(wrappedJS->GetJSObject());
     }
     return rv;
 }
 
 bool
-xpc_qsJsvalToCharStr(JSContext *cx, HandleValue v, JSAutoByteString *bytes)
+xpc_qsJsvalToCharStr(JSContext *cx, jsval v, JSAutoByteString *bytes)
 {
+    JSString *str;
+
     MOZ_ASSERT(!bytes->ptr());
+    if (JSVAL_IS_STRING(v)) {
+        str = JSVAL_TO_STRING(v);
+    } else if (JSVAL_IS_VOID(v) || JSVAL_IS_NULL(v)) {
+        return true;
+    } else {
+        if (!(str = JS_ValueToString(cx, v)))
+            return false;
+    }
+    return !!bytes->encodeLatin1(cx, str);
+}
 
-    if (v.isNullOrUndefined())
-      return true;
+bool
+xpc_qsJsvalToWcharStr(JSContext *cx, jsval v, jsval *pval, const PRUnichar **pstr)
+{
+    JSString *str;
 
-    JSString *str = ToString(cx, v);
-    if (!str)
-      return false;
-    return !!bytes->encodeLatin1(cx, str);
+    if (JSVAL_IS_STRING(v)) {
+        str = JSVAL_TO_STRING(v);
+    } else if (JSVAL_IS_VOID(v) || JSVAL_IS_NULL(v)) {
+        *pstr = nullptr;
+        return true;
+    } else {
+        if (!(str = JS_ValueToString(cx, v)))
+            return false;
+        *pval = STRING_TO_JSVAL(str);  // Root the new string.
+    }
+
+    const jschar *chars = JS_GetStringCharsZ(cx, str);
+    if (!chars)
+        return false;
+
+    *pstr = static_cast<const PRUnichar *>(chars);
+    return true;
 }
 
 namespace xpc {
 
 bool
 NonVoidStringToJsval(JSContext *cx, nsAString &str, MutableHandleValue rval)
 {
     nsStringBuffer* sharedBuffer;
-    if (!XPCStringConvert::ReadableToJSVal(cx, str, &sharedBuffer, rval))
-      return false;
-
+    jsval jsstr = XPCStringConvert::ReadableToJSVal(cx, str, &sharedBuffer);
+    if (JSVAL_IS_NULL(jsstr))
+        return false;
+    rval.set(jsstr);
     if (sharedBuffer) {
         // The string was shared but ReadableToJSVal didn't addref it.
         // Move the ownership from str to jsstr.
         str.ForgetSharedBuffer();
     }
     return true;
 }
 
--- a/js/xpconnect/src/XPCQuickStubs.h
+++ b/js/xpconnect/src/XPCQuickStubs.h
@@ -222,17 +222,17 @@ protected:
      * If null is returned, then we either failed or fully initialized
      * |this|; in either case the caller should return immediately
      * without doing anything else. Otherwise, the JSString* created
      * from |v| will be returned.  It'll be rooted, as needed, in
      * *pval.  nullBehavior and undefinedBehavior control what happens
      * when |v| is JSVAL_IS_NULL and JSVAL_IS_VOID respectively.
      */
     template<class traits>
-    JSString* InitOrStringify(JSContext* cx, JS::HandleValue v,
+    JSString* InitOrStringify(JSContext* cx, jsval v,
                               JS::MutableHandleValue pval,
                               bool notpassed,
                               StringificationBehavior nullBehavior,
                               StringificationBehavior undefinedBehavior) {
         JSString *s;
         if (JSVAL_IS_STRING(v)) {
             s = JSVAL_TO_STRING(v);
         } else {
@@ -250,17 +250,17 @@ protected:
                 // Here behavior == eStringify implies notpassed, so both eNull and
                 // eStringify should end up with void strings.
                 (new(mBuf) implementation_type(traits::sEmptyBuffer, uint32_t(0)))->
                     SetIsVoid(behavior != eEmpty);
                 mValid = true;
                 return nullptr;
             }
 
-            s = JS::ToString(cx, v);
+            s = JS_ValueToString(cx, v);
             if (!s) {
                 mValid = false;
                 return nullptr;
             }
             pval.setString(s);  // Root the new string.
         }
 
         return s;
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -206,30 +206,28 @@ GetLine(JSContext *cx, char *bufp, FILE 
         strcpy(bufp, line);
     }
     return true;
 }
 
 static bool
 ReadLine(JSContext *cx, unsigned argc, jsval *vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-
     // While 4096 might be quite arbitrary, this is something to be fixed in
     // bug 105707. It is also the same limit as in ProcessFile.
     char buf[4096];
-    RootedString str(cx);
+    JSString *str;
 
     /* If a prompt was specified, construct the string */
-    if (args.length() > 0) {
-        str = JS::ToString(cx, args[0]);
+    if (argc > 0) {
+        str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
         if (!str)
             return false;
     } else {
-        str = JS_GetEmptyString(JS_GetRuntime(cx));
+        str = JSVAL_TO_STRING(JS_GetEmptyStringValue(cx));
     }
 
     /* Get a line from the infile */
     JSAutoByteString strBytes(cx, str);
     if (!strBytes || !GetLine(cx, buf, gInFile, strBytes.ptr()))
         return false;
 
     /* Strip newline character added by GetLine() */
@@ -250,45 +248,47 @@ ReadLine(JSContext *cx, unsigned argc, j
 
     JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str));
     return true;
 }
 
 static bool
 Print(JSContext *cx, unsigned argc, jsval *vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
+    unsigned i, n;
+    JSString *str;
 
-    RootedString str(cx);
-    for (unsigned i = 0; i < args.length(); i++) {
-        str = ToString(cx, args[i]);
+    jsval *argv = JS_ARGV(cx, vp);
+    for (i = n = 0; i < argc; i++) {
+        str = JS_ValueToString(cx, argv[i]);
         if (!str)
             return false;
         JSAutoByteString strBytes(cx, str);
         if (!strBytes)
             return false;
         fprintf(gOutFile, "%s%s", i ? " " : "", strBytes.ptr());
         fflush(gOutFile);
     }
-    fputc('\n', gOutFile);
-    args.rval().setUndefined();
+    n++;
+    if (n)
+        fputc('\n', gOutFile);
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 static bool
 Dump(JSContext *cx, unsigned argc, jsval *vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-
-    args.rval().setUndefined();
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
 
-    if (!args.length())
-         return true;
+    JSString *str;
+    if (!argc)
+        return true;
 
-    RootedString str(cx, ToString(cx, args[0]));
+    str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
     if (!str)
         return false;
 
     JSAutoByteString bytes(cx, str);
     if (!bytes)
         return false;
 
 #ifdef ANDROID
@@ -297,27 +297,26 @@ Dump(JSContext *cx, unsigned argc, jsval
     fputs(bytes.ptr(), gOutFile);
     fflush(gOutFile);
     return true;
 }
 
 static bool
 Load(JSContext *cx, unsigned argc, jsval *vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-
     JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp));
     if (!obj)
         return false;
 
-    RootedString str(cx);
-    for (unsigned i = 0; i < args.length(); i++) {
-        str = ToString(cx, args[i]);
+    jsval *argv = JS_ARGV(cx, vp);
+    for (unsigned i = 0; i < argc; i++) {
+        JSString *str = JS_ValueToString(cx, argv[i]);
         if (!str)
             return false;
+        argv[i] = STRING_TO_JSVAL(str);
         JSAutoByteString filename(cx, str);
         if (!filename)
             return false;
         FILE *file = fopen(filename.ptr(), "r");
         if (!file) {
             JS_ReportError(cx, "cannot open file '%s' for reading",
                            filename.ptr());
             return false;
@@ -331,17 +330,17 @@ Load(JSContext *cx, unsigned argc, jsval
         fclose(file);
         if (!script)
             return false;
 
         JS::Rooted<JS::Value> result(cx);
         if (!compileOnly && !JS_ExecuteScript(cx, obj, script, result.address()))
             return false;
     }
-    args.rval().setUndefined();
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 static bool
 Version(JSContext *cx, unsigned argc, jsval *vp)
 {
     JSVersion origVersion = JS_GetVersion(cx);
     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(origVersion));
@@ -426,53 +425,54 @@ GCZeal(JSContext *cx, unsigned argc, jsv
 
     JS_SetGCZeal(cx, uint8_t(zeal), JS_DEFAULT_ZEAL_FREQ);
     args.rval().setUndefined();
     return true;
 }
 #endif
 
 static bool
-SendCommand(JSContext *cx, unsigned argc, Value *vp)
+SendCommand(JSContext* cx,
+            unsigned argc,
+            jsval* vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-
-    if (args.length() == 0) {
+    if (argc == 0) {
         JS_ReportError(cx, "Function takes at least one argument!");
         return false;
     }
 
-    JSString* str = ToString(cx, args[0]);
+    jsval *argv = JS_ARGV(cx, vp);
+    JSString* str = JS_ValueToString(cx, argv[0]);
     if (!str) {
         JS_ReportError(cx, "Could not convert argument 1 to string!");
         return false;
     }
 
-    if (args.length() > 1 && JS_TypeOfValue(cx, args[1]) != JSTYPE_FUNCTION) {
+    if (argc > 1 && JS_TypeOfValue(cx, argv[1]) != JSTYPE_FUNCTION) {
         JS_ReportError(cx, "Could not convert argument 2 to function!");
         return false;
     }
 
-    if (!XRE_SendTestShellCommand(cx, str, args.length() > 1 ? args[1].address() : nullptr)) {
+    if (!XRE_SendTestShellCommand(cx, str, argc > 1 ? &argv[1] : nullptr)) {
         JS_ReportError(cx, "Couldn't send command!");
         return false;
     }
 
-    args.rval().setUndefined();
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 static bool
 Options(JSContext *cx, unsigned argc, jsval *vp)
 {
     JS::CallArgs args = CallArgsFromVp(argc, vp);
     ContextOptions oldOptions = ContextOptionsRef(cx);
 
     for (unsigned i = 0; i < argc; ++i) {
-        JSString *str = ToString(cx, args[i]);
+        JSString *str = JS_ValueToString(cx, args[i]);
         if (!str)
             return false;
 
         JSAutoByteString opt(cx, str);
         if (!opt)
             return false;
 
         if (strcmp(opt.ptr(), "strict") == 0)
@@ -726,22 +726,22 @@ static bool
 env_setProperty(JSContext *cx, HandleObject obj, HandleId id, bool strict, MutableHandleValue vp)
 {
 /* XXX porting may be easy, but these don't seem to supply setenv by default */
 #if !defined XP_OS2 && !defined SOLARIS
     JSString *valstr;
     JS::Rooted<JSString*> idstr(cx);
     int rv;
 
-    RootedValue idval(cx);
-    if (!JS_IdToValue(cx, id, idval.address()))
+    jsval idval;
+    if (!JS_IdToValue(cx, id, &idval))
         return false;
 
-    idstr = ToString(cx, idval);
-    valstr = ToString(cx, vp);
+    idstr = JS_ValueToString(cx, idval);
+    valstr = JS_ValueToString(cx, vp);
     if (!idstr || !valstr)
         return false;
     JSAutoByteString name(cx, idstr);
     if (!name)
         return false;
     JSAutoByteString value(cx, valstr);
     if (!value)
         return false;
@@ -809,21 +809,21 @@ env_enumerate(JSContext *cx, HandleObjec
 }
 
 static bool
 env_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
             JS::MutableHandleObject objp)
 {
     JSString *idstr, *valstr;
 
-    RootedValue idval(cx);
-    if (!JS_IdToValue(cx, id, idval.address()))
+    jsval idval;
+    if (!JS_IdToValue(cx, id, &idval))
         return false;
 
-    idstr = ToString(cx, idval);
+    idstr = JS_ValueToString(cx, idval);
     if (!idstr)
         return false;
     JSAutoByteString name(cx, idstr);
     if (!name)
         return false;
     const char *value = getenv(name.ptr());
     if (value) {
         valstr = JS_NewStringCopyZ(cx, value);
@@ -949,19 +949,19 @@ ProcessFile(JSContext *cx, JS::Handle<JS
         script = JS_CompileScriptForPrincipals(cx, obj, gJSPrincipals, buffer,
                                                strlen(buffer), "typein", startline);
         if (script) {
             JSErrorReporter older;
 
             if (!compileOnly) {
                 ok = JS_ExecuteScript(cx, obj, script, result.address());
                 if (ok && result != JSVAL_VOID) {
-                    /* Suppress error reports from JS::ToString(). */
+                    /* Suppress error reports from JS_ValueToString(). */
                     older = JS_SetErrorReporter(cx, nullptr);
-                    str = ToString(cx, result);
+                    str = JS_ValueToString(cx, result);
                     JS_SetErrorReporter(cx, older);
                     JSAutoByteString bytes;
                     if (str && bytes.encodeLatin1(cx, str))
                         fprintf(gOutFile, "%s\n", bytes.ptr());
                     else
                         ok = false;
                 }
             }
--- a/js/xpconnect/src/XPCString.cpp
+++ b/js/xpconnect/src/XPCString.cpp
@@ -19,17 +19,16 @@
  */
 
 #include "nscore.h"
 #include "nsString.h"
 #include "nsStringBuffer.h"
 #include "jsapi.h"
 #include "xpcpublic.h"
 
-using namespace JS;
 
 // static
 void
 XPCStringConvert::FreeZoneCache(JS::Zone *zone)
 {
     // Put the zone user data into an AutoPtr (which will do the cleanup for us),
     // and null out the user data (which may already be null).
     nsAutoPtr<ZoneStringCache> cache(static_cast<ZoneStringCache*>(JS_GetZoneUserData(zone)));
@@ -55,39 +54,40 @@ XPCStringConvert::FinalizeDOMString(cons
     buf->Release();
 }
 
 const JSStringFinalizer XPCStringConvert::sDOMStringFinalizer =
     { XPCStringConvert::FinalizeDOMString };
 
 // convert a readable to a JSString, copying string data
 // static
-bool
+jsval
 XPCStringConvert::ReadableToJSVal(JSContext *cx,
                                   const nsAString &readable,
-                                  nsStringBuffer** sharedBuffer,
-                                  MutableHandleValue vp)
+                                  nsStringBuffer** sharedBuffer)
 {
+    JSString *str;
     *sharedBuffer = nullptr;
 
     uint32_t length = readable.Length();
-    if (length == 0) {
-        vp.set(JS_GetEmptyStringValue(cx));
-        return true;
-    }
+
+    if (length == 0)
+        return JS_GetEmptyStringValue(cx);
 
     nsStringBuffer *buf = nsStringBuffer::FromString(readable);
     if (buf) {
+        JS::RootedValue val(cx);
         bool shared;
-        if (!StringBufferToJSVal(cx, buf, length, vp, &shared))
-            return false;
-        if (shared)
+        bool ok = StringBufferToJSVal(cx, buf, length, &val, &shared);
+        if (!ok) {
+            return JS::NullValue();
+        }
+
+        if (shared) {
             *sharedBuffer = buf;
-        return true;
+        }
+        return val;
     }
 
     // blech, have to copy.
-    JSString *str = JS_NewUCStringCopyN(cx, readable.BeginReading(), length);
-    if (!str)
-        return false;
-    vp.setString(str);
-    return true;
+    str = JS_NewUCStringCopyN(cx, readable.BeginReading(), length);
+    return str ? JS::StringValue(str) : JS::NullValue();
 }
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -321,39 +321,37 @@ GetNamedPropertyAsVariantRaw(XPCCallCont
 nsresult
 nsXPCWrappedJSClass::GetNamedPropertyAsVariant(XPCCallContext& ccx,
                                                JSObject* aJSObjArg,
                                                const nsAString& aName,
                                                nsIVariant** aResult)
 {
     JSContext* cx = ccx.GetJSContext();
     RootedObject aJSObj(cx, aJSObjArg);
+    bool ok;
+    RootedId id(cx);
+    nsresult rv = NS_ERROR_FAILURE;
 
     AutoScriptEvaluate scriptEval(cx);
     if (!scriptEval.StartEvaluating(aJSObj))
         return NS_ERROR_FAILURE;
 
     // Wrap the string in a jsval after the AutoScriptEvaluate, so that the
     // resulting value ends up in the correct compartment.
     nsStringBuffer* buf;
-    RootedValue value(cx);
-    if (!XPCStringConvert::ReadableToJSVal(ccx, aName, &buf, &value))
+    jsval jsstr = XPCStringConvert::ReadableToJSVal(ccx, aName, &buf);
+    if (JSVAL_IS_NULL(jsstr))
         return NS_ERROR_OUT_OF_MEMORY;
     if (buf)
         buf->AddRef();
 
-    RootedId id(cx);
-    nsresult rv = NS_OK;
-    if (!JS_ValueToId(cx, value, id.address()) ||
-        !GetNamedPropertyAsVariantRaw(ccx, aJSObj, id, aResult, &rv)) {
-        if (NS_FAILED(rv))
-            return rv;
-        return NS_ERROR_FAILURE;
-    }
-    return NS_OK;
+    ok = JS_ValueToId(cx, jsstr, id.address()) &&
+        GetNamedPropertyAsVariantRaw(ccx, aJSObj, id, aResult, &rv);
+
+    return ok ? NS_OK : NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
 }
 
 /***************************************************************************/
 
 // static
 nsresult
 nsXPCWrappedJSClass::BuildPropertyEnumerator(XPCCallContext& ccx,
                                              JSObject* aJSObjArg,
@@ -383,17 +381,17 @@ nsXPCWrappedJSClass::BuildPropertyEnumer
                 return rv;
             return NS_ERROR_FAILURE;
         }
 
         RootedValue jsvalName(cx);
         if (!JS_IdToValue(cx, idName, jsvalName.address()))
             return NS_ERROR_FAILURE;
 
-        JSString* name = ToString(cx, jsvalName);
+        JSString* name = JS_ValueToString(cx, jsvalName);
         if (!name)
             return NS_ERROR_FAILURE;
 
         size_t length;
         const jschar *chars = JS_GetStringCharsAndLength(cx, name, &length);
         if (!chars)
             return NS_ERROR_FAILURE;
 
--- a/js/xpconnect/src/qsgen.py
+++ b/js/xpconnect/src/qsgen.py
@@ -449,16 +449,21 @@ argumentUnboxingTemplates = {
         "        return false;\n",
 
     'string':
         "    JSAutoByteString ${name}_bytes;\n"
         "    if (!xpc_qsJsvalToCharStr(cx, ${argVal}, &${name}_bytes))\n"
         "        return false;\n"
         "    char *${name} = ${name}_bytes.ptr();\n",
 
+    'wstring':
+        "    const PRUnichar *${name};\n"
+        "    if (!xpc_qsJsvalToWcharStr(cx, ${argVal}, ${argPtr}, &${name}))\n"
+        "        return false;\n",
+
     '[cstring]':
         "    xpc_qsACString ${name}(cx, ${argVal}, ${argPtr}, ${notPassed});\n"
         "    if (!${name}.IsValid())\n"
         "        return false;\n",
 
     '[utf8string]':
         "    xpc_qsAUTF8String ${name}(cx, ${argVal}, ${argPtr}, ${notPassed});\n"
         "    if (!${name}.IsValid())\n"
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -193,19 +193,18 @@ class XPCStringConvert
         JSString* mString;
     };
 
 public:
 
     // If the string shares the readable's buffer, that buffer will
     // get assigned to *sharedBuffer.  Otherwise null will be
     // assigned.
-    static bool ReadableToJSVal(JSContext *cx, const nsAString &readable,
-                                nsStringBuffer** sharedBuffer,
-                                JS::MutableHandleValue vp);
+    static jsval ReadableToJSVal(JSContext *cx, const nsAString &readable,
+                                 nsStringBuffer** sharedBuffer);
 
     // Convert the given stringbuffer/length pair to a jsval
     static MOZ_ALWAYS_INLINE bool
     StringBufferToJSVal(JSContext* cx, nsStringBuffer* buf, uint32_t length,
                         JS::MutableHandleValue rval, bool* sharedBuffer)
     {
         JS::Zone *zone = js::GetContextZone(cx);
         ZoneStringCache *cache = static_cast<ZoneStringCache*>(JS_GetZoneUserData(zone));
--- a/security/manager/ssl/src/nsCrypto.cpp
+++ b/security/manager/ssl/src/nsCrypto.cpp
@@ -952,31 +952,29 @@ cryptojs_ReadArgsAndGenerateKey(JSContex
 
   if (!JSVAL_IS_INT(argv[0])) {
     JS_ReportError(cx, "%s%s", JS_ERROR,
                    "passed in non-integer for key size");
     return NS_ERROR_FAILURE;
   }
   keySize = JSVAL_TO_INT(argv[0]);
   if (!JSVAL_IS_NULL(argv[1])) {
-    JS::Rooted<JS::Value> v(cx, argv[1]);
-    jsString = JS::ToString(cx, v);
+    jsString = JS_ValueToString(cx,argv[1]);
     NS_ENSURE_TRUE(jsString, NS_ERROR_OUT_OF_MEMORY);
     argv[1] = STRING_TO_JSVAL(jsString);
     params.encodeLatin1(cx, jsString);
     NS_ENSURE_TRUE(!!params, NS_ERROR_OUT_OF_MEMORY);
   }
 
   if (JSVAL_IS_NULL(argv[2])) {
     JS_ReportError(cx,"%s%s", JS_ERROR,
              "key generation type not specified");
     return NS_ERROR_FAILURE;
   }
-  JS::Rooted<JS::Value> v(cx, argv[2]);
-  jsString = JS::ToString(cx, v);
+  jsString = JS_ValueToString(cx, argv[2]);
   NS_ENSURE_TRUE(jsString, NS_ERROR_OUT_OF_MEMORY);
   argv[2] = STRING_TO_JSVAL(jsString);
   nsDependentJSString dependentKeyGenAlg;
   NS_ENSURE_TRUE(dependentKeyGenAlg.init(cx, jsString), NS_ERROR_UNEXPECTED);
   nsAutoString keyGenAlg(dependentKeyGenAlg);
   keyGenAlg.Trim("\r\n\t ");
   keyGenType->keyGenType = cryptojs_interpret_key_gen_type(keyGenAlg);
   if (keyGenType->keyGenType == invalidKeyGen) {