Backed out changeset 965cf4cbedc8 (bug 958816) for mochitest crashes.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 17 Jan 2014 10:20:05 -0500
changeset 163978 7b0a1d41b80f64ffae47fb108c5d0bfaa8863434
parent 163977 0d8510edd4e650b458382b688a88cca2306e72ad
child 163979 7218723f5a9b545f6a049a00628b67c5f559d168
push id26021
push userryanvm@gmail.com
push dateFri, 17 Jan 2014 19:46:56 +0000
treeherdermozilla-central@316466d0b962 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs958816
milestone29.0a1
backs out965cf4cbedc833a357c2f738d362a669ed48466a
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
Backed out changeset 965cf4cbedc8 (bug 958816) for mochitest crashes. CLOSED TREE
content/base/src/nsHostObjectProtocolHandler.cpp
dom/base/DOMError.cpp
dom/base/DOMException.cpp
dom/base/DOMException.h
dom/bindings/Exceptions.cpp
js/xpconnect/idl/xpccomponents.idl
js/xpconnect/idl/xpcexception.idl
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
xpcom/base/nsIException.idl
--- a/content/base/src/nsHostObjectProtocolHandler.cpp
+++ b/content/base/src/nsHostObjectProtocolHandler.cpp
@@ -89,39 +89,41 @@ class BlobURLsReporter MOZ_FINAL : publi
     nsAutoCString origin;
     nsCOMPtr<nsIURI> principalURI;
     if (NS_SUCCEEDED(aInfo->mPrincipal->GetURI(getter_AddRefs(principalURI)))
         && principalURI) {
       principalURI->GetPrePath(origin);
     }
 
     for (uint32_t i = 0; i < maxFrames && frame; ++i) {
-      nsCString fileName;
+      nsAutoCString fileNameEscaped;
+      char* fileName = nullptr;
       int32_t lineNumber = 0;
 
-      frame->GetFilename(fileName);
+      frame->GetFilename(&fileName);
       frame->GetLineNumber(&lineNumber);
 
-      if (!fileName.IsEmpty()) {
+      if (fileName != nullptr && fileName[0] != '\0') {
         stack += "js(";
+        fileNameEscaped = fileName;
         if (!origin.IsEmpty()) {
           // Make the file name root-relative for conciseness if possible.
           const char* originData;
           uint32_t originLen;
 
           originLen = origin.GetData(&originData);
           // If fileName starts with origin + "/", cut up to that "/".
-          if (fileName.Length() >= originLen + 1 &&
-              memcmp(fileName.get(), originData, originLen) == 0 &&
+          if (strlen(fileName) >= originLen + 1 &&
+              memcmp(fileName, originData, originLen) == 0 &&
               fileName[originLen] == '/') {
-            fileName.Cut(0, originLen);
+            fileNameEscaped.Cut(0, originLen);
           }
         }
-        fileName.ReplaceChar('/', '\\');
-        stack += fileName;
+        fileNameEscaped.ReplaceChar('/', '\\');
+        stack += fileNameEscaped;
         if (lineNumber > 0) {
           stack += ", line=";
           stack.AppendInt(lineNumber);
         }
         stack += ")/";
       }
 
       rv = frame->GetCaller(getter_AddRefs(frame));
--- a/dom/base/DOMError.cpp
+++ b/dom/base/DOMError.cpp
@@ -24,21 +24,21 @@ DOMError::DOMError(nsPIDOMWindow* aWindo
   : mWindow(aWindow)
 {
   SetIsDOMBinding();
 }
 
 DOMError::DOMError(nsPIDOMWindow* aWindow, nsresult aValue)
   : mWindow(aWindow)
 {
-  nsCString name, message;
-  NS_GetNameAndMessageForDOMNSResult(aValue, name, message);
+  const char *name, *message;
+  NS_GetNameAndMessageForDOMNSResult(aValue, &name, &message);
 
-  CopyUTF8toUTF16(name, mName);
-  CopyUTF8toUTF16(message, mMessage);
+  mName = NS_ConvertASCIItoUTF16(name);
+  mMessage = NS_ConvertASCIItoUTF16(message);
 
   SetIsDOMBinding();
 }
 
 DOMError::DOMError(nsPIDOMWindow* aWindow, const nsAString& aName)
   : mWindow(aWindow)
   , mName(aName)
 {
--- a/dom/base/DOMException.cpp
+++ b/dom/base/DOMException.cpp
@@ -84,51 +84,49 @@ static const struct ResultStruct
 #include "domerr.msg"
 };
 
 #undef DOM4_MSG_DEF
 #undef DOM_MSG_DEF
 
 static void
 NSResultToNameAndMessage(nsresult aNSResult,
-                         nsCString& aName,
-                         nsCString& aMessage,
+                         const char** aName,
+                         const char** aMessage,
                          uint16_t* aCode)
 {
-  aName.Truncate();
-  aMessage.Truncate();
+  *aName = nullptr;
+  *aMessage = nullptr;
   *aCode = 0;
   for (uint32_t idx = 0; idx < ArrayLength(sDOMErrorMsgMap); idx++) {
     if (aNSResult == sDOMErrorMsgMap[idx].mNSResult) {
-      aName.Rebind(sDOMErrorMsgMap[idx].mName,
-                   strlen(sDOMErrorMsgMap[idx].mName));
-      aMessage.Rebind(sDOMErrorMsgMap[idx].mMessage,
-                   strlen(sDOMErrorMsgMap[idx].mMessage));
+      *aName = sDOMErrorMsgMap[idx].mName;
+      *aMessage = sDOMErrorMsgMap[idx].mMessage;
       *aCode = sDOMErrorMsgMap[idx].mCode;
       return;
     }
   }
 
   NS_WARNING("Huh, someone is throwing non-DOM errors using the DOM module!");
 
   return;
 }
 
 nsresult
-NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, nsACString& aName,
-                                   nsACString& aMessage, uint16_t* aCode)
+NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, const char** aName,
+                                   const char** aMessage, uint16_t* aCode)
 {
-  nsCString name;
-  nsCString message;
+  const char* name = nullptr;
+  const char* message = nullptr;
   uint16_t code = 0;
-  NSResultToNameAndMessage(aNSResult, name, message, &code);
+  NSResultToNameAndMessage(aNSResult, &name, &message, &code);
 
-  if (!name.IsEmpty() && !message.IsEmpty()) {
-    aName = name;
-    aMessage = message;
+  if (name && message) {
+    *aName = name;
+    *aMessage = message;
     if (aCode) {
       *aCode = code;
     }
     return NS_OK;
   }
 
   return NS_ERROR_NOT_AVAILABLE;
 }
@@ -167,23 +165,29 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Ex
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mInner)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   tmp->mThrownJSVal.setNull();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CI_INTERFACE_GETTER1(Exception, nsIXPCException)
 
-Exception::Exception(const nsACString& aMessage,
+Exception::Exception(const char *aMessage,
                      nsresult aResult,
-                     const nsACString& aName,
+                     const char *aName,
                      nsIStackFrame *aLocation,
                      nsISupports *aData)
-: mResult(NS_OK),
+: mMessage(nullptr),
+  mResult(NS_OK),
+  mName(nullptr),
+  mLocation(nullptr),
+  mData(nullptr),
+  mFilename(nullptr),
   mLineNumber(0),
+  mInner(nullptr),
   mInitialized(false),
   mHoldingJSVal(false)
 {
   SetIsDOMBinding();
 
   // A little hack... The nsIGenericModule nsIClassInfo scheme relies on there
   // having been at least one instance made via the factory. Otherwise, the
   // shared factory/classinsance object never gets created and our QI getter
@@ -226,25 +230,41 @@ Exception::Exception(const nsACString& a
       location = caller;
     }
   }
 
   Initialize(aMessage, aResult, aName, location, aData, nullptr);
 }
 
 Exception::Exception()
-  : mResult(NS_OK),
+  : mMessage(nullptr),
+    mResult(NS_OK),
+    mName(nullptr),
+    mFilename(nullptr),
     mLineNumber(-1),
     mInitialized(false),
     mHoldingJSVal(false)
 {
 }
 
 Exception::~Exception()
 {
+  if (mMessage) {
+    nsMemory::Free(mMessage);
+    mMessage = nullptr;
+  }
+  if (mName) {
+    nsMemory::Free(mName);
+    mName = nullptr;
+  }
+  if (mFilename) {
+    nsMemory::Free(mFilename);
+    mFilename = nullptr;
+  }
+
   if (mHoldingJSVal) {
     MOZ_ASSERT(NS_IsMainThread());
 
     mozilla::DropJSObjects(this);
   }
 }
 
 bool
@@ -271,71 +291,76 @@ Exception::StowJSVal(JS::Value& aVp)
 
   mThrownJSVal = aVp;
   if (!mHoldingJSVal) {
     mozilla::HoldJSObjects(this);
     mHoldingJSVal = true;
   }
 }
 
-/* readonly attribute AUTF8String message; */
+/* readonly attribute string message; */
 NS_IMETHODIMP
-Exception::GetMessageMoz(nsACString& aMessage)
+Exception::GetMessageMoz(char** aMessage)
 {
+  NS_ENSURE_ARG_POINTER(aMessage);
   NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
 
-  aMessage.Assign(mMessage);
+  if (mMessage) {
+    *aMessage =
+      (char*) nsMemory::Clone(mMessage, sizeof(char)*(strlen(mMessage)+1));
+  } else {
+    *aMessage = nullptr;
+  }
+
   return NS_OK;
 }
 
 /* readonly attribute nsresult result; */
 NS_IMETHODIMP
 Exception::GetResult(nsresult* aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
   NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
 
   *aResult = mResult;
   return NS_OK;
 }
 
-/* readonly attribute AUTF8String name; */
+/* readonly attribute string name; */
 NS_IMETHODIMP
-Exception::GetName(nsACString& aName)
+Exception::GetName(char** aName)
 {
+  NS_ENSURE_ARG_POINTER(aName);
   NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
 
-  if (!mName.IsEmpty()) {
-    aName.Assign(mName);
-  } else {
-    aName.Truncate();
+  const char* name = mName;
+  if (!name) {
+    nsXPCException::NameAndFormatForNSResult(mResult, &name, nullptr);
+  }
 
-    const char* name = nullptr;
-    nsXPCException::NameAndFormatForNSResult(mResult, &name, nullptr);
-
-    if (name) {
-      aName.Assign(name);
-    }
+  if (name) {
+    *aName = (char*) nsMemory::Clone(name, sizeof(char)*(strlen(name)+1));
+  } else {
+    *aName = nullptr;
   }
 
   return NS_OK;
 }
 
-/* readonly attribute AUTF8String filename; */
+/* readonly attribute string filename; */
 NS_IMETHODIMP
-Exception::GetFilename(nsACString& aFilename)
+Exception::GetFilename(char** aFilename)
 {
   NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
 
   if (mLocation) {
     return mLocation->GetFilename(aFilename);
   }
 
-  aFilename.Assign(mFilename);
-  return NS_OK;
+  XPC_STRING_GETTER_BODY(aFilename, mFilename);
 }
 
 /* readonly attribute uint32_t lineNumber; */
 NS_IMETHODIMP
 Exception::GetLineNumber(uint32_t *aLineNumber)
 {
   NS_ENSURE_ARG_POINTER(aLineNumber);
   NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
@@ -393,70 +418,80 @@ Exception::GetInner(nsIException** aExce
   NS_ENSURE_ARG_POINTER(aException);
   NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
 
   nsCOMPtr<nsIException> inner = mInner;
   inner.forget(aException);
   return NS_OK;
 }
 
-/* AUTF8String toString (); */
+/* string toString (); */
 NS_IMETHODIMP
-Exception::ToString(nsACString& _retval)
+Exception::ToString(char **_retval)
 {
+  NS_ENSURE_ARG_POINTER(_retval);
   NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
 
   static const char defaultMsg[] = "<no message>";
   static const char defaultLocation[] = "<unknown>";
   static const char format[] =
 "[Exception... \"%s\"  nsresult: \"0x%x (%s)\"  location: \"%s\"  data: %s]";
 
-  nsCString location;
+  char* indicatedLocation = nullptr;
 
   if (mLocation) {
     // we need to free this if it does not fail
-    nsresult rv = mLocation->ToString(location);
+    nsresult rv = mLocation->ToString(&indicatedLocation);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  if (location.IsEmpty()) {
-    location.Assign(defaultLocation);
-  }
-
-  const char* msg = mMessage.IsEmpty() ? nullptr : mMessage.get();
-
-  const char* resultName = mName.IsEmpty() ? nullptr: mName.get();
+  const char* msg = mMessage ? mMessage : nullptr;
+  const char* location = indicatedLocation ?
+                              indicatedLocation : defaultLocation;
+  const char* resultName = mName;
   if (!resultName &&
       !nsXPCException::NameAndFormatForNSResult(mResult, &resultName,
                                                 (!msg) ? &msg : nullptr)) {
     if (!msg) {
       msg = defaultMsg;
     }
     resultName = "<unknown>";
   }
   const char* data = mData ? "yes" : "no";
 
-  _retval.Truncate();
-  _retval.AppendPrintf(format, msg, mResult, resultName,
-                       location.get(), data);
-  return NS_OK;
+  char* temp = JS_smprintf(format, msg, mResult, resultName, location, data);
+  if (indicatedLocation) {
+    nsMemory::Free(indicatedLocation);
+  }
+
+  char* final = nullptr;
+  if (temp) {
+    final = (char*) nsMemory::Clone(temp, sizeof(char)*(strlen(temp)+1));
+    JS_smprintf_free(temp);
+  }
+
+  *_retval = final;
+  return final ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
-/* void initialize (in AUTF8String aMessage, in nsresult aResult,
- *                  in AUTF8String aName, in nsIStackFrame aLocation,
- *                  in nsISupports aData, in nsIException aInner); */
+/* void initialize (in string aMessage, in nsresult aResult, in string aName, in nsIStackFrame aLocation, in nsISupports aData, in nsIException aInner); */
 NS_IMETHODIMP
-Exception::Initialize(const nsACString& aMessage, nsresult aResult,
-                      const nsACString& aName, nsIStackFrame *aLocation,
-                      nsISupports *aData, nsIException *aInner)
+Exception::Initialize(const char *aMessage, nsresult aResult, const char *aName, nsIStackFrame *aLocation, nsISupports *aData, nsIException *aInner)
 {
   NS_ENSURE_FALSE(mInitialized, NS_ERROR_ALREADY_INITIALIZED);
 
-  mMessage = aMessage;
-  mName = aName;
+  if (aMessage) {
+    mMessage =
+      (char*) nsMemory::Clone(aMessage, sizeof(char)*(strlen(aMessage)+1));
+  }
+
+  if (aName) {
+    mName = (char*) nsMemory::Clone(aName, sizeof(char)*(strlen(aName)+1));
+  }
+
   mResult = aResult;
 
   if (aLocation) {
     mLocation = aLocation;
   } else {
     nsresult rv;
     nsXPConnect* xpc = nsXPConnect::XPConnect();
     rv = xpc->GetCurrentJSStack(getter_AddRefs(mLocation));
@@ -476,53 +511,56 @@ JSObject*
 Exception::WrapObject(JSContext* cx, JS::Handle<JSObject*> scope)
 {
   return ExceptionBinding::Wrap(cx, scope, this);
 }
 
 void
 Exception::GetMessageMoz(nsString& retval)
 {
-  nsCString str;
+  char* str = nullptr;
 #ifdef DEBUG
   DebugOnly<nsresult> rv = 
 #endif
-  GetMessageMoz(str);
+  GetMessageMoz(&str);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
   CopyUTF8toUTF16(str, retval);
+  nsMemory::Free(str);
 }
 
 uint32_t
 Exception::Result() const
 {
   return (uint32_t)mResult;
 }
 
 void
 Exception::GetName(nsString& retval)
 {
-  nsCString str;
+  char* str = nullptr;
 #ifdef DEBUG
   DebugOnly<nsresult> rv =
 #endif
-  GetName(str);
+  GetName(&str);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
   CopyUTF8toUTF16(str, retval);
+  nsMemory::Free(str);
 }
 
 void
 Exception::GetFilename(nsString& retval)
 {
-  nsCString str;
+  char* str = nullptr;
 #ifdef DEBUG
   DebugOnly<nsresult> rv =
 #endif
-  GetFilename(str);
+  GetFilename(&str);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
   CopyUTF8toUTF16(str, retval);
+  nsMemory::Free(str);
 }
 
 uint32_t
 Exception::LineNumber() const
 {
   if (mLocation) {
     int32_t lineno;
     if (NS_SUCCEEDED(mLocation->GetLineNumber(&lineno))) {
@@ -559,34 +597,35 @@ Exception::GetData() const
 {
   nsCOMPtr<nsISupports> data = mData;
   return data.forget();
 }
 
 void
 Exception::Stringify(nsString& retval)
 {
-  nsCString str;
+  char* str = nullptr;
 #ifdef DEBUG
   DebugOnly<nsresult> rv =
 #endif
-  ToString(str);
+  ToString(&str);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
   CopyUTF8toUTF16(str, retval);
+  nsMemory::Free(str);
 }
 
 NS_IMPL_ADDREF_INHERITED(DOMException, Exception)
 NS_IMPL_RELEASE_INHERITED(DOMException, Exception)
 NS_INTERFACE_MAP_BEGIN(DOMException)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDOMException)
 NS_INTERFACE_MAP_END_INHERITING(Exception)
 
-DOMException::DOMException(nsresult aRv, const nsACString& aMessage,
-                           const nsACString& aName, uint16_t aCode)
-  : Exception(EmptyCString(), aRv, EmptyCString(), nullptr, nullptr),
+DOMException::DOMException(nsresult aRv, const char* aMessage,
+                           const char* aName, uint16_t aCode)
+  : Exception(nullptr, aRv, nullptr, nullptr, nullptr),
     mName(aName),
     mMessage(aMessage),
     mCode(aCode)
 {
   SetIsDOMBinding();
 }
 
 NS_IMETHODIMP
@@ -603,31 +642,32 @@ DOMException::GetCode(uint16_t* aCode)
       doc->WarnOnceAbout(nsIDocument::eDOMExceptionCode);
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-DOMException::ToString(nsACString& aReturn)
+DOMException::ToString(char **aReturn)
 {
-  aReturn.Truncate();
+  *aReturn = nullptr;
 
   static const char defaultMsg[] = "<no message>";
   static const char defaultLocation[] = "<unknown>";
   static const char defaultName[] = "<unknown>";
   static const char format[] =
     "[Exception... \"%s\"  code: \"%d\" nsresult: \"0x%x (%s)\"  location: \"%s\"]";
 
   nsAutoCString location;
 
   if (mInner) {
-    nsCString filename;
-    mInner->GetFilename(filename);
+    nsXPIDLCString filename;
+
+    mInner->GetFilename(getter_Copies(filename));
 
     if (!filename.IsEmpty()) {
       uint32_t line_nr = 0;
 
       mInner->GetLineNumber(&line_nr);
 
       char *temp = PR_smprintf("%s Line: %d", filename.get(), line_nr);
       if (temp) {
@@ -636,23 +676,23 @@ DOMException::ToString(nsACString& aRetu
       }
     }
   }
 
   if (location.IsEmpty()) {
     location = defaultLocation;
   }
 
-  const char* msg = !mMessage.IsEmpty() ? mMessage.get() : defaultMsg;
-  const char* resultName = !mName.IsEmpty() ? mName.get() : defaultName;
+  const char* msg = mMessage ? mMessage : defaultMsg;
+  const char* resultName = mName ? mName : defaultName;
 
-  aReturn.AppendPrintf(format, msg, mCode, mResult, resultName,
-                       location.get());
+  *aReturn = PR_smprintf(format, msg, mCode, mResult, resultName,
+                         location.get());
 
-  return NS_OK;
+  return *aReturn ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 void
 DOMException::GetName(nsString& retval)
 {
   CopyUTF8toUTF16(mName, retval);
 }
 
@@ -666,19 +706,19 @@ JSObject*
 DOMException::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
   return DOMExceptionBinding::Wrap(aCx, aScope, this);
 }
 
 /* static */already_AddRefed<DOMException>
 DOMException::Create(nsresult aRv)
 {
-  nsCString name;
-  nsCString message;
+  const char* name;
+  const char* message;
   uint16_t code;
-  NSResultToNameAndMessage(aRv, name, message, &code);
+  NSResultToNameAndMessage(aRv, &name, &message, &code);
   nsRefPtr<DOMException> inst =
     new DOMException(aRv, message, name, code);
   return inst.forget();
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/DOMException.h
+++ b/dom/base/DOMException.h
@@ -16,24 +16,23 @@
 #include "jspubtd.h"
 #include "js/GCAPI.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsID.h"
 #include "nsIDOMDOMException.h"
 #include "nsWrapperCache.h"
 #include "xpcexception.h"
-#include "nsString.h"
 
 class nsIStackFrame;
 class nsString;
 
 nsresult
-NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, nsACString& aName,
-                                   nsACString& aMessage,
+NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, const char** aName,
+                                   const char** aMessage,
                                    uint16_t* aCode = nullptr);
 
 namespace mozilla {
 namespace dom {
 
 #define MOZILLA_EXCEPTION_IID \
 { 0x55eda557, 0xeba0, 0x4fe3, \
   { 0xae, 0x2e, 0xf3, 0x94, 0x49, 0x23, 0x62, 0xd6 } }
@@ -81,31 +80,31 @@ public:
 
   already_AddRefed<nsISupports> GetData() const;
 
   void Stringify(nsString& retval);
 
   // XPCOM factory ctor.
   Exception();
 
-  Exception(const nsACString& aMessage,
+  Exception(const char *aMessage,
             nsresult aResult,
-            const nsACString& aName,
+            const char *aName,
             nsIStackFrame *aLocation,
             nsISupports *aData);
 
 protected:
   virtual ~Exception();
 
-  nsCString       mMessage;
+  char*           mMessage;
   nsresult        mResult;
-  nsCString       mName;
+  char*           mName;
   nsCOMPtr<nsIStackFrame> mLocation;
   nsCOMPtr<nsISupports> mData;
-  nsCString       mFilename;
+  char*           mFilename;
   int             mLineNumber;
   nsCOMPtr<nsIException> mInner;
   bool            mInitialized;
 
   bool mHoldingJSVal;
   JS::Heap<JS::Value> mThrownJSVal;
 
 private:
@@ -113,24 +112,24 @@ private:
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(Exception, MOZILLA_EXCEPTION_IID)
 
 class DOMException : public Exception,
                      public nsIDOMDOMException
 {
 public:
-  DOMException(nsresult aRv, const nsACString& aMessage,
-               const nsACString& aName, uint16_t aCode);
+  DOMException(nsresult aRv, const char* aMessage,
+               const char* aName, uint16_t aCode);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMEXCEPTION
 
   // nsIException overrides
-  NS_IMETHOD ToString(nsACString& aReturn) MOZ_OVERRIDE;
+  NS_IMETHOD ToString(char **aReturn) MOZ_OVERRIDE;
 
   // nsWrapperCache overrides
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
     MOZ_OVERRIDE;
 
   uint16_t Code() const {
     return mCode;
   }
@@ -141,18 +140,19 @@ public:
 
   static already_AddRefed<DOMException>
   Create(nsresult aRv);
 
 protected:
 
   virtual ~DOMException() {}
 
-  nsCString mName;
-  nsCString mMessage;
+  // Intentionally shadow the nsXPCException version.
+  const char* mName;
+  const char* mMessage;
 
   uint16_t mCode;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #ifdef __GNUC__
--- a/dom/bindings/Exceptions.cpp
+++ b/dom/bindings/Exceptions.cpp
@@ -142,18 +142,17 @@ Throw(JSContext* aCx, nsresult aRv, cons
     break;
 
   default:
       break;
   }
 
   // If not, use the default.
   if (!finalException) {
-    finalException = new Exception(nsCString(aMessage), aRv,
-                                   EmptyCString(), nullptr, nullptr);
+    finalException = new Exception(aMessage, aRv, nullptr, nullptr, nullptr);
   }
 
   MOZ_ASSERT(finalException);
   if (!ThrowExceptionObject(aCx, finalException)) {
     // If we weren't able to throw an exception we're
     // most likely out of memory
     JS_ReportOutOfMemory(aCx);
   }
@@ -288,38 +287,42 @@ public:
                            int32_t aLineNumber,
                            nsIStackFrame* aCaller);
 
 private:
   bool IsJSFrame() const {
     return mLanguage == nsIProgrammingLanguage::JAVASCRIPT;
   }
 
+  const char* GetFilename();
+  const char* GetFunname();
   int32_t GetLineno();
 
   nsRefPtr<StackDescriptionOwner> mStackDescription;
   nsCOMPtr<nsIStackFrame> mCaller;
 
   // Cached values
-  nsCString mFilename;
-  nsCString mFunname;
+  char* mFilename;
+  char* mFunname;
   int32_t mLineno;
   uint32_t mLanguage;
 
   size_t mIndex;
 
   bool mFilenameInitialized;
   bool mFunnameInitialized;
   bool mLinenoInitialized;
   bool mCallerInitialized;
 };
 
 JSStackFrame::JSStackFrame(StackDescriptionOwner* aStackDescription,
                            size_t aIndex)
-  : mLineno(0)
+  : mFilename(nullptr),
+    mFunname(nullptr),
+    mLineno(0)
 {
   if (aStackDescription && aIndex < aStackDescription->NumFrames()) {
     mStackDescription = aStackDescription;
     mIndex = aIndex;
     mFilenameInitialized = false;
     mFunnameInitialized = false;
     mLinenoInitialized = false;
     mCallerInitialized = false;
@@ -332,16 +335,22 @@ JSStackFrame::JSStackFrame(StackDescript
     mLinenoInitialized = true;
     mCallerInitialized = true;
     mLanguage = nsIProgrammingLanguage::UNKNOWN;
   }
 }
 
 JSStackFrame::~JSStackFrame()
 {
+  if (mFilename) {
+    nsMemory::Free(mFilename);
+  }
+  if (mFunname) {
+    nsMemory::Free(mFunname);
+  }
 }
 
 NS_IMPL_CYCLE_COLLECTION_2(JSStackFrame, mStackDescription, mCaller)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(JSStackFrame)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(JSStackFrame)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JSStackFrame)
@@ -352,84 +361,110 @@ NS_INTERFACE_MAP_END
 /* readonly attribute uint32_t language; */
 NS_IMETHODIMP JSStackFrame::GetLanguage(uint32_t* aLanguage)
 {
   *aLanguage = mLanguage;
   return NS_OK;
 }
 
 /* readonly attribute string languageName; */
-NS_IMETHODIMP JSStackFrame::GetLanguageName(nsACString& aLanguageName)
+NS_IMETHODIMP JSStackFrame::GetLanguageName(char** aLanguageName)
 {
   static const char js[] = "JavaScript";
   static const char cpp[] = "C++";
 
   if (IsJSFrame()) {
-    aLanguageName.AssignASCII(js);
+    *aLanguageName = (char*) nsMemory::Clone(js, sizeof(js));
   } else {
-    aLanguageName.AssignASCII(cpp);
+    *aLanguageName = (char*) nsMemory::Clone(cpp, sizeof(cpp));
   }
 
   return NS_OK;
 }
 
-/* readonly attribute string filename; */
-NS_IMETHODIMP JSStackFrame::GetFilename(nsACString& aFilename)
+const char*
+JSStackFrame::GetFilename()
 {
   if (!mFilenameInitialized) {
     JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
     if (desc.script()) {
       // This cx dance is silly, since JS_GetScriptFilename ignores
       // its cx argument.
       JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
       JSAutoRequest ar(cx);
       JSAutoCompartment ac(cx, desc.script());
       const char* filename = JS_GetScriptFilename(cx, desc.script());
       if (filename) {
-        mFilename.Assign(filename);
+        mFilename =
+          (char*)nsMemory::Clone(filename, sizeof(char)*(strlen(filename)+1));
       }
     }
     mFilenameInitialized = true;
   }
 
-  if (mFilename.IsEmpty()) {
-    aFilename.SetIsVoid(true);
+  return mFilename;
+}
+
+/* readonly attribute string filename; */
+NS_IMETHODIMP JSStackFrame::GetFilename(char** aFilename)
+{
+  NS_ENSURE_ARG_POINTER(aFilename);
+
+  const char* filename = GetFilename();
+  if (filename) {
+    *aFilename = (char*) nsMemory::Clone(filename,
+                                         sizeof(char)*(strlen(filename)+1));
   } else {
-    aFilename.Assign(mFilename);
+    *aFilename = nullptr;
   }
+
   return NS_OK;
 }
 
-/* readonly attribute string name; */
-NS_IMETHODIMP JSStackFrame::GetName(nsACString& aFunction)
+const char*
+JSStackFrame::GetFunname()
 {
   if (!mFunnameInitialized) {
     JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
     if (desc.fun() && desc.script()) {
       JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
       JSAutoRequest ar(cx);
       JSAutoCompartment ac(cx, desc.script());
       JS::Rooted<JSFunction*> fun(cx, desc.fun());
       JS::Rooted<JSString*> funid(cx, JS_GetFunctionDisplayId(fun));
       if (funid) {
         size_t length = JS_GetStringEncodingLength(cx, funid);
         if (length != size_t(-1)) {
-          mFunname.SetLength(uint32_t(length));
-          JS_EncodeStringToBuffer(cx, funid, mFunname.BeginWriting(), length);
+          mFunname = static_cast<char *>(nsMemory::Alloc(length + 1));
+          if (mFunname) {
+            JS_EncodeStringToBuffer(cx, funid, mFunname, length);
+            mFunname[length] = '\0';
+          }
         }
       }
     }
     mFunnameInitialized = true;
   }
 
-  if (mFunname.IsEmpty()) {
-    aFunction.SetIsVoid(true);
+  return mFunname;
+}
+
+/* readonly attribute string name; */
+NS_IMETHODIMP JSStackFrame::GetName(char** aFunction)
+{
+  NS_ENSURE_ARG_POINTER(aFunction);
+
+  const char* funname = GetFunname();
+  if (funname) {
+    *aFunction = (char*) nsMemory::Clone(funname,
+                                         sizeof(char)*(strlen(funname)+1));
   } else {
-    aFunction.Assign(mFunname);
+    *aFunction = nullptr;
   }
+
   return NS_OK;
 }
 
 int32_t
 JSStackFrame::GetLineno()
 {
   if (!mLinenoInitialized) {
     JS::FrameDescription& desc = mStackDescription->FrameAt(mIndex);
@@ -442,59 +477,54 @@ JSStackFrame::GetLineno()
 
 /* readonly attribute int32_t lineNumber; */
 NS_IMETHODIMP JSStackFrame::GetLineNumber(int32_t* aLineNumber)
 {
   *aLineNumber = GetLineno();
   return NS_OK;
 }
 
-/* readonly attribute AUTF8String sourceLine; */
-NS_IMETHODIMP JSStackFrame::GetSourceLine(nsACString& aSourceLine)
+/* readonly attribute string sourceLine; */
+NS_IMETHODIMP JSStackFrame::GetSourceLine(char** aSourceLine)
 {
-  aSourceLine.Truncate();
+  *aSourceLine = nullptr;
   return NS_OK;
 }
 
 /* readonly attribute nsIStackFrame caller; */
 NS_IMETHODIMP JSStackFrame::GetCaller(nsIStackFrame** aCaller)
 {
   if (!mCallerInitialized) {
     mCaller = new JSStackFrame(mStackDescription, mIndex+1);
     mCallerInitialized = true;
   }
   NS_IF_ADDREF(*aCaller = mCaller);
   return NS_OK;
 }
 
-/* AUTF8String toString (); */
-NS_IMETHODIMP JSStackFrame::ToString(nsACString& _retval)
+/* string toString (); */
+NS_IMETHODIMP JSStackFrame::ToString(char** _retval)
 {
-  _retval.Truncate();
-
   const char* frametype = IsJSFrame() ? "JS" : "native";
-
-  nsCString filename;
-  nsresult rv = GetFilename(filename);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (filename.IsEmpty()) {
-    filename.AssignASCII("<unknown filename>");
+  const char* filename = GetFilename();
+  if (!filename) {
+    filename = "<unknown filename>";
   }
-
-  nsCString funname;
-  rv = GetName(funname);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (funname.IsEmpty()) {
-    funname.AssignASCII("<TOP_LEVEL>");
+  const char* funname = GetFunname();
+  if (!funname) {
+    funname = "<TOP_LEVEL>";
   }
   static const char format[] = "%s frame :: %s :: %s :: line %d";
-  _retval.AppendPrintf(format, frametype, filename.get(),
-                       funname.get(), GetLineno());
+  int len = sizeof(char)*
+              (strlen(frametype) + strlen(filename) + strlen(funname)) +
+            sizeof(format) + 3 * sizeof(mLineno);
+
+  char* buf = (char*) nsMemory::Alloc(len);
+  JS_snprintf(buf, len, format, frametype, filename, funname, GetLineno());
+  *_retval = buf;
   return NS_OK;
 }
 
 /* static */ already_AddRefed<nsIStackFrame>
 JSStackFrame::CreateStack(JSContext* cx)
 {
   static const unsigned MAX_FRAMES = 100;
 
@@ -515,18 +545,27 @@ JSStackFrame::CreateStackFrameLocation(u
                                        const char* aFunctionName,
                                        int32_t aLineNumber,
                                        nsIStackFrame* aCaller)
 {
   nsRefPtr<JSStackFrame> self = new JSStackFrame(nullptr, 0);
 
   self->mLanguage = aLanguage;
   self->mLineno = aLineNumber;
-  self->mFilename = aFilename;
-  self->mFunname = aFunctionName;
+
+  if (aFilename) {
+    self->mFilename =
+      (char*)nsMemory::Clone(aFilename, sizeof(char)*(strlen(aFilename)+1));
+  }
+
+  if (aFunctionName) {
+    self->mFunname = 
+      (char*)nsMemory::Clone(aFunctionName,
+                             sizeof(char)*(strlen(aFunctionName)+1));
+  }
 
   self->mCaller = aCaller;
 
   return self.forget();
 }
 
 already_AddRefed<nsIStackFrame>
 CreateStack(JSContext* cx)
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -148,17 +148,17 @@ interface nsIXPCComponents_Utils : nsISu
      * var res = C.u.evalInSandbox("var five = 5; 2 + five", s);
      * var outerFive = s.five;
      * s.seven = res;
      * var thirtyFive = C.u.evalInSandbox("five * seven", s);
      */
     [implicit_jscontext,optional_argc]
     jsval evalInSandbox(in AString source, in jsval sandbox,
                         [optional] in jsval version,
-                        [optional] in AUTF8String filename,
+                        [optional] in jsval filename,
                         [optional] in long lineNo);
 
     /*
      * getSandboxMetadata is designed to be called from JavaScript only.
      *
      * getSandboxMetadata retrieves the metadata associated with
      * a sandbox object. It will return undefined if there
      * is no metadata attached to the sandbox.
--- a/js/xpconnect/idl/xpcexception.idl
+++ b/js/xpconnect/idl/xpcexception.idl
@@ -7,19 +7,19 @@
 #include "nsISupports.idl"
 #include "nsIException.idl"
 
 [scriptable, uuid(ce83229c-0a82-4ba4-937b-7fd4cd45f34b)]
 interface nsIXPCException : nsIException
 {
     // inherits methods from nsIException
 
-    void initialize(in AUTF8String      aMessage,
+    void initialize(in string           aMessage,
                     in nsresult         aResult,
-                    in AUTF8String      aName,
+                    in string           aName,
                     in nsIStackFrame    aLocation,
                     in nsISupports      aData,
                     in nsIException     aInner);
 };
 
 /* this goes into the C++ header verbatim. */
 %{ C++
 /********************************************************/
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -1510,17 +1510,17 @@ AssembleSandboxMemoryReporterName(JSCont
     // Get the current source info from xpc.
     nsCOMPtr<nsIStackFrame> frame;
     xpc->GetCurrentJSStack(getter_AddRefs(frame));
 
     // Append the caller's location information.
     if (frame) {
         nsCString location;
         int32_t lineNumber = 0;
-        frame->GetFilename(location);
+        frame->GetFilename(getter_Copies(location));
         frame->GetLineNumber(&lineNumber);
 
         sandboxName.AppendLiteral(" (from: ");
         sandboxName.Append(location);
         sandboxName.AppendLiteral(":");
         sandboxName.AppendInt(lineNumber);
         sandboxName.AppendLiteral(")");
     }
@@ -1629,17 +1629,17 @@ ContextHolder::ContextHolder(JSContext *
 ContextHolder::~ContextHolder()
 {
     if (mJSContext)
         JS_DestroyContextNoGC(mJSContext);
 }
 
 nsresult
 xpc::EvalInSandbox(JSContext *cx, HandleObject sandboxArg, const nsAString& source,
-                   const nsACString& filename, int32_t lineNo,
+                   const char *filename, int32_t lineNo,
                    JSVersion jsVersion, bool returnStringOnly, MutableHandleValue rval)
 {
     JS_AbortIfWrongThread(JS_GetRuntime(cx));
     rval.set(UndefinedValue());
 
     bool waiveXray = xpc::WrapperFactory::HasWaiveXrayFlag(sandboxArg);
     RootedObject sandbox(cx, js::CheckedUnwrap(sandboxArg));
     if (!sandbox || js::GetObjectJSClass(sandbox) != &SandboxClass) {
@@ -1648,21 +1648,20 @@ xpc::EvalInSandbox(JSContext *cx, Handle
 
     nsIScriptObjectPrincipal *sop =
         (nsIScriptObjectPrincipal*)xpc_GetJSPrivate(sandbox);
     MOZ_ASSERT(sop, "Invalid sandbox passed");
     nsCOMPtr<nsIPrincipal> prin = sop->GetPrincipal();
     NS_ENSURE_TRUE(prin, NS_ERROR_FAILURE);
 
     nsAutoCString filenameBuf;
-    if (!filename.IsVoid()) {
-        filenameBuf.Assign(filename);
-    } else {
+    if (!filename) {
         // Default to the spec of the principal.
         nsJSPrincipals::get(prin)->GetScriptLocation(filenameBuf);
+        filename = filenameBuf.get();
         lineNo = 1;
     }
 
     // We create a separate cx to do the sandbox evaluation. Scope it.
     RootedValue v(cx, UndefinedValue());
     RootedValue exn(cx, UndefinedValue());
     bool ok = true;
     {
@@ -1676,17 +1675,17 @@ xpc::EvalInSandbox(JSContext *cx, Handle
             return NS_ERROR_OUT_OF_MEMORY;
         }
         nsCxPusher pusher;
         pusher.Push(sandcx);
         JSAutoCompartment ac(sandcx, sandbox);
 
         JS::CompileOptions options(sandcx);
         options.setPrincipals(nsJSPrincipals::get(prin))
-               .setFileAndLine(filenameBuf.get(), lineNo);
+               .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);
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -1856,20 +1856,18 @@ nsXPCComponents_Exception::CallOrConstru
         return NS_OK;
     }
 
     // Parse the arguments to the Exception constructor.
     ExceptionArgParser parser(cx, xpc);
     if (!parser.parse(args))
         return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
 
-    nsCOMPtr<nsIException> e = new Exception(nsCString(parser.eMsg),
-                                             parser.eResult,
-                                             EmptyCString(),
-                                             parser.eStack,
+    nsCOMPtr<nsIException> e = new Exception(parser.eMsg, parser.eResult,
+                                             nullptr, parser.eStack,
                                              parser.eData);
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     RootedObject newObj(cx);
 
     if (NS_FAILED(xpc->WrapNative(cx, obj, e, NS_GET_IID(nsIXPCException),
                                   getter_AddRefs(holder))) || !holder ||
         // Assign, not compare
@@ -2579,43 +2577,43 @@ nsXPCComponents_Utils::ReportError(Handl
     RootedString msgstr(cx, ToString(cx, error));
     if (!msgstr)
         return NS_OK;
 
     nsCOMPtr<nsIStackFrame> frame;
     nsXPConnect *xpc = nsXPConnect::XPConnect();
     xpc->GetCurrentJSStack(getter_AddRefs(frame));
 
-    nsCString fileName;
+    nsXPIDLCString fileName;
     int32_t lineNo = 0;
     if (frame) {
-        frame->GetFilename(fileName);
+        frame->GetFilename(getter_Copies(fileName));
         frame->GetLineNumber(&lineNo);
     }
 
     const jschar *msgchars = JS_GetStringCharsZ(cx, msgstr);
     if (!msgchars)
         return NS_OK;
 
     nsresult rv = scripterr->InitWithWindowID(
             nsDependentString(static_cast<const char16_t *>(msgchars)),
-            NS_ConvertUTF8toUTF16(fileName), EmptyString(), lineNo, 0, 0,
-            "XPConnect JavaScript", innerWindowID);
+            NS_ConvertUTF8toUTF16(fileName),
+            EmptyString(), lineNo, 0, 0, "XPConnect JavaScript", innerWindowID);
     NS_ENSURE_SUCCESS(rv, NS_OK);
 
     console->LogMessage(scripterr);
     return NS_OK;
 }
 
 /* void evalInSandbox(in AString source, in nativeobj sandbox); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::EvalInSandbox(const nsAString& source,
                                      HandleValue sandboxVal,
                                      HandleValue version,
-                                     const nsACString& filenameArg,
+                                     HandleValue filenameVal,
                                      int32_t lineNumber,
                                      JSContext *cx,
                                      uint8_t optionalArgc,
                                      MutableHandleValue retval)
 {
     RootedObject sandbox(cx);
     if (!JS_ValueToObject(cx, sandboxVal, &sandbox) || !sandbox)
         return NS_ERROR_INVALID_ARG;
@@ -2639,35 +2637,42 @@ nsXPCComponents_Utils::EvalInSandbox(con
         {
             jsVersion = JSVERSION_LATEST;
         }
         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;
-    nsCString filename;
-    if (!filenameArg.IsVoid()) {
-        filename.Assign(filenameArg);
+    if (optionalArgc >= 2) {
+        JSString *filenameStr = ToString(cx, filenameVal);
+        if (!filenameStr)
+            return NS_ERROR_INVALID_ARG;
+
+        JSAutoByteString filenameBytes;
+        if (!filenameBytes.encodeLatin1(cx, filenameStr))
+            return NS_ERROR_INVALID_ARG;
+        filename = filenameBytes.ptr();
     } else {
         // Get the current source info from xpc.
         nsresult rv;
         nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
         NS_ENSURE_SUCCESS(rv, rv);
 
         nsCOMPtr<nsIStackFrame> frame;
         xpc->GetCurrentJSStack(getter_AddRefs(frame));
         if (frame) {
-            frame->GetFilename(filename);
+            frame->GetFilename(getter_Copies(filename));
             frame->GetLineNumber(&lineNo);
         }
     }
 
-    return xpc::EvalInSandbox(cx, sandbox, source, filename, lineNo,
+    return xpc::EvalInSandbox(cx, sandbox, source, filename.get(), lineNo,
                               jsVersion, false, retval);
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::GetSandboxMetadata(HandleValue sandboxVal,
                                           JSContext *cx, MutableHandleValue rval)
 {
     if (!sandboxVal.isObject())
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -1065,41 +1065,43 @@ XPCConvert::ConstructException(nsresult 
                                nsIException** exceptn,
                                JSContext* cx,
                                jsval* jsExceptionPtr)
 {
     MOZ_ASSERT(!cx == !jsExceptionPtr, "Expected cx and jsExceptionPtr to cooccur.");
 
     static const char format[] = "\'%s\' when calling method: [%s::%s]";
     const char * msg = message;
+    char* sz = nullptr;
     nsXPIDLString xmsg;
     nsAutoCString sxmsg;
 
     nsCOMPtr<nsIScriptError> errorObject = do_QueryInterface(data);
     if (errorObject) {
         if (NS_SUCCEEDED(errorObject->GetMessageMoz(getter_Copies(xmsg)))) {
             CopyUTF16toUTF8(xmsg, sxmsg);
             msg = sxmsg.get();
         }
     }
     if (!msg)
         if (!nsXPCException::NameAndFormatForNSResult(rv, nullptr, &msg) || ! msg)
             msg = "<error>";
+    if (ifaceName && methodName)
+        msg = sz = JS_smprintf(format, msg, ifaceName, methodName);
 
-    nsCString msgStr(msg);
-    if (ifaceName && methodName)
-        msgStr.AppendPrintf(format, msg, ifaceName, methodName);
-
-    nsRefPtr<Exception> e = new Exception(msgStr, rv, EmptyCString(), nullptr, data);
+    nsRefPtr<Exception> e = new Exception(msg, rv, nullptr, nullptr, data);
 
     if (cx && jsExceptionPtr) {
         e->StowJSVal(*jsExceptionPtr);
     }
 
     e.forget(exceptn);
+
+    if (sz)
+        JS_smprintf_free(sz);
     return NS_OK;
 }
 
 /********************************/
 
 class MOZ_STACK_CLASS AutoExceptionRestorer
 {
 public:
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -894,21 +894,21 @@ nsXPCWrappedJSClass::CheckForException(X
                         "************************************************************\n";
                     static const char preamble[] =
                         "* Call to xpconnect wrapped JSObject produced this error:  *\n";
                     static const char cant_get_text[] =
                         "FAILED TO GET TEXT FROM EXCEPTION\n";
 
                     fputs(line, stdout);
                     fputs(preamble, stdout);
-                    nsCString text;
-                    if (NS_SUCCEEDED(xpc_exception->ToString(text)) &&
-                        !text.IsEmpty()) {
-                        fputs(text.get(), stdout);
+                    char* text;
+                    if (NS_SUCCEEDED(xpc_exception->ToString(&text)) && text) {
+                        fputs(text, stdout);
                         fputs("\n", stdout);
+                        nsMemory::Free(text);
                     } else
                         fputs(cant_get_text, stdout);
                     fputs(line, stdout);
                 }
 
                 // Log the exception to the JS Console, so that users can do
                 // something with it.
                 nsCOMPtr<nsIConsoleService> consoleService
@@ -921,37 +921,41 @@ nsXPCWrappedJSClass::CheckForException(X
                     if (NS_SUCCEEDED(rv))
                         scriptError = do_QueryInterface(errorData);
 
                     if (nullptr == scriptError) {
                         // No luck getting one from the exception, so
                         // try to cook one up.
                         scriptError = do_CreateInstance(XPC_SCRIPT_ERROR_CONTRACTID);
                         if (nullptr != scriptError) {
-                            nsCString newMessage;
-                            rv = xpc_exception->ToString(newMessage);
+                            char* exn_string;
+                            rv = xpc_exception->ToString(&exn_string);
                             if (NS_SUCCEEDED(rv)) {
+                                // use toString on the exception as the message
+                                NS_ConvertASCIItoUTF16 newMessage(exn_string);
+                                nsMemory::Free((void *) exn_string);
+
                                 // try to get filename, lineno from the first
                                 // stack frame location.
                                 int32_t lineNumber = 0;
-                                nsCString sourceName;
+                                nsXPIDLCString sourceName;
 
                                 nsCOMPtr<nsIStackFrame> location;
                                 xpc_exception->
                                     GetLocation(getter_AddRefs(location));
                                 if (location) {
                                     // Get line number w/o checking; 0 is ok.
                                     location->GetLineNumber(&lineNumber);
 
                                     // get a filename.
-                                    rv = location->GetFilename(sourceName);
+                                    rv = location->GetFilename(getter_Copies(sourceName));
                                 }
 
-                                rv = scriptError->InitWithWindowID(NS_ConvertUTF8toUTF16(newMessage),
-                                                                   NS_ConvertUTF8toUTF16(sourceName),
+                                rv = scriptError->InitWithWindowID(newMessage,
+                                                                   NS_ConvertASCIItoUTF16(sourceName),
                                                                    EmptyString(),
                                                                    lineNumber, 0, 0,
                                                                    "XPConnect JavaScript",
                                                                    nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx));
                                 if (NS_FAILED(rv))
                                     scriptError = nullptr;
                             }
                         }
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -893,24 +893,19 @@ NS_IMETHODIMP
 nsXPConnect::EvalInSandboxObject(const nsAString& source, const char *filename,
                                  JSContext *cx, JSObject *sandboxArg,
                                  bool returnStringOnly, MutableHandleValue rval)
 {
     if (!sandboxArg)
         return NS_ERROR_INVALID_ARG;
 
     RootedObject sandbox(cx, sandboxArg);
-    nsCString filenameStr;
-    if (filename) {
-        filenameStr.Assign(filename);
-    } else {
-        filenameStr = NS_LITERAL_CSTRING("x-bogus://XPConnect/Sandbox");
-    }
-    return EvalInSandbox(cx, sandbox, source, filenameStr, 1,
-                         JSVERSION_DEFAULT, returnStringOnly, rval);
+    return EvalInSandbox(cx, sandbox, source, filename ? filename :
+                         "x-bogus://XPConnect/Sandbox", 1, JSVERSION_DEFAULT,
+                         returnStringOnly, rval);
 }
 
 /* nsIXPConnectJSObjectHolder getWrappedNativePrototype (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsIClassInfo aClassInfo); */
 NS_IMETHODIMP
 nsXPConnect::GetWrappedNativePrototype(JSContext * aJSContext,
                                        JSObject * aScopeArg,
                                        nsIClassInfo *aClassInfo,
                                        nsIXPConnectJSObjectHolder **_retval)
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3522,17 +3522,17 @@ CreateSandboxObject(JSContext *cx, JS::M
 // and if no filename is provided it will use the codebase from the
 // principal and line number 1 as a fallback. if returnStringOnly is
 // true, then the result in *rval, or the exception in cx->exception
 // will be coerced into strings. If an exception is thrown converting
 // an exception to a string, evalInSandbox will return an NS_ERROR_*
 // result, and cx->exception will be empty.
 nsresult
 EvalInSandbox(JSContext *cx, JS::HandleObject sandbox, const nsAString& source,
-              const nsACString& filename, int32_t lineNo,
+              const char *filename, int32_t lineNo,
               JSVersion jsVersion, bool returnStringOnly,
               JS::MutableHandleValue rval);
 
 // Helper for retrieving metadata stored in a reserved slot. The metadata
 // is set during the sandbox creation using the "metadata" option.
 nsresult
 GetSandboxMetadata(JSContext *cx, JS::HandleObject sandboxArg,
                    JS::MutableHandleValue rval);
--- a/xpcom/base/nsIException.idl
+++ b/xpcom/base/nsIException.idl
@@ -5,60 +5,64 @@
 
 /*
  * Interfaces for representing cross-language exceptions and stack traces.
  */
 
 
 #include "nsISupports.idl"
 
+// XXX - most "string"s in this file should probably move to Unicode
+//       so may as well use AStrings...
+
+
 [scriptable, uuid(91d82105-7c62-4f8b-9779-154277c0ee90)]
 interface nsIStackFrame : nsISupports
 {
     // see nsIProgrammingLanguage for list of language consts
     readonly attribute uint32_t                language;
-    readonly attribute AUTF8String             languageName;
-    readonly attribute AUTF8String             filename;
-    readonly attribute AUTF8String             name;
+    readonly attribute string                  languageName;
+    readonly attribute string                  filename;
+    readonly attribute string                  name;
     // Valid line numbers begin at '1'. '0' indicates unknown.
     readonly attribute int32_t                 lineNumber;
-    readonly attribute AUTF8String             sourceLine;
+    readonly attribute string                  sourceLine;
     readonly attribute nsIStackFrame           caller;
 
-    AUTF8String toString();
+    string toString();
 };
 
 [scriptable, uuid(F3A8D3B4-C424-4edc-8BF6-8974C983BA78)]
 interface nsIException : nsISupports
 {
     // A custom message set by the thrower.
-    [binaryname(MessageMoz)] readonly attribute AUTF8String message;
+    [binaryname(MessageMoz)] readonly attribute string message;
     // The nsresult associated with this exception.
     readonly attribute nsresult                result;
     // The name of the error code (ie, a string repr of |result|)
-    readonly attribute AUTF8String             name;
+    readonly attribute string                  name;
 
     // Filename location.  This is the location that caused the
     // error, which may or may not be a source file location.
     // For example, standard language errors would generally have
     // the same location as their top stack entry.  File
     // parsers may put the location of the file they were parsing,
     // etc.
 
     // null indicates "no data"
-    readonly attribute AUTF8String             filename;
+    readonly attribute string                  filename;
     // Valid line numbers begin at '1'. '0' indicates unknown.
     readonly attribute uint32_t                lineNumber;
     // Valid column numbers begin at 0. 
     // We don't have an unambiguous indicator for unknown.
     readonly attribute uint32_t                columnNumber;
 
     // A stack trace, if available.
     readonly attribute nsIStackFrame           location;
     // An inner exception that triggered this, if available.
     readonly attribute nsIException            inner;
 
     // Arbitary data for the implementation.
     readonly attribute nsISupports             data;
 
     // A generic formatter - make it suitable to print, etc.
-    AUTF8String toString();
+    string toString();
 };