Bug 1330759 - Part 4: Change XMLHttpRequest's responseText getter to take a DOMString, not an nsAString. r=froydnj, a=jcristau
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 18 Jan 2017 22:20:15 -0500
changeset 366591 cdaba011494a6f01f7ed4e8f419653b4ee5dbcca
parent 366590 0f3d229ed368c45b2e12e080d0e1d4956a88aaa0
child 366592 121ee6ad585ef8d8f26a986830d71afc9b306c86
push id6805
push userryanvm@gmail.com
push dateTue, 24 Jan 2017 05:52:45 +0000
treeherdermozilla-beta@1522cb56a651 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj, jcristau
bugs1330759
milestone52.0
Bug 1330759 - Part 4: Change XMLHttpRequest's responseText getter to take a DOMString, not an nsAString. r=froydnj, a=jcristau
dom/xhr/XMLHttpRequest.h
dom/xhr/XMLHttpRequestMainThread.cpp
dom/xhr/XMLHttpRequestMainThread.h
dom/xhr/XMLHttpRequestString.cpp
dom/xhr/XMLHttpRequestString.h
dom/xhr/XMLHttpRequestWorker.cpp
dom/xhr/XMLHttpRequestWorker.h
--- a/dom/xhr/XMLHttpRequest.h
+++ b/dom/xhr/XMLHttpRequest.h
@@ -13,16 +13,17 @@
 #include "nsIXMLHttpRequest.h"
 
 class nsIJSID;
 
 namespace mozilla {
 namespace dom {
 
 class Blob;
+class DOMString;
 class FormData;
 class URLSearchParams;
 class XMLHttpRequestUpload;
 
 class XMLHttpRequest : public XMLHttpRequestEventTarget
 {
 public:
   static already_AddRefed<XMLHttpRequest>
@@ -133,17 +134,17 @@ public:
   SetResponseType(XMLHttpRequestResponseType aType,
                   ErrorResult& aRv) = 0;
 
   virtual void
   GetResponse(JSContext* aCx, JS::MutableHandle<JS::Value> aResponse,
               ErrorResult& aRv) = 0;
 
   virtual void
-  GetResponseText(nsAString& aResponseText, ErrorResult& aRv) = 0;
+  GetResponseText(DOMString& aResponseText, ErrorResult& aRv) = 0;
 
   virtual nsIDocument*
   GetResponseXML(ErrorResult& aRv) = 0;
 
   virtual bool
   MozBackgroundRequest() const = 0;
 
   virtual void
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -8,16 +8,17 @@
 
 #include <algorithm>
 #ifndef XP_WIN
 #include <unistd.h>
 #endif
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/dom/BlobSet.h"
+#include "mozilla/dom/DOMString.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/FetchUtil.h"
 #include "mozilla/dom/FormData.h"
 #include "mozilla/dom/MutableBlobStorage.h"
 #include "mozilla/dom/XMLDocument.h"
 #include "mozilla/dom/URLSearchParams.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
@@ -565,22 +566,28 @@ XMLHttpRequestMainThread::AppendToRespon
   helper.AddLength(destlen);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 XMLHttpRequestMainThread::GetResponseText(nsAString& aResponseText)
 {
   ErrorResult rv;
-  GetResponseText(aResponseText, rv);
-  return rv.StealNSResult();
+  DOMString str;
+  GetResponseText(str, rv);
+  if (NS_WARN_IF(rv.Failed())) {
+    return rv.StealNSResult();
+  }
+
+  str.ToString(aResponseText);
+  return NS_OK;
 }
 
 void
-XMLHttpRequestMainThread::GetResponseText(nsAString& aResponseText,
+XMLHttpRequestMainThread::GetResponseText(DOMString& aResponseText,
                                           ErrorResult& aRv)
 {
   XMLHttpRequestStringSnapshot snapshot;
   GetResponseText(snapshot, aRv);
   if (aRv.Failed()) {
     return;
   }
 
@@ -767,18 +774,18 @@ XMLHttpRequestMainThread::GetResponse(JS
                                       JS::MutableHandle<JS::Value> aResponse,
                                       ErrorResult& aRv)
 {
   switch (mResponseType) {
   case XMLHttpRequestResponseType::_empty:
   case XMLHttpRequestResponseType::Text:
   case XMLHttpRequestResponseType::Moz_chunked_text:
   {
-    nsAutoString str;
-    aRv = GetResponseText(str);
+    DOMString str;
+    GetResponseText(str, aRv);
     if (aRv.Failed()) {
       return;
     }
     if (!xpc::StringToJsval(aCx, str, aResponse)) {
       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     }
     return;
   }
--- a/dom/xhr/XMLHttpRequestMainThread.h
+++ b/dom/xhr/XMLHttpRequestMainThread.h
@@ -52,16 +52,17 @@ class nsILoadGroup;
 class nsIUnicodeDecoder;
 class nsIJSID;
 
 namespace mozilla {
 namespace dom {
 
 class Blob;
 class BlobSet;
+class DOMString;
 class FormData;
 class URLSearchParams;
 class XMLHttpRequestUpload;
 struct OriginAttributesDictionary;
 
 // A helper for building up an ArrayBuffer object's data
 // before creating the ArrayBuffer itself.  Will do doubling
 // based reallocation, up to an optional maximum growth given.
@@ -454,17 +455,17 @@ public:
   SetResponseType(XMLHttpRequestResponseType aType,
                   ErrorResult& aRv) override;
 
   virtual void
   GetResponse(JSContext* aCx, JS::MutableHandle<JS::Value> aResponse,
               ErrorResult& aRv) override;
 
   virtual void
-  GetResponseText(nsAString& aResponseText, ErrorResult& aRv) override;
+  GetResponseText(DOMString& aResponseText, ErrorResult& aRv) override;
 
   void
   GetResponseText(XMLHttpRequestStringSnapshot& aSnapshot,
                   ErrorResult& aRv);
 
   virtual nsIDocument*
   GetResponseXML(ErrorResult& aRv) override;
 
--- a/dom/xhr/XMLHttpRequestString.cpp
+++ b/dom/xhr/XMLHttpRequestString.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "XMLHttpRequestString.h"
 #include "mozilla/Mutex.h"
 #include "nsISupportsImpl.h"
+#include "mozilla/dom/DOMString.h"
 
 namespace mozilla {
 namespace dom {
 
 class XMLHttpRequestStringBuffer final
 {
   friend class XMLHttpRequestStringWriterHelper;
   friend class XMLHttpRequestStringSnapshotReaderHelper;
@@ -56,21 +57,34 @@ public:
 
   size_t
   SizeOfThis(MallocSizeOf aMallocSizeOf) const
   {
     return mData.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
   }
 
   MOZ_MUST_USE bool
-  GetAsString(nsAString& aString, uint32_t aLength)
+  GetAsString(DOMString& aString, uint32_t aLength)
   {
     MutexAutoLock lock(mMutex);
     MOZ_ASSERT(aLength <= mData.Length());
-    return aString.Assign(mData, aLength, mozilla::fallible);
+    nsStringBuffer* buf = nsStringBuffer::FromString(mData);
+    if (buf) {
+      // We have to use SetEphemeralStringBuffer, because once we release our
+      // mutex mData can get mutated from some other thread while the DOMString
+      // is still alive.
+      aString.SetEphemeralStringBuffer(buf, aLength);
+      return true;
+    }
+
+    // We can get here if mData is empty.  In that case it won't have an
+    // nsStringBuffer....
+    MOZ_ASSERT(mData.IsEmpty());
+    return aString.AsAString().Assign(mData.BeginReading(), aLength,
+                                      mozilla::fallible);
   }
 
   void
   CreateSnapshot(XMLHttpRequestStringSnapshot& aSnapshot)
   {
     MutexAutoLock lock(mMutex);
     aSnapshot.Set(this, mData.Length());
   }
@@ -182,27 +196,25 @@ XMLHttpRequestStringSnapshot::Set(XMLHtt
   MOZ_ASSERT(aLength <= aBuffer->UnsafeLength());
 
   mBuffer = aBuffer;
   mLength = aLength;
   mVoid = false;
 }
 
 bool
-XMLHttpRequestStringSnapshot::GetAsString(nsAString& aString) const
+XMLHttpRequestStringSnapshot::GetAsString(DOMString& aString) const
 {
   if (mBuffer) {
     MOZ_ASSERT(!mVoid);
     return mBuffer->GetAsString(aString, mLength);
   }
 
-  aString.Truncate();
-
   if (mVoid) {
-    aString.SetIsVoid(true);
+    aString.SetNull();
   }
 
   return true;
 }
 
 // ---------------------------------------------------------------------------
 // XMLHttpRequestStringWriterHelper
 
--- a/dom/xhr/XMLHttpRequestString.h
+++ b/dom/xhr/XMLHttpRequestString.h
@@ -10,16 +10,17 @@
 #include "nsString.h"
 
 namespace mozilla {
 
 class Mutex;
 
 namespace dom {
 
+class DOMString;
 class XMLHttpRequestStringBuffer;
 class XMLHttpRequestStringSnapshot;
 class XMLHttpRequestStringWriterHelper;
 class XMLHttpRequestStringSnapshotReaderHelper;
 
 // We want to avoid the dup of strings when XHR in workers has access to
 // responseText for events dispatched during the loading state. For this reason
 // we use this class, able to create snapshots of the current size of itself
@@ -113,17 +114,17 @@ public:
     return mVoid;
   }
 
   bool IsEmpty() const
   {
     return !mLength;
   }
 
-  MOZ_MUST_USE bool GetAsString(nsAString& aString) const;
+  MOZ_MUST_USE bool GetAsString(DOMString& aString) const;
 
 private:
   XMLHttpRequestStringSnapshot(const XMLHttpRequestStringSnapshot&) = delete;
   XMLHttpRequestStringSnapshot& operator=(const XMLHttpRequestStringSnapshot&&) = delete;
 
   void Set(XMLHttpRequestStringBuffer* aBuffer, uint32_t aLength);
 
   void ResetInternal(bool aIsVoid);
--- a/dom/xhr/XMLHttpRequestWorker.cpp
+++ b/dom/xhr/XMLHttpRequestWorker.cpp
@@ -2413,17 +2413,17 @@ XMLHttpRequestWorker::GetResponse(JSCont
     }
   }
 
   aRv = mStateData.mResponseResult;
   aResponse.set(mStateData.mResponse);
 }
 
 void
-XMLHttpRequestWorker::GetResponseText(nsAString& aResponseText, ErrorResult& aRv)
+XMLHttpRequestWorker::GetResponseText(DOMString& aResponseText, ErrorResult& aRv)
 {
   aRv = mStateData.mResponseTextResult;
   if (aRv.Failed()) {
     return;
   }
 
   if (!mStateData.mResponseText.GetAsString(aResponseText)) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
--- a/dom/xhr/XMLHttpRequestWorker.h
+++ b/dom/xhr/XMLHttpRequestWorker.h
@@ -12,16 +12,17 @@
 #include "XMLHttpRequestString.h"
 #include "mozilla/dom/TypedArray.h"
 
 namespace mozilla {
 namespace dom {
 
 class Proxy;
 class SendRunnable;
+class DOMString;
 
 namespace workers {
 class WorkerPrivate;
 }
 
 class XMLHttpRequestWorker final : public XMLHttpRequest,
                                    public workers::WorkerHolder
 {
@@ -240,17 +241,17 @@ public:
   SetResponseType(XMLHttpRequestResponseType aResponseType,
                   ErrorResult& aRv) override;
 
   virtual void
   GetResponse(JSContext* /* unused */, JS::MutableHandle<JS::Value> aResponse,
               ErrorResult& aRv) override;
 
   virtual void
-  GetResponseText(nsAString& aResponseText, ErrorResult& aRv) override;
+  GetResponseText(DOMString& aResponseText, ErrorResult& aRv) override;
 
   virtual nsIDocument*
   GetResponseXML(ErrorResult& aRv) override
   {
     MOZ_CRASH("This method should not be called.");
   }
 
   virtual void