Merge mozilla-central to autoland. a=merge CLOSED TREE
authorCiure Andrei <aciure@mozilla.com>
Thu, 17 May 2018 01:08:41 +0300
changeset 796250 76512d757a4ed379771c567731fbca9a5c7767c7
parent 796249 278ac3ea0ce59ba78e3b582641f85fdc67315ff1 (current diff)
parent 796087 1800b8895c08bc0c60302775dc0a4b5ea4deb310 (diff)
child 796251 e4cdaab8e5c7b6e78c4f32bb1694e47c257ba363
push id110198
push userbmo:rcaliman@mozilla.com
push dateThu, 17 May 2018 12:04:52 +0000
reviewersmerge
milestone62.0a1
Merge mozilla-central to autoland. a=merge CLOSED TREE
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -58,18 +58,23 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Promise)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Promise)
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mPromiseObj);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Promise, AddRef);
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(Promise, Release);
+NS_IMPL_CYCLE_COLLECTING_ADDREF(Promise)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(Promise)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Promise)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+  NS_INTERFACE_MAP_ENTRY(Promise)
+NS_INTERFACE_MAP_END
 
 Promise::Promise(nsIGlobalObject* aGlobal)
   : mGlobal(aGlobal)
   , mPromiseObj(nullptr)
 {
   MOZ_ASSERT(mGlobal);
 
   mozilla::HoldJSObjects(this);
--- a/dom/promise/Promise.h
+++ b/dom/promise/Promise.h
@@ -27,25 +27,31 @@ namespace mozilla {
 namespace dom {
 
 class AnyCallback;
 class MediaStreamError;
 class PromiseInit;
 class PromiseNativeHandler;
 class PromiseDebugging;
 
-class Promise : public SupportsWeakPtr<Promise>
+#define NS_PROMISE_IID \
+  { 0x1b8d6215, 0x3e67, 0x43ba, \
+    { 0x8a, 0xf9, 0x31, 0x5e, 0x8f, 0xce, 0x75, 0x65 } }
+
+class Promise : public nsISupports,
+                public SupportsWeakPtr<Promise>
 {
   friend class PromiseTask;
   friend class PromiseWorkerProxy;
   friend class PromiseWorkerProxyRunnable;
 
 public:
-  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Promise)
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(Promise)
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_PROMISE_IID)
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Promise)
   MOZ_DECLARE_WEAKREFERENCE_TYPENAME(Promise)
 
   // Promise creation tries to create a JS reflector for the Promise, so is
   // fallible.  Furthermore, we don't want to do JS-wrapping on a 0-refcount
   // object, so we addref before doing that and return the addrefed pointer
   // here.
   static already_AddRefed<Promise>
   Create(nsIGlobalObject* aGlobal, ErrorResult& aRv);
@@ -193,12 +199,14 @@ private:
 
   void HandleException(JSContext* aCx);
 
   RefPtr<nsIGlobalObject> mGlobal;
 
   JS::Heap<JSObject*> mPromiseObj;
 };
 
+NS_DEFINE_STATIC_IID_ACCESSOR(Promise, NS_PROMISE_IID)
+
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_Promise_h
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -886,16 +886,31 @@ XPCConvert::NativeInterface2JSObject(Mut
     }
     if (flat) {
         if (allowNativeWrapper && !JS_WrapObject(cx, &flat))
             return false;
         d.setObjectOrNull(flat);
         return true;
     }
 
+    // NOTE(nika): Remove if Promise becomes non-nsISupports
+    if (iid->Equals(NS_GET_IID(nsISupports))) {
+        // Check for a Promise being returned via nsISupports.  In that
+        // situation, we want to dig out its underlying JS object and return
+        // that.
+        RefPtr<Promise> promise = do_QueryObject(aHelper.Object());
+        if (promise) {
+            flat = promise->PromiseObj();
+            if (!JS_WrapObject(cx, &flat))
+                return false;
+            d.setObjectOrNull(flat);
+            return true;
+        }
+    }
+
     // Don't double wrap CPOWs. This is a temporary measure for compatibility
     // with objects that don't provide necessary QIs (such as objects under
     // the new DOM bindings). We expect the other side of the CPOW to have
     // the appropriate wrappers in place.
     RootedObject cpow(cx, UnwrapNativeCPOW(aHelper.Object()));
     if (cpow) {
         if (!JS_WrapObject(cx, &cpow))
             return false;
@@ -1012,16 +1027,28 @@ XPCConvert::JSObject2NativeInterface(voi
                 if (nsCOMPtr<mozIDOMWindow> inner = do_QueryInterface(iface)) {
                     iface = nsPIDOMWindowInner::From(inner)->GetOuterWindow();
                     return NS_SUCCEEDED(iface->QueryInterface(*iid, dest));
                 }
             }
 
             return false;
         }
+
+        // NOTE(nika): Remove if Promise becomes non-nsISupports
+        // Deal with Promises being passed as nsISupports.  In that situation we
+        // want to create a dom::Promise and use that.
+        if (iid->Equals(NS_GET_IID(nsISupports))) {
+            RootedObject innerObj(cx, inner);
+            if (IsPromiseObject(innerObj)) {
+                nsIGlobalObject* glob = NativeGlobal(innerObj);
+                RefPtr<Promise> p = Promise::CreateFromExisting(glob, innerObj);
+                return p && NS_SUCCEEDED(p->QueryInterface(*iid, dest));
+            }
+        }
     }
 
     RefPtr<nsXPCWrappedJS> wrapper;
     nsresult rv = nsXPCWrappedJS::GetNewOrUsed(src, *iid, getter_AddRefs(wrapper));
     if (pErr)
         *pErr = rv;
 
     if (NS_FAILED(rv) || !wrapper)