Bug 1452754 - Handle promise rejection in cases of error or otherwise through RAII in MapDataIntoBufferSource::DoMapDataIntoBufferSource. r=jgilbert
authorJeff Walden <jwalden@mit.edu>
Mon, 09 Apr 2018 12:57:10 -0700
changeset 412782 ca65fd361e412c270276850cbcc6511c5022f48e
parent 412781 51399503eb15cd14ecc5510d15927c6b0f840175
child 412783 d21bb4d700d80e15500f9140bae2b3e014eaeb10
push id33818
push userapavel@mozilla.com
push dateWed, 11 Apr 2018 14:36:40 +0000
treeherdermozilla-central@cfe6399e142c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs1452754
milestone61.0a1
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
Bug 1452754 - Handle promise rejection in cases of error or otherwise through RAII in MapDataIntoBufferSource::DoMapDataIntoBufferSource. r=jgilbert
dom/canvas/ImageBitmap.cpp
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -11,16 +11,17 @@
 #include "mozilla/dom/ImageBitmapBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/StructuredCloneTags.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Swizzle.h"
 #include "mozilla/Mutex.h"
+#include "mozilla/ScopeExit.h"
 #include "ImageBitmapColorUtils.h"
 #include "ImageBitmapUtils.h"
 #include "ImageUtils.h"
 #include "imgTools.h"
 
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using mozilla::dom::HTMLMediaElementBinding::NETWORK_EMPTY;
@@ -1647,65 +1648,66 @@ protected:
   }
 
   virtual ~MapDataIntoBufferSource() = default;
 
   void DoMapDataIntoBufferSource()
   {
     ErrorResult error;
 
+    auto rejectByDefault =
+      MakeScopeExit([this, &error]() {
+        this->mPromise->MaybeReject(error);
+      });
+
     if (!mImageBitmap->mDataWrapper) {
-      error.ThrowWithCustomCleanup(NS_ERROR_NOT_AVAILABLE);
-      mPromise->MaybeReject(error);
+      error.Throw(NS_ERROR_NOT_AVAILABLE);
       return;
     }
 
     // Prepare destination buffer.
     uint8_t* bufferData = nullptr;
     uint32_t bufferLength = 0;
     bool isSharedMemory = false;
     if (JS_IsArrayBufferObject(mBuffer)) {
       js::GetArrayBufferLengthAndData(mBuffer, &bufferLength, &isSharedMemory, &bufferData);
     } else if (JS_IsArrayBufferViewObject(mBuffer)) {
       js::GetArrayBufferViewLengthAndData(mBuffer, &bufferLength, &isSharedMemory, &bufferData);
     } else {
-      error.ThrowWithCustomCleanup(NS_ERROR_NOT_IMPLEMENTED);
-      mPromise->MaybeReject(error);
+      error.Throw(NS_ERROR_NOT_IMPLEMENTED);
       return;
     }
 
     if (NS_WARN_IF(!bufferData) || NS_WARN_IF(!bufferLength)) {
-      error.ThrowWithCustomCleanup(NS_ERROR_NOT_AVAILABLE);
-      mPromise->MaybeReject(error);
+      error.Throw(NS_ERROR_NOT_AVAILABLE);
       return;
     }
 
     // Check length.
     const int32_t neededBufferLength =
       mImageBitmap->MappedDataLength(mFormat, error);
 
     if (((int32_t)bufferLength - mOffset) < neededBufferLength) {
-      error.ThrowWithCustomCleanup(NS_ERROR_DOM_INDEX_SIZE_ERR);
-      mPromise->MaybeReject(error);
+      error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
       return;
     }
 
     // Call ImageBitmapFormatUtils.
     UniquePtr<ImagePixelLayout> layout =
       mImageBitmap->mDataWrapper->MapDataInto(bufferData,
                                               mOffset,
                                               bufferLength,
                                               mFormat,
                                               error);
 
     if (NS_WARN_IF(!layout)) {
-      mPromise->MaybeReject(error);
       return;
     }
 
+    rejectByDefault.release();
     mPromise->MaybeResolve(*layout);
   }
 
   RefPtr<Promise> mPromise;
   RefPtr<ImageBitmap> mImageBitmap;
   JS::PersistentRooted<JSObject*> mBuffer;
   int32_t mOffset;
   ImageBitmapFormat mFormat;